├── .github └── workflows │ ├── cmake.yml │ └── codeql-analysis.yml ├── .gitignore ├── .vscode └── settings.json ├── CMakeLists.txt ├── LICENCE ├── README.md ├── doc ├── Sample-buginfo.txt ├── buginfo.txt ├── debugger.txt ├── gpl.txt ├── run68.ini └── run68.txt └── src ├── ansicolor-w32.c ├── ansicolor-w32.h ├── calc.c ├── conditions.c ├── debugger.c ├── disassemble.c ├── doscall.c ├── eaaccess.c ├── exec.c ├── getini.c ├── iocscall.c ├── key.c ├── line0.c ├── line2.c ├── line4.c ├── line5.c ├── line6.c ├── line7.c ├── line8.c ├── line9.c ├── lineb.c ├── linec.c ├── lined.c ├── linee.c ├── linef.c ├── load.c ├── mem.c ├── run68.c └── run68.h /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: CMake 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 11 | BUILD_TYPE: Release 12 | 13 | jobs: 14 | build: 15 | # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. 16 | # You can convert this to a matrix build if you need cross-platform coverage. 17 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 18 | # runs-on: [macos-latest, ubuntu-latest, windows-latest] 19 | runs-on: [ubuntu-latest] 20 | 21 | steps: 22 | - uses: actions/checkout@v3 23 | 24 | - name: Configure CMake 25 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 26 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 27 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 28 | 29 | - name: Build 30 | # Build your program with the given configuration 31 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} 32 | 33 | - name: Test 34 | working-directory: ${{github.workspace}}/build 35 | # Execute tests defined by the CMake configuration. 36 | # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail 37 | run: ctest -C ${{env.BUILD_TYPE}} 38 | 39 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '30 16 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'cpp' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | 52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 53 | # queries: security-extended,security-and-quality 54 | 55 | 56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 57 | # If this step fails, then you should remove it and run the build manually (see below) 58 | - name: Autobuild 59 | uses: github/codeql-action/autobuild@v2 60 | 61 | # ℹ️ Command-line programs to run using the OS shell. 62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 63 | 64 | # If the Autobuild fails above, remove it and uncomment the following three lines. 65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 66 | 67 | # - run: | 68 | # echo "Run, Build Application using script" 69 | # ./location_of_script_within_repo/buildscript.sh 70 | 71 | - name: Perform CodeQL Analysis 72 | uses: github/codeql-action/analyze@v2 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.obj 3 | *.old 4 | *.pdb 5 | *.idb 6 | *.user 7 | *.ncb 8 | *.suo 9 | *.aps 10 | *.*~ 11 | build 12 | .DS_Store 13 | *.check_cache 14 | build2 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "makefile.extensionOutputFolder": "./.vscode" 3 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | execute_process(COMMAND uname OUTPUT_VARIABLE uname) # for detecting msys 3 | option(USE_ICONV "Use iconv for converting Shift-JIS to UTF-8." ON) 4 | 5 | #add_definitions(-DFNC_TRACE -DENV_FROM_INI) 6 | add_definitions(-DENV_FROM_INI) 7 | 8 | if(USE_ICONV) 9 | if (NOT(uname MATCHES "^MSYS" OR uname MATCHES "^MINGW")) 10 | add_definitions(-DUSE_ICONV) 11 | endif() 12 | endif() 13 | 14 | 15 | project(run68 C) 16 | 17 | if (EMSCRIPTEN) 18 | set(CMAKE_EXE_LINKER_FLAGS "--embed-file ./fs@ -sFORCE_FILESYSTEM") 19 | endif() 20 | 21 | 22 | set(CMAKE_C_FLAGS 23 | "-O3 -fsigned-char -Wno-int-conversion -Wno-return-type -Wno-switch -Wno-implicit-function-declaration -Wno-format -Wno-invalid-source-encoding -Wno-pointer-integer-compare -Wno-int-to-pointer-cast -Wno-pointer-sign -Wno-incompatible-pointer-types") 24 | 25 | if (uname MATCHES "^MSYS" OR uname MATCHES "^MINGW") 26 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --exec-charset=cp932") # To support utf-8 (cp932 is not a mistake. it works fine.) 27 | endif() 28 | 29 | set(SRC 30 | src/ansicolor-w32.c 31 | src/calc.c 32 | src/conditions.c 33 | src/debugger.c 34 | src/disassemble.c 35 | src/eaaccess.c 36 | src/exec.c 37 | src/getini.c 38 | src/key.c 39 | src/line0.c 40 | src/line2.c 41 | src/line4.c 42 | src/line5.c 43 | src/line6.c 44 | src/line7.c 45 | src/line8.c 46 | src/line9.c 47 | src/lineb.c 48 | src/linec.c 49 | src/lined.c 50 | src/linee.c 51 | src/linef.c 52 | src/load.c 53 | src/mem.c 54 | src/run68.c 55 | src/iocscall.c 56 | src/doscall.c 57 | src/run68.h 58 | ) 59 | 60 | set(CMAKE_CXX_STANDARD, 11) 61 | 62 | add_executable(run68 ${SRC}) 63 | 64 | set(LIBS m) # math lib 65 | 66 | if(USE_ICONV) 67 | if(APPLE) 68 | set(LIBS ${LIBS} "iconv") 69 | endif() 70 | endif() 71 | 72 | target_link_libraries(run68 PUBLIC ${LIBS}) 73 | 74 | INSTALL(TARGETS run68 RUNTIME DESTINATION bin) 75 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | run68mac 2 | ======== 3 | 4 | [![CMake](https://github.com/GOROman/run68mac/actions/workflows/cmake.yml/badge.svg)](https://github.com/GOROman/run68mac/actions/workflows/cmake.yml) 5 | 6 | Human68k CUI Emulator 7 | 8 | Human68k上の実行ファイル(*.x, *.r)をCUIで動かすツールrun68。run68を Mac 上で動作するようにしたものです。 9 | (Mac以外の環境でも使えるようになりました。) 10 | 11 | How to build 12 | ------------ 13 | 14 | CMakeを使用してビルドするように変更しています。あらかじめ、brew install cmake などでインストールしておいてください。漢字コードを変換するライブラリには libiconv を使用しています。 15 | ``` 16 | $ brew install cmake 17 | $ brew install libiconv 18 | ``` 19 | 20 | ``` 21 | $ mkdir build 22 | $ cd build 23 | $ cmake .. 24 | $ make 25 | $ make install 26 | ``` 27 | make install で /usr/local/bin/ 等にインストールされます。 28 | 29 | デバッグのためにXcodeでビルドする場合 30 | ``` 31 | $ mkdir build 32 | $ cd build 33 | $ cmake -G Xcode .. 34 | $ open run68.xcodeproj 35 | ``` 36 | 37 | How to use 38 | ---------- 39 | 40 | ``` 41 | $ run68 [実行ファイル(*.x *.r)] [引数] 42 | ``` 43 | 44 | 45 | 起動例 46 | ``` 47 | $ run68 mdx2mus.x bos14.mdx 48 | ``` 49 | 50 | 標準出力(stdout)および標準エラー出力(strerr)は、Shift-JISは自動的にUTF-8に変換します。 51 | ``` 52 | $ ./run68 mxc.x bos14_.mus 53 | 54 | MML converter for mxdrv2 version 1.01 (c)1989 MFS soft, milk. 55 | MDXタイトル : "Blast Power ! 〜 from BOSCONIAN-X68" 56 | PCMファイル : 'bos' 57 | ChA ChB ChC ChD ChE ChF ChG ChH ChP 58 | Clock counts: 07872 07872 07872 07872 07872 07872 07872 07872 07872 59 | Loop counts: 07872 07872 07872 07872 07872 07872 07872 07872 07872 60 | 使用音色番号: 3 6 7 10 11 12 13 15 61 | ``` 62 | 63 | ``` 64 | $ ./run68 HAS.X 65 | X68k High-speed Assembler v3.09 Copyright 1990-94 by Y.Nakamura 66 | 使用法:as [スイッチ] ファイル名 67 | -t path テンポラリパス指定 68 | -o name オブジェクトファイル名 69 | -i path インクルードパス指定 70 | -p [file] リストファイル作成 71 | -n 最適化の禁止 72 | (...省略) 73 | ``` 74 | 75 | TIPS 76 | ---- 77 | 78 | - あたかもX68000のコマンドがMacのターミナル上で動いているように見せる方法 79 | 80 | 1. /usr/local/x68/bin 以下にX68000形式の実行ファイルを置いておく 81 | ```` 82 | $ ls /usr/local/x68/bin 83 | CV.x HAS.X hlk.x note.x 84 | ```` 85 | 86 | 2. 同名のシェルスクリプトをパスが通っている場所に配置(/usr/local/binなど) 87 | 88 | /usr/local/bin/has.x 89 | ```sh 90 | #!/bin/sh 91 | run68 /usr/local/x68/bin/has.x $@ 92 | ``` 93 | 94 | 3. 実行属性(+x)を与える 95 | ```` 96 | $ chmod +x /usr/local/bin/has.x 97 | ```` 98 | 99 | 4. X68000のコマンドが動作可能 100 | ```` 101 | $ has.x 102 | X68k High-speed Assembler v3.09 Copyright 1990-94 by Y.Nakamura 103 | 使用法:as [スイッチ] ファイル名 104 | -t path テンポラリパス指定 105 | -o name オブジェクトファイル名 106 | -i path インクルードパス指定 107 | ... 108 | ```` 109 | -------------------------------------------------------------------------------- /doc/Sample-buginfo.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GOROman/run68mac/1d5e7efd6fc454dc2f59285366dcd56f7aa6d9a8/doc/Sample-buginfo.txt -------------------------------------------------------------------------------- /doc/buginfo.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GOROman/run68mac/1d5e7efd6fc454dc2f59285366dcd56f7aa6d9a8/doc/buginfo.txt -------------------------------------------------------------------------------- /doc/debugger.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GOROman/run68mac/1d5e7efd6fc454dc2f59285366dcd56f7aa6d9a8/doc/debugger.txt -------------------------------------------------------------------------------- /doc/gpl.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /doc/run68.ini: -------------------------------------------------------------------------------- 1 | [all] 2 | mainmemory=12 3 | iothrough 4 | [environment] 5 | PATH=E:\X68000\BIN;E:\X68000\GCC;E:\X68000\SHELLS\DASH 6 | INCLUDE=E:\X68000\INCLUDE 7 | LIB=E:\X68000\LIB 8 | PASCAL=E:\X68000\PASCAL 9 | -------------------------------------------------------------------------------- /doc/run68.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GOROman/run68mac/1d5e7efd6fc454dc2f59285366dcd56f7aa6d9a8/doc/run68.txt -------------------------------------------------------------------------------- /src/ansicolor-w32.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GOROman/run68mac/1d5e7efd6fc454dc2f59285366dcd56f7aa6d9a8/src/ansicolor-w32.c -------------------------------------------------------------------------------- /src/ansicolor-w32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | int WriteW32(short _type, FILE* fp, const char* buf, size_t len); 5 | #endif 6 | -------------------------------------------------------------------------------- /src/calc.c: -------------------------------------------------------------------------------- 1 | /* $Id: calc.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:05 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.3 1999/12/21 10:08:59 yfujii 9 | * Uptodate source code from Beppu. 10 | * 11 | * Revision 1.2 1999/12/07 12:39:26 yfujii 12 | * *** empty log message *** 13 | * 14 | * Revision 1.2 1999/10/21 12:17:46 yfujii 15 | * Added RCS keywords and modified for WIN32 a little. 16 | * 17 | */ 18 | 19 | #undef MAIN 20 | 21 | #include 22 | #include "run68.h" 23 | 24 | // Long add_Long(Long src, Long dest, int size); 25 | // Long sub_Long(Long src, Long dest, int size); 26 | 27 | /* 28 |  機能:destにsrcをsizeサイズで加算する 29 | 戻り値:答え 30 | */ 31 | Long add_long(Long src, Long dest, int size) { 32 | 33 | Long result; 34 | 35 | switch(size) { 36 | case S_BYTE: 37 | result = (dest & 0xffffff00) | (((dest & 0xff) + (src & 0xff)) & 0xff); 38 | break; 39 | case S_WORD: 40 | result = (dest & 0xffff0000) | (((dest & 0xffff) + (src & 0xffff)) & 0xffff); 41 | break; 42 | case S_LONG: 43 | result = dest + src; 44 | break; 45 | } 46 | 47 | return(result); 48 | } 49 | 50 | /* 51 |  機能:destからsrcをsizeサイズで減算する 52 | 戻り値:答え 53 | */ 54 | Long sub_long(Long src, Long dest, int size) { 55 | 56 | Long result; 57 | 58 | switch(size) { 59 | case S_BYTE: 60 | result = (dest & 0xffffff00) | (((dest & 0xff) - (src & 0xff)) & 0xff); 61 | break; 62 | case S_WORD: 63 | result = (dest & 0xffff0000) | (((dest & 0xffff) - (src & 0xffff)) & 0xffff); 64 | break; 65 | case S_LONG: 66 | result = dest - src; 67 | break; 68 | } 69 | 70 | return(result); 71 | } 72 | -------------------------------------------------------------------------------- /src/conditions.c: -------------------------------------------------------------------------------- 1 | /* $Id: conditions.c,v 1.3 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.2 2009/08/05 14:44:33 masamic 6 | * Some Bug fix, and implemented some instruction 7 | * Following Modification contributed by TRAP. 8 | * 9 | * Fixed Bug: In disassemble.c, shift/rotate as{lr},ls{lr},ro{lr} alway show word size. 10 | * Modify: enable KEYSNS, register behaiviour of sub ea, Dn. 11 | * Add: Nbcd, Sbcd. 12 | * 13 | * Revision 1.1.1.1 2001/05/23 11:22:05 masamic 14 | * First imported source code and docs 15 | * 16 | * Revision 1.2 1999/12/07 12:39:54 yfujii 17 | * *** empty log message *** 18 | * 19 | * Revision 1.2 1999/11/29 06:24:04 yfujii 20 | * Condition code operations are modified to be correct. 21 | * 22 | * 23 | */ 24 | 25 | // /* conditions.c */ 26 | 27 | // void general_conditions(Long result, int size); 28 | // void add_conditions(Long src , Long dest, Long result, int size, BOOL zero_flag); 29 | // void cmp_conditions(Long src , Long dest, Long result, int size); 30 | // void sub_conditions(Long src , Long dest, Long result, int size, BOOL zero_flag); 31 | // void neg_conditions(Long dest, Long result, int size, BOOL zero_flag); 32 | // void check(char *mode, Long src, Long dest, Long result, int size, short before); 33 | 34 | #include "run68.h" 35 | 36 | static void ccr2bitmap(short ccr, char *bitmap) { 37 | int i; 38 | int flag; 39 | int j = 0; 40 | 41 | ccr &= 0x1f; 42 | 43 | for (i = 6; i >= 0; i--) { 44 | flag = (ccr >> i) & 1; 45 | if (flag == 1) { 46 | bitmap[j++] = '1'; 47 | } else { 48 | bitmap[j++] = '0'; 49 | } 50 | } 51 | bitmap[j] = '\0'; 52 | } 53 | 54 | void check(char *mode, Long src, Long dest, Long result, int size, short before) { 55 | char befstr[9]; 56 | char aftstr[9]; 57 | 58 | ccr2bitmap((short)(before & 0x1f), befstr); 59 | ccr2bitmap((short)(sr & 0x1f), aftstr); 60 | 61 | printf("%s: 0x%08x 0x%08x 0x%08x %1d %8s %8s\n", mode, src, dest, result, size, befstr, aftstr); 62 | } 63 | 64 | Long getMSB(Long num, int size) { 65 | 66 | Long ret; 67 | 68 | switch (size) { 69 | case S_BYTE: 70 | ret = ((num >> 7) & 1); 71 | break; 72 | case S_WORD: 73 | ret = ((num >> 15) & 1); 74 | break; 75 | case S_LONG: 76 | ret = ((num >> 31) & 1); 77 | break; 78 | default: 79 | err68a("不正なデータサイズです。", __FILE__, __LINE__); 80 | } 81 | 82 | return(ret); 83 | } 84 | 85 | Long getBitsByDataSize(Long num, int size) { 86 | Long ret; 87 | switch (size) { 88 | case S_BYTE: 89 | ret = num & 0xff; 90 | break; 91 | case S_WORD: 92 | ret = num & 0xffff; 93 | break; 94 | case S_LONG: 95 | ret = num; 96 | break; 97 | default: 98 | err68a("不正なデータサイズです。", __FILE__, __LINE__); 99 | } 100 | return(ret); 101 | } 102 | 103 | 104 | 105 | /* 106 | * 【説明】 107 | * 一般系コンディションフラグの設定 108 | * 109 | * 【レジスタの変化】 110 | * X: 変化なし 111 | * N: 負数のときON、零または正数のときOFF 112 | * Z: 零のときON、零以外のときOFF 113 | * V: 常に0 114 | * C: 常に0 115 | * 116 | * 【関数書式】 117 | * general_conditions(result, size); 118 | * 119 | * 【引数】 120 | * Long result; Result値 121 | * int size; アクセスサイズ 122 | * 123 | * 【返値】 124 | * なし 125 | * 126 | */ 127 | 128 | void general_conditions(Long result, int size) { 129 | 130 | int Rm; 131 | 132 | Rm = (getMSB(result, size) != (Long)0); 133 | 134 | /* Overflow Flag */ 135 | CCR_V_OFF(); 136 | 137 | /* Carry Flag & Extend Flag */ 138 | CCR_C_OFF(); 139 | // CCR_X_OFF(); 140 | 141 | /* Zero Flag */ 142 | if (getBitsByDataSize(result, size) == 0) { 143 | CCR_Z_ON(); 144 | } else { 145 | CCR_Z_OFF(); 146 | } 147 | 148 | /* Negative Flag */ 149 | if (Rm != 0) { 150 | CCR_N_ON(); 151 | } else { 152 | CCR_N_OFF(); 153 | } 154 | } 155 | 156 | /* 157 | * 【説明】 158 | * add系コンディションフラグの設定 159 | * 160 | * 【関数書式】 161 | * add_conditions(src, dest, result, size, zero_flag); 162 | * 163 | * 【引数】 164 | * Long src; Source値 165 | * Long dest; Destination値 166 | * Long result; Result値 167 | * int size; アクセスサイズ 168 | * BOOL zero_flag; addx用演算前 zero flag 値。 169 | * その他の場合は常に 1 を指定のこと。 170 | * 171 | * 【返値】 172 | * なし 173 | * 174 | */ 175 | 176 | void add_conditions(Long src, Long dest, Long result, int size, BOOL zero_flag) { 177 | 178 | int Sm, Dm, Rm; 179 | 180 | Sm = (getMSB(src, size) != (Long)0); 181 | Dm = (getMSB(dest, size) != (Long)0); 182 | Rm = (getMSB(result, size) != (Long)0); 183 | 184 | /* Overflow Flag */ 185 | if ((Sm && Dm && !Rm) || (!Sm && !Dm && Rm)) { 186 | CCR_V_ON(); 187 | } else { 188 | CCR_V_OFF(); 189 | } 190 | 191 | /* Carry Flag & Extend Flag */ 192 | if ((Sm && Dm) || (Dm && !Rm) || (Sm && !Rm)) { 193 | CCR_C_ON(); 194 | CCR_X_ON(); 195 | } else { 196 | CCR_C_OFF(); 197 | CCR_X_OFF(); 198 | } 199 | 200 | /* Zero Flag */ 201 | if (zero_flag && getBitsByDataSize(result, size) == 0) { 202 | CCR_Z_ON(); 203 | } else { 204 | CCR_Z_OFF(); 205 | } 206 | 207 | /* Negative Flag */ 208 | if (Rm != 0) { 209 | CCR_N_ON(); 210 | } else { 211 | CCR_N_OFF(); 212 | } 213 | } 214 | 215 | 216 | /* 217 | * 【説明】 218 | * cmp系コンディションフラグの設定 219 | * 220 | * 【関数書式】 221 | * cmp_conditions(src, dest, result, size, zero_flag); 222 | * 223 | * 【引数】 224 | * Long src; Source値 225 | * Long dest; Destination値 226 | * Long result; Result値 227 | * int size; アクセスサイズ 228 | * BOOL zero_flag; subx用演算前 zero flag 値。 229 | * その他の場合は常に 1 を指定のこと。 230 | * 231 | * 【返値】 232 | * なし 233 | * 234 | */ 235 | 236 | void cmp_conditions(Long src, Long dest, Long result, int size) { 237 | 238 | int Sm, Dm, Rm; 239 | 240 | Sm = (getMSB(src, size) != (Long)0); 241 | Dm = (getMSB(dest, size) != (Long)0); 242 | Rm = (getMSB(result, size) != (Long)0); 243 | 244 | /* Overflow Flag */ 245 | if ((!Sm && Dm && !Rm) || (Sm && !Dm && Rm)) { 246 | CCR_V_ON(); 247 | } else { 248 | CCR_V_OFF(); 249 | } 250 | 251 | /* Carry Flag & Extend Flag */ 252 | if ((Sm && !Dm) || (!Dm && Rm) || (Sm && Rm)) { 253 | CCR_C_ON(); 254 | } else { 255 | CCR_C_OFF(); 256 | } 257 | 258 | /* Zero Flag */ 259 | if (getBitsByDataSize(result, size) == 0) { 260 | CCR_Z_ON(); 261 | } else { 262 | CCR_Z_OFF(); 263 | } 264 | 265 | /* Negative Flag */ 266 | if (Rm != 0) { 267 | CCR_N_ON(); 268 | } else { 269 | CCR_N_OFF(); 270 | } 271 | } 272 | 273 | 274 | /* 275 | * 【説明】 276 | * sub系コンディションフラグの設定 277 | * 278 | * 【関数書式】 279 | * sub_conditions(src, dest, result, size, zero_flag); 280 | * 281 | * 【引数】 282 | * Long src; Source値 283 | * Long dest; Destination値 284 | * Long result; Result値 285 | * int size; アクセスサイズ 286 | * BOOL zero_flag; subx用演算前 zero flag 値。 287 | * その他の場合は常に 1 を指定のこと。 288 | * 289 | * 【返値】 290 | * なし 291 | * 292 | */ 293 | 294 | void sub_conditions(Long src, Long dest, Long result, int size, BOOL zero_flag) { 295 | 296 | cmp_conditions(src, dest, result, size); 297 | 298 | if (CCR_C_REF()) { 299 | CCR_X_ON(); 300 | } else { 301 | CCR_X_OFF(); 302 | } 303 | 304 | /* Zero Flag */ 305 | if ((zero_flag == 1) && (CCR_Z_REF() != 0)) { 306 | CCR_Z_ON(); 307 | } else { 308 | CCR_Z_OFF(); 309 | } 310 | 311 | } 312 | 313 | /* 314 | * 【説明】 315 | * neg系コンディションフラグの設定 316 | * 317 | * 【関数書式】 318 | * neg_conditions(dest, result, size, zero_flag); 319 | * 320 | * 【引数】 321 | * Long dest; Destination値 322 | * Long result; Result値 323 | * int size; アクセスサイズ 324 | * BOOL zero_flag; negx用演算前 zero flag 値。 325 | * その他の場合は常に 1 を指定のこと。 326 | * 327 | * 【返値】 328 | * なし 329 | * 330 | */ 331 | 332 | void neg_conditions(Long dest, Long result, int size, BOOL zero_flag) { 333 | 334 | int Dm, Rm; 335 | 336 | Dm = (getMSB(dest, size) != (Long)0); 337 | Rm = (getMSB(result, size) != (Long)0); 338 | 339 | /* Overflow Flag */ 340 | if (Dm && Rm) { 341 | CCR_V_ON(); 342 | } else { 343 | CCR_V_OFF(); 344 | } 345 | 346 | /* Carry Flag & Extend Flag */ 347 | if (Dm || Rm) { 348 | CCR_C_ON(); 349 | CCR_X_ON(); 350 | } else { 351 | CCR_C_OFF(); 352 | CCR_X_OFF(); 353 | } 354 | 355 | /* Zero Flag */ 356 | if (getBitsByDataSize(result, size) == 0) { 357 | CCR_Z_ON(); 358 | } else { 359 | CCR_Z_OFF(); 360 | } 361 | 362 | /* Negative Flag */ 363 | if (Rm != 0) { 364 | CCR_N_ON(); 365 | } else { 366 | CCR_N_OFF(); 367 | } 368 | } 369 | -------------------------------------------------------------------------------- /src/debugger.c: -------------------------------------------------------------------------------- 1 | /* $Id: debugger.c,v 1.2 2009-08-08 06:49:44 masamic Exp $*/ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:06 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.5 1999/12/23 08:07:58 yfujii 9 | * Help messages are changed. 10 | * 11 | * Revision 1.4 1999/12/07 12:40:12 yfujii 12 | * *** empty log message *** 13 | * 14 | * Revision 1.4 1999/12/01 13:53:48 yfujii 15 | * Help messages are modified. 16 | * 17 | * Revision 1.3 1999/11/29 06:16:47 yfujii 18 | * Disassemble and step command are implemented. 19 | * 20 | * Revision 1.2 1999/11/01 06:23:33 yfujii 21 | * Some debugging functions are introduced. 22 | * 23 | * Revision 1.1 1999/10/29 13:41:07 yfujii 24 | * Initial revision 25 | * 26 | */ 27 | 28 | #include "run68.h" 29 | 30 | /* デバッグモードのプロンプト */ 31 | #define PROMPT "(run68)" 32 | /* コマンドラインの最大文字列長 */ 33 | #define MAX_LINE 256 34 | 35 | static char *command_name[] = { 36 | "BREAK", /* ブレークポイントの設定 */ 37 | "CLEAR", /* ブレークポイントの解除 */ 38 | "CONT", /* 実行の継続 */ 39 | "DUMP", /* メモリをダンプする */ 40 | "HELP", /* 命令の実行履歴 */ 41 | "HISTORY", /* 命令の実行履歴 */ 42 | "LIST", /* ディスアセンブル */ 43 | "NEXT", /* STEPと同じ。ただし、サブルーチン呼出しはスキップ */ 44 | "QUIT", /* run68を終了する */ 45 | "REG", /* レジスタの内容を表示する */ 46 | "RUN", /* 環境を初期化してプログラム実行 */ 47 | "SET", /* メモリに値をセットする */ 48 | "STEP", /* 一命令分ステップ実行 */ 49 | "WATCHC" /* 命令ウォッチ */ 50 | }; 51 | 52 | /* prog_ptr_uは符号付きcharで不便なので、符号なしcharに変換しておく。*/ 53 | #define prog_ptr_u ((unsigned char *)prog_ptr) 54 | ULong stepcount; 55 | 56 | static RUN68_COMMAND analyze(const char *line, int *argc, char** argv); 57 | static short determine_string(const char *str); 58 | static void display_help(); 59 | static void display_history(int argc, char **argv); 60 | static void display_list(int argc, char **argv); 61 | static void run68_dump(int argc, char **argv); 62 | static void display_registers(); 63 | static void set_breakpoint(int argc, char **argv); 64 | static void clear_breakpoint(); 65 | static ULong get_stepcount(int argc, char **argv); 66 | extern char *disassemble(Long addr, Long* next_addr); 67 | static unsigned short watchcode(int argc, char **argv); 68 | 69 | 70 | /* 71 | 機能: 72 | run68をデバッグモードで起動すると、この関数が呼出される。 73 | パラメータ: 74 | BOOL running - アプリケーションプログラムの実行中はTRUEで 75 | 呼出される。 76 | 戻り値: 77 | COMMAND - 呼び側のコードで実行すべきコマンドを表している。 78 | */ 79 | RUN68_COMMAND debugger(BOOL running) 80 | { 81 | RUN68_COMMAND cmd; 82 | 83 | if (running) 84 | { 85 | Long naddr, addr = pc; 86 | char hex[64]; 87 | char *s = disassemble(addr, &naddr); 88 | unsigned short code; 89 | int j; 90 | 91 | /* まず全レジスタを表示し、*/ 92 | display_registers(); 93 | /* 1命令分、逆アセンブルして表示する。*/ 94 | sprintf(hex, "$%06X ", addr); 95 | if (addr == naddr) 96 | { 97 | /* ディスアセンブルできなかった */ 98 | naddr += 2; 99 | } 100 | while (addr < naddr) 101 | { 102 | char *p = hex + strlen(hex); 103 | code = (((unsigned short)prog_ptr_u[addr]) << 8) + (unsigned short)prog_ptr_u[addr + 1]; 104 | sprintf(p, "%04X ", code); 105 | addr += 2; 106 | } 107 | for (j = strlen(hex); j < 34; j ++) 108 | { 109 | hex[j] = ' '; 110 | } 111 | hex[j] = '\0'; 112 | if (s == NULL) 113 | { 114 | fprintf(stderr, "%s%s\n", hex, "????"); 115 | } else 116 | { 117 | fprintf(stderr, "%s%s\n", hex, s); 118 | } 119 | } else 120 | { 121 | stepcount = 0; 122 | } 123 | if (stepcount != 0) 124 | { 125 | stepcount --; 126 | cmd = RUN68_COMMAND_STEP; 127 | goto EndOfLoop; 128 | } 129 | /* コマンドループ */ 130 | while(TRUE) 131 | { 132 | char line[MAX_LINE]; 133 | char *argv[MAX_LINE]; 134 | int argc; 135 | fprintf(stderr, "%s", PROMPT); 136 | if (fgets(line, MAX_LINE, stdin) == NULL) 137 | { 138 | if (feof(stdin) || ferror(stdin)) 139 | { 140 | fputs("quit\n", stderr); 141 | cmd = RUN68_COMMAND_QUIT; 142 | goto EndOfLoop; 143 | } 144 | } 145 | cmd = analyze(line, &argc, argv); 146 | if (argc == 0) 147 | { 148 | continue; 149 | } 150 | switch(cmd) { 151 | case RUN68_COMMAND_BREAK: /* ブレークポイントの設定 */ 152 | set_breakpoint(argc, argv); 153 | break; 154 | case RUN68_COMMAND_CLEAR: /* ブレークポイントの解除 */ 155 | clear_breakpoint(); 156 | break; 157 | case RUN68_COMMAND_CONT: /* 実行の継続 */ 158 | if (!running) 159 | { 160 | fprintf(stderr, "Program is not running!\n"); 161 | break; 162 | } 163 | stepcount = get_stepcount(argc, argv); 164 | goto EndOfLoop; 165 | case RUN68_COMMAND_DUMP: /* メモリをダンプする */ 166 | run68_dump(argc, argv); 167 | break; 168 | case RUN68_COMMAND_HELP: /* デバッガのヘルプ */ 169 | display_help(); 170 | break; 171 | case RUN68_COMMAND_HISTORY: /* 命令の実行履歴 */ 172 | display_history(argc, argv); 173 | break; 174 | case RUN68_COMMAND_LIST: /* ディスアセンブル */ 175 | display_list(argc, argv); 176 | break; 177 | case RUN68_COMMAND_NEXT: /* STEPと同じ。ただし、サブルーチン呼出しはスキップ */ 178 | if (!running) 179 | { 180 | fprintf(stderr, "Program is not running!\n"); 181 | break; 182 | } 183 | goto EndOfLoop; 184 | case RUN68_COMMAND_QUIT: /* run68を終了する */ 185 | goto EndOfLoop; 186 | case RUN68_COMMAND_REG: /* レジスタの値を表示する */ 187 | display_registers(); 188 | break; 189 | case RUN68_COMMAND_RUN: /* 環境を初期化してプログラム実行 */ 190 | goto EndOfLoop; 191 | case RUN68_COMMAND_SET: /* メモリに値をセットする */ 192 | fprintf(stderr, "cmd:%s is not implemented yet.\n", argv[0]); 193 | break; 194 | case RUN68_COMMAND_STEP: /* 一命令分ステップ実行 */ 195 | if (!running) 196 | { 197 | fprintf(stderr, "Program is not running!\n"); 198 | break; 199 | } 200 | stepcount = get_stepcount(argc, argv); 201 | goto EndOfLoop; 202 | case RUN68_COMMAND_WATCHC: /* 命令ウォッチ */ 203 | cwatchpoint = watchcode(argc, argv); 204 | break; 205 | case RUN68_COMMAND_NULL: /* コマンドではない(移動禁止) */ 206 | fprintf(stderr, "cmd:%s is not a command.\n", argv[0]); 207 | break; 208 | case RUN68_COMMAND_ERROR: /* コマンドエラー(移動禁止) */ 209 | fprintf(stderr, "Command line error:\"%s\"\n", argv[0]); 210 | break; 211 | } 212 | } 213 | EndOfLoop: 214 | return cmd; 215 | } 216 | 217 | /* 218 | 機能: 219 | コマンドライン文字列を解析し、コマンドとその引き数を取り出す。 220 | パラメータ: 221 | const char* line コマンドライン文字列 222 | int* argc コマンドラインに含まれるトークン数 223 | char** argv トークンに分解された文字列の配列 224 | 戻り値: 225 | COMMAND コマンドの列挙値 226 | */ 227 | static RUN68_COMMAND analyze(const char *line, int *argc, char** argv) 228 | { 229 | static char cline[MAX_LINE*2]; 230 | unsigned int ac = 0, i; 231 | char *q = cline; 232 | 233 | *argc = 0; 234 | for (i = 0; i < strlen(line); i ++) 235 | { 236 | /* 空白文字を読み飛ばす。*/ 237 | const char *p = &line[i]; 238 | char c = toupper(*p++); 239 | if (c == ' ' || c == '\t') 240 | { 241 | continue; 242 | } else if ('A' <= c && c <= 'Z') 243 | { 244 | /* コマンド等の名前 */ 245 | argv[(*argc)++] = q; 246 | do { 247 | *q++ = c; 248 | c = toupper(*p++); 249 | } while('A' <= c && c <= 'Z' || '0' <= c && c <= '9' || c == '_'); 250 | *q++ = '\0'; 251 | i += strlen(argv[*argc - 1]); 252 | } else if ('0' <= c && c <= '9') 253 | { 254 | /* 10進数 */ 255 | argv[(*argc)++] = q; 256 | do { 257 | *(q++) = c; 258 | c = toupper(*p++); 259 | } while('0' <= c && c <= '9'); 260 | *q++ = '\0'; 261 | i += strlen(argv[*argc - 1]); 262 | } else if (c == '$' && 'A' <= toupper(*p) && toupper(*p) <= 'F' || '0' <= *p && *p <= '9') 263 | { 264 | /* 16進数は$記号を付ける。*/ 265 | argv[(*argc)++] = q; 266 | *q++ = c; 267 | c = toupper(*p++); 268 | do { 269 | *q++ = c; 270 | c = toupper(*p++); 271 | } while('A' <= c && c <= 'F' || '0' <= c && c <= '9'); 272 | *q++ = '\0'; 273 | i += strlen(argv[*argc - 1]); 274 | } 275 | } 276 | if (*argc == 0) 277 | { 278 | return RUN68_COMMAND_NULL; 279 | } else if ('A' <= argv[0][0] && argv[0][0] <= 'Z') 280 | { 281 | RUN68_COMMAND cmd; 282 | for (cmd = (RUN68_COMMAND)0; cmd < RUN68_COMMAND_NULL; cmd ++) 283 | { 284 | if (strcmp(argv[0], command_name[cmd]) == 0) 285 | { 286 | return cmd; 287 | } 288 | } 289 | return RUN68_COMMAND_ERROR; 290 | } else 291 | { 292 | return RUN68_COMMAND_ERROR; 293 | } 294 | } 295 | 296 | /* 文字列が名前か、10進数値か、16進数か、あるいは記号かを判定する。*/ 297 | static short determine_string(const char *str) 298 | { 299 | /* とりあえずいい加減な実装をする。*/ 300 | if ('A' <= str[0] && str[0] <= 'Z') 301 | { 302 | return 0; /* 名前 */ 303 | } else if ('0' <= str[0] && str[0] <= '9') 304 | { 305 | return 1; /* 10進数 */ 306 | } else if (str[0] == '$') 307 | { 308 | return 2; /* 16進数 */ 309 | } 310 | return 3; /* 記号 */ 311 | } 312 | 313 | static void display_help() 314 | { 315 | fprintf(stderr, " ============= run68 debugger commands =============\n"); 316 | fprintf(stderr, "break $adr - Set a breakpoint.\n"); 317 | fprintf(stderr, "clear - Clear the breakpoint.\n"); 318 | fprintf(stderr, "cont - Continue running.\n"); 319 | fprintf(stderr, "cont n - Continue running and stops after executing n instructions.\n"); 320 | fprintf(stderr, "dump $adr [n] - Dump memory (n bytes) from $adr.\n"); 321 | fprintf(stderr, "dump [n] - Dump memory (n bytes) continuously.\n"); 322 | fprintf(stderr, "help - Show this menu.\n"); 323 | fprintf(stderr, "history [n] - Show last n instructions executed.\n"); 324 | fprintf(stderr, "list $adr [n] - Disassemble from $adr.\n"); 325 | fprintf(stderr, "list [n] - Disassemble n instructions from current PC.\n"); 326 | fprintf(stderr, "quit - Quit from run68.\n"); 327 | fprintf(stderr, "reg - Display registers.\n"); 328 | fprintf(stderr, "run - Run Human68k program from the begining.\n"); 329 | fprintf(stderr, "step - Execute only one instruction.\n"); 330 | fprintf(stderr, "step n - Continue running with showing all registers\n"); 331 | fprintf(stderr, " and stops after executing n instructions.\n"); 332 | } 333 | 334 | static void run68_dump(int argc, char **argv) 335 | { 336 | static Long dump_addr = -1; 337 | static Long size = 32; 338 | Long sadr; 339 | int i, j; 340 | 341 | if (dump_addr == -1) 342 | { 343 | if (argc == 1) 344 | { 345 | fprintf(stderr, "run68-dump:You must specify $adr at least once.\n"); 346 | return; 347 | } 348 | } else 349 | { 350 | sadr = dump_addr; 351 | } 352 | if (2 <= argc) 353 | { 354 | if (determine_string(argv[1]) == 1) 355 | { 356 | sscanf(argv[1], "%d", &size); 357 | } else if (argc >= 2 && determine_string(argv[1]) == 2) 358 | { 359 | sscanf(&argv[1][1], "%x", &sadr); 360 | } else 361 | { 362 | fprintf(stderr, "run68-dump:Argument error.\n"); 363 | return; 364 | } 365 | if (argc == 3) 366 | { 367 | if (determine_string(argv[2]) == 1) 368 | { 369 | sscanf(argv[2], "%d", &size); 370 | } else 371 | { 372 | fprintf(stderr, "run68-dump:Argument error.\n"); 373 | return; 374 | } 375 | } 376 | } 377 | for (i = 0; i < size; i ++) 378 | { 379 | ULong d; 380 | d = (unsigned char)prog_ptr_u[sadr+i]; 381 | if (i % 16 == 0) 382 | { 383 | fprintf(stderr, "%06X:", sadr+i); 384 | } else if (i % 8 == 0) 385 | { 386 | fprintf(stderr, "-"); 387 | } else 388 | { 389 | fprintf(stderr, " "); 390 | } 391 | fprintf(stderr, "%02X", d); 392 | if (i % 16 == 15 || i == size - 1) 393 | { 394 | if (i % 16 != 15) 395 | { 396 | for (j = i % 16 + 1; j < 16; j ++) 397 | { 398 | fprintf(stderr, " "); 399 | } 400 | } 401 | fprintf(stderr, ":"); 402 | for (j = i & 0xfffffff0; j <= i; j ++) 403 | { 404 | d = (unsigned char)prog_ptr_u[sadr+j]; 405 | fprintf(stderr, "%c", (' ' <= d && d <= 0x7e) ? d : '.'); 406 | } 407 | fprintf(stderr, "\n"); 408 | } 409 | } 410 | dump_addr = sadr + size; 411 | } 412 | 413 | static void display_registers() 414 | { 415 | int i; 416 | fprintf(stderr, "D0-D7=%08X" , rd [ 0 ] ); 417 | for ( i = 1; i < 8; i++ ) { 418 | fprintf(stderr, ",%08X" , rd [ i ] ); 419 | } 420 | fprintf(stderr,"\n"); 421 | fprintf(stderr, "A0-A7=%08X" , ra [ 0 ] ); 422 | for ( i = 1; i < 8; i++ ) { 423 | fprintf(stderr, ",%08X" , ra [ i ] ); 424 | } 425 | fprintf(stderr,"\n"); 426 | fprintf(stderr, " PC=%08X SR=%04X\n" , pc, sr ); 427 | } 428 | 429 | static void set_breakpoint(int argc, char **argv) 430 | { 431 | if (argc < 2) 432 | { 433 | if (trap_pc == 0) 434 | { 435 | fprintf(stderr, "run68-break:No breakpoints set.\n"); 436 | } else 437 | { 438 | fprintf(stderr, "run68-break:Breakpoint is set to $%06X.\n", trap_pc); 439 | } 440 | return; 441 | } else if (determine_string(argv[1]) != 2) 442 | { 443 | fprintf(stderr, "run68-break:Address expression error.\n"); 444 | return; 445 | } 446 | sscanf(&argv[1][1], "%lx", &trap_pc); 447 | } 448 | 449 | static void clear_breakpoint() 450 | { 451 | trap_pc = 0; 452 | } 453 | 454 | static void display_history(int argc, char **argv) 455 | { 456 | int n = 0; 457 | if (argc == 1) 458 | { 459 | n = 10; 460 | }else if (determine_string(argv[1]) != 1) 461 | { 462 | fprintf(stderr, "run68-history:Argument error.\n"); 463 | } else 464 | { 465 | sscanf(argv[1], "%d", &n); 466 | } 467 | OPBuf_display(n); 468 | } 469 | 470 | static void display_list(int argc, char **argv) 471 | { 472 | static Long list_addr = 0; 473 | static Long old_pc = 0; 474 | Long addr, naddr; 475 | int i, j, n; 476 | 477 | n = 10; 478 | if (old_pc == 0) 479 | { 480 | old_pc = pc; 481 | } else if (old_pc != pc) 482 | { 483 | old_pc = pc; 484 | list_addr = 0; 485 | } 486 | if (list_addr == 0) 487 | { 488 | addr = pc; 489 | } else 490 | { 491 | addr = list_addr; 492 | } 493 | if (2 <= argc) 494 | { 495 | if (argc == 2 && determine_string(argv[1]) == 1) 496 | { 497 | sscanf(argv[1], "%d", &n); 498 | } else if (argc >= 2 && determine_string(argv[1]) == 2) 499 | { 500 | sscanf(&argv[1][1], "%x", &addr); 501 | } 502 | if (argc == 3 && determine_string(argv[2]) == 1) 503 | { 504 | sscanf(argv[2], "%d", &n); 505 | } 506 | } 507 | for (i = 0; i < n; i ++) 508 | { 509 | char *s = disassemble(addr, &naddr); 510 | char hex[64]; 511 | unsigned short code; 512 | 513 | sprintf(hex, "$%06X ", addr); 514 | if (addr == naddr) 515 | { 516 | /* ディスアセンブルできなかった */ 517 | naddr += 2; 518 | } 519 | while (addr < naddr) 520 | { 521 | char *p = hex + strlen(hex); 522 | code = (((unsigned short)prog_ptr_u[addr]) << 8) + (unsigned short)prog_ptr_u[addr + 1]; 523 | sprintf(p, "%04X ", code); 524 | addr += 2; 525 | } 526 | for (j = strlen(hex); j < 34; j ++) 527 | { 528 | hex[j] = ' '; 529 | } 530 | hex[j] = '\0'; 531 | if (s == NULL) 532 | { 533 | fprintf(stderr, "%s%s\n", hex, "????"); 534 | } else 535 | { 536 | fprintf(stderr, "%s%s\n", hex, s); 537 | } 538 | } 539 | list_addr = naddr; 540 | } 541 | 542 | static ULong get_stepcount(int argc, char **argv) 543 | { 544 | ULong count = 0; 545 | if (argc == 1) 546 | { 547 | return 0; 548 | } else if (determine_string(argv[1]) == 1) 549 | { 550 | sscanf(argv[1], "%lu", &count); 551 | } 552 | return count; 553 | } 554 | 555 | static unsigned short watchcode(int argc, char **argv) 556 | { 557 | unsigned short wcode; 558 | 559 | if (argc < 2) 560 | { 561 | fprintf(stderr, "run68-watchcode:Too few arguments.\n"); 562 | return 0x4afc; 563 | } else if (determine_string(argv[1]) != 2) 564 | { 565 | fprintf(stderr, "run68-watchcode:Instruction code expression error.\n"); 566 | return 0x4afc; 567 | } 568 | sscanf(&argv[1][1], "%hx", &wcode); 569 | return wcode; 570 | } 571 | -------------------------------------------------------------------------------- /src/eaaccess.c: -------------------------------------------------------------------------------- 1 | /* $Id: eaaccess.c,v 1.3 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.2 2009/08/05 14:44:33 masamic 6 | * Some Bug fix, and implemented some instruction 7 | * Following Modification contributed by TRAP. 8 | * 9 | * Fixed Bug: In disassemble.c, shift/rotate as{lr},ls{lr},ro{lr} alway show word size. 10 | * Modify: enable KEYSNS, register behaiviour of sub ea, Dn. 11 | * Add: Nbcd, Sbcd. 12 | * 13 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 14 | * First imported source code and docs 15 | * 16 | * Revision 1.6 2000/01/09 06:49:20 yfujii 17 | * Push/Pop instruction's word alignment is adjusted. 18 | * 19 | * Revision 1.3 1999/12/07 12:42:08 yfujii 20 | * *** empty log message *** 21 | * 22 | * Revision 1.3 1999/11/04 09:05:57 yfujii 23 | * Wrong addressing mode selection problem is fixed. 24 | * 25 | * Revision 1.1 1999/11/01 10:36:33 masamichi 26 | * Initial revision 27 | * 28 | * 29 | */ 30 | 31 | /* Get from / Set to Effective Address */ 32 | 33 | #include "run68.h" 34 | 35 | /* 36 | * 【説明】 37 | * 実効アドレスを取得する。 38 | * 39 | * 【関数書式】 40 | * retcode = get_ea(save_pc, AceptAdrMode, mode, reg, &data); 41 | * 42 | * 【引数】 43 | * Long save_pc; PC相対時の基準となるPC値 44 | * int AceptAdrMode; アドレッシングモード MD_?? 45 | * int mode; アドレッシングモード MD_?? 46 | * int reg; レジスタ番号またはアドレッシングモード MR_?? 47 | * Long *data; 取得するデータを格納する場所へのポインタ 48 | * 49 | * 【返値】 50 | * TURE: エラー 51 | * FALSE: 正常 52 | * 53 | */ 54 | 55 | BOOL get_ea(Long save_pc, int AceptAdrMode, int mode, int reg, Long *data) 56 | { 57 | short disp; 58 | Long idx; 59 | BOOL retcode = FALSE; 60 | 61 | /* 操作しやすいようにモードを統合 */ 62 | int gmode = (mode < 7) ? mode : (7 + reg); /* gmode = 0-11 */ 63 | 64 | /* AceptAdrMode で許されたアドレッシングモードでなければエラー */ 65 | 66 | if ((AceptAdrMode & (1 << gmode)) == 0) { 67 | 68 | err68a( "アドレッシングモードが異常です。", __FILE__, __LINE__ ); 69 | return TRUE; 70 | 71 | } 72 | 73 | /* アドレッシングモードに応じた処理 */ 74 | switch (gmode) { 75 | case EA_AI: 76 | *data = ra [ reg ]; 77 | break; 78 | case EA_AID: 79 | disp = (short)imi_get( S_WORD ); 80 | *data = ra [ reg ] + (int)disp; 81 | break; 82 | case EA_AIX: 83 | idx = idx_get(); 84 | *data = ra [ reg ] + idx; 85 | break; 86 | case EA_SRT: 87 | idx = imi_get( S_WORD ); 88 | if ( (idx & 0x8000) != 0 ) 89 | idx |= 0xFFFF0000; 90 | *data = idx; 91 | break; 92 | case EA_LNG: 93 | *data = imi_get( S_LONG ); 94 | break; 95 | case EA_PC: 96 | disp = (short)imi_get( S_WORD ); 97 | *data = save_pc + (int)disp; 98 | break; 99 | case EA_PCX: 100 | idx = idx_get(); 101 | *data = save_pc + idx; 102 | break; 103 | default: 104 | err68a( "アドレッシングモードが異常です。", __FILE__, __LINE__ ); 105 | retcode = TRUE; 106 | } 107 | return( retcode ); 108 | } 109 | 110 | /* Get Data at Effective Address */ 111 | 112 | /* 113 | * 【説明】 114 | * 実効アドレスで示された値を取得する。 115 | * 116 | * 【関数書式】 117 | * retcode = get_data_at_ea(AceptAdrMode, mode, reg, &data); 118 | * 119 | * 【引数】 120 | * int AceptAdrMode; 処理可能なアドレッシングモード群 EA_????* 121 | * int mode; アドレッシングモード MD_?? 122 | * int reg; レジスタ番号またはアドレッシングモード MR_?? 123 | * Long *data; 取得するデータを格納する場所へのポインタ 124 | * 125 | * 【返値】 126 | * TURE: エラー 127 | * FALSE: 正常 128 | * 129 | */ 130 | 131 | BOOL get_data_at_ea(int AceptAdrMode, int mode, int reg, int size, Long *data) 132 | { 133 | short disp; 134 | Long idx; 135 | BOOL retcode; 136 | int gmode; 137 | Long save_pc; 138 | 139 | save_pc = pc; 140 | retcode = FALSE; 141 | 142 | /* 操作しやすいようにモードを統合 */ 143 | gmode = mode < 7 ? mode : 7 + reg; /* gmode = 0-11 */ 144 | 145 | /* AceptAdrMode で許されたアドレッシングモードでなければエラー */ 146 | 147 | if ((AceptAdrMode & (1 << gmode)) == 0) { 148 | 149 | err68a( "アドレッシングモードが異常です。", __FILE__, __LINE__ ); 150 | retcode = TRUE; 151 | 152 | } else { 153 | 154 | /* アドレッシングモードに応じた処理 */ 155 | switch (gmode) { 156 | case EA_DD: 157 | switch( size ) { 158 | case S_BYTE: 159 | *data = (rd [ reg ] & 0xFF); 160 | break; 161 | case S_WORD: 162 | *data = (rd [ reg ] & 0xFFFF); 163 | break; 164 | case S_LONG: 165 | *data = rd [ reg ]; 166 | break; 167 | } 168 | break; 169 | case EA_AD: 170 | switch( size ) { 171 | case S_BYTE: 172 | *data = (ra [ reg ] & 0xFF); 173 | break; 174 | case S_WORD: 175 | *data = (ra [ reg ] & 0xFFFF); 176 | break; 177 | case S_LONG: 178 | *data = ra [ reg ]; 179 | break; 180 | } 181 | break; 182 | case EA_AI: 183 | *data = mem_get( ra [ reg ], (char)size ); 184 | break; 185 | case EA_AIPI: 186 | *data = mem_get( ra [ reg ], (char)size ); 187 | if ( reg == 7 && size == S_BYTE ) { 188 | /* システムスタックのポインタは常に偶数 */ 189 | inc_ra( (char)reg, (char)S_WORD ); 190 | } else { 191 | inc_ra( (char)reg, (char)size ); 192 | } 193 | break; 194 | case EA_AIPD: 195 | if ( reg == 7 && size == S_BYTE ) { 196 | /* システムスタックのポインタは常に偶数 */ 197 | dec_ra( (char)reg, (char)S_WORD ); 198 | } else { 199 | dec_ra( (char)reg, (char)size ); 200 | } 201 | *data = mem_get( ra [ reg ], (char)size ); 202 | break; 203 | case EA_AID: 204 | disp = (short)imi_get( S_WORD ); 205 | *data = mem_get( ra [ reg ] + disp, (char)size ); 206 | break; 207 | case EA_AIX: 208 | idx = idx_get(); 209 | *data = mem_get( ra [ reg ] + (int)idx, (char)size ); 210 | break; 211 | case EA_SRT: 212 | idx = imi_get( S_WORD ); 213 | if ( (idx & 0x8000) != 0 ) 214 | idx |= 0xFFFF0000; 215 | *data = mem_get( idx, (char)size ); 216 | break; 217 | case EA_LNG: 218 | idx = imi_get( S_LONG ); 219 | *data = mem_get( idx, (char)size ); 220 | break; 221 | case EA_PC: 222 | disp = (short)imi_get( S_WORD ); 223 | *data = mem_get( save_pc + disp, (char)size ); 224 | break; 225 | case EA_PCX: 226 | idx = idx_get(); 227 | *data = mem_get( save_pc + idx, (char)size ); 228 | break; 229 | case EA_IM: 230 | *data = imi_get( (char)size ); 231 | break; 232 | default: 233 | err68a( "アドレッシングモードが異常です。", __FILE__, __LINE__ ); 234 | retcode = TRUE; 235 | } 236 | } 237 | return( retcode ); 238 | } 239 | 240 | /* 241 | * 【説明】 242 | * 与えられたデータを実効アドレスで示された場所に設定する。 243 | * 244 | * 【関数書式】 245 | * retcode = set_data_at_ea(AceptAdrMode, mode, reg, data); 246 | * 247 | * 【引数】 248 | * int AceptAdrMode; 処理可能なアドレッシングモード群 EA_????* 249 | * int mode; アドレッシングモード MD_?? 250 | * int reg; レジスタ番号またはアドレッシングモード MR_?? 251 | * Long data; 設定するデータ 252 | * 253 | * 【返値】 254 | * TURE: エラー 255 | * FALSE: 正常 256 | * 257 | */ 258 | 259 | BOOL set_data_at_ea(int AceptAdrMode, int mode, int reg, int size, Long data) 260 | { 261 | short disp; 262 | Long idx; 263 | BOOL retcode; 264 | int gmode; 265 | Long save_pc; 266 | 267 | save_pc = pc; 268 | retcode = FALSE; 269 | 270 | /* 操作しやすいようにモードを統合 */ 271 | gmode = mode < 7 ? mode : 7 + reg; /* gmode = 0-11 */ 272 | 273 | /* AceptAdrMode で許されたアドレッシングモードでなければエラー */ 274 | 275 | if ((AceptAdrMode & (1 << gmode)) == 0) { 276 | 277 | err68a( "アドレッシングモードが異常です。", __FILE__, __LINE__ ); 278 | retcode = TRUE; 279 | 280 | } else { 281 | 282 | /* ディスティネーションのアドレッシングモードに応じた処理 */ 283 | switch( gmode ) { 284 | case EA_DD: 285 | switch( size ) { 286 | case S_BYTE: 287 | rd [ reg ] = ( rd [ reg ] & 0xFFFFFF00 ) | 288 | ( data & 0xFF); 289 | break; 290 | case S_WORD: 291 | rd [ reg ] = ( rd [ reg ] & 0xFFFF0000 ) | 292 | ( data & 0xFFFF); 293 | break; 294 | case S_LONG: 295 | rd [ reg ] = data; 296 | break; 297 | } 298 | break; 299 | case EA_AD: 300 | switch( size ) { 301 | case S_BYTE: 302 | ra [ reg ] = ( ra [ reg ] & 0xFFFFFF00 ) | 303 | ( data & 0xFF ); 304 | break; 305 | case S_WORD: 306 | ra [ reg ] = ( ra [ reg ] & 0xFFFF0000 ) | 307 | ( data & 0xFFFF ); 308 | break; 309 | case S_LONG: 310 | ra [ reg ] = data; 311 | break; 312 | } 313 | break; 314 | case EA_AI: 315 | mem_set( ra [ reg ], data, (char)size ); 316 | break; 317 | case EA_AIPI: 318 | mem_set( ra [ reg ], data, (char)size ); 319 | if ( reg == 7 && size == S_BYTE ) { 320 | /* システムスタックのポインタは常に偶数 */ 321 | inc_ra( (char)reg, (char)S_WORD ); 322 | } else { 323 | inc_ra ( (char)reg , (char)size ); 324 | } 325 | break; 326 | case EA_AIPD: 327 | if ( reg == 7 && size == S_BYTE ) { 328 | /* システムスタックのポインタは常に偶数 */ 329 | dec_ra( (char)reg, (char)S_WORD ); 330 | } else { 331 | dec_ra ( (char)reg , (char)size ); 332 | } 333 | 334 | mem_set( ra [ reg ], data, (char)size ); 335 | break; 336 | case EA_AID: 337 | disp = (short)imi_get( S_WORD ); 338 | mem_set( ra [ reg ] + (int)disp, data, (char)size ); 339 | break; 340 | case EA_AIX: 341 | idx = idx_get(); 342 | mem_set( ra [ reg ] + idx, data, (char)size ); 343 | break; 344 | case EA_SRT: 345 | idx = imi_get( S_WORD ); 346 | if ( (idx & 0x8000) != 0 ) 347 | idx |= 0xFFFF0000; 348 | mem_set( idx, data, (char)size ); 349 | break; 350 | case EA_LNG: 351 | idx = imi_get( S_LONG ); 352 | mem_set( idx, data, (char)size ); 353 | break; 354 | case EA_PC: 355 | disp = (short)imi_get( S_WORD ); 356 | mem_set( save_pc + (int)disp, data, (char)size ); 357 | break; 358 | case EA_PCX: 359 | idx = idx_get(); 360 | mem_set( save_pc + idx, data, (char)size ); 361 | break; 362 | default: 363 | err68a( "アドレッシングモードが異常です。", __FILE__, __LINE__ ); 364 | retcode = TRUE; 365 | } 366 | } 367 | 368 | return( retcode ); 369 | } 370 | 371 | /* 372 | * 【説明】 373 | * 実効アドレスで示された値を取得する。 374 | * この時、PCを移動させない。 375 | * 376 | * 【関数書式】 377 | * retcode = get_data_at_ea_noinc(AceptAdrMode, mode, reg, &data); 378 | * 379 | * 【引数】 380 | * int AceptAdrMode; 処理可能なアドレッシングモード群 EA_????* 381 | * int mode; アドレッシングモード MD_?? 382 | * int reg; レジスタ番号またはアドレッシングモード MR_?? 383 | * Long *data; 取得するデータを格納する場所へのポインタ 384 | * 385 | * 【返値】 386 | * TURE: エラー 387 | * FALSE: 正常 388 | * 389 | */ 390 | 391 | BOOL get_data_at_ea_noinc(int AceptAdrMode, int mode, int reg, int size, Long *data) 392 | { 393 | Long save_pc; 394 | BOOL retcode; 395 | 396 | save_pc = pc; 397 | retcode = get_data_at_ea(AceptAdrMode, mode, reg, size, data); 398 | pc = save_pc; 399 | 400 | return(retcode); 401 | } 402 | -------------------------------------------------------------------------------- /src/exec.c: -------------------------------------------------------------------------------- 1 | /* $Id: exec.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.9 1999/12/07 12:42:21 yfujii 9 | * *** empty log message *** 10 | * 11 | * Revision 1.9 1999/11/29 06:22:21 yfujii 12 | * The way of recording instruction history is changed. 13 | * 14 | * Revision 1.8 1999/11/01 06:23:33 yfujii 15 | * Some debugging functions are introduced. 16 | * 17 | * Revision 1.7 1999/10/28 06:34:08 masamichi 18 | * Modified trace behavior 19 | * 20 | * Revision 1.6 1999/10/26 02:12:07 yfujii 21 | * Fixed a bug of displaying code in the wrong byte order. 22 | * 23 | * Revision 1.5 1999/10/26 01:31:54 yfujii 24 | * Execution history and address trap is added. 25 | * 26 | * Revision 1.4 1999/10/22 03:23:18 yfujii 27 | * #include is removed. 28 | * 29 | * Revision 1.3 1999/10/20 02:43:59 masamichi 30 | * Add for showing more information about errors. 31 | * 32 | * Revision 1.2 1999/10/18 03:24:40 yfujii 33 | * Added RCS keywords and modified for WIN32 a little. 34 | * 35 | */ 36 | 37 | #undef MAIN 38 | 39 | #include 40 | #include 41 | #include "run68.h" 42 | #if defined(DOSX) 43 | #include 44 | #endif 45 | 46 | /* prog_ptr_uは符号付きcharで不便なので、符号なしcharに変換しておく。*/ 47 | #define prog_ptr_u ((unsigned char *)prog_ptr) 48 | void run68_abort( Long ); 49 | extern char *disassemble(Long addr, Long* next_addr); 50 | 51 | /* 52 |  機能:1命令実行する 53 | 戻り値: TRUE = 実行終了 54 | FALSE = 実行継続 55 | */ 56 | int prog_exec() 57 | { 58 | char *pc_ptr; 59 | Long adr; 60 | short save_s; 61 | 62 | /* 上位4ビットで命令を振り分ける */ 63 | pc_ptr = prog_ptr + pc; 64 | switch( *pc_ptr & 0xF0 ) { 65 | case 0x00: 66 | return( line0( pc_ptr ) ); 67 | case 0x10: 68 | case 0x20: 69 | case 0x30: 70 | return( line2( pc_ptr ) ); 71 | case 0x40: 72 | return( line4( pc_ptr ) ); 73 | case 0x50: 74 | return( line5( pc_ptr ) ); 75 | case 0x60: 76 | return( line6( pc_ptr ) ); 77 | case 0x70: 78 | return( line7( pc_ptr ) ); 79 | case 0x80: 80 | return( line8( pc_ptr ) ); 81 | case 0x90: 82 | return( line9( pc_ptr ) ); 83 | case 0xB0: 84 | return( lineb( pc_ptr ) ); 85 | case 0xC0: 86 | return( linec( pc_ptr ) ); 87 | case 0xD0: 88 | return( lined( pc_ptr ) ); 89 | case 0xE0: 90 | return( linee( pc_ptr ) ); 91 | case 0xF0: 92 | return( linef( pc_ptr ) ); 93 | case 0xA0: 94 | save_s = SR_S_REF(); 95 | SR_S_ON(); 96 | adr = mem_get( 0x28, S_LONG ); 97 | if ( adr != HUMAN_WORK ) { 98 | ra [ 7 ] -= 4; 99 | mem_set( ra [ 7 ], pc, S_LONG ); 100 | ra [ 7 ] -= 2; 101 | mem_set( ra [ 7 ], sr, S_WORD ); 102 | pc = adr; 103 | return( FALSE ); 104 | } 105 | if ( save_s == 0 ) 106 | SR_S_OFF(); 107 | pc += 2; 108 | err68( "A系列割り込みを実行しました" ); 109 | return( TRUE ); 110 | default: 111 | pc += 2; 112 | err68( "おかしな命令を実行しました" ); 113 | return( TRUE ); 114 | } 115 | } 116 | 117 | /* 118 |  機能:コンディションが成立しているかどうか調べる 119 | 戻り値: TRUE = 成立 120 |     FALSE = 不成立 121 | */ 122 | int get_cond( char cond ) 123 | { 124 | switch( cond ) { 125 | case 0x00: /* t */ 126 | return( TRUE ); 127 | case 0x02: /* hi */ 128 | if ( CCR_C_REF() == 0 && CCR_Z_REF() == 0 ) 129 | return( TRUE ); 130 | break; 131 | case 0x03: /* ls */ 132 | if ( CCR_C_REF() != 0 || CCR_Z_REF() != 0 ) 133 | return( TRUE ); 134 | break; 135 | case 0x04: /* cc */ 136 | if ( CCR_C_REF() == 0 ) 137 | return( TRUE ); 138 | break; 139 | case 0x05: /* cs */ 140 | if ( CCR_C_REF() != 0 ) 141 | return( TRUE ); 142 | break; 143 | case 0x06: /* ne */ 144 | if ( CCR_Z_REF() == 0 ) 145 | return( TRUE ); 146 | break; 147 | case 0x07: /* eq */ 148 | if ( CCR_Z_REF() != 0 ) 149 | return( TRUE ); 150 | break; 151 | case 0x08: /* vc */ 152 | if ( CCR_V_REF() == 0 ) 153 | return( TRUE ); 154 | break; 155 | case 0x09: /* vs */ 156 | if ( CCR_V_REF() != 0 ) 157 | return( TRUE ); 158 | break; 159 | case 0x0A: /* pl */ 160 | if ( CCR_N_REF() == 0 ) 161 | return( TRUE ); 162 | break; 163 | case 0x0B: /* mi */ 164 | if ( CCR_N_REF() != 0 ) 165 | return( TRUE ); 166 | break; 167 | case 0x0C: /* ge */ 168 | if ( (CCR_N_REF() != 0 && CCR_V_REF() != 0) || 169 | (CCR_N_REF() == 0 && CCR_V_REF() == 0) ) 170 | return( TRUE ); 171 | break; 172 | case 0x0D: /* lt */ 173 | if ( (CCR_N_REF() != 0 && CCR_V_REF() == 0) || 174 | (CCR_N_REF() == 0 && CCR_V_REF() != 0) ) 175 | return( TRUE ); 176 | break; 177 | case 0x0E: /* gt */ 178 | if ( CCR_Z_REF() == 0 && 179 | ( (CCR_N_REF() != 0 && CCR_V_REF() != 0) || 180 | (CCR_N_REF() == 0 && CCR_V_REF() == 0) ) ) 181 | return( TRUE ); 182 | break; 183 | case 0x0F: /* le */ 184 | if ( CCR_Z_REF() != 0 || 185 | (CCR_N_REF() != 0 && CCR_V_REF() == 0) || 186 | (CCR_N_REF() == 0 && CCR_V_REF() != 0) ) 187 | return( TRUE ); 188 | break; 189 | } 190 | 191 | return( FALSE ); 192 | } 193 | 194 | /* 195 |  機能:実行時エラーメッセージを表示する 196 | 戻り値:なし 197 | */ 198 | void err68( char *mes ) 199 | { 200 | OPBuf_insert(&OP_info); 201 | fprintf(stderr, "run68 exec error: %s PC=%06X\n", mes, pc); 202 | if ( memcmp( mes, "未定義", 6 ) == 0 ) 203 | fprintf(stderr, "code = %08X\n",mem_get( pc - 4, S_LONG )); 204 | OPBuf_display(10); 205 | run68_abort(pc); 206 | } 207 | 208 | /* 209 |  機能:実行時エラーメッセージを表示する(その2) 210 | 引数: 211 | char* mes メッセージ 212 | char* file ファイル名 213 | int line 行番号 214 | 戻り値:なし 215 | */ 216 | void err68a( char *mes, char *file, int line ) 217 | { 218 | OPBuf_insert(&OP_info); 219 | fprintf(stderr, "run68 exec error: %s PC=%06X\n", mes, pc); 220 | fprintf(stderr, "\tAt %s:%d\n", file, line); 221 | if ( memcmp( mes, "未定義", 6 ) == 0 ) 222 | fprintf(stderr, "code = %08X\n",mem_get( pc - 4, S_LONG )); 223 | OPBuf_display(10); 224 | run68_abort(pc); 225 | } 226 | 227 | /* 228 | 機能:実行時エラーメッセージを表示する(その3) 229 | 引数: 230 | char* mes メッセージ 231 | Long pc プログラムカウンタ 232 | Long ppc 一つ前に実行した命令のプログラムカウンタ 233 | 戻り値: 234 | なし 235 | */ 236 | void err68b(char *mes, Long pc, Long ppc) 237 | { 238 | OPBuf_insert(&OP_info); 239 | fprintf(stderr, "run68 exec error: %s PC=%06X\n", mes, pc); 240 | fprintf(stderr, "PC of previous op code: PC=%06X\n", ppc); 241 | if ( memcmp( mes, "未定義", 6 ) == 0 ) 242 | fprintf(stderr, "code = %08X\n",mem_get( pc - 4, S_LONG )); 243 | OPBuf_display(10); 244 | run68_abort(pc); 245 | } 246 | 247 | /* 248 |  機能:アドレスレジスタをインクリメントする 249 | 戻り値:なし 250 | */ 251 | void inc_ra( char reg, char size ) 252 | { 253 | if ( reg == 7 && size == S_BYTE ) { 254 | ra [ 7 ] += 2; 255 | } else { 256 | switch( size ) { 257 | case S_BYTE: 258 | ra [ reg ] += 1; 259 | break; 260 | case S_WORD: 261 | ra [ reg ] += 2; 262 | break; 263 | default: /* S_LONG */ 264 | ra [ reg ] += 4; 265 | break; 266 | } 267 | } 268 | } 269 | 270 | /* 271 |  機能:アドレスレジスタをデクリメントする 272 | 戻り値:なし 273 | */ 274 | void dec_ra( char reg, char size ) 275 | { 276 | if ( reg == 7 && size == S_BYTE ) { 277 | ra [ 7 ] -= 2; 278 | } else { 279 | switch( size ) { 280 | case S_BYTE: 281 | ra [ reg ] -= 1; 282 | break; 283 | case S_WORD: 284 | ra [ reg ] -= 2; 285 | break; 286 | default: /* S_LONG */ 287 | ra [ reg ] -= 4; 288 | break; 289 | } 290 | } 291 | } 292 | 293 | /* 294 |  機能:テキストカラーを設定する 295 | 戻り値:なし 296 | */ 297 | void text_color( short c ) 298 | { 299 | switch( c ) { 300 | case 0: 301 | printf("%c[0;30m", 0x1B ); 302 | break; 303 | case 1: 304 | printf("%c[0;36m", 0x1B ); 305 | break; 306 | case 2: 307 | printf("%c[0;33m", 0x1B ); 308 | break; 309 | case 3: 310 | printf("%c[0;37m", 0x1B ); 311 | break; 312 | case 4: 313 | printf("%c[0;1;30m", 0x1B ); 314 | break; 315 | case 5: 316 | printf("%c[0;1;36m", 0x1B ); 317 | break; 318 | case 6: 319 | printf("%c[0;1;33m", 0x1B ); 320 | break; 321 | case 7: 322 | printf("%c[0;1;37m", 0x1B ); 323 | break; 324 | case 8: 325 | printf("%c[0;30;40m", 0x1B ); 326 | break; 327 | case 9: 328 | printf("%c[0;30;46m", 0x1B ); 329 | break; 330 | case 10: 331 | printf("%c[0;30;43m", 0x1B ); 332 | break; 333 | case 11: 334 | printf("%c[0;30;47m", 0x1B ); 335 | break; 336 | case 12: 337 | printf("%c[0;30;1;40m", 0x1B ); 338 | break; 339 | case 13: 340 | printf("%c[0;30;1;46m", 0x1B ); 341 | break; 342 | case 14: 343 | printf("%c[0;30;1;43m", 0x1B ); 344 | break; 345 | case 15: 346 | printf("%c[0;30;1;47m", 0x1B ); 347 | break; 348 | } 349 | } 350 | 351 | /* 352 | 機能:カーソル位置を得る 353 | 戻り値:カーソル位置 354 | */ 355 | Long get_locate() 356 | { 357 | UShort x = 0, y = 0; 358 | 359 | #if defined(WIN32) 360 | // @Todo 361 | #elif defined(DOSX) 362 | union REGS inreg, outreg; 363 | short save_s; 364 | 365 | fflush( stdout ); 366 | inreg.h.ah = 0x03; 367 | inreg.h.bh = 0; 368 | int86( 0x10, &inreg, &outreg ); 369 | x = outreg.h.dl; 370 | y = outreg.h.dh; 371 | save_s = SR_S_REF(); 372 | SR_S_ON(); 373 | mem_set( 0x974, x, S_WORD ); 374 | mem_set( 0x976, y, S_WORD ); 375 | if ( save_s == 0 ) 376 | SR_S_OFF(); 377 | #endif 378 | 379 | return( (x << 16) | y ); 380 | } 381 | 382 | /* 383 | 命令情報リングバッファの作業領域 384 | */ 385 | #define MAX_OPBUF 200 386 | static int num_entries; 387 | static int current_p; 388 | static EXEC_INSTRUCTION_INFO entry[MAX_OPBUF]; 389 | /* 390 | 機能: 391 | 実行した命令の情報をリングバッファに保存する。 392 | パラメータ: 393 | EXEC_INSTRUCTION_INFO op 命令情報 394 | 戻り値: 395 | なし。 396 | */ 397 | void OPBuf_insert(const EXEC_INSTRUCTION_INFO *op) 398 | { 399 | if (num_entries < MAX_OPBUF) 400 | { 401 | num_entries ++; 402 | } 403 | entry[current_p++] = *op; 404 | if (MAX_OPBUF == current_p) 405 | { 406 | current_p = 0; 407 | } 408 | } 409 | 410 | /* 411 | 機能: 412 | 命令情報リングバッファをクリアする。 413 | パラメータ; 414 | なし。 415 | 戻り値: 416 | なし。 417 | */ 418 | void OPBuf_clear() 419 | { 420 | num_entries = 0; 421 | current_p = 0; 422 | } 423 | 424 | /* 425 | 機能: 426 | 命令情報リングバッファのサイズを取得する。 427 | パラメータ: 428 | なし。 429 | 戻り値: 430 | int バッファのエントリ数 431 | */ 432 | int OPBuf_numentries() 433 | { 434 | return num_entries; 435 | } 436 | 437 | /* 438 | 機能: 439 | 命令情報リングバッファのno番目のエントリを取得する。 440 | パラメータ: 441 | int no 取り出したいエントリ番号(0が最近のもの) 442 | 戻り値: 443 | EXEC_INSTRUCTION_INFO* 命令情報へのポインタ 444 | */ 445 | const EXEC_INSTRUCTION_INFO *OPBuf_getentry(int no) 446 | { 447 | int p; 448 | if (no < 0 || num_entries <= no) 449 | return NULL; 450 | p = current_p - no - 1; 451 | if (p < 0) 452 | { 453 | p += MAX_OPBUF; 454 | } 455 | return &entry[p]; 456 | } 457 | 458 | /* 459 | 機能: 460 | 命令情報リングバッファの内容を出力する。 461 | パラメータ: 462 | int n 表示するバッファのエントリ数 463 | 戻り値: 464 | なし。 465 | */ 466 | void OPBuf_display(int n) 467 | { 468 | int max = OPBuf_numentries(); 469 | int i; 470 | if (max < n) 471 | n = max; 472 | fprintf(stderr, "** EXECUTED INSTRUCTION HISTORY **\n"); 473 | fprintf(stderr, "ADDRESS OPCODE MNEMONIC\n"); 474 | fprintf(stderr, "-------------------------------------------------------\n"); 475 | for (i = n-1; 0 <= i; i --) 476 | { 477 | const EXEC_INSTRUCTION_INFO *op; 478 | Long addr, naddr; 479 | char *s, hex[64]; 480 | unsigned short code; 481 | int j; 482 | 483 | op = OPBuf_getentry(i); 484 | addr = op->pc; 485 | s = disassemble(addr, &naddr); 486 | sprintf(hex, "$%06X ", addr); 487 | while (addr < naddr) 488 | { 489 | char *p = hex + strlen(hex); 490 | code = (((unsigned short)prog_ptr_u[addr]) << 8) + (unsigned short)prog_ptr_u[addr + 1]; 491 | sprintf(p, "%04X ", code); 492 | addr += 2; 493 | } 494 | for (j = strlen(hex); j < 34; j ++) 495 | { 496 | hex[j] = ' '; 497 | } 498 | hex[j] = '\0'; 499 | if (s == NULL) 500 | { 501 | fprintf(stderr, "%s%s\n", hex, "????"); 502 | } else 503 | { 504 | fprintf(stderr, "%s%s\n", hex, s); 505 | } 506 | } 507 | } 508 | 509 | /* 510 |  機能:PCの指すメモリからインデックスレジスタ+8ビットディスプレースメント 511 |     の値を得る 512 | 戻り値:その値 513 | */ 514 | int get_idx(int *pc, char *regstr) 515 | { 516 | char *mem; 517 | char idx2; 518 | char idx_reg; 519 | 520 | mem = prog_ptr + (*pc); 521 | 522 | idx2 = *(mem++); 523 | idx_reg = ((idx2 >> 4) & 0x07); 524 | if ( (idx2 & 0x80) == 0 ) { 525 | sprintf(regstr, "d%d", idx_reg); 526 | } else { 527 | sprintf(regstr, "d%d", idx_reg); 528 | } 529 | if ( (idx2 & 0x08) == 0 ) { /* WORD */ 530 | strcat(regstr, ".w"); 531 | } else { 532 | strcat(regstr, ".l"); 533 | } 534 | (*pc) += 2; 535 | 536 | return ((int)(*mem)); 537 | } 538 | 539 | /* 540 |  機能:PCの指すメモリから指定されたサイズのイミディエイトデータをゲットし、 541 |     サイズに応じてPCを進める 542 | 戻り値:データの値 543 | */ 544 | Long get_imi(int *pc, char size ) 545 | { 546 | UChar *mem; 547 | Long d; 548 | 549 | mem = (UChar *)prog_ptr + (*pc); 550 | 551 | 552 | switch( size ) { 553 | case S_BYTE: 554 | (*pc) += 2; 555 | return( *(mem + 1) ); 556 | case S_WORD: 557 | (*pc) += 2; 558 | d = *(mem++); 559 | d = ((d << 8) | *mem); 560 | return( d ); 561 | default: /* S_LONG */ 562 | (*pc) += 4; 563 | d = *(mem++); 564 | d = ((d << 8) | *(mem++)); 565 | d = ((d << 8) | *(mem++)); 566 | d = ((d << 8) | *mem); 567 | return( d ); 568 | } 569 | } 570 | 571 | /* 572 | 機能: 573 | オペランド文字列を生成する。 574 | パラメータ: 575 | char *buf 生成した文字列を格納する。 576 | int AddressingMode アドレッシングモード 577 | int RegisterNumber レジスタ番号(またはアドレッシングモード) 578 | char *pc 拡張部取得用プログラムカウンタ 579 | 戻り値: 580 | なし。 581 | */ 582 | 583 | void get_operand(char *buf, int *pc, int AddressingMode, int RegisterNumber, int size) 584 | { 585 | char regstr[16]; 586 | int disp; 587 | 588 | switch (AddressingMode) { 589 | case 0: 590 | sprintf(buf, "d%d", RegisterNumber); 591 | break; 592 | case 1: 593 | sprintf(buf, "a%d", RegisterNumber); 594 | break; 595 | case 2: 596 | sprintf(buf, "(a%d)", RegisterNumber); 597 | break; 598 | case 3: 599 | sprintf(buf, "(a%d)+", RegisterNumber); 600 | break; 601 | case 4: 602 | sprintf(buf, "-(a%d)", RegisterNumber); 603 | break; 604 | case 5: 605 | disp = get_imi(pc, S_WORD); 606 | sprintf(buf, "$%04x(a%d)", disp, RegisterNumber); 607 | break; 608 | case 6: 609 | disp = get_idx(pc, regstr); 610 | sprintf(buf, "%d(a%d,%s)", disp, RegisterNumber, regstr); 611 | break; 612 | case 7: 613 | switch( RegisterNumber ) { 614 | case 0: 615 | disp = get_imi(pc, S_WORD); 616 | sprintf(buf, "$%04x", disp); 617 | break; 618 | case 1: 619 | disp = get_imi(pc, S_LONG); 620 | sprintf(buf, "$%08x", disp); 621 | break; 622 | case 2: 623 | disp = get_imi(pc, S_WORD); 624 | sprintf(buf, "$%04x(pc)", disp); 625 | break; 626 | case 3: 627 | disp = get_idx(pc, regstr); 628 | sprintf(buf, "%d(pc,%s)", disp, regstr); 629 | break; 630 | case 4: 631 | disp = get_imi(pc, size); 632 | switch (size) { 633 | case S_BYTE: 634 | sprintf(buf, "#$%02x", disp); 635 | break; 636 | case S_WORD: 637 | sprintf(buf, "#$%04x", disp); 638 | break; 639 | case S_LONG: 640 | sprintf(buf, "#$%08x", disp); 641 | break; 642 | default: 643 | strcpy(buf, "????????"); 644 | } 645 | break; 646 | default: 647 | strcpy(buf, "????????"); 648 | } 649 | break; 650 | } 651 | } 652 | 653 | -------------------------------------------------------------------------------- /src/getini.c: -------------------------------------------------------------------------------- 1 | /* $Id: getini.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.5 1999/12/07 12:42:44 yfujii 9 | * *** empty log message *** 10 | * 11 | * Revision 1.5 1999/12/01 04:02:55 yfujii 12 | * .ini file is now retrieved from the same dir as the run68.exe file. 13 | * 14 | * Revision 1.4 1999/10/26 12:26:08 yfujii 15 | * Environment variable function is drasticaly modified. 16 | * 17 | * Revision 1.3 1999/10/22 11:06:22 yfujii 18 | * Expanded emulation memory from 9M to 12M. 19 | * 20 | * Revision 1.2 1999/10/18 03:24:40 yfujii 21 | * Added RCS keywords and modified for WIN32 a little. 22 | * 23 | */ 24 | 25 | #undef MAIN 26 | 27 | #include 28 | #include 29 | #include "run68.h" 30 | 31 | /* 文字列末尾の CR LF を \0 で上書きすることで除去 */ 32 | static void chomp(char *buf) 33 | { 34 | while (strlen(buf) != 0 && (buf[strlen(buf)-1] == '\r' || buf[strlen(buf)-1] == '\n')) { 35 | buf[strlen(buf)-1] = '\0'; 36 | } 37 | } 38 | 39 | void read_ini(char *path, char *prog) 40 | { 41 | char dir[1024] = {0}; 42 | char buf[1024] = {0}; 43 | char sec_name[MAX_PATH]; 44 | FILE *fp; 45 | int flag = TRUE; 46 | int i; 47 | int c; 48 | char *p; 49 | long l; 50 | 51 | /* 情報構造体の初期化 */ 52 | ini_info.env_lower = FALSE; 53 | ini_info.trap_emulate = FALSE; 54 | ini_info.pc98_key = FALSE; 55 | ini_info.io_through = FALSE; 56 | mem_aloc = 0x100000; 57 | 58 | /* INIファイルのフルパス名を得る。*/ 59 | /* まずはファイル名を取得する。*/ 60 | if ((p = strrchr(path, '\\')) != NULL) 61 | { 62 | memcpy(dir, path, p - path + 1); 63 | strcpy(buf, p+1); 64 | } else if ((p = strrchr(path, '/')) != NULL) 65 | { 66 | memcpy(dir, path, p - path + 1); 67 | strcpy(buf, p+1); 68 | } else if ((p = strrchr(path, ':')) != NULL) 69 | { 70 | memcpy(dir, path, p - path + 1); 71 | strcpy(buf, p+1); 72 | } else 73 | { 74 | strcpy(buf, path); 75 | } 76 | /* 拡張子.exeを.iniに置き換える。*/ 77 | if ((p = strrchr(buf, '.')) == NULL) 78 | { 79 | /* 拡張子がついていない時は単に付加する。*/ 80 | strcat(buf, ".ini"); 81 | } else if (_stricmp(p, ".exe") == 0) 82 | { 83 | strcpy(p, ".ini"); 84 | } else 85 | { 86 | return; /* .exe以外の拡張子はないと思う。*/ 87 | } 88 | /* ディレクトリ名とファイル名を結合する。*/ 89 | snprintf(path, MAX_PATH, "%s%s", dir, buf); 90 | #if defined(_DEBUG) 91 | printf("INI:%s\n", path); 92 | #endif 93 | /* フルパス名を使ってファイルをオープンする。*/ 94 | if ( (fp=fopen(path, "r")) == NULL ) 95 | return; 96 | /* プログラム名を得る */ 97 | for( i = strlen( prog ) - 1; i >= 0; i-- ) { 98 | if ( prog [ i ] == '\\' || prog [ i ] == '/' || prog [ i ] == ':' ) 99 | break; 100 | } 101 | i ++; 102 | if ( strlen( &(prog [ i ]) ) > 22 ) { 103 | fclose(fp); 104 | return; 105 | } 106 | sprintf( sec_name, "[%s]", &(prog [ i ]) ); 107 | _strlwr( sec_name ); 108 | /* 内容を調べる */ 109 | while( fgets(buf, 1023, fp) != NULL ) { 110 | _strlwr(buf); 111 | chomp(buf); 112 | 113 | /* セクションを見る */ 114 | if ( buf[ 0 ] == '[' ) { 115 | flag = FALSE; 116 | if ( _stricmp( buf, "[all]" ) == 0 ) 117 | flag = TRUE; 118 | else if ( _stricmp( buf, sec_name ) == 0 ) 119 | flag = TRUE; 120 | continue; 121 | } 122 | 123 | /* キーワードを見る */ 124 | if (flag == TRUE) 125 | { 126 | if ( _stricmp( buf, "envlower" ) == 0 ) 127 | ini_info.env_lower = TRUE; 128 | else if ( _stricmp( buf, "trapemulate" ) == 0 ) 129 | ini_info.trap_emulate = TRUE; 130 | else if ( _stricmp( buf, "pc98" ) == 0 ) 131 | ini_info.pc98_key = TRUE; 132 | else if ( _stricmp( buf, "iothrough" ) == 0 ) 133 | ini_info.io_through = TRUE; 134 | else if ( strncmp( buf, "mainmemory=", 11 ) == 0 ) { 135 | if (strlen(buf) < 12 || 13 < strlen(buf)) 136 | continue; 137 | if ('0' <= buf[11] && buf[11] <= '9') 138 | { 139 | c = buf[11] - '0'; 140 | if (strlen(buf) == 13 && '0' <= buf[12] && buf[12] <= '9') 141 | { 142 | c = c*10 + buf[11] - '0'; 143 | } else { 144 | continue; 145 | } 146 | } else { 147 | continue; 148 | } 149 | if ( 1 <= c && c <= 12 ) 150 | mem_aloc = 0x100000 * c; 151 | } 152 | } 153 | } 154 | fclose( fp ); 155 | } 156 | 157 | /* run68.iniファイルから環境変数の初期値を取得する。*/ 158 | void readenv_from_ini(char *path) 159 | { 160 | char buf [ 1024 ]; 161 | FILE *fp; 162 | int len; 163 | char *mem_ptr; /* メモリ管理ブロック */ 164 | char *read_ptr; 165 | int env_len = 0; /* 環境の長さ */ 166 | BOOL env_flag; 167 | 168 | /* INIファイルの名前(パス含む)を得る */ 169 | strcpy( buf, path ); 170 | if ( (len=strlen( buf )) < 4 ) 171 | return; 172 | buf [ len - 3 ] = 'i'; 173 | buf [ len - 2 ] = 'n'; 174 | buf [ len - 1 ] = 'i'; 175 | if ( (fp=fopen( buf, "r" )) == NULL ) 176 | return; 177 | 178 | /* 環境変数はiniファイルに記述する。*/ 179 | mem_set( ra [ 3 ], ENV_SIZE, S_LONG ); 180 | mem_set( ra [ 3 ] + 4, 0, S_BYTE ); 181 | /* 内容を調べる */ 182 | while( fgets( buf, 1023, fp ) != NULL ) { 183 | _strlwr( buf ); 184 | chomp(buf); 185 | 186 | /* セクションを見る */ 187 | if ( buf[ 0 ] == '[' ) { 188 | env_flag = FALSE; 189 | if ( strcmp( buf, "[environment]" ) == 0 ) { 190 | env_flag = TRUE; 191 | } 192 | continue; 193 | } 194 | 195 | if (env_flag == TRUE) 196 | { 197 | /* 環境変数はiniファイルに記述する。*/ 198 | /* bufに格納された文字列の書式を確認すべきである。*/ 199 | if ( env_len + strlen(buf) < ENV_SIZE - 5 ) 200 | { 201 | mem_ptr = prog_ptr + ra [ 3 ] + 4 + env_len; 202 | strcpy( mem_ptr, buf); 203 | if ( ini_info.env_lower == TRUE ) { 204 | strcpy( buf, buf); 205 | _strlwr(buf); 206 | read_ptr = buf; 207 | while( *mem_ptr != '\0' && *mem_ptr != '=' ) 208 | *(mem_ptr ++) = *(read_ptr ++); 209 | } 210 | #ifdef TRACE 211 | mem_ptr = prog_ptr + ra [ 3 ] + 4 + env_len; 212 | printf( "env: %s\n", mem_ptr ); 213 | #endif 214 | env_len += strlen(buf) + 1; 215 | } 216 | } 217 | } 218 | mem_set( ra [ 3 ] + 4 + env_len, 0, S_BYTE ); 219 | fclose( fp ); 220 | } 221 | -------------------------------------------------------------------------------- /src/iocscall.c: -------------------------------------------------------------------------------- 1 | /* $Id: iocscall.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.3 1999/12/07 12:42:59 yfujii 9 | * *** empty log message *** 10 | * 11 | * Revision 1.3 1999/10/25 03:24:58 yfujii 12 | * Trace output is now controlled with command option. 13 | * 14 | * Revision 1.2 1999/10/18 03:24:40 yfujii 15 | * Added RCS keywords and modified for WIN32 a little. 16 | * 17 | */ 18 | 19 | #undef MAIN 20 | 21 | #include 22 | #include 23 | #include "run68.h" 24 | 25 | #if defined(WIN32) 26 | #include 27 | #elif defined(DOSX) 28 | #include 29 | #elif defined(__APPLE__) 30 | #else 31 | #include 32 | #endif 33 | 34 | #if defined (USE_ICONV) 35 | #include 36 | #endif 37 | 38 | #include 39 | #include 40 | 41 | static Long Putc( UShort ); 42 | static Long Color( short ); 43 | static void Putmes( void ); 44 | static Long Dateget( void ); 45 | static Long Timeget( void ); 46 | static Long Datebin( Long ); 47 | static Long Timebin( Long ); 48 | static Long Dateasc( Long, Long ); 49 | static Long Timeasc( Long, Long ); 50 | static void Dayasc( Long, Long ); 51 | static Long Intvcs( Long, Long ); 52 | static void Dmamove( Long, Long, Long, Long ); 53 | 54 | /* 55 |  機能:IOCSCALLを実行する 56 | 戻り値: TRUE = 実行終了 57 | FALSE = 実行継続 58 | */ 59 | int iocs_call() 60 | { 61 | UChar *data_ptr; 62 | ULong ul; 63 | UChar no; 64 | int x, y; 65 | short save_s; 66 | 67 | no = rd [ 0 ] & 0xff; 68 | 69 | if (func_trace_f) 70 | { 71 | printf( "IOCS(%02X): PC=%06X\n", no, pc ); 72 | } 73 | switch( no ) { 74 | case 0x20: /* B_PUTC */ 75 | rd [ 0 ] = Putc( (rd [ 1 ] & 0xFFFF) ); 76 | break; 77 | case 0x21: /* B_PRINT */ 78 | data_ptr = (UChar *)prog_ptr + ra [ 1 ]; 79 | #if defined (USE_ICONV) 80 | { 81 | // SJIS to UTF-8 82 | char utf8_buf[8192]; 83 | iconv_t icd = iconv_open("UTF-8", "Shift_JIS"); 84 | size_t inbytes = strlen(data_ptr); 85 | size_t outbytes = sizeof(utf8_buf) - 1; 86 | char *ptr_in = data_ptr; 87 | char *ptr_out = utf8_buf; 88 | memset(utf8_buf, 0x00, sizeof(utf8_buf)); 89 | iconv(icd, &ptr_in, &inbytes, &ptr_out, &outbytes); 90 | iconv_close(icd); 91 | 92 | printf("%s", utf8_buf); 93 | } 94 | #else 95 | printf( "%s", data_ptr ); 96 | #endif 97 | 98 | ra [ 1 ] += strlen((char *)data_ptr); 99 | rd [ 0 ] = get_locate(); 100 | break; 101 | case 0x22: /* B_COLOR */ 102 | rd [ 0 ] = Color( (rd [ 1 ] & 0xFFFF) ); 103 | break; 104 | case 0x23: /* B_LOCATE */ 105 | if ( rd [ 1 ] != -1 ) { 106 | x = (rd [ 1 ] & 0xFFFF) + 1; 107 | y = (rd [ 2 ] & 0xFFFF) + 1; 108 | printf( "%c[%d;%dH", 0x1B, y, x ); 109 | } 110 | rd [ 0 ] = get_locate(); 111 | break; 112 | case 0x24: /* B_DOWN_S */ 113 | printf( "%c[s\n%c[u%c[1B", 0x1B, 0x1B, 0x1B ); 114 | break; 115 | case 0x25: /* B_UP_S *//* (スクロール未サポート) */ 116 | printf( "%c[1A", 0x1B ); 117 | break; 118 | case 0x2F: /* B_PUTMES */ 119 | Putmes(); 120 | break; 121 | case 0x54: /* DATEGET */ 122 | rd [ 0 ] = Dateget(); 123 | break; 124 | case 0x55: /* DATEBIN */ 125 | rd [ 0 ] = Datebin( rd [ 1 ] ); 126 | break; 127 | case 0x56: /* TIMEGET */ 128 | rd [ 0 ] = Timeget(); 129 | break; 130 | case 0x57: /* TIMEBIN */ 131 | rd [ 0 ] = Timebin( rd [ 1 ] ); 132 | break; 133 | case 0x5A: /* DATEASC */ 134 | rd [ 0 ] = Dateasc( rd [ 1 ], ra [ 1 ] ); 135 | break; 136 | case 0x5B: /* TIMEASC */ 137 | rd [ 0 ] = Timeasc( rd [ 1 ], ra [ 1 ] ); 138 | break; 139 | case 0x5C: /* DAYASC */ 140 | Dayasc( rd [ 1 ], ra [ 1 ] ); 141 | break; 142 | case 0x6C: /* VDISPST */ 143 | save_s = SR_S_REF(); 144 | SR_S_ON(); 145 | if ( ra [ 1 ] == 0 ) { 146 | mem_set( 0x118, 0, S_LONG ); 147 | } else { 148 | rd [ 0 ] = mem_get( 0x118, S_LONG ); 149 | if ( rd [ 0 ] == 0 ) 150 | mem_set( 0x118, ra [ 1 ], S_LONG ); 151 | } 152 | if ( save_s == 0 ) 153 | SR_S_OFF(); 154 | break; 155 | case 0x6D: /* CRTCRAS */ 156 | save_s = SR_S_REF(); 157 | SR_S_ON(); 158 | if ( ra [ 1 ] == 0 ) { 159 | mem_set( 0x138, 0, S_LONG ); 160 | } else { 161 | rd [ 0 ] = mem_get( 0x138, S_LONG ); 162 | if ( rd [ 0 ] == 0 ) 163 | mem_set( 0x138, ra [ 1 ], S_LONG ); 164 | } 165 | if ( save_s == 0 ) 166 | SR_S_OFF(); 167 | break; 168 | case 0x6E: /* HSYNCST */ 169 | err68( "水平同期割り込みを設定しようとしました" ); 170 | return( TRUE ); 171 | case 0x7F: /* ONTIME */ 172 | #if defined(WIN32) 173 | ul = GetTickCount() / 1000; 174 | rd [ 0 ] = (ul % (60 * 60 * 24)) * 100; 175 | rd [ 1 ] = ((ul / (60 * 60 * 24)) & 0xFFFF); 176 | #elif defined(DOSX) 177 | ul = time( NULL ); 178 | rd [ 0 ] = (ul % (60 * 60 * 24)) * 100; 179 | rd [ 1 ] = ((ul / (60 * 60 * 24)) & 0xFFFF); 180 | #elif defined(__APPLE__) || defined(__EMSCRIPTEN__) 181 | ul = time( NULL ); 182 | rd [ 0 ] = (ul % (60 * 60 * 24)) * 100; 183 | rd [ 1 ] = ((ul / (60 * 60 * 24)) & 0xFFFF); 184 | #else 185 | { 186 | struct sysinfo info; 187 | sysinfo(&info); 188 | ul = info.uptime; 189 | rd [ 0 ] = (ul % (60 * 60 * 24)) * 100; 190 | rd [ 1 ] = ((ul / (60 * 60 * 24)) & 0xFFFF); 191 | } 192 | #endif 193 | break; 194 | case 0x80: /* B_INTVCS */ 195 | rd [ 0 ] = Intvcs( rd [ 1 ], ra [ 1 ] ); 196 | break; 197 | case 0x81: /* B_SUPER */ 198 | if ( ra [ 1 ] == 0 ) { 199 | /* user -> super */ 200 | if ( SR_S_REF() != 0 ) { 201 | rd [ 0 ] = -1; /* エラー */ 202 | } else { 203 | rd [ 0 ] = ra [ 7 ]; 204 | SR_S_ON(); 205 | } 206 | } else { 207 | /* super -> user */ 208 | ra [ 7 ] = ra [ 1 ]; 209 | rd [ 0 ] = 0; 210 | SR_S_OFF(); 211 | } 212 | break; 213 | case 0x82: /* B_BPEEK */ 214 | save_s = SR_S_REF(); 215 | SR_S_ON(); 216 | rd [ 0 ] = ( ( rd [ 0 ] & 0xFFFFFF00 ) | 217 | ( mem_get( ra [ 1 ], S_BYTE ) & 0xFF ) ); 218 | if ( save_s == 0 ) 219 | SR_S_OFF(); 220 | ra [ 1 ] += 1; 221 | break; 222 | case 0x83: /* B_WPEEK */ 223 | save_s = SR_S_REF(); 224 | SR_S_ON(); 225 | rd [ 0 ] = ( ( rd [ 0 ] & 0xFFFF0000 ) | 226 | ( mem_get( ra [ 1 ], S_WORD ) & 0xFFFF ) ); 227 | if ( save_s == 0 ) 228 | SR_S_OFF(); 229 | ra [ 1 ] += 2; 230 | break; 231 | case 0x84: /* B_LPEEK */ 232 | save_s = SR_S_REF(); 233 | SR_S_ON(); 234 | rd [ 0 ] = mem_get( ra [ 1 ], S_LONG ); 235 | if ( save_s == 0 ) 236 | SR_S_OFF(); 237 | ra [ 1 ] += 4; 238 | break; 239 | case 0x8A: /* DMAMOVE */ 240 | Dmamove( rd [ 1 ], rd [ 2 ], ra [ 1 ], ra [ 2 ] ); 241 | break; 242 | case 0xAE: /* OS_CURON */ 243 | printf( "%c[>5l", 0x1B ); 244 | break; 245 | case 0xAF: /* OS_CUROF */ 246 | printf( "%c[>5h", 0x1B ); 247 | break; 248 | default: 249 | if (func_trace_f) 250 | { 251 | printf( "IOCS(%02X): Unknown IOCS call. Ignored.\n", no ); 252 | } 253 | break; 254 | } 255 | 256 | return( FALSE ); 257 | } 258 | 259 | /* 260 |  機能:文字を表示する 261 | 戻り値:カーソル位置 262 | */ 263 | static Long Putc( UShort code ) 264 | { 265 | if ( code == 0x1A ) { 266 | printf( "%c[0J", 0x1B ); /* 最終行左端まで消去 */ 267 | } else { 268 | if ( code >= 0x0100 ) 269 | putchar( code >> 8 ); 270 | putchar( code ); 271 | } 272 | return( get_locate() ); 273 | } 274 | 275 | /* 276 |  機能:文字のカラー属性を指定する 277 | 戻り値:変更前のカラーまたは現在のカラー 278 | */ 279 | static Long Color( short arg ) 280 | { 281 | if ( arg == -1 ) /* 現在のカラーを調べる(未サポート) */ 282 | return( 3 ); 283 | 284 | text_color( arg ); 285 | 286 | return( 3 ); 287 | } 288 | 289 | /* 290 |  機能:文字列を表示する 291 | 戻り値:なし 292 | */ 293 | static void Putmes() 294 | { 295 | char temp [ 97 ]; 296 | char *p; 297 | int x, y; 298 | int keta; 299 | int len; 300 | 301 | x = (rd [ 2 ] & 0xFFFF) + 1; 302 | y = (rd [ 3 ] & 0xFFFF) + 1; 303 | keta = (rd [ 4 ] & 0xFFFF) + 1; 304 | 305 | p = prog_ptr + ra [ 1 ]; 306 | len = strlen( p ); 307 | if ( keta > 96 ) 308 | keta = 96; 309 | memcpy( temp, p, keta ); 310 | temp [ keta ] = '\0'; 311 | 312 | printf( "%c[%d;%dH", 0x1B, y, x ); 313 | text_color( (rd [ 1 ] & 0xFF) ); 314 | printf("%s", temp); 315 | 316 | ra [ 1 ] += len; 317 | } 318 | 319 | /* 320 |  機能:日付を得る 321 | 戻り値:BCDの日付データ 322 | */ 323 | static Long Dateget() 324 | { 325 | Long ret; 326 | #if defined(WIN32) 327 | SYSTEMTIME st; 328 | GetSystemTime(&st); 329 | ret = (st.wDayOfWeek << 24); 330 | ret |= (((st.wYear - 1980) / 10) << 20); 331 | ret |= (((st.wYear - 1980) % 10) << 16); 332 | ret |= ((st.wMonth / 10) << 12); 333 | ret |= ((st.wMonth % 10) << 8); 334 | ret |= ((st.wDay / 10) << 4); 335 | ret |= (st.wDay % 10); 336 | #elif defined(DOSX) 337 | struct dos_date_t ddate; 338 | dos_getdate( &ddate ); 339 | ret = (ddate.dayofweek << 24); 340 | ret |= (((ddate.year - 1980) / 10) << 20); 341 | ret |= (((ddate.year - 1980) % 10) << 16); 342 | ret |= ((ddate.month / 10) << 12); 343 | ret |= ((ddate.month % 10) << 8); 344 | ret |= ((ddate.day / 10) << 4); 345 | ret |= (ddate.day % 10); 346 | #else 347 | time_t now = time(NULL); 348 | struct tm *t = localtime(&now); 349 | ret = (t->tm_wday << 24); 350 | ret |= (((t->tm_year - 80) / 10) << 20); 351 | ret |= (((t->tm_year - 80) % 10) << 16); 352 | ret |= ((t->tm_mon / 10) << 12); 353 | ret |= ((t->tm_mon % 10) << 8); 354 | ret |= ((t->tm_mday / 10) << 4); 355 | ret |= (t->tm_mday % 10); 356 | #endif 357 | return( ret ); 358 | } 359 | 360 | /* 361 |  機能:時刻を得る 362 | 戻り値:BCDの時刻データ 363 | */ 364 | static Long Timeget() 365 | { 366 | Long ret; 367 | #if defined(WIN32) 368 | SYSTEMTIME st; 369 | GetSystemTime(&st); 370 | ret = ((st.wHour / 10) << 20); 371 | ret |= ((st.wHour % 10) << 16); 372 | ret |= ((st.wMinute / 10) << 12); 373 | ret |= ((st.wMinute % 10) << 8); 374 | ret |= ((st.wSecond / 10) << 4); 375 | ret |= (st.wSecond % 10); 376 | #elif defined(DOSX) 377 | struct dos_time_t dtime; 378 | dos_gettime( &dtime ); 379 | ret = ((dtime.hour / 10) << 20); 380 | ret |= ((dtime.hour % 10) << 16); 381 | ret |= ((dtime.minute / 10) << 12); 382 | ret |= ((dtime.minute % 10) << 8); 383 | ret |= ((dtime.second / 10) << 4); 384 | ret |= (dtime.second % 10); 385 | #else 386 | time_t now = time(NULL); 387 | struct tm *t = localtime(&now); 388 | ret = ((t->tm_hour / 10) << 20); 389 | ret |= ((t->tm_hour % 10) << 16); 390 | ret |= ((t->tm_min / 10) << 12); 391 | ret |= ((t->tm_min % 10) << 8); 392 | ret |= ((t->tm_sec / 10) << 4); 393 | ret |= (t->tm_sec % 10); 394 | #endif 395 | return( ret ); 396 | } 397 | 398 | /* 399 |  機能:BCD表現の日付データをバイナリ表現に直す 400 | 戻り値:バイナリの日付データ 401 | */ 402 | static Long Datebin( Long bcd ) 403 | { 404 | UShort youbi; 405 | UShort year; 406 | UShort month; 407 | UShort day; 408 | 409 | youbi = ( bcd >> 24 ); 410 | year = (( bcd >> 20 ) & 0xF) * 10 + (( bcd >> 16 ) & 0xF) + 1980; 411 | month = (( bcd >> 12 ) & 0xF) * 10 + (( bcd >> 8 ) & 0xF); 412 | day = (( bcd >> 4 ) & 0xF) * 10 + (bcd & 0xF); 413 | 414 | return( (youbi << 28) | (year << 16) | (month << 8) | day ); 415 | } 416 | 417 | /* 418 |  機能:BCD表現の時刻データをバイナリ表現に直す 419 | 戻り値:バイナリの時刻データ 420 | */ 421 | static Long Timebin( Long bcd ) 422 | { 423 | UShort hh; 424 | UShort mm; 425 | UShort ss; 426 | 427 | hh = (( bcd >> 20 ) & 0xF) * 10 + (( bcd >> 16 ) & 0xF); 428 | mm = (( bcd >> 12 ) & 0xF) * 10 + (( bcd >> 8 ) & 0xF); 429 | ss = (( bcd >> 4 ) & 0xF) * 10 + (bcd & 0xF); 430 | 431 | return( (hh << 16) | (mm << 8) | ss ); 432 | } 433 | 434 | /* 435 |  機能:バイナリ表現の日付データを文字列に直す 436 | 戻り値:-1のときエラー 437 | */ 438 | static Long Dateasc( Long data, Long adr ) 439 | { 440 | char *data_ptr; 441 | UShort year; 442 | UShort month; 443 | UShort day; 444 | int form; 445 | 446 | data_ptr = prog_ptr + adr; 447 | 448 | form = data >> 28; 449 | year = ((data >> 16) & 0xFFF); 450 | if ( year < 1980 || year > 2079 ) 451 | return( -1 ); 452 | month = ((data >> 8) & 0xFF); 453 | if ( month < 1 || month > 12 ) 454 | return( -1 ); 455 | day = (data & 0xFF); 456 | if ( day < 1 || day > 31 ) 457 | return( -1 ); 458 | 459 | switch( form ) { 460 | case 0: 461 | sprintf( data_ptr, "%04d/%02d/%02d", year, month, day); 462 | ra [ 1 ] += 10; 463 | break; 464 | case 1: 465 | sprintf( data_ptr, "%04d-%02d-%02d", year, month, day); 466 | ra [ 1 ] += 10; 467 | break; 468 | case 2: 469 | sprintf( data_ptr, "%02d/%02d/%02d", year % 100, month, day); 470 | ra [ 1 ] += 8; 471 | break; 472 | case 3: 473 | sprintf( data_ptr, "%02d-%02d-%02d", year % 100, month, day); 474 | ra [ 1 ] += 8; 475 | break; 476 | default: 477 | return( -1 ); 478 | } 479 | 480 | return( 0 ); 481 | } 482 | 483 | /* 484 |  機能:バイナリ表現の時刻データを文字列に直す 485 | 戻り値:-1のときエラー 486 | */ 487 | static Long Timeasc( Long data, Long adr ) 488 | { 489 | char *data_ptr; 490 | UShort hh; 491 | UShort mm; 492 | UShort ss; 493 | 494 | data_ptr = prog_ptr + adr; 495 | 496 | hh = ((data >> 16) & 0xFF); 497 | if ( hh < 0 || hh > 23 ) 498 | return( -1 ); 499 | mm = ((data >> 8) & 0xFF); 500 | if ( mm < 0 || mm > 59 ) 501 | return( -1 ); 502 | ss = (data & 0xFF); 503 | if ( ss < 0 || ss > 59 ) 504 | return( -1 ); 505 | 506 | sprintf( data_ptr, "%02d:%02d:%02d", hh, mm, ss); 507 | ra [ 1 ] += 8; 508 | 509 | return( 0 ); 510 | } 511 | 512 | /* 513 |  機能:曜日番号から文字列を得る 514 | 戻り値:なし 515 | */ 516 | static void Dayasc( Long data, Long adr ) 517 | { 518 | char *data_ptr; 519 | 520 | data_ptr = prog_ptr + adr; 521 | 522 | switch( data ) { 523 | case 0: 524 | strcpy( data_ptr, "日" ); 525 | break; 526 | case 1: 527 | strcpy( data_ptr, "月" ); 528 | break; 529 | case 2: 530 | strcpy( data_ptr, "火" ); 531 | break; 532 | case 3: 533 | strcpy( data_ptr, "水" ); 534 | break; 535 | case 4: 536 | strcpy( data_ptr, "木" ); 537 | break; 538 | case 5: 539 | strcpy( data_ptr, "金" ); 540 | break; 541 | case 6: 542 | strcpy( data_ptr, "土" ); 543 | break; 544 | default: 545 | ra [ 1 ] -= 2; 546 | break; 547 | } 548 | ra [ 1 ] += 2; 549 | } 550 | 551 | /* 552 |  機能:ベクタ・テーブルを書き換える 553 | 戻り値:設定前の処理アドレス 554 | */ 555 | static Long Intvcs( Long no, Long adr ) 556 | { 557 | Long adr2; 558 | Long mae = 0; 559 | short save_s; 560 | 561 | no &= 0xFFFF; 562 | adr2 = no * 4; 563 | save_s = SR_S_REF(); 564 | SR_S_ON(); 565 | mae = mem_get( adr2, S_LONG ); 566 | mem_set( adr2, adr, S_LONG ); 567 | if ( save_s == 0 ) 568 | SR_S_OFF(); 569 | 570 | return( mae ); 571 | } 572 | 573 | /* 574 |  機能:DMA転送をする 575 | 戻り値:設定前の処理アドレス 576 | */ 577 | static void Dmamove( Long md, Long size, Long adr1, Long adr2 ) 578 | { 579 | char *p1; 580 | char *p2; 581 | Long tmp; 582 | 583 | if ( (md & 0x80) != 0 ) { 584 | /* adr1 -> adr2転送にする */ 585 | tmp = adr1; 586 | adr1 = adr2; 587 | adr2 = tmp; 588 | } 589 | 590 | /* adr1,adr2共にインクリメントモードでない場合は未サポート */ 591 | if ( (md & 0x0F) != 5 ) 592 | return; 593 | 594 | p1 = prog_ptr + adr1; 595 | p2 = prog_ptr + adr2; 596 | memcpy( p2, p1, size ); 597 | } 598 | -------------------------------------------------------------------------------- /src/key.c: -------------------------------------------------------------------------------- 1 | /* $Id: key.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.2 1999/12/07 12:43:13 yfujii 9 | * *** empty log message *** 10 | * 11 | * Revision 1.2 1999/10/18 03:24:40 yfujii 12 | * Added RCS keywords and modified for WIN32 a little. 13 | * 14 | */ 15 | 16 | #undef MAIN 17 | 18 | #include 19 | #include 20 | #include "run68.h" 21 | 22 | static char fnc_key1 [ 20 ] [ 32 ] = { 23 | "", "", "", "", "", "", "", "", "", "", 24 | "", "", "", "", "", "", "", "", "", "" 25 | }; 26 | static char fnc_key2 [ 12 ] [ 6 ] = { 27 | "", "", "", "", "", "", 28 | "", "", "", "", "", "" 29 | }; 30 | 31 | static void put_fnckey1( int, char * ); 32 | static void put_fnckey2( int, char * ); 33 | 34 | /* 35 |  機能:ファンクションキーに割り当てた文字列を得る 36 | 戻り値:なし 37 | */ 38 | void get_fnckey( int no, char *p ) 39 | { 40 | if ( no == 0 ) { 41 | memcpy( p, fnc_key1, 20 * 32 ); 42 | memcpy( p + 20 * 32, fnc_key2, 12 * 6 ); 43 | } 44 | if ( no >= 1 && no <= 20 ) 45 | memcpy( p, fnc_key1 [ no - 1 ], 32 ); 46 | if ( no >= 21 && no <= 32 ) 47 | memcpy( p, fnc_key2 [ no - 21 ], 6 ); 48 | } 49 | 50 | /* 51 |  機能:ファンクションキーに文字列を割り当てる 52 | 戻り値:なし 53 | */ 54 | void put_fnckey( int no, char *p ) 55 | { 56 | int i; 57 | 58 | if ( no == 0 ) { 59 | for( i = 0; i < 20; i++, p += 32 ) 60 | put_fnckey1( i, p ); 61 | for( i = 0; i < 12; i++, p += 6 ) 62 | put_fnckey2( i, p ); 63 | } 64 | if ( no >= 1 && no <= 20 ) 65 | put_fnckey1( no - 1, p ); 66 | if ( no >= 21 && no <= 32 ) 67 | put_fnckey2( no - 21, p ); 68 | } 69 | 70 | /* 71 |  機能:個々のファンクションキーに文字列を割り当てる(その1) 72 | 戻り値:なし 73 | */ 74 | void put_fnckey1( int no, char *p ) 75 | { 76 | int kno; 77 | int i; 78 | 79 | if ( *p == (char)0xFE ) { 80 | memcpy( fnc_key1 [ no ], p, 8 ); 81 | p += 8; 82 | strcpy( &(fnc_key1 [ no ] [ 8 ]), p ); 83 | } else { 84 | strcpy( fnc_key1 [ no ], p ); 85 | } 86 | if ( no < 10 ) 87 | kno = 0x3B + no; 88 | else 89 | kno = 0x54 + no - 10; 90 | if ( *p == '\0' ) { 91 | printf("%c[0;%d;\"%c%c\"p", 0x1B, kno, 0, kno); 92 | } else { 93 | for( i = 0; p [ i ] != '\0'; i++ ) { 94 | if ( p [ i ] == 0x1A ) 95 | return; 96 | } 97 | printf("%c[0;%d;\"%s\"p", 0x1B, kno, p); 98 | } 99 | } 100 | 101 | /* 102 |  機能:個々のファンクションキーに文字列を割り当てる(その2) 103 | 戻り値:なし 104 | */ 105 | void put_fnckey2( int no, char *p ) 106 | { 107 | int kno; 108 | int i; 109 | 110 | strcpy( fnc_key2 [ no ], p ); 111 | switch( no ) { 112 | case 0: /* ROLL UP */ 113 | kno = 0x51; /* PAGE DOWN */ 114 | break; 115 | case 1: /* ROLL DOWN */ 116 | kno = 0x49; /* PAGE UP */ 117 | break; 118 | case 2: /* INS */ 119 | kno = 0x52; 120 | break; 121 | case 3: /* DEL */ 122 | kno = 0x53; 123 | break; 124 | case 4: /* ↑ */ 125 | kno = 0x48; 126 | break; 127 | case 5: /* ← */ 128 | kno = 0x4B; 129 | break; 130 | case 6: /* → */ 131 | kno = 0x4D; 132 | break; 133 | case 7: /* ↓ */ 134 | kno = 0x50; 135 | break; 136 | case 8: /* CLR */ 137 | kno = 0x97; /* ALT+HOME */ 138 | break; 139 | case 9: /* HELP */ 140 | kno = 0x86; /* F12 */ 141 | break; 142 | case 10:/* HOME */ 143 | kno = 0x47; 144 | break; 145 | default:/* UNDO */ 146 | kno = 0x4F; /* END */ 147 | break; 148 | } 149 | if ( *p == '\0' ) { 150 | printf("%c[0;%d;\"%c%c\"p", 0x1B, kno, 0, kno); 151 | } else { 152 | for( i = 0; p [ i ] != '\0'; i++ ) { 153 | if ( p [ i ] == 0x1A ) 154 | return; 155 | } 156 | printf("%c[0;%d;\"%s\"p", 0x1B, kno, p); 157 | } 158 | } 159 | 160 | /* 161 |  機能:キーコードを変換する 162 | 戻り値:変換後のキーコード 163 | */ 164 | UChar cnv_key98( UChar c ) 165 | { 166 | switch( c ) { 167 | case 0x0A: /* ↓ */ 168 | c = 0x1F; 169 | break; 170 | case 0x0B: /* ↑ */ 171 | c = 0x1E; 172 | break; 173 | case 0x0C: /* → */ 174 | c = 0x1C; 175 | break; 176 | case 0x1A: /* CLR */ 177 | c = 0x0C; 178 | break; 179 | case 0x1E: /* HOME */ 180 | c = 0x0B; 181 | break; 182 | } 183 | return( c ); 184 | } 185 | -------------------------------------------------------------------------------- /src/line2.c: -------------------------------------------------------------------------------- 1 | /* $Id: line2.c,v 1.3 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.2 2009/08/05 14:44:33 masamic 6 | * Some Bug fix, and implemented some instruction 7 | * Following Modification contributed by TRAP. 8 | * 9 | * Fixed Bug: In disassemble.c, shift/rotate as{lr},ls{lr},ro{lr} alway show word size. 10 | * Modify: enable KEYSNS, register behaiviour of sub ea, Dn. 11 | * Add: Nbcd, Sbcd. 12 | * 13 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 14 | * First imported source code and docs 15 | * 16 | * Revision 1.8 1999/12/07 12:43:51 yfujii 17 | * *** empty log message *** 18 | * 19 | * Revision 1.8 1999/11/22 03:57:08 yfujii 20 | * Condition code calculations are rewriten. 21 | * 22 | * Revision 1.6 1999/11/01 10:36:33 masamichi 23 | * Reduced move[a].l routine. and Create functions about accessing effective address. 24 | * 25 | * Revision 1.4 1999/10/26 06:08:46 masamichi 26 | * precision implementation for move operation. 27 | * 28 | * Revision 1.3 1999/10/20 03:43:08 masamichi 29 | * Added showing more information about errors. 30 | * 31 | * Revision 1.2 1999/10/18 03:24:40 yfujii 32 | * Added RCS keywords and modified for WIN32 a little. 33 | * 34 | */ 35 | 36 | #undef MAIN 37 | 38 | #include 39 | #include "run68.h" 40 | 41 | /* 42 |  機能:1/2/3ライン命令(move / movea)を実行する 43 | 戻り値: TRUE = 実行終了 44 | FALSE = 実行継続 45 | */ 46 | int line2( char *pc_ptr ) 47 | { 48 | Long save_pc; 49 | char src_mode; 50 | char dst_mode; 51 | char src_reg; 52 | char dst_reg; 53 | char code1, code2; 54 | Long src_data; 55 | int size; 56 | 57 | code1 = *(pc_ptr++); 58 | code2 = *pc_ptr; 59 | pc += 2; 60 | save_pc = pc; 61 | dst_reg = ((code1 & 0x0E) >> 1); 62 | dst_mode = (((code1 & 0x01) << 2) | ((code2 >> 6) & 0x03)); 63 | src_mode = ((code2 & 0x38) >> 3); 64 | src_reg = (code2 & 0x07); 65 | 66 | /* アクセスサイズの決定 */ 67 | switch ((code1 >> 4) & 0x03) { 68 | case 1: 69 | size = S_BYTE; 70 | break; 71 | case 3: 72 | size = S_WORD; 73 | break; 74 | case 2: 75 | size = S_LONG; 76 | break; 77 | default: 78 | err68a( "存在しないアクセスサイズです。", __FILE__, __LINE__ ); 79 | return( TRUE ); 80 | } 81 | 82 | /* ソースのアドレッシングモードに応じた処理 */ 83 | if (src_mode == EA_AD && size == S_BYTE) { 84 | err68a( "不正な命令: move[a].b An, を実行しようとしました。", __FILE__, __LINE__ ); 85 | return(TRUE); 86 | } else if (get_data_at_ea(EA_All, src_mode, src_reg, size, &src_data)) { 87 | return(TRUE); 88 | } 89 | 90 | /* movea 実効時の処理 */ 91 | if (dst_mode == EA_AD) { 92 | if (size == S_BYTE) { 93 | err68a( "不正な命令: movea.b , An を実行しようとしました。", __FILE__, __LINE__ ); 94 | return(TRUE); 95 | } else if (size == S_WORD) { 96 | if (src_data & 0x8000) { 97 | src_data |= 0xffff0000; 98 | } else { 99 | src_data &= 0x0000ffff; 100 | } 101 | size = S_LONG; 102 | } 103 | } 104 | 105 | /* ディスティネーションのアドレッシングモードに応じた処理 */ 106 | if (set_data_at_ea(EA_VariableData | (1 << (EA_AI - 1)), dst_mode, dst_reg, size, src_data)) { 107 | return(TRUE); 108 | } 109 | 110 | /* movea のときはフラグは変化しない */ 111 | if ( dst_mode != MD_AD ) { 112 | 113 | /* フラグの変化 */ 114 | general_conditions(src_data, size); 115 | 116 | } 117 | 118 | return( FALSE ); 119 | } 120 | -------------------------------------------------------------------------------- /src/line5.c: -------------------------------------------------------------------------------- 1 | /* $Id: line5.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.6 1999/12/21 10:08:59 yfujii 9 | * Uptodate source code from Beppu. 10 | * 11 | * Revision 1.5 1999/12/07 12:44:27 yfujii 12 | * *** empty log message *** 13 | * 14 | * Revision 1.5 1999/11/22 03:57:08 yfujii 15 | * Condition code calculations are rewriten. 16 | * 17 | * Revision 1.3 1999/10/20 03:55:03 masamichi 18 | * Added showing more information about errors. 19 | * 20 | * Revision 1.2 1999/10/18 03:24:40 yfujii 21 | * Added RCS keywords and modified for WIN32 a little. 22 | * 23 | */ 24 | 25 | #undef MAIN 26 | 27 | #include 28 | #include "run68.h" 29 | 30 | static int Dbcc( char, char ); 31 | static int Scc( char, char ); 32 | static int Addq( char, char ); 33 | static int Subq( char, char ); 34 | 35 | /* 36 |  機能:5ライン命令を実行する 37 | 戻り値: TRUE = 実行終了 38 | FALSE = 実行継続 39 | */ 40 | int line5( char *pc_ptr ) 41 | { 42 | char code1, code2; 43 | 44 | code1 = *(pc_ptr++); 45 | code2 = *pc_ptr; 46 | pc += 2; 47 | 48 | if ( (code2 & 0xC0) == 0xC0 ) { 49 | if ( (code2 & 0x38) == 0x08 ) 50 | return( Dbcc( code1, code2 ) ); 51 | else 52 | return( Scc( code1, code2 ) ); 53 | } 54 | if ( (code1 & 0x01) != 0 ) 55 | return( Subq( code1, code2 ) ); 56 | else 57 | return( Addq( code1, code2 ) ); 58 | } 59 | 60 | /* 61 |  機能:dbcc命令を実行する 62 | 戻り値: TRUE = 実行終了 63 | FALSE = 実行継続 64 | */ 65 | static int Dbcc( char code1, char code2 ) 66 | { 67 | char reg; 68 | short disp; 69 | UShort src_data; 70 | 71 | reg = (code2 & 0x07); 72 | disp = (short)imi_get( S_WORD ); 73 | src_data = (rd [ reg ] & 0xFFFF); 74 | 75 | #ifdef TRACE 76 | printf( "trace: dbcc src=%d PC=%06lX\n", (short)src_data, pc - 2 ); 77 | #endif 78 | 79 | if ( (BOOL)get_cond( (char)(code1 & 0x0F) ) == TRUE ) 80 | return( FALSE ); 81 | 82 | src_data --; 83 | rd [ reg ] = ((rd [ reg ] & 0xFFFF0000) | src_data); 84 | if ( src_data != 0xFFFF ) 85 | pc += (disp - 2); 86 | 87 | return( FALSE ); 88 | } 89 | 90 | /* 91 |  機能:scc命令を実行する 92 | 戻り値: TRUE = 実行終了 93 | FALSE = 実行継続 94 | */ 95 | static int Scc( char code1, char code2 ) 96 | { 97 | char mode; 98 | char reg; 99 | Long save_pc; 100 | int ret; 101 | Long src_data; 102 | 103 | save_pc = pc; 104 | mode = (code2 & 0x38) >> 3; 105 | reg = (code2 & 0x07); 106 | ret = get_cond( (char)(code1 & 0x0F) ); 107 | 108 | /* 条件よりビットを決める */ 109 | if ( ret == TRUE ) { 110 | src_data = 0xff; 111 | } else { 112 | src_data = 0; 113 | } 114 | 115 | /* ディスティネーションのアドレッシングモードに応じた処理 */ 116 | if (set_data_at_ea(EA_VariableData, mode, reg, S_BYTE, src_data)) { 117 | return(TRUE); 118 | } 119 | 120 | return( FALSE ); 121 | } 122 | 123 | /* 124 |  機能:addq命令を実行する 125 | 戻り値: TRUE = 実行終了 126 | FALSE = 実行継続 127 | */ 128 | static int Addq( char code1, char code2 ) 129 | { 130 | char size; 131 | char mode; 132 | char reg; 133 | char src_data; 134 | short disp = 0; 135 | int work_mode; 136 | 137 | Long dest_data; 138 | 139 | src_data = (code1 & 0x0E) >> 1; 140 | if ( src_data == 0 ) 141 | src_data = 8; 142 | size = ((code2 >> 6) & 0x03); 143 | mode = (code2 & 0x38) >> 3; 144 | reg = (code2 & 0x07); 145 | 146 | if (mode == EA_AD) { 147 | if (size == S_BYTE) { 148 | err68a( "不正な命令: addq.b #, An を実行しようとしました。", __FILE__, __LINE__ ); 149 | return(TRUE); 150 | } else { 151 | /* アドレスレジスタ直接モードの時のアクセスサイズは必ずロングワードになる */ 152 | size = S_LONG; 153 | } 154 | } 155 | 156 | /* アドレッシングモードがポストインクリメント間接の場合は間接でデータの取得 */ 157 | if (mode == EA_AIPI) { 158 | work_mode = EA_AI; 159 | } else { 160 | work_mode = mode; 161 | } 162 | 163 | if (get_data_at_ea_noinc(EA_Variable, work_mode, reg, size, &dest_data)) { 164 | return(TRUE); 165 | } 166 | 167 | /* ワークレジスタにコピー */ 168 | rd[8] = dest_data; 169 | 170 | /* Add演算 */ 171 | //rd [ 8 ] = add_rd( 8, (Long)src_data, size ); 172 | rd [ 8 ] = add_long((Long)src_data, dest_data, size ); 173 | 174 | /* アドレッシングモードがプレデクリメント間接の場合は間接でデータの設定 */ 175 | if (mode == EA_AIPD) { 176 | work_mode = EA_AI; 177 | } else { 178 | work_mode = mode; 179 | } 180 | 181 | if (set_data_at_ea(EA_Variable, work_mode, reg, size, rd[8])) { 182 | return(TRUE); 183 | } 184 | 185 | // アドレスレジスタ直接の場合はレジスタは変化しない 186 | if (mode != EA_AD) { 187 | /* フラグの変化 */ 188 | add_conditions((Long)src_data, dest_data, rd[8], size, 1); 189 | } 190 | 191 | return( FALSE ); 192 | } 193 | 194 | /* 195 |  機能:subq命令を実行する 196 | 戻り値: TRUE = 実行終了 197 | FALSE = 実行継続 198 | */ 199 | static int Subq( char code1, char code2 ) 200 | { 201 | char size; 202 | char mode; 203 | char reg; 204 | char src_data; 205 | short disp = 0; 206 | int work_mode; 207 | Long dest_data; 208 | 209 | src_data = (code1 & 0x0E) >> 1; 210 | if ( src_data == 0 ) 211 | src_data = 8; 212 | size = ((code2 >> 6) & 0x03); 213 | mode = (code2 & 0x38) >> 3; 214 | reg = (code2 & 0x07); 215 | 216 | if (mode == EA_AD) { 217 | if (size == S_BYTE) { 218 | err68a( "不正な命令: subq.b #, An を実行しようとしました。", __FILE__, __LINE__ ); 219 | return(TRUE); 220 | } else { 221 | /* アドレスレジスタ直接モードの時のアクセスサイズは必ずロングワードになる */ 222 | size = S_LONG; 223 | } 224 | } 225 | 226 | /* アドレッシングモードがポストインクリメント間接の場合は間接でデータの取得 */ 227 | if (mode == EA_AIPI) { 228 | work_mode = EA_AI; 229 | } else { 230 | work_mode = mode; 231 | } 232 | 233 | if (get_data_at_ea_noinc(EA_Variable, work_mode, reg, size, &dest_data)) { 234 | return(TRUE); 235 | } 236 | 237 | /* ワークレジスタにコピー */ 238 | rd[8] = dest_data; 239 | 240 | /* Add演算 */ 241 | //rd [ 8 ] = sub_rd( 8, (Long)src_data, size ); 242 | rd [ 8 ] = sub_long((Long)src_data, dest_data, size ); 243 | 244 | /* アドレッシングモードがプレデクリメント間接の場合は間接でデータの設定 */ 245 | if (mode == EA_AIPD) { 246 | work_mode = EA_AI; 247 | } else { 248 | work_mode = mode; 249 | } 250 | 251 | if (set_data_at_ea(EA_Variable, work_mode, reg, size, rd[8])) { 252 | return(TRUE); 253 | } 254 | 255 | // アドレスレジスタ直接の場合はレジスタは変化しない 256 | if (mode != EA_AD) { 257 | /* フラグの変化 */ 258 | sub_conditions((Long)src_data, dest_data, rd[8], size, 1); 259 | } 260 | 261 | return( FALSE ); 262 | } 263 | -------------------------------------------------------------------------------- /src/line6.c: -------------------------------------------------------------------------------- 1 | /* $Id: line6.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.6 1999/12/21 10:08:59 yfujii 9 | * Uptodate source code from Beppu. 10 | * 11 | * Revision 1.5 1999/12/07 12:44:37 yfujii 12 | * *** empty log message *** 13 | * 14 | * Revision 1.5 1999/11/22 03:57:08 yfujii 15 | * Condition code calculations are rewriten. 16 | * 17 | * Revision 1.3 1999/10/28 06:34:08 masamichi 18 | * Modified trace behavior 19 | * 20 | * Revision 1.2 1999/10/18 03:24:40 yfujii 21 | * Added RCS keywords and modified for WIN32 a little. 22 | * 23 | */ 24 | 25 | #undef MAIN 26 | 27 | #include 28 | #include "run68.h" 29 | 30 | /* 31 | �@�@�\�F6���C�����?����s���� 32 | �?�l�F TRUE = ���s�I�� 33 | FALSE = ���s�p�� 34 | */ 35 | int line6( char *pc_ptr ) 36 | { 37 | char code; 38 | char cond; 39 | char disp; 40 | short disp_w; 41 | 42 | code = *pc_ptr; 43 | cond = (*pc_ptr & 0x0F); 44 | disp = *(pc_ptr + 1); 45 | pc += 2; 46 | 47 | if ( cond == 0x01 ) { /* bsr */ 48 | ra [ 7 ] -= 4; 49 | if ( disp == 0 ) { 50 | disp_w = (short)imi_get( S_WORD ); 51 | mem_set( ra [ 7 ], pc, S_LONG ); 52 | pc += (disp_w - 2); 53 | } else { 54 | mem_set( ra [ 7 ], pc, S_LONG ); 55 | pc += disp; 56 | } 57 | return( FALSE ); 58 | } 59 | 60 | if ( get_cond( cond ) == TRUE ) { 61 | if ( disp == 0 ) { 62 | disp_w = (short)imi_get( S_WORD ); 63 | pc += (disp_w - 2); 64 | } else { 65 | pc += disp; 66 | } 67 | } else { 68 | if ( disp == 0 ) 69 | pc += 2; 70 | } 71 | 72 | return( FALSE ); 73 | } 74 | -------------------------------------------------------------------------------- /src/line7.c: -------------------------------------------------------------------------------- 1 | /* $Id: line7.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.4 1999/12/07 12:44:50 yfujii 9 | * *** empty log message *** 10 | * 11 | * Revision 1.4 1999/11/22 03:57:08 yfujii 12 | * Condition code calculations are rewriten. 13 | * 14 | * Revision 1.3 1999/10/20 04:00:59 masamichi 15 | * Added showing more information about errors. 16 | * 17 | * Revision 1.2 1999/10/18 03:24:40 yfujii 18 | * Added RCS keywords and modified for WIN32 a little. 19 | * 20 | */ 21 | 22 | #undef MAIN 23 | 24 | #include 25 | #include "run68.h" 26 | 27 | /* 28 |  機能:7ライン命令(moveq)を実行する 29 | 戻り値: TRUE = 実行終了 30 | FALSE = 実行継続 31 | */ 32 | int line7( char *pc_ptr ) 33 | { 34 | char code; 35 | char reg; 36 | char data; 37 | 38 | code = *(pc_ptr++); 39 | pc += 2; 40 | if ( (code & 0x01) != 0 ) { 41 | err68a( "おかしな命令を実行しました", __FILE__, __LINE__ ); 42 | return( TRUE ); 43 | } 44 | reg = ((code >> 1) & 0x07); 45 | data = *pc_ptr; 46 | if ( data < 0 ) { 47 | rd [ reg ] = (0xFFFFFF00 | data); 48 | } else { 49 | rd [ reg ] = data; 50 | } 51 | 52 | /* フラグの変化 */ 53 | general_conditions(rd[reg], S_LONG); 54 | 55 | #ifdef TRACE 56 | printf( "trace: moveq src=%d PC=%06lX\n", data, pc ); 57 | #endif 58 | 59 | return( FALSE ); 60 | } 61 | -------------------------------------------------------------------------------- /src/line8.c: -------------------------------------------------------------------------------- 1 | /* $Id: line8.c,v 1.3 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.2 2009/08/05 14:44:33 masamic 6 | * Some Bug fix, and implemented some instruction 7 | * Following Modification contributed by TRAP. 8 | * 9 | * Fixed Bug: In disassemble.c, shift/rotate as{lr},ls{lr},ro{lr} alway show word size. 10 | * Modify: enable KEYSNS, register behaiviour of sub ea, Dn. 11 | * Add: Nbcd, Sbcd. 12 | * 13 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 14 | * First imported source code and docs 15 | * 16 | * Revision 1.6 1999/12/21 10:08:59 yfujii 17 | * Uptodate source code from Beppu. 18 | * 19 | * Revision 1.5 1999/12/07 12:45:00 yfujii 20 | * *** empty log message *** 21 | * 22 | * Revision 1.5 1999/11/22 03:57:08 yfujii 23 | * Condition code calculations are rewriten. 24 | * 25 | * Revision 1.3 1999/10/20 04:00:59 masamichi 26 | * Added showing more information about errors. 27 | * 28 | * Revision 1.2 1999/10/18 03:24:40 yfujii 29 | * Added RCS keywords and modified for WIN32 a little. 30 | * 31 | */ 32 | 33 | #undef MAIN 34 | 35 | #include 36 | #include "run68.h" 37 | 38 | static int Divu( char, char ); 39 | static int Divs( char, char ); 40 | static int Or1( char, char ); 41 | static int Or2( char, char ); 42 | 43 | /* 44 |  機能:8ライン命令を実行する 45 | 戻り値: TRUE = 実行終了 46 | FALSE = 実行継続 47 | */ 48 | int line8( char *pc_ptr ) 49 | { 50 | char code1, code2; 51 | 52 | code1 = *(pc_ptr++); 53 | code2 = *pc_ptr; 54 | pc += 2; 55 | 56 | if ( (code2 & 0xC0) == 0xC0 ) { 57 | if ( (code1 & 0x01) == 0 ) 58 | return( Divu( code1, code2 ) ); 59 | else 60 | return( Divs( code1, code2 ) ); 61 | } 62 | if ( ((code1 & 0x01) == 0x01) && ((code2 & 0xF0) == 0) ) { 63 | /* sbcd */ 64 | char src_reg = (code2 & 0x7); 65 | char dst_reg = ((code1 & 0xE) >> 1); 66 | char size = 0; /* S_BYTE 固定 */ 67 | Long src_data; 68 | Long dst_data; 69 | Long kekka; 70 | Long X; 71 | 72 | if ( (code2 & 0x8) != 0 ) { 73 | /* -(am),-(an); */ 74 | if ( get_data_at_ea(EA_All, EA_AIPD, src_reg, size, &src_data) ) { 75 | return( TRUE ); 76 | } 77 | if ( get_data_at_ea(EA_All, EA_AIPD, dst_reg, size, &dst_data) ) { 78 | return( TRUE ); 79 | } 80 | }else{ 81 | /* dm,dn; */ 82 | if ( get_data_at_ea(EA_All, EA_DD, src_reg, size, &src_data) ) { 83 | return( TRUE ); 84 | } 85 | if ( get_data_at_ea(EA_All, EA_DD, dst_reg, size, &dst_data) ) { 86 | return( TRUE ); 87 | } 88 | } 89 | 90 | X = (CCR_X_REF() != 0) ? 1 : 0; 91 | 92 | kekka = dst_data - src_data - X; 93 | 94 | if ( (dst_data & 0xff) < ((src_data & 0xff) + X) ) 95 | kekka -= 0x60; 96 | 97 | if ( (dst_data & 0x0f) < ((src_data & 0x0f) + X) ) 98 | kekka -= 0x06; 99 | 100 | if ( (dst_data ^ kekka) & 0x100 ) { 101 | CCR_X_ON(); 102 | CCR_C_ON(); 103 | }else{ 104 | CCR_X_OFF(); 105 | CCR_C_OFF(); 106 | } 107 | 108 | kekka &= 0xff; 109 | 110 | /* 0 以外の値になった時のみ、Z フラグをリセットする */ 111 | if ( kekka != 0 ) { 112 | CCR_Z_OFF(); 113 | } 114 | 115 | /* Nフラグは結果に応じて立てる */ 116 | if ( kekka & 0x80 ) { 117 | CCR_N_ON(); 118 | }else{ 119 | CCR_N_OFF(); 120 | } 121 | 122 | /* Vフラグ */ 123 | if ( (dst_data <= kekka) && (0x20 <= kekka) && (kekka < 0x80) ) { 124 | CCR_V_ON(); 125 | }else{ 126 | CCR_V_OFF(); 127 | } 128 | 129 | dst_data = kekka; 130 | 131 | if ( (code2 & 0x8) != 0 ) { 132 | /* -(am),-(an); */ 133 | if ( set_data_at_ea(EA_All, EA_AI, dst_reg, size, dst_data) ) { 134 | return( TRUE ); 135 | } 136 | }else{ 137 | /* dm,dn; */ 138 | if ( set_data_at_ea(EA_All, EA_DD, dst_reg, size, dst_data) ) { 139 | return( TRUE ); 140 | } 141 | } 142 | 143 | return( FALSE ); 144 | 145 | /* 146 | err68a( "未定義命令を実行しました", __FILE__, __LINE__ ); 147 | return( TRUE ); 148 | */ 149 | } 150 | 151 | if ( (code1 & 0x01) == 0x01 ) 152 | return ( Or1( code1, code2 ) ); 153 | else 154 | return ( Or2( code1, code2 ) ); 155 | } 156 | 157 | /* 158 |  機能:divu命令を実行する 159 | 戻り値: TRUE = 実行終了 160 | FALSE = 実行継続 161 | */ 162 | static int Divu( char code1, char code2 ) 163 | { 164 | char mode; 165 | char src_reg; 166 | char dst_reg; 167 | UShort waru; 168 | ULong data; 169 | ULong ans; 170 | UShort mod; 171 | Long save_pc; 172 | Long waru_l; 173 | 174 | save_pc = pc; 175 | mode = ((code2 & 0x38) >> 3); 176 | src_reg = (code2 & 0x07); 177 | dst_reg = ((code1 & 0x0E) >> 1); 178 | data = rd [ dst_reg ]; 179 | 180 | /* ソースのアドレッシングモードに応じた処理 */ 181 | if (get_data_at_ea(EA_Data, mode, src_reg, S_WORD, &waru_l)) { 182 | return(TRUE); 183 | } 184 | waru = (UShort)waru_l; 185 | 186 | if ( waru == 0 ) { 187 | err68a( "0で除算しました", __FILE__, __LINE__ ); 188 | return( TRUE ); 189 | } 190 | 191 | CCR_C_OFF(); 192 | ans = data / waru; 193 | mod = (unsigned char)(data % waru); 194 | if ( ans > 0xFFFF ) { 195 | CCR_V_ON(); 196 | return( FALSE ); 197 | } 198 | rd [ dst_reg ] = ((mod << 16) | ans); 199 | 200 | CCR_V_OFF(); 201 | if ( ans >= 0x8000 ) { 202 | CCR_N_ON(); 203 | CCR_Z_OFF(); 204 | } else { 205 | CCR_N_OFF(); 206 | if ( ans == 0 ) 207 | CCR_Z_ON(); 208 | else 209 | CCR_Z_OFF(); 210 | } 211 | return( FALSE ); 212 | } 213 | 214 | /* 215 |  機能:divs命令を実行する 216 | 戻り値: TRUE = 実行終了 217 | FALSE = 実行継続 218 | */ 219 | static int Divs( char code1, char code2 ) 220 | { 221 | char mode; 222 | char src_reg; 223 | char dst_reg; 224 | short waru; 225 | Long data; 226 | Long ans; 227 | short mod; 228 | Long save_pc; 229 | Long waru_l; 230 | 231 | save_pc = pc; 232 | mode = ((code2 & 0x38) >> 3); 233 | src_reg = (code2 & 0x07); 234 | dst_reg = ((code1 & 0x0E) >> 1); 235 | data = rd [ dst_reg ]; 236 | 237 | /* ソースのアドレッシングモードに応じた処理 */ 238 | if (get_data_at_ea(EA_Data, mode, src_reg, S_WORD, &waru_l)) { 239 | return(TRUE); 240 | } 241 | 242 | waru = (UShort)waru_l; 243 | 244 | if ( waru == 0 ) { 245 | err68a( "0で除算しました", __FILE__, __LINE__ ); 246 | return( TRUE ); 247 | } 248 | 249 | CCR_C_OFF(); 250 | ans = data / waru; 251 | mod = data % waru; 252 | if ( ans > 32767 || ans < -32768 ) { 253 | CCR_V_ON(); 254 | return( FALSE ); 255 | } 256 | rd [ dst_reg ] = ((mod << 16) | (ans & 0xFFFF)); 257 | 258 | CCR_V_OFF(); 259 | if ( ans < 0 ) { 260 | CCR_N_ON(); 261 | CCR_Z_OFF(); 262 | } else { 263 | CCR_N_OFF(); 264 | if ( ans == 0 ) 265 | CCR_Z_ON(); 266 | else 267 | CCR_Z_OFF(); 268 | } 269 | return( FALSE ); 270 | } 271 | 272 | /* 273 |  機能:or Dn,命令を実行する 274 | 戻り値: TRUE = 実行終了 275 | FALSE = 実行継続 276 | */ 277 | static int Or1( char code1, char code2 ) 278 | { 279 | char size; 280 | char mode; 281 | char src_reg; 282 | char dst_reg; 283 | Long data; 284 | Long save_pc; 285 | Long src_data; 286 | Long work_mode; 287 | 288 | save_pc = pc; 289 | size = ((code2 >> 6) & 0x03); 290 | mode = ((code2 & 0x38) >> 3); 291 | src_reg = ((code1 & 0x0E) >> 1); 292 | dst_reg = (code2 & 0x07); 293 | 294 | /* ソースのアドレッシングモードに応じた処理 */ 295 | if (get_data_at_ea(EA_All, EA_DD, src_reg, size, &src_data)) { 296 | return(TRUE); 297 | } 298 | 299 | /* アドレッシングモードがポストインクリメント間接の場合は間接でデータの取得 */ 300 | if (mode == EA_AIPI) { 301 | work_mode = EA_AI; 302 | } else { 303 | work_mode = mode; 304 | } 305 | 306 | if (get_data_at_ea_noinc(EA_VariableMemory, work_mode, dst_reg, size, &data)) { 307 | return(TRUE); 308 | } 309 | 310 | /* OR演算 */ 311 | data |= src_data; 312 | 313 | /* アドレッシングモードがプレデクリメント間接の場合は間接でデータの設定 */ 314 | if (mode == EA_AIPD) { 315 | work_mode = EA_AI; 316 | } else { 317 | work_mode = mode; 318 | } 319 | 320 | if (set_data_at_ea(EA_VariableMemory, work_mode, dst_reg, size, data)) { 321 | return(TRUE); 322 | } 323 | 324 | /* フラグの変化 */ 325 | general_conditions(data, size); 326 | 327 | return( FALSE ); 328 | } 329 | 330 | /* 331 |  機能:or ,Dn命令を実行する 332 | 戻り値: TRUE = 実行終了 333 | FALSE = 実行継続 334 | */ 335 | static int Or2( char code1, char code2 ) 336 | { 337 | char size; 338 | char mode; 339 | char src_reg; 340 | char dst_reg; 341 | Long src_data; 342 | Long save_pc; 343 | Long data; 344 | 345 | save_pc = pc; 346 | mode = ((code2 & 0x38) >> 3); 347 | src_reg = (code2 & 0x07); 348 | dst_reg = ((code1 & 0x0E) >> 1); 349 | size = ((code2 >> 6) & 0x03); 350 | 351 | /* ソースのアドレッシングモードに応じた処理 */ 352 | if (get_data_at_ea(EA_Data, mode, src_reg, size, &src_data)) { 353 | return(TRUE); 354 | } 355 | 356 | /* デスティネーションのアドレッシングモードに応じた処理 */ 357 | if (get_data_at_ea(EA_All, EA_DD, dst_reg, size, &data)) { 358 | return(TRUE); 359 | } 360 | 361 | data |= src_data; 362 | 363 | /* デスティネーションのアドレッシングモードに応じた処理 */ 364 | if (set_data_at_ea(EA_All, EA_DD, dst_reg, size, data)) { 365 | return(TRUE); 366 | } 367 | 368 | /* フラグの変化 */ 369 | general_conditions(data, size); 370 | 371 | return( FALSE ); 372 | } 373 | -------------------------------------------------------------------------------- /src/line9.c: -------------------------------------------------------------------------------- 1 | /* $Id: line9.c,v 1.3 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.2 2009/08/05 14:44:33 masamic 6 | * Some Bug fix, and implemented some instruction 7 | * Following Modification contributed by TRAP. 8 | * 9 | * Fixed Bug: In disassemble.c, shift/rotate as{lr},ls{lr},ro{lr} alway show word size. 10 | * Modify: enable KEYSNS, register behaiviour of sub ea, Dn. 11 | * Add: Nbcd, Sbcd. 12 | * 13 | * Revision 1.1.1.1 2001/05/23 11:22:07 masamic 14 | * First imported source code and docs 15 | * 16 | * Revision 1.6 1999/12/21 10:08:59 yfujii 17 | * Uptodate source code from Beppu. 18 | * 19 | * Revision 1.5 1999/12/07 12:45:13 yfujii 20 | * *** empty log message *** 21 | * 22 | * Revision 1.5 1999/11/22 03:57:08 yfujii 23 | * Condition code calculations are rewriten. 24 | * 25 | * Revision 1.3 1999/10/20 04:00:59 masamichi 26 | * Added showing more information about errors. 27 | * 28 | * Revision 1.2 1999/10/18 03:24:40 yfujii 29 | * Added RCS keywords and modified for WIN32 a little. 30 | * 31 | */ 32 | 33 | #undef MAIN 34 | 35 | #include 36 | #include "run68.h" 37 | 38 | static int Suba( char, char ); 39 | static int Subx( char, char ); 40 | static int Sub1( char, char ); 41 | static int Sub2( char, char ); 42 | 43 | /* 44 |  機能:9ライン命令を実行する 45 | 戻り値: TRUE = 実行終了 46 | FALSE = 実行継続 47 | */ 48 | int line9( char *pc_ptr ) 49 | { 50 | char code1, code2; 51 | 52 | code1 = *(pc_ptr++); 53 | code2 = *pc_ptr; 54 | pc += 2; 55 | 56 | if ( (code2 & 0xC0) == 0xC0 ) { 57 | return( Suba( code1, code2 ) ); 58 | } else { 59 | if ( (code1 & 0x01) == 1 ) { 60 | if ( (code2 & 0x30) == 0x00 ) 61 | return( Subx( code1, code2 ) ); 62 | else 63 | return( Sub1( code1, code2 ) ); 64 | } else { 65 | return( Sub2( code1, code2 ) ); 66 | } 67 | } 68 | } 69 | 70 | static int Suba( char code1, char code2 ) 71 | { 72 | char mode; 73 | char src_reg; 74 | char dst_reg; 75 | char size; 76 | Long src_data; 77 | Long save_pc; 78 | Long dest_data; 79 | 80 | save_pc = pc; 81 | dst_reg = ((code1 & 0x0E) >> 1); 82 | if ( (code1 & 0x01) == 0x01 ) 83 | size = S_LONG; 84 | else 85 | size = S_WORD; 86 | mode = ((code2 & 0x38) >> 3); 87 | src_reg = (code2 & 0x07); 88 | 89 | /* ソースのアドレッシングモードに応じた処理 */ 90 | if (size == S_BYTE) { 91 | err68a( "不正な命令: suba.b , An を実行しようとしました。", __FILE__, __LINE__ ); 92 | return(TRUE); 93 | } else if (get_data_at_ea(EA_All, mode, src_reg, size, &src_data)) { 94 | return(TRUE); 95 | } 96 | 97 | if ( size == S_WORD ) { 98 | if ( (src_data & 0x8000) != 0 ) { 99 | src_data |= 0xFFFF0000; 100 | } else { 101 | src_data &= 0x0000FFFF; 102 | } 103 | } 104 | 105 | dest_data = ra[dst_reg]; 106 | 107 | // sub演算 108 | ra[dst_reg] = sub_long(src_data, dest_data, S_LONG); 109 | // ra [ dst_reg ] -= src_data; 110 | 111 | #ifdef TRACE 112 | printf( "trace: suba.%c src=%d PC=%06lX\n", 113 | size_char [ size ], src_data, save_pc ); 114 | #endif 115 | 116 | /* フラグの変化はなし */ 117 | // sub_conditions(src_data, dest_data, ra[dst_reg], size, 1); 118 | 119 | return( FALSE ); 120 | } 121 | 122 | /* 123 |  機能:subx命令を実行する 124 | 戻り値: TRUE = 実行終了 125 | FALSE = 実行継続 126 | */ 127 | static int Subx( char code1, char code2 ) 128 | { 129 | char size; 130 | char src_reg; 131 | char dst_reg; 132 | short save_z; 133 | short save_x; 134 | Long dest_data; 135 | 136 | #ifdef TEST_CCR 137 | short before; 138 | #endif 139 | 140 | src_reg = (code2 & 0x07); 141 | dst_reg = ((code1 & 0x0E) >> 1); 142 | size = ((code2 >> 6) & 0x03); 143 | 144 | if ( (code2 & 0x08) != 0 ) { 145 | /* -(An), -(An) */ 146 | err68a( "未定義命令を実行しました", __FILE__, __LINE__ ); 147 | return( TRUE ); 148 | } 149 | 150 | #ifdef TEST_CCR 151 | before = sr & 0x1f; 152 | #endif 153 | dest_data = rd [ dst_reg ]; 154 | 155 | save_z = CCR_Z_REF() != 0 ? 1 : 0; 156 | save_x = CCR_X_REF() != 0 ? 1 : 0; 157 | // if ( CCR_X_REF() == 0 ) { 158 | // //rd [ dst_reg ] = sub_rd( dst_reg, rd [ src_reg ], size ); 159 | // rd [ dst_reg ] = sub_long(rd [ src_reg ], dest_data, size ); 160 | // } else { 161 | //rd [ dst_reg ] = sub_rd( dst_reg, rd [ src_reg ] + 1, size ); 162 | rd [ dst_reg ] = sub_long(rd [ src_reg ] + save_x, dest_data , size ); 163 | // } 164 | 165 | // if ( rd [ dst_reg ] == 0 ) { 166 | // if ( save_z == 0 ) 167 | // CCR_Z_OFF(); 168 | // } 169 | 170 | /* フラグの変化 */ 171 | sub_conditions(rd[src_reg], dest_data, rd[dst_reg], size, save_z); 172 | 173 | #ifdef TEST_CCR 174 | check("subx", rd[src_reg], dest_data, rd[dst_reg], size, before); 175 | #endif 176 | 177 | #ifdef TRACE 178 | switch( size ) { 179 | case S_BYTE: 180 | rd [ 8 ] = ( rd [ src_reg ] & 0xFF ); 181 | break; 182 | case S_WORD: 183 | rd [ 8 ] = ( rd [ src_reg ] & 0xFFFF); 184 | break; 185 | default: /* S_LONG */ 186 | rd [ 8 ] = rd [ src_reg ]; 187 | break; 188 | } 189 | printf( "trace: subx.%c src=%d PC=%06lX\n", 190 | size_char [ size ], rd [ 8 ], pc ); 191 | #endif 192 | 193 | return( FALSE ); 194 | } 195 | 196 | /* 197 |  機能:sub Dn,命令を実行する 198 | 戻り値: TRUE = 実行終了 199 | FALSE = 実行継続 200 | */ 201 | static int Sub1( char code1, char code2 ) 202 | { 203 | char size; 204 | char mode; 205 | char src_reg; 206 | char dst_reg; 207 | short disp = 0; 208 | Long save_pc; 209 | int work_mode; 210 | Long src_data; 211 | Long dest_data; 212 | 213 | #ifdef TEST_CCR 214 | short before; 215 | #endif 216 | 217 | save_pc = pc; 218 | mode = ((code2 & 0x38) >> 3); 219 | src_reg = ((code1 & 0x0E) >> 1); 220 | dst_reg = (code2 & 0x07); 221 | size = ((code2 >> 6) & 0x03); 222 | 223 | if (get_data_at_ea(EA_All, EA_DD, src_reg, size, &src_data)) { 224 | return(TRUE); 225 | } 226 | 227 | /* アドレッシングモードがポストインクリメント間接の場合は間接でデータの取得 */ 228 | if (mode == EA_AIPI) { 229 | work_mode = EA_AI; 230 | } else { 231 | work_mode = mode; 232 | } 233 | 234 | if (get_data_at_ea_noinc(EA_VariableMemory, work_mode, dst_reg, size, &dest_data)) { 235 | return(TRUE); 236 | } 237 | 238 | #ifdef TEST_CCR 239 | before = sr & 0x1f; 240 | #endif 241 | 242 | /* ワークレジスタへコピー */ 243 | rd [ 8 ] = dest_data; 244 | 245 | /* Sub演算 */ 246 | // rd [ 8 ] = sub_rd( 8, src_data, size ); 247 | rd [ 8 ] = sub_long(src_data, dest_data, size ); 248 | 249 | /* アドレッシングモードがプレデクリメント間接の場合は間接でデータの設定 */ 250 | if (mode == EA_AIPD) { 251 | work_mode = EA_AI; 252 | } else { 253 | work_mode = mode; 254 | } 255 | 256 | if (set_data_at_ea(EA_VariableMemory, work_mode, dst_reg, size, rd[8])) { 257 | return(TRUE); 258 | } 259 | 260 | /* フラグの変化 */ 261 | sub_conditions(src_data, dest_data, rd[ 8 ], size, 1); 262 | 263 | #ifdef TEST_CCR 264 | check("sub", src_data, dest_data, rd[8], size, before); 265 | #endif 266 | 267 | #ifdef TRACE 268 | switch( size ) { 269 | case S_BYTE: 270 | rd [ 8 ] = ( rd [ src_reg ] & 0xFF ); 271 | break; 272 | case S_WORD: 273 | rd [ 8 ] = ( rd [ src_reg ] & 0xFFFF); 274 | break; 275 | default: /* S_LONG */ 276 | rd [ 8 ] = rd [ src_reg ]; 277 | break; 278 | } 279 | printf( "trace: sub.%c src=%d PC=%06lX\n", 280 | size_char [ size ], rd [ 8 ], save_pc ); 281 | #endif 282 | 283 | return( FALSE ); 284 | } 285 | 286 | /* 287 |  機能:sub ,Dn命令を実行する 288 | 戻り値: TRUE = 実行終了 289 | FALSE = 実行継続 290 | */ 291 | static int Sub2( char code1, char code2 ) 292 | { 293 | char size; 294 | char mode; 295 | char src_reg; 296 | char dst_reg; 297 | Long src_data; 298 | Long save_pc; 299 | Long dest_data; 300 | 301 | #ifdef TEST_CCR 302 | short before; 303 | #endif 304 | 305 | save_pc = pc; 306 | mode = ((code2 & 0x38) >> 3); 307 | src_reg = (code2 & 0x07); 308 | dst_reg = ((code1 & 0x0E) >> 1); 309 | size = ((code2 >> 6) & 0x03); 310 | 311 | if (mode == EA_AD && size == S_BYTE) { 312 | err68a( "不正な命令: sub.b An, Dn を実行しようとしました。", __FILE__, __LINE__ ); 313 | return(TRUE); 314 | } else if (get_data_at_ea(EA_All, mode, src_reg, size, &src_data)) { 315 | return(TRUE); 316 | } 317 | 318 | /* レジスタへの格納である為、Long で値を得ておかないと、格納時に上位ワードを破壊してしまう */ 319 | if (get_data_at_ea(EA_All, EA_DD, dst_reg, S_LONG /*size*/, &dest_data)) { 320 | return(TRUE); 321 | } 322 | 323 | #ifdef TEST_CCR 324 | before = sr & 0x1f; 325 | #endif 326 | 327 | //rd [ dst_reg ] = sub_rd( dst_reg, src_data, size ); 328 | rd [ dst_reg ] = sub_long(src_data, dest_data, size ); 329 | 330 | /* フラグの変化 */ 331 | sub_conditions(src_data, dest_data, rd[ dst_reg ], size, 1); 332 | 333 | #ifdef TEST_CCR 334 | check("sub2", src_data, dest_data, rd[dst_reg], size, before); 335 | #endif 336 | 337 | #ifdef TRACE 338 | switch( size ) { 339 | case S_BYTE: 340 | rd [ 8 ] = (rd [ dst_reg ] & 0xFF); 341 | break; 342 | case S_WORD: 343 | rd [ 8 ] = (rd [ dst_reg ] & 0xFFFF); 344 | break; 345 | default: /* S_LONG */ 346 | rd [ 8 ] = rd [ dst_reg ]; 347 | break; 348 | } 349 | printf( "trace: sub.%c src=%d dst=%d PC=%06lX\n", 350 | size_char [ size ], src_data, rd [ 8 ], save_pc ); 351 | #endif 352 | 353 | return( FALSE ); 354 | } 355 | -------------------------------------------------------------------------------- /src/lineb.c: -------------------------------------------------------------------------------- 1 | /* $Id: lineb.c,v 1.2 2009/08/08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: lineb.c,v $ 5 | * Revision 1.2 2009/08/08 06:49:44 masamic 6 | * Convert Character Encoding Shifted-JIS to UTF-8. 7 | * 8 | * Revision 1.1.1.1 2001/05/23 11:22:08 masamic 9 | * First imported source code and docs 10 | * 11 | * Revision 1.7 1999/12/21 10:08:59 yfujii 12 | * Uptodate source code from Beppu. 13 | * 14 | * Revision 1.6 1999/12/07 12:45:26 yfujii 15 | * *** empty log message *** 16 | * 17 | * Revision 1.6 1999/11/22 03:57:08 yfujii 18 | * Condition code calculations are rewriten. 19 | * 20 | * Revision 1.4 1999/10/25 04:22:27 masamichi 21 | * Full implements EOR instruction. 22 | * 23 | * Revision 1.3 1999/10/20 04:14:48 masamichi 24 | * Added showing more information about errors. 25 | * 26 | * Revision 1.2 1999/10/18 03:24:40 yfujii 27 | * Added RCS keywords and modified for WIN32 a little. 28 | * 29 | */ 30 | 31 | #undef MAIN 32 | 33 | #include 34 | #include "run68.h" 35 | 36 | static int Cmp( char, char ); 37 | static int Cmpa( char, char ); 38 | static int Cmpm( char, char ); 39 | static int Eor( char, char ); 40 | 41 | /* 42 |  機能:Bライン命令を実行する 43 | 戻り値: TRUE = 実行終了 44 | FALSE = 実行継続 45 | */ 46 | int lineb( char *pc_ptr ) 47 | { 48 | char code1, code2; 49 | 50 | code1 = *(pc_ptr++); 51 | code2 = *pc_ptr; 52 | pc += 2; 53 | 54 | if ( (code1 & 0x01) == 0x00 ) { 55 | if ( (code2 & 0xC0) == 0xC0 ) 56 | return( Cmpa( code1, code2 ) ); 57 | return( Cmp( code1, code2 ) ); 58 | } 59 | 60 | if ( (code2 & 0xC0) == 0xC0 ) 61 | return( Cmpa( code1, code2 ) ); 62 | 63 | if ( (code2 & 0x38) == 0x08 ) 64 | return( Cmpm( code1, code2 ) ); 65 | 66 | return( Eor( code1, code2 ) ); 67 | } 68 | 69 | /* 70 |  機能:cmpi命令を実行する 71 | 戻り値: TRUE = 実行終了 72 | FALSE = 実行継続 73 | */ 74 | static int Cmp( char code1, char code2 ) 75 | { 76 | char size; 77 | char mode; 78 | char src_reg; 79 | char dst_reg; 80 | Long src_data; 81 | Long save_pc; 82 | short save_x; 83 | Long dest_data; 84 | Long result; 85 | 86 | #ifdef TEST_CCR 87 | short before; 88 | #endif 89 | 90 | save_pc = pc; 91 | size = ((code2 >> 6) & 0x03); 92 | mode = ((code2 & 0x38) >> 3); 93 | src_reg = (code2 & 0x07); 94 | dst_reg = ((code1 & 0x0E) >> 1); 95 | 96 | /* ソースのアドレッシングモードに応じた処理 */ 97 | if (mode == EA_AD && size == S_BYTE) { 98 | err68a( "不正な命令: cmp.b An, Dn を実行しようとしました。", __FILE__, __LINE__ ); 99 | return(TRUE); 100 | } else if (get_data_at_ea(EA_All, mode, src_reg, size, &src_data)) { 101 | return(TRUE); 102 | } 103 | 104 | /* ディスティネーションのアドレッシングモードに応じた処理 */ 105 | if (get_data_at_ea(EA_All, EA_DD, dst_reg, size, &dest_data)) { 106 | return(TRUE); 107 | } 108 | 109 | #ifdef TEST_CCR 110 | before = sr & 0x1f; 111 | #endif 112 | 113 | /* サイズに応じてCCRをセットする */ 114 | save_x = CCR_X_REF(); 115 | // result = sub_rd( dst_reg, src_data, size ); 116 | result = sub_long(src_data, dest_data, size); 117 | // if ( save_x == 0 ) 118 | // CCR_X_OFF(); 119 | // else 120 | // CCR_X_ON(); 121 | 122 | /* 先のフラグ変化を無視する */ 123 | /* フラグの変化 */ 124 | cmp_conditions(src_data, dest_data, result, size); 125 | 126 | #ifdef TEST_CCR 127 | check("cmp", src_data, dest_data, result, size, before); 128 | #endif 129 | 130 | #ifdef TRACE 131 | switch( size ) { 132 | case S_BYTE: 133 | rd [ 8 ] = ( rd [ dst_reg ] & 0xFF ); 134 | break; 135 | case S_WORD: 136 | rd [ 8 ] = ( rd [ dst_reg ] & 0xFFFF); 137 | break; 138 | default: /* S_LONG */ 139 | rd [ 8 ] = rd [ dst_reg ]; 140 | break; 141 | } 142 | printf( "trace: cmp.%c src=%d dst=%d PC=%06lX\n", 143 | size_char [ size ], src_data, rd [ 8 ], save_pc ); 144 | #endif 145 | 146 | return( FALSE ); 147 | } 148 | 149 | /* 150 |  機能:cmpa命令を実行する 151 | 戻り値: TRUE = 実行終了 152 | FALSE = 実行継続 153 | */ 154 | static int Cmpa( char code1, char code2 ) 155 | { 156 | char size; 157 | char mode; 158 | char src_reg; 159 | char dst_reg; 160 | Long src_data; 161 | Long save_pc; 162 | Long old; 163 | Long ans; 164 | Long dest_data; 165 | 166 | #ifdef TEST_CCR 167 | short before; 168 | #endif 169 | 170 | save_pc = pc; 171 | if ( (code1 & 0x01) == 0 ) 172 | size = S_WORD; 173 | else 174 | size = S_LONG; 175 | mode = ((code2 & 0x38) >> 3); 176 | src_reg = (code2 & 0x07); 177 | dst_reg = ((code1 & 0x0E) >> 1); 178 | 179 | /* ソースのアドレッシングモードに応じた処理 */ 180 | if (size == S_BYTE) { 181 | err68a( "不正な命令: cmp.b , An を実行しようとしました。", __FILE__, __LINE__ ); 182 | return(TRUE); 183 | } else if (get_data_at_ea(EA_All, mode, src_reg, size, &src_data)) { 184 | return(TRUE); 185 | } 186 | 187 | /* ディスティネーションのアドレッシングモードに応じた処理 */ 188 | if (get_data_at_ea(EA_All, EA_AD, dst_reg, size, &dest_data)) { 189 | return(TRUE); 190 | } 191 | 192 | if ( size == S_WORD ) { 193 | if ( (src_data & 0x8000) != 0 ) 194 | src_data |= 0xFFFF0000; 195 | } 196 | 197 | #ifdef TRACE 198 | printf( "trace: cmpa.%c src=%d PC=%06lX\n", 199 | size_char [ size ], src_data, save_pc ); 200 | #endif 201 | 202 | #ifdef TEST_CCR 203 | before = sr & 0x1f; 204 | #endif 205 | old = ra [ dst_reg ]; 206 | ans = old - src_data; 207 | 208 | #if 0 209 | carry = ((old >> 1) & 0x7FFFFFFF) - ((src_data >> 1) & 0x7FFFFFFF); 210 | if ( (old & 0x1) == 0 && (src_data & 0x1) > 0 ) 211 | carry --; 212 | if (carry < 0) { 213 | CCR_C_ON(); 214 | CCR_V_OFF(); 215 | } else { 216 | CCR_C_OFF(); 217 | if ( (old & 0x80000000) == 0 && (ans & 0x80000000) != 0 ) 218 | CCR_V_ON(); 219 | else 220 | CCR_V_OFF(); 221 | } 222 | if ( ans < 0 ) { 223 | CCR_N_ON(); 224 | CCR_Z_OFF(); 225 | } else { 226 | CCR_N_OFF(); 227 | if ( ans == 0 ) 228 | CCR_Z_ON(); 229 | else 230 | CCR_Z_OFF(); 231 | } 232 | 233 | /* 先のフラグ変化を無視する */ 234 | #endif 235 | 236 | /* フラグの変化 */ 237 | cmp_conditions(src_data, old, ans, size); 238 | 239 | #ifdef TEST_CCR 240 | check("cmpa", src_data, dest_data, ans, size, before); 241 | #endif 242 | 243 | return( FALSE ); 244 | } 245 | 246 | /* 247 |  機能:cmpm命令を実行する 248 | 戻り値: TRUE = 実行終了 249 | FALSE = 実行継続 250 | */ 251 | static int Cmpm( char code1, char code2 ) 252 | { 253 | char size; 254 | char src_reg; 255 | char dst_reg; 256 | Long src_data; 257 | Long dest_data; 258 | Long result; 259 | 260 | size = ((code2 >> 6) & 0x03); 261 | src_reg = (code2 & 0x07); 262 | dst_reg = ((code1 & 0x0E) >> 1); 263 | 264 | /* ソースのアドレッシングモードに応じた処理 */ 265 | if (get_data_at_ea(EA_All, EA_AIPI, src_reg, size, &src_data)) { 266 | return(TRUE); 267 | } 268 | 269 | /* ディスティネーションのアドレッシングモードに応じた処理 */ 270 | if (get_data_at_ea(EA_All, EA_AIPI, dst_reg, size, &dest_data)) { 271 | return(TRUE); 272 | } 273 | 274 | rd [ 8 ] = dest_data; 275 | 276 | /* サイズに応じてCCRをセットする */ 277 | // save_x = CCR_X_REF(); 278 | // result = sub_rd( 8, src_data, size ); 279 | result = sub_long(src_data, dest_data, size); 280 | // if ( save_x == 0 ) 281 | // CCR_X_OFF(); 282 | // else 283 | // CCR_X_ON(); 284 | 285 | /* 先のフラグ変化を無視する */ 286 | /* フラグの変化 */ 287 | cmp_conditions(src_data, dest_data, result, size); 288 | 289 | 290 | #ifdef TRACE 291 | printf( "trace: cmpm.%c src=%d dst=%d PC=%06lX\n", 292 | size_char [ size ], src_data, rd [ 8 ], pc ); 293 | #endif 294 | 295 | 296 | return( FALSE ); 297 | } 298 | 299 | /* 300 |  機能:eor命令を実行する 301 | 戻り値: TRUE = 実行終了 302 | FALSE = 実行継続 303 | */ 304 | static int Eor( char code1, char code2 ) 305 | { 306 | char size; 307 | char mode; 308 | char src_reg; 309 | char dst_reg; 310 | Long data; 311 | Long save_pc; 312 | Long src_data; 313 | int work_mode; 314 | 315 | save_pc = pc; 316 | size = ((code2 >> 6) & 0x03); 317 | mode = ((code2 & 0x38) >> 3); 318 | src_reg = ((code1 & 0x0E) >> 1); 319 | dst_reg = (code2 & 0x07); 320 | 321 | /* ソースのアドレッシングモードに応じた処理 */ 322 | if (get_data_at_ea(EA_All, EA_DD, src_reg, size, &src_data)) { 323 | return(TRUE); 324 | } 325 | 326 | /* アドレッシングモードがポストインクリメント間接の場合は間接でデータの取得 */ 327 | if (mode == EA_AIPI) { 328 | work_mode = EA_AI; 329 | } else { 330 | work_mode = mode; 331 | } 332 | 333 | if (get_data_at_ea_noinc(EA_VariableData, work_mode, dst_reg, size, &data)) { 334 | return(TRUE); 335 | } 336 | 337 | /* EOR演算 */ 338 | data ^= src_data; 339 | 340 | /* アドレッシングモードがプレデクリメント間接の場合は間接でデータの設定 */ 341 | if (mode == EA_AIPD) { 342 | work_mode = EA_AI; 343 | } else { 344 | work_mode = mode; 345 | } 346 | 347 | if (set_data_at_ea(EA_VariableData, work_mode, dst_reg, size, data)) { 348 | return(TRUE); 349 | } 350 | 351 | /* フラグの変化 */ 352 | general_conditions(data, size); 353 | 354 | #ifdef TRACE 355 | printf( "trace: eor.%c src=%d PC=%06lX\n", 356 | size_char [ size ], rd [ src_reg ], save_pc ); 357 | #endif 358 | 359 | return( FALSE ); 360 | } 361 | -------------------------------------------------------------------------------- /src/linec.c: -------------------------------------------------------------------------------- 1 | /* $Id: linec.c,v 1.3 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.2 2009/08/05 14:44:33 masamic 6 | * Some Bug fix, and implemented some instruction 7 | * Following Modification contributed by TRAP. 8 | * 9 | * Fixed Bug: In disassemble.c, shift/rotate as{lr},ls{lr},ro{lr} alway show word size. 10 | * Modify: enable KEYSNS, register behaiviour of sub ea, Dn. 11 | * Add: Nbcd, Sbcd. 12 | * 13 | * Revision 1.1.1.1 2001/05/23 11:22:08 masamic 14 | * First imported source code and docs 15 | * 16 | * Revision 1.7 1999/12/21 10:08:59 yfujii 17 | * Uptodate source code from Beppu. 18 | * 19 | * Revision 1.6 1999/12/07 12:45:42 yfujii 20 | * *** empty log message *** 21 | * 22 | * Revision 1.6 1999/11/22 03:57:08 yfujii 23 | * Condition code calculations are rewriten. 24 | * 25 | * Revision 1.4 1999/11/01 12:10:21 masamichi 26 | * Maybe correct error at code: $C073 27 | * 28 | * Revision 1.3 1999/10/20 04:14:48 masamichi 29 | * Added showing more information about errors. 30 | * 31 | * Revision 1.2 1999/10/18 03:24:40 yfujii 32 | * Added RCS keywords and modified for WIN32 a little. 33 | * 34 | */ 35 | 36 | #undef MAIN 37 | 38 | #include 39 | #include "run68.h" 40 | 41 | static int And1( char, char ); 42 | static int And2( char, char ); 43 | static int Exg( char, char ); 44 | static int Mulu( char, char ); 45 | static int Muls( char, char ); 46 | 47 | /* 48 |  機能:Cライン命令を実行する 49 | 戻り値: TRUE = 実行終了 50 | FALSE = 実行継続 51 | */ 52 | int linec( char *pc_ptr ) 53 | { 54 | char code1, code2; 55 | 56 | code1 = *(pc_ptr++); 57 | code2 = *pc_ptr; 58 | pc += 2; 59 | if ( (code1 & 0x01) == 0 ) { 60 | if ( (code2 & 0xC0) == 0xC0 ) 61 | return( Mulu( code1, code2 ) ); 62 | return( And2( code1, code2 ) ); 63 | } else { 64 | if ( (code2 & 0xC0) == 0xC0 ) 65 | return( Muls( code1, code2 ) ); 66 | if ( (code2 & 0xF0) == 0x00 ) { 67 | /* abcd */ 68 | char src_reg = (code2 & 0x7); 69 | char dst_reg = ((code1 & 0xE) >> 1); 70 | char size = 0; /* S_BYTE 固定 */ 71 | Long src_data; 72 | Long dst_data; 73 | Long low; 74 | Long high; 75 | Long kekka; 76 | Long X; 77 | 78 | if ( (code2 & 0x8) != 0 ) { 79 | /* -(am),-(an); */ 80 | if ( get_data_at_ea(EA_All, EA_AIPD, src_reg, size, &src_data) ) { 81 | return( TRUE ); 82 | } 83 | if ( get_data_at_ea(EA_All, EA_AIPD, dst_reg, size, &dst_data) ) { 84 | return( TRUE ); 85 | } 86 | }else{ 87 | /* dm,dn; */ 88 | if ( get_data_at_ea(EA_All, EA_DD, src_reg, size, &src_data) ) { 89 | return( TRUE ); 90 | } 91 | if ( get_data_at_ea(EA_All, EA_DD, dst_reg, size, &dst_data) ) { 92 | return( TRUE ); 93 | } 94 | } 95 | 96 | X = (CCR_X_REF() != 0) ? 1 : 0; 97 | 98 | low = (src_data & 0x0f) + (dst_data & 0x0f) + X; 99 | if ( low >= 0x0a ) { 100 | low += 0x06; 101 | } 102 | 103 | high = (src_data & 0xf0) + (dst_data & 0xf0) + (low & 0xf0); 104 | if ( high >= 0xa0 ) { 105 | high += 0x60; 106 | } 107 | 108 | if ( high >= 0x100 ) { 109 | CCR_X_ON(); 110 | CCR_C_ON(); 111 | }else{ 112 | CCR_X_OFF(); 113 | CCR_C_OFF(); 114 | } 115 | 116 | kekka = (high & 0xf0) | (low & 0x0f); 117 | 118 | /* 0 以外の値になった時のみ、Z フラグをリセットする */ 119 | if ( kekka != 0 ) { 120 | CCR_Z_OFF(); 121 | } 122 | 123 | /* Nフラグは結果に応じて立てる */ 124 | if ( kekka & 0x80 ) { 125 | CCR_N_ON(); 126 | }else{ 127 | CCR_N_OFF(); 128 | } 129 | 130 | /* Vフラグ */ 131 | if ( dst_data < 0x80 ) { 132 | if ( 5 <= (dst_data & 0x0f) ) { 133 | if ( (0x80 <= kekka) && (kekka <= 0x85) ) { 134 | CCR_V_ON(); 135 | }else{ 136 | CCR_V_OFF(); 137 | } 138 | }else{ 139 | if ( (0x80 <= kekka) && (kekka <= (0x80 + (dst_data & 0x0f))) ) { 140 | CCR_V_ON(); 141 | }else{ 142 | CCR_V_OFF(); 143 | } 144 | } 145 | }else{ 146 | if ( (0x80 <= kekka) && (kekka <= dst_data) ) { 147 | CCR_V_ON(); 148 | }else{ 149 | CCR_V_OFF(); 150 | } 151 | } 152 | 153 | dst_data = kekka; 154 | 155 | if ( (code2 & 0x8) != 0 ) { 156 | /* -(am),-(an); */ 157 | if ( set_data_at_ea(EA_All, EA_AI, dst_reg, size, dst_data) ) { 158 | return( TRUE ); 159 | } 160 | }else{ 161 | /* dm,dn; */ 162 | if ( set_data_at_ea(EA_All, EA_DD, dst_reg, size, dst_data) ) { 163 | return( TRUE ); 164 | } 165 | } 166 | 167 | return( FALSE ); 168 | /* 169 | err68a( "未定義命令(abcd)を実行しました", __FILE__, __LINE__ ); 170 | return( TRUE ); abcd 171 | */ 172 | } 173 | if ( (code2 & 0x30) == 0x00 ) { 174 | return( Exg( code1, code2 ) ); 175 | } 176 | return( And1( code1, code2 ) ); 177 | } 178 | } 179 | 180 | /* 181 |  機能:and Dn,命令を実行する 182 | 戻り値: TRUE = 実行終了 183 | FALSE = 実行継続 184 | */ 185 | static int And1( char code1, char code2 ) 186 | { 187 | char size; 188 | char mode; 189 | char src_reg; 190 | char dst_reg; 191 | short disp = 0; 192 | Long data; 193 | Long save_pc; 194 | int work_mode; 195 | Long src_data; 196 | 197 | save_pc = pc; 198 | size = ((code2 >> 6) & 0x03); 199 | mode = ((code2 & 0x38) >> 3); 200 | src_reg = ((code1 & 0x0E) >> 1); 201 | dst_reg = (code2 & 0x07); 202 | 203 | /* ソースのアドレッシングモードに応じた処理 */ 204 | if (get_data_at_ea(EA_All, EA_DD, src_reg, size, &src_data)) { 205 | return(TRUE); 206 | } 207 | 208 | /* アドレッシングモードがポストインクリメント間接の場合は間接でデータの取得 */ 209 | if (mode == EA_AIPI) { 210 | work_mode = EA_AI; 211 | } else { 212 | work_mode = mode; 213 | } 214 | 215 | if (get_data_at_ea_noinc(EA_VariableMemory, work_mode, dst_reg, size, &data)) { 216 | return(TRUE); 217 | } 218 | 219 | /* AND演算 */ 220 | data &= src_data; 221 | 222 | /* アドレッシングモードがプレデクリメント間接の場合は間接でデータの設定 */ 223 | if (mode == EA_AIPD) { 224 | work_mode = EA_AI; 225 | } else { 226 | work_mode = mode; 227 | } 228 | 229 | if (set_data_at_ea(EA_VariableMemory, work_mode, dst_reg, size, data)) { 230 | return(TRUE); 231 | } 232 | 233 | /* フラグの変化 */ 234 | general_conditions(data, size); 235 | 236 | #ifdef TRACE 237 | switch( size ) { 238 | case S_BYTE: 239 | rd [ 8 ] = ( rd [ src_reg ] & 0xFF ); 240 | break; 241 | case S_WORD: 242 | rd [ 8 ] = ( rd [ src_reg ] & 0xFFFF); 243 | break; 244 | default: /* S_LONG */ 245 | rd [ 8 ] = rd [ src_reg ]; 246 | break; 247 | } 248 | printf( "trace: and.%c src=0x%08X PC=%06lX\n", 249 | size_char [ size ], rd [ 8 ], save_pc ); 250 | #endif 251 | 252 | return( FALSE ); 253 | } 254 | 255 | /* 256 |  機能:and ,Dn命令を実行する 257 | 戻り値: TRUE = 実行終了 258 | FALSE = 実行継続 259 | */ 260 | static int And2( char code1, char code2 ) 261 | { 262 | char size; 263 | char mode; 264 | char src_reg; 265 | char dst_reg; 266 | Long src_data; 267 | Long save_pc; 268 | int work_pc; 269 | Long data; 270 | 271 | save_pc = pc; 272 | work_pc = pc; 273 | mode = ((code2 & 0x38) >> 3); 274 | src_reg = (code2 & 0x07); 275 | dst_reg = ((code1 & 0x0E) >> 1); 276 | size = ((code2 >> 6) & 0x03); 277 | 278 | 279 | /* ソースのアドレッシングモードに応じた処理 */ 280 | if (get_data_at_ea(EA_Data, mode, src_reg, size, &src_data)) { 281 | return(TRUE); 282 | } 283 | 284 | /* デスティネーションのアドレッシングモードに応じた処理 */ 285 | if (get_data_at_ea(EA_All, EA_DD, dst_reg, size, &data)) { 286 | return(TRUE); 287 | } 288 | 289 | /* AND演算 */ 290 | data &= src_data; 291 | 292 | if (set_data_at_ea(EA_All, EA_DD, dst_reg, size, data)) { 293 | return(TRUE); 294 | } 295 | 296 | /* フラグの変化 */ 297 | general_conditions(data, size); 298 | 299 | return( FALSE ); 300 | } 301 | 302 | /* 303 |  機能:exg命令を実行する 304 | 戻り値: TRUE = 実行終了 305 | FALSE = 実行継続 306 | */ 307 | static int Exg( char code1, char code2 ) 308 | { 309 | char src_reg; 310 | char dst_reg; 311 | char mode; 312 | Long tmp; 313 | 314 | mode = ((code2 & 0xF8) >> 3); 315 | src_reg = ((code1 & 0x0E) >> 1); 316 | dst_reg = (code2 & 0x07); 317 | 318 | switch( mode ) { 319 | case 0x08: 320 | tmp = rd [ src_reg ]; 321 | rd [ src_reg ] = rd [ dst_reg ]; 322 | rd [ dst_reg ] = tmp; 323 | break; 324 | case 0x09: 325 | tmp = ra [ src_reg ]; 326 | ra [ src_reg ] = ra [ dst_reg ]; 327 | ra [ dst_reg ] = tmp; 328 | break; 329 | case 0x11: 330 | tmp = rd [ src_reg ]; 331 | rd [ src_reg ] = ra [ dst_reg ]; 332 | ra [ dst_reg ] = tmp; 333 | break; 334 | default: 335 | err68a( "EXG: 不正なOPモードです。", __FILE__, __LINE__ ); 336 | return( TRUE ); 337 | } 338 | 339 | #ifdef TRACE 340 | printf( "trace: exg PC=%06lX\n", pc ); 341 | #endif 342 | 343 | return( FALSE ); 344 | } 345 | 346 | /* 347 |  機能:mulu命令を実行する 348 | 戻り値: TRUE = 実行終了 349 | FALSE = 実行継続 350 | */ 351 | static int Mulu( char code1, char code2 ) 352 | { 353 | char src_reg; 354 | char dst_reg; 355 | char mode; 356 | UShort src_data; 357 | UShort dst_data; 358 | ULong ans; 359 | Long save_pc; 360 | Long src_data_l; 361 | 362 | save_pc = pc; 363 | mode = ((code2 & 0x38) >> 3); 364 | src_reg = (code2 & 0x07); 365 | dst_reg = ((code1 & 0x0E) >> 1); 366 | 367 | dst_data = (rd [ dst_reg ] & 0xFFFF); 368 | 369 | /* ソースのアドレッシングモードに応じた処理 */ 370 | if (get_data_at_ea(EA_Data, mode, src_reg, S_WORD, &src_data_l)) { 371 | return(TRUE); 372 | } 373 | src_data = (UShort)src_data_l; 374 | 375 | ans = src_data * dst_data; 376 | rd [ dst_reg ] = ans; 377 | #ifdef TRACE 378 | printf( "trace: mulu src=%u PC=%06lX\n", src_data, save_pc ); 379 | #endif 380 | 381 | /* フラグの変化 */ 382 | general_conditions(ans, S_LONG); 383 | 384 | return( FALSE ); 385 | } 386 | 387 | /* 388 |  機能:muls命令を実行する 389 | 戻り値: TRUE = 実行終了 390 | FALSE = 実行継続 391 | */ 392 | static int Muls( char code1, char code2 ) 393 | { 394 | char src_reg; 395 | char dst_reg; 396 | char mode; 397 | short src_data; 398 | short dst_data; 399 | Long ans; 400 | Long save_pc; 401 | Long src_data_l; 402 | 403 | save_pc = pc; 404 | mode = ((code2 & 0x38) >> 3); 405 | src_reg = (code2 & 0x07); 406 | dst_reg = ((code1 & 0x0E) >> 1); 407 | 408 | dst_data = (rd [ dst_reg ] & 0xFFFF); 409 | 410 | /* ソースのアドレッシングモードに応じた処理 */ 411 | if (get_data_at_ea(EA_Data, mode, src_reg, S_WORD, &src_data_l)) { 412 | return(TRUE); 413 | } 414 | src_data = (UShort)src_data_l; 415 | 416 | ans = src_data * dst_data; 417 | rd [ dst_reg ] = ans; 418 | 419 | #ifdef TRACE 420 | printf( "trace: muls src=%d PC=%06lX\n", src_data, save_pc ); 421 | #endif 422 | 423 | /* フラグの変化 */ 424 | general_conditions(ans, S_LONG); 425 | 426 | return( FALSE ); 427 | } 428 | -------------------------------------------------------------------------------- /src/lined.c: -------------------------------------------------------------------------------- 1 | /* $Id: lined.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:08 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.5 1999/12/21 10:08:59 yfujii 9 | * Uptodate source code from Beppu. 10 | * 11 | * Revision 1.4 1999/12/07 12:45:54 yfujii 12 | * *** empty log message *** 13 | * 14 | * Revision 1.4 1999/11/22 03:57:08 yfujii 15 | * Condition code calculations are rewriten. 16 | * 17 | * Revision 1.3 1999/10/20 04:14:48 masamichi 18 | * Added showing more information about errors. 19 | * 20 | * Revision 1.2 1999/10/18 03:24:40 yfujii 21 | * Added RCS keywords and modified for WIN32 a little. 22 | * 23 | */ 24 | 25 | #undef MAIN 26 | 27 | #include 28 | #include "run68.h" 29 | 30 | static int Adda( char, char ); 31 | static int Addx( char, char ); 32 | static int Add1( char, char ); 33 | static int Add2( char, char ); 34 | 35 | /* 36 |  機能:Dライン命令を実行する 37 | 戻り値: TRUE = 実行終了 38 | FALSE = 実行継続 39 | */ 40 | int lined( char *pc_ptr ) 41 | { 42 | char code1, code2; 43 | 44 | code1 = *(pc_ptr++); 45 | code2 = *pc_ptr; 46 | pc += 2; 47 | 48 | if ( (code2 & 0xC0) == 0xC0 ) { 49 | return( Adda( code1, code2 ) ); 50 | } else { 51 | if ( (code1 & 0x01) == 1 ) { 52 | if ( (code2 & 0x30) == 0x00 ) 53 | return( Addx( code1, code2 ) ); 54 | else 55 | return( Add1( code1, code2 ) ); 56 | } else { 57 | return( Add2( code1, code2 ) ); 58 | } 59 | } 60 | } 61 | 62 | static int Adda( char code1, char code2 ) 63 | { 64 | char mode; 65 | char src_reg; 66 | char dst_reg; 67 | char size; 68 | Long src_data; 69 | Long save_pc; 70 | 71 | save_pc = pc; 72 | dst_reg = ((code1 & 0x0E) >> 1); 73 | if ( (code1 & 0x01) == 0x01 ) 74 | size = S_LONG; 75 | else 76 | size = S_WORD; 77 | mode = ((code2 & 0x38) >> 3); 78 | src_reg = (code2 & 0x07); 79 | 80 | 81 | /* ソースのアドレッシングモードに応じた処理 */ 82 | if (size == S_BYTE) { 83 | err68a( "不正な命令: adda.b , An を実行しようとしました。", __FILE__, __LINE__ ); 84 | return(TRUE); 85 | } else if (get_data_at_ea(EA_All, mode, src_reg, size, &src_data)) { 86 | return(TRUE); 87 | } 88 | 89 | if ( size == S_WORD ) { 90 | if ( (src_data & 0x8000) != 0 ) { 91 | src_data |= 0xFFFF0000; 92 | } else { 93 | src_data &= 0x0000FFFF; 94 | } 95 | } 96 | 97 | ra [ dst_reg ] += src_data; 98 | 99 | #ifdef TRACE 100 | printf( "trace: adda.%c src=%d PC=%06lX\n", 101 | size_char [ size ], src_data, save_pc ); 102 | #endif 103 | 104 | return( FALSE ); 105 | } 106 | 107 | static int Addx( char code1, char code2 ) 108 | { 109 | char size; 110 | char src_reg; 111 | char dst_reg; 112 | short save_z; 113 | short save_x; 114 | Long dest_data; 115 | 116 | src_reg = (code2 & 0x07); 117 | dst_reg = ((code1 & 0x0E) >> 1); 118 | size = ((code2 >> 6) & 0x03); 119 | 120 | if ( (code2 & 0x08) != 0 ) { 121 | /* -(An), -(An) */ 122 | err68a( "未定義命令を実行しました", __FILE__, __LINE__ ); 123 | return( TRUE ); 124 | } 125 | 126 | dest_data = rd [ dst_reg ]; 127 | 128 | save_z = CCR_Z_REF() != 0 ? 1 : 0; 129 | save_x = CCR_X_REF() != 0 ? 1 : 0; 130 | rd [ dst_reg ] = add_long(rd [ src_reg ] + save_x, dest_data , size ); 131 | 132 | /* フラグの変化 */ 133 | add_conditions(rd[src_reg], dest_data, rd[dst_reg], size, save_z); 134 | 135 | #ifdef TRACE 136 | switch( size ) { 137 | case S_BYTE: 138 | rd [ 8 ] = ( rd [ src_reg ] & 0xFF ); 139 | break; 140 | case S_WORD: 141 | rd [ 8 ] = ( rd [ src_reg ] & 0xFFFF); 142 | break; 143 | default: /* S_LONG */ 144 | rd [ 8 ] = rd [ src_reg ]; 145 | break; 146 | } 147 | printf( "trace: addx.%c src=%d PC=%06lX\n", 148 | size_char [ size ], rd [ 8 ], pc ); 149 | #endif 150 | 151 | return( FALSE ); 152 | } 153 | 154 | /* 155 |  機能:add Dn,命令を実行する 156 | 戻り値: TRUE = 実行終了 157 | FALSE = 実行継続 158 | */ 159 | static int Add1( char code1, char code2 ) 160 | { 161 | char size; 162 | char mode; 163 | char src_reg; 164 | char dst_reg; 165 | short disp = 0; 166 | Long save_pc; 167 | int work_mode; 168 | Long src_data; 169 | Long dest_data; 170 | 171 | save_pc = pc; 172 | mode = ((code2 & 0x38) >> 3); 173 | src_reg = ((code1 & 0x0E) >> 1); 174 | dst_reg = (code2 & 0x07); 175 | size = ((code2 >> 6) & 0x03); 176 | 177 | if (get_data_at_ea(EA_All, EA_DD, src_reg, size, &src_data)) { 178 | return(TRUE); 179 | } 180 | 181 | /* アドレッシングモードがポストインクリメント間接の場合は間接でデータの取得 */ 182 | if (mode == EA_AIPI) { 183 | work_mode = EA_AI; 184 | } else { 185 | work_mode = mode; 186 | } 187 | 188 | if (get_data_at_ea_noinc(EA_VariableMemory, work_mode, dst_reg, size, &dest_data)) { 189 | return(TRUE); 190 | } 191 | 192 | /* Sub演算 */ 193 | rd [ 8 ] = add_long(src_data, dest_data, size ); 194 | 195 | /* アドレッシングモードがプレデクリメント間接の場合は間接でデータの設定 */ 196 | if (mode == EA_AIPD) { 197 | work_mode = EA_AI; 198 | } else { 199 | work_mode = mode; 200 | } 201 | 202 | if (set_data_at_ea(EA_VariableMemory, work_mode, dst_reg, size, rd[8])) { 203 | return(TRUE); 204 | } 205 | 206 | /* フラグの変化 */ 207 | sub_conditions(src_data, dest_data, rd[ 8 ], size, 1); 208 | 209 | #ifdef TRACE 210 | switch( size ) { 211 | case S_BYTE: 212 | rd [ 8 ] = ( rd [ src_reg ] & 0xFF ); 213 | break; 214 | case S_WORD: 215 | rd [ 8 ] = ( rd [ src_reg ] & 0xFFFF); 216 | break; 217 | default: /* S_LONG */ 218 | rd [ 8 ] = rd [ src_reg ]; 219 | break; 220 | } 221 | printf( "trace: add.%c src=%d PC=%06lX\n", 222 | size_char [ size ], rd [ 8 ], save_pc ); 223 | #endif 224 | 225 | return( FALSE ); 226 | } 227 | 228 | /* 229 |  機能:add ,Dn命令を実行する 230 | 戻り値: TRUE = 実行終了 231 | FALSE = 実行継続 232 | */ 233 | static int Add2( char code1, char code2 ) 234 | { 235 | char size; 236 | char mode; 237 | char src_reg; 238 | char dst_reg; 239 | Long src_data; 240 | Long save_pc; 241 | Long dest_data; 242 | 243 | save_pc = pc; 244 | mode = ((code2 & 0x38) >> 3); 245 | src_reg = (code2 & 0x07); 246 | dst_reg = ((code1 & 0x0E) >> 1); 247 | size = ((code2 >> 6) & 0x03); 248 | 249 | 250 | if (mode == EA_AD && size == S_BYTE) { 251 | err68a( "不正な命令: sub.b An, Dn を実行しようとしました。", __FILE__, __LINE__ ); 252 | return(TRUE); 253 | } else if (get_data_at_ea(EA_All, mode, src_reg, size, &src_data)) { 254 | return(TRUE); 255 | } 256 | 257 | if (get_data_at_ea(EA_All, EA_DD, dst_reg, size, &dest_data)) { 258 | return(TRUE); 259 | } 260 | switch(size) 261 | { 262 | case 0: 263 | rd[dst_reg] = (rd[dst_reg] & 0xffffff00) | (add_long(src_data, dest_data, size) & 0xff); 264 | break; 265 | case 1: 266 | rd[dst_reg] = (rd[dst_reg] & 0xffff0000) | (add_long(src_data, dest_data, size) & 0xffff); 267 | break; 268 | case 2: 269 | rd[dst_reg] = add_long(src_data, dest_data, size ); 270 | break; 271 | default: 272 | return TRUE; 273 | } 274 | /* フラグの変化 */ 275 | add_conditions(src_data, dest_data, rd[ dst_reg ], size, 1); 276 | 277 | #ifdef TRACE 278 | printf( "trace: add.%c src=%d PC=%06lX\n", 279 | size_char [ size ], src_data, save_pc ); 280 | #endif 281 | 282 | return( FALSE ); 283 | } 284 | -------------------------------------------------------------------------------- /src/load.c: -------------------------------------------------------------------------------- 1 | /* $Id: load.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:08 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.5 1999/12/24 04:04:37 yfujii 9 | * BUGFIX:When .x or .r is ommited and specified drive or path, 10 | * run68 couldn't find the executable file. 11 | * 12 | * Revision 1.4 1999/12/07 12:47:10 yfujii 13 | * *** empty log message *** 14 | * 15 | * Revision 1.4 1999/11/29 06:11:28 yfujii 16 | * *** empty log message *** 17 | * 18 | * Revision 1.3 1999/10/21 13:32:01 yfujii 19 | * DOS calls are replaced by win32 functions. 20 | * 21 | * Revision 1.2 1999/10/18 03:24:40 yfujii 22 | * Added RCS keywords and modified for WIN32 a little. 23 | * 24 | */ 25 | 26 | #undef MAIN 27 | 28 | #include 29 | #include 30 | #if defined(WIN32) 31 | #include 32 | #endif 33 | #include "run68.h" 34 | 35 | static UChar xhead [ XHEAD_SIZE ]; 36 | 37 | static Long xfile_cnv( Long *, Long, int ); 38 | static int xrelocate( Long, Long, Long ); 39 | static Long xhead_getl( int ); 40 | static int set_fname( char *, Long ); 41 | 42 | /* doscall.c */ 43 | Long Getenv_common(const char *name_p, char *buf_p); 44 | 45 | static char *GetAPath(char **path_p, char *buf); 46 | 47 | /* 48 | 機能: 49 | 実行ファイルをオープンする。環境変数のPATHから取得したパスを 50 | 順番に探索して最初に見付かったファイルをオープンする。 51 | 最初にカレントディレクトリを検索する。 52 | 引数: 53 | char *fname -- ファイル名文字列 54 | int msg_flag -- 0でない時メッセージを標準エラー出力に出力 55 | 戻り値: 56 | NULL = オープンできない 57 | !NULL = 実行ファイルのファイルポインタ 58 | */ 59 | FILE *prog_open(char *fname, int mes_flag) 60 | { 61 | char dir[MAX_PATH], fullname[MAX_PATH], cwd[MAX_PATH]; 62 | FILE *fp = 0; 63 | char *exp = strrchr(fname, '.'); 64 | char env_p[4096], *p; 65 | #if defined(WIN32) || defined(DOSX) 66 | char sep_chr = '\\'; 67 | char sep_str[] = "\\"; 68 | #else 69 | char sep_chr = '/'; 70 | char sep_str[] = "/"; 71 | #endif 72 | 73 | if (strchr(fname, sep_chr) != NULL || strchr(fname, ':') != NULL) 74 | { 75 | strcpy(fullname, fname); 76 | if ((fp=fopen(fullname, "rb")) != NULL) 77 | goto EndOfFunc; 78 | // ここから追加(by Yokko氏) 79 | strcat(fullname, ".r"); 80 | if ((fp=fopen(fullname, "rb")) != NULL) 81 | goto EndOfFunc; 82 | strcpy(fullname, fname); 83 | strcat(fullname, ".x"); 84 | if ((fp=fopen(fullname, "rb")) != NULL) 85 | goto EndOfFunc; 86 | // ここまで追加(by Yokko氏) 87 | goto ErrorRet; 88 | } 89 | if (exp != NULL && !_stricmp(exp, ".x") && !_stricmp(exp, ".r")) 90 | goto ErrorRet; /* 拡張子が違う */ 91 | #if defined(WIN32) 92 | GetCurrentDirectory(sizeof(cwd), cwd); 93 | #else 94 | getcwd(cwd, sizeof(cwd)); 95 | #endif 96 | /* PATH環境変数を取得する */ 97 | #if defined(WIN32) 98 | Getenv_common("PATH", env_p); 99 | p = env_p; 100 | #else 101 | p = getenv("PATH"); 102 | #endif 103 | for (strcpy(dir, cwd); strlen(dir) != 0; GetAPath(&p, dir)) 104 | { 105 | if (exp != NULL) 106 | { 107 | strcpy(fullname, dir); 108 | if (dir[strlen(dir)-1] != sep_chr) 109 | strcat(fullname, sep_str); 110 | strcat(fullname, fname); 111 | if ((fp = fopen(fullname, "rb")) != NULL) 112 | goto EndOfFunc; 113 | } else 114 | { 115 | strcpy(fullname, dir); 116 | if (fullname[strlen(fullname)-1] != sep_chr) 117 | strcat(fullname, sep_str); 118 | strcat(fullname, fname); 119 | strcat(fullname, ".r"); 120 | if ((fp=fopen(fullname, "rb")) != NULL) 121 | goto EndOfFunc; 122 | strcpy(fullname, dir); 123 | if (fullname[strlen(fullname)-1] != sep_chr) 124 | strcat(fullname, sep_str); 125 | strcat(fullname, fname); 126 | strcat(fullname, ".x"); 127 | if ((fp=fopen(fullname, "rb")) != NULL) 128 | goto EndOfFunc; 129 | } 130 | } 131 | EndOfFunc: 132 | strcpy(fname, fullname); 133 | return fp; 134 | ErrorRet: 135 | if (mes_flag == TRUE) 136 | fprintf(stderr, "ファイルがオープンできません\n"); 137 | return NULL; 138 | } 139 | 140 | #if defined(__APPLE__) || defined(__linux__) || defined(__EMSCRIPTEN__) 141 | #define PATH_DELIMITER ':' 142 | #else 143 | #define PATH_DELIMITER ';' 144 | #endif 145 | 146 | static char *GetAPath(char **path_p, char *buf) 147 | { 148 | unsigned int i; 149 | 150 | if (path_p == NULL || *path_p == NULL || strlen(*path_p) == 0) 151 | { 152 | *buf = '\0'; 153 | goto ErrorReturn; 154 | } 155 | for (i = 0; i < strlen(*path_p) && (*path_p)[i] != PATH_DELIMITER; i ++) 156 | { 157 | /* 2バイトコードのスキップ */ 158 | ; 159 | } 160 | strncpy(buf, *path_p, i); 161 | buf[i] = '\0'; 162 | if ((*path_p)[i] == '\0') 163 | { 164 | *path_p = &((*path_p)[i]); 165 | } else 166 | { 167 | *path_p += i + 1; 168 | } 169 | return buf; 170 | ErrorReturn: 171 | return NULL; 172 | } 173 | 174 | /* 175 |  機能:プログラムをメモリに読み込む(fpはクローズされる) 176 | 戻り値:正 = 実行開始アドレス 177 |     負 = エラーコード 178 | */ 179 | Long prog_read( FILE *fp, char *fname, Long read_top, 180 | Long *prog_sz, Long *prog_sz2, int mes_flag ) 181 | /* prog_sz2はロードモード+リミットアドレスの役割も果たす */ 182 | { 183 | char *read_ptr; 184 | Long read_sz; 185 | Long pc_begin; 186 | int x_flag = FALSE; 187 | int loadmode; 188 | int i; 189 | 190 | loadmode = ((*prog_sz2 >> 24) & 0x03); 191 | *prog_sz2 &= 0xFFFFFF; 192 | 193 | if ( fseek( fp, 0, SEEK_END ) != 0 ) { 194 | fclose( fp ); 195 | if ( mes_flag == TRUE ) 196 | fprintf(stderr, "ファイルのシークに失敗しました\n"); 197 | return( -11 ); 198 | } 199 | if ( (*prog_sz=ftell( fp )) <= 0 ) { 200 | fclose( fp ); 201 | if ( mes_flag == TRUE ) 202 | fprintf(stderr, "ファイルサイズが0です\n"); 203 | return( -11 ); 204 | } 205 | if ( fseek( fp, 0, SEEK_SET ) != 0 ) { 206 | fclose( fp ); 207 | if ( mes_flag == TRUE ) 208 | fprintf(stderr, "ファイルのシークに失敗しました\n"); 209 | return( -11 ); 210 | } 211 | if ( read_top + *prog_sz > *prog_sz2 ) { 212 | fclose( fp ); 213 | if ( mes_flag == TRUE ) 214 | fprintf(stderr, "ファイルサイズが大きすぎます\n"); 215 | return( -8 ); 216 | } 217 | 218 | read_sz = *prog_sz; 219 | read_ptr = prog_ptr + read_top; 220 | pc_begin = read_top; 221 | 222 | /* XHEAD_SIZEバイト読み込む */ 223 | if ( *prog_sz >= XHEAD_SIZE ) { 224 | if ( fread( read_ptr, 1, XHEAD_SIZE, fp ) != XHEAD_SIZE ) { 225 | fclose( fp ); 226 | if ( mes_flag == TRUE ) 227 | fprintf(stderr, "ファイルの読み込みに失敗しました\n"); 228 | return( -11 ); 229 | } 230 | read_sz -= XHEAD_SIZE; 231 | if ( loadmode == 1 ) 232 | i = 0; /* Rファイル */ 233 | else if ( loadmode == 3 ) 234 | i = 1; /* Xファイル */ 235 | else 236 | i = strlen( fname ) - 2; 237 | if ( mem_get( read_top, S_WORD ) == 0x4855 && i > 0 ) 238 | { 239 | if ( loadmode == 3 || 240 | strcmp( &(fname [ i ]), ".x" ) == 0 || 241 | strcmp( &(fname [ i ]), ".X" ) == 0 ) { 242 | x_flag = TRUE; 243 | memcpy( xhead, read_ptr, XHEAD_SIZE ); 244 | *prog_sz = read_sz; 245 | } 246 | } 247 | if ( x_flag == FALSE ) 248 | read_ptr += XHEAD_SIZE; 249 | } 250 | 251 | if ( fread( read_ptr, 1, read_sz, fp ) != (size_t)read_sz ) { 252 | fclose( fp ); 253 | if ( mes_flag == TRUE ) 254 | fprintf(stderr, "ファイルの読み込みに失敗しました\n"); 255 | return( -11 ); 256 | } 257 | 258 | /* 実行ファイルのクローズ */ 259 | fclose( fp ); 260 | 261 | /* Xファイルの処理 */ 262 | *prog_sz2 = *prog_sz; 263 | if ( x_flag == TRUE ) { 264 | if ( (pc_begin=xfile_cnv( prog_sz, read_top, mes_flag )) == 0 ) 265 | return( -11 ); 266 | } 267 | 268 | return( pc_begin ); 269 | } 270 | 271 | /* 272 |  機能:Xファイルをコンバートする 273 | 戻り値: 0 = エラー 274 |     !0 = プログラム開始アドレス 275 | */ 276 | static Long xfile_cnv( Long *prog_size, Long read_top, int mes_flag ) 277 | { 278 | Long pc_begin; 279 | Long code_size; 280 | Long data_size; 281 | Long bss_size; 282 | Long reloc_size; 283 | 284 | if ( xhead_getl( 0x3C ) != 0 ) { 285 | if ( mes_flag == TRUE ) 286 | fprintf(stderr, "BINDされているファイルです\n"); 287 | return( 0 ); 288 | } 289 | pc_begin = xhead_getl( 0x08 ); 290 | code_size = xhead_getl( 0x0C ); 291 | data_size = xhead_getl( 0x10 ); 292 | bss_size = xhead_getl( 0x14 ); 293 | reloc_size = xhead_getl( 0x18 ); 294 | 295 | if ( reloc_size != 0 ) { 296 | if ( xrelocate( code_size + data_size, reloc_size, read_top ) 297 | == FALSE ) { 298 | if ( mes_flag == TRUE ) 299 | fprintf(stderr, "未対応のリロケート情報があります\n"); 300 | return( 0 ); 301 | } 302 | } 303 | 304 | memset( prog_ptr + read_top + code_size + data_size, 0, bss_size ); 305 | *prog_size += bss_size; 306 | 307 | return( read_top + pc_begin ); 308 | } 309 | 310 | /* 311 |  機能:Xファイルをリロケートする 312 | 戻り値: TRUE = 正常終了 313 |     FALSE = 異常終了 314 | */ 315 | static int xrelocate( Long reloc_adr, Long reloc_size, Long read_top ) 316 | { 317 | Long prog_adr; 318 | Long data; 319 | UShort disp; 320 | 321 | prog_adr = read_top; 322 | for(; reloc_size > 0; reloc_size -= 2, reloc_adr += 2 ) { 323 | disp = (UShort)mem_get( read_top + reloc_adr, S_WORD ); 324 | if ( disp == 1 ) 325 | return ( FALSE ); 326 | prog_adr += disp; 327 | data = mem_get( prog_adr, S_LONG ) + read_top; 328 | mem_set( prog_adr, data, S_LONG ); 329 | } 330 | 331 | return( TRUE ); 332 | } 333 | 334 | /* 335 |  機能:xheadからロングデータをゲットする 336 | 戻り値:データの値 337 | */ 338 | static Long xhead_getl( int adr ) 339 | { 340 | UChar *p; 341 | Long d; 342 | 343 | p = &( xhead [ adr ] ); 344 | 345 | d = *(p++); 346 | d = ((d << 8) | *(p++)); 347 | d = ((d << 8) | *(p++)); 348 | d = ((d << 8) | *p); 349 | return( d ); 350 | } 351 | 352 | /* 353 |  機能:プロセス管理テーブルを作成する 354 | 戻り値: TRUE = 正常終了 355 |     FALSE = 異常終了 356 | */ 357 | int make_psp( char *fname, Long prev_adr, Long end_adr, Long process_id, 358 | Long prog_size2 ) 359 | { 360 | char *mem_ptr; 361 | 362 | mem_ptr = prog_ptr + ra [ 0 ]; 363 | memset( mem_ptr, 0, PSP_SIZE ); 364 | mem_set( ra [ 0 ], prev_adr, S_LONG ); /* 前 */ 365 | mem_set( ra [ 0 ] + 0x04, process_id, S_LONG ); /* 確保プロセス */ 366 | mem_set( ra [ 0 ] + 0x08, end_adr, S_LONG ); /* 終わり+1 */ 367 | mem_set( ra [ 0 ] + 0x0c, 0, S_LONG ); /* 次 */ 368 | 369 | mem_set( ra [ 0 ] + 0x10, ra [ 3 ], S_LONG ); 370 | mem_set( ra [ 0 ] + 0x20, ra [ 2 ], S_LONG ); 371 | mem_set( ra [ 0 ] + 0x30, ra [ 0 ] + PSP_SIZE + prog_size2, S_LONG ); 372 | mem_set( ra [ 0 ] + 0x34, ra [ 0 ] + PSP_SIZE + prog_size2, S_LONG ); 373 | mem_set( ra [ 0 ] + 0x38, ra [ 1 ], S_LONG ); 374 | mem_set( ra [ 0 ] + 0x44, sr, S_WORD ); /* 親のSRの値 */ 375 | mem_set( ra [ 0 ] + 0x60, 0, S_LONG ); /* 親あり */ 376 | if ( set_fname( fname, ra [ 0 ] ) == FALSE ) 377 | return( FALSE ); 378 | 379 | psp [ nest_cnt ] = ra [ 0 ]; 380 | return( TRUE ); 381 | } 382 | 383 | /* 384 |  機能:プロセス管理テーブルにファイル名をセットする 385 | 戻り値: TRUE = 正常終了 386 |     FALSE = 異常終了 387 | */ 388 | static int set_fname( char *p, Long psp_adr ) 389 | { 390 | char cud [ 67 ]; 391 | char *mem_ptr; 392 | int i; 393 | 394 | for( i = strlen( p ) - 1; i >= 0; i-- ) { 395 | if ( p [ i ] == '\\' || p [ i ] == '/' || p [ i ] == ':' ) 396 | break; 397 | } 398 | i ++; 399 | if ( strlen( &(p [ i ]) ) > 22 ) 400 | return( FALSE ); 401 | mem_ptr = prog_ptr + psp_adr + 0xC4; 402 | strcpy( mem_ptr, &(p [ i ]) ); 403 | 404 | mem_ptr = prog_ptr + psp_adr + 0x82; 405 | if ( i == 0 ) { 406 | /* カレントディレクトリをセット */ 407 | #if defined(WIN32) 408 | { 409 | BOOL b; 410 | b = GetCurrentDirectoryA(sizeof(cud), cud); 411 | cud[sizeof(cud)-1] = '\0'; 412 | } 413 | if (FALSE) { 414 | #else 415 | if ( getcwd( cud, 66 ) == NULL ) { 416 | #endif 417 | strcpy( mem_ptr, ".\\" ); 418 | } else { 419 | mem_ptr -= 2; 420 | strcpy( mem_ptr, cud ); 421 | if ( cud [ strlen( cud ) - 1 ] != '\\' ) 422 | strcat( mem_ptr, "\\" ); 423 | return( TRUE ); 424 | } 425 | } else { 426 | p [ i ] = '\0'; 427 | for( i--; i >= 0; i-- ) { 428 | if ( p [ i ] == ':' ) 429 | break; 430 | } 431 | i ++; 432 | if ( strlen( &(p [ i ]) ) > 64 ) 433 | return( FALSE ); 434 | strcpy( mem_ptr, &(p [ i ]) ); 435 | } 436 | 437 | mem_ptr = prog_ptr + psp_adr + 0x80; 438 | if ( i == 0 ) { 439 | /* カレントドライブをセット */ 440 | #if defined(WIN32) 441 | { 442 | char cpath[MAX_PATH]; 443 | BOOL b; 444 | b = GetCurrentDirectoryA(sizeof(cpath), cpath); 445 | mem_ptr[0] = cpath[0]; 446 | } 447 | #elif defined(DOSX) 448 | dos_getdrive( &drv ); 449 | mem_ptr [ 0 ] = drv - 1 + 'A'; 450 | #else 451 | mem_ptr [ 0 ] = 'A'; 452 | #endif 453 | mem_ptr [ 1 ] = ':'; 454 | } else { 455 | memcpy( mem_ptr, p, 2 ); 456 | } 457 | 458 | return( TRUE ); 459 | } 460 | -------------------------------------------------------------------------------- /src/mem.c: -------------------------------------------------------------------------------- 1 | /* $Id: mem.c,v 1.2 2009-08-08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: not supported by cvs2svn $ 5 | * Revision 1.1.1.1 2001/05/23 11:22:08 masamic 6 | * First imported source code and docs 7 | * 8 | * Revision 1.4 1999/12/07 12:47:22 yfujii 9 | * *** empty log message *** 10 | * 11 | * Revision 1.4 1999/11/29 06:18:06 yfujii 12 | * Calling CloseHandle instead of fclose when abort(). 13 | * 14 | * Revision 1.3 1999/11/01 06:23:33 yfujii 15 | * Some debugging functions are introduced. 16 | * 17 | * Revision 1.2 1999/10/18 03:24:40 yfujii 18 | * Added RCS keywords and modified for WIN32 a little. 19 | * 20 | */ 21 | 22 | #undef MAIN 23 | 24 | #include 25 | #include "run68.h" 26 | 27 | static int mem_red_chk( Long ); 28 | static int mem_wrt_chk( Long ); 29 | void run68_abort( Long ); 30 | 31 | /* 32 |  機能:PCの指すメモリからインデックスレジスタ+8ビットディスプレースメント 33 |     の値を得る 34 | 戻り値:その値 35 | */ 36 | Long idx_get() 37 | { 38 | char *mem; 39 | char idx2; 40 | char idx_reg; 41 | Long idx; 42 | 43 | mem = prog_ptr + pc; 44 | idx2 = *(mem++); 45 | idx_reg = ((idx2 >> 4) & 0x07); 46 | if ( (idx2 & 0x80) == 0 ) 47 | idx = rd [ idx_reg ]; 48 | else 49 | idx = ra [ idx_reg ]; 50 | if ( (idx2 & 0x08) == 0 ) { /* WORD */ 51 | if ((idx & 0x8000) != 0) 52 | idx |= 0xFFFF0000; 53 | else 54 | idx &= 0x0000FFFF; 55 | } 56 | pc += 2; 57 | 58 | return( idx + *mem ); 59 | } 60 | 61 | /* 62 |  機能:PCの指すメモリから指定されたサイズのイミディエイトデータをゲットし、 63 |     サイズに応じてPCを進める 64 | 戻り値:データの値 65 | */ 66 | Long imi_get( char size ) 67 | { 68 | UChar *mem; 69 | Long d; 70 | 71 | mem = (UChar *)prog_ptr + pc; 72 | 73 | switch( size ) { 74 | case S_BYTE: 75 | pc += 2; 76 | return( *(mem + 1) ); 77 | case S_WORD: 78 | pc += 2; 79 | d = *(mem++); 80 | d = ((d << 8) | *mem); 81 | return( d ); 82 | default: /* S_LONG */ 83 | pc += 4; 84 | d = *(mem++); 85 | d = ((d << 8) | *(mem++)); 86 | d = ((d << 8) | *(mem++)); 87 | d = ((d << 8) | *mem); 88 | return( d ); 89 | } 90 | } 91 | 92 | /* 93 |  機能:メモリから指定されたサイズのデータをゲットする 94 | 戻り値:データの値 95 | */ 96 | Long mem_get( Long adr, char size ) 97 | { 98 | UChar *mem; 99 | Long d; 100 | 101 | if ( adr < ENV_TOP || adr >= mem_aloc ) { 102 | if ( mem_red_chk( adr ) == FALSE ) 103 | return( 0 ); 104 | } 105 | mem = (UChar *)prog_ptr + adr; 106 | 107 | switch( size ) { 108 | case S_BYTE: 109 | return( *mem ); 110 | case S_WORD: 111 | d = *(mem++); 112 | d = ((d << 8) | *mem); 113 | return( d ); 114 | default: /* S_LONG */ 115 | d = *(mem++); 116 | d = ((d << 8) | *(mem++)); 117 | d = ((d << 8) | *(mem++)); 118 | d = ((d << 8) | *mem); 119 | return( d ); 120 | } 121 | } 122 | 123 | /* 124 |  機能:メモリに指定されたサイズのデータをセットする 125 | 戻り値:なし 126 | */ 127 | void mem_set( Long adr, Long d, char size ) 128 | { 129 | UChar *mem; 130 | 131 | if ( adr < ENV_TOP || adr >= mem_aloc ) { 132 | if ( mem_wrt_chk( adr ) == FALSE ) 133 | return; 134 | } 135 | mem = (UChar *)prog_ptr + adr; 136 | 137 | switch( size ) { 138 | case S_BYTE: 139 | *mem = (d & 0xFF); 140 | return; 141 | case S_WORD: 142 | *(mem++) = ((d >> 8) & 0xFF); 143 | *mem = (d & 0xFF); 144 | return; 145 | default: /* S_LONG */ 146 | *(mem++) = ((d >> 24) & 0xFF); 147 | *(mem++) = ((d >> 16) & 0xFF); 148 | *(mem++) = ((d >> 8) & 0xFF); 149 | *mem = (d & 0xFF); 150 | return; 151 | } 152 | } 153 | 154 | /* 155 |  機能:読み込みアドレスのチェック 156 | 戻り値: TRUE = OK 157 | FALSE = NGだが、0を読み込んだとみなす 158 | */ 159 | static int mem_red_chk( Long adr ) 160 | { 161 | char message[256]; 162 | 163 | adr &= 0x00FFFFFF; 164 | if ( adr >= 0xC00000 ) { 165 | if ( ini_info.io_through == TRUE ) 166 | return( FALSE ); 167 | sprintf(message, "I/OポートorROM($%06X)から読み込もうとしました。", adr); 168 | err68(message); 169 | run68_abort( adr ); 170 | } 171 | if ( SR_S_REF() == 0 || adr >= mem_aloc ) { 172 | sprintf(message, "不正アドレス($%06X)からの読み込みです。", adr); 173 | err68(message); 174 | run68_abort( adr ); 175 | } 176 | return( TRUE ); 177 | } 178 | 179 | /* 180 |  機能:書き込みアドレスのチェック 181 | 戻り値: TRUE = OK 182 | FALSE = NGだが、何も書き込まずにOKとみなす 183 | */ 184 | static int mem_wrt_chk( Long adr ) 185 | { 186 | char message[256]; 187 | 188 | adr &= 0x00FFFFFF; 189 | if ( adr >= 0xC00000 ) { 190 | if ( ini_info.io_through == TRUE ) 191 | return( FALSE ); 192 | /* 193 | if ( adr == 0xE8A01F ) /# RESET CONTROLLER #/ 194 | return( FALSE ); 195 | */ 196 | sprintf(message, "I/OポートorROM($%06X)に書き込もうとしました。", adr); 197 | err68(message); 198 | run68_abort(adr); 199 | } 200 | if ( SR_S_REF() == 0 || adr >= mem_aloc ) { 201 | sprintf(message, "不正アドレスへの書き込みです($%06X)", adr); 202 | err68(message); 203 | run68_abort( adr ); 204 | } 205 | return( TRUE ); 206 | } 207 | 208 | /* 209 | 機能:異常終了する 210 | */ 211 | void run68_abort( Long adr ) 212 | { 213 | int i; 214 | 215 | fprintf( stderr, "アドレス:%08X\n", adr ); 216 | 217 | for ( i = 5; i < FILE_MAX; i ++ ) { 218 | if ( finfo [ i ].fh != NULL ) 219 | #if defined(WIN32) 220 | CloseHandle(finfo [ i ].fh); 221 | #else 222 | fclose(finfo [ i ].fh); 223 | #endif 224 | } 225 | 226 | #ifdef TRACE 227 | printf( "d0-7=%08lx" , rd [ 0 ] ); 228 | for ( i = 1; i < 8; i++ ) { 229 | printf( ",%08lx" , rd [ i ] ); 230 | } 231 | printf("\n"); 232 | printf( "a0-7=%08lx" , ra [ 0 ] ); 233 | for ( i = 1; i < 8; i++ ) { 234 | printf( ",%08lx" , ra [ i ] ); 235 | } 236 | printf("\n"); 237 | printf( " pc=%08lx sr=%04x\n" , pc, sr ); 238 | #endif 239 | longjmp(jmp_when_abort, 2); 240 | } 241 | -------------------------------------------------------------------------------- /src/run68.h: -------------------------------------------------------------------------------- 1 | /* $Id: run68.h,v 1.5 2009/08/08 06:49:44 masamic Exp $ */ 2 | 3 | /* 4 | * $Log: run68.h,v $ 5 | * Revision 1.5 2009/08/08 06:49:44 masamic 6 | * Convert Character Encoding Shifted-JIS to UTF-8. 7 | * 8 | * Revision 1.4 2009/08/05 14:44:33 masamic 9 | * Some Bug fix, and implemented some instruction 10 | * Following Modification contributed by TRAP. 11 | * 12 | * Fixed Bug: In disassemble.c, shift/rotate as{lr},ls{lr},ro{lr} alway show word size. 13 | * Modify: enable KEYSNS, register behaiviour of sub ea, Dn. 14 | * Add: Nbcd, Sbcd. 15 | * 16 | * Revision 1.3 2004/12/17 07:51:06 masamic 17 | * Support TRAP instraction widely. (but not be tested) 18 | * 19 | * Revision 1.2 2004/12/16 12:25:12 masamic 20 | * It has become under GPL. 21 | * Maintenor name has changed. 22 | * Modify codes for aboves. 23 | * 24 | * Revision 1.1.1.1 2001/05/23 11:22:08 masamic 25 | * First imported source code and docs 26 | * 27 | * Revision 1.14 1999/12/07 12:47:54 yfujii 28 | * *** empty log message *** 29 | * 30 | * Revision 1.14 1999/11/29 06:24:55 yfujii 31 | * Some functions' prototypes are added. 32 | * 33 | * Revision 1.13 1999/11/08 10:29:30 yfujii 34 | * Calling convention to eaaccess.c is changed. 35 | * 36 | * Revision 1.12 1999/11/08 03:09:41 yfujii 37 | * Debugger command "wathchc" is added. 38 | * 39 | * Revision 1.11 1999/11/01 10:36:33 masamichi 40 | * Reduced move[a].l routine. and Create functions about accessing effective address. 41 | * 42 | * Revision 1.10 1999/11/01 06:23:33 yfujii 43 | * Some debugging functions are introduced. 44 | * 45 | * Revision 1.9 1999/10/29 13:44:04 yfujii 46 | * Debugging facilities are introduced. 47 | * 48 | * Revision 1.8 1999/10/27 03:44:01 yfujii 49 | * Macro RUN68VERSION is defined. 50 | * 51 | * Revision 1.7 1999/10/26 12:26:08 yfujii 52 | * Environment variable function is drasticaly modified. 53 | * 54 | * Revision 1.6 1999/10/26 01:31:54 yfujii 55 | * Execution history and address trap is added. 56 | * 57 | * Revision 1.5 1999/10/25 03:26:27 yfujii 58 | * Declarations for some flags are added. 59 | * 60 | * Revision 1.4 1999/10/20 12:52:10 yfujii 61 | * Add an #if directive. 62 | * 63 | * Revision 1.3 1999/10/20 06:31:09 yfujii 64 | * Made a little modification for Cygnus GCC. 65 | * 66 | * Revision 1.2 1999/10/18 03:24:40 yfujii 67 | * Added RCS keywords and modified for WIN32 a little. 68 | * 69 | */ 70 | 71 | #define RUN68VERSION "0.09a+MacOS" 72 | #if !defined(_RUN68_H_) 73 | #define _RUN68_H_ 74 | 75 | #if defined(__GNUC__) 76 | #if !defined(__int64) 77 | #define __int64 Long Long 78 | #endif 79 | #endif 80 | 81 | #if defined(_WIN32) /* for Cygnus GCC */ 82 | #if !defined(WIN32) 83 | #define WIN32 84 | #endif 85 | #endif 86 | 87 | 88 | #include // for intXX_t 89 | #include 90 | 91 | typedef int8_t Char ; 92 | typedef uint8_t UChar ; 93 | typedef int16_t Short ; 94 | typedef uint16_t UShort ; 95 | typedef int32_t Long ; // 64bit 環境対応 96 | typedef uint32_t ULong ; // 64bit 環境対応 97 | 98 | 99 | /* 100 | #undef TRACE 101 | #undef FNC_TRACE 102 | */ 103 | 104 | #if defined(WIN32) /* Win32 APIでDOSコールをエミュレートする。*/ 105 | #undef DOSX 106 | #endif 107 | 108 | #if defined(WIN32) 109 | #include 110 | #endif 111 | 112 | #include 113 | #include 114 | #if !defined(WIN32) /* Win32 APIでDOSコールをエミュレートする。*/ 115 | #if !defined(DOSX) 116 | #include 117 | #define MAX_PATH PATH_MAX 118 | #define _fcvt fcvt 119 | #define _gcvt gcvt 120 | #define _stricmp strcasecmp 121 | #define _strlwr(p) { char *s; for (s = p; *s; s++) *s = tolower(*s); } 122 | #define _ltoa(v, p, n) snprintf(p, n, "%l", v) 123 | #define BOOL int 124 | #endif 125 | #define TRUE -1 126 | #define FALSE 0 127 | #endif 128 | #define XHEAD_SIZE 0x40 /* Xファイルのヘッダサイズ */ 129 | #define HUMAN_HEAD 0x6800 /* Humanのメモリ管理ブロック位置 */ 130 | #define FCB_WORK 0x20F00 /* DOSCALL GETFCB用ワーク領域 */ 131 | #define HUMAN_WORK 0x21000 /* 割り込み処理先等のワーク領域 */ 132 | #define TRAP0_WORK 0x20FF0000 /* TRAP割り込み処理先等のワーク領域 */ 133 | #define TRAP1_WORK 0x21FF0000 /* TRAP割り込み処理先等のワーク領域 */ 134 | #define TRAP2_WORK 0x22FF0000 /* TRAP割り込み処理先等のワーク領域 */ 135 | #define TRAP3_WORK 0x23FF0000 /* TRAP割り込み処理先等のワーク領域 */ 136 | #define TRAP4_WORK 0x24FF0000 /* TRAP割り込み処理先等のワーク領域 */ 137 | #define TRAP5_WORK 0x25FF0000 /* TRAP割り込み処理先等のワーク領域 */ 138 | #define TRAP6_WORK 0x26FF0000 /* TRAP割り込み処理先等のワーク領域 */ 139 | #define TRAP7_WORK 0x27FF0000 /* TRAP割り込み処理先等のワーク領域 */ 140 | #define TRAP8_WORK 0x28FF0000 /* TRAP割り込み処理先等のワーク領域 */ 141 | #define ENV_TOP 0x21C00 142 | #define ENV_SIZE 0x2000 143 | #define STACK_TOP ENV_TOP + ENV_SIZE 144 | #define STACK_SIZE 0x10000 /* 64KB */ 145 | #define MB_SIZE 16 146 | #define PSP_SIZE MB_SIZE + 240 147 | #define PROG_TOP (STACK_TOP + STACK_SIZE + PSP_SIZE) 148 | #define NEST_MAX 20 149 | #define FILE_MAX 20 150 | 151 | #define RAS_INTERVAL 10000 /* ラスタ割り込みの間隔 */ 152 | 153 | #define S_BYTE 0 /* BYTEサイズ */ 154 | #define S_WORD 1 /* WORDサイズ */ 155 | #define S_LONG 2 /* LONGサイズ */ 156 | 157 | #define MD_DD 0 /* データレジスタ直接 */ 158 | #define MD_AD 1 /* アドレスレジスタ直接 */ 159 | #define MD_AI 2 /* アドレスレジスタ間接 */ 160 | #define MD_AIPI 3 /* ポストインクリメント・アドレスレジスタ間接 */ 161 | #define MD_AIPD 4 /* プリデクリメント・アドレスレジスタ間接 */ 162 | #define MD_AID 5 /* ディスプレースメント付きアドレスレジスタ間接 */ 163 | #define MD_AIX 6 /* インデックス付きアドレスレジスタ間接 */ 164 | #define MD_OTH 7 /* その他 */ 165 | 166 | #define MR_SRT 0 /* 絶対ショート */ 167 | #define MR_LNG 1 /* 絶対ロング */ 168 | #define MR_PC 2 /* プログラムカウンタ相対 */ 169 | #define MR_PCX 3 /* インデックス付きプログラムカウンタ相対 */ 170 | #define MR_IM 4 /* イミディエイトデータ */ 171 | 172 | /* Replace from MD_xx, MR_xx */ 173 | #define EA_DD 0 /* データレジスタ直接 */ 174 | #define EA_AD 1 /* アドレスレジスタ直接 */ 175 | #define EA_AI 2 /* アドレスレジスタ間接 */ 176 | #define EA_AIPI 3 /* ポストインクリメント・アドレスレジスタ間接 */ 177 | #define EA_AIPD 4 /* プリデクリメント・アドレスレジスタ間接 */ 178 | #define EA_AID 5 /* ディスプレースメント付きアドレスレジスタ間接 */ 179 | #define EA_AIX 6 /* インデックス付きアドレスレジスタ間接 */ 180 | #define EA_SRT 7 /* 絶対ショート */ 181 | #define EA_LNG 8 /* 絶対ロング */ 182 | #define EA_PC 9 /* プログラムカウンタ相対 */ 183 | #define EA_PCX 10 /* インデックス付きプログラムカウンタ相対 */ 184 | #define EA_IM 11 /* イミディエイトデータ */ 185 | 186 | /* 選択可能実効アドレス組み合わせ fedc ba98 7654 3210 */ 187 | #define EA_All 0x0fff /* 0000 1111 1111 1111 */ 188 | #define EA_Control 0x07e4 /* 0000 0111 1110 0100 */ 189 | #define EA_Data 0x0ffd /* 0000 1111 1111 1101 */ 190 | #define EA_PreDecriment 0x01f4 /* 0000 0001 1111 0100 */ 191 | #define EA_PostIncrement 0x07ec /* 0000 0111 1110 1100 */ 192 | #define EA_VariableData 0x01fd /* 0000 0001 1111 1101 */ 193 | #define EA_Variable 0x01ff /* 0000 0001 1111 1111 */ 194 | #define EA_VariableMemory 0x01fc /* 0000 0001 1111 1100 */ 195 | 196 | /* EaAccess.c */ 197 | BOOL get_data_at_ea(int AceptAdrMode, int mode, int reg, int size, Long *data) ; 198 | BOOL set_data_at_ea(int AceptAdrMode, int mode, int reg, int size, Long data) ; 199 | BOOL get_ea(Long save_pc, int AceptAdrMode, int mode, int reg, Long *data) ; 200 | 201 | #define CCR_X_ON() sr |= 0x0010 202 | #define CCR_X_OFF() sr &= 0xFFEF 203 | #define CCR_X_REF() (sr & 0x0010) 204 | #define CCR_N_ON() sr |= 0x0008 205 | #define CCR_N_OFF() sr &= 0xFFF7 206 | #define CCR_N_REF() (sr & 0x0008) 207 | #define CCR_Z_ON() sr |= 0x0004 208 | #define CCR_Z_OFF() sr &= 0xFFFB 209 | #define CCR_Z_REF() (sr & 0x0004) 210 | #define CCR_V_ON() sr |= 0x0002 211 | #define CCR_V_OFF() sr &= 0xFFFD 212 | #define CCR_V_REF() (sr & 0x0002) 213 | #define CCR_C_ON() sr |= 0x0001 214 | #define CCR_C_OFF() sr &= 0xFFFE 215 | #define CCR_C_REF() (sr & 0x0001) 216 | #define SR_S_ON() sr |= 0x2000 217 | #define SR_S_OFF() sr &= 0xDFFF 218 | #define SR_S_REF() (sr & 0x2000) 219 | #define SR_T_REF() (sr & 0x8000) 220 | 221 | 222 | 223 | typedef struct { 224 | #if defined(WIN32) 225 | HANDLE fh ; 226 | #else 227 | FILE *fh ; 228 | #endif 229 | unsigned date ; 230 | unsigned time ; 231 | short mode ; 232 | char nest ; 233 | char name [ 89 ] ; 234 | } FILEINFO ; 235 | 236 | typedef struct { 237 | char env_lower ; 238 | char trap_emulate ; 239 | char pc98_key ; 240 | char io_through ; 241 | } INI_INFO ; 242 | 243 | /* デバッグ用に実行した命令の情報を保存しておく構造体 */ 244 | typedef struct { 245 | Long pc; 246 | /* 本当は全レジスタを保存しておきたい。*/ 247 | unsigned short code; /* OPコード */ 248 | Long rmem; /* READしたメモリ */ 249 | char rsize; /* B/W/L or N(READなし) movemの場合は最後の一つ */ 250 | Long wmem; /* WRITEしたメモリ */ 251 | char wsize; /* B/W/L or N(WRITEなし) movemの場合は最後の一つ */ 252 | char mnemonic[64]; /* ニーモニック(できれば) */ 253 | } EXEC_INSTRUCTION_INFO; 254 | 255 | /* run68.c */ 256 | /* フラグ */ 257 | extern BOOL func_trace_f; 258 | extern BOOL trace_f; 259 | extern Long trap_pc; 260 | extern jmp_buf jmp_when_abort; 261 | extern unsigned short cwatchpoint; 262 | /* 標準入力のハンドル */ 263 | #if defined(WIN32) 264 | extern HANDLE stdin_handle; 265 | #endif 266 | 267 | /* 命令実行情報 */ 268 | extern EXEC_INSTRUCTION_INFO OP_info; 269 | void term( int ) ; 270 | 271 | /* getini.c */ 272 | void read_ini( char *path, char *prog ) ; 273 | void readenv_from_ini(char *path); 274 | 275 | /* load.c */ 276 | FILE *prog_open(char *, int ) ; 277 | Long prog_read( FILE *, char *, Long, Long *, Long *, int ) ; 278 | int make_psp( char *, Long, Long, Long, Long ) ; 279 | 280 | /* exec.c */ 281 | int prog_exec( void ) ; 282 | int get_cond( char ) ; 283 | void err68( char * ) ; 284 | void err68a(char *mes, char *file, int line); 285 | void err68b(char *mes, Long pc, Long ppc); 286 | void inc_ra( char, char ) ; 287 | void dec_ra( char, char ) ; 288 | void text_color( short ) ; 289 | Long get_locate( void ) ; 290 | void OPBuf_insert(const EXEC_INSTRUCTION_INFO *op); 291 | void OPBuf_clear(); 292 | int OPBuf_numentries(); 293 | const EXEC_INSTRUCTION_INFO *OPBuf_getentry(int no); 294 | void OPBuf_display(int n); 295 | 296 | /* calc.c */ 297 | Long add_long(Long src, Long dest, int size); 298 | Long sub_long(Long src, Long dest, int size); 299 | 300 | /* mem.c */ 301 | Long idx_get( void ) ; 302 | Long imi_get ( char ) ; 303 | Long mem_get ( Long, char ) ; 304 | void mem_set ( Long, Long, char ) ; 305 | 306 | /* doscall.c */ 307 | int dos_call( UChar ) ; 308 | 309 | /* iocscall.c */ 310 | int iocs_call( void ) ; 311 | 312 | /* key.c */ 313 | void get_fnckey( int, char * ) ; 314 | void put_fnckey( int, char * ) ; 315 | UChar cnv_key98( UChar ) ; 316 | 317 | /* line?.c */ 318 | int line0( char * ) ; 319 | int line2( char * ) ; 320 | int line4( char * ) ; 321 | int line5( char * ) ; 322 | int line6( char * ) ; 323 | int line7( char * ) ; 324 | int line8( char * ) ; 325 | int line9( char * ) ; 326 | int lineb( char * ) ; 327 | int linec( char * ) ; 328 | int lined( char * ) ; 329 | int linee( char * ) ; 330 | int linef( char * ) ; 331 | 332 | /* eaaccess.c */ 333 | BOOL get_data_at_ea_noinc(int AceptAdrMode, int mode, int reg, int size, Long *data) ; 334 | 335 | /* debugger.c */ 336 | typedef enum { 337 | RUN68_COMMAND_BREAK, /* ブレークポイントの設定 */ 338 | RUN68_COMMAND_CLEAR, /* ブレークポイントのクリア */ 339 | RUN68_COMMAND_CONT, /* 実行の継続 */ 340 | RUN68_COMMAND_DUMP, /* メモリをダンプする */ 341 | RUN68_COMMAND_HELP, /* デバッガのヘルプ */ 342 | RUN68_COMMAND_HISTORY, /* 命令の実行履歴 */ 343 | RUN68_COMMAND_LIST, /* ディスアセンブル */ 344 | RUN68_COMMAND_NEXT, /* STEPと同じ。ただし、サブルーチン呼出しはスキップ */ 345 | RUN68_COMMAND_QUIT, /* run68を終了する */ 346 | RUN68_COMMAND_REG, /* レジスタの内容を表示する */ 347 | RUN68_COMMAND_RUN, /* 環境を初期化してプログラム実行 */ 348 | RUN68_COMMAND_SET, /* メモリに値をセットする */ 349 | RUN68_COMMAND_STEP, /* 一命令分ステップ実行 */ 350 | RUN68_COMMAND_WATCHC, /* 命令ウォッチ */ 351 | RUN68_COMMAND_NULL, /* コマンドではない(移動禁止) */ 352 | RUN68_COMMAND_ERROR /* コマンドエラー(移動禁止) */ 353 | } RUN68_COMMAND; 354 | 355 | RUN68_COMMAND debugger(BOOL running); 356 | 357 | /* conditions.c */ 358 | void general_conditions(Long dest, int size); 359 | void add_conditions(Long src , Long dest, Long result, int size, BOOL zero_flag); 360 | void cmp_conditions(Long src , Long dest, Long result, int size); 361 | void sub_conditions(Long src , Long dest, Long result, int size, BOOL zero_flag); 362 | void neg_conditions(Long dest, Long result, int size, BOOL zero_flag); 363 | void check(char *mode, Long src, Long dest, Long result, int size, short before); 364 | 365 | #ifdef MAIN 366 | FILEINFO finfo [ FILE_MAX ] ; /* ファイル管理テーブル */ 367 | INI_INFO ini_info ; /* iniファイルの内容 */ 368 | char size_char [ 3 ] = { 'b', 'w', 'l' } ; 369 | Long ra [ 8 ] ; /* アドレスレジスタ */ 370 | Long rd [ 8 + 1 ] ; /* データレジスタ */ 371 | Long usp ; /* USP */ 372 | Long pc ; /* プログラムカウンタ */ 373 | short sr ; /* ステータスレジスタ */ 374 | char *prog_ptr ; /* プログラムをロードしたメモリへのポインタ */ 375 | int trap_count ; /* 割り込み処理中なら0 */ 376 | Long superjsr_ret ; /* DOSCALL SUPER_JSRの戻りアドレス */ 377 | Long psp [ NEST_MAX ] ; /* PSP */ 378 | Long nest_pc [ NEST_MAX ] ; /* 親プロセスへの戻りアドレスを保存 */ 379 | Long nest_sp [ NEST_MAX ] ; /* 親プロセスのスタックポインタを保存 */ 380 | char nest_cnt ; /* 子プロセスを起動するたびに+1 */ 381 | Long mem_aloc ; /* メインメモリの大きさ */ 382 | #else 383 | extern FILEINFO finfo [ FILE_MAX ] ; 384 | extern INI_INFO ini_info ; 385 | extern char size_char [ 3 ] ; 386 | extern Long ra [ 8 ] ; 387 | extern Long rd [ 8 + 1 ] ; 388 | extern Long usp ; 389 | extern Long pc ; 390 | extern short sr ; 391 | extern char *prog_ptr ; 392 | extern int trap_count ; 393 | extern Long superjsr_ret ; 394 | extern Long psp [ NEST_MAX ] ; 395 | extern Long nest_pc [ NEST_MAX ] ; 396 | extern Long nest_sp [ NEST_MAX ] ; 397 | extern char nest_cnt ; 398 | extern Long mem_aloc ; 399 | #endif 400 | 401 | /* 402 | 0ライン命令:movep, addi, subi, cmpi, andi, eori, ori, btst, bset, bclr, bchg 403 | 1ライン命令:move.b 404 | 2ライン命令:move.l, movea.l 405 | 3ライン命令:move.w, movea.w 406 | 4ライン命令:moveccr, movesr, moveusp, movem, swap, lea, pea, link, unlk, 407 |        clr, ext, neg, negx, tst, tas, not, nbcd, jmp, jsr, rtr, rts, 408 |        trap, trapv, chk, rte, reset, stop, nop 409 | 5ライン命令:addq, subq, dbcc, scc 410 | 6ライン命令:bcc, bra, bsr 411 | 7ライン命令:moveq 412 | 8ライン命令:divs, divu, or, sbcd 413 | 9ライン命令:sub, suba, subx 414 | Bライン命令:cmp, cmpa, cmpm, eor 415 | Cライン命令:exg, muls, mulu, and, abcd 416 | Dライン命令:add, adda, addx 417 | Eライン命令:asl, asr, lsl, lsr, rol, ror, roxl, roxr 418 | */ 419 | 420 | #endif /* !defined(_RUN68_H_) */ 421 | --------------------------------------------------------------------------------