├── .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 | [](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 |
--------------------------------------------------------------------------------