mirror of
https://github.com/ksherlock/mpw.git
synced 2024-06-08 02:29:36 +00:00
Compare commits
415 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d59a35d3a9 | ||
|
9951892251 | ||
|
79a8a93e03 | ||
|
f619ed31b3 | ||
|
f460696b4f | ||
|
6151ca1e87 | ||
|
b9c7d9f95f | ||
|
2dcb161f5e | ||
|
f08d67333d | ||
|
2e7e75a2a9 | ||
|
bdb1f4b2b9 | ||
|
b8d17f4481 | ||
|
a76287876c | ||
|
022d4cffe9 | ||
|
843ea2764c | ||
|
fc15ad1d81 | ||
|
7ac2a88974 | ||
|
2703e00201 | ||
|
5facdb095c | ||
|
194c36c89a | ||
|
3e2c02f796 | ||
|
48d869c6e8 | ||
|
8c911ab83d | ||
|
b6b0abefbf | ||
|
67253a69e5 | ||
|
f3b3d221be | ||
|
f4e3bd70a1 | ||
|
1925dc172b | ||
|
4730a70874 | ||
|
a70270be52 | ||
|
f12b3789c4 | ||
|
6dfefb2343 | ||
|
35443c9aa8 | ||
|
fcdfe76817 | ||
|
a55b38104b | ||
|
fb0d353716 | ||
|
7dc85091a3 | ||
|
0cca883287 | ||
|
58f2557df5 | ||
|
031cdf0d08 | ||
|
c8310c0dbd | ||
|
3480881001 | ||
|
8f64923f9c | ||
|
7cb4c8cbc3 | ||
|
1a9cb0d766 | ||
|
02629c4eee | ||
|
fa1f4623c9 | ||
|
b560c66dda | ||
|
2eb90481bc | ||
|
8c38175492 | ||
|
08fef2cef5 | ||
|
fb6d52a93d | ||
|
26bd3f53b7 | ||
|
d11dab46e2 | ||
|
c3d1121f36 | ||
|
776b385a41 | ||
|
119d9aab57 | ||
|
60b49a1ff4 | ||
|
e21aac4022 | ||
|
60c4977dfa | ||
|
58f4ca4ac6 | ||
|
3ef7de4b8a | ||
|
67d176856a | ||
|
ac3c3293d1 | ||
|
c3b235ee95 | ||
|
51a86117b8 | ||
|
5976f91a89 | ||
|
f79e74c510 | ||
|
99d1ca04fd | ||
|
b5a39a1a8f | ||
|
197726c6cc | ||
|
c9c77d33b8 | ||
|
2e0cb34559 | ||
|
eb54d7bb79 | ||
|
fc5e675a51 | ||
|
4af7d59c9c | ||
|
115acb493b | ||
|
5ebc0b276b | ||
|
288a11e6af | ||
|
aae68c20dd | ||
|
cd99626176 | ||
|
dd460a21eb | ||
|
f52331035a | ||
|
a726a68dfc | ||
|
c17dd4f400 | ||
|
97f7e734bb | ||
|
de50c3d796 | ||
|
861ca9b83a | ||
|
56fb5d9743 | ||
|
2a62ad32d2 | ||
|
559f36c437 | ||
|
563dd0f485 | ||
|
1bbcf1cc39 | ||
|
8d40559a62 | ||
|
f17839cc7e | ||
|
f2dc249614 | ||
|
2766493398 | ||
|
ac4506b52e | ||
|
37220202a6 | ||
|
88bc42d153 | ||
|
8bfff02114 | ||
|
29b780c712 | ||
|
b1d647d695 | ||
|
84ff99c177 | ||
|
1675a479c9 | ||
|
a7301cfd5d | ||
|
d48f3c39da | ||
|
67cb2b6e09 | ||
|
42fe265dd2 | ||
|
9fda034e0e | ||
|
f0e585aada | ||
|
279c8c2300 | ||
|
3ff0697e46 | ||
|
6197910e3e | ||
|
33ba7e076a | ||
|
acf93dacbf | ||
|
ab6259c030 | ||
|
bfc36cb872 | ||
|
7168fe8ba3 | ||
|
ce3b1ca11d | ||
|
ddeea8620f | ||
|
710da65650 | ||
|
023d233c40 | ||
|
d0d1e84162 | ||
|
5bab4d85eb | ||
|
cbe642bfc8 | ||
|
f02b930700 | ||
|
176fb108a6 | ||
|
928010f800 | ||
|
792e21d0c1 | ||
|
7c928c8eb5 | ||
|
3e64b3e087 | ||
|
e4ad003bc7 | ||
|
7beb3a7b43 | ||
|
813e36a6c4 | ||
|
44d19f7d1b | ||
|
3615fbe941 | ||
|
172da3e250 | ||
|
acea989367 | ||
|
3448078612 | ||
|
24666c209f | ||
|
34d1fba0f1 | ||
|
654baccabc | ||
|
92d465fb56 | ||
|
e8d756c1b6 | ||
|
74370db603 | ||
|
b146399a7e | ||
|
245fabe648 | ||
|
6c8511838e | ||
|
cc477e0865 | ||
|
863fafda98 | ||
|
eca0516094 | ||
|
d2bca7efe0 | ||
|
cf4a8e2fcc | ||
|
cb08a2e4c2 | ||
|
dbdcbea31c | ||
|
80efa55c24 | ||
|
5deea9eb84 | ||
|
bfa09940e7 | ||
|
f42c8e06dd | ||
|
ff9a0aad3e | ||
|
6aaadb8861 | ||
|
dba511a103 | ||
|
3f4dd56d78 | ||
|
b9fcbf2aac | ||
|
45c89042ee | ||
|
2bb2bd4326 | ||
|
d043ff9d9c | ||
|
2adbe82704 | ||
|
42a1f5030d | ||
|
02e95874d1 | ||
|
1e2c1a8f5d | ||
|
7eb33de435 | ||
|
24e47c7f9b | ||
|
183078925e | ||
|
6449892f51 | ||
|
ac66233f40 | ||
|
00c38721a7 | ||
|
3b904ee3de | ||
|
806a4b7eaf | ||
|
a78226c536 | ||
|
6acd7797af | ||
|
25357e2666 | ||
|
15d0eded63 | ||
|
427a4a6f31 | ||
|
5aa9f08870 | ||
|
b707e02295 | ||
|
cbe66b6798 | ||
|
f946dc1884 | ||
|
f6cc3925a7 | ||
|
f7bee265cc | ||
|
8e434d39f8 | ||
|
d400bfb4da | ||
|
1cd59d36f3 | ||
|
7691267dea | ||
|
a111120033 | ||
|
490519b0d1 | ||
|
f9508bbfda | ||
|
ab783ea4c9 | ||
|
231bd95bdc | ||
|
6d3ba9430e | ||
|
2c3388f76a | ||
|
b7aa23f163 | ||
|
9d46424968 | ||
|
45269178b4 | ||
|
22a8d6f588 | ||
|
8c9e50cd8f | ||
|
45fae53ef5 | ||
|
8c811c4de9 | ||
|
e0094d199b | ||
|
f7c779a5d1 | ||
|
09d17315d3 | ||
|
e377025e48 | ||
|
3dd91f18b6 | ||
|
ace2810e34 | ||
|
48558e9885 | ||
|
d8f6edd964 | ||
|
f1566cce45 | ||
|
1e7139ddbf | ||
|
30d6b05adc | ||
|
91a0da2e0a | ||
|
b60d23ea60 | ||
|
6787eb1f1a | ||
|
204332c4c9 | ||
|
6929a374d0 | ||
|
728db5133e | ||
|
841af35840 | ||
|
1a70abf995 | ||
|
8257050afc | ||
|
240a3ac480 | ||
|
a4e89626d5 | ||
|
148b13cdf1 | ||
|
4bf57c6ce4 | ||
|
84fdeb116f | ||
|
304dcda66c | ||
|
c03938ca7d | ||
|
eda186e9ff | ||
|
6a8a30df5a | ||
|
325c1c5850 | ||
|
18b2e7ff67 | ||
|
bd93788eef | ||
|
85e515bdeb | ||
|
0b76b9266e | ||
|
d79f498cfd | ||
|
80be590e76 | ||
|
294a0c901b | ||
|
f6f7964f81 | ||
|
91e142446b | ||
|
fed6e9b172 | ||
|
abe8b9236b | ||
|
ff52cae4e9 | ||
|
6f50f9de03 | ||
|
2502c18862 | ||
|
d826ef8c13 | ||
|
4895cfbf10 | ||
|
d1c067e47a | ||
|
28d8900f3f | ||
|
8d93303781 | ||
|
4007491eec | ||
|
e31c376a7d | ||
|
5dcf23ad76 | ||
|
cd8bdfaa60 | ||
|
74216da21e | ||
|
b15d86b543 | ||
|
afdfbf7c33 | ||
|
6d2ebdf4c1 | ||
|
00e519cdff | ||
|
3c77f0b58f | ||
|
63ef12bac3 | ||
|
0dd7b46d8f | ||
|
a02e5ccec8 | ||
|
a97d8b08fe | ||
|
7196a85c36 | ||
|
d0bc67e9d5 | ||
|
d275c389e6 | ||
|
e1ff46a97a | ||
|
9c9decbe3b | ||
|
53cda5c7b7 | ||
|
a11eacf317 | ||
|
c7acd1d8e1 | ||
|
caac09787a | ||
|
4b4122bee2 | ||
|
ff84c1d3f1 | ||
|
58b1ced70f | ||
|
cff61ead03 | ||
|
e2700665d0 | ||
|
05317be1e1 | ||
|
7c2cf3d1fd | ||
|
e414163ec9 | ||
|
b7b6d8656b | ||
|
810b521a11 | ||
|
10bed9a239 | ||
|
0d24388f98 | ||
|
b61d082497 | ||
|
60683d14ea | ||
|
ca57bad853 | ||
|
2fcbf090bb | ||
|
7858711902 | ||
|
49dcba4173 | ||
|
60869a697a | ||
|
a0ea7c365a | ||
|
4133014b3d | ||
|
f448a290b6 | ||
|
ada525cc4b | ||
|
6e5134389d | ||
|
fe8137bb37 | ||
|
e83f2d6d35 | ||
|
4041b14b36 | ||
|
88423bc690 | ||
|
d6d30ba81e | ||
|
99a5ed86f8 | ||
|
748dd6e634 | ||
|
5130649a9e | ||
|
980a21d510 | ||
|
061c025e02 | ||
|
bd3e540b89 | ||
|
8db3b90777 | ||
|
e53dbcce13 | ||
|
4a1aace4d7 | ||
|
bf5b087514 | ||
|
75606c72e2 | ||
|
2bd086232b | ||
|
bdce056449 | ||
|
37b45e66ab | ||
|
b4e5e5a059 | ||
|
011a9967e5 | ||
|
1193ad2de7 | ||
|
83ccc8270c | ||
|
680e57fcb0 | ||
|
e83477c9b2 | ||
|
6b383a0e35 | ||
|
e1e3f3f4a2 | ||
|
7a08004542 | ||
|
fc04a2b2cb | ||
|
a47a55e7ce | ||
|
eacb0d4716 | ||
|
541ac7fc29 | ||
|
7c127931e1 | ||
|
76af81ab0e | ||
|
958dafa754 | ||
|
1abb98e1dd | ||
|
3f55b2b8ab | ||
|
92ef78516c | ||
|
6eb07f173a | ||
|
9aaf997fe3 | ||
|
9dc63fd4b7 | ||
|
ce5ad32be1 | ||
|
23ff00baa7 | ||
|
81ce611bfc | ||
|
e571c7066d | ||
|
ece1984c5c | ||
|
9acce3ae03 | ||
|
75ad0ab38c | ||
|
9312383433 | ||
|
616d0ec0c7 | ||
|
4995a12be5 | ||
|
7f59b64aad | ||
|
68a70cfcbc | ||
|
6e68357051 | ||
|
ccd3273ff0 | ||
|
69cd091397 | ||
|
0c87dbd545 | ||
|
9e2a8d3e53 | ||
|
db89554b31 | ||
|
fa92c2fca7 | ||
|
eedf675ebd | ||
|
6fbde7e1bf | ||
|
62a374ee16 | ||
|
b85cf313c0 | ||
|
7c218a7a9e | ||
|
5d87528367 | ||
|
0a729dcacf | ||
|
82f8770a5e | ||
|
4bdac5a62a | ||
|
27cd692790 | ||
|
552d95f9e0 | ||
|
03c0951253 | ||
|
ba2fba246b | ||
|
98b5455549 | ||
|
8c0e3f04ac | ||
|
dccdd7cb26 | ||
|
a436e91373 | ||
|
0dbb111b9b | ||
|
16604caf0f | ||
|
07a2120993 | ||
|
c156fd4aa2 | ||
|
f0a1240475 | ||
|
ef168abf26 | ||
|
a35fa69cf1 | ||
|
71517ad252 | ||
|
04e48765b2 | ||
|
651922bd26 | ||
|
890d703f9f | ||
|
9ddb015b1b | ||
|
bf6d689264 | ||
|
a11a264b02 | ||
|
ce66961c7e | ||
|
a40bf9ee39 | ||
|
457c045ebe | ||
|
9ef1bba18d | ||
|
4c27545022 | ||
|
1dc96f1777 | ||
|
39d1a33483 | ||
|
e40bd303f2 | ||
|
fafc1b6cd8 | ||
|
675f36368b | ||
|
7f3b7bcd13 | ||
|
13657ab760 | ||
|
f4d4100c5d | ||
|
acb5733e6c | ||
|
ef80d410ca | ||
|
922783b288 | ||
|
095a38596d | ||
|
f6132773db | ||
|
1aebf46653 |
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: [ksherlock]
|
38
.github/workflows/cmake-fat.yml
vendored
Normal file
38
.github/workflows/cmake-fat.yml
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
name: CMake fat
|
||||
|
||||
on: [push]
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Brew
|
||||
run: brew install ragel lemon
|
||||
|
||||
- name: Create Build Environment
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: make mpw
|
||||
|
||||
- name: Archive
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: mpw fat
|
||||
path: ${{runner.workspace}}/build/bin/mpw
|
41
.github/workflows/cmake.yml
vendored
Normal file
41
.github/workflows/cmake.yml
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
name: CMake
|
||||
|
||||
on: [push]
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-12, macos-13]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Brew
|
||||
run: brew install ragel lemon
|
||||
|
||||
- name: Create Build Environment
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
|
||||
- name: Archive
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: mpw ${{ matrix.os }}
|
||||
path: ${{runner.workspace}}/build/bin/mpw
|
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,4 +1,10 @@
|
|||
.DS_Store
|
||||
*.dSYM
|
||||
build/
|
||||
fellow/
|
||||
fellow/
|
||||
dist/
|
||||
rtl/
|
||||
docs/
|
||||
MrC/
|
||||
testing/
|
||||
|
||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "libsane"]
|
||||
path = libsane
|
||||
url = https://github.com/ksherlock/libsane.git
|
18
.travis.yml
Normal file
18
.travis.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
os: osx
|
||||
osx_image:
|
||||
- xcode11
|
||||
- xcode12
|
||||
- xcode12.5
|
||||
language: cpp
|
||||
compiler: clang
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake ..
|
||||
script: make mpw
|
||||
before_install:
|
||||
- brew update
|
||||
- brew install lemon
|
||||
- brew install ragel
|
||||
# - brew install cmake # not needed.
|
||||
|
84
CHANGELOG.text
Normal file
84
CHANGELOG.text
Normal file
|
@ -0,0 +1,84 @@
|
|||
|
||||
-------------------------
|
||||
0.8.0 - February 12, 2014
|
||||
-------------------------
|
||||
|
||||
* new debugger feature: templates ("a0;t HFileInfo" to display as an HFileInfo struct)
|
||||
* Prevent OS X Resource Manager from byteswapping resource data. Rez and DeRez now work.
|
||||
* .sym and .ntkc files considered binary (Newton tools)
|
||||
* some support for the MetroWerks MPW tools
|
||||
* Lots of other miscellaneous bug fixes and tweaks
|
||||
|
||||
-------------------------
|
||||
0.7.9.a - January 4, 2014
|
||||
-------------------------
|
||||
|
||||
* Improved MrC/pp compatibility. MrC creates a binary temp file that was treated as text which caused problems.
|
||||
* added TempNewHandle, TempHLock, TempHUnlock, and TempDisposeHandle toolcalls
|
||||
* added ;date debugger command: expr;date will display expr as a MacOS date/time
|
||||
* added ;error debugger command: expr;error will display exrp as a MacOS error.
|
||||
|
||||
------------------------
|
||||
0.7.9 - December 28, 2014
|
||||
------------------------
|
||||
|
||||
* MrC, MrCpp, PEFDump, DumpXCOFF, PPCLink now supported
|
||||
- various new tools implemented and bug fixes for existing ones.
|
||||
|
||||
* Debugger improvements:
|
||||
- jsr $deadbeef now shows as jsr _deadbeef (if the macsbug name is available)
|
||||
- expression evaluator now support 68k asm style offset(register) syntax
|
||||
eg, $fffb(a6) is equivalent to a6-5
|
||||
- backtrace support. bt prints the last 20 instructions with register values.
|
||||
|
||||
* SetFileInfo tool calls now set the creation, backup, and modification dates.
|
||||
|
||||
* etc.
|
||||
|
||||
------------------------
|
||||
0.7.1 - October 30, 2013
|
||||
------------------------
|
||||
|
||||
* FCONVERT/Comp support
|
||||
- FX2C and FC2X are now supported
|
||||
- cciigs now supports the comp data type.
|
||||
|
||||
* AsmMatIIgs fixes
|
||||
- added support for faccess F_GTABINFO
|
||||
|
||||
* Debugger improvements:
|
||||
- ;i also shows toolbox and global info
|
||||
- added a symbol table, pre-populated with addresses from MacsBugs debug names.
|
||||
- tab completion for symbol table entries.
|
||||
|
||||
* PPCAsm utility now supported
|
||||
- added HomeResFile toolbox call.
|
||||
|
||||
* CODE loader enhancements
|
||||
- Cleaned up CODE loader.
|
||||
- Added experimental support for far model segments
|
||||
- SCpp works, MrC and MrCpp does not currently work
|
||||
|
||||
* DumpCode utility now supported
|
||||
- added HGetState, GetResInfo, LoadResource, Count1Types, Get1IndType toolbox calls
|
||||
|
||||
|
||||
* Pathname conversion enhancements:
|
||||
- code has been rewritten
|
||||
- supports :: to go up a directory
|
||||
- supports MPW environment variables (eg {PLibraries}PasLib.o)
|
||||
|
||||
* Environment enhancements:
|
||||
- code has been rewritten.
|
||||
- -DName=Value now supported on the commandline (eg MPW -DMPWVersion=3.5 SC .... )
|
||||
- += now supported in the text file for appending
|
||||
- {variables} are now supported for better MPW compatibility.
|
||||
- At some point, ${variables} and $variables may be removed.
|
||||
|
||||
* debugger now support 0b binary literals
|
||||
|
||||
---------------------
|
||||
0.7.1 - July 26, 2013
|
||||
---------------------
|
||||
|
||||
* First public release.
|
|
@ -1,10 +1,32 @@
|
|||
set(CMAKE_C_COMPILER "clang")
|
||||
set(CMAKE_CXX_COMPILER "clang++")
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -g")
|
||||
set(CMAKE_C_FLAGS " -Wall -g")
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(mpw VERSION 0.8.3 LANGUAGES CXX C)
|
||||
|
||||
project(mpw)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||
set(CMAKE_CXX_EXTENSIONS FALSE)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED TRUE)
|
||||
set(CMAKE_C_EXTENSIONS FALSE)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
# Clang or AppleClang
|
||||
set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
|
||||
# Clang or AppleClang
|
||||
set(CMAKE_C_FLAGS "-Wall ${CMAKE_C_FLAGS}")
|
||||
endif()
|
||||
|
||||
|
||||
find_program(RAGEL NAMES ragel)
|
||||
if (NOT RAGEL)
|
||||
message(FATAL_ERROR "ragel (version 6) is required.")
|
||||
endif()
|
||||
|
||||
|
||||
include_directories("${CMAKE_SOURCE_DIR}")
|
||||
|
||||
add_subdirectory(bin)
|
||||
add_subdirectory(cpu)
|
||||
|
@ -12,3 +34,5 @@ add_subdirectory(toolbox)
|
|||
add_subdirectory(mplite)
|
||||
add_subdirectory(mpw)
|
||||
add_subdirectory(macos)
|
||||
|
||||
add_subdirectory(libsane)
|
||||
|
|
29
Environment
29
Environment
|
@ -1,29 +0,0 @@
|
|||
# MPW Environment file
|
||||
# ${var} or $var substitution supported
|
||||
# $MPW and $Command are pre-defined
|
||||
# $MPW uses MacOS : paths.
|
||||
|
||||
ShellDirectory=$MPW
|
||||
SysTempFolder=/tmp/
|
||||
TempFolder=/tmp/
|
||||
|
||||
AIIGSIncludes=$MPW:Interfaces:AIIGSIncludes:
|
||||
RIIGSIncludes=$MPW:Interfaces:RIIGSIncludes:
|
||||
CIIGSIncludes=$MPW:Interfaces:CIIGSIncludes:
|
||||
CIIGSLibraries=$MPW:Libraries:CIIGSLibraries:
|
||||
PIIGSIncludes=$MPW:Interfaces:PIIGSIncludes:
|
||||
PIIGSLibraries=$MPW:Libraries:PIIGSLibraries:
|
||||
|
||||
# MPW IIgs v 1.0 compatibility
|
||||
AIIGSInclude=$MPW:Interfaces:AIIGSIncludes:
|
||||
RIIGSInclude=$MPW:Interfaces:RIIGSIncludes:
|
||||
CIIGSinclude=$MPW:Interfaces:CIIGSIncludes:
|
||||
CIIGSLibrary=$MPW:Libraries:CIIGSIncludes:
|
||||
|
||||
# MPW Macintosh compilers
|
||||
SCIncludes=$MPW:Interfaces:CIncludes:
|
||||
CIncludes=$MPW:Interfaces:CIncludes:
|
||||
AIncludes=$MPW:Interfaces:AIncludes:
|
||||
RIncludes=$MPW:Interfaces:RIncludes:
|
||||
PInterfaces=$MPW:Interfaces:PInterfaces:
|
||||
|
100
README.md
Normal file
100
README.md
Normal file
|
@ -0,0 +1,100 @@
|
|||
MPW Emulator
|
||||
------------
|
||||
|
||||
by Kelvin W Sherlock, _et alia_
|
||||
|
||||
Please check the [wiki](https://github.com/ksherlock/mpw/wiki/_pages) for useful information.
|
||||
|
||||
Please check the [releases](https://github.com/ksherlock/mpw/releases) for compiled binaries.
|
||||
|
||||
|
||||
## System compatibility
|
||||
|
||||
Currently, only OS X 10.8+ with case-insensitive HFS+ is supported.
|
||||
|
||||
## License
|
||||
|
||||
The 680x0 CPU code is from [WinFellow](http://fellow.sourceforge.net) and is
|
||||
licensed under GPL v2 or later. Consequently, the compiled binary is licensed
|
||||
under the GPL v2 as well.
|
||||
|
||||
The memory allocator (NewHandle/NewPointer) code is from [mempoolite](https://github.com/jeftyneg/mempoolite),
|
||||
which is a fork of the SQLite zero-alloc allocator by Jefty Negapatan and D. Richard Hipp. It, as is SQLite,
|
||||
is in the public domain.
|
||||
|
||||
## Building
|
||||
|
||||
First initialize and fetch submodules:
|
||||
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
Compiling requires cmake, ragel, lemon, and a recent version of clang++ with
|
||||
c++11 support. It has only been built and tested with OS X 10.8+.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
This will generate `bin/mpw` and `bin/disasm`.
|
||||
|
||||
## Installation
|
||||
|
||||
Certain configuration and execution files are generally useful. They are
|
||||
stored in an mpw directory, which may be located:
|
||||
|
||||
$MPW (shell variable)
|
||||
~/mpw/ (your home directory)
|
||||
/usr/local/share/mpw/
|
||||
/usr/share/mpw/
|
||||
|
||||
The layout is reminiscent of actual MPW installations.
|
||||
|
||||
mpw/Environment.text
|
||||
mpw/Tools/...
|
||||
mpw/Interfaces/...
|
||||
mpw/Libraries/...
|
||||
mpw/Help/...
|
||||
|
||||
## Environment file
|
||||
|
||||
The Environment.text file is new; it contains MPW environment variables (many
|
||||
of them set the library and include file locations). The format is fairly
|
||||
simple.
|
||||
|
||||
# this is a comment
|
||||
|
||||
#this sets a variable
|
||||
name = value
|
||||
|
||||
# this sets a variable if it is undefined.
|
||||
name ?= value
|
||||
|
||||
# values may refer to other variables
|
||||
Libraries=$MPW:Libraries:Libraries:
|
||||
Libraries=${MPW}:Libraries:Libraries:
|
||||
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
`mpw [mpw flags] command-name [command arguments]`
|
||||
|
||||
you may also create shell aliases:
|
||||
|
||||
`alias AsmIIgs='mpw AsmIIgs'`
|
||||
|
||||
or create a shell script (in `/usr/local/bin`, etc)
|
||||
|
||||
`/usr/local/bin/AsmIIgs`:
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
exec mpw AsmIIgs "$@"
|
||||
|
||||
|
||||
mpw uses the MPW `$Commands` variable to find the command, similar to `$PATH` on Unix. If the `$Commands` variable
|
||||
is not set, mpw looks in the current directory and then in the `$MPW:Tools:` directory.
|
||||
|
93
README.text
Normal file
93
README.text
Normal file
|
@ -0,0 +1,93 @@
|
|||
MPW Emulator
|
||||
------------
|
||||
|
||||
by Kelvin W Sherlock, et alia.
|
||||
|
||||
0. System compatibility
|
||||
|
||||
Currently, only OS X 10.8 with case-insensitive HFS+ is supported.
|
||||
|
||||
1. License
|
||||
|
||||
The 680x0 CPU code is from WinFellow (http://fellow.sourceforge.net) and is
|
||||
licensed under GPL v2 or later. Consequently, the rest of the code is licensed
|
||||
under the GPL v2 as well.
|
||||
|
||||
The memory allocator (NewHandle/NewPointer) code is from mempoolite, which
|
||||
is a fork of the SQLite zero-alloc allocator by Jefty Negapatan and D. Richard Hipp.
|
||||
It, as is SQLite, is in the public domain.
|
||||
|
||||
2. Building
|
||||
|
||||
Compiling requires cmake, ragel, lemon, and a recent version of clang++ with
|
||||
c++11 support. It has only been built and tested with OS X 10.8.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
This will generate bin/mpw and bin/disasm.
|
||||
|
||||
3. Installation
|
||||
|
||||
Certain configuration and execution files are generally useful. They are
|
||||
stored in an mpw directory, which may be located:
|
||||
|
||||
$MPW (shell variable)
|
||||
~/mpw/ (your home directory)
|
||||
/usr/local/share/mpw/
|
||||
/usr/share/mpw/
|
||||
|
||||
The layout is reminiscent of actual MPW installations.
|
||||
|
||||
mpw/Environment.text
|
||||
mpw/Tools/...
|
||||
mpw/Interfaces/...
|
||||
mpw/Libraries/...
|
||||
mpw/Help/...
|
||||
|
||||
4. Environment file
|
||||
|
||||
The Environment.text file is new; it contains MPW environment variables (many
|
||||
of them set the library and include file locations). The format is fairly
|
||||
simple.
|
||||
|
||||
# this is a comment
|
||||
|
||||
#this sets a variable
|
||||
name = value
|
||||
|
||||
# this sets a variable if it is undefined.
|
||||
name ?= value
|
||||
|
||||
# values may refer to other variables
|
||||
Libraries=$MPW:Libraries:Libraries:
|
||||
Libraries=${MPW}:Libraries:Libraries:
|
||||
|
||||
eventually, mpw will support a -Dname=value flag, so you can do something like:
|
||||
|
||||
# use 3.2 headers/libraries unless overridden on the command line
|
||||
MPWVersion ?= 3.2
|
||||
Libraries=$MPW:Libraries:Libraries-$MPWVersion:
|
||||
|
||||
|
||||
5. Usage
|
||||
|
||||
mpw [mpw flags] command-name [command arguments]
|
||||
|
||||
you may also create shell aliases:
|
||||
|
||||
alias AsmIIgs='mpw AsmIIgs'
|
||||
|
||||
or create a shell script (in /usr/local/bin, etc)
|
||||
|
||||
/usr/local/bin/AsmIIgs:
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
exec mpw AsmIIgs "$@"
|
||||
|
||||
mpw looks in the current directory and then in the $MPW:Tools: directory
|
||||
for the command to run. The MPW $Commands variable is not yet supported.
|
||||
|
60
TODO.txt
60
TODO.txt
|
@ -1,3 +1,58 @@
|
|||
TODO
|
||||
|
||||
|
||||
.B .W .L -- add a modifier field. * uses it for the read size. all others use it when token converted to integer.
|
||||
|
||||
debugger improvements:
|
||||
|
||||
completion context:
|
||||
|
||||
when in tbrk, lookup based on the toolbox map ninstead of general symbol table?
|
||||
|
||||
|
||||
symbol table should be a range. Debug names are loaded as start:end.
|
||||
In scalar context, just use the start value.
|
||||
In range context, use as a range unless specific range or count provided.
|
||||
|
||||
eg:
|
||||
|
||||
main;l <- list all of main
|
||||
|
||||
new command: protect
|
||||
usage: protect range
|
||||
(where range can be explicit or a debug name)
|
||||
prevents tracing within the defined code.
|
||||
|
||||
|
||||
last address
|
||||
expression evaluation updates the last address. ;command is equivalent to lastaddress;command.
|
||||
|
||||
|
||||
- tool to list iigs/mac resource fork (rlist)
|
||||
|
||||
|
||||
1. scan file for debug names (starting at 4e56 - link a6), load into environment table (with tools)
|
||||
2. address break, ^C break, etc - list reason *before* disasm line
|
||||
4. ; commands - keep track of last address (;l to repeat...)
|
||||
|
||||
5. run until return? (t bits in csr?)
|
||||
|
||||
6. local variables (set/clear)
|
||||
set identifier '=' expression
|
||||
unset identifier
|
||||
|
||||
expression '(' expression ')' -> 16-bit offset.
|
||||
|
||||
|
||||
stack dump? any safe way to get the previous address (how many bytes for jsr?)
|
||||
|
||||
option for MPW 3.2 vs 3.5?
|
||||
store as MPWVersion (standard shell variable)
|
||||
CLibraries=$MPW:Libraries:CLibraries-$MPWVersion:
|
||||
|
||||
|
||||
|
||||
|
||||
--trace-cpu:
|
||||
- add support for global vars [?]
|
||||
- improve MOVEM disassembly [?]
|
||||
|
@ -18,11 +73,14 @@
|
|||
|
||||
- stdout -- convert macroman to utf8 on output?
|
||||
|
||||
-- orca/c - symfile support.
|
||||
|
||||
|
||||
Done
|
||||
----
|
||||
- set the time global @ start up (Pascal res files)
|
||||
|
||||
- rbreak/wbreak/rwbreak - break on memory access
|
||||
- orca/c : symfile support.
|
||||
|
||||
- Use MM code for all memory allocs
|
||||
- GetFileInfo -- create fake finderinfo record from extension.
|
||||
|
|
|
@ -1,19 +1,82 @@
|
|||
#set(CMAKE_C_COMPILER "clang")
|
||||
#set(CMAKE_CXX_COMPILER "clang++")
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -Wno-deprecated-declarations -g")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-framework Carbon")
|
||||
|
||||
add_definitions(-I ${CMAKE_SOURCE_DIR}/)
|
||||
|
||||
|
||||
add_executable(mpw loader.cpp)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
# Clang or AppleClang
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations -Wno-unused-variable")
|
||||
endif()
|
||||
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT lexer.cpp
|
||||
COMMAND "${RAGEL}" -p -G2 -o lexer.cpp "${CMAKE_CURRENT_SOURCE_DIR}/lexer.rl"
|
||||
MAIN_DEPENDENCY lexer.rl
|
||||
)
|
||||
|
||||
find_program(LEMON NAMES lemon)
|
||||
|
||||
if (LEMON)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/parser.cpp ${CMAKE_CURRENT_SOURCE_DIR}/parser.h
|
||||
# COMMAND cp -f "${CMAKE_CURRENT_SOURCE_DIR}/parser.lemon" "parser.lemon"
|
||||
COMMAND ${LEMON} parser.lemon
|
||||
COMMAND mv -f parser.c parser.cpp
|
||||
MAIN_DEPENDENCY parser.lemon
|
||||
DEPENDS debugger.h
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/template_parser.cpp ${CMAKE_CURRENT_SOURCE_DIR}/template_parser.h
|
||||
# COMMAND cp -f "${CMAKE_CURRENT_SOURCE_DIR}/template_parser.lemon" "template_parser.lemon"
|
||||
COMMAND ${LEMON} template_parser.lemon
|
||||
COMMAND mv -f template_parser.c template_parser.cpp
|
||||
MAIN_DEPENDENCY template_parser.lemon
|
||||
DEPENDS debugger.h
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT loadtrap.cpp
|
||||
COMMAND "${RAGEL}" -p -G2 -o loadtrap.cpp "${CMAKE_CURRENT_SOURCE_DIR}/loadtrap.rl"
|
||||
MAIN_DEPENDENCY loadtrap.rl
|
||||
DEPENDS debugger.h
|
||||
)
|
||||
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT template_loader.cpp
|
||||
COMMAND "${RAGEL}" -p -G2 -o template_loader.cpp "${CMAKE_CURRENT_SOURCE_DIR}/template_loader.rl"
|
||||
MAIN_DEPENDENCY template_loader.rl
|
||||
DEPENDS debugger.h template_parser.h
|
||||
)
|
||||
|
||||
|
||||
add_executable(mpw loader.cpp debugger.cpp debugger_internal.cpp
|
||||
address_map.cpp lexer.cpp parser.cpp loadtrap.cpp
|
||||
commands.cpp
|
||||
template_loader.cpp template_parser.cpp intern.cpp template.cpp)
|
||||
|
||||
|
||||
target_link_libraries(mpw CPU_LIB)
|
||||
target_link_libraries(mpw TOOLBOX_LIB)
|
||||
target_link_libraries(mpw MPW_LIB)
|
||||
target_link_libraries(mpw MPLITE_LIB)
|
||||
target_link_libraries(mpw MACOS_LIB)
|
||||
|
||||
target_link_libraries(mpw -ledit)
|
||||
target_link_libraries(mpw "-framework Carbon")
|
||||
|
||||
add_executable(disasm disasm.cpp)
|
||||
target_link_libraries(disasm CPU_LIB)
|
||||
target_link_libraries(disasm MACOS_LIB)
|
||||
target_link_libraries(disasm "-framework Carbon")
|
||||
|
||||
install(
|
||||
PROGRAMS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mpw
|
||||
DESTINATION bin
|
||||
)
|
||||
|
|
102
bin/address_map.cpp
Normal file
102
bin/address_map.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "address_map.h"
|
||||
|
||||
AddressMap::AddressMap()
|
||||
{
|
||||
}
|
||||
AddressMap::~AddressMap()
|
||||
{
|
||||
}
|
||||
|
||||
void AddressMap::add(uint32_t address)
|
||||
{
|
||||
unsigned page = address >> 12;
|
||||
if (page >= pageMap.size()) return;
|
||||
pageMap[page]++;
|
||||
|
||||
map.emplace(address, 0);
|
||||
}
|
||||
|
||||
void AddressMap::remove(uint32_t address)
|
||||
{
|
||||
unsigned page = address >> 12;
|
||||
if (page >= pageMap.size()) return;
|
||||
|
||||
// erase(key) returns # of elements erased.
|
||||
pageMap[page] -= map.erase(address);
|
||||
}
|
||||
|
||||
bool AddressMap::lookup(uint32_t address)
|
||||
{
|
||||
unsigned page = address >> 12;
|
||||
if (page >= pageMap.size()) return false;
|
||||
if (!pageMap[page]) return false;
|
||||
|
||||
return map.find(address) != map.end();
|
||||
}
|
||||
|
||||
void AddressMap::clear()
|
||||
{
|
||||
pageMap.fill(0);
|
||||
map.clear();
|
||||
}
|
||||
|
||||
|
||||
ToolMap::ToolMap()
|
||||
{
|
||||
}
|
||||
|
||||
ToolMap::~ToolMap()
|
||||
{
|
||||
}
|
||||
|
||||
void ToolMap::clear()
|
||||
{
|
||||
map.clear();
|
||||
}
|
||||
|
||||
bool ToolMap::lookup(uint16_t tool)
|
||||
{
|
||||
if ((tool & 0xf000) != 0xa000) return false;
|
||||
return map.find(tool) != map.end();
|
||||
}
|
||||
|
||||
void ToolMap::add(uint16_t tool)
|
||||
{
|
||||
if ((tool & 0xf000) != 0xa000) return;
|
||||
|
||||
// return std::pair<iter, bool>
|
||||
map.emplace(tool, 0);
|
||||
}
|
||||
|
||||
void ToolMap::remove(uint16_t tool)
|
||||
{
|
||||
if ((tool & 0xf000) != 0xa000) return;
|
||||
|
||||
map.erase(tool);
|
||||
}
|
72
bin/address_map.h
Normal file
72
bin/address_map.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
#ifndef __address_map__
|
||||
#define __address_map__
|
||||
|
||||
#include <unordered_map>
|
||||
#include <array>
|
||||
|
||||
class AddressMap
|
||||
{
|
||||
public:
|
||||
AddressMap();
|
||||
~AddressMap();
|
||||
|
||||
void add(uint32_t address);
|
||||
void remove(uint32_t address);
|
||||
bool lookup(uint32_t address);
|
||||
|
||||
void clear();
|
||||
|
||||
std::unordered_map<uint32_t, unsigned>::iterator begin()
|
||||
{
|
||||
return map.begin();
|
||||
}
|
||||
|
||||
std::unordered_map<uint32_t, unsigned>::iterator end()
|
||||
{
|
||||
return map.end();
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return map.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<unsigned, 4096> pageMap;
|
||||
std::unordered_map<uint32_t, unsigned> map;
|
||||
};
|
||||
|
||||
class ToolMap
|
||||
{
|
||||
public:
|
||||
|
||||
ToolMap();
|
||||
~ToolMap();
|
||||
|
||||
void add(uint16_t tool);
|
||||
void remove(uint16_t tool);
|
||||
bool lookup(uint16_t tool);
|
||||
|
||||
void clear();
|
||||
|
||||
std::unordered_map<uint32_t, unsigned>::iterator begin()
|
||||
{
|
||||
return map.begin();
|
||||
}
|
||||
|
||||
std::unordered_map<uint32_t, unsigned>::iterator end()
|
||||
{
|
||||
return map.end();
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return map.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<uint32_t, unsigned> map;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
243
bin/commands.cpp
Normal file
243
bin/commands.cpp
Normal file
|
@ -0,0 +1,243 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
#include <toolbox/os.h>
|
||||
#include <macos/errors.h>
|
||||
|
||||
#include <cpu/defs.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
|
||||
#include "debugger.h"
|
||||
#include "debugger_internal.h"
|
||||
#include "loader.h" // Flags
|
||||
|
||||
|
||||
namespace Debug {
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
|
||||
void hexdump(const uint8_t *data, ssize_t size, uint32_t address = 0)
|
||||
{
|
||||
const char *HexMap = "0123456789abcdef";
|
||||
|
||||
char buffer1[16 * 3 + 1 + 1];
|
||||
char buffer2[16 + 1];
|
||||
ssize_t offset = 0;
|
||||
unsigned i, j;
|
||||
|
||||
|
||||
while(size > 0)
|
||||
{
|
||||
std::memset(buffer1, ' ', sizeof(buffer1));
|
||||
std::memset(buffer2, ' ', sizeof(buffer2));
|
||||
|
||||
unsigned linelen = (unsigned)std::min(size, (ssize_t)16);
|
||||
|
||||
|
||||
for (i = 0, j = 0; i < linelen; i++)
|
||||
{
|
||||
unsigned x = data[i];
|
||||
buffer1[j++] = HexMap[x >> 4];
|
||||
buffer1[j++] = HexMap[x & 0x0f];
|
||||
j++;
|
||||
if (i == 7) j++;
|
||||
|
||||
// isascii not part of std:: and may be a macro.
|
||||
buffer2[i] = isascii(x) && std::isprint(x) ? x : '.';
|
||||
|
||||
}
|
||||
|
||||
buffer1[sizeof(buffer1)-1] = 0;
|
||||
buffer2[sizeof(buffer2)-1] = 0;
|
||||
|
||||
|
||||
std::printf("%06x: %s %s\n", address + (unsigned)offset, buffer1, buffer2);
|
||||
offset += 16;
|
||||
data += 16;
|
||||
size -= 16;
|
||||
}
|
||||
std::printf("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PrintError(uint32_t value)
|
||||
{
|
||||
/* expr ; error -- interpret expr as an OSErr */
|
||||
|
||||
|
||||
// errors are signed 16-bit values.
|
||||
|
||||
if ((int32_t)value > UINT16_MAX) return;
|
||||
if ((int32_t)value < INT16_MIN) return;
|
||||
|
||||
|
||||
uint16_t error = value;
|
||||
printf("%d\n", (int16_t)error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
bool found = false;
|
||||
const char *cp = ErrorName(error);
|
||||
if (cp)
|
||||
{
|
||||
printf("%s\n", cp);
|
||||
found = true;
|
||||
}
|
||||
|
||||
|
||||
for (auto iter = ErrorTableInvert.find(error); iter != ErrorTableInvert.end(); ++iter) {
|
||||
|
||||
// multimap - continue until error doesn't match.
|
||||
if (iter->first != error) break;
|
||||
|
||||
printf("%s\n", iter->second.c_str());
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found) printf("Unknown error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("noErr\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PrintDate(uint32_t value)
|
||||
{
|
||||
/* expr ; date -- interpret expr as a macos date */
|
||||
|
||||
char buffer[64];
|
||||
struct tm *tm;
|
||||
time_t t = OS::MacToUnix(value);
|
||||
|
||||
// localtime vs gmtime?
|
||||
tm = ::localtime(&t);
|
||||
strftime(buffer, sizeof(buffer), "%Y-%m-%d %I:%M:%S %p", tm);
|
||||
puts(buffer);
|
||||
}
|
||||
|
||||
|
||||
void Moof(void)
|
||||
{
|
||||
|
||||
puts("");
|
||||
puts(" ## ");
|
||||
puts(" ## ## #### ");
|
||||
puts(" ## #### ## ");
|
||||
puts(" ## ## ");
|
||||
puts(" ## ## ## ## ");
|
||||
puts(" ## ## #### ");
|
||||
puts(" ## ## ## ## ");
|
||||
puts(" ######## #### ## ## ");
|
||||
puts(" ## #################### ## ");
|
||||
puts(" ## ############## ## ");
|
||||
puts(" #### ############ ## ");
|
||||
puts(" ###### ###### ## ");
|
||||
puts(" ###### ## ");
|
||||
puts(" #### ## ");
|
||||
puts(" ## ## ");
|
||||
puts(" ## ################ ## ");
|
||||
puts(" ## ## ## ## ");
|
||||
puts(" ## ## ## ## ");
|
||||
puts(" ## ## ## ## ");
|
||||
puts(" ## ## ## ## ");
|
||||
puts(" ## ## ## ## ");
|
||||
puts(" ###### ###### ");
|
||||
puts("");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void StackCrawl(void)
|
||||
{
|
||||
// stack crawl based on a6 frame pointers. (link/unlink)
|
||||
// start with current a6.
|
||||
|
||||
uint32_t a6 = cpuGetAReg(6);
|
||||
|
||||
/*
|
||||
* a6: previous a6
|
||||
* a6+4 return pc
|
||||
* .... parameters, locals, stack data
|
||||
* previous a6
|
||||
* return pc
|
||||
* ....
|
||||
*/
|
||||
// todo -- need a function to verify address is w/in stack range.
|
||||
|
||||
// todo print in reverse order so newest frame doesn't scroll away.
|
||||
|
||||
if (!a6) return;
|
||||
printf("a6: %08x\n", a6);
|
||||
|
||||
while(a6)
|
||||
{
|
||||
|
||||
uint32_t prevA6 = ReadLong(a6);
|
||||
if (prevA6 <= a6) break;
|
||||
|
||||
uint32_t pc = ReadLong(a6+4); //
|
||||
|
||||
|
||||
|
||||
// hexdump contents between pc and previous....
|
||||
ssize_t size = prevA6 - a6 - 8;
|
||||
hexdump(Flags.memory + a6 + 8, size);
|
||||
|
||||
|
||||
|
||||
puts("------------");
|
||||
printf("a6: %08x\n", prevA6);
|
||||
printf("pc: %08x", pc);
|
||||
|
||||
// find the routine name...
|
||||
for (const auto &kv : SymbolTable)
|
||||
{
|
||||
const auto &name = kv.first;
|
||||
auto range = kv.second;
|
||||
|
||||
// range end may be 0
|
||||
if ((pc == range.first) || (pc >= range.first && pc < range.second))
|
||||
{
|
||||
uint32_t offset = pc - range.first;
|
||||
if (offset)
|
||||
printf(" %s+$%x", name.c_str(), offset);
|
||||
else
|
||||
printf(" %s", name.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
puts("");
|
||||
|
||||
a6 = prevA6;
|
||||
}
|
||||
}
|
||||
|
||||
void Dump(uint32_t start, int size)
|
||||
{
|
||||
// TODO -- if no address, use previous address.
|
||||
// TODO -- support range?
|
||||
|
||||
|
||||
if (size <= 0) return;
|
||||
|
||||
uint32_t end = start + size;
|
||||
|
||||
if (start >= Flags.memorySize) return;
|
||||
|
||||
end = std::min(end, Flags.memorySize);
|
||||
size = end - start;
|
||||
|
||||
hexdump(Flags.memory + start, size, start);
|
||||
}
|
||||
|
||||
|
||||
}
|
1315
bin/debugger.cpp
Normal file
1315
bin/debugger.cpp
Normal file
File diff suppressed because it is too large
Load Diff
156
bin/debugger.h
Normal file
156
bin/debugger.h
Normal file
|
@ -0,0 +1,156 @@
|
|||
#ifndef __debugger_h__
|
||||
#define __debugger_h__
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
// Debugger is a function in MacTypes.h
|
||||
namespace Debug {
|
||||
|
||||
|
||||
enum {
|
||||
cmdNull,
|
||||
cmdContinue,
|
||||
cmdStep,
|
||||
cmdRun,
|
||||
};
|
||||
|
||||
enum {
|
||||
// subtypes
|
||||
// ; commands
|
||||
kHexdump = 1,
|
||||
kInfo,
|
||||
kList,
|
||||
kBreak,
|
||||
kTBreak
|
||||
};
|
||||
|
||||
struct Command {
|
||||
bool valid;
|
||||
int action;
|
||||
uint32_t argc;
|
||||
uint32_t argv[10];
|
||||
};
|
||||
|
||||
struct Token {
|
||||
// constructor is not allowable because
|
||||
// this is a union in the parser.
|
||||
#if 0
|
||||
Token():
|
||||
intValue(0), stringValue(0), subtype(0)
|
||||
{}
|
||||
|
||||
Token(uint32_t i) :
|
||||
intValue(i), subtype(0)
|
||||
{}
|
||||
|
||||
Token(std::string *s, unsigned st = 0) :
|
||||
intValue(0), stringValue(s), subtype(st)
|
||||
{}
|
||||
#endif
|
||||
|
||||
static Token Make()
|
||||
{
|
||||
Token t = {0, 0, 0};
|
||||
return t;
|
||||
}
|
||||
|
||||
static Token Make(uint32_t i)
|
||||
{
|
||||
Token t = { i, 0, 0};
|
||||
return t;
|
||||
}
|
||||
|
||||
static Token Make(std::string *s, uint32_t st)
|
||||
{
|
||||
Token t = { 0, s, st};
|
||||
return t;
|
||||
}
|
||||
|
||||
uint32_t intValue;
|
||||
std::string *stringValue;
|
||||
unsigned subtype;
|
||||
|
||||
// unsigned range?
|
||||
// unsigned modifier?
|
||||
|
||||
|
||||
#if 0
|
||||
Token& operator=(uint32_t rhs)
|
||||
{
|
||||
intValue = rhs;
|
||||
stringValue = 0;
|
||||
subtype = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
operator uint32_t() const
|
||||
{
|
||||
return intValue;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool ParseLine(const char *iter, Command *command);
|
||||
|
||||
void LoadTrapFile(const std::string &path, std::map<std::string, uint16_t> &map);
|
||||
|
||||
uint32_t VariableGet(const std::string &);
|
||||
void VariableSet(const std::string &name, uint32_t value);
|
||||
|
||||
void Shell();
|
||||
void Help();
|
||||
|
||||
uint32_t ReadLong(uint32_t);
|
||||
uint16_t ReadWord(uint32_t);
|
||||
uint8_t ReadByte(uint32_t);
|
||||
|
||||
std::string ReadPString(uint32_t);
|
||||
std::string ReadCString(uint32_t);
|
||||
|
||||
void Print(uint32_t value);
|
||||
void PrintRegisters();
|
||||
|
||||
void PrintBackTrace();
|
||||
|
||||
void Info(uint32_t address);
|
||||
|
||||
void Dump(uint32_t address, int count = 256);
|
||||
void List(uint32_t address, int count = 20);
|
||||
void List(uint32_t pc, uint32_t endpc);
|
||||
|
||||
void SetARegister(unsigned reg, uint32_t value);
|
||||
void SetDRegister(unsigned reg, uint32_t value);
|
||||
void SetXRegister(unsigned reg, uint32_t value);
|
||||
|
||||
void ToolBreak(int32_t tool);
|
||||
void ToolBreak();
|
||||
|
||||
void Break(int32_t address);
|
||||
void Break();
|
||||
|
||||
void ReadBreak();
|
||||
void ReadBreak(int32_t address);
|
||||
|
||||
void WriteBreak();
|
||||
void WriteBreak(int32_t address);
|
||||
|
||||
void ReadWriteBreak();
|
||||
void ReadWriteBreak(int32_t address);
|
||||
|
||||
|
||||
void PrintError(uint32_t value);
|
||||
void PrintDate(uint32_t value);
|
||||
|
||||
void StackCrawl(void);
|
||||
|
||||
void ApplyTemplate(int32_t address, const std::string &name);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
17
bin/debugger_internal.cpp
Normal file
17
bin/debugger_internal.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "debugger_internal.h"
|
||||
|
||||
namespace Debug {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
Loader::DebugNameTable SymbolTable;
|
||||
|
||||
std::map<std::string, uint16_t> ErrorTable;
|
||||
std::map<std::string, uint16_t> GlobalTable;
|
||||
std::map<std::string, uint16_t> TrapTable;
|
||||
|
||||
std::unordered_multimap<uint16_t, std::string> ErrorTableInvert;
|
||||
std::unordered_map<uint32_t, std::string> SymbolTableInvert;
|
||||
|
||||
}
|
||||
}
|
28
bin/debugger_internal.h
Normal file
28
bin/debugger_internal.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef __debug_internal_h__
|
||||
#define __debug_internal_h__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <toolbox/loader.h>
|
||||
|
||||
namespace Debug {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
extern Loader::DebugNameTable SymbolTable;
|
||||
|
||||
extern std::map<std::string, uint16_t> ErrorTable;
|
||||
extern std::map<std::string, uint16_t> GlobalTable;
|
||||
extern std::map<std::string, uint16_t> TrapTable;
|
||||
|
||||
extern std::unordered_multimap<uint16_t, std::string> ErrorTableInvert;
|
||||
extern std::unordered_map<uint32_t, std::string> SymbolTableInvert;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
133
bin/disasm.cpp
133
bin/disasm.cpp
|
@ -1,6 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -10,7 +37,8 @@
|
|||
#include <cpu/fmem.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
|
||||
|
||||
#include <macos/traps.h>
|
||||
#include <macos/sysequ.h>
|
||||
|
||||
char strings[4][256];
|
||||
|
||||
|
@ -18,8 +46,6 @@ const uint8_t *Memory = NULL;
|
|||
uint32_t MemorySize = 0;
|
||||
|
||||
|
||||
extern "C" { const char *TrapName(uint16_t trap); }
|
||||
|
||||
void ToolBox(uint32_t pc, uint16_t trap)
|
||||
{
|
||||
const char *name;
|
||||
|
@ -56,20 +82,47 @@ void code0(uint32_t data_size)
|
|||
|
||||
offset = 16;
|
||||
|
||||
bool longA5 = false;
|
||||
while (offset < data_size)
|
||||
{
|
||||
uint16_t off = memoryReadWord(offset);
|
||||
uint16_t seg = -1;
|
||||
if (memoryReadWord(offset + 2) == 0x3F3C && memoryReadWord(offset + 6) == 0xA9F0)
|
||||
{
|
||||
uint16_t seg = memoryReadWord(offset + 4);
|
||||
|
||||
// pc +2 since the first byte is the offset, not code.
|
||||
printf("$%08X %04X : %04X\n", pc + 2, seg, off);
|
||||
if (longA5)
|
||||
{
|
||||
uint16_t segment = memoryReadWord(offset);
|
||||
uint32_t segOffset = memoryReadLong(offset + 4);
|
||||
|
||||
if (memoryReadWord(offset + 2) == 0xA9F0)
|
||||
{
|
||||
printf("$%08X %04X : %08X\n", pc + 2, segment, segOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("$%08X ???\n", pc + 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("$%08X ???\n", pc + 2);
|
||||
uint16_t data[4];
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
data[i] = memoryReadWord(offset + 2 * i);
|
||||
|
||||
if (data[1] == 0xffff)
|
||||
{
|
||||
longA5 = true;
|
||||
printf("--------\n");
|
||||
}
|
||||
else if (data[1] == 0x3F3C && data[3] == 0xA9F0)
|
||||
{
|
||||
uint16_t segOffset = data[0];
|
||||
uint16_t segment = data[2];
|
||||
|
||||
// pc +2 since the first byte is the offset, not code.
|
||||
printf("$%08X %04X : %04X\n", pc + 2, segment, segOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("$%08X ???\n", pc + 2);
|
||||
}
|
||||
}
|
||||
offset += 8;
|
||||
pc += 8;
|
||||
|
@ -78,6 +131,22 @@ void code0(uint32_t data_size)
|
|||
printf("\n\n");
|
||||
}
|
||||
|
||||
inline char *cc2(uint16_t value, char out[3])
|
||||
{
|
||||
uint8_t tmp;
|
||||
|
||||
tmp = (value >> 8) & 0xff;
|
||||
if (tmp & 0x80 || !isprint(tmp)) out[0] = '.';
|
||||
else out[0] = tmp;
|
||||
|
||||
tmp = (value >> 0) & 0xff;
|
||||
if (tmp & 0x80 || !isprint(tmp)) out[1] = '.';
|
||||
else out[1] = tmp;
|
||||
|
||||
out[2] = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
void disasm(const char *name, int segment, uint32_t data_size)
|
||||
{
|
||||
|
||||
|
@ -104,16 +173,29 @@ void disasm(const char *name, int segment, uint32_t data_size)
|
|||
|
||||
std::string s;
|
||||
s.reserve(len);
|
||||
pc += 1; // skip the length byte.
|
||||
for (unsigned i = 0; i < len; ++ i)
|
||||
{
|
||||
|
||||
s.push_back(memoryReadByte(pc + 1 + i));
|
||||
s.push_back(memoryReadByte(pc++));
|
||||
}
|
||||
|
||||
printf("%s\n\n", s.c_str());
|
||||
printf("%s\n", s.c_str());
|
||||
pc = (pc + 1) & ~0x01;
|
||||
// if next word is 0, skip as well.
|
||||
if (memoryReadWord(pc) == 0) pc += 2;
|
||||
|
||||
#if 0
|
||||
if (memoryReadWord(pc) == 0x0000) pc += 2;
|
||||
#else
|
||||
// treat the remainder as data until 4E56. [Link A6,#]
|
||||
while (pc < data_size)
|
||||
{
|
||||
char tmp[3];
|
||||
uint16_t data = memoryReadWord(pc);
|
||||
if (data == 0x4e56) break;
|
||||
printf("$%08X $%04X ; '%s'\n", pc, data, cc2(data, tmp));
|
||||
pc += 2;
|
||||
}
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
prevOP = 0;
|
||||
continue;
|
||||
|
@ -126,7 +208,7 @@ void disasm(const char *name, int segment, uint32_t data_size)
|
|||
|
||||
ToolBox(pc, op);
|
||||
pc += 2;
|
||||
prevOP = op;
|
||||
prevOP = op;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -198,9 +280,18 @@ int main(int argc, char **argv)
|
|||
}
|
||||
else
|
||||
{
|
||||
// 4-byte header for segment stuff.
|
||||
data += 4;
|
||||
size -= 4;
|
||||
// near model uses a $4-byte header.
|
||||
// far model uses a $28-byte header.
|
||||
if (data[0] == 0xff && data[1] == 0xff)
|
||||
{
|
||||
data += 0x28;
|
||||
size -= 0x28;
|
||||
}
|
||||
else
|
||||
{
|
||||
data += 0x04;
|
||||
size -= 0x04;
|
||||
}
|
||||
memorySetMemory(data, size);
|
||||
disasm(cname.c_str(), resID, size);
|
||||
}
|
||||
|
@ -214,4 +305,4 @@ int main(int argc, char **argv)
|
|||
CloseResFile(refNum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
98
bin/intern.cpp
Normal file
98
bin/intern.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include "intern.h"
|
||||
#include <unordered_map>
|
||||
#include <cstring>
|
||||
|
||||
namespace {
|
||||
|
||||
std::unordered_multimap<unsigned, std::string *> InternTable;
|
||||
|
||||
std::string EmptyString;
|
||||
|
||||
unsigned int DJBHash(const char* begin, size_t length)
|
||||
{
|
||||
unsigned int hash = 5381;
|
||||
|
||||
for(size_t i = 0; i < length; ++i)
|
||||
{
|
||||
hash = ((hash << 5) + hash) + (begin[i]);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Intern {
|
||||
|
||||
const std::string *String(std::string &&str)
|
||||
{
|
||||
size_t size = str.size();
|
||||
if (!size) return &EmptyString;
|
||||
|
||||
unsigned hash = DJBHash(str.data(), size);
|
||||
|
||||
auto range = InternTable.equal_range(hash);
|
||||
auto iter = range.first;
|
||||
auto endit = range.second;
|
||||
|
||||
for( ; iter != endit; ++iter)
|
||||
{
|
||||
// hash matches, make sure the string does.
|
||||
const std::string *s = iter->second;
|
||||
|
||||
if (s->size() == size && std::memcmp(s->data(), str.data(), size) == 0)
|
||||
return s;
|
||||
}
|
||||
|
||||
// insert it. I suppose this could throw, in which case a string would leak.
|
||||
std::string *s = new std::string(std::move(str));
|
||||
InternTable.emplace(std::make_pair(hash, s));
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::string *String(const char *begin, size_t size)
|
||||
{
|
||||
if (!size) return &EmptyString;
|
||||
|
||||
unsigned hash = DJBHash(begin, size);
|
||||
|
||||
auto range = InternTable.equal_range(hash);
|
||||
auto iter = range.first;
|
||||
auto endit = range.second;
|
||||
|
||||
for( ; iter != endit; ++iter)
|
||||
{
|
||||
// hash matches, make sure the string does.
|
||||
const std::string *s = iter->second;
|
||||
|
||||
if (s->size() == size && std::memcmp(s->data(), begin, size) == 0)
|
||||
return s;
|
||||
}
|
||||
|
||||
// insert it. I suppose this could throw, in which case a string would leak.
|
||||
std::string *s = new std::string(begin, size);
|
||||
InternTable.emplace(std::make_pair(hash, s));
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::string *String(const char *begin, const char *end)
|
||||
{
|
||||
return String(begin, end - begin);
|
||||
}
|
||||
|
||||
|
||||
const std::string *String(const char *cp)
|
||||
{
|
||||
if (!cp || !*cp) return &EmptyString;
|
||||
|
||||
return String(cp, strlen(cp));
|
||||
}
|
||||
|
||||
const std::string *String(const std::string &s)
|
||||
{
|
||||
return String(s.data(), s.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
14
bin/intern.h
Normal file
14
bin/intern.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef __intern_h__
|
||||
#define __intern_h__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Intern {
|
||||
const std::string *String(const std::string &s);
|
||||
const std::string *String(std::string &&s);
|
||||
const std::string *String(const char *);
|
||||
const std::string *String(const char *, size_t size);
|
||||
const std::string *String(const char *, const char *);
|
||||
};
|
||||
|
||||
#endif
|
326
bin/lexer.re.cpp
Normal file
326
bin/lexer.re.cpp
Normal file
|
@ -0,0 +1,326 @@
|
|||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "debugger.h"
|
||||
#include "parser.h"
|
||||
|
||||
// re2c -b -i
|
||||
|
||||
|
||||
//extern "C" {
|
||||
|
||||
void *ParseAlloc(void *(*mallocProc)(size_t));
|
||||
void ParseFree(void *p, void (*freeProc)(void*));
|
||||
void Parse(void *yyp, int yymajor, uint32_t yyminor, Debug::Command *command);
|
||||
void ParseTrace(FILE *TraceFILE, char *zTracePrompt);
|
||||
//}
|
||||
|
||||
// p / print expression
|
||||
// hd / hexdump expression [:expression]
|
||||
// stack ?
|
||||
// brk expression
|
||||
// tbrk expression
|
||||
namespace {
|
||||
int tox(char c)
|
||||
{
|
||||
c |= 0x20; // lowercase it.
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t scan10(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](uint32_t value, char c){
|
||||
return value * 10 + c - '0';
|
||||
});
|
||||
}
|
||||
|
||||
uint32_t scan16(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](uint32_t value, char c){
|
||||
return (value << 4) + tox(c);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace Debug {
|
||||
bool ParseLine(const char *iter, Command *command)
|
||||
{
|
||||
void *parser;
|
||||
|
||||
parser = ParseAlloc(malloc);
|
||||
|
||||
//ParseTrace(stdout, "--> ");
|
||||
command->action = cmdNull;
|
||||
for (;;)
|
||||
{
|
||||
const char *begin = iter;
|
||||
const char *marker;
|
||||
|
||||
/*!re2c
|
||||
re2c:define:YYCURSOR = iter;
|
||||
re2c:define:YYMARKER = marker;
|
||||
re2c:define:YYCTYPE = char;
|
||||
re2c:yyfill:enable = 0;
|
||||
|
||||
[ \t\f\r\n]+ {
|
||||
// white space
|
||||
continue;
|
||||
}
|
||||
|
||||
'>=' { Parse(parser, tkGTEQ, 0, command); continue; }
|
||||
'>>' { Parse(parser, tkGTGT, 0, command); continue; }
|
||||
'<=' { Parse(parser, tkLTEQ, 0, command); continue; }
|
||||
'<<' { Parse(parser, tkLTLT, 0, command); continue; }
|
||||
'!=' { Parse(parser, tkBANGEQ, 0, command); continue; }
|
||||
'==' { Parse(parser, tkEQEQ, 0, command); continue; }
|
||||
'||' { Parse(parser, tkPIPEPIPE, 0, command); continue; }
|
||||
'&&' { Parse(parser, tkAMPAMP, 0, command); continue; }
|
||||
|
||||
|
||||
'(' { Parse(parser, tkLPAREN, 0, command); continue; }
|
||||
')' { Parse(parser, tkRPAREN, 0, command); continue; }
|
||||
'=' { Parse(parser, tkEQ, 0, command); continue; }
|
||||
'+' { Parse(parser, tkPLUS, 0, command); continue; }
|
||||
'-' { Parse(parser, tkMINUS, 0, command); continue; }
|
||||
'*' { Parse(parser, tkSTAR, 0, command); continue; }
|
||||
'/' { Parse(parser, tkSLASH, 0, command); continue; }
|
||||
'%' { Parse(parser, tkPERCENT, 0, command); continue; }
|
||||
'~' { Parse(parser, tkTILDE, 0, command); continue; }
|
||||
'!' { Parse(parser, tkBANG, 0, command); continue; }
|
||||
'^' { Parse(parser, tkCARET, 0, command); continue; }
|
||||
'&' { Parse(parser, tkAMP, 0, command); continue; }
|
||||
'|' { Parse(parser, tkPIPE, 0, command); continue; }
|
||||
'<' { Parse(parser, tkLT, 0, command); continue; }
|
||||
'>' { Parse(parser, tkGT, 0, command); continue; }
|
||||
|
||||
':' { Parse(parser, tkCOLON, 0, command); continue; }
|
||||
'@' { Parse(parser, tkAT, 0, command); continue; }
|
||||
|
||||
[0-9]+ {
|
||||
// integer
|
||||
uint32_t data;
|
||||
|
||||
data = std::accumulate(begin, iter, 0,
|
||||
[](uint32_t value, char c){
|
||||
return (value * 10) + c - '0';
|
||||
});
|
||||
|
||||
Parse(parser, tkINTEGER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'$' [0-9A-Fa-f]+ {
|
||||
// hex number
|
||||
uint32_t data;
|
||||
|
||||
data = std::accumulate(begin + 1, iter, 0,
|
||||
[](uint32_t value, char c){
|
||||
return (value << 4) + tox(c);
|
||||
}
|
||||
);
|
||||
Parse(parser, tkINTEGER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'0x' [0-9A-Fa-f]+ {
|
||||
// hex number
|
||||
uint32_t data;
|
||||
|
||||
data = std::accumulate(begin + 2, iter, 0,
|
||||
[](uint32_t value, char c){
|
||||
return (value << 4) + tox(c);
|
||||
}
|
||||
);
|
||||
Parse(parser, tkINTEGER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
['] [^']{1,4} ['] {
|
||||
// 4 cc code
|
||||
uint32_t data;
|
||||
|
||||
data = std::accumulate(begin + 1, iter - 1, 0,
|
||||
[](uint32_t value, char c)
|
||||
{
|
||||
return (value << 8) + (unsigned)c;
|
||||
}
|
||||
);
|
||||
Parse(parser, tkINTEGER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
'd' [0-7] {
|
||||
// data register
|
||||
uint32_t data = begin[1] - '0';
|
||||
Parse(parser, tkDREGISTER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'a' [0-7] {
|
||||
// address register
|
||||
uint32_t data = begin[1] - '0';
|
||||
Parse(parser, tkAREGISTER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'pc' {
|
||||
// program counter...
|
||||
Parse(parser, tkXREGISTER, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'csr' {
|
||||
// condition status register.
|
||||
Parse(parser, tkXREGISTER, 1, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'sp' {
|
||||
// stack pointer aka a7
|
||||
Parse(parser, tkAREGISTER, 7, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'fp' {
|
||||
// frame pointer aka a6
|
||||
Parse(parser, tkAREGISTER, 6, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
'c' | 'continue' {
|
||||
Parse(parser, tkCONTINUE, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'hd' | 'dump' {
|
||||
Parse(parser, tkDUMP, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'h' | 'help' {
|
||||
Parse(parser, tkHELP, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'l' | 'list' {
|
||||
Parse(parser, tkLIST, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'n' | 'next' {
|
||||
Parse(parser, tkNEXT, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
's' | 'step' {
|
||||
Parse(parser, tkNEXT, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'b' | 'brk' | 'break' {
|
||||
Parse(parser, tkBREAK, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'tbrk' | 'tbreak' | 'toolbreak' {
|
||||
Parse(parser, tkTBREAK, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'mbrk' | 'mbreak' | 'rwbrk' | 'rwbreak' {
|
||||
Parse(parser, tkRWBREAK, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'rbrk' | 'rbreak' {
|
||||
Parse(parser, tkRBREAK, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'wbrk' | 'wbreak' {
|
||||
Parse(parser, tkWBREAK, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
'g' | 'go' {
|
||||
Parse(parser, tkCONTINUE, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'p' | 'print' {
|
||||
Parse(parser, tkPRINT, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'r' | 'run' {
|
||||
Parse(parser, tkCONTINUE, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
';h' | ';hd' | ';hexdump' {
|
||||
Parse(parser, tkSEMIH, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
';i' | ';info' {
|
||||
Parse(parser, tkSEMII, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
';l' | ';list' {
|
||||
Parse(parser, tkSEMIL, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[_A-Za-z][_A-Za-z0-9] + {
|
||||
// identifier. lookup global address, tool number, etc.
|
||||
fprintf(stderr, "illegal identifier: `%.*s`\n", (int)(iter - begin), begin);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
[\x00] {
|
||||
// eol.
|
||||
Parse(parser, tkEOL, 0, command);
|
||||
break;
|
||||
}
|
||||
|
||||
[^] {
|
||||
fprintf(stderr, "illegal character: `%c`\n", *begin);
|
||||
ParseFree(parser, free);
|
||||
return false;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
Parse(parser, 0, 0, command);
|
||||
ParseFree(parser, free);
|
||||
|
||||
if (!command->valid)
|
||||
fprintf(stderr,"I don't understand.\n");
|
||||
|
||||
return command->valid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Debugger
|
435
bin/lexer.rl
Normal file
435
bin/lexer.rl
Normal file
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "debugger.h"
|
||||
#include "parser.h"
|
||||
|
||||
|
||||
void *ParseAlloc(void *(*mallocProc)(size_t));
|
||||
void ParseFree(void *p, void (*freeProc)(void*));
|
||||
void Parse(void *yyp, int yymajor, Debug::Token yyminor, Debug::Command *command);
|
||||
void ParseTrace(FILE *TraceFILE, char *zTracePrompt);
|
||||
|
||||
|
||||
// for the common case....
|
||||
void Parse(void *yyp, int yymajor, uint32_t yyminor, Debug::Command *command)
|
||||
{
|
||||
Parse(yyp, yymajor, Debug::Token::Make(yyminor), command);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
int tox(char c)
|
||||
{
|
||||
c |= 0x20; // lowercase it.
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t scan10(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](uint32_t value, char c){
|
||||
return value * 10 + c - '0';
|
||||
});
|
||||
}
|
||||
|
||||
uint32_t scan16(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](uint32_t value, char c){
|
||||
return (value << 4) + tox(c);
|
||||
});
|
||||
}
|
||||
|
||||
uint32_t scan2(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](uint32_t value, char c){
|
||||
return (value << 1) + (c & 0x01);
|
||||
});
|
||||
}
|
||||
|
||||
uint32_t scancc(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](uint32_t value, char c)
|
||||
{
|
||||
return (value << 8) + (unsigned)c;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
%%{
|
||||
machine lexer;
|
||||
|
||||
# this exits with cs == lexer_en_error.
|
||||
error := any* ${ fbreak; };
|
||||
|
||||
# identifiers.
|
||||
ident := |*
|
||||
|
||||
[ \t\r\n]+;
|
||||
|
||||
[_A-Za-z][_A-Za-z0-9]* {
|
||||
|
||||
std::unique_ptr<std::string> sp(new std::string(ts, te));
|
||||
|
||||
Parse(parser, tkIDENTIFIER, Token::Make(sp.get(), 0), command);
|
||||
Strings.push_back(std::move(sp));
|
||||
};
|
||||
|
||||
*|;
|
||||
|
||||
# semi-colon commands.
|
||||
semi := |*
|
||||
|
||||
[ \t\r\n]+;
|
||||
|
||||
'h'i | 'hd'i | 'hexdump'i {
|
||||
Parse(parser, tkSEMIH, 0, command);
|
||||
};
|
||||
|
||||
'i'i | 'info'i {
|
||||
Parse(parser, tkSEMII, 0, command);
|
||||
};
|
||||
|
||||
'l'i | 'list'i {
|
||||
Parse(parser, tkSEMIL, 0, command);
|
||||
};
|
||||
|
||||
'date'i {
|
||||
Parse(parser, tkSEMIDATE, 0, command);
|
||||
};
|
||||
|
||||
'error'i {
|
||||
Parse(parser, tkSEMIERROR, 0, command);
|
||||
};
|
||||
|
||||
't'i {
|
||||
Parse(parser, tkSEMIT, 0, command);
|
||||
fgoto ident;
|
||||
};
|
||||
|
||||
|
||||
*|;
|
||||
|
||||
main := |*
|
||||
|
||||
[ \t\r\n]+;
|
||||
|
||||
'>=' { Parse(parser, tkGTEQ, 0, command); };
|
||||
'>>' { Parse(parser, tkGTGT, 0, command); };
|
||||
'<=' { Parse(parser, tkLTEQ, 0, command); };
|
||||
'<<' { Parse(parser, tkLTLT, 0, command); };
|
||||
'!=' { Parse(parser, tkBANGEQ, 0, command); };
|
||||
'==' { Parse(parser, tkEQEQ, 0, command); };
|
||||
'||' { Parse(parser, tkPIPEPIPE, 0, command); };
|
||||
'&&' { Parse(parser, tkAMPAMP, 0, command); };
|
||||
|
||||
|
||||
'(' { Parse(parser, tkLPAREN, 0, command); };
|
||||
')' { Parse(parser, tkRPAREN, 0, command); };
|
||||
'=' { Parse(parser, tkEQ, 0, command); };
|
||||
'+' { Parse(parser, tkPLUS, 0, command); };
|
||||
'-' { Parse(parser, tkMINUS, 0, command); };
|
||||
'*' { Parse(parser, tkSTAR, 0, command); };
|
||||
'/' { Parse(parser, tkSLASH, 0, command); };
|
||||
'%' { Parse(parser, tkPERCENT, 0, command); };
|
||||
'~' { Parse(parser, tkTILDE, 0, command); };
|
||||
'!' { Parse(parser, tkBANG, 0, command); };
|
||||
'^' { Parse(parser, tkCARET, 0, command); };
|
||||
'&' { Parse(parser, tkAMP, 0, command); };
|
||||
'|' { Parse(parser, tkPIPE, 0, command); };
|
||||
'<' { Parse(parser, tkLT, 0, command); };
|
||||
'>' { Parse(parser, tkGT, 0, command); };
|
||||
|
||||
':' { Parse(parser, tkCOLON, 0, command); };
|
||||
|
||||
'@' { Parse(parser, tkAT, 0, command); };
|
||||
|
||||
';' {
|
||||
Parse(parser, tkSEMI, 0, command);
|
||||
fgoto semi;
|
||||
};
|
||||
|
||||
|
||||
'$' xdigit + {
|
||||
uint32_t value = scan16(ts + 1, te);
|
||||
Parse(parser, tkINTEGER, value, command);
|
||||
};
|
||||
|
||||
'0x'i xdigit+ {
|
||||
// hexadecimal
|
||||
uint32_t value = scan16(ts + 2, te);
|
||||
Parse(parser, tkINTEGER, value, command);
|
||||
};
|
||||
|
||||
'0b'i [01]+ {
|
||||
// binary
|
||||
uint32_t value = scan2(ts + 2, te);
|
||||
Parse(parser, tkINTEGER, value, command);
|
||||
};
|
||||
|
||||
digit+ {
|
||||
uint32_t value = scan10(ts, te);
|
||||
Parse(parser, tkINTEGER, value, command);
|
||||
};
|
||||
|
||||
# todo -- (\['\]|[^'\]){1,4} ?
|
||||
['] [^']{1,4} ['] {
|
||||
// 4 cc code
|
||||
|
||||
uint32_t value = scancc(ts + 1, te - 1);
|
||||
Parse(parser, tkINTEGER, value, command);
|
||||
|
||||
};
|
||||
|
||||
'd'i [0-7] {
|
||||
// data register
|
||||
uint32_t data = ts[1] - '0';
|
||||
Parse(parser, tkDREGISTER, data, command);
|
||||
};
|
||||
|
||||
'a'i [0-7] {
|
||||
// address register
|
||||
uint32_t data = ts[1] - '0';
|
||||
Parse(parser, tkAREGISTER, data, command);
|
||||
};
|
||||
|
||||
'pc'i {
|
||||
// program counter...
|
||||
Parse(parser, tkXREGISTER, 0, command);
|
||||
};
|
||||
|
||||
'csr'i {
|
||||
// condition status register.
|
||||
Parse(parser, tkXREGISTER, 1, command);
|
||||
};
|
||||
|
||||
'sp'i {
|
||||
// stack pointer aka a7
|
||||
Parse(parser, tkAREGISTER, 7, command);
|
||||
};
|
||||
|
||||
'fp'i {
|
||||
// frame pointer aka a6
|
||||
Parse(parser, tkAREGISTER, 6, command);
|
||||
};
|
||||
|
||||
# commands...
|
||||
|
||||
'bt'i | 'backtrace'i {
|
||||
Parse(parser, tkBACKTRACE, 0, command);
|
||||
};
|
||||
|
||||
'c'i | 'continue'i {
|
||||
Parse(parser, tkCONTINUE, 0, command);
|
||||
};
|
||||
|
||||
'hd'i | 'dump'i {
|
||||
Parse(parser, tkDUMP, 0, command);
|
||||
};
|
||||
|
||||
|
||||
'sc'i | 'stackcrawl'i {
|
||||
Parse(parser, tkSTACKCRAWL, 0, command);
|
||||
};
|
||||
|
||||
|
||||
'h'i | 'help'i {
|
||||
Parse(parser, tkHELP, 0, command);
|
||||
};
|
||||
|
||||
'l'i | 'list'i {
|
||||
Parse(parser, tkLIST, 0, command);
|
||||
};
|
||||
|
||||
'n'i | 'next'i {
|
||||
Parse(parser, tkNEXT, 0, command);
|
||||
};
|
||||
|
||||
's'i | 'step'i {
|
||||
Parse(parser, tkNEXT, 0, command);
|
||||
};
|
||||
|
||||
'b'i | 'brk'i | 'break'i {
|
||||
Parse(parser, tkBREAK, 0, command);
|
||||
};
|
||||
|
||||
'tbrk'i | 'tbreak'i | 'toolbreak'i {
|
||||
Parse(parser, tkTBREAK, 0, command);
|
||||
};
|
||||
|
||||
'mbrk'i | 'mbreak'i | 'rwbrk'i | 'rwbreak'i {
|
||||
Parse(parser, tkRWBREAK, 0, command);
|
||||
};
|
||||
|
||||
'rbrk'i | 'rbreak'i {
|
||||
Parse(parser, tkRBREAK, 0, command);
|
||||
};
|
||||
|
||||
'wbrk'i | 'wbreak'i {
|
||||
Parse(parser, tkWBREAK, 0, command);
|
||||
};
|
||||
|
||||
|
||||
'g'i | 'go'i {
|
||||
Parse(parser, tkCONTINUE, 0, command);
|
||||
};
|
||||
|
||||
'p'i | 'print'i {
|
||||
Parse(parser, tkPRINT, 0, command);
|
||||
};
|
||||
|
||||
'r'i | 'run'i {
|
||||
Parse(parser, tkCONTINUE, 0, command);
|
||||
};
|
||||
|
||||
|
||||
# generic identifier
|
||||
# since % is a valid character, should drop %/modulo operator.
|
||||
[%_A-Za-z][%_.A-Za-z0-9]* {
|
||||
|
||||
std::unique_ptr<std::string> sp(new std::string(ts, te));
|
||||
|
||||
Parse(parser, tkIDENTIFIER, Token::Make(sp.get(), 0), command);
|
||||
Strings.push_back(std::move(sp));
|
||||
};
|
||||
|
||||
|
||||
# end of the line...
|
||||
#0 {
|
||||
# Parse(parser, tkEOL, 0, command);
|
||||
#};
|
||||
|
||||
#any {
|
||||
# fprintf(stderr, "illegal character: `%c`\n", *ts);
|
||||
# fbreak;
|
||||
#};
|
||||
|
||||
|
||||
*|;
|
||||
}%%
|
||||
|
||||
namespace Debug {
|
||||
|
||||
bool ParseLine(const char *iter, Command *command)
|
||||
{
|
||||
%% write data;
|
||||
|
||||
void *parser;
|
||||
|
||||
// string table to avoid memory leaks in parser.
|
||||
std::deque<std::unique_ptr<std::string>> Strings;
|
||||
|
||||
|
||||
parser = ParseAlloc(malloc);
|
||||
|
||||
//ParseTrace(stdout, "--> ");
|
||||
command->action = cmdNull;
|
||||
|
||||
int length = std::strlen(iter);
|
||||
const char *p = iter;
|
||||
const char *pe = iter + length;
|
||||
const char *eof = pe;
|
||||
const char *ts;
|
||||
const char *te;
|
||||
int cs, act;
|
||||
|
||||
%% write init;
|
||||
|
||||
|
||||
%% write exec;
|
||||
|
||||
if (cs == lexer_error || cs < lexer_first_final)
|
||||
{
|
||||
if (p == eof)
|
||||
{
|
||||
fprintf(stderr, "Unexpected end of line\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0, l = 2 + (p - iter); i < l; ++i)
|
||||
fputc(' ', stderr);
|
||||
|
||||
fprintf(stderr, "^\nunexpected character: `%c'\n", *p);
|
||||
|
||||
}
|
||||
|
||||
ParseFree(parser, free);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
if (cs == lexer_en_error)
|
||||
{
|
||||
ParseFree(parser, free);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cs < lexer_first_final)
|
||||
{
|
||||
fprintf(stderr, "Incomplete command\n");
|
||||
ParseFree(parser, free);
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
if (p == pe)
|
||||
{
|
||||
// always true?
|
||||
Parse(parser, tkEOL, 0, command);
|
||||
}
|
||||
|
||||
Parse(parser, 0, 0, command);
|
||||
ParseFree(parser, free);
|
||||
|
||||
if (!command->valid)
|
||||
fprintf(stderr,"I don't understand.\n");
|
||||
|
||||
return command->valid;
|
||||
|
||||
}
|
||||
|
||||
} // namespace
|
636
bin/loader.cpp
636
bin/loader.cpp
|
@ -1,6 +1,32 @@
|
|||
// clang++ -c -std=c++11 -stdlib=libc++ -Wno-deprecated-declarations loader.cpp
|
||||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -20,55 +46,31 @@
|
|||
|
||||
#include <toolbox/toolbox.h>
|
||||
#include <toolbox/mm.h>
|
||||
#include <toolbox/os.h>
|
||||
#include <toolbox/loader.h>
|
||||
|
||||
#include <mpw/mpw.h>
|
||||
|
||||
#include <mplite/mplite.h>
|
||||
|
||||
#include <macos/sysequ.h>
|
||||
#include <macos/traps.h>
|
||||
|
||||
struct {
|
||||
uint32_t ram;
|
||||
uint32_t stack;
|
||||
uint32_t machine;
|
||||
#include "loader.h"
|
||||
#include "debugger.h"
|
||||
|
||||
bool traceCPU;
|
||||
bool traceMacsbug;
|
||||
bool traceGlobals;
|
||||
bool traceToolBox;
|
||||
bool traceMPW;
|
||||
#include <cxx/string_splitter.h>
|
||||
|
||||
bool memoryStats;
|
||||
|
||||
} Flags = { 16 * 1024 * 1024, 8 * 1024, 68030, false, false, false, false, false, false};
|
||||
#define LOADER_LOAD
|
||||
|
||||
Settings Flags;
|
||||
|
||||
const uint32_t kGlobalSize = 0x10000;
|
||||
// retained to make debugging easier.
|
||||
uint8_t *Memory = nullptr;
|
||||
uint32_t MemorySize = 0;
|
||||
|
||||
#if 0
|
||||
uint32_t EmulatedNewPtr(uint32_t size)
|
||||
{
|
||||
if (size & 0x01) size++;
|
||||
|
||||
if (HighWater + size > MemorySize)
|
||||
{
|
||||
fprintf(stderr, "Insufficient Memory!\n");
|
||||
exit(EX_CONFIG);
|
||||
}
|
||||
|
||||
|
||||
uint32_t address = HighWater;
|
||||
|
||||
|
||||
HighWater += size;
|
||||
|
||||
std::memset(Memory + HighWater, 0, size);
|
||||
|
||||
return address;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t ReadByte(const void *data, uint32_t offset)
|
||||
{
|
||||
|
@ -112,6 +114,69 @@ void WriteLong(void *data, uint32_t offset, uint32_t value)
|
|||
((uint8_t *)data)[offset++] = value;
|
||||
}
|
||||
|
||||
#ifndef LOADER_LOAD
|
||||
void reloc1(const uint8_t *r, uint32_t address, uint32_t offset)
|
||||
{
|
||||
// %00000000 00000000 -> break
|
||||
// %0xxxxxxx -> 7-bit value
|
||||
// %1xxxxxxx xxxxxxxx -> 15-bit value
|
||||
// %00000000 1xxxxxxx x{8} x{8} x{8} -> 31 bit value
|
||||
// ^ that's what the documentation says..
|
||||
// that's how the 32-bit bootstrap works
|
||||
// DumpCode ignores the high 2 bytes.
|
||||
for(;;)
|
||||
{
|
||||
uint32_t x;
|
||||
uint32_t value;
|
||||
|
||||
x = *r++;
|
||||
|
||||
if (x == 0x00)
|
||||
{
|
||||
x = *r++;
|
||||
if (x == 0x00) break;
|
||||
|
||||
x = (x << 8) | *r++;
|
||||
x = (x << 8) | *r++;
|
||||
x = (x << 8) | *r++;
|
||||
}
|
||||
else if (x & 0x80)
|
||||
{
|
||||
x &= 0x7f;
|
||||
x = (x << 8) | *r++;
|
||||
}
|
||||
|
||||
x <<= 1; // * 2
|
||||
|
||||
address += x;
|
||||
|
||||
value = memoryReadLong(address);
|
||||
memoryWriteLong(value + offset, address);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// relocate a far model segment.
|
||||
void relocate(uint32_t address, uint32_t size, uint32_t a5)
|
||||
{
|
||||
// see MacOS RT Architecture, 10-23 .. 10-26
|
||||
uint32_t offset;
|
||||
|
||||
offset = memoryReadLong(address + 0x14);
|
||||
if (memoryReadLong(address + 0x18) != a5 && offset != 0)
|
||||
{
|
||||
memoryWriteLong(a5, address + 0x18); // current value of A5
|
||||
reloc1(memoryPointer(address + offset), address, a5);
|
||||
}
|
||||
|
||||
offset = memoryReadLong(address + 0x1c);
|
||||
if (memoryReadLong(address + 0x20) != address && offset != 0)
|
||||
{
|
||||
memoryWriteLong(address, address + 0x20); // segment load address.
|
||||
reloc1(memoryPointer(address + offset), address, address + 0x28);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t load(const char *file)
|
||||
{
|
||||
|
||||
|
@ -120,7 +185,22 @@ uint32_t load(const char *file)
|
|||
|
||||
uint32_t returnAddress = 0;
|
||||
|
||||
std::vector< std::pair<uint32_t, uint32_t> > segments; // segment, address
|
||||
struct SegInfo {
|
||||
public:
|
||||
|
||||
SegInfo()
|
||||
{}
|
||||
|
||||
SegInfo(uint32_t a, uint32_t s, bool f) :
|
||||
address(a), size(s), farModel(f)
|
||||
{}
|
||||
|
||||
uint32_t address = 0;
|
||||
uint32_t size = 0;
|
||||
bool farModel = 0;
|
||||
|
||||
};
|
||||
std::vector< SegInfo> segments;
|
||||
|
||||
|
||||
uint32_t a5 = 0;
|
||||
|
@ -128,7 +208,11 @@ uint32_t load(const char *file)
|
|||
uint32_t jtStart = 0;
|
||||
uint32_t jtEnd = 0;
|
||||
|
||||
// todo -- call RM::Native to open and load the Resource File.
|
||||
|
||||
assert(FSPathMakeRef( (const UInt8 *)file, &ref, NULL) == noErr);
|
||||
// todo -- if it wasn't a resource file, this will fail
|
||||
// should provide a nicer error message.
|
||||
refNum = FSOpenResFile(&ref, fsRdPerm);
|
||||
assert(refNum != -1 );
|
||||
|
||||
|
@ -187,7 +271,7 @@ uint32_t load(const char *file)
|
|||
a5 = address + below;
|
||||
std::memcpy(memoryPointer(a5 + jtOffset), data + 16 , jtSize);
|
||||
|
||||
segments[resID] = std::make_pair(address, a5size);
|
||||
segments[resID] = SegInfo(address, a5size, false);
|
||||
|
||||
jtStart = a5 + jtOffset;
|
||||
jtEnd = jtStart + jtSize;
|
||||
|
@ -202,6 +286,9 @@ uint32_t load(const char *file)
|
|||
}
|
||||
else
|
||||
{
|
||||
bool farModel = false;
|
||||
if (data[0] == 0xff && data[1] == 0xff) farModel = true;
|
||||
|
||||
error = MM::Native::NewPtr(size, false, address);
|
||||
if (error)
|
||||
{
|
||||
|
@ -211,32 +298,56 @@ uint32_t load(const char *file)
|
|||
|
||||
std::memcpy(memoryPointer(address), data, size);
|
||||
|
||||
segments[resID] = std::make_pair(address, size);
|
||||
segments[resID] = SegInfo(address, size, farModel);
|
||||
}
|
||||
|
||||
ReleaseResource(h);
|
||||
}
|
||||
}
|
||||
|
||||
// now link the segment 0 jump table...
|
||||
assert(a5);
|
||||
|
||||
bool first = true;
|
||||
bool farModel = false;
|
||||
for (; jtStart < jtEnd; jtStart += 8)
|
||||
{
|
||||
uint16_t offset = memoryReadWord(jtStart);
|
||||
uint16_t seg = memoryReadWord(jtStart + 4);
|
||||
uint16_t seg;
|
||||
uint32_t offset;
|
||||
if (farModel)
|
||||
{
|
||||
seg = memoryReadWord(jtStart + 0);
|
||||
offset = memoryReadLong(jtStart + 4);
|
||||
|
||||
assert(memoryReadWord(jtStart + 2) == 0x3F3C);
|
||||
assert(memoryReadWord(jtStart + 6) == 0xA9F0);
|
||||
assert(memoryReadWord(jtStart + 2) == 0xA9F0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t farModelCheck;
|
||||
offset = memoryReadWord(jtStart);
|
||||
farModelCheck = memoryReadWord(jtStart + 2);
|
||||
seg = memoryReadWord(jtStart + 4);
|
||||
|
||||
assert(seg < segments.size());
|
||||
if (farModelCheck == 0xffff)
|
||||
{
|
||||
farModel = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(memoryReadWord(jtStart + 2) == 0x3F3C);
|
||||
assert(memoryReadWord(jtStart + 6) == 0xA9F0);
|
||||
}
|
||||
|
||||
assert(seg < segments.size());
|
||||
|
||||
auto p = segments[seg];
|
||||
assert(p.first); // missing segment?!
|
||||
assert(offset < p.second);
|
||||
//assert(p.first); // missing segment?!
|
||||
//assert(offset < p.second);
|
||||
|
||||
// +4 for the jump table info header.
|
||||
uint32_t address = p.first + offset + 4;
|
||||
assert(p.address); // missing segment?!
|
||||
assert(offset < p.size);
|
||||
|
||||
// +$4/$28 for the jump table info header.
|
||||
uint32_t address = p.address + offset + (p.farModel ? 0x00 : 0x04); // was 0x28
|
||||
|
||||
// JMP absolute long
|
||||
memoryWriteWord(0x4EF9, jtStart + 2);
|
||||
|
@ -250,11 +361,21 @@ uint32_t load(const char *file)
|
|||
}
|
||||
}
|
||||
|
||||
// far-model relocation. This happens here, after a5 is loaded.
|
||||
|
||||
for (const auto &seg : segments)
|
||||
{
|
||||
if (seg.farModel)
|
||||
{
|
||||
relocate(seg.address, seg.size, a5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// set pc to jump table entry 0.
|
||||
return returnAddress;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void GlobalInit()
|
||||
|
@ -272,16 +393,52 @@ void GlobalInit()
|
|||
memoryWriteLong(0xffffffff, MacOS::MinusOne);
|
||||
|
||||
|
||||
// todo -- expects high stack, low heap.
|
||||
// the allocator currently works from the top down,
|
||||
// so put stack at top of memory?
|
||||
|
||||
// 0x0130 -- ApplLimit
|
||||
memoryWriteLong(Flags.ram - 1, MacOS::ApplLimit);
|
||||
memoryWriteLong(Flags.memorySize - Flags.stackSize - 1, MacOS::ApplLimit);
|
||||
memoryWriteLong(kGlobalSize, MacOS::ApplZone);
|
||||
memoryWriteLong(Flags.memorySize - 1, MacOS::BufPtr);
|
||||
|
||||
//
|
||||
memoryWriteLong(Flags.stackRange.first, MacOS::CurStackBase);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CreateStack()
|
||||
{
|
||||
// allocate stack, set A7...
|
||||
|
||||
uint32_t address;
|
||||
//uint16_t error;
|
||||
|
||||
#if 0
|
||||
Flags.stackSize = (Flags.stackSize + 3) & ~0x03;
|
||||
|
||||
error = MM::Native::NewPtr(Flags.stackSize, true, address);
|
||||
if (error)
|
||||
{
|
||||
fprintf(stderr, "Unable to allocate stack (%08x bytes)\n", Flags.stackSize);
|
||||
exit(EX_CONFIG);
|
||||
}
|
||||
#else
|
||||
|
||||
address = Flags.memorySize - Flags.stackSize;
|
||||
|
||||
#endif
|
||||
|
||||
Flags.stackRange.first = address;
|
||||
Flags.stackRange.second = address + Flags.stackSize;
|
||||
|
||||
// TODO -- is there a global for the max (min) stack pointer?
|
||||
|
||||
// address grows down
|
||||
// -4 is for the return address.
|
||||
cpuSetAReg(7, Flags.stackRange.second - 4);
|
||||
// return address.
|
||||
memoryWriteLong(MacOS::MinusOne, Flags.stackRange.second - 4); // MinusOne Global -- 0xffff ffff
|
||||
}
|
||||
|
||||
|
||||
extern "C" { const char *TrapName(uint16_t trap); }
|
||||
|
||||
void LogToolBox(uint32_t pc, uint16_t trap)
|
||||
{
|
||||
|
@ -315,19 +472,6 @@ void InstructionLogger()
|
|||
}
|
||||
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "D: %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
cpuGetDReg(0), cpuGetDReg(1), cpuGetDReg(2), cpuGetDReg(3),
|
||||
cpuGetDReg(4), cpuGetDReg(5), cpuGetDReg(6), cpuGetDReg(7)
|
||||
|
||||
);
|
||||
|
||||
fprintf(stderr, "A: %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
cpuGetAReg(0), cpuGetAReg(1), cpuGetAReg(2), cpuGetAReg(3),
|
||||
cpuGetAReg(4), cpuGetAReg(5), cpuGetAReg(6), cpuGetAReg(7)
|
||||
);
|
||||
#endif
|
||||
|
||||
if (Flags.traceCPU)
|
||||
{
|
||||
cpuDisOpcode(pc, strings[0], strings[1], strings[2], strings[3]);
|
||||
|
@ -363,10 +507,13 @@ void InstructionLogger()
|
|||
// check for MacsBug name after rts.
|
||||
std::string s;
|
||||
unsigned b = memoryReadByte(pc);
|
||||
if (b > 0x80 && b < 0xa0)
|
||||
if (b >= 0x80 && b <= 0x9f)
|
||||
{
|
||||
b -= 0x80;
|
||||
pc++;
|
||||
|
||||
if (!b) b = memoryReadByte(pc++);
|
||||
|
||||
s.reserve(b);
|
||||
for (unsigned i = 0; i < b; ++i)
|
||||
{
|
||||
|
@ -378,7 +525,65 @@ void InstructionLogger()
|
|||
|
||||
}
|
||||
|
||||
#define MPW_VERSION "0.4"
|
||||
void MemoryLogger(uint32_t address, int size, int readWrite, uint32_t value)
|
||||
{
|
||||
if (address < kGlobalSize)
|
||||
{
|
||||
const char *name = GlobalName(address);
|
||||
if (!name) name = "unknown";
|
||||
|
||||
fprintf(stderr, "%-20s %08x - ", name, address);
|
||||
|
||||
if (!readWrite)
|
||||
{
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
value = ReadByte(Memory, address);
|
||||
break;
|
||||
case 2:
|
||||
value = ReadWord(Memory, address);
|
||||
break;
|
||||
case 4:
|
||||
value = ReadLong(Memory, address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// todo -- for write, display previous value?
|
||||
fprintf(stderr, " %s %d bytes", readWrite ? "write" : "read ", size);
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
fprintf(stderr, " [%02x]\n", value);
|
||||
break;
|
||||
case 2:
|
||||
fprintf(stderr, " [%04x]\n", value);
|
||||
break;
|
||||
case 3:
|
||||
fprintf(stderr, " [%06x]\n", value);
|
||||
break;
|
||||
case 4:
|
||||
fprintf(stderr, " [%08x]\n", value);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MidInstructionExceptionFunc()
|
||||
{
|
||||
// todo - cpu exception?
|
||||
fprintf(stderr, "Mid Instruction Exception!\n");
|
||||
//throw std::runtime_error::runtime_error("mid instruction exception");
|
||||
}
|
||||
|
||||
|
||||
#define MPW_VERSION "0.8.3"
|
||||
void help()
|
||||
{
|
||||
printf("MPW " MPW_VERSION "\n");
|
||||
|
@ -389,7 +594,7 @@ void help()
|
|||
printf(" --trace-macsbug print macsbug names\n");
|
||||
printf(" --trace-toolbox print toolbox calls\n");
|
||||
printf(" --trace-mpw print mpw calls\n");
|
||||
printf(" --memory stats print memory usage information\n");
|
||||
printf(" --memory-stats print memory usage information\n");
|
||||
printf(" --ram=<number> set the ram size. Default=16M\n");
|
||||
printf(" --stack=<number> set the stack size. Default=8K\n");
|
||||
printf("\n");
|
||||
|
@ -419,11 +624,11 @@ bool parse_number(const char *input, uint32_t *dest)
|
|||
if (*end)
|
||||
{
|
||||
int old = value;
|
||||
if (strcasecmp(end, "M") == 0)
|
||||
if (strcasecmp(end, "M") == 0 || strcasecmp(end, "MB") == 0)
|
||||
value *= 1024 * 1024;
|
||||
else if (strcasecmp(end, "K") == 0)
|
||||
else if (strcasecmp(end, "K") == 0 || strcasecmp(end, "KB") == 0)
|
||||
value *= 1024;
|
||||
else
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s - invalid input\n", input);
|
||||
return false;
|
||||
|
@ -447,7 +652,7 @@ bool file_exists(const std::string & name)
|
|||
return ::stat(name.c_str(), &st) == 0 && S_ISREG(st.st_mode);
|
||||
}
|
||||
|
||||
std::string find_exe(const std::string &name)
|
||||
std::string old_find_exe(const std::string &name)
|
||||
{
|
||||
if (file_exists(name)) return name;
|
||||
|
||||
|
@ -469,6 +674,103 @@ std::string find_exe(const std::string &name)
|
|||
}
|
||||
|
||||
|
||||
// this needs to run *after* the MPW environment variables are loaded.
|
||||
std::string find_exe(const std::string &name)
|
||||
{
|
||||
|
||||
// if this is an absolute or relative name, return as-is.
|
||||
|
||||
if (name.find(':') != name.npos) {
|
||||
std::string path = ToolBox::MacToUnix(name);
|
||||
if (file_exists(path)) return path;
|
||||
return "";
|
||||
}
|
||||
|
||||
if (name.find('/') != name.npos) {
|
||||
if (file_exists(name)) return name;
|
||||
return "";
|
||||
}
|
||||
|
||||
// otherwise, check the Commands variable for locations.
|
||||
std::string commands = MPW::GetEnv("Commands");
|
||||
if (commands.empty()) return old_find_exe(name);
|
||||
|
||||
|
||||
// string is , separated, possibly in MacOS format.
|
||||
|
||||
for (auto iter = string_splitter(commands, ','); iter; ++iter)
|
||||
{
|
||||
if (iter->empty()) continue;
|
||||
std::string path = *iter;
|
||||
|
||||
// convert to unix.
|
||||
path = ToolBox::MacToUnix(path);
|
||||
// should always have a length...
|
||||
if (path.length() && path.back() != '/') path.push_back('/');
|
||||
path.append(name);
|
||||
if (file_exists(path)) return path;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
void MainLoop()
|
||||
{
|
||||
#if 0
|
||||
auto begin_emu_time = std::chrono::high_resolution_clock::now();
|
||||
fprintf(stderr, "Begin Emulation Time: %20lld\n", (begin_emu_time - start_time).count());
|
||||
#endif
|
||||
|
||||
|
||||
uint64_t cycles = 0;
|
||||
for (;;)
|
||||
{
|
||||
uint32_t pc = cpuGetPC();
|
||||
uint32_t sp = cpuGetAReg(7);
|
||||
|
||||
if (pc == 0x00000000)
|
||||
{
|
||||
fprintf(stderr, "Exiting - PC = 0\n");
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
if (sp < Flags.stackRange.first)
|
||||
{
|
||||
fprintf(stderr, "Stack overflow error - please increase the stack size (--stack=size)\n");
|
||||
fprintf(stderr, "Current stack size is 0x%06x\n", Flags.stackSize);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
if (sp > Flags.stackRange.second)
|
||||
{
|
||||
fprintf(stderr, "Stack underflow error\n");
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
|
||||
if (cpuGetStop()) break; // will this also be set by an interrupt?
|
||||
|
||||
|
||||
#ifndef CPU_INSTRUCTION_LOGGING
|
||||
if (Flags.traceCPU || Flags.traceMacsbug)
|
||||
{
|
||||
InstructionLogger();
|
||||
}
|
||||
#endif
|
||||
|
||||
cycles += cpuExecuteInstruction();
|
||||
}
|
||||
|
||||
#if 0
|
||||
auto end_emu_time = std::chrono::high_resolution_clock::now();
|
||||
fprintf(stderr, " End Emulation Time: %20lld\n", (end_emu_time - start_time).count());
|
||||
fprintf(stderr, " Cycles: %20lld\n", cycles);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// getopt...
|
||||
|
@ -480,9 +782,11 @@ int main(int argc, char **argv)
|
|||
kTraceGlobals,
|
||||
kTraceToolBox,
|
||||
kTraceMPW,
|
||||
kDebugger,
|
||||
kMemoryStats,
|
||||
kShell,
|
||||
};
|
||||
static struct option LongOpts[] =
|
||||
static struct option LongOpts[] =
|
||||
{
|
||||
{ "ram",required_argument, NULL, 'r' },
|
||||
{ "stack", required_argument, NULL, 's' },
|
||||
|
@ -494,17 +798,23 @@ int main(int argc, char **argv)
|
|||
{ "trace-tools", no_argument, NULL, kTraceToolBox },
|
||||
{ "trace-mpw", no_argument, NULL, kTraceMPW },
|
||||
|
||||
{ "debug", no_argument, NULL, kDebugger },
|
||||
{ "debugger", no_argument, NULL, kDebugger },
|
||||
|
||||
{ "memory-stats", no_argument, NULL, kMemoryStats },
|
||||
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "shell", no_argument, NULL, kShell },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
//auto start_time = std::chrono::high_resolution_clock::now();
|
||||
|
||||
std::vector<std::string> defines;
|
||||
|
||||
int c;
|
||||
while ((c = getopt_long(argc, argv, "+hVm:r:s:", LongOpts, NULL)) != -1)
|
||||
while ((c = getopt_long(argc, argv, "+hVm:r:s:D:", LongOpts, NULL)) != -1)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
|
@ -527,26 +837,37 @@ int main(int argc, char **argv)
|
|||
case kTraceMPW:
|
||||
Flags.traceMPW = true;
|
||||
break;
|
||||
|
||||
|
||||
case kMemoryStats:
|
||||
Flags.memoryStats = true;
|
||||
break;
|
||||
|
||||
case kDebugger:
|
||||
Flags.debugger = true;
|
||||
break;
|
||||
|
||||
case kShell:
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (!parse_number(optarg, &Flags.machine))
|
||||
exit(EX_CONFIG);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (!parse_number(optarg, &Flags.ram))
|
||||
if (!parse_number(optarg, &Flags.memorySize))
|
||||
exit(EX_CONFIG);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (!parse_number(optarg, &Flags.stack))
|
||||
if (!parse_number(optarg, &Flags.stackSize))
|
||||
exit(EX_CONFIG);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
defines.push_back(optarg);
|
||||
break;
|
||||
|
||||
case ':':
|
||||
case '?':
|
||||
help();
|
||||
|
@ -575,92 +896,97 @@ int main(int argc, char **argv)
|
|||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
std::string command(argv[0]); // InitMPW updates argv...
|
||||
Flags.stackSize = (Flags.stackSize + 0xff) & ~0xff;
|
||||
Flags.memorySize = (Flags.memorySize + 0xff) & ~0xff;
|
||||
|
||||
if (Flags.stackSize < 0x100)
|
||||
{
|
||||
fprintf(stderr, "Invalid stack size\n");
|
||||
exit(EX_CONFIG);
|
||||
}
|
||||
|
||||
if (Flags.memorySize < 0x200)
|
||||
{
|
||||
fprintf(stderr, "Invalid ram size\n");
|
||||
exit(EX_CONFIG);
|
||||
}
|
||||
|
||||
if (Flags.stackSize >= Flags.memorySize)
|
||||
{
|
||||
fprintf(stderr, "Invalid stack/ram size\n");
|
||||
exit(EX_CONFIG);
|
||||
}
|
||||
|
||||
|
||||
|
||||
MPW::InitEnvironment(defines);
|
||||
|
||||
std::string command(argv[0]); // InitMPW updates argv...
|
||||
command = find_exe(command);
|
||||
if (command.empty())
|
||||
{
|
||||
const char *mpw = getenv("MPW");
|
||||
std::string mpw = MPW::RootDir();
|
||||
fprintf(stderr, "Unable to find command %s\n", argv[0]);
|
||||
fprintf(stderr, "$MPW = %s\n", mpw ? mpw : "<null>");
|
||||
fprintf(stderr, "$MPW = %s\n", mpw.c_str());
|
||||
fprintf(stderr, "$Commands = %s\n", MPW::GetEnv("Commands").c_str());
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
argv[0] = ::strdup(command.c_str()); // hmm.. could setenv(mpw_command) instead.
|
||||
|
||||
|
||||
|
||||
Memory = new uint8_t[Flags.ram];
|
||||
MemorySize = Flags.ram;
|
||||
// move to CreateRam()
|
||||
Memory = Flags.memory = new uint8_t[Flags.memorySize];
|
||||
MemorySize = Flags.memorySize;
|
||||
|
||||
|
||||
/// ahhh... need to set PC after memory.
|
||||
// for pre-fetch.
|
||||
memorySetMemory(Memory, MemorySize);
|
||||
|
||||
// should we subtract memory from the top
|
||||
// for the stack vs allocating it?
|
||||
|
||||
MM::Init(Memory, MemorySize, kGlobalSize);
|
||||
|
||||
MM::Init(Memory, MemorySize, kGlobalSize, Flags.stackSize);
|
||||
OS::Init();
|
||||
ToolBox::Init();
|
||||
MPW::Init(argc, argv);
|
||||
|
||||
|
||||
cpuStartup();
|
||||
cpuSetModel(3,0);
|
||||
|
||||
CreateStack();
|
||||
|
||||
|
||||
if (!Flags.stack)
|
||||
{
|
||||
fprintf(stderr, "Invalid stack size\n");
|
||||
exit(EX_CONFIG);
|
||||
#ifdef LOADER_LOAD
|
||||
uint16_t err = Loader::Native::LoadFile(command);
|
||||
if (err) {
|
||||
const char *cp = ErrorName(err);
|
||||
fprintf(stderr, "Unable to load command %s: ", command.c_str());
|
||||
if (cp) printf("%s\n", cp);
|
||||
else printf("%hd\n", err);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
std::pair<uint32_t, uint32_t> StackRange;
|
||||
// allocate stack, set A7...
|
||||
{
|
||||
uint32_t address;
|
||||
uint16_t error;
|
||||
|
||||
Flags.stack = (Flags.stack + 3) & ~0x03;
|
||||
|
||||
error = MM::Native::NewPtr(Flags.stack, true, address);
|
||||
if (error)
|
||||
{
|
||||
fprintf(stderr, "Unable to allocate stack (%08x bytes)\n", Flags.stack);
|
||||
exit(EX_CONFIG);
|
||||
}
|
||||
|
||||
StackRange.first = address;
|
||||
StackRange.second = address + Flags.stack;
|
||||
|
||||
// TODO -- is there a global for the max (min) stack pointer?
|
||||
|
||||
// address grows down
|
||||
// -4 is for the return address.
|
||||
cpuSetAReg(7, address + Flags.stack - 4);
|
||||
// return address.
|
||||
memoryWriteLong(MacOS::MinusOne, StackRange.second - 4); // MinusOne Global -- 0xffff ffff
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
uint32_t address = load(command.c_str());
|
||||
if (!address) exit(EX_CONFIG);
|
||||
|
||||
if (!address) {
|
||||
fprintf(stderr, "Unable to load command %s\n", command.c_str());
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
#endif
|
||||
GlobalInit();
|
||||
|
||||
|
||||
cpuSetALineExceptionFunc(ToolBox::dispatch);
|
||||
cpuSetFLineExceptionFunc(MPW::dispatch);
|
||||
|
||||
cpuSetMidInstructionExceptionFunc(MidInstructionExceptionFunc);
|
||||
|
||||
if (Flags.traceGlobals) memorySetGlobalLog(kGlobalSize);
|
||||
|
||||
if (Flags.traceGlobals) //memorySetGlobalLog(kGlobalSize);
|
||||
memorySetLoggingFunc(MemoryLogger);
|
||||
|
||||
MPW::Trace = Flags.traceMPW;
|
||||
ToolBox::Trace = Flags.traceToolBox;
|
||||
|
||||
|
||||
|
||||
if (Flags.traceCPU || Flags.traceMacsbug)
|
||||
{
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
@ -669,60 +995,14 @@ int main(int argc, char **argv)
|
|||
// else do it manually below.
|
||||
}
|
||||
|
||||
|
||||
#ifndef LOADER_LOAD
|
||||
cpuInitializeFromNewPC(address);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
auto begin_emu_time = std::chrono::high_resolution_clock::now();
|
||||
fprintf(stderr, "Begin Emulation Time: %20lld\n", (begin_emu_time - start_time).count());
|
||||
#endif
|
||||
|
||||
uint64_t cycles = 0;
|
||||
for (;;)
|
||||
{
|
||||
uint32_t pc = cpuGetPC();
|
||||
uint32_t sp = cpuGetAReg(7);
|
||||
|
||||
if (pc == 0x00000000)
|
||||
{
|
||||
fprintf(stderr, "Exiting - PC = 0\n");
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
if (sp < StackRange.first)
|
||||
{
|
||||
fprintf(stderr, "Stack overflow error - please increase the stack size (--stack=size)\n");
|
||||
fprintf(stderr, "Current stack size is 0x%06x\n", Flags.stack);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
if (sp > StackRange.second)
|
||||
{
|
||||
fprintf(stderr, "Stack underflow error\n");
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
if (Flags.debugger) Debug::Shell();
|
||||
else MainLoop();
|
||||
|
||||
|
||||
if (cpuGetStop()) break; // will this also be set by an interrupt?
|
||||
|
||||
|
||||
#ifndef CPU_INSTRUCTION_LOGGING
|
||||
if (Flags.traceCPU || Flags.traceMacsbug)
|
||||
{
|
||||
InstructionLogger();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
cycles += cpuExecuteInstruction();
|
||||
}
|
||||
|
||||
#if 0
|
||||
auto end_emu_time = std::chrono::high_resolution_clock::now();
|
||||
fprintf(stderr, " End Emulation Time: %20lld\n", (end_emu_time - start_time).count());
|
||||
fprintf(stderr, " Cycles: %20lld\n", cycles);
|
||||
#endif
|
||||
|
||||
if (Flags.memoryStats)
|
||||
{
|
||||
|
@ -733,6 +1013,6 @@ int main(int argc, char **argv)
|
|||
if (rv > 0xff) rv = 0xff;
|
||||
|
||||
|
||||
|
||||
|
||||
exit(rv);
|
||||
}
|
||||
}
|
||||
|
|
41
bin/loader.h
Normal file
41
bin/loader.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef __mpw_loader__
|
||||
#define __mpw_loader__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct Settings {
|
||||
Settings() {}
|
||||
|
||||
// command-line settings.
|
||||
|
||||
uint32_t memorySize = 16 * 1024 * 1024;
|
||||
uint32_t stackSize = 32 * 1024;
|
||||
uint32_t machine = 68030;
|
||||
|
||||
bool traceCPU = false;
|
||||
bool traceMacsbug = false;
|
||||
bool traceGlobals = false;
|
||||
bool traceToolBox = false;
|
||||
bool traceMPW = false;
|
||||
|
||||
bool debugger = false;
|
||||
|
||||
bool memoryStats = false;
|
||||
|
||||
|
||||
// updated later.
|
||||
std::pair<uint32_t, uint32_t> stackRange = {0, 0};
|
||||
uint8_t *memory = nullptr;
|
||||
|
||||
uint64_t cycles = 0;
|
||||
|
||||
const uint32_t kGlobalSize = 0x10000;
|
||||
};
|
||||
|
||||
|
||||
extern Settings Flags;
|
||||
|
||||
void DebugShell();
|
||||
|
||||
|
||||
#endif
|
298
bin/loadtrap.rl
Normal file
298
bin/loadtrap.rl
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
|
||||
namespace _loadtrap_rl {
|
||||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
|
||||
#define _GETDELIM_GROWBY 128 /* amount to grow line buffer by */
|
||||
#define _GETDELIM_MINLEN 4 /* minimum line buffer size */
|
||||
|
||||
ssize_t getdelim(char ** lineptr, size_t * n, int delimiter, FILE * stream) {
|
||||
char *buf, *pos;
|
||||
int c;
|
||||
ssize_t bytes;
|
||||
|
||||
if (lineptr == NULL || n == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (stream == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* resize (or allocate) the line buffer if necessary */
|
||||
buf = *lineptr;
|
||||
if (buf == NULL || *n < _GETDELIM_MINLEN) {
|
||||
buf = (char*)realloc(*lineptr, _GETDELIM_GROWBY);
|
||||
if (buf == NULL) {
|
||||
/* ENOMEM */
|
||||
return -1;
|
||||
}
|
||||
*n = _GETDELIM_GROWBY;
|
||||
*lineptr = buf;
|
||||
}
|
||||
|
||||
/* read characters until delimiter is found, end of file is reached, or an
|
||||
error occurs. */
|
||||
bytes = 0;
|
||||
pos = buf;
|
||||
while ((c = getc(stream)) != EOF) {
|
||||
if (bytes + 1 >= SSIZE_MAX) {
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
bytes++;
|
||||
if (bytes >= *n - 1) {
|
||||
buf = (char*)realloc(*lineptr, *n + _GETDELIM_GROWBY);
|
||||
if (buf == NULL) {
|
||||
/* ENOMEM */
|
||||
return -1;
|
||||
}
|
||||
*n += _GETDELIM_GROWBY;
|
||||
pos = buf + bytes - 1;
|
||||
*lineptr = buf;
|
||||
}
|
||||
|
||||
*pos++ = (char) c;
|
||||
if (c == delimiter) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror(stream) || (feof(stream) && (bytes == 0))) {
|
||||
/* EOF, or an error from getc(). */
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pos = '\0';
|
||||
return bytes;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ssize_t getline(char ** lineptr, size_t * n, FILE * stream) {
|
||||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
|
||||
return getdelim(lineptr, n, '\n', stream);
|
||||
#else
|
||||
return ::getline(lineptr, n, stream);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
namespace {
|
||||
// private...
|
||||
%%{
|
||||
|
||||
machine lexer;
|
||||
|
||||
action addx {
|
||||
value = (value << 4) + digittoint(fc);
|
||||
}
|
||||
|
||||
ws = [ \t];
|
||||
|
||||
value =
|
||||
'0x' xdigit+ @addx
|
||||
|
|
||||
'$' xdigit+ @addx
|
||||
|
|
||||
'-'? @{ negative = true; }
|
||||
digit+ @{value = value * 10 + (fc - '0'); }
|
||||
|
|
||||
[A-Za-z_] @{ stringValue.push_back(fc); }
|
||||
[A-Za-z0-9_]+ @{ stringValue.push_back(fc); }
|
||||
;
|
||||
|
||||
|
||||
name =
|
||||
[A-Za-z0-9_]+ @{
|
||||
name.push_back(fc);
|
||||
}
|
||||
;
|
||||
|
||||
main :=
|
||||
|
||||
name
|
||||
ws*
|
||||
'='
|
||||
ws*
|
||||
value
|
||||
;
|
||||
|
||||
write data;
|
||||
}%%
|
||||
|
||||
|
||||
|
||||
bool ParseLine(const char *p, const char *pe, std::map<std::string, uint16_t> &map)
|
||||
{
|
||||
|
||||
// trap = number
|
||||
// or trap = [previously defined trap]
|
||||
|
||||
std::string name;
|
||||
std::string stringValue;
|
||||
uint32_t value;
|
||||
bool negative = false;
|
||||
|
||||
value = 0;
|
||||
const char *eof = pe;
|
||||
int cs;
|
||||
|
||||
%%write init;
|
||||
%%write exec;
|
||||
|
||||
if (cs < %%{ write first_final; }%% )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (negative) value = (-value) & 0xffff;
|
||||
|
||||
// name lookup
|
||||
if (!stringValue.empty())
|
||||
{
|
||||
auto iter = map.find(stringValue);
|
||||
if (iter == map.end())
|
||||
{
|
||||
fprintf(stderr, "Undefined trap: %s\n", stringValue.c_str());
|
||||
return false;
|
||||
}
|
||||
value = iter->second;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// if loading globals, wouldn't need to do this...
|
||||
if (value > 0xafff || value < 0xa000)
|
||||
{
|
||||
fprintf(stderr, "Invalid trap number: $%04x\n", value);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
map.emplace(name, (uint16_t)value);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
|
||||
void LoadTrapFile(const std::string &path, std::map<std::string, uint16_t> &map)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(path.c_str(), "r");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "Unable to open trap file %s\n", path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getline(3) is 2008 posix. it allocates (and resizes as appropriate)
|
||||
* the buffer.
|
||||
*
|
||||
*/
|
||||
char *lineBuffer = NULL;
|
||||
size_t lineSize = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
char *line;
|
||||
ssize_t length;
|
||||
|
||||
length = _loadtrap_rl::getline(&lineBuffer, &lineSize, fp);
|
||||
if (!length) continue; //?
|
||||
if (length < 0) break; // eof or error.
|
||||
|
||||
line = lineBuffer;
|
||||
|
||||
// skip any leading space.
|
||||
while (length && isspace(*line))
|
||||
{
|
||||
++line;
|
||||
--length;
|
||||
}
|
||||
if (!length) continue;
|
||||
|
||||
// comments
|
||||
if (*line == '#') continue;
|
||||
|
||||
|
||||
// strip any trailing space.
|
||||
// (will be \n terminated unless there was no \n)
|
||||
while (length && isspace(line[length - 1]))
|
||||
{
|
||||
line[--length] = 0;
|
||||
}
|
||||
if (!length) continue;
|
||||
|
||||
if (!ParseLine(line, line + length, map))
|
||||
{
|
||||
fprintf(stderr, "Error in trap definition: %s\n", line);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::string f(argv[i]);
|
||||
std::map<std::string, uint16_t> map;
|
||||
Debug::LoadTrapFile(f, map);
|
||||
|
||||
for(const auto kv : map)
|
||||
{
|
||||
printf("%s -> %04x\n", kv.first.c_str(), kv.second);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
1868
bin/parser.cpp
Normal file
1868
bin/parser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
51
bin/parser.h
Normal file
51
bin/parser.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
#define tkPIPEPIPE 1
|
||||
#define tkAMPAMP 2
|
||||
#define tkPIPE 3
|
||||
#define tkCARET 4
|
||||
#define tkAMP 5
|
||||
#define tkEQEQ 6
|
||||
#define tkBANGEQ 7
|
||||
#define tkLT 8
|
||||
#define tkLTEQ 9
|
||||
#define tkGT 10
|
||||
#define tkGTEQ 11
|
||||
#define tkLTLT 12
|
||||
#define tkGTGT 13
|
||||
#define tkPLUS 14
|
||||
#define tkMINUS 15
|
||||
#define tkSTAR 16
|
||||
#define tkSLASH 17
|
||||
#define tkPERCENT 18
|
||||
#define tkBANG 19
|
||||
#define tkTILDE 20
|
||||
#define tkEOL 21
|
||||
#define tkPRINT 22
|
||||
#define tkBREAK 23
|
||||
#define tkBACKTRACE 24
|
||||
#define tkCONTINUE 25
|
||||
#define tkTBREAK 26
|
||||
#define tkRBREAK 27
|
||||
#define tkWBREAK 28
|
||||
#define tkRWBREAK 29
|
||||
#define tkNEXT 30
|
||||
#define tkDUMP 31
|
||||
#define tkCOLON 32
|
||||
#define tkAT 33
|
||||
#define tkLIST 34
|
||||
#define tkSTACKCRAWL 35
|
||||
#define tkSEMI 36
|
||||
#define tkSEMIH 37
|
||||
#define tkSEMII 38
|
||||
#define tkSEMIL 39
|
||||
#define tkSEMIDATE 40
|
||||
#define tkSEMIERROR 41
|
||||
#define tkSEMIT 42
|
||||
#define tkIDENTIFIER 43
|
||||
#define tkDREGISTER 44
|
||||
#define tkEQ 45
|
||||
#define tkAREGISTER 46
|
||||
#define tkXREGISTER 47
|
||||
#define tkHELP 48
|
||||
#define tkLPAREN 49
|
||||
#define tkRPAREN 50
|
||||
#define tkINTEGER 51
|
330
bin/parser.lemon
Normal file
330
bin/parser.lemon
Normal file
|
@ -0,0 +1,330 @@
|
|||
|
||||
%extra_argument { Debug::Command *command }
|
||||
%token_prefix tk
|
||||
|
||||
%token_type { Token }
|
||||
%include {
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include "debugger.h"
|
||||
|
||||
#include <toolbox/mm.h>
|
||||
|
||||
using Debug::Token;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t cpuGetSR();
|
||||
uint32_t cpuGetPC();
|
||||
uint32_t cpuGetAReg(unsigned);
|
||||
uint32_t cpuGetDReg(unsigned);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
}
|
||||
|
||||
%parse_failure {
|
||||
//fprintf(stderr,"I don't understand.\n");
|
||||
command->valid = false;
|
||||
}
|
||||
|
||||
%parse_accept {
|
||||
command->valid = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
%left PIPEPIPE.
|
||||
%left AMPAMP.
|
||||
%left PIPE.
|
||||
%left CARET.
|
||||
%left AMP.
|
||||
%left EQEQ BANGEQ.
|
||||
%left LT LTEQ GT GTEQ.
|
||||
%left LTLT GTGT.
|
||||
%left PLUS MINUS.
|
||||
%left STAR SLASH PERCENT.
|
||||
%right BANG TILDE.
|
||||
|
||||
|
||||
stmt ::= expr(a) EOL.
|
||||
{
|
||||
Debug::Print(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= STAR EOL.
|
||||
{
|
||||
Debug::PrintRegisters();
|
||||
}
|
||||
|
||||
stmt ::= PRINT expr(a) EOL.
|
||||
{
|
||||
Debug::Print(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= BREAK EOL.
|
||||
{
|
||||
Debug::Break();
|
||||
}
|
||||
|
||||
stmt ::= BREAK expr(a) EOL.
|
||||
{
|
||||
Debug::Break(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= BACKTRACE EOL.
|
||||
{
|
||||
Debug::PrintBackTrace();
|
||||
}
|
||||
|
||||
stmt ::= CONTINUE EOL.
|
||||
{
|
||||
command->action = Debug::cmdContinue;
|
||||
command->argc = 0;
|
||||
}
|
||||
|
||||
stmt ::= TBREAK EOL.
|
||||
{
|
||||
Debug::ToolBreak();
|
||||
}
|
||||
|
||||
stmt ::= TBREAK expr(a) EOL.
|
||||
{
|
||||
Debug::ToolBreak(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= RBREAK EOL .
|
||||
{
|
||||
Debug::ReadBreak();
|
||||
}
|
||||
|
||||
stmt ::= RBREAK expr(a) EOL.
|
||||
{
|
||||
Debug::ReadBreak(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= WBREAK EOL.
|
||||
{
|
||||
Debug::WriteBreak();
|
||||
}
|
||||
|
||||
stmt ::= WBREAK expr(a) EOL.
|
||||
{
|
||||
Debug::WriteBreak(a.intValue);
|
||||
}
|
||||
|
||||
|
||||
stmt ::= RWBREAK expr(a) EOL .
|
||||
{
|
||||
Debug::ReadWriteBreak(a.intValue);
|
||||
}
|
||||
|
||||
|
||||
stmt ::= NEXT EOL.
|
||||
{
|
||||
command->action = Debug::cmdStep;
|
||||
command->argc = 0;
|
||||
}
|
||||
|
||||
stmt ::= NEXT expr(a) EOL.
|
||||
{
|
||||
command->action = Debug::cmdStep;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a.intValue;
|
||||
}
|
||||
|
||||
stmt ::= DUMP expr(a) EOL.
|
||||
{
|
||||
Debug::Dump(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= DUMP expr(a) COLON expr(b) EOL.
|
||||
{
|
||||
Debug::Dump(a.intValue, b.intValue - a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= DUMP expr(a) AT expr(b) EOL.
|
||||
{
|
||||
Debug::Dump(a.intValue, b.intValue);
|
||||
}
|
||||
|
||||
stmt ::= LIST expr(a) EOL.
|
||||
{
|
||||
Debug::List(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= STACKCRAWL EOL.
|
||||
{
|
||||
Debug::StackCrawl();
|
||||
}
|
||||
|
||||
stmt ::= expr(a) SEMI SEMIH EOL.
|
||||
{
|
||||
Debug::Dump(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= expr(a) COLON expr(b) SEMI SEMIH EOL.
|
||||
{
|
||||
Debug::Dump(a.intValue, b.intValue - a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= expr(a) AT expr(b) SEMI SEMIH EOL.
|
||||
{
|
||||
Debug::Dump(a.intValue, b.intValue);
|
||||
}
|
||||
|
||||
|
||||
stmt ::= expr(a) SEMI SEMII EOL.
|
||||
{
|
||||
Debug::Info(a.intValue);
|
||||
}
|
||||
|
||||
|
||||
stmt ::= expr(a) SEMI SEMIL EOL.
|
||||
{
|
||||
Debug::List(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= expr(a) AT expr(b) SEMI SEMIL EOL.
|
||||
{
|
||||
Debug::List(a.intValue, (int)b.intValue);
|
||||
}
|
||||
|
||||
stmt ::= expr(a) COLON expr(b) SEMI SEMIL EOL.
|
||||
{
|
||||
Debug::List(a.intValue, b.intValue);
|
||||
}
|
||||
|
||||
stmt ::= expr(a) SEMI SEMIDATE EOL.
|
||||
{
|
||||
Debug::PrintDate(a.intValue);
|
||||
}
|
||||
|
||||
stmt ::= expr(a) SEMI SEMIERROR EOL.
|
||||
{
|
||||
Debug::PrintError(a.intValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
stmt ::= expr(a) SEMI SEMIT IDENTIFIER(b) EOL.
|
||||
{
|
||||
Debug::ApplyTemplate(a.intValue, *b.stringValue);
|
||||
}
|
||||
|
||||
|
||||
stmt ::= expr SEMI SEMIT error EOL.
|
||||
{
|
||||
fprintf(stderr, "usage: expression ; t TemplateName\n");
|
||||
}
|
||||
|
||||
|
||||
stmt ::= DREGISTER(a) EQ expr(b) EOL.
|
||||
{
|
||||
Debug::SetDRegister(a.intValue, b.intValue);
|
||||
}
|
||||
|
||||
stmt ::= AREGISTER(a) EQ expr(b) EOL.
|
||||
{
|
||||
Debug::SetARegister(a.intValue, b.intValue);
|
||||
}
|
||||
|
||||
stmt ::= XREGISTER(a) EQ expr(b) EOL.
|
||||
{
|
||||
Debug::SetXRegister(a.intValue, b.intValue);
|
||||
}
|
||||
|
||||
stmt ::= HELP EOL.
|
||||
{
|
||||
Debug::Help();
|
||||
}
|
||||
|
||||
stmt ::= IDENTIFIER(a) EQ expr(b) EOL.
|
||||
{
|
||||
Debug::VariableSet(*a.stringValue, b.intValue);
|
||||
}
|
||||
|
||||
expr(rhs) ::= unary(a). { rhs = a; }
|
||||
expr(rhs) ::= expr(a) PLUS expr(b). { rhs = Token::Make(a.intValue + b.intValue); }
|
||||
expr(rhs) ::= expr(a) MINUS expr(b). { rhs = Token::Make(a.intValue - b.intValue); }
|
||||
expr(rhs) ::= expr(a) STAR expr(b). { rhs = Token::Make(a.intValue * b.intValue); }
|
||||
expr(rhs) ::= expr(a) SLASH expr(b). { rhs = Token::Make(a.intValue / b.intValue); }
|
||||
expr(rhs) ::= expr(a) PERCENT expr(b). { rhs = Token::Make(a.intValue % b.intValue); }
|
||||
expr(rhs) ::= expr(a) LTLT expr(b). { rhs = Token::Make(a.intValue << b.intValue); }
|
||||
expr(rhs) ::= expr(a) GTGT expr(b). { rhs = Token::Make(a.intValue >> b.intValue); }
|
||||
expr(rhs) ::= expr(a) LT expr(b). { rhs = Token::Make(a.intValue < b.intValue); }
|
||||
expr(rhs) ::= expr(a) LTEQ expr(b). { rhs = Token::Make(a.intValue <= b.intValue); }
|
||||
expr(rhs) ::= expr(a) GT expr(b). { rhs = Token::Make(a.intValue > b.intValue); }
|
||||
expr(rhs) ::= expr(a) GTEQ expr(b). { rhs = Token::Make(a.intValue >= b.intValue); }
|
||||
expr(rhs) ::= expr(a) EQEQ expr(b). { rhs = Token::Make(a.intValue == b.intValue); }
|
||||
expr(rhs) ::= expr(a) BANGEQ expr(b). { rhs = Token::Make(a.intValue != b.intValue); }
|
||||
expr(rhs) ::= expr(a) AMP expr(b). { rhs = Token::Make(a.intValue & b.intValue); }
|
||||
expr(rhs) ::= expr(a) CARET expr(b). { rhs = Token::Make(a.intValue ^ b.intValue); }
|
||||
expr(rhs) ::= expr(a) PIPE expr(b). { rhs = Token::Make(a.intValue | b.intValue); }
|
||||
expr(rhs) ::= expr(a) AMPAMP expr(b). { rhs = Token::Make(a.intValue && b.intValue); }
|
||||
expr(rhs) ::= expr(a) PIPEPIPE expr(b). { rhs = Token::Make(a.intValue || b.intValue); }
|
||||
|
||||
// 68k assembly - offset(register)
|
||||
// offset is a 16-bit quantity... this will
|
||||
// handle 32-bit values or 16-bit.
|
||||
expr(rhs) ::= unary(a) LPAREN register(b) RPAREN.
|
||||
{
|
||||
uint32_t offset = a.intValue;
|
||||
uint32_t value = b.intValue;
|
||||
|
||||
// offset is 16-bits.
|
||||
if (offset <= 0xffff)
|
||||
{
|
||||
if (offset & 0x8000)
|
||||
offset |= 0xffff0000;
|
||||
}
|
||||
|
||||
rhs = Token::Make(value + offset);
|
||||
}
|
||||
|
||||
|
||||
unary(rhs) ::= term(a). { rhs = a; }
|
||||
unary(rhs) ::= PLUS unary(a). [BANG] { rhs = a; }
|
||||
unary(rhs) ::= MINUS unary(a). [BANG] { rhs = Token::Make(-a.intValue); }
|
||||
unary(rhs) ::= TILDE unary(a). { rhs = Token::Make(~a.intValue); }
|
||||
unary(rhs) ::= BANG unary(a). { rhs = Token::Make(!a.intValue); }
|
||||
unary(rhs) ::= STAR unary(a). [BANG] { rhs = Token::Make(Debug::ReadLong(a)); }
|
||||
|
||||
term(rhs) ::= LPAREN expr(a) RPAREN. { rhs = a; }
|
||||
term(rhs) ::= INTEGER(a). { rhs = a; }
|
||||
term(rhs) ::= register(a). { rhs = a; }
|
||||
|
||||
|
||||
term(rhs) ::= IDENTIFIER(a).
|
||||
{
|
||||
// should throw/barf if undefined?
|
||||
rhs = Token::Make(Debug::VariableGet(*a.stringValue));
|
||||
}
|
||||
|
||||
|
||||
register(rhs) ::= DREGISTER(a). { rhs = Token::Make(cpuGetDReg(a)); }
|
||||
register(rhs) ::= AREGISTER(a). { rhs = Token::Make(cpuGetAReg(a)); }
|
||||
register(rhs) ::= XREGISTER(a).
|
||||
{
|
||||
switch(a)
|
||||
{
|
||||
case 0:
|
||||
rhs = Token::Make(cpuGetPC());
|
||||
break;
|
||||
case 1:
|
||||
rhs = Token::Make(cpuGetSR());
|
||||
break;
|
||||
default:
|
||||
rhs = Token::Make(0);
|
||||
}
|
||||
}
|
272
bin/template.cpp
Normal file
272
bin/template.cpp
Normal file
|
@ -0,0 +1,272 @@
|
|||
#include "template.h"
|
||||
#include "debugger.h"
|
||||
#include "debugger_internal.h"
|
||||
#include "loader.h" // Flags.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <toolbox/toolbox.h>
|
||||
|
||||
|
||||
namespace Debug {
|
||||
|
||||
using namespace Debug::Internal;
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
unsigned CalcOneSize(FieldEntry *e)
|
||||
{
|
||||
unsigned s = (e->type & 0x0f00) >> 8;
|
||||
|
||||
if (!s) {
|
||||
// struct or pointer...
|
||||
if (e->type & 0x8000) s = 4;
|
||||
else if (e->tmpl) s = e->tmpl->struct_size;
|
||||
}
|
||||
|
||||
if (e->count) s *= e->count;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
unsigned CalcSize(FieldEntry *e)
|
||||
{
|
||||
unsigned size = 0;
|
||||
|
||||
while (e)
|
||||
{
|
||||
size += CalcOneSize(e);
|
||||
e = e->next;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
FieldEntry *Reverse(FieldEntry *e)
|
||||
{
|
||||
if (!e) return e;
|
||||
|
||||
// reverse the order...
|
||||
FieldEntry *prev;
|
||||
FieldEntry *next;
|
||||
|
||||
prev = nullptr;
|
||||
for(;;)
|
||||
{
|
||||
next = e->next;
|
||||
e->next = prev;
|
||||
|
||||
prev = e;
|
||||
e = next;
|
||||
if (!e) return prev;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline bool ValidPointer(uint32_t value)
|
||||
{
|
||||
return value && value < Flags.memorySize;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CreateTypedef(const std::string *name, int type, TemplateParseInfo *info)
|
||||
{
|
||||
// check if it's an existing typedef...
|
||||
|
||||
auto &Templates = *info->templates;
|
||||
auto &Types = *info->types;
|
||||
|
||||
|
||||
auto iter = Types.find(*name);
|
||||
if (iter != Types.end())
|
||||
{
|
||||
if (iter->second == type) return; // ok, just a duplicate.
|
||||
fprintf(stderr, "Template Error: line %d - redefining %s\n",
|
||||
info->LineNumber, name->c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Templates.find(*name) != Templates.end())
|
||||
{
|
||||
fprintf(stderr, "Template Error: line %d - redefining %s\n",
|
||||
info->LineNumber, name->c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Types.emplace(std::make_pair(*name, type));
|
||||
}
|
||||
|
||||
|
||||
void CreateTemplate(const std::string *name, FieldEntry *firstField, TemplateParseInfo *info)
|
||||
{
|
||||
auto &Templates = *info->templates;
|
||||
auto &Types = *info->types;
|
||||
|
||||
// check if it exists...
|
||||
|
||||
if (Templates.find(*name) != Templates.end())
|
||||
{
|
||||
fprintf(stderr, "Template Error: line %d - redefining %s\n",
|
||||
info->LineNumber, name->c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (Types.find(*name) != Types.end())
|
||||
{
|
||||
fprintf(stderr, "Template Error: line %d - redefining %s\n",
|
||||
info->LineNumber, name->c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
firstField = Reverse(firstField);
|
||||
firstField->struct_size = CalcSize(firstField);
|
||||
|
||||
Templates.emplace(std::make_pair(*name, firstField));
|
||||
}
|
||||
|
||||
void CleanupString(std::string &s)
|
||||
{
|
||||
// replace non-printables.
|
||||
std::transform(s.begin(), s.end(), s.begin(), [](char c){
|
||||
return isprint(c) ? c : '.';
|
||||
});
|
||||
|
||||
if (s.size() > 40) {
|
||||
s.resize(37);
|
||||
s.append("...");
|
||||
}
|
||||
}
|
||||
void PrettyPrint(uint32_t value, unsigned type)
|
||||
{
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case kOSType:
|
||||
// print 4-cc code
|
||||
fputc(' ', stdout);
|
||||
fputs(ToolBox::TypeToString(value).c_str(), stdout);
|
||||
return;
|
||||
|
||||
case kOSErr:
|
||||
// print value + short name
|
||||
{
|
||||
printf(" %-6d", (int16_t)value);
|
||||
auto iter = ErrorTableInvert.find(value);
|
||||
if (iter != ErrorTableInvert.end()) printf(" %s", iter->second.c_str());
|
||||
}
|
||||
return;
|
||||
|
||||
case kPStringPtr:
|
||||
// read the string...
|
||||
if (ValidPointer(value))
|
||||
{
|
||||
std::string tmp = ReadPString(value);
|
||||
CleanupString(tmp);
|
||||
printf(" '%s'", tmp.c_str());
|
||||
}
|
||||
return;
|
||||
|
||||
case kCStringPtr:
|
||||
// read the string...
|
||||
if (ValidPointer(value))
|
||||
{
|
||||
std::string tmp = ReadCString(value);
|
||||
CleanupString(tmp);
|
||||
printf(" '%s'", tmp.c_str());
|
||||
}
|
||||
return;
|
||||
return;
|
||||
|
||||
case kBoolean:
|
||||
fputc(' ', stdout);
|
||||
fputs(value ? "true" : "false", stdout);
|
||||
return;
|
||||
|
||||
case kHandle:
|
||||
// print address, size, locked stats.
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// int/signed int - print base 10.
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ApplyTemplate(uint32_t address, FieldEntry *e, unsigned indent)
|
||||
{
|
||||
unsigned offset = 0;
|
||||
|
||||
if (!e) return;
|
||||
|
||||
for( ; e ; e = e->next)
|
||||
{
|
||||
|
||||
bool nonl = false;
|
||||
unsigned count = e->count;
|
||||
unsigned type = e->type;
|
||||
unsigned s = (type & 0x0f00) >> 8;
|
||||
|
||||
for (unsigned i = 0; i < indent; ++i) fputc('>',stdout);
|
||||
printf("%08x %s", address + offset, e->name->c_str());
|
||||
for(unsigned i = indent + e->name->length(); i < 32; ++i) fputc(' ',stdout);
|
||||
|
||||
// todo -- support arrays
|
||||
// todo -- pretty print values (boolean, oserr, ostype, etc.)
|
||||
switch(s)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
uint8_t value = ReadByte(address + offset);
|
||||
printf(" %02x", value);
|
||||
PrettyPrint(value, type);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
uint16_t value = ReadWord(address + offset);
|
||||
printf(" %04x", value);
|
||||
PrettyPrint(value, type);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
uint32_t value = ReadLong(address + offset);
|
||||
printf("%08x", value);
|
||||
PrettyPrint(value, type);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
// either a pointer or a struct
|
||||
if (type & 0x8000) {
|
||||
// pointer.
|
||||
uint32_t value = ReadLong(address + offset);
|
||||
printf("%08x", value);
|
||||
PrettyPrint(value, type);
|
||||
break;
|
||||
}
|
||||
if (type == 0) {
|
||||
// struct ... recurse.
|
||||
fputc('\n', stdout);
|
||||
nonl = true;
|
||||
ApplyTemplate(address + offset, e->tmpl, indent + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nonl) fputc('\n', stdout);
|
||||
offset += CalcOneSize(e);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
88
bin/template.h
Normal file
88
bin/template.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
#ifndef __debug_template_h__
|
||||
#define __debug_template_h__
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
namespace Debug {
|
||||
|
||||
|
||||
enum {
|
||||
|
||||
// 0x8000 = pointer
|
||||
// 0x1000 = unsigned
|
||||
// 0x0f00 = size
|
||||
// 0-255 - type
|
||||
|
||||
kSInt64 = 0x0800,
|
||||
kUInt64 = 0x1800,
|
||||
|
||||
kSInt32 = 0x0400,
|
||||
kUInt32 = 0x1400,
|
||||
|
||||
kSInt16 = 0x0200,
|
||||
kUInt16 = 0x1200,
|
||||
|
||||
kSInt8 = 0x0100,
|
||||
kUInt8 = 0x1100,
|
||||
|
||||
kStruct = 0x0000,
|
||||
kStructPtr = 0x8000,
|
||||
|
||||
// ptrs are a special case where size = 0
|
||||
//kVoid = 0x0001,
|
||||
kVoidPtr = 0x8001,
|
||||
|
||||
// these exist for display purposes.
|
||||
kCStringPtr = 0x8002,
|
||||
kPStringPtr = 0x8003,
|
||||
|
||||
kOSType = 0x00404,
|
||||
kBoolean = 0x0105,
|
||||
kOSErr = 0x0206,
|
||||
kHandle = 0x04007,
|
||||
|
||||
};
|
||||
|
||||
inline unsigned MakePtr(unsigned type) { return type | 0x8000; }
|
||||
inline unsigned MakeType(unsigned size, bool sign, bool ptr) {
|
||||
unsigned rv = size << 8;
|
||||
if (!sign) rv |= 0x0100;
|
||||
if (ptr) rv |= 0x8000;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct FieldEntry;
|
||||
typedef FieldEntry *Template;
|
||||
|
||||
struct FieldEntry {
|
||||
std::string *name;
|
||||
unsigned type;
|
||||
unsigned count;
|
||||
Template tmpl;
|
||||
FieldEntry *next;
|
||||
unsigned struct_size; // only populated for head entry.
|
||||
};
|
||||
|
||||
struct TemplateParseInfo {
|
||||
std::unordered_map<std::string, Template> *templates;
|
||||
std::unordered_map<std::string, unsigned> *types;
|
||||
int LineNumber;
|
||||
};
|
||||
|
||||
|
||||
void CreateTypedef(const std::string *name, int type, TemplateParseInfo *);
|
||||
void CreateTemplate(const std::string *name, FieldEntry *firstField, TemplateParseInfo *);
|
||||
|
||||
|
||||
bool LoadTemplateFile(const std::string &filename, std::unordered_map<std::string, Template> &);
|
||||
|
||||
|
||||
void ApplyTemplate(uint32_t address, FieldEntry *e, unsigned indent = 0);
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
255
bin/template_loader.rl
Normal file
255
bin/template_loader.rl
Normal file
|
@ -0,0 +1,255 @@
|
|||
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "template_parser.h"
|
||||
#include "template.h"
|
||||
#include "intern.h"
|
||||
|
||||
namespace {
|
||||
|
||||
int tox(char c)
|
||||
{
|
||||
c |= 0x20; // lowercase it.
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
return 0;
|
||||
}
|
||||
uint32_t scan10(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](uint32_t value, char c){
|
||||
return value * 10 + c - '0';
|
||||
});
|
||||
}
|
||||
|
||||
uint32_t scan16(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](uint32_t value, char c){
|
||||
return (value << 4) + tox(c);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void *TemplateParseAlloc(void *(*mallocProc)(size_t));
|
||||
void TemplateParseFree(void *p, void (*freeProc)(void*));
|
||||
|
||||
void TemplateParse(void *yyp, int yymajor, void *yyminor, Debug::TemplateParseInfo *);
|
||||
|
||||
|
||||
void TemplateParse(void *yyp, int yymajor, int yyminor, Debug::TemplateParseInfo *info)
|
||||
{
|
||||
TemplateParse(yyp, yymajor, (void *)(ptrdiff_t)yyminor, info);
|
||||
}
|
||||
|
||||
void TemplateParse(void *yyp, int yymajor, const std::string *yyminor, Debug::TemplateParseInfo *info)
|
||||
{
|
||||
TemplateParse(yyp, yymajor, (void *)yyminor, info);
|
||||
}
|
||||
|
||||
#define TemplateParse(a,b,c) TemplateParse(a,b,c, &info)
|
||||
|
||||
%%{
|
||||
machine lexer;
|
||||
|
||||
# this exits with cs == lexer_en_error.
|
||||
error := any* ${ fbreak; };
|
||||
|
||||
block_comment := |*
|
||||
[\n\r] { info.LineNumber++; };
|
||||
'*/' { fgoto main; };
|
||||
any ;
|
||||
*|;
|
||||
|
||||
main := |*
|
||||
|
||||
[\n\r] { info.LineNumber++; };
|
||||
[ \t]+;
|
||||
|
||||
'//' [^\r\n]* ;
|
||||
'/*' { fgoto block_comment; };
|
||||
|
||||
';' { TemplateParse(parser, tkSEMI, 0); };
|
||||
'{' { TemplateParse(parser, tkLBRACE, 0); };
|
||||
'}' { TemplateParse(parser, tkRBRACE, 0); };
|
||||
'[' { TemplateParse(parser, tkLBRACKET, 0); };
|
||||
']' { TemplateParse(parser, tkRBRACKET, 0); };
|
||||
'*' { TemplateParse(parser, tkSTAR, 0); };
|
||||
|
||||
'struct' { TemplateParse(parser, tkSTRUCT, 0); };
|
||||
'typedef' { TemplateParse(parser, tkTYPEDEF, 0); };
|
||||
|
||||
|
||||
'int' { TemplateParse(parser, tkINT, 0); };
|
||||
'long' { TemplateParse(parser, tkLONG, 0); };
|
||||
'short' { TemplateParse(parser, tkSHORT, 0); };
|
||||
'volatile' { TemplateParse(parser, tkVOLATILE, 0); };
|
||||
#'const' { TemplateParse(parser, tkCONST, 0); };
|
||||
'char' { TemplateParse(parser, tkCHAR, 0); };
|
||||
#'bool' { TemplateParse(parser, tkBOOL, 0); };
|
||||
'void' { TemplateParse(parser, tkVOID, 0); };
|
||||
|
||||
'signed' { TemplateParse(parser, tkSIGNED, 0); };
|
||||
'unsigned' { TemplateParse(parser, tkUNSIGNED, 0); };
|
||||
|
||||
'int64_t' { TemplateParse(parser, tkTYPECODE, kSInt64); };
|
||||
'uint64_t' { TemplateParse(parser, tkTYPECODE, kUInt64); };
|
||||
|
||||
'int32_t' { TemplateParse(parser, tkTYPECODE, kSInt32); };
|
||||
'uint32_t' { TemplateParse(parser, tkTYPECODE, kUInt32); };
|
||||
|
||||
'int16_t' { TemplateParse(parser, tkTYPECODE, kSInt16); };
|
||||
'uint16_t' { TemplateParse(parser, tkTYPECODE, kUInt16); };
|
||||
|
||||
'int8_t' { TemplateParse(parser, tkTYPECODE, kSInt8); };
|
||||
'uint8_t' { TemplateParse(parser, tkTYPECODE, kUInt8); };
|
||||
|
||||
|
||||
'StringPtr' { TemplateParse(parser, tkTYPECODE, kPStringPtr); };
|
||||
'CStringPtr' { TemplateParse(parser, tkTYPECODE, kCStringPtr); };
|
||||
'Ptr' { TemplateParse(parser, tkTYPECODE, kVoidPtr); };
|
||||
'OSType' { TemplateParse(parser, tkTYPECODE, kOSType); };
|
||||
'OSErr' { TemplateParse(parser, tkTYPECODE, kOSErr); };
|
||||
'Boolean' { TemplateParse(parser, tkTYPECODE, kBoolean); };
|
||||
'Handle' { TemplateParse(parser, tkTYPECODE, kHandle); };
|
||||
|
||||
|
||||
# numbers. negative numbers are not allowed.
|
||||
|
||||
'0x'i xdigit+ {
|
||||
// hexadecimal
|
||||
uint32_t value = scan16(ts + 2, te);
|
||||
TemplateParse(parser, tkINTEGER, value);
|
||||
};
|
||||
|
||||
digit+ {
|
||||
uint32_t value = scan10(ts, te);
|
||||
TemplateParse(parser, tkINTEGER, value);
|
||||
};
|
||||
|
||||
# identifier ... but also need to check if it's a type.
|
||||
[A-Za-z_][A-Za-z0-9_]* {
|
||||
|
||||
// intern the string.
|
||||
|
||||
const std::string *name = Intern::String(ts, te);
|
||||
bool ok = false;
|
||||
|
||||
if (!ok) {
|
||||
auto iter = Types.find(*name);
|
||||
if (iter != Types.end())
|
||||
{
|
||||
TemplateParse(parser, tkTYPECODE, iter->second);
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
auto iter = Templates.find(*name);
|
||||
if (iter != Templates.end())
|
||||
{
|
||||
TemplateParse(parser, tkTEMPLATE, iter->second);
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
TemplateParse(parser, tkIDENTIFIER, name);
|
||||
}
|
||||
};
|
||||
|
||||
*|;
|
||||
|
||||
}%%
|
||||
|
||||
namespace Debug {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool LoadTemplateFile(const std::string &filename, std::unordered_map<std::string, Template> &Templates)
|
||||
{
|
||||
%% write data;
|
||||
|
||||
void *parser;
|
||||
|
||||
int fd;
|
||||
struct stat st;
|
||||
char *buffer;
|
||||
|
||||
std::unordered_map<std::string, unsigned> Types;
|
||||
TemplateParseInfo info;
|
||||
|
||||
info.LineNumber = 1;
|
||||
info.templates = &Templates;
|
||||
info.types = &Types;
|
||||
|
||||
// simple types are handled via the lexer so no need to populate them here.
|
||||
|
||||
|
||||
|
||||
if (stat(filename.c_str(), &st) < 0) return false;
|
||||
if (st.st_size == 0) return false;
|
||||
|
||||
fd = open(filename.c_str(), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("Error opening template file: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer = (char *)mmap(nullptr, st.st_size, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
|
||||
if (buffer == MAP_FAILED) {
|
||||
perror("Error mapping template file: ");
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
|
||||
|
||||
|
||||
parser = TemplateParseAlloc(malloc);
|
||||
|
||||
const char *p = buffer;
|
||||
const char *pe = buffer + st.st_size;
|
||||
const char *eof = pe;
|
||||
const char *ts;
|
||||
const char *te;
|
||||
int cs, act;
|
||||
|
||||
%% write init;
|
||||
%% write exec;
|
||||
|
||||
if (cs == lexer_error || cs < lexer_first_final)
|
||||
{
|
||||
if (p == eof)
|
||||
fprintf(stderr, "Template error: line %d - unexpected EOF\n", info.LineNumber);
|
||||
else
|
||||
fprintf(stderr, "Template error: line %d - illegal character: `%c'\n", info.LineNumber, *p);
|
||||
TemplateParseFree(parser, free);
|
||||
munmap(buffer, st.st_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
TemplateParse(parser, 0, 0);
|
||||
TemplateParseFree(parser, free);
|
||||
|
||||
munmap(buffer, st.st_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
1291
bin/template_parser.cpp
Normal file
1291
bin/template_parser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
20
bin/template_parser.h
Normal file
20
bin/template_parser.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#define tkTYPEDEF 1
|
||||
#define tkIDENTIFIER 2
|
||||
#define tkSTRUCT 3
|
||||
#define tkLBRACE 4
|
||||
#define tkRBRACE 5
|
||||
#define tkSEMI 6
|
||||
#define tkTEMPLATE 7
|
||||
#define tkLBRACKET 8
|
||||
#define tkINTEGER 9
|
||||
#define tkRBRACKET 10
|
||||
#define tkVOLATILE 11
|
||||
#define tkSIGNED 12
|
||||
#define tkUNSIGNED 13
|
||||
#define tkCHAR 14
|
||||
#define tkSHORT 15
|
||||
#define tkLONG 16
|
||||
#define tkTYPECODE 17
|
||||
#define tkVOID 18
|
||||
#define tkSTAR 19
|
||||
#define tkINT 20
|
129
bin/template_parser.lemon
Normal file
129
bin/template_parser.lemon
Normal file
|
@ -0,0 +1,129 @@
|
|||
%token_prefix tk
|
||||
%name TemplateParse
|
||||
%extra_argument { Debug::TemplateParseInfo *info }
|
||||
|
||||
|
||||
%include {
|
||||
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#include "template.h"
|
||||
|
||||
using namespace Debug;
|
||||
}
|
||||
|
||||
%type struct_fields { FieldEntry * }
|
||||
%type struct_field { FieldEntry * }
|
||||
|
||||
start ::= templates.
|
||||
|
||||
templates ::= templates struct.
|
||||
templates ::= templates typedef.
|
||||
templates ::= .
|
||||
|
||||
// typedeffing arrays or pointers is not allowed.
|
||||
|
||||
typedef ::= TYPEDEF type(a) IDENTIFIER(b). {
|
||||
CreateTypedef((std::string *)b, a, info);
|
||||
}
|
||||
|
||||
struct ::= STRUCT IDENTIFIER(a) LBRACE struct_fields(b) RBRACE SEMI.
|
||||
{
|
||||
CreateTemplate((std::string *)a, b, info);
|
||||
}
|
||||
|
||||
struct_fields(rhs) ::= struct_fields(a) struct_field(b). {
|
||||
// reverse order?
|
||||
b->next = a;
|
||||
rhs = b;
|
||||
}
|
||||
|
||||
struct_fields(rhs) ::= struct_field(a). {
|
||||
rhs = a;
|
||||
}
|
||||
|
||||
struct_field(rhs) ::= type(a) IDENTIFIER(b) array_count(c) SEMI.
|
||||
{
|
||||
FieldEntry *e = (FieldEntry *)calloc(sizeof(FieldEntry), 1);
|
||||
|
||||
e->name = (std::string *)b;
|
||||
e->type = a;
|
||||
e->count = c;
|
||||
rhs = e;
|
||||
}
|
||||
|
||||
struct_field(rhs) ::= opt_volatile TEMPLATE(a) opt_star(star) IDENTIFIER(b) array_count(c) SEMI. {
|
||||
FieldEntry *e = (FieldEntry *)calloc(sizeof(FieldEntry), 1);
|
||||
|
||||
e->name = (std::string *)b;
|
||||
e->type = star ? kStructPtr : kStruct;
|
||||
e->tmpl = (Template)a;
|
||||
e->count = c;
|
||||
|
||||
rhs = e;
|
||||
}
|
||||
|
||||
%type array_count { int }
|
||||
array_count(rhs) ::= . { rhs = 0; }
|
||||
array_count(rhs) ::= LBRACKET INTEGER(a) RBRACKET. {
|
||||
int i = (int)(ptrdiff_t)a;
|
||||
if (i == 0) {
|
||||
fprintf(stderr, "Template error: line %u: 0-sized arrays are not allowed.\n",
|
||||
info->LineNumber);
|
||||
i = 1;
|
||||
}
|
||||
rhs = i;
|
||||
}
|
||||
|
||||
%type type { int }
|
||||
type(rhs) ::= opt_volatile typecode(a). { rhs = a; }
|
||||
|
||||
// this is an expected error...
|
||||
type(rhs) ::= opt_volatile IDENTIFIER(xxx). {
|
||||
|
||||
// ugh, Lemon will blindly replace text within a string.
|
||||
fprintf(stderr, "Template error: line %u: %s is not a known type.\n",
|
||||
info->LineNumber, ((std::string *)xxx)->c_str());
|
||||
|
||||
rhs = 'i';
|
||||
}
|
||||
|
||||
|
||||
opt_volatile ::= .
|
||||
opt_volatile ::= VOLATILE.
|
||||
|
||||
|
||||
%type typecode { int }
|
||||
typecode(rhs) ::= SIGNED. { rhs = kSInt32; }
|
||||
typecode(rhs) ::= UNSIGNED. {rhs = kUInt32; }
|
||||
|
||||
typecode(rhs) ::= opt_signed CHAR. { rhs = kSInt8; }
|
||||
typecode(rhs) ::= UNSIGNED CHAR. { rhs = kUInt8; }
|
||||
|
||||
typecode(rhs) ::= opt_signed SHORT. { rhs = kSInt16; }
|
||||
typecode(rhs) ::= UNSIGNED SHORT. { rhs = kUInt16; }
|
||||
|
||||
typecode(rhs) ::= opt_signed LONG opt_int. { rhs = kSInt32; }
|
||||
typecode(rhs) ::= UNSIGNED LONG opt_int. { rhs = kUInt32; }
|
||||
|
||||
typecode(rhs) ::= opt_signed LONG LONG. { rhs = kSInt64; }
|
||||
typecode(rhs) ::= UNSIGNED LONG LONG. { rhs = kUInt64; }
|
||||
|
||||
typecode(rhs) ::= TYPECODE(a). { rhs = (int)(ptrdiff_t)a; }
|
||||
|
||||
/* pointers are not fully supported yet */
|
||||
typecode(rhs) ::= VOID STAR. { rhs = kVoidPtr; }
|
||||
|
||||
opt_signed ::= .
|
||||
opt_signed ::= SIGNED.
|
||||
|
||||
opt_int ::= .
|
||||
opt_int ::= INT.
|
||||
|
||||
%type opt_star { int }
|
||||
opt_star(rhs) ::= . { rhs = 0; }
|
||||
opt_star(rhs) ::= STAR. { rhs = 1; }
|
||||
|
|
@ -1,6 +1,12 @@
|
|||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
# Clang or AppleClang
|
||||
set(CMAKE_CXX_FLAGS "-Wall -Wno-unused-function")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS " -Wall -Wno-unused-function -g")
|
||||
if ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
|
||||
# Clang or AppleClang
|
||||
set(CMAKE_C_FLAGS "-Wall -Wno-unused-function")
|
||||
endif()
|
||||
|
||||
set(CPU_SRC
|
||||
CpuModule.c
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/* @(#) $Id: CpuIntegration.c,v 1.10 2013/01/08 19:17:33 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* Initialization of 68000 core */
|
||||
/* Integrates the 68k emulation with custom chips */
|
||||
/* Integrates the 68k emulation with custom chips */
|
||||
/* */
|
||||
/* Author: Petter Schau */
|
||||
/* */
|
||||
|
@ -29,55 +28,52 @@
|
|||
#include "CpuModule.h"
|
||||
#include "CpuIntegration.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
//#include "bus.h"
|
||||
//#include "fileops.h"
|
||||
|
||||
#include "bus.h"
|
||||
#include "fileops.h"
|
||||
#include "interrupt.h"
|
||||
|
||||
jmp_buf cpu_integration_exception_buffer;
|
||||
|
||||
/* custom chip intreq bit-number to irq-level */
|
||||
static ULO cpu_integration_int_to_level[16] = {1,1,1,2, 3,3,3,4, 4,4,4,5, 5,6,6,7};
|
||||
static ULO cpu_integration_irq_source;
|
||||
uint32_t cpu_integration_chip_interrupt_number;
|
||||
|
||||
/* Cycles spent by chips (Blitter) as a result of an instruction */
|
||||
static ULO cpu_integration_chip_cycles;
|
||||
static ULO cpu_integration_chip_slowdown;
|
||||
static uint32_t cpu_integration_chip_cycles;
|
||||
static uint32_t cpu_integration_chip_slowdown;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CPU properties */
|
||||
/*===========================================================================*/
|
||||
|
||||
ULO cpu_integration_speed; // The speed as expressed in the fellow configuration settings
|
||||
ULO cpu_integration_speed_multiplier; // The cycle multiplier used to adjust the cpu-speed, calculated from cpu_integration_speed
|
||||
uint32_t cpu_integration_speed; // The speed as expressed in the fellow configuration settings
|
||||
uint32_t cpu_integration_speed_multiplier; // The cycle multiplier used to adjust the cpu-speed, calculated from cpu_integration_speed
|
||||
cpu_integration_models cpu_integration_model; // The cpu model as expressed in the fellow configuration settings
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CPU properties */
|
||||
/*===========================================================================*/
|
||||
|
||||
void cpuIntegrationSetSpeed(ULO speed)
|
||||
void cpuIntegrationSetSpeed(uint32_t speed)
|
||||
{
|
||||
cpu_integration_speed = speed;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetSpeed(void)
|
||||
uint32_t cpuIntegrationGetSpeed(void)
|
||||
{
|
||||
return cpu_integration_speed;
|
||||
}
|
||||
|
||||
static void cpuIntegrationSetSpeedMultiplier(ULO multiplier)
|
||||
static void cpuIntegrationSetSpeedMultiplier(uint32_t multiplier)
|
||||
{
|
||||
cpu_integration_speed_multiplier = multiplier;
|
||||
}
|
||||
|
||||
static ULO cpuIntegrationGetSpeedMultiplier(void)
|
||||
static uint32_t cpuIntegrationGetSpeedMultiplier(void)
|
||||
{
|
||||
return cpu_integration_speed_multiplier;
|
||||
}
|
||||
|
||||
static void cpuIntegrationCalculateMultiplier(void)
|
||||
void cpuIntegrationCalculateMultiplier(void)
|
||||
{
|
||||
ULO multiplier = 12;
|
||||
uint32_t multiplier = 12;
|
||||
|
||||
switch (cpuGetModelMajor())
|
||||
{
|
||||
|
@ -124,85 +120,45 @@ cpu_integration_models cpuIntegrationGetModel(void)
|
|||
return cpu_integration_model;
|
||||
}
|
||||
|
||||
void cpuIntegrationSetChipCycles(ULO chip_cycles)
|
||||
void cpuIntegrationSetChipCycles(uint32_t chip_cycles)
|
||||
{
|
||||
cpu_integration_chip_cycles = chip_cycles;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetChipCycles(void)
|
||||
uint32_t cpuIntegrationGetChipCycles(void)
|
||||
{
|
||||
return cpu_integration_chip_cycles;
|
||||
}
|
||||
|
||||
void cpuIntegrationSetChipSlowdown(ULO chip_slowdown)
|
||||
void cpuIntegrationSetChipSlowdown(uint32_t chip_slowdown)
|
||||
{
|
||||
cpu_integration_chip_slowdown = chip_slowdown;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetChipSlowdown(void)
|
||||
uint32_t cpuIntegrationGetChipSlowdown(void)
|
||||
{
|
||||
return cpu_integration_chip_slowdown;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetChipIrqToIntLevel(ULO chip_irq)
|
||||
void cpuIntegrationSetChipInterruptNumber(uint32_t chip_interrupt_number)
|
||||
{
|
||||
return cpu_integration_int_to_level[chip_irq];
|
||||
cpu_integration_chip_interrupt_number = chip_interrupt_number;
|
||||
}
|
||||
|
||||
void cpuIntegrationSetIrqSource(ULO irq_source)
|
||||
uint32_t cpuIntegrationGetChipInterruptNumber(void)
|
||||
{
|
||||
cpu_integration_irq_source = irq_source;
|
||||
return cpu_integration_chip_interrupt_number;
|
||||
}
|
||||
|
||||
ULO cpuIntegrationGetIrqSource(void)
|
||||
// A wrapper for cpuSetIrqLevel that restarts the
|
||||
// scheduling of cpu events if the cpu was stoppped
|
||||
void cpuIntegrationSetIrqLevel(uint32_t new_interrupt_level, uint32_t chip_interrupt_number)
|
||||
{
|
||||
return cpu_integration_irq_source;
|
||||
}
|
||||
|
||||
/*=====================================================
|
||||
Checking for waiting interrupts
|
||||
=====================================================*/
|
||||
|
||||
static BOOLE cpuIntegrationCheckPendingInterruptsFunc(void)
|
||||
{
|
||||
ULO current_cpu_level = (cpuGetSR() >> 8) & 7;
|
||||
BOOLE chip_irqs_enabled = !!(intena & 0x4000);
|
||||
|
||||
if (chip_irqs_enabled)
|
||||
if (cpuSetIrqLevel(new_interrupt_level))
|
||||
{
|
||||
LON highest_chip_irq;
|
||||
ULO chip_irqs = intreq & intena;
|
||||
|
||||
if (chip_irqs == 0) return FALSE;
|
||||
|
||||
for (highest_chip_irq = 13; highest_chip_irq >= 0; highest_chip_irq--)
|
||||
{
|
||||
if (chip_irqs & (1 << highest_chip_irq))
|
||||
{
|
||||
// Found a chip-irq that is both flagged and enabled.
|
||||
ULO highest_chip_level = cpuIntegrationGetChipIrqToIntLevel(highest_chip_irq);
|
||||
if (highest_chip_level > current_cpu_level)
|
||||
{
|
||||
cpuSetIrqLevel(highest_chip_level);
|
||||
cpuSetIrqAddress(memoryReadLong(cpuGetVbr() + 0x60 + highest_chip_level*4));
|
||||
cpuIntegrationSetIrqSource(highest_chip_irq);
|
||||
|
||||
if (cpuGetStop())
|
||||
{
|
||||
cpuSetStop(FALSE);
|
||||
cpuEvent.cycle = bus.cycle;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
cpuEvent.cycle = busGetCycle();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void cpuIntegrationCheckPendingInterrupts(void)
|
||||
{
|
||||
cpuCheckPendingInterrupts();
|
||||
cpuIntegrationSetChipInterruptNumber(chip_interrupt_number);
|
||||
}
|
||||
|
||||
/*=========================================*/
|
||||
|
@ -244,7 +200,7 @@ void cpuInstructionLogOpen(void)
|
|||
|
||||
void cpuIntegrationPrintBusCycle(void)
|
||||
{
|
||||
fprintf(CPUINSTRUCTIONLOG, "%d:%.5d ", bus.frame_no, bus.cycle);
|
||||
fprintf(CPUINSTRUCTIONLOG, "%I64u:%.5u ", bus.frame_no, bus.cycle);
|
||||
}
|
||||
|
||||
void cpuIntegrationInstructionLogging(void)
|
||||
|
@ -284,7 +240,7 @@ void cpuIntegrationInstructionLogging(void)
|
|||
fprintf(CPUINSTRUCTIONLOG, "SSP:%.6X USP:%.6X SP:%.4X %s %s\t%s\t%s\n", cpuGetSspDirect(), cpuGetUspDirect(), cpuGetSR(), saddress, sdata, sinstruction, soperands);
|
||||
}
|
||||
|
||||
void cpuIntegrationExceptionLogging(STR *description, ULO original_pc, UWO opcode)
|
||||
void cpuIntegrationExceptionLogging(char *description, uint32_t original_pc, uint16_t opcode)
|
||||
{
|
||||
if (cpu_disable_instruction_log) return;
|
||||
cpuInstructionLogOpen();
|
||||
|
@ -293,45 +249,20 @@ void cpuIntegrationExceptionLogging(STR *description, ULO original_pc, UWO opcod
|
|||
fprintf(CPUINSTRUCTIONLOG, "%s for opcode %.4X at PC %.8X from PC %.8X\n", description, opcode, original_pc, cpuGetPC());
|
||||
}
|
||||
|
||||
STR *cpuIntegrationGetInterruptName(ULO chip_irq_no)
|
||||
{
|
||||
switch (chip_irq_no)
|
||||
{
|
||||
case 0: return "TBE: Output buffer of the serial port is empty.";
|
||||
case 1: return "DSKBLK: Disk DMA transfer ended.";
|
||||
case 2: return "SOFT: Software interrupt.";
|
||||
case 3: return "PORTS: From CIA-A or expansion port.";
|
||||
case 4: return "COPER: Copper interrupt.";
|
||||
case 5: return "VERTB: Start of vertical blank.";
|
||||
case 6: return "BLIT: Blitter done.";
|
||||
case 7: return "AUD0: Audio data on channel 0.";
|
||||
case 8: return "AUD1: Audio data on channel 1.";
|
||||
case 9: return "AUD2: Audio data on channel 2.";
|
||||
case 10: return "AUD3: Audio data on channel 3.";
|
||||
case 11: return "RBF: Input buffer of the serial port full.";
|
||||
case 12: return "DSKSYN: Disk sync value recognized.";
|
||||
case 13: return "EXTER: From CIA-B or expansion port.";
|
||||
case 14: return "INTEN: BUG! Not an interrupt.";
|
||||
case 15: return "NMI: BUG! Not an interrupt.";
|
||||
}
|
||||
return "Illegal interrupt source!";
|
||||
}
|
||||
|
||||
void cpuIntegrationInterruptLogging(ULO level, ULO vector_address)
|
||||
void cpuIntegrationInterruptLogging(uint32_t level, uint32_t vector_address)
|
||||
{
|
||||
if (cpu_disable_instruction_log) return;
|
||||
cpuInstructionLogOpen();
|
||||
|
||||
cpuIntegrationPrintBusCycle();
|
||||
fprintf(CPUINSTRUCTIONLOG, "Irq %d to %.6X (%s)\n", level, vector_address, cpuIntegrationGetInterruptName(cpuIntegrationGetIrqSource()));
|
||||
fprintf(CPUINSTRUCTIONLOG, "Irq %u to %.6X (%s)\n", level, vector_address, interruptGetInterruptName(cpuIntegrationGetChipInterruptNumber()));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void cpuIntegrationExecuteInstructionEventHandler68000Fast(void)
|
||||
{
|
||||
ULO cycles;
|
||||
cycles = cpuExecuteInstruction();
|
||||
uint32_t cycles = cpuExecuteInstruction();
|
||||
|
||||
if (cpuGetStop())
|
||||
{
|
||||
|
@ -346,8 +277,8 @@ void cpuIntegrationExecuteInstructionEventHandler68000Fast(void)
|
|||
|
||||
void cpuIntegrationExecuteInstructionEventHandler68000General(void)
|
||||
{
|
||||
ULO cycles = 0;
|
||||
ULO time_used = 0;
|
||||
uint32_t cycles = 0;
|
||||
uint32_t time_used = 0;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -370,7 +301,7 @@ void cpuIntegrationExecuteInstructionEventHandler68000General(void)
|
|||
|
||||
void cpuIntegrationExecuteInstructionEventHandler68020(void)
|
||||
{
|
||||
ULO time_used = 0;
|
||||
uint32_t time_used = 0;
|
||||
do
|
||||
{
|
||||
cpuExecuteInstruction();
|
||||
|
@ -396,7 +327,7 @@ void cpuIntegrationSetDefaultConfig(void)
|
|||
cpuIntegrationSetChipSlowdown(1);
|
||||
cpuIntegrationSetSpeed(4);
|
||||
|
||||
cpuSetCheckPendingInterruptsFunc(cpuIntegrationCheckPendingInterruptsFunc);
|
||||
cpuSetCheckPendingInterruptsFunc(interruptRaisePending);
|
||||
cpuSetMidInstructionExceptionFunc(cpuIntegrationMidInstructionExceptionFunc);
|
||||
cpuSetResetExceptionFunc(cpuIntegrationResetExceptionFunc);
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#ifndef CpuIntegration_H
|
||||
#define CpuIntegration_H
|
||||
|
||||
#include <setjmp.h>
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -16,25 +13,25 @@ typedef enum {
|
|||
M68EC20 = 9
|
||||
} cpu_integration_models;
|
||||
|
||||
extern void cpuIntegrationSetUpInterruptEventHandler(void);
|
||||
extern void cpuIntegrationCalculateMultiplier(void);
|
||||
|
||||
extern void cpuIntegrationExecuteInstructionEventHandler68000Fast(void);
|
||||
extern void cpuIntegrationExecuteInstructionEventHandler68000General(void);
|
||||
extern void cpuIntegrationExecuteInstructionEventHandler68020(void);
|
||||
extern void cpuIntegrationCheckPendingInterrupts(void);
|
||||
extern ULO cpuIntegrationDisOpcode(ULO disasm_pc, STR *saddress, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern uint32_t cpuIntegrationDisOpcode(uint32_t disasm_pc, char *saddress, char *sdata, char *sinstruction, char *soperands);
|
||||
|
||||
extern BOOLE cpuIntegrationSetModel(cpu_integration_models model);
|
||||
extern cpu_integration_models cpuIntegrationGetModel(void);
|
||||
extern ULO cpuIntegrationGetModelMajor(void);
|
||||
extern ULO cpuIntegrationGetPC(void);
|
||||
extern uint32_t cpuIntegrationGetModelMajor(void);
|
||||
|
||||
extern ULO cpuIntegrationGetInstructionTime(void);
|
||||
extern void cpuIntegrationSetSpeed(ULO speed);
|
||||
extern ULO cpuIntegrationGetSpeed(void);
|
||||
extern void cpuIntegrationSetChipCycles(ULO chip_cycles);
|
||||
extern ULO cpuIntegrationGetChipCycles(void);
|
||||
extern void cpuIntegrationSetChipSlowdown(ULO chip_slowdown);
|
||||
extern ULO cpuIntegrationGetChipSlowdown(void);
|
||||
void cpuIntegrationSetIrqLevel(uint32_t new_interrupt_level, uint32_t chip_interrupt_number);
|
||||
extern uint32_t cpuIntegrationGetInstructionTime(void);
|
||||
extern void cpuIntegrationSetSpeed(uint32_t speed);
|
||||
extern uint32_t cpuIntegrationGetSpeed(void);
|
||||
extern void cpuIntegrationSetChipCycles(uint32_t chip_cycles);
|
||||
extern uint32_t cpuIntegrationGetChipCycles(void);
|
||||
extern void cpuIntegrationSetChipSlowdown(uint32_t chip_slowdown);
|
||||
extern uint32_t cpuIntegrationGetChipSlowdown(void);
|
||||
|
||||
extern jmp_buf cpu_integration_exception_buffer;
|
||||
|
||||
|
@ -50,5 +47,3 @@ extern void cpuIntegrationShutdown(void);
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* @(#) $Id: CpuModule.c,v 1.7 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* Initialization of 68000 core */
|
||||
|
@ -24,16 +23,13 @@
|
|||
|
||||
#include "defs.h"
|
||||
#include "CpuModule.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
#include "CpuModule_Memory.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
void cpuClearEverything(void)
|
||||
{
|
||||
ULO i,j;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
for (i = 0; i < 8; i++)
|
||||
for (uint32_t j = 0; j < 2; j++)
|
||||
for (uint32_t i = 0; i < 8; i++)
|
||||
cpuSetReg(j, i, 0);
|
||||
|
||||
cpuSetUspDirect(0);
|
||||
|
@ -48,7 +44,6 @@ void cpuClearEverything(void)
|
|||
cpuSetSfc(0);
|
||||
cpuSetDfc(0);
|
||||
cpuSetIrqLevel(0);
|
||||
cpuSetIrqAddress(0);
|
||||
cpuSetStop(FALSE);
|
||||
cpuSetInstructionTime(0);
|
||||
cpuSetOriginalPC(0);
|
||||
|
|
|
@ -1,86 +1,88 @@
|
|||
#ifndef CpuModule_H
|
||||
#define CpuModule_H
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// This header file defines the internal interfaces of the CPU module.
|
||||
|
||||
// MPW additions.
|
||||
typedef void (*cpuLineExceptionFunc)(uint16_t);
|
||||
extern void cpuSetALineExceptionFunc(cpuLineExceptionFunc func);
|
||||
extern void cpuSetFLineExceptionFunc(cpuLineExceptionFunc func);
|
||||
typedef void (*memoryLoggingFunc)(uint32_t address, int size, int readWrite, uint32_t value);
|
||||
extern void memorySetLoggingFunc(memoryLoggingFunc func);
|
||||
|
||||
// This header file defines the internal interfaces of the CPU module.
|
||||
|
||||
//#define CPU_INSTRUCTION_LOGGING
|
||||
#ifdef _DEBUG
|
||||
#define CPU_INSTRUCTION_LOGGING
|
||||
#endif
|
||||
|
||||
// Function to check if there are any external interrupt sources wanting to issue interrupts
|
||||
typedef BOOLE (*cpuCheckPendingInterruptsFunc)(void);
|
||||
typedef void (*cpuCheckPendingInterruptsFunc)(void);
|
||||
extern void cpuSetCheckPendingInterruptsFunc(cpuCheckPendingInterruptsFunc func);
|
||||
extern void cpuCheckPendingInterrupts(void);
|
||||
extern void cpuSetUpInterrupt(void);
|
||||
extern void cpuInitializeFromNewPC(ULO new_pc);
|
||||
extern void cpuSetUpInterrupt(uint32_t new_interrupt_level);
|
||||
extern void cpuInitializeFromNewPC(uint32_t new_pc);
|
||||
|
||||
// Logging interface
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
typedef void (*cpuInstructionLoggingFunc)(void);
|
||||
extern void cpuSetInstructionLoggingFunc(cpuInstructionLoggingFunc func);
|
||||
typedef void (*cpuExceptionLoggingFunc)(STR *description, ULO original_pc, UWO opcode);
|
||||
typedef void (*cpuExceptionLoggingFunc)(char *description, uint32_t original_pc, uint16_t opcode);
|
||||
extern void cpuSetExceptionLoggingFunc(cpuExceptionLoggingFunc func);
|
||||
typedef void (*cpuInterruptLoggingFunc)(ULO level, ULO vector_address);
|
||||
typedef void (*cpuInterruptLoggingFunc)(uint32_t level, uint32_t vector_address);
|
||||
extern void cpuSetInterruptLoggingFunc(cpuInterruptLoggingFunc func);
|
||||
|
||||
#endif
|
||||
|
||||
// CPU register and control properties
|
||||
extern void cpuSetPC(ULO pc);
|
||||
extern ULO cpuGetPC(void);
|
||||
extern void cpuSetPC(uint32_t pc);
|
||||
extern uint32_t cpuGetPC(void);
|
||||
|
||||
extern void cpuSetReg(ULO da, ULO i, ULO value);
|
||||
extern ULO cpuGetReg(ULO da, ULO i);
|
||||
extern void cpuSetReg(uint32_t da, uint32_t i, uint32_t value);
|
||||
extern uint32_t cpuGetReg(uint32_t da, uint32_t i);
|
||||
|
||||
extern void cpuSetDReg(ULO i, ULO value);
|
||||
extern ULO cpuGetDReg(ULO i);
|
||||
extern void cpuSetDReg(uint32_t i, uint32_t value);
|
||||
extern uint32_t cpuGetDReg(uint32_t i);
|
||||
|
||||
extern void cpuSetAReg(ULO i, ULO value);
|
||||
extern ULO cpuGetAReg(ULO i);
|
||||
extern void cpuSetAReg(uint32_t i, uint32_t value);
|
||||
extern uint32_t cpuGetAReg(uint32_t i);
|
||||
|
||||
extern void cpuSetSR(ULO sr);
|
||||
extern ULO cpuGetSR(void);
|
||||
extern void cpuSetSR(uint32_t sr);
|
||||
extern uint32_t cpuGetSR(void);
|
||||
|
||||
extern void cpuSetUspDirect(ULO usp);
|
||||
extern ULO cpuGetUspDirect(void);
|
||||
extern ULO cpuGetUspAutoMap(void);
|
||||
extern void cpuSetUspDirect(uint32_t usp);
|
||||
extern uint32_t cpuGetUspDirect(void);
|
||||
extern uint32_t cpuGetUspAutoMap(void);
|
||||
|
||||
extern void cpuSetMspDirect(ULO msp);
|
||||
extern ULO cpuGetMspDirect(void);
|
||||
extern void cpuSetMspDirect(uint32_t msp);
|
||||
extern uint32_t cpuGetMspDirect(void);
|
||||
|
||||
extern void cpuSetSspDirect(ULO ssp);
|
||||
extern ULO cpuGetSspDirect(void);
|
||||
extern ULO cpuGetSspAutoMap(void);
|
||||
extern void cpuSetSspDirect(uint32_t ssp);
|
||||
extern uint32_t cpuGetSspDirect(void);
|
||||
extern uint32_t cpuGetSspAutoMap(void);
|
||||
|
||||
extern ULO cpuGetVbr(void);
|
||||
extern uint32_t cpuGetVbr(void);
|
||||
|
||||
extern void cpuSetStop(BOOLE stop);
|
||||
extern BOOLE cpuGetStop(void);
|
||||
|
||||
extern void cpuSetInitialPC(ULO pc);
|
||||
extern ULO cpuGetInitialPC(void);
|
||||
extern void cpuSetInitialPC(uint32_t pc);
|
||||
extern uint32_t cpuGetInitialPC(void);
|
||||
|
||||
extern void cpuSetInitialSP(ULO sp);
|
||||
extern ULO cpuGetInitialSP(void);
|
||||
extern void cpuSetInitialSP(uint32_t sp);
|
||||
extern uint32_t cpuGetInitialSP(void);
|
||||
|
||||
extern ULO cpuGetInstructionTime(void);
|
||||
extern uint32_t cpuGetInstructionTime(void);
|
||||
|
||||
extern void cpuSetIrqLevel(ULO irq_level);
|
||||
extern ULO cpuGetIrqLevel(void);
|
||||
extern BOOLE cpuSetIrqLevel(uint32_t irq_level);
|
||||
extern uint32_t cpuGetIrqLevel(void);
|
||||
|
||||
extern void cpuSetIrqAddress(ULO irq_address);
|
||||
extern ULO cpuGetIrqAddress(void);
|
||||
|
||||
extern ULO cpuExecuteInstruction(void);
|
||||
extern ULO cpuDisOpcode(ULO disasm_pc, STR *saddress, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern uint32_t cpuExecuteInstruction(void);
|
||||
extern uint32_t cpuDisOpcode(uint32_t disasm_pc, char *saddress, char *sdata, char *sinstruction, char *soperands);
|
||||
|
||||
extern void cpuSaveState(FILE *F);
|
||||
extern void cpuLoadState(FILE *F);
|
||||
|
@ -95,12 +97,10 @@ typedef void (*cpuResetExceptionFunc)(void);
|
|||
extern void cpuSetResetExceptionFunc(cpuResetExceptionFunc func);
|
||||
|
||||
// Configuration settings
|
||||
extern void cpuSetModel(ULO major, ULO minor);
|
||||
extern ULO cpuGetModelMajor(void);
|
||||
extern ULO cpuGetModelMinor(void);
|
||||
extern void cpuSetModel(uint32_t major, uint32_t minor);
|
||||
extern uint32_t cpuGetModelMajor(void);
|
||||
extern uint32_t cpuGetModelMinor(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
10646
cpu/CpuModule_Code.h
10646
cpu/CpuModule_Code.h
File diff suppressed because it is too large
Load Diff
2609
cpu/CpuModule_Data.h
2609
cpu/CpuModule_Data.h
File diff suppressed because it is too large
Load Diff
3358
cpu/CpuModule_Decl.h
3358
cpu/CpuModule_Decl.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,105 +1,102 @@
|
|||
#ifndef CPUMODULE_DISASSEMBLER_H
|
||||
#define CPUMODULE_DISASSEMBLER_H
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern ULO cpuDisOpcode(ULO disasm_pc, STR *saddress, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern uint32_t cpuDisOpcode(uint32_t disasm_pc, char *saddress, char *sdata, char *sinstruction, char *soperands);
|
||||
|
||||
extern ULO cpuDisIllegal(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAbcd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAdd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAdda(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAddi(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAddq(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAddx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAnd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAndi(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisAsx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisBcc(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisBt(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisChk(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisClr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCmp(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCmpa(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCmpi(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCmpm(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisDBcc(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisDivs(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisDivu(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisEor(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisEori(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisExg(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisExt(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisJmp(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisJsr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisLea(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisLink(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisLsx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMove(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveToCcr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveToSr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveFromSr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveUsp(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMovea(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMovem(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMovep(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveq(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMuls(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMulu(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNbcd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNeg(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNegx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNop(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisNot(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisOr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisOri(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPea(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisReset(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRox(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRoxx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRte(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRtr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRts(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSbcd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisScc(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisStop(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSub(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSuba(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSubi(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSubq(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSubx(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisSwap(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTas(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTrap(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTrapv(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTst(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisUnlk(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisBkpt(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisBf(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCas(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisChkl(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisChk2(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisDivl(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisExtb(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisLinkl(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoveFromCcr(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMovec(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMoves(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisMull(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPack(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPflush030(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPflush040(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisPtest040(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRtd(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisTrapcc(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisUnpk(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisCallm(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern ULO cpuDisRtm(ULO prc, ULO opc, STR *sdata, STR *sinstruction, STR *soperands);
|
||||
extern uint32_t cpuDisIllegal(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisAbcd(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisAdd(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisAdda(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisAddi(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisAddq(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisAddx(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisAnd(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisAndi(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisAsx(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisBcc(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisBt(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisChk(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisClr(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisCmp(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisCmpa(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisCmpi(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisCmpm(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisDBcc(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisDivs(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisDivu(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisEor(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisEori(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisExg(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisExt(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisJmp(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisJsr(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisLea(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisLink(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisLsx(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMove(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMoveToCcr(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMoveToSr(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMoveFromSr(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMoveUsp(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMovea(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMovem(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMovep(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMoveq(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMuls(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMulu(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisNbcd(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisNeg(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisNegx(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisNop(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisNot(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisOr(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisOri(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisPea(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisReset(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisRox(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisRoxx(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisRte(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisRtr(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisRts(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisSbcd(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisScc(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisStop(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisSub(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisSuba(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisSubi(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisSubq(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisSubx(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisSwap(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisTas(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisTrap(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisTrapv(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisTst(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisUnlk(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisBkpt(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisBf(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisCas(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisChkl(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisChk2(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisDivl(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisExtb(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisLinkl(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMoveFromCcr(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMovec(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMoves(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisMull(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisPack(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisPflush030(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisPflush040(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisPtest040(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisRtd(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisTrapcc(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisUnpk(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisCallm(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
extern uint32_t cpuDisRtm(uint32_t prc, uint32_t opc, char *sdata, char *sinstruction, char *soperands);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef CPUMODULE_DISASSEMBLERFUNC_H
|
||||
#define CPUMODULE_DISASSEMBLERFUNC_H
|
||||
#pragma once
|
||||
|
||||
static UBY cpu_dis_func_tab[65536] =
|
||||
static uint8_t cpu_dis_func_tab[65536] =
|
||||
{
|
||||
60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,
|
||||
60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
|
||||
|
@ -259,7 +258,7 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
|
||||
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
|
||||
11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -267,31 +266,31 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -299,31 +298,31 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -331,23 +330,23 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -355,7 +354,7 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -363,23 +362,23 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -387,7 +386,7 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -395,23 +394,23 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -419,7 +418,7 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -427,23 +426,23 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -451,7 +450,7 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -459,23 +458,23 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -483,7 +482,7 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -491,23 +490,23 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
|
||||
39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,
|
||||
|
@ -4100,4 +4099,3 @@ static UBY cpu_dis_func_tab[65536] =
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* @(#) $Id: CpuModule_EffectiveAddress.c,v 1.3 2012/07/15 22:20:35 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* CPU 68k effective address calculation functions */
|
||||
|
@ -24,29 +23,28 @@
|
|||
/*=========================================================================*/
|
||||
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
#include "CpuModule_Memory.h"
|
||||
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
/* Calculates EA for (Ax). */
|
||||
ULO cpuEA02(ULO regno)
|
||||
uint32_t cpuEA02(uint32_t regno)
|
||||
{
|
||||
return cpuGetAReg(regno);
|
||||
}
|
||||
|
||||
/* Calculates EA for (Ax)+ */
|
||||
ULO cpuEA03(ULO regno, ULO size)
|
||||
uint32_t cpuEA03(uint32_t regno, uint32_t size)
|
||||
{
|
||||
ULO tmp = cpuGetAReg(regno);
|
||||
uint32_t tmp = cpuGetAReg(regno);
|
||||
if (regno == 7 && size == 1) size++;
|
||||
cpuSetAReg(regno, tmp + size);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Calculates EA for -(Ax) */
|
||||
ULO cpuEA04(ULO regno, ULO size)
|
||||
uint32_t cpuEA04(uint32_t regno, uint32_t size)
|
||||
{
|
||||
if (regno == 7 && size == 1) size++;
|
||||
cpuSetAReg(regno, cpuGetAReg(regno) - size);
|
||||
|
@ -54,20 +52,20 @@ ULO cpuEA04(ULO regno, ULO size)
|
|||
}
|
||||
|
||||
/* Calculates EA for disp16(Ax) */
|
||||
ULO cpuEA05(ULO regno)
|
||||
uint32_t cpuEA05(uint32_t regno)
|
||||
{
|
||||
return cpuGetAReg(regno) + cpuGetNextWordSignExt();
|
||||
}
|
||||
|
||||
/* Calculates EA for disp8(Ax,Ri.size) with 68020 extended modes. */
|
||||
static ULO cpuEA06Ext(UWO ext, ULO base_reg_value, ULO index_value)
|
||||
static uint32_t cpuEA06Ext(uint16_t ext, uint32_t base_reg_value, uint32_t index_value)
|
||||
{
|
||||
ULO base_displacement;
|
||||
ULO outer_displacement;
|
||||
uint32_t base_displacement;
|
||||
uint32_t outer_displacement;
|
||||
BOOLE index_register_suppressed = (ext & 0x0040);
|
||||
BOOLE base_register_suppressed = (ext & 0x0080);
|
||||
ULO base_displacement_size = (ext >> 4) & 3;
|
||||
ULO memory_indirect_action = (ext & 7);
|
||||
uint32_t base_displacement_size = (ext >> 4) & 3;
|
||||
uint32_t memory_indirect_action = (ext & 7);
|
||||
|
||||
if (memory_indirect_action == 4
|
||||
|| (memory_indirect_action > 4 && index_register_suppressed))
|
||||
|
@ -127,14 +125,14 @@ static ULO cpuEA06Ext(UWO ext, ULO base_reg_value, ULO index_value)
|
|||
}
|
||||
|
||||
/* Calculates EA for disp8(Ax,Ri.size), calls cpuEA06Ext() for 68020 extended modes. */
|
||||
ULO cpuEA06(ULO regno)
|
||||
uint32_t cpuEA06(uint32_t regno)
|
||||
{
|
||||
ULO reg_value = cpuGetAReg(regno);
|
||||
UWO ext = cpuGetNextWord();
|
||||
ULO index_value = cpuGetReg(ext >> 15, (ext >> 12) & 7);
|
||||
uint32_t reg_value = cpuGetAReg(regno);
|
||||
uint16_t ext = cpuGetNextWord();
|
||||
uint32_t index_value = cpuGetReg(ext >> 15, (ext >> 12) & 7);
|
||||
if (!(ext & 0x0800))
|
||||
{
|
||||
index_value = cpuSignExtWordToLong((UWO)index_value);
|
||||
index_value = cpuSignExtWordToLong((uint16_t)index_value);
|
||||
}
|
||||
if (cpuGetModelMajor() >= 2)
|
||||
{
|
||||
|
@ -144,17 +142,17 @@ ULO cpuEA06(ULO regno)
|
|||
return cpuEA06Ext(ext, reg_value, index_value);
|
||||
}
|
||||
}
|
||||
return reg_value + index_value + cpuSignExtByteToLong((UBY)ext);
|
||||
return reg_value + index_value + cpuSignExtByteToLong((uint8_t)ext);
|
||||
}
|
||||
|
||||
/* Calculates EA for xxxx.W */
|
||||
ULO cpuEA70(void)
|
||||
uint32_t cpuEA70()
|
||||
{
|
||||
return cpuGetNextWordSignExt();
|
||||
}
|
||||
|
||||
/* Calculates EA for xxxxxxxx.L */
|
||||
ULO cpuEA71(void)
|
||||
uint32_t cpuEA71()
|
||||
{
|
||||
return cpuGetNextLong();
|
||||
}
|
||||
|
@ -163,9 +161,9 @@ ULO cpuEA71(void)
|
|||
/// Calculates EA for disp16(PC)
|
||||
/// </summary>
|
||||
/// <returns>Address</returns>
|
||||
ULO cpuEA72(void)
|
||||
uint32_t cpuEA72()
|
||||
{
|
||||
ULO pc_tmp = cpuGetPC();
|
||||
uint32_t pc_tmp = cpuGetPC();
|
||||
return pc_tmp + cpuGetNextWordSignExt();
|
||||
}
|
||||
|
||||
|
@ -173,14 +171,14 @@ ULO cpuEA72(void)
|
|||
/// Calculates EA for disp8(PC,Ri.size). Calls cpuEA06Ext() to calculate extended 68020 modes.
|
||||
/// </summary>
|
||||
/// <returns>Address</returns>
|
||||
ULO cpuEA73(void)
|
||||
uint32_t cpuEA73()
|
||||
{
|
||||
ULO reg_value = cpuGetPC();
|
||||
UWO ext = cpuGetNextWord();
|
||||
ULO index_value = cpuGetReg(ext >> 15, (ext >> 12) & 0x7);
|
||||
uint32_t reg_value = cpuGetPC();
|
||||
uint16_t ext = cpuGetNextWord();
|
||||
uint32_t index_value = cpuGetReg(ext >> 15, (ext >> 12) & 0x7);
|
||||
if (!(ext & 0x0800))
|
||||
{
|
||||
index_value = cpuSignExtWordToLong((UWO)index_value);
|
||||
index_value = cpuSignExtWordToLong((uint16_t)index_value);
|
||||
}
|
||||
if (cpuGetModelMajor() >= 2)
|
||||
{
|
||||
|
@ -190,5 +188,5 @@ ULO cpuEA73(void)
|
|||
return cpuEA06Ext(ext, reg_value, index_value);
|
||||
}
|
||||
}
|
||||
return reg_value + index_value + cpuSignExtByteToLong((UBY)ext);
|
||||
return reg_value + index_value + cpuSignExtByteToLong((uint8_t)ext);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* @(#) $Id: CpuModule_Exceptions.c,v 1.5 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* CPU 68k exception handling functions */
|
||||
|
@ -24,12 +23,27 @@
|
|||
/*=========================================================================*/
|
||||
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
#include "CpuModule_Memory.h"
|
||||
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
|
||||
// MPW
|
||||
static cpuLineExceptionFunc cpu_a_line_exception_func = NULL;
|
||||
static cpuLineExceptionFunc cpu_f_line_exception_func = NULL;
|
||||
|
||||
void cpuSetALineExceptionFunc(cpuLineExceptionFunc func)
|
||||
{
|
||||
cpu_a_line_exception_func = func;
|
||||
}
|
||||
|
||||
void cpuSetFLineExceptionFunc(cpuLineExceptionFunc func)
|
||||
{
|
||||
cpu_f_line_exception_func = func;
|
||||
}
|
||||
|
||||
|
||||
/* Function for exiting from mid-instruction exceptions */
|
||||
static cpuMidInstructionExceptionFunc cpu_mid_instruction_exception_func;
|
||||
|
||||
|
@ -56,12 +70,12 @@ void cpuSetResetExceptionFunc(cpuResetExceptionFunc func)
|
|||
cpu_reset_exception_func = func;
|
||||
}
|
||||
|
||||
static STR *cpuGetExceptionName(ULO vector_offset)
|
||||
static char *cpuGetExceptionName(uint32_t vector_offset)
|
||||
{
|
||||
char *name;
|
||||
|
||||
if (vector_offset == 0x8)
|
||||
name = "Exception: 2 - Access fault";
|
||||
name = "Exception: 2 - Bus error";
|
||||
else if (vector_offset == 0xc)
|
||||
name = "Exception: 3 - Address error";
|
||||
else if (vector_offset == 0x10)
|
||||
|
@ -94,26 +108,54 @@ static STR *cpuGetExceptionName(ULO vector_offset)
|
|||
Sets up an exception
|
||||
===============================================*/
|
||||
|
||||
void cpuThrowException(ULO vector_offset, ULO pc, BOOLE executejmp)
|
||||
void cpuExceptionFail(BOOLE executejmp)
|
||||
{
|
||||
ULO vector_address;
|
||||
// Avoid endless loop that will crash the emulator.
|
||||
// The (odd) address error exception vector contained an odd address.
|
||||
cpuCallResetExceptionFunc();
|
||||
cpuHardReset();
|
||||
cpuSetInstructionTime(132);
|
||||
if (executejmp)
|
||||
{
|
||||
cpuCallMidInstructionExceptionFunc(); // Supposed to be doing setjmp/longjmp back to machine emulator code
|
||||
}
|
||||
}
|
||||
|
||||
void cpuThrowException(uint32_t vector_offset, uint32_t pc, BOOLE executejmp)
|
||||
{
|
||||
uint32_t vector_address;
|
||||
BOOLE is_address_error_on_sub_020 = (cpuGetModelMajor() < 2 && vector_offset == 0xc);
|
||||
BOOLE stack_is_even = !(cpuGetAReg(7) & 1);
|
||||
BOOLE vbr_is_even = !(cpuGetVbr() & 1);
|
||||
|
||||
if ((is_address_error_on_sub_020 && !stack_is_even) || !vbr_is_even)
|
||||
{
|
||||
cpuExceptionFail(executejmp);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
cpuCallExceptionLoggingFunc(cpuGetExceptionName(vector_offset), cpuGetOriginalPC(), cpuGetCurrentOpcode());
|
||||
#endif
|
||||
|
||||
cpuActivateSSP();
|
||||
cpuStackFrameGenerate((UWO) vector_offset, pc);
|
||||
cpuActivateSSP();
|
||||
|
||||
stack_is_even = !(cpuGetAReg(7) & 1);
|
||||
|
||||
if (is_address_error_on_sub_020 && !stack_is_even)
|
||||
{
|
||||
cpuExceptionFail(executejmp);
|
||||
return;
|
||||
}
|
||||
|
||||
cpuStackFrameGenerate((uint16_t) vector_offset, pc);
|
||||
|
||||
// read a memory position
|
||||
vector_address = memoryReadLong(cpuGetVbr() + vector_offset);
|
||||
if (cpuGetModelMajor() < 2 && vector_address & 0x1 && vector_offset == 0xc)
|
||||
if (is_address_error_on_sub_020 && vector_address & 1)
|
||||
{
|
||||
// Avoid endless loop that will crash the emulator.
|
||||
// The (odd) address error exception vector contained an odd address.
|
||||
cpuCallResetExceptionFunc();
|
||||
cpuHardReset();
|
||||
cpuSetInstructionTime(132);
|
||||
cpuExceptionFail(executejmp);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -125,7 +167,40 @@ void cpuThrowException(ULO vector_offset, ULO pc, BOOLE executejmp)
|
|||
cpuSetStop(FALSE);
|
||||
|
||||
cpuInitializeFromNewPC(vector_address);
|
||||
cpuSetInstructionTime(40);
|
||||
|
||||
uint32_t exceptionCycles = 0;
|
||||
|
||||
switch (vector_offset)
|
||||
{
|
||||
case 0x08: exceptionCycles = 50; break; // Bus
|
||||
case 0x0c: exceptionCycles = 50; break; // Address
|
||||
case 0x10: exceptionCycles = 34; break; // Illegal
|
||||
case 0x14: exceptionCycles = 42; break; // Division by zero
|
||||
case 0x18: exceptionCycles = 28; break; // Chk
|
||||
case 0x1c: exceptionCycles = 34; break; // Trapcc/trapv
|
||||
case 0x20: exceptionCycles = 34; break; // Privilege
|
||||
case 0x24: exceptionCycles = 34; break; // Trace
|
||||
case 0x28: exceptionCycles = 34; break; // Line A
|
||||
case 0x2c: exceptionCycles = 34; break; // Line F
|
||||
case 0x80:
|
||||
case 0x84:
|
||||
case 0x88:
|
||||
case 0x8c:
|
||||
case 0x90:
|
||||
case 0x94:
|
||||
case 0x98:
|
||||
case 0x9c:
|
||||
case 0xa0:
|
||||
case 0xa4:
|
||||
case 0xa8:
|
||||
case 0xac:
|
||||
case 0xb0:
|
||||
case 0xb4:
|
||||
case 0xb8:
|
||||
case 0xbc: exceptionCycles = 34; break; // TRAP
|
||||
default: exceptionCycles = 4; break; // Should not come here
|
||||
}
|
||||
cpuSetInstructionTime(exceptionCycles);
|
||||
}
|
||||
|
||||
// If the exception happened mid-instruction...
|
||||
|
@ -137,6 +212,7 @@ void cpuThrowException(ULO vector_offset, ULO pc, BOOLE executejmp)
|
|||
|
||||
void cpuThrowPrivilegeViolationException(void)
|
||||
{
|
||||
cpuSetInstructionAborted(true);
|
||||
// The saved pc points to the instruction causing the violation
|
||||
// (And the kickstart excpects pc in the stack frame to be the opcode PC.)
|
||||
cpuThrowException(0x20, cpuGetOriginalPC(), FALSE);
|
||||
|
@ -144,18 +220,48 @@ void cpuThrowPrivilegeViolationException(void)
|
|||
|
||||
void cpuThrowIllegalInstructionException(BOOLE executejmp)
|
||||
{
|
||||
cpuSetInstructionAborted(true);
|
||||
// The saved pc points to the illegal instruction
|
||||
cpuThrowException(0x10, cpuGetOriginalPC(), executejmp);
|
||||
}
|
||||
|
||||
void cpuThrowIllegalInstructionExceptionFromBreakpoint(void)
|
||||
{
|
||||
cpuSetInstructionAborted(true);
|
||||
// The saved pc points to the illegal instruction
|
||||
cpuThrowException(0x10, cpuGetPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowALineException(void)
|
||||
{
|
||||
// MPW
|
||||
if (cpu_a_line_exception_func)
|
||||
{
|
||||
uint16_t opcode = memoryReadWord(cpuGetPC() - 2);
|
||||
cpu_a_line_exception_func(opcode);
|
||||
cpuInitializeFromNewPC(cpuGetPC());
|
||||
cpuSetInstructionTime(512);
|
||||
return;
|
||||
}
|
||||
|
||||
cpuSetInstructionAborted(true);
|
||||
// The saved pc points to the a-line instruction
|
||||
cpuThrowException(0x28, cpuGetOriginalPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowFLineException(void)
|
||||
{
|
||||
// MPW
|
||||
if (cpu_f_line_exception_func)
|
||||
{
|
||||
uint16_t opcode = memoryReadWord(cpuGetPC() - 2);
|
||||
cpu_f_line_exception_func(opcode);
|
||||
cpuInitializeFromNewPC(cpuGetPC());
|
||||
cpuSetInstructionTime(512);
|
||||
return;
|
||||
}
|
||||
|
||||
cpuSetInstructionAborted(true);
|
||||
// The saved pc points to the f-line instruction
|
||||
cpuThrowException(0x2c, cpuGetOriginalPC(), FALSE);
|
||||
}
|
||||
|
@ -166,13 +272,13 @@ void cpuThrowTrapVException(void)
|
|||
cpuThrowException(0x1c, cpuGetPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowDivisionByZeroException(BOOLE executejmp)
|
||||
void cpuThrowDivisionByZeroException(void)
|
||||
{
|
||||
// The saved pc points to the next instruction, which is now in pc
|
||||
cpuThrowException(0x14, cpuGetPC(), executejmp);
|
||||
cpuThrowException(0x14, cpuGetPC(), FALSE);
|
||||
}
|
||||
|
||||
void cpuThrowTrapException(ULO vector_no)
|
||||
void cpuThrowTrapException(uint32_t vector_no)
|
||||
{
|
||||
// The saved pc points to the next instruction, which is now in pc
|
||||
cpuThrowException(0x80 + vector_no*4, cpuGetPC(), FALSE);
|
||||
|
@ -192,7 +298,8 @@ void cpuThrowTraceException(void)
|
|||
|
||||
void cpuThrowAddressErrorException(void)
|
||||
{
|
||||
cpuThrowException(0xc, cpuGetPC(), TRUE);
|
||||
cpuSetInstructionAborted(true);
|
||||
cpuThrowException(0xc, cpuGetPC() - 2, TRUE);
|
||||
}
|
||||
|
||||
/*=================*/
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* @(#) $Id: CpuModule_Flags.c,v 1.3 2011/07/18 17:22:55 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* 68000 flag and condition code handling */
|
||||
|
@ -22,29 +21,28 @@
|
|||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
|
||||
/// Sets the Z flag for bit operations
|
||||
void cpuSetZFlagBitOpsB(UBY res)
|
||||
void cpuSetZFlagBitOpsB(uint8_t res)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfffb;
|
||||
uint32_t flags = cpu_sr & 0xfffb;
|
||||
if (res == 0) flags |= 4;
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
/// Sets the Z flag for bit operations
|
||||
void cpuSetZFlagBitOpsL(ULO res)
|
||||
void cpuSetZFlagBitOpsL(uint32_t res)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfffb;
|
||||
uint32_t flags = cpu_sr & 0xfffb;
|
||||
if (res == 0) flags |= 4;
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
||||
// rm,dm,sm
|
||||
ULO cpu_xnvc_flag_add_table[2][2][2] = { 0,0x11,0x11,0x13,0xa,8,8,0x19};
|
||||
uint32_t cpu_xnvc_flag_add_table[2][2][2] = { 0,0x11,0x11,0x13,0xa,8,8,0x19};
|
||||
|
||||
/// <summary>
|
||||
/// Calculate XNVC flags of an add operation.
|
||||
|
@ -52,13 +50,13 @@ ULO cpu_xnvc_flag_add_table[2][2][2] = { 0,0x11,0x11,0x13,0xa,8,8,0x19};
|
|||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
static ULO cpuMakeFlagXNVCAdd(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
static uint32_t cpuMakeFlagXNVCAdd(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
return cpu_xnvc_flag_add_table[rm][dm][sm];
|
||||
}
|
||||
|
||||
// rm,dm,sm
|
||||
ULO cpu_nvc_flag_add_table[2][2][2] = { 0,1,1,3,0xa,8,8,9};
|
||||
uint32_t cpu_nvc_flag_add_table[2][2][2] = { 0,1,1,3,0xa,8,8,9};
|
||||
|
||||
/// <summary>
|
||||
/// Calculate NVC flags of an add operation for instructions not setting X.
|
||||
|
@ -66,13 +64,13 @@ ULO cpu_nvc_flag_add_table[2][2][2] = { 0,1,1,3,0xa,8,8,9};
|
|||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
static ULO cpuMakeFlagNVCAdd(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
static uint32_t cpuMakeFlagNVCAdd(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
return cpu_nvc_flag_add_table[rm][dm][sm];
|
||||
}
|
||||
|
||||
// rm,dm,sm
|
||||
ULO cpu_xnvc_flag_sub_table[2][2][2] = { 0,0x11,2,0,0x19,0x1b,8,0x19};
|
||||
uint32_t cpu_xnvc_flag_sub_table[2][2][2] = { 0,0x11,2,0,0x19,0x1b,8,0x19};
|
||||
|
||||
/// <summary>
|
||||
/// Calculate XNVC flags of a sub operation.
|
||||
|
@ -80,13 +78,13 @@ ULO cpu_xnvc_flag_sub_table[2][2][2] = { 0,0x11,2,0,0x19,0x1b,8,0x19};
|
|||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
static ULO cpuMakeFlagXNVCSub(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
static uint32_t cpuMakeFlagXNVCSub(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
return cpu_xnvc_flag_sub_table[rm][dm][sm];
|
||||
}
|
||||
|
||||
// rm,dm,sm
|
||||
ULO cpu_nvc_flag_sub_table[2][2][2] = { 0,1,2,0,9,0xb,8,9};
|
||||
uint32_t cpu_nvc_flag_sub_table[2][2][2] = { 0,1,2,0,9,0xb,8,9};
|
||||
|
||||
/// <summary>
|
||||
/// Calculate NVC flags of a sub operation for instructions not setting X.
|
||||
|
@ -94,7 +92,7 @@ ULO cpu_nvc_flag_sub_table[2][2][2] = { 0,1,2,0,9,0xb,8,9};
|
|||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
/// <param name="sm">The MSB of the source.</param>
|
||||
static ULO cpuMakeFlagNVCSub(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
static uint32_t cpuMakeFlagNVCSub(BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
return cpu_nvc_flag_sub_table[rm][dm][sm];
|
||||
}
|
||||
|
@ -126,14 +124,6 @@ void cpuSetFlagV(BOOLE f)
|
|||
cpu_sr = (cpu_sr & 0xfffd) | ((f) ? 2 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the V flag.
|
||||
/// </summary>
|
||||
static void cpuClearFlagV(void)
|
||||
{
|
||||
cpu_sr = cpu_sr & 0xfffd;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the V flag.
|
||||
/// </summary>
|
||||
|
@ -160,22 +150,6 @@ void cpuSetFlagZ(BOOLE f)
|
|||
cpu_sr = (cpu_sr & 0xfffb) | ((f) ? 4 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the Z flag.
|
||||
/// </summary>
|
||||
static void cpuClearFlagZ(void)
|
||||
{
|
||||
cpu_sr = cpu_sr & 0xfffb;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Z flag.
|
||||
/// </summary>
|
||||
static BOOLE cpuGetFlagZ(void)
|
||||
{
|
||||
return cpu_sr & 0x4;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the X flag.
|
||||
/// </summary>
|
||||
|
@ -195,18 +169,18 @@ void cpuSetFlags0100(void)
|
|||
/// <summary>
|
||||
/// Clear V and C.
|
||||
/// </summary>
|
||||
static void cpuClearFlagsVC(void)
|
||||
void cpuClearFlagsVC(void)
|
||||
{
|
||||
cpu_sr = cpu_sr & 0xfffc;
|
||||
}
|
||||
|
||||
UWO cpuGetZFlagB(UBY res) {return (UWO)((res) ? 0 : 4);}
|
||||
UWO cpuGetZFlagW(UWO res) {return (UWO)((res) ? 0 : 4);}
|
||||
UWO cpuGetZFlagL(ULO res) {return (UWO)((res) ? 0 : 4);}
|
||||
uint16_t cpuGetZFlagB(uint8_t res) {return (uint16_t)((res) ? 0 : 4);}
|
||||
uint16_t cpuGetZFlagW(uint16_t res) {return (uint16_t)((res) ? 0 : 4);}
|
||||
uint16_t cpuGetZFlagL(uint32_t res) {return (uint16_t)((res) ? 0 : 4);}
|
||||
|
||||
UWO cpuGetNFlagB(UBY res) {return (UWO)((res & 0x80) >> 4);}
|
||||
UWO cpuGetNFlagW(UWO res) {return (UWO)((res & 0x8000) >> 12);}
|
||||
UWO cpuGetNFlagL(ULO res) {return (UWO)((res & 0x80000000) >> 28);}
|
||||
uint16_t cpuGetNFlagB(uint8_t res) {return (uint16_t)((res & 0x80) >> 4);}
|
||||
uint16_t cpuGetNFlagW(uint16_t res) {return (uint16_t)((res & 0x8000) >> 12);}
|
||||
uint16_t cpuGetNFlagL(uint32_t res) {return (uint16_t)((res & 0x80000000) >> 28);}
|
||||
|
||||
/// <summary>
|
||||
/// Set the flags NZVC.
|
||||
|
@ -217,7 +191,7 @@ UWO cpuGetNFlagL(ULO res) {return (UWO)((res & 0x80000000) >> 28);}
|
|||
/// <param name="c">The C flag.</param>
|
||||
void cpuSetFlagsNZVC(BOOLE z, BOOLE n, BOOLE v, BOOLE c)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfff0;
|
||||
uint32_t flags = cpu_sr & 0xfff0;
|
||||
if (n) flags |= 8;
|
||||
else if (z) flags |= 4;
|
||||
if (v) flags |= 2;
|
||||
|
@ -232,7 +206,7 @@ void cpuSetFlagsNZVC(BOOLE z, BOOLE n, BOOLE v, BOOLE c)
|
|||
/// <param name="c">The C flag.</param>
|
||||
void cpuSetFlagsVC(BOOLE v, BOOLE c)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfffc;
|
||||
uint32_t flags = cpu_sr & 0xfffc;
|
||||
if (v) flags |= 2;
|
||||
if (c) flags |= 1;
|
||||
cpu_sr = flags;
|
||||
|
@ -247,7 +221,7 @@ void cpuSetFlagsVC(BOOLE v, BOOLE c)
|
|||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsAdd(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xffe0;
|
||||
uint32_t flags = cpu_sr & 0xffe0;
|
||||
if (z) flags |= 4;
|
||||
flags |= cpuMakeFlagXNVCAdd(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
|
@ -262,7 +236,7 @@ void cpuSetFlagsAdd(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
|||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsSub(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xffe0;
|
||||
uint32_t flags = cpu_sr & 0xffe0;
|
||||
if (z) flags |= 4;
|
||||
flags |= cpuMakeFlagXNVCSub(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
|
@ -277,7 +251,7 @@ void cpuSetFlagsSub(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
|||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsAddX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & ((z) ? 0xffe4 : 0xffe0); // Clear z if result is non-zero
|
||||
uint32_t flags = cpu_sr & ((z) ? 0xffe4 : 0xffe0); // Clear z if result is non-zero
|
||||
flags |= cpuMakeFlagXNVCAdd(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
@ -291,7 +265,7 @@ void cpuSetFlagsAddX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
|||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsSubX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & ((z) ? 0xffe4 : 0xffe0); // Clear z if result is non-zero
|
||||
uint32_t flags = cpu_sr & ((z) ? 0xffe4 : 0xffe0); // Clear z if result is non-zero
|
||||
flags |= cpuMakeFlagXNVCSub(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
}
|
||||
|
@ -304,7 +278,7 @@ void cpuSetFlagsSubX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
|||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
void cpuSetFlagsNeg(BOOLE z, BOOLE rm, BOOLE dm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xffe0;
|
||||
uint32_t flags = cpu_sr & 0xffe0;
|
||||
if (z) flags |= 4;
|
||||
else
|
||||
{
|
||||
|
@ -326,7 +300,7 @@ void cpuSetFlagsNeg(BOOLE z, BOOLE rm, BOOLE dm)
|
|||
/// <param name="dm">The MSB of the destination source.</param>
|
||||
void cpuSetFlagsNegx(BOOLE z, BOOLE rm, BOOLE dm)
|
||||
{
|
||||
ULO flags = cpu_sr & ((z) ? 0xffe4 : 0xffe0); // Clear z if result is non-zero
|
||||
uint32_t flags = cpu_sr & ((z) ? 0xffe4 : 0xffe0); // Clear z if result is non-zero
|
||||
if (dm || rm)
|
||||
{
|
||||
flags |= 0x11; // XC
|
||||
|
@ -348,7 +322,7 @@ void cpuSetFlagsNegx(BOOLE z, BOOLE rm, BOOLE dm)
|
|||
/// <param name="sm">The MSB of the source.</param>
|
||||
void cpuSetFlagsCmp(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfff0;
|
||||
uint32_t flags = cpu_sr & 0xfff0;
|
||||
if (z) flags |= 4;
|
||||
flags |= cpuMakeFlagNVCSub(rm, dm, sm);
|
||||
cpu_sr = flags;
|
||||
|
@ -361,7 +335,7 @@ void cpuSetFlagsCmp(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm)
|
|||
/// <param name="rm">The MSB of the result.</param>
|
||||
void cpuSetFlagsShiftZero(BOOLE z, BOOLE rm)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfff0; // Always clearing the VC flag
|
||||
uint32_t flags = cpu_sr & 0xfff0; // Always clearing the VC flag
|
||||
if (rm) flags |= 8;
|
||||
else if (z) flags |= 4;
|
||||
cpu_sr = flags;
|
||||
|
@ -376,7 +350,7 @@ void cpuSetFlagsShiftZero(BOOLE z, BOOLE rm)
|
|||
/// <param name="c">The overflow of the result.</param>
|
||||
void cpuSetFlagsShift(BOOLE z, BOOLE rm, BOOLE c, BOOLE v)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xffe0;
|
||||
uint32_t flags = cpu_sr & 0xffe0;
|
||||
if (rm) flags |= 8;
|
||||
else if (z) flags |= 4;
|
||||
if (v) flags |= 2;
|
||||
|
@ -392,7 +366,7 @@ void cpuSetFlagsShift(BOOLE z, BOOLE rm, BOOLE c, BOOLE v)
|
|||
/// <param name="c">The carry of the result.</param>
|
||||
void cpuSetFlagsRotate(BOOLE z, BOOLE rm, BOOLE c)
|
||||
{
|
||||
ULO flags = cpu_sr & 0xfff0; // Always clearing the V flag
|
||||
uint32_t flags = cpu_sr & 0xfff0; // Always clearing the V flag
|
||||
|
||||
if (rm) flags |= 8;
|
||||
else if (z) flags |= 4;
|
||||
|
@ -407,7 +381,7 @@ void cpuSetFlagsRotate(BOOLE z, BOOLE rm, BOOLE c)
|
|||
/// <param name="z">The Z flag.</param>
|
||||
/// <param name="rm">The MSB of the result.</param>
|
||||
/// <param name="c">The extend bit and carry of the result.</param>
|
||||
void cpuSetFlagsRotateX(UWO z, UWO rm, UWO x)
|
||||
void cpuSetFlagsRotateX(uint16_t z, uint16_t rm, uint16_t x)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xffe0) | z | rm | x;
|
||||
}
|
||||
|
@ -415,9 +389,9 @@ void cpuSetFlagsRotateX(UWO z, UWO rm, UWO x)
|
|||
/// <summary>
|
||||
/// Set the flags (ZN00).
|
||||
/// </summary>
|
||||
void cpuSetFlagsNZ00NewB(UBY res)
|
||||
void cpuSetFlagsNZ00NewB(uint8_t res)
|
||||
{
|
||||
ULO flag = cpu_sr & 0xfff0;
|
||||
uint32_t flag = cpu_sr & 0xfff0;
|
||||
if (res & 0x80) flag |= 0x8;
|
||||
else if (res == 0) flag |= 0x4;
|
||||
cpu_sr = flag;
|
||||
|
@ -426,9 +400,9 @@ void cpuSetFlagsNZ00NewB(UBY res)
|
|||
/// <summary>
|
||||
/// Set the flags (ZN00).
|
||||
/// </summary>
|
||||
void cpuSetFlagsNZ00NewW(UWO res)
|
||||
void cpuSetFlagsNZ00NewW(uint16_t res)
|
||||
{
|
||||
ULO flag = cpu_sr & 0xfff0;
|
||||
uint32_t flag = cpu_sr & 0xfff0;
|
||||
if (res & 0x8000) flag |= 0x8;
|
||||
else if (res == 0) flag |= 0x4;
|
||||
cpu_sr = flag;
|
||||
|
@ -437,9 +411,9 @@ void cpuSetFlagsNZ00NewW(UWO res)
|
|||
/// <summary>
|
||||
/// Set the flags (ZN00).
|
||||
/// </summary>
|
||||
void cpuSetFlagsNZ00NewL(ULO res)
|
||||
void cpuSetFlagsNZ00NewL(uint32_t res)
|
||||
{
|
||||
ULO flag = cpu_sr & 0xfff0;
|
||||
uint32_t flag = cpu_sr & 0xfff0;
|
||||
if (res & 0x80000000) flag |= 0x8;
|
||||
else if (res == 0) flag |= 0x4;
|
||||
cpu_sr = flag;
|
||||
|
@ -448,9 +422,9 @@ void cpuSetFlagsNZ00NewL(ULO res)
|
|||
/// <summary>
|
||||
/// Set the flags (ZN00).
|
||||
/// </summary>
|
||||
void cpuSetFlagsNZ00New64(LLO res)
|
||||
void cpuSetFlagsNZ00New64(int64_t res)
|
||||
{
|
||||
ULO flag = cpu_sr & 0xfff0;
|
||||
uint32_t flag = cpu_sr & 0xfff0;
|
||||
if (res < 0) flag |= 0x8;
|
||||
else if (res == 0) flag |= 0x4;
|
||||
cpu_sr = flag;
|
||||
|
@ -460,7 +434,7 @@ void cpuSetFlagsNZ00New64(LLO res)
|
|||
/// Set the 4 flags absolute.
|
||||
/// </summary>
|
||||
/// <param name="f">flags</param>
|
||||
void cpuSetFlagsAbs(UWO f)
|
||||
void cpuSetFlagsAbs(uint16_t f)
|
||||
{
|
||||
cpu_sr = (cpu_sr & 0xfff0) | f;
|
||||
}
|
||||
|
@ -531,29 +505,29 @@ BOOLE cpuCalculateConditionCode11(void)
|
|||
|
||||
BOOLE cpuCalculateConditionCode12(void)
|
||||
{
|
||||
ULO tmp = cpu_sr & 0xa;
|
||||
uint32_t tmp = cpu_sr & 0xa;
|
||||
return (tmp == 0xa) || (tmp == 0); // GE - (N && V) || (!N && !V)
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode13(void)
|
||||
{
|
||||
ULO tmp = cpu_sr & 0xa;
|
||||
uint32_t tmp = cpu_sr & 0xa;
|
||||
return (tmp == 0x8) || (tmp == 0x2); // LT - (N && !V) || (!N && V)
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode14(void)
|
||||
{
|
||||
ULO tmp = cpu_sr & 0xa;
|
||||
uint32_t tmp = cpu_sr & 0xa;
|
||||
return (!(cpu_sr & 0x4)) && ((tmp == 0xa) || (tmp == 0)); // GT - (N && V && !Z) || (!N && !V && !Z)
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode15(void)
|
||||
{
|
||||
ULO tmp = cpu_sr & 0xa;
|
||||
uint32_t tmp = cpu_sr & 0xa;
|
||||
return (cpu_sr & 0x4) || (tmp == 0x8) || (tmp == 2);// LE - Z || (N && !V) || (!N && V)
|
||||
}
|
||||
|
||||
BOOLE cpuCalculateConditionCode(ULO cc)
|
||||
BOOLE cpuCalculateConditionCode(uint32_t cc)
|
||||
{
|
||||
switch (cc & 0xf)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,119 +1,112 @@
|
|||
#ifndef CpuModule_Internal_H
|
||||
#define CpuModule_Internal_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#pragma once
|
||||
|
||||
// This header file defines the internal interfaces of the CPU module.
|
||||
extern void cpuMakeOpcodeTableForModel(void);
|
||||
extern void cpuCreateMulTimeTables(void);
|
||||
|
||||
// StackFrameGen
|
||||
extern void cpuStackFrameGenerate(UWO vector_no, ULO pc);
|
||||
extern void cpuStackFrameGenerate(uint16_t vector_no, uint32_t pc);
|
||||
extern void cpuStackFrameInit(void);
|
||||
|
||||
// Registers
|
||||
extern ULO cpu_sr; // Not static because the flags calculation uses it extensively
|
||||
extern uint32_t cpu_sr; // Not static because the flags calculation uses it extensively
|
||||
extern BOOLE cpuGetFlagSupervisor(void);
|
||||
extern BOOLE cpuGetFlagMaster(void);
|
||||
extern void cpuSetUspDirect(ULO usp);
|
||||
extern ULO cpuGetUspDirect(void);
|
||||
extern ULO cpuGetUspAutoMap(void);
|
||||
extern void cpuSetSspDirect(ULO ssp);
|
||||
extern ULO cpuGetSspDirect(void);
|
||||
extern ULO cpuGetSspAutoMap(void);
|
||||
extern void cpuSetMspDirect(ULO msp);
|
||||
extern ULO cpuGetMspDirect(void);
|
||||
extern ULO cpuGetMspAutoMap(void);
|
||||
extern void cpuSetMspAutoMap(ULO new_msp);
|
||||
extern ULO cpuGetIspAutoMap(void);
|
||||
extern void cpuSetIspAutoMap(ULO new_isp);
|
||||
extern void cpuSetDReg(ULO i, ULO value);
|
||||
extern ULO cpuGetDReg(ULO i);
|
||||
extern void cpuSetAReg(ULO i, ULO value);
|
||||
extern ULO cpuGetAReg(ULO i);
|
||||
extern void cpuSetReg(ULO da, ULO i, ULO value);
|
||||
extern ULO cpuGetReg(ULO da, ULO i);
|
||||
extern void cpuSetPC(ULO address);
|
||||
extern ULO cpuGetPC(void);
|
||||
extern void cpuSetUspDirect(uint32_t usp);
|
||||
extern uint32_t cpuGetUspDirect(void);
|
||||
extern uint32_t cpuGetUspAutoMap(void);
|
||||
extern void cpuSetSspDirect(uint32_t ssp);
|
||||
extern uint32_t cpuGetSspDirect(void);
|
||||
extern uint32_t cpuGetSspAutoMap(void);
|
||||
extern void cpuSetMspDirect(uint32_t msp);
|
||||
extern uint32_t cpuGetMspDirect(void);
|
||||
extern uint32_t cpuGetMspAutoMap(void);
|
||||
extern void cpuSetMspAutoMap(uint32_t new_msp);
|
||||
extern uint32_t cpuGetIspAutoMap(void);
|
||||
extern void cpuSetIspAutoMap(uint32_t new_isp);
|
||||
extern void cpuSetDReg(uint32_t i, uint32_t value);
|
||||
extern uint32_t cpuGetDReg(uint32_t i);
|
||||
extern void cpuSetAReg(uint32_t i, uint32_t value);
|
||||
extern uint32_t cpuGetAReg(uint32_t i);
|
||||
extern void cpuSetReg(uint32_t da, uint32_t i, uint32_t value);
|
||||
extern uint32_t cpuGetReg(uint32_t da, uint32_t i);
|
||||
extern void cpuSetPC(uint32_t address);
|
||||
extern uint32_t cpuGetPC(void);
|
||||
extern void cpuSetStop(BOOLE stop);
|
||||
extern BOOLE cpuGetStop(void);
|
||||
extern void cpuSetVbr(ULO vbr);
|
||||
extern ULO cpuGetVbr(void);
|
||||
extern void cpuSetSfc(ULO sfc);
|
||||
extern ULO cpuGetSfc(void);
|
||||
extern void cpuSetDfc(ULO dfc);
|
||||
extern ULO cpuGetDfc(void);
|
||||
extern void cpuSetCacr(ULO cacr);
|
||||
extern ULO cpuGetCacr(void);
|
||||
extern void cpuSetCaar(ULO caar);
|
||||
extern ULO cpuGetCaar(void);
|
||||
extern void cpuSetSR(ULO sr);
|
||||
extern ULO cpuGetSR(void);
|
||||
extern void cpuSetIrqLevel(ULO irq_level);
|
||||
extern ULO cpuGetIrqLevel(void);
|
||||
extern void cpuSetIrqAddress(ULO irq_address);
|
||||
extern ULO cpuGetIrqAddress(void);
|
||||
extern void cpuSetInstructionTime(ULO cycles);
|
||||
extern ULO cpuGetInstructionTime(void);
|
||||
extern void cpuSetOriginalPC(ULO pc);
|
||||
extern ULO cpuGetOriginalPC(void);
|
||||
extern void cpuSetVbr(uint32_t vbr);
|
||||
extern uint32_t cpuGetVbr(void);
|
||||
extern void cpuSetSfc(uint32_t sfc);
|
||||
extern uint32_t cpuGetSfc(void);
|
||||
extern void cpuSetDfc(uint32_t dfc);
|
||||
extern uint32_t cpuGetDfc(void);
|
||||
extern void cpuSetCacr(uint32_t cacr);
|
||||
extern uint32_t cpuGetCacr(void);
|
||||
extern void cpuSetCaar(uint32_t caar);
|
||||
extern uint32_t cpuGetCaar(void);
|
||||
extern void cpuSetSR(uint32_t sr);
|
||||
extern uint32_t cpuGetSR(void);
|
||||
extern void cpuSetInstructionTime(uint32_t cycles);
|
||||
extern uint32_t cpuGetInstructionTime(void);
|
||||
extern void cpuSetOriginalPC(uint32_t pc);
|
||||
extern uint32_t cpuGetOriginalPC(void);
|
||||
extern void cpuSetInstructionAborted(bool aborted);
|
||||
extern bool cpuGetInstructionAborted(void);
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
extern void cpuSetCurrentOpcode(UWO opcode);
|
||||
extern UWO cpuGetCurrentOpcode(void);
|
||||
extern void cpuSetCurrentOpcode(uint16_t opcode);
|
||||
extern uint16_t cpuGetCurrentOpcode(void);
|
||||
|
||||
#endif
|
||||
|
||||
extern void cpuProfileWrite(void);
|
||||
|
||||
extern void cpuSetModelMask(UBY model_mask);
|
||||
extern UBY cpuGetModelMask(void);
|
||||
extern void cpuSetDRegWord(ULO regno, UWO val);
|
||||
extern void cpuSetDRegByte(ULO regno, UBY val);
|
||||
extern UWO cpuGetRegWord(ULO i, ULO regno);
|
||||
extern UWO cpuGetDRegWord(ULO regno);
|
||||
extern UBY cpuGetDRegByte(ULO regno);
|
||||
extern ULO cpuGetDRegWordSignExtLong(ULO regno);
|
||||
extern UWO cpuGetDRegByteSignExtWord(ULO regno);
|
||||
extern ULO cpuGetDRegByteSignExtLong(ULO regno);
|
||||
extern UWO cpuGetARegWord(ULO regno);
|
||||
extern UBY cpuGetARegByte(ULO regno);
|
||||
extern void cpuSetModelMask(uint8_t model_mask);
|
||||
extern uint8_t cpuGetModelMask(void);
|
||||
extern void cpuSetDRegWord(uint32_t regno, uint16_t val);
|
||||
extern void cpuSetDRegByte(uint32_t regno, uint8_t val);
|
||||
extern uint16_t cpuGetRegWord(uint32_t i, uint32_t regno);
|
||||
extern uint16_t cpuGetDRegWord(uint32_t regno);
|
||||
extern uint8_t cpuGetDRegByte(uint32_t regno);
|
||||
extern uint32_t cpuGetDRegWordSignExtLong(uint32_t regno);
|
||||
extern uint16_t cpuGetDRegByteSignExtWord(uint32_t regno);
|
||||
extern uint32_t cpuGetDRegByteSignExtLong(uint32_t regno);
|
||||
extern uint16_t cpuGetARegWord(uint32_t regno);
|
||||
extern uint8_t cpuGetARegByte(uint32_t regno);
|
||||
|
||||
extern UWO cpuGetNextWord(void);
|
||||
extern ULO cpuGetNextWordSignExt(void);
|
||||
extern ULO cpuGetNextLong(void);
|
||||
extern uint16_t cpuGetNextWord(void);
|
||||
extern uint32_t cpuGetNextWordSignExt(void);
|
||||
extern uint32_t cpuGetNextLong(void);
|
||||
extern void cpuSkipNextWord(void);
|
||||
extern void cpuSkipNextLong(void);
|
||||
extern void cpuClearPrefetch(void);
|
||||
extern void cpuValidateReadPointer(void);
|
||||
|
||||
extern void cpuInitializeFromNewPC(ULO new_pc);
|
||||
extern void cpuInitializeFromNewPC(uint32_t new_pc);
|
||||
|
||||
// Effective address
|
||||
extern ULO cpuEA02(ULO regno);
|
||||
extern ULO cpuEA03(ULO regno, ULO size);
|
||||
extern ULO cpuEA04(ULO regno, ULO size);
|
||||
extern ULO cpuEA05(ULO regno);
|
||||
extern ULO cpuEA06(ULO regno);
|
||||
extern ULO cpuEA70(void);
|
||||
extern ULO cpuEA71(void);
|
||||
extern ULO cpuEA72(void);
|
||||
extern ULO cpuEA73(void);
|
||||
extern uint32_t cpuEA02(uint32_t regno);
|
||||
extern uint32_t cpuEA03(uint32_t regno, uint32_t size);
|
||||
extern uint32_t cpuEA04(uint32_t regno, uint32_t size);
|
||||
extern uint32_t cpuEA05(uint32_t regno);
|
||||
extern uint32_t cpuEA06(uint32_t regno);
|
||||
extern uint32_t cpuEA70(void);
|
||||
extern uint32_t cpuEA71(void);
|
||||
extern uint32_t cpuEA72(void);
|
||||
extern uint32_t cpuEA73(void);
|
||||
|
||||
// Flags
|
||||
extern void cpuSetFlagsAdd(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetFlagsSub(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetFlagsCmp(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetZFlagBitOpsB(UBY res);
|
||||
extern void cpuSetZFlagBitOpsL(ULO res);
|
||||
extern void cpuSetZFlagBitOpsB(uint8_t res);
|
||||
extern void cpuSetZFlagBitOpsL(uint32_t res);
|
||||
|
||||
extern void cpuSetFlagsNZ00NewB(UBY res);
|
||||
extern void cpuSetFlagsNZ00NewW(UWO res);
|
||||
extern void cpuSetFlagsNZ00NewL(ULO res);
|
||||
extern void cpuSetFlagsNZ00New64(LLO res);
|
||||
extern void cpuSetFlagsNZ00NewB(uint8_t res);
|
||||
extern void cpuSetFlagsNZ00NewW(uint16_t res);
|
||||
extern void cpuSetFlagsNZ00NewL(uint32_t res);
|
||||
extern void cpuSetFlagsNZ00New64(int64_t res);
|
||||
|
||||
extern void cpuSetFlagZ(BOOLE f);
|
||||
extern void cpuSetFlagN(BOOLE f);
|
||||
|
@ -130,16 +123,17 @@ extern void cpuSetFlagsVC(BOOLE v, BOOLE c);
|
|||
extern void cpuSetFlagsShiftZero(BOOLE z, BOOLE rm);
|
||||
extern void cpuSetFlagsShift(BOOLE z, BOOLE rm, BOOLE c, BOOLE v);
|
||||
extern void cpuSetFlagsRotate(BOOLE z, BOOLE rm, BOOLE c);
|
||||
extern void cpuSetFlagsRotateX(UWO z, UWO rm, UWO x);
|
||||
extern void cpuSetFlagsRotateX(uint16_t z, uint16_t rm, uint16_t x);
|
||||
extern void cpuSetFlagsAddX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetFlagsSubX(BOOLE z, BOOLE rm, BOOLE dm, BOOLE sm);
|
||||
extern void cpuSetFlagsAbs(UWO f);
|
||||
extern UWO cpuGetZFlagB(UBY res);
|
||||
extern UWO cpuGetZFlagW(UWO res);
|
||||
extern UWO cpuGetZFlagL(ULO res);
|
||||
extern UWO cpuGetNFlagB(UBY res);
|
||||
extern UWO cpuGetNFlagW(UWO res);
|
||||
extern UWO cpuGetNFlagL(ULO res);
|
||||
extern void cpuSetFlagsAbs(uint16_t f);
|
||||
extern uint16_t cpuGetZFlagB(uint8_t res);
|
||||
extern uint16_t cpuGetZFlagW(uint16_t res);
|
||||
extern uint16_t cpuGetZFlagL(uint32_t res);
|
||||
extern uint16_t cpuGetNFlagB(uint8_t res);
|
||||
extern uint16_t cpuGetNFlagW(uint16_t res);
|
||||
extern uint16_t cpuGetNFlagL(uint32_t res);
|
||||
extern void cpuClearFlagsVC(void);
|
||||
|
||||
extern BOOLE cpuCalculateConditionCode0(void);
|
||||
extern BOOLE cpuCalculateConditionCode1(void);
|
||||
|
@ -157,52 +151,47 @@ extern BOOLE cpuCalculateConditionCode12(void);
|
|||
extern BOOLE cpuCalculateConditionCode13(void);
|
||||
extern BOOLE cpuCalculateConditionCode14(void);
|
||||
extern BOOLE cpuCalculateConditionCode15(void);
|
||||
extern BOOLE cpuCalculateConditionCode(ULO cc);
|
||||
extern BOOLE cpuCalculateConditionCode(uint32_t cc);
|
||||
|
||||
// Logging
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
extern void cpuCallInstructionLoggingFunc(void);
|
||||
extern void cpuCallExceptionLoggingFunc(STR *description, ULO original_pc, UWO opcode);
|
||||
extern void cpuCallInterruptLoggingFunc(ULO level, ULO vector_address);
|
||||
extern void cpuCallExceptionLoggingFunc(char *description, uint32_t original_pc, uint16_t opcode);
|
||||
extern void cpuCallInterruptLoggingFunc(uint32_t level, uint32_t vector_address);
|
||||
#endif
|
||||
|
||||
// Interrupt
|
||||
extern void cpuCallCheckPendingInterruptsFunc(void);
|
||||
extern ULO cpuActivateSSP(void);
|
||||
extern uint32_t cpuActivateSSP(void);
|
||||
extern void cpuSetRaiseInterrupt(BOOLE raise_irq);
|
||||
extern BOOLE cpuGetRaiseInterrupt(void);
|
||||
extern void cpuSetRaiseInterruptLevel(uint32_t raise_irq_level);
|
||||
extern uint32_t cpuGetRaiseInterruptLevel(void);
|
||||
|
||||
// Exceptions
|
||||
extern void cpuThrowPrivilegeViolationException(void);
|
||||
extern void cpuThrowIllegalInstructionException(BOOLE executejmp);
|
||||
extern void cpuThrowIllegalInstructionExceptionFromBreakpoint(void);
|
||||
extern void cpuThrowFLineException(void);
|
||||
extern void cpuThrowALineException(void);
|
||||
extern void cpuThrowTrapVException(void);
|
||||
extern void cpuThrowTrapException(ULO vector_no);
|
||||
extern void cpuThrowDivisionByZeroException(BOOLE executejmp);
|
||||
extern void cpuThrowTrapException(uint32_t vector_no);
|
||||
extern void cpuThrowDivisionByZeroException(void);
|
||||
extern void cpuThrowChkException(void);
|
||||
extern void cpuThrowTraceException(void);
|
||||
extern void cpuThrowResetException(void);
|
||||
extern void cpuCallResetExceptionFunc(void);
|
||||
extern void cpuFrame1(UWO vector_offset, ULO pc);
|
||||
extern void cpuFrame1(uint16_t vector_offset, uint32_t pc);
|
||||
|
||||
// Private help functions
|
||||
static ULO cpuSignExtByteToLong(UBY v) {return (ULO)(LON)(BYT) v;}
|
||||
static UWO cpuSignExtByteToWord(UBY v) {return (UWO)(WOR)(BYT) v;}
|
||||
static ULO cpuSignExtWordToLong(UWO v) {return (ULO)(LON)(WOR) v;}
|
||||
static ULO cpuJoinWordToLong(UWO upper, UWO lower) {return (((ULO)upper) << 16) | ((ULO)lower);}
|
||||
static ULO cpuJoinByteToLong(UBY upper, UBY midh, UBY midl, UBY lower) {return (((ULO)upper) << 24) | (((ULO)midh) << 16) | (((ULO)midl) << 8) | ((ULO)lower);}
|
||||
static UWO cpuJoinByteToWord(UBY upper, UBY lower) {return (((UWO)upper) << 8) | ((UWO)lower);}
|
||||
static BOOLE cpuMsbB(UBY v) {return v>>7;}
|
||||
static BOOLE cpuMsbW(UWO v) {return v>>15;}
|
||||
static BOOLE cpuMsbL(ULO v) {return v>>31;}
|
||||
static BOOLE cpuIsZeroB(UBY v) {return v == 0;}
|
||||
static BOOLE cpuIsZeroW(UWO v) {return v == 0;}
|
||||
static BOOLE cpuIsZeroL(ULO v) {return v == 0;}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
static uint32_t cpuSignExtByteToLong(uint8_t v) {return (uint32_t)(int32_t)(int8_t) v;}
|
||||
static uint16_t cpuSignExtByteToWord(uint8_t v) {return (uint16_t)(int16_t)(int8_t) v;}
|
||||
static uint32_t cpuSignExtWordToLong(uint16_t v) {return (uint32_t)(int32_t)(int16_t) v;}
|
||||
static uint32_t cpuJoinWordToLong(uint16_t upper, uint16_t lower) {return (((uint32_t)upper) << 16) | ((uint32_t)lower);}
|
||||
static uint32_t cpuJoinByteToLong(uint8_t upper, uint8_t midh, uint8_t midl, uint8_t lower) {return (((uint32_t)upper) << 24) | (((uint32_t)midh) << 16) | (((uint32_t)midl) << 8) | ((uint32_t)lower);}
|
||||
static uint16_t cpuJoinByteToWord(uint8_t upper, uint8_t lower) {return (((uint16_t)upper) << 8) | ((uint16_t)lower);}
|
||||
static BOOLE cpuMsbB(uint8_t v) {return v>>7;}
|
||||
static BOOLE cpuMsbW(uint16_t v) {return v>>15;}
|
||||
static BOOLE cpuMsbL(uint32_t v) {return v>>31;}
|
||||
static BOOLE cpuIsZeroB(uint8_t v) {return v == 0;}
|
||||
static BOOLE cpuIsZeroW(uint16_t v) {return v == 0;}
|
||||
static BOOLE cpuIsZeroL(uint32_t v) {return v == 0;}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* @(#) $Id: CpuModule_InternalState.c,v 1.9 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* 68000 internal state */
|
||||
|
@ -23,63 +22,62 @@
|
|||
/*=========================================================================*/
|
||||
#include "defs.h"
|
||||
#include "CpuModule.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
#include "CpuModule_Memory.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
/* M68k registers */
|
||||
static ULO cpu_regs[2][8]; /* 0 - data, 1 - address */
|
||||
static ULO cpu_pc;
|
||||
static ULO cpu_usp;
|
||||
static ULO cpu_ssp;
|
||||
static ULO cpu_msp;
|
||||
static ULO cpu_sfc;
|
||||
static ULO cpu_dfc;
|
||||
ULO cpu_sr; // Not static because flags calculation use it extensively
|
||||
static ULO cpu_vbr;
|
||||
static UWO cpu_prefetch_word;
|
||||
static ULO cpu_cacr;
|
||||
static ULO cpu_caar;
|
||||
static uint32_t cpu_regs[2][8]; /* 0 - data, 1 - address */
|
||||
static uint32_t cpu_pc;
|
||||
static uint32_t cpu_usp;
|
||||
static uint32_t cpu_ssp;
|
||||
static uint32_t cpu_msp;
|
||||
static uint32_t cpu_sfc;
|
||||
static uint32_t cpu_dfc;
|
||||
uint32_t cpu_sr; // Not static because flags calculation use it extensively
|
||||
static uint32_t cpu_vbr;
|
||||
static uint16_t cpu_prefetch_word;
|
||||
static uint32_t cpu_cacr;
|
||||
static uint32_t cpu_caar;
|
||||
|
||||
/* Irq management */
|
||||
static BOOLE cpu_raise_irq;
|
||||
static ULO cpu_irq_level;
|
||||
static ULO cpu_irq_address;
|
||||
static uint32_t cpu_raise_irq_level;
|
||||
|
||||
/* Reset values */
|
||||
static ULO cpu_initial_pc;
|
||||
static ULO cpu_initial_sp;
|
||||
static uint32_t cpu_initial_pc;
|
||||
static uint32_t cpu_initial_sp;
|
||||
|
||||
/* Flag set if CPU is stopped */
|
||||
static BOOLE cpu_stop;
|
||||
|
||||
/* The current CPU model */
|
||||
static ULO cpu_model_major = -1;
|
||||
static ULO cpu_model_minor;
|
||||
static UBY cpu_model_mask;
|
||||
static uint32_t cpu_model_major = -1;
|
||||
static uint32_t cpu_model_minor;
|
||||
static uint8_t cpu_model_mask;
|
||||
|
||||
/* For exception handling */
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
static UWO cpu_current_opcode;
|
||||
static uint16_t cpu_current_opcode;
|
||||
|
||||
#endif
|
||||
|
||||
static ULO cpu_original_pc;
|
||||
static uint32_t cpu_original_pc;
|
||||
static bool cpu_instruction_aborted;
|
||||
|
||||
/* Number of cycles taken by the last intstruction */
|
||||
static ULO cpu_instruction_time;
|
||||
static uint32_t cpu_instruction_time;
|
||||
|
||||
/* Getters and setters */
|
||||
|
||||
void cpuSetDReg(ULO i, ULO value) {cpu_regs[0][i] = value;}
|
||||
ULO cpuGetDReg(ULO i) {return cpu_regs[0][i];}
|
||||
void cpuSetDReg(uint32_t i, uint32_t value) {cpu_regs[0][i] = value;}
|
||||
uint32_t cpuGetDReg(uint32_t i) {return cpu_regs[0][i];}
|
||||
|
||||
void cpuSetAReg(ULO i, ULO value) {cpu_regs[1][i] = value;}
|
||||
ULO cpuGetAReg(ULO i) {return cpu_regs[1][i];}
|
||||
void cpuSetAReg(uint32_t i, uint32_t value) {cpu_regs[1][i] = value;}
|
||||
uint32_t cpuGetAReg(uint32_t i) {return cpu_regs[1][i];}
|
||||
|
||||
void cpuSetReg(ULO da, ULO i, ULO value) {cpu_regs[da][i] = value;}
|
||||
ULO cpuGetReg(ULO da, ULO i) {return cpu_regs[da][i];}
|
||||
void cpuSetReg(uint32_t da, uint32_t i, uint32_t value) {cpu_regs[da][i] = value;}
|
||||
uint32_t cpuGetReg(uint32_t da, uint32_t i) {return cpu_regs[da][i];}
|
||||
|
||||
/// <summary>
|
||||
/// Get the supervisor bit from sr.
|
||||
|
@ -97,21 +95,21 @@ BOOLE cpuGetFlagMaster(void)
|
|||
return cpu_sr & 0x1000;
|
||||
}
|
||||
|
||||
void cpuSetUspDirect(ULO usp) {cpu_usp = usp;}
|
||||
ULO cpuGetUspDirect(void) {return cpu_usp;}
|
||||
ULO cpuGetUspAutoMap(void) {return (cpuGetFlagSupervisor()) ? cpuGetUspDirect() : cpuGetAReg(7);}
|
||||
void cpuSetUspDirect(uint32_t usp) {cpu_usp = usp;}
|
||||
uint32_t cpuGetUspDirect() {return cpu_usp;}
|
||||
uint32_t cpuGetUspAutoMap() {return (cpuGetFlagSupervisor()) ? cpuGetUspDirect() : cpuGetAReg(7);}
|
||||
|
||||
void cpuSetSspDirect(ULO ssp) {cpu_ssp = ssp;}
|
||||
ULO cpuGetSspDirect(void) {return cpu_ssp;}
|
||||
ULO cpuGetSspAutoMap(void) {return (cpuGetFlagSupervisor()) ? cpuGetAReg(7) : cpuGetSspDirect();}
|
||||
void cpuSetSspDirect(uint32_t ssp) {cpu_ssp = ssp;}
|
||||
uint32_t cpuGetSspDirect() {return cpu_ssp;}
|
||||
uint32_t cpuGetSspAutoMap() {return (cpuGetFlagSupervisor()) ? cpuGetAReg(7) : cpuGetSspDirect();}
|
||||
|
||||
void cpuSetMspDirect(ULO msp) {cpu_msp = msp;}
|
||||
ULO cpuGetMspDirect(void) {return cpu_msp;}
|
||||
void cpuSetMspDirect(uint32_t msp) {cpu_msp = msp;}
|
||||
uint32_t cpuGetMspDirect() {return cpu_msp;}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the master stack pointer.
|
||||
/// </summary>
|
||||
ULO cpuGetMspAutoMap(void)
|
||||
uint32_t cpuGetMspAutoMap(void)
|
||||
{
|
||||
if (cpuGetFlagSupervisor() && cpuGetFlagMaster())
|
||||
{
|
||||
|
@ -123,7 +121,7 @@ ULO cpuGetMspAutoMap(void)
|
|||
/// <summary>
|
||||
/// Sets the master stack pointer.
|
||||
/// </summary>
|
||||
void cpuSetMspAutoMap(ULO new_msp)
|
||||
void cpuSetMspAutoMap(uint32_t new_msp)
|
||||
{
|
||||
if (cpuGetFlagSupervisor() && cpuGetFlagMaster())
|
||||
{
|
||||
|
@ -138,7 +136,7 @@ void cpuSetMspAutoMap(ULO new_msp)
|
|||
/// <summary>
|
||||
/// Returns the interrupt stack pointer. ssp is used as isp.
|
||||
/// </summary>
|
||||
ULO cpuGetIspAutoMap(void)
|
||||
uint32_t cpuGetIspAutoMap(void)
|
||||
{
|
||||
if (cpuGetFlagSupervisor() && !cpuGetFlagMaster())
|
||||
{
|
||||
|
@ -150,7 +148,7 @@ ULO cpuGetIspAutoMap(void)
|
|||
/// <summary>
|
||||
/// Sets the interrupt stack pointer. ssp is used as isp.
|
||||
/// </summary>
|
||||
void cpuSetIspAutoMap(ULO new_isp)
|
||||
void cpuSetIspAutoMap(uint32_t new_isp)
|
||||
{
|
||||
if (cpuGetFlagSupervisor() && !cpuGetFlagMaster())
|
||||
{
|
||||
|
@ -162,63 +160,64 @@ void cpuSetIspAutoMap(ULO new_isp)
|
|||
}
|
||||
}
|
||||
|
||||
void cpuSetPC(ULO address) {cpu_pc = address;}
|
||||
ULO cpuGetPC(void) {return cpu_pc;}
|
||||
void cpuSetPC(uint32_t address) {cpu_pc = address;}
|
||||
uint32_t cpuGetPC() {return cpu_pc;}
|
||||
|
||||
void cpuSetStop(BOOLE stop) {cpu_stop = stop;}
|
||||
BOOLE cpuGetStop(void) {return cpu_stop;}
|
||||
BOOLE cpuGetStop() {return cpu_stop;}
|
||||
|
||||
void cpuSetVbr(ULO vbr) {cpu_vbr = vbr;}
|
||||
ULO cpuGetVbr(void) {return cpu_vbr;}
|
||||
void cpuSetVbr(uint32_t vbr) {cpu_vbr = vbr;}
|
||||
uint32_t cpuGetVbr() {return cpu_vbr;}
|
||||
|
||||
void cpuSetSfc(ULO sfc) {cpu_sfc = sfc;}
|
||||
ULO cpuGetSfc(void) {return cpu_sfc;}
|
||||
void cpuSetSfc(uint32_t sfc) {cpu_sfc = sfc;}
|
||||
uint32_t cpuGetSfc() {return cpu_sfc;}
|
||||
|
||||
void cpuSetDfc(ULO dfc) {cpu_dfc = dfc;}
|
||||
ULO cpuGetDfc(void) {return cpu_dfc;}
|
||||
void cpuSetDfc(uint32_t dfc) {cpu_dfc = dfc;}
|
||||
uint32_t cpuGetDfc() {return cpu_dfc;}
|
||||
|
||||
void cpuSetCacr(ULO cacr) {cpu_cacr = cacr;}
|
||||
ULO cpuGetCacr(void) {return cpu_cacr;}
|
||||
void cpuSetCacr(uint32_t cacr) {cpu_cacr = cacr;}
|
||||
uint32_t cpuGetCacr() {return cpu_cacr;}
|
||||
|
||||
void cpuSetCaar(ULO caar) {cpu_caar = caar;}
|
||||
ULO cpuGetCaar(void) {return cpu_caar;}
|
||||
void cpuSetCaar(uint32_t caar) {cpu_caar = caar;}
|
||||
uint32_t cpuGetCaar() {return cpu_caar;}
|
||||
|
||||
void cpuSetSR(ULO sr) {cpu_sr = sr;}
|
||||
ULO cpuGetSR(void) {return cpu_sr;}
|
||||
void cpuSetSR(uint32_t sr) {cpu_sr = sr;}
|
||||
uint32_t cpuGetSR() {return cpu_sr;}
|
||||
|
||||
void cpuSetIrqLevel(ULO irq_level) {cpu_irq_level = irq_level;}
|
||||
ULO cpuGetIrqLevel(void) {return cpu_irq_level;}
|
||||
void cpuSetInstructionTime(uint32_t cycles) {cpu_instruction_time = cycles;}
|
||||
uint32_t cpuGetInstructionTime() {return cpu_instruction_time;}
|
||||
|
||||
void cpuSetIrqAddress(ULO irq_address) {cpu_irq_address = irq_address;}
|
||||
ULO cpuGetIrqAddress(void) {return cpu_irq_address;}
|
||||
void cpuSetOriginalPC(uint32_t pc) {cpu_original_pc = pc;}
|
||||
uint32_t cpuGetOriginalPC() {return cpu_original_pc;}
|
||||
|
||||
void cpuSetInstructionTime(ULO cycles) {cpu_instruction_time = cycles;}
|
||||
ULO cpuGetInstructionTime(void) {return cpu_instruction_time;}
|
||||
|
||||
void cpuSetOriginalPC(ULO pc) {cpu_original_pc = pc;}
|
||||
ULO cpuGetOriginalPC(void) {return cpu_original_pc;}
|
||||
void cpuSetInstructionAborted(bool aborted) {cpu_instruction_aborted = aborted;}
|
||||
bool cpuGetInstructionAborted() {return cpu_instruction_aborted;}
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
||||
void cpuSetCurrentOpcode(UWO opcode) {cpu_current_opcode = opcode;}
|
||||
UWO cpuGetCurrentOpcode(void) {return cpu_current_opcode;}
|
||||
void cpuSetCurrentOpcode(uint16_t opcode) {cpu_current_opcode = opcode;}
|
||||
uint16_t cpuGetCurrentOpcode() {return cpu_current_opcode;}
|
||||
|
||||
#endif
|
||||
|
||||
void cpuSetRaiseInterrupt(BOOLE raise_irq) {cpu_raise_irq = raise_irq;}
|
||||
BOOLE cpuGetRaiseInterrupt(void) {return cpu_raise_irq;}
|
||||
BOOLE cpuGetRaiseInterrupt() {return cpu_raise_irq;}
|
||||
void cpuSetRaiseInterruptLevel(uint32_t raise_irq_level) {cpu_raise_irq_level = raise_irq_level;}
|
||||
uint32_t cpuGetRaiseInterruptLevel() {return cpu_raise_irq_level;}
|
||||
|
||||
void cpuSetInitialPC(ULO pc) {cpu_initial_pc = pc;}
|
||||
ULO cpuGetInitialPC(void) {return cpu_initial_pc;}
|
||||
uint32_t cpuGetIrqLevel() {return (cpu_sr & 0x0700) >> 8;}
|
||||
|
||||
void cpuSetInitialSP(ULO sp) {cpu_initial_sp = sp;}
|
||||
ULO cpuGetInitialSP(void) {return cpu_initial_sp;}
|
||||
void cpuSetInitialPC(uint32_t pc) {cpu_initial_pc = pc;}
|
||||
uint32_t cpuGetInitialPC() {return cpu_initial_pc;}
|
||||
|
||||
void cpuSetModelMask(UBY model_mask) {cpu_model_mask = model_mask;}
|
||||
UBY cpuGetModelMask(void) {return cpu_model_mask;}
|
||||
void cpuSetInitialSP(uint32_t sp) {cpu_initial_sp = sp;}
|
||||
uint32_t cpuGetInitialSP() {return cpu_initial_sp;}
|
||||
|
||||
ULO cpuGetModelMajor(void) {return cpu_model_major;}
|
||||
ULO cpuGetModelMinor(void) {return cpu_model_minor;}
|
||||
void cpuSetModelMask(uint8_t model_mask) {cpu_model_mask = model_mask;}
|
||||
uint8_t cpuGetModelMask() {return cpu_model_mask;}
|
||||
|
||||
uint32_t cpuGetModelMajor() {return cpu_model_major;}
|
||||
uint32_t cpuGetModelMinor() {return cpu_model_minor;}
|
||||
|
||||
static void cpuCalculateModelMask(void)
|
||||
{
|
||||
|
@ -239,7 +238,7 @@ static void cpuCalculateModelMask(void)
|
|||
}
|
||||
}
|
||||
|
||||
void cpuSetModel(ULO major, ULO minor)
|
||||
void cpuSetModel(uint32_t major, uint32_t minor)
|
||||
{
|
||||
BOOLE makeOpcodeTable = (cpu_model_major != major);
|
||||
cpu_model_major = major;
|
||||
|
@ -249,53 +248,59 @@ void cpuSetModel(ULO major, ULO minor)
|
|||
if (makeOpcodeTable) cpuMakeOpcodeTableForModel();
|
||||
}
|
||||
|
||||
void cpuSetDRegWord(ULO regno, UWO val) {*((WOR*)&cpu_regs[0][regno]) = val;}
|
||||
void cpuSetDRegByte(ULO regno, UBY val) {*((UBY*)&cpu_regs[0][regno]) = val;}
|
||||
UWO cpuGetRegWord(ULO i, ULO regno) {return (UWO)cpu_regs[i][regno];}
|
||||
#if 0
|
||||
void cpuSetDRegWord(uint32_t regno, uint16_t val) {*((int16_t*)&cpu_regs[0][regno]) = val;}
|
||||
void cpuSetDRegByte(uint32_t regno, uint8_t val) {*((uint8_t*)&cpu_regs[0][regno]) = val;}
|
||||
#else
|
||||
// MPW -- above assumes little endian.
|
||||
void cpuSetDRegWord(uint32_t regno, uint16_t val) {cpu_regs[0][regno] &= 0xffff0000; cpu_regs[0][regno] |= val;}
|
||||
void cpuSetDRegByte(uint32_t regno, uint8_t val) {cpu_regs[0][regno] &= 0xffffff00; cpu_regs[0][regno] |= val;}
|
||||
#endif
|
||||
|
||||
UWO cpuGetDRegWord(ULO regno) {return (UWO)cpu_regs[0][regno];}
|
||||
UBY cpuGetDRegByte(ULO regno) {return (UBY)cpu_regs[0][regno];}
|
||||
uint16_t cpuGetRegWord(uint32_t i, uint32_t regno) {return (uint16_t)cpu_regs[i][regno];}
|
||||
uint16_t cpuGetDRegWord(uint32_t regno) {return (uint16_t)cpu_regs[0][regno];}
|
||||
uint8_t cpuGetDRegByte(uint32_t regno) {return (uint8_t)cpu_regs[0][regno];}
|
||||
|
||||
ULO cpuGetDRegWordSignExtLong(ULO regno) {return cpuSignExtWordToLong(cpuGetDRegWord(regno));}
|
||||
UWO cpuGetDRegByteSignExtWord(ULO regno) {return cpuSignExtByteToWord(cpuGetDRegByte(regno));}
|
||||
ULO cpuGetDRegByteSignExtLong(ULO regno) {return cpuSignExtByteToLong(cpuGetDRegByte(regno));}
|
||||
uint32_t cpuGetDRegWordSignExtLong(uint32_t regno) {return cpuSignExtWordToLong(cpuGetDRegWord(regno));}
|
||||
uint16_t cpuGetDRegByteSignExtWord(uint32_t regno) {return cpuSignExtByteToWord(cpuGetDRegByte(regno));}
|
||||
uint32_t cpuGetDRegByteSignExtLong(uint32_t regno) {return cpuSignExtByteToLong(cpuGetDRegByte(regno));}
|
||||
|
||||
UWO cpuGetARegWord(ULO regno) {return (UWO)cpu_regs[1][regno];}
|
||||
UBY cpuGetARegByte(ULO regno) {return (UBY)cpu_regs[1][regno];}
|
||||
uint16_t cpuGetARegWord(uint32_t regno) {return (uint16_t)cpu_regs[1][regno];}
|
||||
uint8_t cpuGetARegByte(uint32_t regno) {return (uint8_t)cpu_regs[1][regno];}
|
||||
|
||||
typedef UWO (*cpuGetWordFunc)(void);
|
||||
typedef ULO (*cpuGetLongFunc)(void);
|
||||
typedef uint16_t (*cpuGetWordFunc)(void);
|
||||
typedef uint32_t (*cpuGetLongFunc)(void);
|
||||
|
||||
static UWO cpuGetNextWordInternal(void)
|
||||
static uint16_t cpuGetNextWordInternal(void)
|
||||
{
|
||||
UWO data = memoryReadWord(cpuGetPC() + 2);
|
||||
uint16_t data = memoryReadWord(cpuGetPC() + 2);
|
||||
return data;
|
||||
}
|
||||
|
||||
static ULO cpuGetNextLongInternal(void)
|
||||
static uint32_t cpuGetNextLongInternal(void)
|
||||
{
|
||||
ULO data = memoryReadLong(cpuGetPC() + 2);
|
||||
uint32_t data = memoryReadLong(cpuGetPC() + 2);
|
||||
return data;
|
||||
}
|
||||
|
||||
UWO cpuGetNextWord(void)
|
||||
uint16_t cpuGetNextWord(void)
|
||||
{
|
||||
UWO tmp = cpu_prefetch_word;
|
||||
uint16_t tmp = cpu_prefetch_word;
|
||||
cpu_prefetch_word = cpuGetNextWordInternal();
|
||||
cpuSetPC(cpuGetPC() + 2);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ULO cpuGetNextWordSignExt(void)
|
||||
uint32_t cpuGetNextWordSignExt(void)
|
||||
{
|
||||
return cpuSignExtWordToLong(cpuGetNextWord());
|
||||
}
|
||||
|
||||
ULO cpuGetNextLong(void)
|
||||
uint32_t cpuGetNextLong(void)
|
||||
{
|
||||
ULO tmp = cpu_prefetch_word << 16;
|
||||
ULO data = cpuGetNextLongInternal();
|
||||
cpu_prefetch_word = (UWO) data;
|
||||
uint32_t tmp = cpu_prefetch_word << 16;
|
||||
uint32_t data = cpuGetNextLongInternal();
|
||||
cpu_prefetch_word = (uint16_t) data;
|
||||
cpuSetPC(cpuGetPC() + 4);
|
||||
return tmp | (data >> 16);
|
||||
}
|
||||
|
@ -322,7 +327,7 @@ void cpuSkipNextLong(void)
|
|||
cpuInitializePrefetch();
|
||||
}
|
||||
|
||||
void cpuInitializeFromNewPC(ULO new_pc)
|
||||
void cpuInitializeFromNewPC(uint32_t new_pc)
|
||||
{
|
||||
cpuSetPC(new_pc);
|
||||
cpuInitializePrefetch();
|
||||
|
@ -330,13 +335,11 @@ void cpuInitializeFromNewPC(ULO new_pc)
|
|||
|
||||
void cpuSaveState(FILE *F)
|
||||
{
|
||||
ULO i, j;
|
||||
|
||||
fwrite(&cpu_model_major, sizeof(cpu_model_major), 1, F);
|
||||
fwrite(&cpu_model_minor, sizeof(cpu_model_minor), 1, F);
|
||||
for (i = 0; i < 2; i++)
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
{
|
||||
for (j = 0; j < 7; j++)
|
||||
for (uint32_t j = 0; j < 7; j++)
|
||||
{
|
||||
fwrite(&cpu_regs[i][j], sizeof(cpu_regs[i][j]), 1, F);
|
||||
}
|
||||
|
@ -352,21 +355,17 @@ void cpuSaveState(FILE *F)
|
|||
fwrite(&cpu_vbr, sizeof(cpu_vbr), 1, F);
|
||||
fwrite(&cpu_cacr, sizeof(cpu_cacr), 1, F);
|
||||
fwrite(&cpu_caar, sizeof(cpu_caar), 1, F);
|
||||
fwrite(&cpu_irq_level, sizeof(cpu_irq_level), 1, F);
|
||||
fwrite(&cpu_irq_address, sizeof(cpu_irq_address), 1, F);
|
||||
fwrite(&cpu_initial_pc, sizeof(cpu_initial_pc), 1, F);
|
||||
fwrite(&cpu_initial_sp, sizeof(cpu_initial_sp), 1, F);
|
||||
}
|
||||
|
||||
void cpuLoadState(FILE *F)
|
||||
{
|
||||
ULO i, j;
|
||||
|
||||
fread(&cpu_model_major, sizeof(cpu_model_major), 1, F);
|
||||
fread(&cpu_model_minor, sizeof(cpu_model_minor), 1, F);
|
||||
for (i = 0; i < 2; i++)
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
{
|
||||
for (j = 0; j < 7; j++)
|
||||
for (uint32_t j = 0; j < 7; j++)
|
||||
{
|
||||
fread(&cpu_regs[i][j], sizeof(cpu_regs[i][j]), 1, F);
|
||||
}
|
||||
|
@ -382,8 +381,6 @@ void cpuLoadState(FILE *F)
|
|||
fread(&cpu_vbr, sizeof(cpu_vbr), 1, F);
|
||||
fread(&cpu_cacr, sizeof(cpu_cacr), 1, F);
|
||||
fread(&cpu_caar, sizeof(cpu_caar), 1, F);
|
||||
fread(&cpu_irq_level, sizeof(cpu_irq_level), 1, F);
|
||||
fread(&cpu_irq_address, sizeof(cpu_irq_address), 1, F);
|
||||
fread(&cpu_initial_pc, sizeof(cpu_initial_pc), 1, F);
|
||||
fread(&cpu_initial_sp, sizeof(cpu_initial_sp), 1, F);
|
||||
cpuSetModel(cpu_model_major, cpu_model_minor); // Recalculates stack frames etc.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* @(#) $Id: CpuModule_Interrupts.c,v 1.5 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* 68000 interrupt handling */
|
||||
|
@ -22,24 +21,17 @@
|
|||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
|
||||
#include "CpuModule_Memory.h"
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
/* Function for checking pending interrupts */
|
||||
cpuCheckPendingInterruptsFunc cpu_check_pending_interrupts_func;
|
||||
|
||||
void cpuCallCheckPendingInterruptsFunc(void)
|
||||
{
|
||||
if (cpuGetRaiseInterrupt()) return;
|
||||
cpuSetRaiseInterrupt(cpu_check_pending_interrupts_func());
|
||||
}
|
||||
|
||||
void cpuCheckPendingInterrupts(void)
|
||||
{
|
||||
cpuCallCheckPendingInterruptsFunc();
|
||||
if (cpuGetRaiseInterrupt()) return;
|
||||
cpu_check_pending_interrupts_func();
|
||||
}
|
||||
|
||||
void cpuSetCheckPendingInterruptsFunc(cpuCheckPendingInterruptsFunc func)
|
||||
|
@ -47,9 +39,9 @@ void cpuSetCheckPendingInterruptsFunc(cpuCheckPendingInterruptsFunc func)
|
|||
cpu_check_pending_interrupts_func = func;
|
||||
}
|
||||
|
||||
ULO cpuActivateSSP(void)
|
||||
uint32_t cpuActivateSSP(void)
|
||||
{
|
||||
ULO currentSP = cpuGetAReg(7);
|
||||
uint32_t currentSP = cpuGetAReg(7);
|
||||
|
||||
// check supervisor bit number (bit 13) within the system byte of the status register
|
||||
if (!cpuGetFlagSupervisor())
|
||||
|
@ -70,38 +62,55 @@ ULO cpuActivateSSP(void)
|
|||
return currentSP;
|
||||
}
|
||||
|
||||
// Retrns TRUE if the CPU is in the stopped state,
|
||||
// this allows our scheduling queue to start
|
||||
// scheduling CPU events again.
|
||||
BOOLE cpuSetIrqLevel(uint32_t new_interrupt_level)
|
||||
{
|
||||
cpuSetRaiseInterrupt(TRUE);
|
||||
cpuSetRaiseInterruptLevel(new_interrupt_level);
|
||||
|
||||
if (cpuGetStop())
|
||||
{
|
||||
cpuSetStop(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*============================================================
|
||||
Transfers control to an interrupt routine
|
||||
============================================================*/
|
||||
|
||||
// Returns TRUE if the cpu was stopped
|
||||
void cpuSetUpInterrupt(void)
|
||||
void cpuSetUpInterrupt(uint32_t new_interrupt_level)
|
||||
{
|
||||
UWO vector_offset = (UWO) (0x60 + cpuGetIrqLevel()*4);
|
||||
uint16_t vector_offset = (uint16_t) (0x60 + new_interrupt_level*4);
|
||||
uint32_t vector_address = memoryReadLong(cpuGetVbr() + vector_offset);
|
||||
|
||||
cpuActivateSSP(); // Switch to using ssp or msp. Loads a7 and preserves usp if we came from user-mode.
|
||||
|
||||
cpuStackFrameGenerate(vector_offset, cpuGetPC()); // This will end up on msp if master is enabled, or on the ssp/isp if not.
|
||||
|
||||
cpuSetSR(cpuGetSR() & 0x38ff); // Clear interrupt level
|
||||
cpuSetSR(cpuGetSR() | 0x2000); // Set supervisor mode
|
||||
cpuSetSR(cpuGetSR() | (UWO)(cpuGetIrqLevel() << 8)); // Set interrupt level
|
||||
cpuSetSR(cpuGetSR() | (uint16_t)(new_interrupt_level << 8)); // Set interrupt level
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
cpuCallInterruptLoggingFunc(cpuGetIrqLevel(), cpuGetIrqAddress());
|
||||
cpuCallInterruptLoggingFunc(new_interrupt_level, vector_address);
|
||||
#endif
|
||||
|
||||
if (cpuGetModelMajor() >= 2 && cpuGetModelMajor() < 6)
|
||||
{
|
||||
if (cpuGetFlagMaster())
|
||||
{ // If the cpu was in master mode, preserve msp, and switch to using ssp (isp) in a7.
|
||||
ULO oldA7 = cpuGetAReg(7);
|
||||
uint32_t oldA7 = cpuGetAReg(7);
|
||||
cpuSetMspDirect(oldA7);
|
||||
cpuSetAReg(7, cpuGetSspDirect());
|
||||
cpuFrame1(vector_offset, cpuGetPC()); // Make the throwaway frame on ssp/isp
|
||||
cpuSetSR(cpuGetSR() & 0xefff); // Clear master bit
|
||||
}
|
||||
}
|
||||
cpuInitializeFromNewPC(cpuGetIrqAddress());
|
||||
cpuInitializeFromNewPC(vector_address);
|
||||
cpuSetStop(FALSE);
|
||||
cpuSetRaiseInterrupt(FALSE);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* @(#) $Id: CpuModule_Logging.c,v 1.3 2012/08/12 16:51:02 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* CPU 68k logging functions */
|
||||
|
@ -24,8 +23,6 @@
|
|||
/*=========================================================================*/
|
||||
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
|
||||
#include "CpuModule.h"
|
||||
|
||||
#ifdef CPU_INSTRUCTION_LOGGING
|
||||
|
@ -51,7 +48,7 @@ void cpuSetExceptionLoggingFunc(cpuExceptionLoggingFunc func)
|
|||
cpu_exception_logging_func = func;
|
||||
}
|
||||
|
||||
void cpuCallExceptionLoggingFunc(STR *description, ULO original_pc, UWO opcode)
|
||||
void cpuCallExceptionLoggingFunc(char *description, uint32_t original_pc, uint16_t opcode)
|
||||
{
|
||||
if (cpu_exception_logging_func != NULL)
|
||||
cpu_exception_logging_func(description, original_pc, opcode);
|
||||
|
@ -62,7 +59,7 @@ void cpuSetInterruptLoggingFunc(cpuInterruptLoggingFunc func)
|
|||
cpu_interrupt_logging_func = func;
|
||||
}
|
||||
|
||||
void cpuCallInterruptLoggingFunc(ULO level, ULO vector_address)
|
||||
void cpuCallInterruptLoggingFunc(uint32_t level, uint32_t vector_address)
|
||||
{
|
||||
if (cpu_interrupt_logging_func != NULL)
|
||||
cpu_interrupt_logging_func(level, vector_address);
|
||||
|
|
1
cpu/CpuModule_Memory.h
Normal file
1
cpu/CpuModule_Memory.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include "fmem.h"
|
|
@ -1,8 +1,5 @@
|
|||
#ifndef CPUMODULE_PROFILE_H
|
||||
#define CPUMODULE_PROFILE_H
|
||||
#pragma once
|
||||
|
||||
#include "fileops.h"
|
||||
void cpuProfileWrite(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* @(#) $Id: CpuModule_StackFrameGen.c,v 1.3 2011/07/18 17:22:55 peschau Exp $ */
|
||||
/*=========================================================================*/
|
||||
/* Fellow */
|
||||
/* 68000 stack frame generation */
|
||||
|
@ -22,17 +21,15 @@
|
|||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*=========================================================================*/
|
||||
#include "defs.h"
|
||||
#include "fellow.h"
|
||||
#include "fmem.h"
|
||||
|
||||
#include "CpuModule_Memory.h"
|
||||
#include "CpuModule.h"
|
||||
#include "CpuModule_Internal.h"
|
||||
|
||||
/* Exception stack frame jmptables */
|
||||
typedef void(*cpuStackFrameGenFunc)(UWO, ULO);
|
||||
typedef void(*cpuStackFrameGenFunc)(uint16_t, uint32_t);
|
||||
static cpuStackFrameGenFunc cpu_stack_frame_gen_func[64];
|
||||
|
||||
static void cpuSetStackFrameGenFunc(ULO vector_no, cpuStackFrameGenFunc func)
|
||||
static void cpuSetStackFrameGenFunc(uint32_t vector_no, cpuStackFrameGenFunc func)
|
||||
{
|
||||
cpu_stack_frame_gen_func[vector_no] = func;
|
||||
}
|
||||
|
@ -43,7 +40,7 @@ static void cpuSetStackFrameGenFunc(ULO vector_no, cpuStackFrameGenFunc func)
|
|||
000: All, except bus and address error
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrameGroup1(UWO vector_offset, ULO pcPtr)
|
||||
static void cpuFrameGroup1(uint16_t vector_offset, uint32_t pcPtr)
|
||||
{
|
||||
// save PC
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 4);
|
||||
|
@ -51,7 +48,7 @@ static void cpuFrameGroup1(UWO vector_offset, ULO pcPtr)
|
|||
|
||||
// save SR
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 2);
|
||||
memoryWriteWord((UWO)cpuGetSR(), cpuGetAReg(7));
|
||||
memoryWriteWord((uint16_t)cpuGetSR(), cpuGetAReg(7));
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
|
@ -63,7 +60,7 @@ static void cpuFrameGroup1(UWO vector_offset, ULO pcPtr)
|
|||
memory_fault_read is TRUE if the access was a read
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrameGroup2(UWO vector_offset, ULO pcPtr)
|
||||
static void cpuFrameGroup2(uint16_t vector_offset, uint32_t pcPtr)
|
||||
{
|
||||
// save PC
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 4);
|
||||
|
@ -71,7 +68,7 @@ static void cpuFrameGroup2(UWO vector_offset, ULO pcPtr)
|
|||
|
||||
// save SR
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 2);
|
||||
memoryWriteWord((UWO)cpuGetSR(), cpuGetAReg(7));
|
||||
memoryWriteWord((uint16_t)cpuGetSR(), cpuGetAReg(7));
|
||||
|
||||
// fault address, skip ireg
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 6);
|
||||
|
@ -81,7 +78,7 @@ static void cpuFrameGroup2(UWO vector_offset, ULO pcPtr)
|
|||
memoryWriteLong(memory_fault_read << 4, cpuGetAReg(7));
|
||||
}
|
||||
|
||||
static void cpuFrame4Words(UWO frame_code, UWO vector_offset, ULO pc)
|
||||
static void cpuFrame4Words(uint16_t frame_code, uint16_t vector_offset, uint32_t pc)
|
||||
{
|
||||
// save vector_offset word
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 2);
|
||||
|
@ -93,7 +90,7 @@ static void cpuFrame4Words(UWO frame_code, UWO vector_offset, ULO pc)
|
|||
|
||||
// save SR
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 2);
|
||||
memoryWriteWord((UWO)cpuGetSR(), cpuGetAReg(7));
|
||||
memoryWriteWord((uint16_t)cpuGetSR(), cpuGetAReg(7));
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,7 +110,7 @@ static void cpuFrame4Words(UWO frame_code, UWO vector_offset, ULO pc)
|
|||
030: Same as for 020
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrame0(UWO vector_offset, ULO pc)
|
||||
static void cpuFrame0(uint16_t vector_offset, uint32_t pc)
|
||||
{
|
||||
cpuFrame4Words(0x0000, vector_offset, pc);
|
||||
}
|
||||
|
@ -133,7 +130,7 @@ static void cpuFrame0(UWO vector_offset, ULO pc)
|
|||
040: Same as for 020
|
||||
========================================================================*/
|
||||
|
||||
void cpuFrame1(UWO vector_offset, ULO pc)
|
||||
void cpuFrame1(uint16_t vector_offset, uint32_t pc)
|
||||
{
|
||||
cpuFrame4Words(0x1000, vector_offset, pc);
|
||||
}
|
||||
|
@ -149,7 +146,7 @@ void cpuFrame1(UWO vector_offset, ULO pc)
|
|||
060: Same as for 040
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrame2(UWO vector_offset, ULO pc)
|
||||
static void cpuFrame2(uint16_t vector_offset, uint32_t pc)
|
||||
{
|
||||
// save inst address
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 4);
|
||||
|
@ -164,7 +161,7 @@ static void cpuFrame2(UWO vector_offset, ULO pc)
|
|||
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrame8(UWO vector_offset, ULO pc)
|
||||
static void cpuFrame8(uint16_t vector_offset, uint32_t pc)
|
||||
{
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 50);
|
||||
cpuFrame4Words(0x8000, vector_offset, pc);
|
||||
|
@ -180,14 +177,14 @@ static void cpuFrame8(UWO vector_offset, ULO pc)
|
|||
Fellow will always generate this frame for bus/address errors
|
||||
========================================================================*/
|
||||
|
||||
static void cpuFrameA(UWO vector_offset, ULO pc)
|
||||
static void cpuFrameA(uint16_t vector_offset, uint32_t pc)
|
||||
{
|
||||
// save vector_offset offset
|
||||
cpuSetAReg(7, cpuGetAReg(7) - 24);
|
||||
cpuFrame4Words(0xa000, vector_offset, pc);
|
||||
}
|
||||
|
||||
void cpuStackFrameGenerate(UWO vector_offset, ULO pc)
|
||||
void cpuStackFrameGenerate(uint16_t vector_offset, uint32_t pc)
|
||||
{
|
||||
cpu_stack_frame_gen_func[vector_offset>>2](vector_offset, pc);
|
||||
}
|
||||
|
@ -198,8 +195,7 @@ void cpuStackFrameGenerate(UWO vector_offset, ULO pc)
|
|||
|
||||
static void cpuStackFrameInitSetDefaultFunc(cpuStackFrameGenFunc default_func)
|
||||
{
|
||||
ULO i;
|
||||
for (i = 0; i < 64; i++)
|
||||
for (uint32_t i = 0; i < 64; i++)
|
||||
cpuSetStackFrameGenFunc(i, default_func);
|
||||
}
|
||||
|
||||
|
|
51
cpu/defs.h
51
cpu/defs.h
|
@ -1,13 +1,10 @@
|
|||
#ifndef DEFS_H
|
||||
#define DEFS_H
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Maximum values for memory, don't change */
|
||||
|
||||
|
@ -16,27 +13,19 @@ extern "C" {
|
|||
#define BOGOMEM 0x1c0000
|
||||
#define KICKMEM 0x080000
|
||||
|
||||
/* Fellow types to ensure correct sizes */
|
||||
|
||||
typedef uint8_t UBY;
|
||||
typedef uint16_t UWO;
|
||||
typedef uint32_t ULO;
|
||||
typedef uint64_t ULL;
|
||||
typedef int8_t BYT;
|
||||
typedef int16_t WOR;
|
||||
typedef int32_t LON;
|
||||
typedef int64_t LLO;
|
||||
typedef int BOOLE;
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
typedef char STR;
|
||||
|
||||
/*
|
||||
#ifndef X64
|
||||
#define PTR_TO_INT(i) ((ULO)i)
|
||||
#define PTR_TO_INT(i) ((uint32_t)i)
|
||||
#define PTR_TO_INT_MASK_TYPE(i) ((uint32_t)i)
|
||||
#endif
|
||||
#ifdef X64
|
||||
#define PTR_TO_INT(i) ((ULL)i)
|
||||
#define PTR_TO_INT(i) ((uint64_t)i)
|
||||
#define PTR_TO_INT_MASK_TYPE(i) ((uint64_t)i)
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
@ -48,17 +37,17 @@ typedef char STR;
|
|||
/* The decode routines have this type */
|
||||
/*------------------------------------*/
|
||||
|
||||
typedef void (*decoderoutinetype)(ULO,ULO);
|
||||
typedef void (*decoderoutinetype)(uint32_t, uint32_t);
|
||||
|
||||
extern UBY configromname[];
|
||||
extern uint8_t configromname[];
|
||||
|
||||
typedef union {
|
||||
ULO *lptr;
|
||||
UWO *wptr;
|
||||
UBY *bptr;
|
||||
ULO lval;
|
||||
UWO wval[2];
|
||||
UBY bval[4];
|
||||
uint32_t *lptr;
|
||||
uint16_t *wptr;
|
||||
uint8_t *bptr;
|
||||
uint32_t lval;
|
||||
uint16_t wval[2];
|
||||
uint8_t bval[4];
|
||||
} ptunion;
|
||||
|
||||
typedef void (*planar2chunkyroutine)(void);
|
||||
|
@ -68,13 +57,3 @@ typedef void (*sound_before_emu_routine)(void);
|
|||
typedef void (*sound_after_emu_routine)(void);
|
||||
|
||||
typedef void (*buseventfunc)(void);
|
||||
|
||||
#define FELLOWVERSION "WinFellow alpha v0.5.0 build 0 (CVS)"
|
||||
#define FELLOWLONGVERSION "WinFellow Amiga Emulator alpha v0.5.0 - CVS"
|
||||
#define FELLOWNUMERICVERSION "0.5.0.0"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
1692
cpu/fmem.c
1692
cpu/fmem.c
File diff suppressed because it is too large
Load Diff
152
cpu/fmem.h
152
cpu/fmem.h
|
@ -1,41 +1,50 @@
|
|||
#ifndef FMEM_H
|
||||
#define FMEM_H
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// new functions
|
||||
|
||||
// MPW
|
||||
extern void memorySetMemory(uint8_t *memory, uint32_t size);
|
||||
extern void memorySetGlobalLog(uint32_t globalLog);
|
||||
extern uint8_t *memoryPointer(uint32_t address);
|
||||
|
||||
|
||||
/* Access for chipset emulation that already have validated addresses */
|
||||
|
||||
#define chipmemReadByte(address) (memory_chip[address])
|
||||
#define chipmemReadWord(address) ((((uint16_t) memory_chip[address]) << 8) | ((uint16_t) memory_chip[address + 1]))
|
||||
#define chipmemWriteWord(data, address) \
|
||||
memory_chip[address] = (uint8_t) (data >> 8); \
|
||||
memory_chip[address + 1] = (uint8_t) data
|
||||
|
||||
/* Memory access functions */
|
||||
|
||||
extern UBY memoryReadByte(ULO address);
|
||||
extern UWO memoryReadWord(ULO address);
|
||||
extern ULO memoryReadLong(ULO address);
|
||||
extern uint64_t memoryReadLongLong(ULO address);
|
||||
extern void memoryWriteByte(UBY data, ULO address);
|
||||
extern void memoryWriteWord(UWO data, ULO address);
|
||||
extern void memoryWriteLong(ULO data, ULO address);
|
||||
extern void memoryWriteLongLong(uint64_t data, ULO address);
|
||||
extern uint8_t memoryReadByte(uint32_t address);
|
||||
extern uint16_t memoryReadWord(uint32_t address);
|
||||
extern uint32_t memoryReadLong(uint32_t address);
|
||||
extern uint64_t memoryReadLongLong(uint32_t address);
|
||||
extern void memoryWriteByte(uint8_t data, uint32_t address);
|
||||
extern void memoryWriteWord(uint16_t data, uint32_t address);
|
||||
extern void memoryWriteLong(uint32_t data, uint32_t address);
|
||||
extern void memoryWriteLongLong(uint64_t data, uint32_t address);
|
||||
|
||||
extern UWO memoryChipReadWord(ULO address);
|
||||
extern void memoryChipWriteWord(UWO data, ULO address);
|
||||
extern uint16_t memoryChipReadWord(uint32_t address);
|
||||
extern void memoryChipWriteWord(uint16_t data, uint32_t address);
|
||||
|
||||
#define memoryReadByteFromPointer(address) (address[0])
|
||||
#define memoryReadWordFromPointer(address) ((address[0] << 8) | address[1])
|
||||
#define memoryReadLongFromPointer(address) ((address[0] << 24) | (address[1] << 16) | (address[2] << 8) | address[3])
|
||||
|
||||
extern void memoryWriteLongToPointer(uint32_t data, uint8_t *address);
|
||||
|
||||
/* IO Bank functions */
|
||||
|
||||
typedef UWO (*memoryIoReadFunc)(ULO address);
|
||||
typedef void (*memoryIoWriteFunc)(UWO data, ULO address);
|
||||
typedef uint16_t (*memoryIoReadFunc)(uint32_t address);
|
||||
typedef void (*memoryIoWriteFunc)(uint16_t data, uint32_t address);
|
||||
|
||||
extern void memorySetIoReadStub(ULO index, memoryIoReadFunc ioreadfunction);
|
||||
extern void memorySetIoWriteStub(ULO index, memoryIoWriteFunc iowritefunction);
|
||||
extern void memorySetIoReadStub(uint32_t index, memoryIoReadFunc ioreadfunction);
|
||||
extern void memorySetIoWriteStub(uint32_t index, memoryIoWriteFunc iowritefunction);
|
||||
|
||||
/* For the copper */
|
||||
extern memoryIoWriteFunc memory_iobank_write[257];
|
||||
|
@ -43,23 +52,24 @@ extern memoryIoWriteFunc memory_iobank_write[257];
|
|||
/* Expansion card functions */
|
||||
|
||||
typedef void (*memoryEmemCardInitFunc)(void);
|
||||
typedef void (*memoryEmemCardMapFunc)(ULO);
|
||||
typedef void (*memoryEmemCardMapFunc)(uint32_t);
|
||||
|
||||
extern void memoryEmemClear(void);
|
||||
extern void memoryEmemCardAdd(memoryEmemCardInitFunc cardinit,
|
||||
memoryEmemCardMapFunc cardmap);
|
||||
extern void memoryEmemSet(ULO index, ULO data);
|
||||
extern void memoryEmemMirror(ULO emem_offset, UBY *src, ULO size);
|
||||
extern void memoryEmemSet(uint32_t index, uint32_t data);
|
||||
extern void memoryEmemMirror(uint32_t emem_offset, uint8_t *src, uint32_t size);
|
||||
|
||||
/* Device memory functions. fhfile is using these. */
|
||||
|
||||
extern void memoryDmemSetByte(UBY data);
|
||||
extern void memoryDmemSetWord(UWO data);
|
||||
extern void memoryDmemSetLong(ULO data);
|
||||
extern void memoryDmemSetLongNoCounter(ULO data, ULO offset);
|
||||
extern void memoryDmemSetString(STR *data);
|
||||
extern void memoryDmemSetCounter(ULO val);
|
||||
extern ULO memoryDmemGetCounter(void);
|
||||
extern void memoryDmemSetByte(uint8_t data);
|
||||
extern void memoryDmemSetWord(uint16_t data);
|
||||
extern void memoryDmemSetLong(uint32_t data);
|
||||
extern void memoryDmemSetLongNoCounter(uint32_t data, uint32_t offset);
|
||||
extern void memoryDmemSetString(const char *data);
|
||||
extern void memoryDmemSetCounter(uint32_t val);
|
||||
extern uint32_t memoryDmemGetCounter(void);
|
||||
extern uint32_t memoryDmemGetCounterWithoutOffset(void);
|
||||
extern void memoryDmemClear(void);
|
||||
|
||||
/* Module management functions */
|
||||
|
@ -76,12 +86,12 @@ extern void memoryShutdown(void);
|
|||
|
||||
/* Memory bank functions */
|
||||
|
||||
typedef UBY (*memoryReadByteFunc)(ULO address);
|
||||
typedef UWO (*memoryReadWordFunc)(ULO address);
|
||||
typedef ULO (*memoryReadLongFunc)(ULO address);
|
||||
typedef void (*memoryWriteByteFunc)(UBY data, ULO address);
|
||||
typedef void (*memoryWriteWordFunc)(UWO data, ULO address);
|
||||
typedef void (*memoryWriteLongFunc)(ULO data, ULO address);
|
||||
typedef uint8_t (*memoryReadByteFunc)(uint32_t address);
|
||||
typedef uint16_t (*memoryReadWordFunc)(uint32_t address);
|
||||
typedef uint32_t (*memoryReadLongFunc)(uint32_t address);
|
||||
typedef void (*memoryWriteByteFunc)(uint8_t data, uint32_t address);
|
||||
typedef void (*memoryWriteWordFunc)(uint16_t data, uint32_t address);
|
||||
typedef void (*memoryWriteLongFunc)(uint32_t data, uint32_t address);
|
||||
|
||||
extern memoryReadByteFunc memory_bank_readbyte[65536];
|
||||
extern memoryReadWordFunc memory_bank_readword[65536];
|
||||
|
@ -90,8 +100,8 @@ extern memoryWriteByteFunc memory_bank_writebyte[65536];
|
|||
extern memoryWriteWordFunc memory_bank_writeword[65536];
|
||||
extern memoryWriteLongFunc memory_bank_writelong[65536];
|
||||
|
||||
extern UBY *memory_bank_pointer[65536];
|
||||
extern UBY *memory_bank_datapointer[65536];
|
||||
extern uint8_t *memory_bank_pointer[65536];
|
||||
extern uint8_t *memory_bank_datapointer[65536];
|
||||
|
||||
extern void memoryBankSet(memoryReadByteFunc rb,
|
||||
memoryReadWordFunc rw,
|
||||
|
@ -99,39 +109,43 @@ extern void memoryBankSet(memoryReadByteFunc rb,
|
|||
memoryWriteByteFunc wb,
|
||||
memoryWriteWordFunc ww,
|
||||
memoryWriteLongFunc wl,
|
||||
UBY *basep,
|
||||
ULO bank,
|
||||
ULO basebank,
|
||||
uint8_t *basep,
|
||||
uint32_t bank,
|
||||
uint32_t basebank,
|
||||
BOOLE pointer_can_write);
|
||||
extern UBY *memoryAddressToPtr(ULO address);
|
||||
extern void memoryChipMap(BOOLE overlay);
|
||||
extern uint8_t *memoryAddressToPtr(uint32_t address);
|
||||
extern void memoryChipMap(bool overlay);
|
||||
|
||||
/* Memory configuration properties */
|
||||
|
||||
extern BOOLE memorySetChipSize(ULO chipsize);
|
||||
extern ULO memoryGetChipSize(void);
|
||||
extern BOOLE memorySetFastSize(ULO fastsize);
|
||||
extern ULO memoryGetFastSize(void);
|
||||
extern void memorySetFastAllocatedSize(ULO fastallocatedsize);
|
||||
extern ULO memoryGetFastAllocatedSize(void);
|
||||
extern BOOLE memorySetSlowSize(ULO bogosize);
|
||||
extern ULO memoryGetSlowSize(void);
|
||||
extern BOOLE memorySetUseAutoconfig(BOOLE useautoconfig);
|
||||
extern BOOLE memoryGetUseAutoconfig(void);
|
||||
extern BOOLE memorySetChipSize(uint32_t chipsize);
|
||||
extern uint32_t memoryGetChipSize(void);
|
||||
extern BOOLE memorySetFastSize(uint32_t fastsize);
|
||||
extern uint32_t memoryGetFastSize(void);
|
||||
extern void memorySetFastAllocatedSize(uint32_t fastallocatedsize);
|
||||
extern uint32_t memoryGetFastAllocatedSize(void);
|
||||
extern BOOLE memorySetSlowSize(uint32_t bogosize);
|
||||
extern uint32_t memoryGetSlowSize(void);
|
||||
extern bool memorySetUseAutoconfig(bool useautoconfig);
|
||||
extern bool memoryGetUseAutoconfig(void);
|
||||
extern BOOLE memorySetAddress32Bit(BOOLE address32bit);
|
||||
extern BOOLE memoryGetAddress32Bit(void);
|
||||
extern BOOLE memorySetKickImage(STR *kickimage);
|
||||
extern STR *memoryGetKickImage(void);
|
||||
extern void memorySetKey(STR *key);
|
||||
extern STR *memoryGetKey(void);
|
||||
extern BOOLE memorySetKickImage(char *kickimage);
|
||||
extern BOOLE memorySetKickImageExtended(char *kickimageext);
|
||||
extern char *memoryGetKickImage(void);
|
||||
extern void memorySetKey(char *key);
|
||||
extern char *memoryGetKey(void);
|
||||
extern BOOLE memoryGetKickImageOK(void);
|
||||
|
||||
/* Derived from memory configuration */
|
||||
|
||||
extern ULO memoryGetKickImageBaseBank(void);
|
||||
extern ULO memoryGetKickImageVersion(void);
|
||||
extern ULO memoryInitialPC(void);
|
||||
extern ULO memoryInitialSP(void);
|
||||
extern uint32_t memoryGetKickImageBaseBank(void);
|
||||
extern uint32_t memoryGetKickImageVersion(void);
|
||||
extern uint32_t memoryInitialPC(void);
|
||||
extern uint32_t memoryInitialSP(void);
|
||||
|
||||
/* Kickstart decryption */
|
||||
extern int memoryKickLoadAF2(char *filename, FILE *F, uint8_t *memory_kick, const bool);
|
||||
|
||||
/* Kickstart load error handling */
|
||||
|
||||
|
@ -148,21 +162,19 @@ extern ULO memoryInitialSP(void);
|
|||
|
||||
/* Global variables */
|
||||
|
||||
extern UBY memory_chip[];
|
||||
extern UBY *memory_fast;
|
||||
extern UBY memory_slow[];
|
||||
extern UBY memory_kick[];
|
||||
extern ULO memory_chipsize;
|
||||
extern UBY memory_emem[];
|
||||
extern uint8_t memory_chip[];
|
||||
extern uint8_t *memory_fast;
|
||||
extern uint8_t memory_slow[];
|
||||
extern uint8_t memory_kick[];
|
||||
extern uint32_t memory_chipsize;
|
||||
extern uint8_t memory_emem[];
|
||||
|
||||
extern ULO intenar,intena,intreq;
|
||||
extern ULO potgor;
|
||||
extern uint32_t potgor;
|
||||
|
||||
extern ULO memory_fault_address;
|
||||
extern uint32_t memory_fault_address;
|
||||
extern BOOLE memory_fault_read;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
86
cpu/memory.c
86
cpu/memory.c
|
@ -8,14 +8,14 @@
|
|||
/*============================================================================*/
|
||||
|
||||
BOOLE memory_fault_read = FALSE; /* TRUE - read / FALSE - write */
|
||||
ULO memory_fault_address = 0;
|
||||
uint32_t memory_fault_address = 0;
|
||||
|
||||
/*==============================================================================
|
||||
Raises exception 3 when a word or long is accessing an odd address
|
||||
and the CPU is < 020
|
||||
==============================================================================*/
|
||||
|
||||
static void memoryOddRead(ULO address)
|
||||
static void memoryOddRead(uint32_t address)
|
||||
{
|
||||
if (address & 1)
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ static void memoryOddRead(ULO address)
|
|||
}
|
||||
}
|
||||
|
||||
static void memoryOddWrite(ULO address)
|
||||
static void memoryOddWrite(uint32_t address)
|
||||
{
|
||||
if (address & 1)
|
||||
{
|
||||
|
@ -48,6 +48,14 @@ static uint8_t *Memory = NULL;
|
|||
static uint32_t MemorySize = 0;
|
||||
static uint32_t MemoryGlobalLog = 0;
|
||||
|
||||
static memoryLoggingFunc MemoryLoggingFunc = NULL;
|
||||
|
||||
void memorySetLoggingFunc(memoryLoggingFunc func)
|
||||
{
|
||||
MemoryLoggingFunc = func;
|
||||
}
|
||||
|
||||
|
||||
void memorySetMemory(uint8_t *memory, uint32_t size)
|
||||
{
|
||||
Memory = memory;
|
||||
|
@ -67,13 +75,12 @@ uint8_t *memoryPointer(uint32_t address)
|
|||
|
||||
// memory read of 0xffffffff not handled correctly
|
||||
// since the unsigned compare overflows.
|
||||
UBY memoryReadByte(ULO address)
|
||||
uint8_t memoryReadByte(uint32_t address)
|
||||
{
|
||||
|
||||
if (address < MemoryGlobalLog)
|
||||
{
|
||||
fprintf(stderr, "memoryReadByte(%08x)\n", address);
|
||||
}
|
||||
if (MemoryLoggingFunc)
|
||||
MemoryLoggingFunc(address, 1, 0, 0);
|
||||
|
||||
|
||||
// hmmm... 32-bit clean addresses?
|
||||
if (address < MemorySize)
|
||||
|
@ -81,44 +88,40 @@ UBY memoryReadByte(ULO address)
|
|||
return 0;
|
||||
}
|
||||
|
||||
UWO memoryReadWord(ULO address)
|
||||
uint16_t memoryReadWord(uint32_t address)
|
||||
{
|
||||
|
||||
if (address < MemoryGlobalLog)
|
||||
{
|
||||
fprintf(stderr, "memoryReadWord(%08x)\n", address);
|
||||
}
|
||||
|
||||
if (MemoryLoggingFunc)
|
||||
MemoryLoggingFunc(address, 2, 0, 0);
|
||||
|
||||
if (address & 0x01) memoryOddRead(address);
|
||||
|
||||
if (address + 1 < MemorySize)
|
||||
return (Memory[address++] << 8)
|
||||
| (Memory[address++] << 0);
|
||||
return (Memory[address + 0] << 8)
|
||||
| (Memory[address + 1] << 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULO memoryReadLong(ULO address)
|
||||
uint32_t memoryReadLong(uint32_t address)
|
||||
{
|
||||
if (address < MemoryGlobalLog)
|
||||
{
|
||||
fprintf(stderr, "memoryReadLong(%08x)\n", address);
|
||||
}
|
||||
|
||||
if (MemoryLoggingFunc)
|
||||
MemoryLoggingFunc(address, 4, 0, 0);
|
||||
|
||||
if (address & 0x01) memoryOddRead(address);
|
||||
|
||||
if (address + 3 < MemorySize)
|
||||
return (Memory[address++] << 24)
|
||||
| (Memory[address++] << 16)
|
||||
| (Memory[address++] << 8)
|
||||
| (Memory[address++] << 0);
|
||||
return (Memory[address + 0] << 24)
|
||||
| (Memory[address + 1] << 16)
|
||||
| (Memory[address + 2] << 8)
|
||||
| (Memory[address + 3] << 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint64_t memoryReadLongLong(ULO address)
|
||||
uint64_t memoryReadLongLong(uint32_t address)
|
||||
{
|
||||
uint64_t tmp;
|
||||
|
||||
|
@ -129,12 +132,11 @@ uint64_t memoryReadLongLong(ULO address)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
void memoryWriteByte(UBY data, ULO address)
|
||||
void memoryWriteByte(uint8_t data, uint32_t address)
|
||||
{
|
||||
if (address < MemoryGlobalLog)
|
||||
{
|
||||
fprintf(stderr, "memoryWriteByte(%02x, %08x)\n", data, address);
|
||||
}
|
||||
|
||||
if (MemoryLoggingFunc)
|
||||
MemoryLoggingFunc(address, 1, 1, data);
|
||||
|
||||
if (address < MemorySize)
|
||||
{
|
||||
|
@ -142,13 +144,11 @@ void memoryWriteByte(UBY data, ULO address)
|
|||
}
|
||||
}
|
||||
|
||||
void memoryWriteWord(UWO data, ULO address)
|
||||
void memoryWriteWord(uint16_t data, uint32_t address)
|
||||
{
|
||||
|
||||
if (address < MemoryGlobalLog)
|
||||
{
|
||||
fprintf(stderr, "memoryWriteWord(%04x, %08x)\n", data, address);
|
||||
}
|
||||
if (MemoryLoggingFunc)
|
||||
MemoryLoggingFunc(address, 2, 1, data);
|
||||
|
||||
if (address & 0x01) memoryOddWrite(address);
|
||||
|
||||
|
@ -159,13 +159,11 @@ void memoryWriteWord(UWO data, ULO address)
|
|||
}
|
||||
}
|
||||
|
||||
void memoryWriteLong(ULO data, ULO address)
|
||||
void memoryWriteLong(uint32_t data, uint32_t address)
|
||||
{
|
||||
|
||||
if (address < MemoryGlobalLog)
|
||||
{
|
||||
fprintf(stderr, "memoryWriteLong(%08x, %08x)\n", data, address);
|
||||
}
|
||||
if (MemoryLoggingFunc)
|
||||
MemoryLoggingFunc(address, 4, 1, data);
|
||||
|
||||
|
||||
if (address & 0x01) memoryOddWrite(address);
|
||||
|
@ -180,12 +178,8 @@ void memoryWriteLong(ULO data, ULO address)
|
|||
}
|
||||
|
||||
|
||||
void memoryWriteLongLong(uint64_t data, ULO address)
|
||||
void memoryWriteLongLong(uint64_t data, uint32_t address)
|
||||
{
|
||||
if (address < MemoryGlobalLog)
|
||||
{
|
||||
fprintf(stderr, "memoryWriteLongLong(%08llx, %08x)\n", data, address);
|
||||
}
|
||||
|
||||
if (address & 0x01) memoryOddWrite(address);
|
||||
|
||||
|
|
81
cxx/string_splitter.h
Normal file
81
cxx/string_splitter.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
#ifndef __string_splitter__
|
||||
#define __string_splitter__
|
||||
|
||||
#include <string>
|
||||
|
||||
class string_splitter {
|
||||
public:
|
||||
string_splitter(const std::string &str, char sep) :
|
||||
_parent(str), _sep(sep)
|
||||
{
|
||||
_begin = 0;
|
||||
_end = _parent.find(_sep);
|
||||
_str = _parent.substr(_begin, _end);
|
||||
// _begin is 0, _end is either npos or offset from 0,
|
||||
// so no need to calculate a count.
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return _begin != npos;
|
||||
}
|
||||
|
||||
string_splitter &operator++() {
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::string &operator *() const {
|
||||
return _str;
|
||||
}
|
||||
|
||||
const std::string *operator ->() const {
|
||||
return &_str;
|
||||
}
|
||||
|
||||
private:
|
||||
void increment() {
|
||||
_str.clear();
|
||||
if (_begin == npos) return;
|
||||
if (_end == npos) { _begin = _end; return; }
|
||||
|
||||
_begin = _end + 1;
|
||||
_end = _parent.find(_sep, _begin);
|
||||
auto count = _end == npos ? _end : _end - _begin;
|
||||
_str = _parent.substr(_begin, count);
|
||||
}
|
||||
|
||||
const static auto npos = std::string::npos;
|
||||
std::string _str;
|
||||
const std::string &_parent;
|
||||
char _sep;
|
||||
std::string::size_type _begin = 0;
|
||||
std::string::size_type _end = 0;
|
||||
};
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s sep string\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (strlen(argv[1]) != 1) {
|
||||
fprintf(stderr, "Separator must be a single character\n");
|
||||
return 1;
|
||||
}
|
||||
char sep = argv[1][0];
|
||||
std::string str(argv[2]);
|
||||
|
||||
for (auto iter = string_splitter(str, sep); iter; ++iter) {
|
||||
printf("%s\n", iter->c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
1
libsane
Submodule
1
libsane
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 8a47aacd7d8a19566701ae60dd03ff3c6e6b3634
|
|
@ -1,10 +1,3 @@
|
|||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -g")
|
||||
|
||||
add_definitions(-I ${CMAKE_SOURCE_DIR}/)
|
||||
|
||||
set(MACOS_SRC traps.c sysequ.c)
|
||||
|
||||
set(MACOS_SRC traps.c sysequ.c errors.cpp)
|
||||
|
||||
add_library(MACOS_LIB ${MACOS_SRC})
|
945
macos/errors.cpp
Normal file
945
macos/errors.cpp
Normal file
|
@ -0,0 +1,945 @@
|
|||
|
||||
#include <cstddef> // null
|
||||
#include <cstdint>
|
||||
#include <cerrno>
|
||||
#include <string>
|
||||
|
||||
#include "errors.h"
|
||||
|
||||
const char *ErrorName(int16_t error)
|
||||
{
|
||||
switch(error)
|
||||
{
|
||||
case -32768: return "Temporarily disable card but run primary init.";
|
||||
case -32767: return "Bad component instance";
|
||||
case -32766: return "Bad component selector";
|
||||
case -32640: return "Reserve range -32640 to -32768 for Apple temp disables.";
|
||||
case -32615: return "Bitmap font passed to routine that does outlines only";
|
||||
case -32100: return "Can't mount system startup volume";
|
||||
case -32086: return "Circular reference in hierarchical menu";
|
||||
case -32085: return "Unable to load menu bar defproc";
|
||||
case -32041: return "The file named \"Finder\" can't be found on the disk";
|
||||
case -32030: return "\"Please insert the disk\"";
|
||||
case -32029: return "File server error";
|
||||
case -32028: return "Stack overflow: the stack has expanded into the heap";
|
||||
case -32027: return "File map destroyed";
|
||||
case -32026: return "Segment Loader error: a GetResource call to read a 'CODE' resource failed";
|
||||
case -32025: return "Can't allocate requested memory block in heap";
|
||||
case -32024: return "Can't load package";
|
||||
case -32023: return "Can't load package";
|
||||
case -32022: return "Can't load package";
|
||||
case -32021: return "Can't load package";
|
||||
case -32020: return "Can't load package";
|
||||
case -32019: return "Can't load package";
|
||||
case -32018: return "Can't load package";
|
||||
case -32017: return "Can't load package";
|
||||
case -32016: return "Floating point error";
|
||||
case -32015: return "Segment Loader error: a GetResource call failed";
|
||||
case -32014: return "I/O system error";
|
||||
case -32013: return "Spurious interrupt";
|
||||
case -32012: return "Unimplemented core routine: Unimplemented trap number encountered";
|
||||
case -32011: return "Miscellaneous exception";
|
||||
case -32010: return "Line 1111 exception: Unimplemented instruction";
|
||||
case -32009: return "Line 1010 exception: the 1010 trap dispatcher has failed";
|
||||
case -32008: return "Trace exception";
|
||||
case -32007: return "Privilege violation";
|
||||
case -32006: return "Trap V exception";
|
||||
case -32005: return "Check exception: value out of range";
|
||||
case -32004: return "Zero divide";
|
||||
case -32003: return "Illegal instruction";
|
||||
case -32002: return "Address error: word or long-word reference to an odd address";
|
||||
case -32001: return "Bus error: invalid memory reference";
|
||||
case -31009: return "Inconsistent dump format";
|
||||
case -31008: return "Invalid file type";
|
||||
case -31007: return "Illegal use of I/O control block";
|
||||
case -31006: return "Attempt to use I/O control block which is currently in use";
|
||||
case -31005: return "Too many includes";
|
||||
case -31004: return "I/O system error (illegal use of buffer)";
|
||||
case -31003: return "Not enough heap space to allocate I/O control block";
|
||||
case -31002: return "Not enough heap space to allocate I/O buffer";
|
||||
case -31001: return "Not a text file";
|
||||
case -20002: return "The recordIndex parameter is not valid";
|
||||
case -20001: return "The record data is bigger than buffer size (1024 bytes)";
|
||||
case -20000: return "There is no such insert mode";
|
||||
case -13005: return "Power Manager did not finish handshake during receive";
|
||||
case -13004: return "Power Manager did not start handshake during receive";
|
||||
case -13003: return "Power Manager did not finish handshake during send";
|
||||
case -13002: return "Power Manager did not start handshake during send";
|
||||
case -13001: return "Timed out waiting for reply";
|
||||
case -13000: return "Power Manager never ready to start handshake";
|
||||
case -11005: return "The picture data was invalid ";
|
||||
case -11004: return "The number of colors requested was illegal ";
|
||||
case -11003: return "Custom pick method not in resource chain";
|
||||
case -11002: return "Invalid verb combination specified";
|
||||
case -11001: return "Invalid PictInfo ID";
|
||||
case -11000: return "Version number not zero";
|
||||
case -10016: return "Apple Event Local Only";
|
||||
case -10015: return "Apple Event Can't Undo";
|
||||
case -10014: return "Apple Event Not A Single Object";
|
||||
case -10013: return "Apple Event No User Selection";
|
||||
case -10012: return "Apple Event No Such Transaction";
|
||||
case -10011: return "Apple Event In Transaction";
|
||||
case -10010: return "Apple Event Can't Handle Class";
|
||||
case -10009: return "Apple Event Can't Supply Type";
|
||||
case -10008: return "Apple Event Not An Element";
|
||||
case -10007: return "Apple Event Index Too Large";
|
||||
case -10006: return "Apple Event Write Denied";
|
||||
case -10005: return "Apple Event Read Denied";
|
||||
case -10004: return "Apple Event Privilege Error";
|
||||
case -10003: return "Apple Event Not Modifiable";
|
||||
case -10002: return "Apple Event Bad Key Form";
|
||||
case -10001: return "Apple Event Type Error";
|
||||
case -10000: return "Apple Event Failed";
|
||||
case -9999: return "Can't move attached controller";
|
||||
case -9998: return "Controller has fixed height";
|
||||
case -9997: return "Can't set width of attached controller";
|
||||
case -9996: return "Controller bounds not exact";
|
||||
case -9995: return "Editing not allowed ";
|
||||
case -9994: return "Bad controller height";
|
||||
case -9408: return "Device can't meet request";
|
||||
case -9407: return "Sequence grab info not available";
|
||||
case -9406: return "Bad SG channel";
|
||||
case -9405: return "Couldn't get required component";
|
||||
case -9404: return "Not enough disk space to grab";
|
||||
case -9403: return "Not enough memory to grab";
|
||||
case -9402: return "Can't do that in current mode";
|
||||
case -9401: return "Grab time complete";
|
||||
case -9400: return "No device for channel";
|
||||
case -8976: return "Codec Nothing to Blit error";
|
||||
case -8975: return "Codec Can't Queue error";
|
||||
case -8974: return "Codec Can't When error";
|
||||
case -8973: return "Codec open error";
|
||||
case -8972: return "Codec Condition error";
|
||||
case -8971: return "Codec extension not found error";
|
||||
case -8970: return "Codec data version error";
|
||||
case -8969: return "Codec bad data error";
|
||||
case -8968: return "Codec off screen error";
|
||||
case -8967: return "Codec abort error";
|
||||
case -8966: return "Codec spool error";
|
||||
case -8965: return "Codec image buffer error";
|
||||
case -8964: return "Codec screen buffer error";
|
||||
case -8963: return "Codec size error";
|
||||
case -8962: return "Codec unimplemented error";
|
||||
case -8961: return "No codec error";
|
||||
case -8960: return "Codec error";
|
||||
case -8159: return "Printer not initialized";
|
||||
case -8151: return "Incompatible printer initialization";
|
||||
case -8150: return "No printer chosen";
|
||||
case -8133: return "Postscript error";
|
||||
case -6230: return "Attempt to add an already installed display";
|
||||
case -6229: return "Could not find item";
|
||||
case -6228: return "Video Driver does not support display manager";
|
||||
case -6227: return "Required software not initialized (eg window manager or display mgr)";
|
||||
case -6226: return "Missing critical pieces of System Software";
|
||||
case -6225: return "Mirroring is off; should be turned on";
|
||||
case -6224: return "Can't Block because mirroring is on (first call DMUnMirror() )";
|
||||
case -6223: return "DMBlockMirroring() has been called";
|
||||
case -6222: return "More than two displays attempted";
|
||||
case -6221: return "Mirroring is on; should be turned off";
|
||||
case -6220: return "Display Manager unexpected error";
|
||||
case -5553: return "Gestalt function pointer wasn't in sysheap";
|
||||
case -5552: return "Tried to add an entry that already existed";
|
||||
case -5551: return "Undefined selector was passed to Gestalt";
|
||||
case -5550: return "Value returned if Gestalt doesn't know the answer";
|
||||
case -5502: return "The version requested is greater than the current SysEnvirons trap can provide";
|
||||
case -5501: return "Non-positive selector was passed to SysEnvirons trap";
|
||||
case -5500: return "SysEnvirons call not present as a trap";
|
||||
case -5044: return "the folder being shared is inside or being moved to the trash folder";
|
||||
case -5043: return "the folder being shared is inside or being moved to a shared folder";
|
||||
case -5042: return "the password being used is too old: this requires the user to change the password before log-in can continue";
|
||||
case -5041: return "the password being set is too short: there is a minimum length that must be met or exceeded";
|
||||
case -5040: return "someone tried to change their password to the same password on a mandatory password change";
|
||||
case -5039: return "afpBadIDErr";
|
||||
case -5038: return "afpSameObjectErr";
|
||||
case -5037: return "afpCatalogChanged";
|
||||
case -5036: return "afpDiffVolErr";
|
||||
case -5035: return "afpIDExists";
|
||||
case -5034: return "afpIDNotFound";
|
||||
case -5033: return "the folder being shared contains a shared folder";
|
||||
case -5032: return "Object is MODIFY/READ/DELETE/WRITE inhibited";
|
||||
case -5031: return "Volume is Read-Only";
|
||||
case -5030: return "Icon size specified different from existing icon size";
|
||||
case -5029: return "Unknown directory specified";
|
||||
case -5028: return "AFPRename cannot rename volume";
|
||||
case -5027: return "Server is shutting down";
|
||||
case -5026: return "Maximum open file count reached";
|
||||
case -5025: return "File/Directory specified where Directory/File expected";
|
||||
case -5024: return "Unsupported AFP call was made";
|
||||
case -5023: return "No AFPLogin call has successfully been made for this session";
|
||||
case -5022: return "Session closed";
|
||||
case -5021: return "Some or all of range already locked by same user";
|
||||
case -5020: return "Tried to unlock range that was not locked by user";
|
||||
case -5019: return "A specified parameter was out of allowable range";
|
||||
case -5018: return "Specified file or directory does not exist";
|
||||
case -5017: return "Specified destination file or directory already exists";
|
||||
case -5016: return "Server not responding";
|
||||
case -5015: return "Maximum lock limit reached";
|
||||
case -5014: return "Unexpected error encountered during execution";
|
||||
case -5013: return "Some or all of requested range is locked by another user";
|
||||
case -5012: return "Unknown UserName/UserID or missing comment/APPL entry";
|
||||
case -5011: return "Cannot create directory on specified volume";
|
||||
case -5010: return "Cannot delete an open file";
|
||||
case -5009: return "Read beyond logical end-of-file";
|
||||
case -5008: return "Insufficient free space on volume for operation";
|
||||
case -5007: return "Cannot delete non-empty directory";
|
||||
case -5006: return "Specified open/deny modes conflict with current open modes";
|
||||
case -5005: return "Move destination is offspring of source, or root was specified";
|
||||
case -5004: return "Bitmap contained bits undefined for call";
|
||||
case -5003: return "Unknown AFP version number specified";
|
||||
case -5002: return "Unknown user authentication method specified";
|
||||
case -5001: return "Further information required to complete AFPLogin call";
|
||||
case -5000: return "Insufficient access privileges for operation";
|
||||
case -4101: return "Printer not found or closed";
|
||||
case -4100: return "Connection to printer closed";
|
||||
case -4099: return "Printing failure: write request too big";
|
||||
case -4098: return "Printing failure: request already active";
|
||||
case -4097: return "Printing failure: bad connection reference number";
|
||||
case -4096: return "Printing failure: no free connect control blocks available";
|
||||
case -3109: return "Asynchronous call aborted because socket was closed before call was completed";
|
||||
case -3108: return "ABRecord not found";
|
||||
case -3107: return "Bad response from ATPRequest";
|
||||
case -3106: return "ATP response message too large";
|
||||
case -3105: return "Socket or protocol type invalid or not found in table";
|
||||
case -3104: return "NBP can't find tuple in buffer";
|
||||
case -3103: return "DDP bad checksum";
|
||||
case -3102: return "MPP driver not installed";
|
||||
case -3101: return "ALAP frame too large for buffer / DDP datagram too large for buffer";
|
||||
case -3032: return "noPrefAppErr";
|
||||
case -3031: return "Bad translation spec";
|
||||
case -3030: return "No translation path";
|
||||
case -3026: return "Could not parse source file";
|
||||
case -3025: return "Invalid translation path";
|
||||
case -3003: return "Component doesn't register";
|
||||
case -3002: return "Component not captured";
|
||||
case -3001: return "Valid instances exist";
|
||||
case -3000: return "Invalid component ID";
|
||||
case -2824: return "Invalid fragment usage";
|
||||
case -2823: return "Fragment targeted for an unacceptable architecture";
|
||||
case -2822: return "No application found in cfrg (for Process Manager)";
|
||||
case -2821: return "Fragment user initialization routine did not return noErr";
|
||||
case -2820: return "Fragment container corrupted (known format) ";
|
||||
case -2819: return "Fragment internal inconsistency ";
|
||||
case -2818: return "Error in initialization of CFM";
|
||||
case -2817: return "Error connecting to library (error occurred in sub prepare) ";
|
||||
case -2816: return "Boot library has initialization routine";
|
||||
case -2815: return "Fragment circularity detected in mandatory initialization order";
|
||||
case -2814: return "Import library was too new and therefore incompatible";
|
||||
case -2813: return "Import library was too old and therefore incompatible";
|
||||
case -2812: return "Fragment order error during user initialization function invocation";
|
||||
case -2811: return "Fragment no more context id's";
|
||||
case -2810: return "Fragment out of memory in user's address space for loadable section";
|
||||
case -2809: return "Fragment out of memory for internal bookkeeping";
|
||||
case -2807: return "Loaded fragment had \"hard\" unresolved imports";
|
||||
case -2806: return "Fragment container format unknown";
|
||||
case -2805: return "Fragment registered name already in use";
|
||||
case -2804: return "Fragment library name not found in registry";
|
||||
case -2803: return "Fragment section not found";
|
||||
case -2802: return "Fragment symbol not found in connection";
|
||||
case -2801: return "Fragment connectionID not valid";
|
||||
case -2800: return "Fragment contextID not valid";
|
||||
case -2780: return "AppleScript inconsistent names";
|
||||
case -2763: return "AppleScript no result returned";
|
||||
case -2762: return "AppleScript parameter not for event";
|
||||
case -2761: return "AppleScript illegal formal parameter";
|
||||
case -2760: return "AppleScript terminology nesting too deep";
|
||||
case -2721: return "AppleScript can't compare more than 32k";
|
||||
case -2720: return "AppleScript can't consider and ignore";
|
||||
case -2526: return "Mixed mode internal error";
|
||||
case -2519: return "TSM unknown error";
|
||||
case -2518: return "TSM Unsupported interface type";
|
||||
case -2517: return "TSM script has no input method or is using old IM";
|
||||
case -2516: return "TSM returned by GetDefaultInputMethod";
|
||||
case -2515: return "TSM text service already opened for the document";
|
||||
case -2514: return "TSM text service is not open";
|
||||
case -2513: return "TSM the text service has no menu";
|
||||
case -2512: return "Not TSM aware because we are using input window";
|
||||
case -2511: return "TSM there are open documents";
|
||||
case -2510: return "TSM no text service found";
|
||||
case -2509: return "TSM can't open the component";
|
||||
case -2508: return "TSM no open text service";
|
||||
case -2507: return "TSM document is not active";
|
||||
case -2506: return "TSM document is still active";
|
||||
case -2505: return "Invalid TSM documentation ID ";
|
||||
case -2504: return "TSM application not registered";
|
||||
case -2503: return "TSM application already registered";
|
||||
case -2502: return "TSM not an application";
|
||||
case -2501: return "TSM input method not found";
|
||||
case -2500: return "Unsupported script language error";
|
||||
case -2062: return "Movie text not found";
|
||||
case -2059: return "Samples already in media";
|
||||
case -2058: return "Auxiliary export data unavailable";
|
||||
case -2057: return "Unsupported auxiliary import data";
|
||||
case -2053: return "Feature unsupported";
|
||||
case -2052: return "Couldn't use an existing sample";
|
||||
case -2051: return "No defaultdata reference";
|
||||
case -2050: return "Bad data reference index";
|
||||
case -2049: return "Invalid data reference container";
|
||||
case -2048: return "No movie found";
|
||||
case -2047: return "No data reference";
|
||||
case -2046: return "End of data reached";
|
||||
case -2045: return "data already closed";
|
||||
case -2044: return "Data already open for write";
|
||||
case -2043: return "Data not open for write";
|
||||
case -2042: return "Data not open for read";
|
||||
case -2041: return "Invalid sample description";
|
||||
case -2040: return "Invalid chunk cache";
|
||||
case -2039: return "Invalid sample description index";
|
||||
case -2038: return "Invalid chunk number";
|
||||
case -2037: return "Invalid sample number";
|
||||
case -2036: return "Invalid rectangle";
|
||||
case -2035: return "Can't enable track";
|
||||
case -2034: return "Internal QuickTime error";
|
||||
case -2033: return "Bad edit index";
|
||||
case -2032: return "Time not in media";
|
||||
case -2031: return "Time not in track";
|
||||
case -2030: return "Track not in movie";
|
||||
case -2029: return "Track ID not found";
|
||||
case -2028: return "Bad track index";
|
||||
case -2027: return "Max size to grow too small";
|
||||
case -2026: return "User data item not found";
|
||||
case -2025: return "Stale edit state";
|
||||
case -2024: return "Non-matching edit state";
|
||||
case -2023: return "Invalid edit state";
|
||||
case -2022: return "Can't create single fork file";
|
||||
case -2021: return "WF file not found";
|
||||
case -2020: return "Movie toolbox uninitialized";
|
||||
case -2019: return "Progress proc aborted";
|
||||
case -2018: return "Media types don't match";
|
||||
case -2017: return "Bad edit list";
|
||||
case -2016: return "Can't put public movie atom";
|
||||
case -2015: return "Invalid Time";
|
||||
case -2014: return "Invalid duration";
|
||||
case -2013: return "Invalid handler";
|
||||
case -2012: return "Invalid data reference";
|
||||
case -2011: return "Invalid sample table";
|
||||
case -2010: return "Invalid movie";
|
||||
case -2009: return "Invalid track";
|
||||
case -2008: return "Invalid media";
|
||||
case -2007: return "No data handler";
|
||||
case -2006: return "No media handler";
|
||||
case -2005: return "Bad component type";
|
||||
case -2004: return "Can't open handler";
|
||||
case -2003: return "Can't find handler";
|
||||
case -2002: return "Bad public movie atom";
|
||||
case -2001: return "Bad image description";
|
||||
case -2000: return "Could not resolve data reference";
|
||||
case -1857: return "Drag was not accepted by receiver";
|
||||
case -1856: return "Handler not found (Drag Manager)";
|
||||
case -1855: return "Handler already exists (Drag Manager) ";
|
||||
case -1854: return "Error while trying to get flavor data (Drag Manager)";
|
||||
case -1853: return "Flavor type already exists (Drag Manager)";
|
||||
case -1852: return "Unknown flavor type (Drag Manager)";
|
||||
case -1851: return "Unknown drag item reference";
|
||||
case -1850: return "Unknown drag reference";
|
||||
case -1813: return "Apple Event end of body";
|
||||
case -1812: return "Apple Event end of document";
|
||||
case -1811: return "Apple Event top of body";
|
||||
case -1810: return "Apple Event top of document";
|
||||
case -1801: return "Apple Event offset outside of view";
|
||||
case -1800: return "Apple Event offset invalid";
|
||||
case -1730: return "Empty list container";
|
||||
case -1729: return "Negative count";
|
||||
case -1728: return "No such object";
|
||||
case -1727: return "Not an object specifier";
|
||||
case -1726: return "Bad test key";
|
||||
case -1725: return "No such logical operator";
|
||||
case -1723: return "Accessor not found";
|
||||
case -1721: return "Wrong number of arguments";
|
||||
case -1720: return "Impossible range";
|
||||
case -1719: return "Index is out of range in a put operation";
|
||||
case -1718: return "The contents of the reply you are accessing have not arrived yet";
|
||||
case -1717: return "No handler in the dispatch tables fits the parameters";
|
||||
case -1716: return "The target address type is not known";
|
||||
case -1715: return "A required parameter was not accessed";
|
||||
case -1714: return "There is no special function with this keyword";
|
||||
case -1713: return "No user interaction allowed";
|
||||
case -1712: return "AppleEvent timed out";
|
||||
case -1711: return "In AESend, User canceled out of wait loop for reply or receipt";
|
||||
case -1710: return "Mode wasn't NoReply, WaitReply, or QueueReply; or Interaction level is unknown";
|
||||
case -1709: return "AEResetTimer was passed an invalid reply parameter";
|
||||
case -1708: return "The AppleEvent was not handled by any handler";
|
||||
case -1707: return "The event is not in AppleEvent format";
|
||||
case -1706: return "Need newer version of AppleEvent Manager";
|
||||
case -1705: return "Specified list item does not exist";
|
||||
case -1704: return "Not a valid AppleEvent descriptor";
|
||||
case -1703: return "Data with a keyword was expected but not found";
|
||||
case -1702: return "Data in an AppleEvent could not be read";
|
||||
case -1701: return "Descriptor was not found";
|
||||
case -1700: return "Data could not be coerced to the requested data type";
|
||||
case -1308: return "When _Mount allows only remounts and doesn't get a remount.";
|
||||
case -1307: return "File id is dangling or doesn't match with the file number";
|
||||
case -1306: return "Can't exchange a file with itself";
|
||||
case -1305: return "Desktop database files are corrupted";
|
||||
case -1304: return "The catalog has been modified";
|
||||
case -1303: return "Files on different volumes";
|
||||
case -1302: return "Directory specified";
|
||||
case -1301: return "File id already exists";
|
||||
case -1300: return "No file thread exists.";
|
||||
case -1280: return "Bad connection refNum";
|
||||
case -1279: return "Control call was aborted";
|
||||
case -1278: return "Bad connection state for this operation";
|
||||
case -1277: return "Open connection request failed";
|
||||
case -1276: return "Attention message too long";
|
||||
case -1275: return "Read terminated by forward reset";
|
||||
case -1274: return "DSP Read/Write Queue Too small";
|
||||
case -1273: return "Open connection request was denied";
|
||||
case -1105: return "Request aborted";
|
||||
case -1104: return "Too many outstanding ATP calls";
|
||||
case -1103: return "ATPAddRsp issued before ATPSndRsp";
|
||||
case -1102: return "ATP control block not found";
|
||||
case -1101: return "ATP no release received";
|
||||
case -1100: return "ATP bad sequence number";
|
||||
case -1099: return "ATP bad responding socket";
|
||||
case -1098: return "ATP too many responding sockets";
|
||||
case -1097: return "ATP too many concurrent requests";
|
||||
case -1096: return "ATPSndRequest failed: retry count exceeded";
|
||||
case -1075: return "No acknowledge on server attention request";
|
||||
case -1074: return "Too many server clients";
|
||||
case -1073: return "Command block too big";
|
||||
case -1072: return "Session closed";
|
||||
case -1071: return "Server cannot open another session";
|
||||
case -1070: return "ASP parameter error";
|
||||
case -1069: return "No servers at that address";
|
||||
case -1068: return "No more sessions on server";
|
||||
case -1067: return "Buffer too small";
|
||||
case -1066: return "Server cannot support this ASP version";
|
||||
case -1029: return "NBP names information socket error";
|
||||
case -1028: return "NBP name not found";
|
||||
case -1027: return "NBP duplicate name already exists";
|
||||
case -1026: return "NBP name confirmed for different socket";
|
||||
case -1025: return "NBP name not confirmed";
|
||||
case -1024: return "NBP buffer overflow";
|
||||
case -1011: return "Mixed mode failure";
|
||||
case -1010: return "Bad shared library";
|
||||
case -1000: return "No mask found";
|
||||
case -932: return "Destination port requires authentication";
|
||||
case -931: return "Location name is invalid ";
|
||||
case -930: return "Illegal service type, or not supported ";
|
||||
case -928: return "Invalid user reference number ";
|
||||
case -927: return "User's password is wrong";
|
||||
case -926: return "PPCStart failed because destination did not have inform pending ";
|
||||
case -925: return "Error has occurred in the network";
|
||||
case -924: return "Unable to create a new userRefNum";
|
||||
case -923: return "The default userRefNum does not yet exist ";
|
||||
case -922: return "User hasn't specified an owner's name in Sharing Setup Control Panel ";
|
||||
case -919: return "PPCPortRec malformed";
|
||||
case -917: return "The session was closed ";
|
||||
case -916: return "The port was closed";
|
||||
case -915: return "Unable to contact application ";
|
||||
case -914: return "A system resource is missing";
|
||||
case -913: return "User hasn't named his Macintosh in the Sharing Setup Control Panel";
|
||||
case -912: return "Destination rejected the session request";
|
||||
case -911: return "User name unknown on destination machine ";
|
||||
case -910: return "A port is already open with this name";
|
||||
case -909: return "Bad parameter or invalid state for operation";
|
||||
case -908: return "Invalid session reference number ";
|
||||
case -907: return "Out of session tables";
|
||||
case -906: return "Port does not exist at destination";
|
||||
case -905: return "Network activity is currently disabled ";
|
||||
case -904: return "The system is unable to allocate memory, critical error";
|
||||
case -903: return "Unable to open port or bad portRefNum";
|
||||
case -902: return "Invalid or inappropriate locationKindSelector in location name";
|
||||
case -900: return "PPCToolBox not initialized ";
|
||||
case -863: return "User using Close View won't let you remove balloons";
|
||||
case -862: return "No balloon showing";
|
||||
case -861: return "Invalid method passed in the method parameter";
|
||||
case -860: return "Help Manager - could not load package";
|
||||
case -859: return "Help message record contained a bad type";
|
||||
case -858: return "Help manager resource was the wrong version";
|
||||
case -857: return "No balloon content to fill in";
|
||||
case -856: return "Help Manager - bad selector";
|
||||
case -855: return "Help menu not set up";
|
||||
case -854: return "Menu & item is same as previous menu, item";
|
||||
case -853: return "Because of constant cursor movement, the help balloon was not displayed";
|
||||
case -852: return "Help Manager - out of memory";
|
||||
case -851: return "Help Manager - resource not found";
|
||||
case -850: return "Show Balloons mode was off, call to routine ignored";
|
||||
case -813: return "Attempt to call other routine before InitDBPack";
|
||||
case -812: return "Wrong version ";
|
||||
case -811: return "No application handler for specified data type";
|
||||
case -810: return "Invalid parameter block specified";
|
||||
case -809: return "The database extension does not support async calls";
|
||||
case -808: return "Couldn't open or find the specified database extension.";
|
||||
case -807: return "Invalid session number";
|
||||
case -806: return "Session ID is invalid";
|
||||
case -805: return "Query currently executing";
|
||||
case -804: return "Function timed out";
|
||||
case -803: return "Next data item not of requested data type";
|
||||
case -802: return "Error executing function";
|
||||
case -801: return "Data available or successfully retrieved";
|
||||
case -800: return "The data item was NULL";
|
||||
case -625: return "Unable to defer additional functions";
|
||||
case -624: return "Called with interrupts masked";
|
||||
case -623: return "Specified range of memory is not locked";
|
||||
case -622: return "Cannot make specified range contiguous";
|
||||
case -621: return "Specified range of memory is not held";
|
||||
case -620: return "Insufficient physical memory";
|
||||
case -619: return "Bad thread protocol";
|
||||
case -618: return "Thread not found";
|
||||
case -617: return "Thread Manager--Too many reqs";
|
||||
case -610: return "Cannot interact directly with user";
|
||||
case -609: return "Connection is invalid";
|
||||
case -608: return "No outstanding high-level event";
|
||||
case -607: return "Buffer is too small";
|
||||
case -606: return "Application is background only";
|
||||
case -605: return "Application SIZE not big enough for launch ";
|
||||
case -604: return "Hardware configuration is not correct for call ";
|
||||
case -603: return "Application made module calls in improper order ";
|
||||
case -602: return "Memory mode is 32-bit, but application is not 32-bit clean ";
|
||||
case -601: return "Not enough room to launch application with special requirements";
|
||||
case -600: return "No eligible process with specified process serial number ";
|
||||
case -502: return "Bad selector for _HWPriv";
|
||||
case -501: return "Scrap item too big for text edit record";
|
||||
case -500: return "Region is too big";
|
||||
case -492: return "User debugger break - execute commands on stack";
|
||||
case -491: return "User debugger break - display string on stack";
|
||||
case -490: return "User debugger break";
|
||||
case -489: return "Unimplemented routine was called (SCSI)";
|
||||
case -479: return "Linked command never executed (SCSI)";
|
||||
case -478: return "Device did not go through a status phase (SCSI)";
|
||||
case -477: return "Non-zero (not \"Good\") status returned (SCSI)";
|
||||
case -476: return "The bus was reset, so your request was aborted (SCSI)";
|
||||
case -475: return "scsiReqTO exceeded (SCSI)";
|
||||
case -474: return "scsiSelTO exceeded (selection failed) (SCSI)";
|
||||
case -473: return "(SCSI)us error during transfer (SCSI)";
|
||||
case -472: return "Write flag conflicts with data transfer phase (SCSI)";
|
||||
case -471: return "Attempted to transfer too many bytes (SCSI)";
|
||||
case -470: return "Invalid field(s) in the parameter block (SCSI)";
|
||||
case -463: return "Not the first registered publisher for that container";
|
||||
case -462: return "Container already opened by this section";
|
||||
case -461: return "Alias was not resolved";
|
||||
case -460: return "A Publisher is already registered for that container";
|
||||
case -454: return "Bad edition container spec or invalid edition container";
|
||||
case -453: return "Edition file is corrupt";
|
||||
case -452: return "Not a registered section type";
|
||||
case -451: return "Not a valid section type";
|
||||
case -450: return "Edition manager not initialized or could not load package.";
|
||||
case -417: return "There is no such a key attribute";
|
||||
case -416: return "Maximum key length is too long or equal to zero";
|
||||
case -415: return "Record cannot be found";
|
||||
case -414: return "Record already exists";
|
||||
case -413: return "Can't allocate disk space";
|
||||
case -410: return "The file is not a dictionary";
|
||||
case -400: return "GCR format on high density media error";
|
||||
case -360: return "Invalid slot number";
|
||||
case -351: return "Record not found in the SRT";
|
||||
case -350: return "SRT overflow";
|
||||
case -349: return "No opens were successful in the loop";
|
||||
case -348: return "Offset was too big";
|
||||
case -347: return "NumByteLanes was determined to be zero";
|
||||
case -346: return "Bad sPointer was passed to a SDM call";
|
||||
case -345: return "Error occurred during _sGetDriver";
|
||||
case -344: return "No more sResources";
|
||||
case -343: return "Error occurred during _sDisDrvrName";
|
||||
case -342: return "Error occurred during _sGetDrvrName";
|
||||
case -341: return "Status of slot is bad";
|
||||
case -340: return "Error occurred during _BlockMove";
|
||||
case -339: return "Error occurred during _NewPtr";
|
||||
case -338: return "Selector out of bounds";
|
||||
case -337: return "Slot out of bounds or does not exist";
|
||||
case -336: return "The physical block size of an sBlock was zero";
|
||||
case -335: return "The sPointer is nil; no list is specified";
|
||||
case -334: return "The CPU field of the code to be executed by sExec was wrong";
|
||||
case -333: return "The revision code to be executed by sExec was wrong";
|
||||
case -332: return "A reserved field was not zero";
|
||||
case -331: return "The id's in the given sList are not in ascending order";
|
||||
case -330: return "Reference id not found in the given list";
|
||||
case -320: return "Bus error timeout";
|
||||
case -319: return "Board ID was wrong: Init the PRAM record";
|
||||
case -318: return "SDM jump table could not be created";
|
||||
case -317: return "Error occurred while trying to initialize the slot resource table";
|
||||
case -316: return "The InitStatus_V field was negative after primary init";
|
||||
case -315: return "No board id";
|
||||
case -314: return "Error occurred during _sGetPRAMRec";
|
||||
case -313: return "No board sResource";
|
||||
case -312: return "Error occurred during _DisposePointer";
|
||||
case -311: return "The F-Header block could not be disposed";
|
||||
case -310: return "The F-Header block could not be read";
|
||||
case -309: return "A valid ByteLane field was not found";
|
||||
case -308: return "An unexpected bus error occurred";
|
||||
case -307: return "A reserved field of the declaration ROM was used";
|
||||
case -306: return "The SDM was unable to allocate memory for the sInfo array";
|
||||
case -305: return "The longword test failed";
|
||||
case -304: return "There is no directory";
|
||||
case -303: return "The revision of the declaration ROM is wrong";
|
||||
case -302: return "The format of the declaration ROM is wrong";
|
||||
case -301: return "CRC check failed";
|
||||
case -300: return "No card in slot";
|
||||
case -299: return "Wrong queue type";
|
||||
case -293: return "Cards could not be initialized";
|
||||
case -292: return "Slot Resource Table could not be initialized";
|
||||
case -291: return "Slot Resource Table could not be initialized";
|
||||
case -290: return "SDM could not be initialized";
|
||||
case -261: return "Command not supported for port type";
|
||||
case -260: return "Duplicate client ID";
|
||||
case -259: return "Name supplied is longer than 31 characters";
|
||||
case -258: return "MIDIWritePacket couldn't write to all connected ports";
|
||||
case -257: return "No connection exists between specified ports";
|
||||
case -256: return "Pending virtual connection removed";
|
||||
case -255: return "Pending virtual connection resolved";
|
||||
case -254: return "Pending virtual connection created";
|
||||
case -253: return "Too many connections made";
|
||||
case -252: return "Too many ports already installed in the system";
|
||||
case -251: return "No port with that ID found";
|
||||
case -250: return "No client with that ID found ";
|
||||
case -247: return "Bad input text";
|
||||
case -246: return "Bad dictionary format";
|
||||
case -245: return "Incompatible voice";
|
||||
case -244: return "Voice not found";
|
||||
case -243: return "Buffer too small";
|
||||
case -242: return "Synthesizer not ready";
|
||||
case -241: return "Synthesizer open failed";
|
||||
case -240: return "No synthesizer found";
|
||||
case -232: return "Unknown quality";
|
||||
case -231: return "Unknown type of information";
|
||||
case -230: return "Input device hardware failure";
|
||||
case -229: return "Invalid input device reference number";
|
||||
case -228: return "Input device could not be opened";
|
||||
case -227: return "Input device already in use";
|
||||
case -226: return "Invalid sample size";
|
||||
case -225: return "Invalid sample rate";
|
||||
case -224: return "Hard disk drive too slow to record to disk";
|
||||
case -223: return "Invalid compression type";
|
||||
case -222: return "No buffer specified";
|
||||
case -221: return "Invalid Sound Input device";
|
||||
case -220: return "No Sound Input hardware";
|
||||
case -213: return "A parameter is incorrect";
|
||||
case -212: return "Not enough CPU cycles left to add another task";
|
||||
case -211: return "Channel not currently used";
|
||||
case -210: return "Can not operate in the memory allowed ";
|
||||
case -209: return "The Channel is being used already ";
|
||||
case -208: return "Corrupt/bad format or not of type AIFF";
|
||||
case -207: return "Could not allocate enough memory";
|
||||
case -206: return "Bad sound resource format";
|
||||
case -205: return "Bad sound channel specified";
|
||||
case -204: return "Sound resource error";
|
||||
case -203: return "Sound channel full";
|
||||
case -201: return "All available channels are already open for the synthesizer";
|
||||
case -200: return "No sound hardware";
|
||||
case -199: return "Resource map read error";
|
||||
case -198: return "Resource attribute error";
|
||||
case -197: return "RmveReference failed";
|
||||
case -196: return "RmveResource failed";
|
||||
case -195: return "AddReference failed";
|
||||
case -194: return "AddResource failed";
|
||||
case -193: return "Resource file not found";
|
||||
case -192: return "Resource not found";
|
||||
case -190: return "Offset or count out of bounds";
|
||||
case -189: return "Writing past end of file";
|
||||
case -188: return "Resource already in memory";
|
||||
case -186: return "Resource bent - Can't decompress a compressed resource";
|
||||
case -185: return "Extended resource has a bad format.";
|
||||
case -158: return "Invalid parameter";
|
||||
case -157: return "Invalid pixel depth";
|
||||
case -156: return "Invalid resolution for MakeITable";
|
||||
case -155: return "Invalid type of graphics device";
|
||||
case -154: return "ColorTable entry protection violation";
|
||||
case -153: return "Range error in colorTable request";
|
||||
case -152: return "Failed to allocate memory for structure";
|
||||
case -151: return "Failed to allocate memory for temporary structures";
|
||||
case -150: return "Color2Index failed to find an index";
|
||||
case -149: return "QuickDraw could not complete the operation (insufficient stack)";
|
||||
case -148: return "Pixel map record is deeper than 1 bit per pixel";
|
||||
case -147: return "Region accumulation failed. Resulting region may be corrupt";
|
||||
case -145: return "Not enough memory for picture";
|
||||
case -132: return "File id already exists";
|
||||
case -131: return "Directory specified";
|
||||
case -130: return "No file thread exists";
|
||||
case -128: return "User canceled the query";
|
||||
case -127: return "Could not find HMenu's parent in MenuKey";
|
||||
case -126: return "System error code for MBDF not found";
|
||||
case -125: return "Insufficient memory to update a pixmap";
|
||||
case -124: return "Server volume has been disconnected";
|
||||
case -123: return "Attempt to do a hierarchical operation on a non hierarchical volume";
|
||||
case -122: return "Attempt to move into offspring (file system)";
|
||||
case -121: return "Too many working directories open";
|
||||
case -120: return "Directory not found";
|
||||
case -117: return "Block is locked";
|
||||
case -116: return "Size check failed";
|
||||
case -115: return "Block check failed";
|
||||
case -114: return "Pointer check failed";
|
||||
case -113: return "Address in zone check failed";
|
||||
case -112: return "Attempt to purge a locked or non-purgeable block";
|
||||
case -111: return "Attempt to operate on a free block";
|
||||
case -110: return "Address was odd, or out of range";
|
||||
case -109: return "NIL master pointer";
|
||||
case -108: return "Not enough room in heap zone";
|
||||
case -102: return "No object of that type in scrap";
|
||||
case -100: return "Desk scrap isn't initialized";
|
||||
case -99: return "Error in ROZ";
|
||||
case -98: return "Driver open error; port not configured for this connection";
|
||||
case -97: return "Driver open error; port already in use";
|
||||
case -95: return "Excessive collisions on AppleTalk write";
|
||||
case -94: return "AppleTalk error in attaching/detaching protocol";
|
||||
case -93: return "No AppleTalk bridge found";
|
||||
case -92: return "AppleTalk data length too big";
|
||||
case -91: return "AppleTalk socket error: socket already active; not a known socket; socket table full; all dynamic socket numbers in use / Multicast address error ddpSktErr";
|
||||
case -90: return "SCC break received";
|
||||
case -89: return "SCC receiver error";
|
||||
case -88: return "Parameter RAM uninitialized";
|
||||
case -87: return "Parameter RAM written did not verify";
|
||||
case -86: return "Time written did not verify";
|
||||
case -85: return "Unable to read clock";
|
||||
case -84: return "Track failed to verify / I/O error";
|
||||
case -83: return "Cannot synchronize";
|
||||
case -82: return "Can't find sector 0 after track format";
|
||||
case -81: return "Can't find sector";
|
||||
case -80: return "Drive error (track number wrong in address mark)";
|
||||
case -79: return "Can't correctly adjust disk speed";
|
||||
case -78: return "Tried to read side 2 of a disk in a single-sided drive";
|
||||
case -77: return "Can't initialize disk controller chip";
|
||||
case -76: return "Can't find track 0";
|
||||
case -75: return "Drive error";
|
||||
case -74: return "Write underrun occurred";
|
||||
case -73: return "Bad data mark bit slip nibbles";
|
||||
case -72: return "Bad data mark checksum";
|
||||
case -71: return "Can't find a data mark";
|
||||
case -70: return "Bad address mark (bit slip nibbles)";
|
||||
case -69: return "Bad address mark (checksum didn't check)";
|
||||
case -68: return "Read verify failed";
|
||||
case -67: return "Can't find an address mark";
|
||||
case -66: return "Disk is probably blank / Font substitution occurred";
|
||||
case -65: return "No disk in drive / Font not declared";
|
||||
case -64: return "Drive isn't connected / Font declaration error / I/O error";
|
||||
case -61: return "Read/write permission doesn't allow writing";
|
||||
case -60: return "Bad master directory block; must reinitialize volume";
|
||||
case -59: return "Problem during rename";
|
||||
case -58: return "External file system; file-system identifier is non zero, or path reference number is greater than 1024";
|
||||
case -57: return "Not a Macintosh disk; volume lacks Macintosh-format directory";
|
||||
case -56: return "No such drive; specified drive number doesn't match any number in the drive queue";
|
||||
case -55: return "Specified volume is already mounted and on-line";
|
||||
case -54: return "Attempt to open locked file for writing";
|
||||
case -53: return "Volume not on-line";
|
||||
case -52: return "Error getting file position";
|
||||
case -51: return "Path reference number specifies nonexistent access path";
|
||||
case -50: return "Error in parameter list / Not an existing volume, and no default volume / Bad positioning information / Bad drive number";
|
||||
case -49: return "The read/write permission of only one access path to a file can allow writing";
|
||||
case -48: return "File with specified name and version number already exists";
|
||||
case -47: return "File is busy; one or more files are open";
|
||||
case -46: return "Volume is locked by a software flag";
|
||||
case -45: return "File is locked";
|
||||
case -44: return "Volume is locked by a hardware setting";
|
||||
case -43: return "File not found";
|
||||
case -42: return "Too many files open";
|
||||
case -41: return "Memory full (open) or file won't fit (load)";
|
||||
case -40: return "Attempt to position before start of file";
|
||||
case -39: return "Logical end-of-file reached during read operation";
|
||||
case -38: return "File not open";
|
||||
case -37: return "Bad file name or volume name (perhaps zero-length)";
|
||||
case -36: return "I/O error";
|
||||
case -35: return "Specified volume doesn't exist";
|
||||
case -34: return "All allocation blocks on the volume are full";
|
||||
case -33: return "File directory full";
|
||||
case -30: return "DCE extension error";
|
||||
case -29: return "Unit table has no more entries";
|
||||
case -28: return "Driver isn't open";
|
||||
case -27: return "I/O request aborted by KillIO / I/O abort error";
|
||||
case -26: return "Couldn't find driver in resource file";
|
||||
case -25: return "Attempt to remove an open driver";
|
||||
case -24: return "Close error";
|
||||
case -23: return "Requested read/write permission doesn't match driver's open permission / Attempt to open RAM Serial Driver failed";
|
||||
case -22: return "Driver reference number specifies NIL handle in unit table";
|
||||
case -21: return "Driver reference number doesn't match unit table";
|
||||
case -20: return "Driver can't respond to Write call";
|
||||
case -19: return "Driver can't respond to Read call";
|
||||
case -18: return "Driver can't respond to Status call";
|
||||
case -17: return "Driver can't respond to Control call / Unimplemented control instruction";
|
||||
case -13: return "Extensions disabled";
|
||||
case -12: return "Process ID not in valid range or unavailable";
|
||||
case -11: return "Disassembler installed";
|
||||
case -10: return "MacsBug installed";
|
||||
case -9: return "Miscellaneous system error";
|
||||
case -8: return "No debugger installed to handle debugger command";
|
||||
case -5: return "Invalid Power Manager queue element";
|
||||
case -4: return "Unimplemented core routine";
|
||||
case -3: return "Core routine number out of range";
|
||||
case -2: return "Invalid queue element";
|
||||
case -1: return "Saving spool file / Entry not in queue";
|
||||
case 0: return "No error";
|
||||
case 1: return "Event type not designated in system event mask / bus error / uninitialized slot interrupt dispatch table";
|
||||
case 2: return "No such file";
|
||||
case 3: return "No such resource / Arbitration failed during SCSIGet; bus busy / uninitialized slot priority table";
|
||||
case 4: return "Interrupted system call";
|
||||
case 5: return "I/O error";
|
||||
case 6: return "No such device";
|
||||
case 7: return "Insufficient space for return argument / SCSI Manager busy with another operation";
|
||||
case 8: return "Attempted operation was out of sequence (e.g., SCSISelect before SCSIGet)";
|
||||
case 9: return "File not open or bad file number";
|
||||
case 10: return "SCSIComplete failed; bus not in status phase";
|
||||
case 11: return "Miscellaneous hardware exception error";
|
||||
case 12: return "Not enough memory / Slot resource table uninitialized / Unimplemented Core routine";
|
||||
case 13: return "Permission denied / Slot PRAM uninitialized / Uninstalled interrupt error";
|
||||
case 14: return "Bad address / I/O Core Error";
|
||||
case 15: return "Block device required / Segment loader error";
|
||||
case 16: return "Mount device busy / Floating Point error / Serial driver error";
|
||||
case 17: return "File exists";
|
||||
case 18: return "Cross-device link";
|
||||
case 19: return "No such device";
|
||||
case 20: return "Not a directory";
|
||||
case 21: return "Is a directory";
|
||||
case 22: return "Invalid or unsupported parameter";
|
||||
case 23: return "File table overflow";
|
||||
case 24: return "Too many open files";
|
||||
case 25: return "Not an interactive device / Out of memory";
|
||||
case 26: return "Text file busy / Can't launch file";
|
||||
case 27: return "File too large / File system map has been trashed";
|
||||
case 28: return "No space left on device / Stack has moved into application heap";
|
||||
case 29: return "Illegal seek";
|
||||
case 30: return "Read-only file system";
|
||||
case 31: return "Too many links";
|
||||
case 32: return "Serial hardware overrun";
|
||||
case 33: return "Math argument out or range for domain of function";
|
||||
case 34: return "Math result not representable";
|
||||
case 35: return "Record doesn't fit in node ";
|
||||
case 36: return "Time out waiting for sync after holdoff";
|
||||
case 37: return "Time out waiting for HSHK high";
|
||||
case 38: return "Checksum error on response packet";
|
||||
case 40: return "Welcome to Macintosh greeting";
|
||||
case 41: return "Can't load the Finder error";
|
||||
case 42: return "Shutdown error / Unable to mount boot volume (sad Mac only)";
|
||||
case 43: return "Can't find System file to open (sad Mac only)";
|
||||
case 48: return "First byte in response packet was wrong";
|
||||
case 49: return "Sequence number in response packet was wrong";
|
||||
case 50: return "Drive number in response packet was wrong";
|
||||
case 51: return "Unserviceable slot interrupt";
|
||||
case 52: return "Detected bad catalog structure";
|
||||
case 53: return "Thread belongs to a directory not a file";
|
||||
case 54: return "File thread doesn't exist";
|
||||
case 64: return "Serial driver error";
|
||||
case 81: return "Bad opcode given to SANE Pack4";
|
||||
case 83: return "SetTrapAddress saw the \"come-from\" header";
|
||||
case 84: return "A menu was purged";
|
||||
case 85: return "MBDF resource not found";
|
||||
case 86: return "Hierarchical menus cannot be recursive";
|
||||
case 87: return "Could not load WDEF";
|
||||
case 88: return "Could not load CDEF";
|
||||
case 89: return "Could not load MDEF";
|
||||
case 90: return "An FPU instruction was executed and the machine doesn't have one";
|
||||
case 98: return "Can't patch for particular Model Mac";
|
||||
case 99: return "Can't load patch resource";
|
||||
case 101: return "Memory parity error";
|
||||
case 102: return "System is too old for this ROM";
|
||||
case 103: return "Booting in 32-bit on a 24-bit system";
|
||||
case 104: return "Need to write new boot blocks";
|
||||
case 105: return "Must have at least 1.5MB of RAM to boot 7.0";
|
||||
case 106: return "BufPtr moved too far during boot";
|
||||
case 128: return "Application or user requested abort";
|
||||
case 255: return "All command words less than this are errors";
|
||||
case 20000: return "User choice between ShutDown and Restart";
|
||||
case 20001: return "User choice between switching off and Restart";
|
||||
case 20002: return "Allow the user to ExitToShell, return if Cancel";
|
||||
case 32767: return "General system error (catch-all used in DSAT)";
|
||||
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MacOS {
|
||||
|
||||
namespace {
|
||||
class __system_category : public std::error_category
|
||||
{
|
||||
public:
|
||||
virtual const char* name() const noexcept;
|
||||
virtual std::string message(int ev) const;
|
||||
virtual std::error_condition default_error_condition(int ev) const noexcept;
|
||||
|
||||
private:
|
||||
static int remap(macos_error e);
|
||||
|
||||
};
|
||||
|
||||
|
||||
const char *__system_category::name() const noexcept
|
||||
{
|
||||
return "macos error";
|
||||
}
|
||||
|
||||
std::string __system_category::message(int ev) const
|
||||
{
|
||||
|
||||
const char *cp = ErrorName(ev);
|
||||
if (cp) return std::string(cp);
|
||||
|
||||
std::string tmp("Unknown error: ");
|
||||
tmp += std::to_string(ev);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
std::error_condition __system_category::default_error_condition(int ev) const noexcept
|
||||
{
|
||||
|
||||
int x = remap(static_cast<macos_error>(ev));
|
||||
if (x >= 0) return std::error_condition(x, std::generic_category());
|
||||
|
||||
return std::error_condition(ev, macos_system_category());
|
||||
}
|
||||
|
||||
int __system_category::remap(macos_error e)
|
||||
{
|
||||
// todo
|
||||
switch(e)
|
||||
{
|
||||
case rfNumErr: return EBADF;
|
||||
case ioErr: return EIO;
|
||||
case permErr: return EACCES;
|
||||
case fnfErr: return ENOENT;
|
||||
case dirNFErr: return ENOTDIR;
|
||||
case notAFileErr: return EISDIR;
|
||||
case extFSErr: return ENOTSUP;
|
||||
case wPrErr: return EROFS;
|
||||
case dupFNErr: return EEXIST;
|
||||
case fBsyErr: return EBUSY;
|
||||
case dskFulErr: return ENOSPC;
|
||||
|
||||
default: return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::error_category& macos_system_category()
|
||||
{
|
||||
static __system_category s;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
macos_error macos_error_from_errno()
|
||||
{
|
||||
return macos_error_from_errno(errno);
|
||||
}
|
||||
|
||||
macos_error macos_error_from_errno(int error)
|
||||
{
|
||||
switch(error)
|
||||
{
|
||||
case 0: return noErr;
|
||||
case EBADF: return rfNumErr;
|
||||
case EIO: return ioErr;
|
||||
case EACCES: return permErr;
|
||||
case ENOENT: return fnfErr;
|
||||
case ENOTDIR: return dirNFErr;
|
||||
case EISDIR: return notAFileErr;
|
||||
case ENOTSUP: return extFSErr;
|
||||
case EROFS: return wPrErr;
|
||||
|
||||
case EEXIST: return dupFNErr;
|
||||
|
||||
case EBUSY: return fBsyErr;
|
||||
|
||||
case EDQUOT: return dskFulErr;
|
||||
case ENOSPC: return dskFulErr;
|
||||
|
||||
case ENOTEMPTY: return fBsyErr;
|
||||
|
||||
|
||||
default:
|
||||
return ioErr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
242
macos/errors.h
242
macos/errors.h
|
@ -14,12 +14,20 @@ Created: Thursday, March 14, 1991 at 3:53 PM
|
|||
#ifndef __macos_errors__
|
||||
#define __macos_errors__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
const char *ErrorName(int16_t trap);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace MacOS {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
|
||||
enum macos_error {
|
||||
noErr = 0,
|
||||
paramErr = -50, /*error in user parameter list*/
|
||||
noHardwareErr = -200, /*Sound Manager Error Returns*/
|
||||
notEnoughHardwareErr = -201, /*Sound Manager Error Returns*/
|
||||
|
@ -39,9 +47,9 @@ enum {
|
|||
openErr = -23, /*I/O System Errors*/
|
||||
closErr = -24, /*I/O System Errors*/
|
||||
dRemovErr = -25, /*tried to remove an open driver*/
|
||||
dInstErr = -26 /*DrvrInstall couldn't find driver in resources */
|
||||
};
|
||||
enum {
|
||||
dInstErr = -26, /*DrvrInstall couldn't find driver in resources */
|
||||
|
||||
|
||||
abortErr = -27, /*IO call aborted by KillIO*/
|
||||
iIOAbortErr = -27, /*IO abort error (Printing Manager)*/
|
||||
notOpenErr = -28, /*Couldn't rd/wr/ctl/sts cause driver not opened*/
|
||||
|
@ -61,9 +69,9 @@ enum {
|
|||
tmfoErr = -42, /*too many files open*/
|
||||
fnfErr = -43, /*File not found*/
|
||||
wPrErr = -44, /*diskette is write protected.*/
|
||||
fLckdErr = -45 /*file is locked*/
|
||||
};
|
||||
enum {
|
||||
fLckdErr = -45, /*file is locked*/
|
||||
|
||||
|
||||
vLckdErr = -46, /*volume is locked*/
|
||||
fBsyErr = -47, /*File is busy (delete)*/
|
||||
dupFNErr = -48, /*duplicate filename (rename)*/
|
||||
|
@ -83,9 +91,9 @@ enum {
|
|||
tmwdoErr = -121, /*No free WDCB available*/
|
||||
badMovErr = -122, /*Move into offspring error*/
|
||||
wrgVolTypErr = -123, /*Wrong volume type error [operation not supported for MFS]*/
|
||||
volGoneErr = -124 /*Server volume has been disconnected.*/
|
||||
};
|
||||
enum {
|
||||
volGoneErr = -124, /*Server volume has been disconnected.*/
|
||||
|
||||
|
||||
fidNotFound = -1300, /*no file thread exists.*/
|
||||
fidExists = -1301, /*file id already exists*/
|
||||
notAFileErr = -1302, /*directory specified*/
|
||||
|
@ -99,15 +107,15 @@ enum {
|
|||
envVersTooBig = -5502, /*Version bigger than call can handle*/
|
||||
fontDecError = -64, /*error during font declaration*/
|
||||
fontNotDeclared = -65, /*font not declared*/
|
||||
fontSubErr = -66, /*font substitution occured*/
|
||||
fontSubErr = -66, /*font substitution occurred*/
|
||||
fontNotOutlineErr = -32615, /*bitmap font passed to routine that does outlines only*/
|
||||
firstDskErr = -84, /*I/O System Errors*/
|
||||
lastDskErr = -64, /*I/O System Errors*/
|
||||
noDriveErr = -64, /*drive not installed*/
|
||||
offLinErr = -65, /*r/w requested for an off-line drive*/
|
||||
noNybErr = -66 /*couldn't find 5 nybbles in 200 tries*/
|
||||
};
|
||||
enum {
|
||||
noNybErr = -66, /*couldn't find 5 nybbles in 200 tries*/
|
||||
|
||||
|
||||
noAdrMkErr = -67, /*couldn't find valid addr mark*/
|
||||
dataVerErr = -68, /*read verify compare failed*/
|
||||
badCksmErr = -69, /*addr mark checksum didn't check*/
|
||||
|
@ -127,9 +135,9 @@ enum {
|
|||
fmt2Err = -83, /*can't get enough sync*/
|
||||
verErr = -84, /*track failed to verify*/
|
||||
clkRdErr = -85, /*unable to read same clock value twice*/
|
||||
clkWrErr = -86 /*time written did not verify*/
|
||||
};
|
||||
enum {
|
||||
clkWrErr = -86, /*time written did not verify*/
|
||||
|
||||
|
||||
prWrErr = -87, /*parameter ram written didn't read-verify*/
|
||||
prInitErr = -88, /*InitUtil found the parameter ram uninitialized*/
|
||||
rcvrErr = -89, /*SCC receiver error (framing; parity; OR)*/
|
||||
|
@ -153,9 +161,9 @@ enum {
|
|||
nilHandleErr = -109, /*Master Pointer was NIL in HandleZone or other*/
|
||||
memWZErr = -111, /*WhichZone failed (applied to free block)*/
|
||||
memPurErr = -112, /*trying to purge a locked or non-purgeable block*/
|
||||
memAdrErr = -110 /*address was odd; or out of range*/
|
||||
};
|
||||
enum {
|
||||
memAdrErr = -110, /*address was odd; or out of range*/
|
||||
|
||||
|
||||
memAZErr = -113, /*Address in zone check failed*/
|
||||
memPCErr = -114, /*Pointer Check failed*/
|
||||
memBCErr = -115, /*Block Check failed*/
|
||||
|
@ -175,9 +183,9 @@ enum {
|
|||
noMemForPictPlaybackErr = -145,
|
||||
rgnTooBigError = -147,
|
||||
pixMapTooDeepErr = -148,
|
||||
nsStackErr = -149
|
||||
};
|
||||
enum {
|
||||
nsStackErr = -149,
|
||||
|
||||
|
||||
cMatchErr = -150, /*Color2Index failed to find an index*/
|
||||
cTempMemErr = -151, /*failed to allocate memory for temporary structures*/
|
||||
cNoMemErr = -152, /*failed to allocate memory for structure*/
|
||||
|
@ -188,7 +196,7 @@ enum {
|
|||
rgnTooBigErr = -500,
|
||||
updPixMemErr = -125, /*insufficient memory to update a pixmap*/
|
||||
pictInfoVersionErr = -11000, /* wrong version of the PictInfo structure */
|
||||
pictInfoIDErr = -11001, /* the internal consistancy check for the PictInfoID is wrong */
|
||||
pictInfoIDErr = -11001, /* the internal consistency check for the PictInfoID is wrong */
|
||||
pictInfoVerbErr = -11002, /* the passed verb was invalid */
|
||||
cantLoadPickMethodErr = -11003, /* unable to load the custom pick proc */
|
||||
colorsRequestedErr = -11004, /* the number of colors requested was illegal */
|
||||
|
@ -199,9 +207,9 @@ enum {
|
|||
notEnoughHardware = notEnoughHardwareErr, /* *** obsolete spelling */
|
||||
queueFull = -203, /*Sound Manager Error Returns*/
|
||||
resProblem = -204, /*Sound Manager Error Returns*/
|
||||
badChannel = -205 /*Sound Manager Error Returns*/
|
||||
};
|
||||
enum {
|
||||
badChannel = -205, /*Sound Manager Error Returns*/
|
||||
|
||||
|
||||
badFormat = -206, /*Sound Manager Error Returns*/
|
||||
notEnoughBufferSpace = -207, /* could not allocate enough memory */
|
||||
badFileFormat = -208, /* was not type AIFF or was of bad format,corrupt */
|
||||
|
@ -221,9 +229,8 @@ enum {
|
|||
siBadRefNum = -229, /*invalid input device reference number*/
|
||||
siInputDeviceErr = -230, /*input device hardware failure*/
|
||||
siUnknownInfoType = -231, /*invalid info type selector (returned by driver)*/
|
||||
siUnknownQuality = -232 /*invalid quality selector (returned by driver)*/
|
||||
};
|
||||
enum {
|
||||
siUnknownQuality = -232, /*invalid quality selector (returned by driver)*/
|
||||
|
||||
|
||||
/*Notification Manager errors*/
|
||||
nmTypErr = -299, /*wrong queue type*/
|
||||
|
@ -242,23 +249,23 @@ enum {
|
|||
smEmptySlot = -300, /*No card in slot*/
|
||||
smCRCFail = -301, /*CRC check failed for declaration data*/
|
||||
smFormatErr = -302, /*FHeader Format is not Apple's*/
|
||||
smRevisionErr = -303, /*Wrong revison level*/
|
||||
smRevisionErr = -303, /*Wrong revision level*/
|
||||
smNoDir = -304, /*Directory offset is Nil */
|
||||
smDisabledSlot = -305, /*This slot is disabled (-305 use to be smLWTstBad)*/
|
||||
smNosInfoArray = -306 /*No sInfoArray. Memory Mgr error.*/
|
||||
};
|
||||
enum {
|
||||
smNosInfoArray = -306, /*No sInfoArray. Memory Mgr error.*/
|
||||
|
||||
|
||||
smResrvErr = -307, /*Fatal reserved error. Resreved field <> 0.*/
|
||||
smUnExBusErr = -308, /*Unexpected BusError*/
|
||||
smBLFieldBad = -309, /*ByteLanes field was bad.*/
|
||||
smFHBlockRdErr = -310, /*Error occured during _sGetFHeader.*/
|
||||
smFHBlkDispErr = -311, /*Error occured during _sDisposePtr (Dispose of FHeader block).*/
|
||||
smFHBlockRdErr = -310, /*Error occurred during _sGetFHeader.*/
|
||||
smFHBlkDispErr = -311, /*Error occurred during _sDisposePtr (Dispose of FHeader block).*/
|
||||
smDisposePErr = -312, /*_DisposePointer error*/
|
||||
smNoBoardSRsrc = -313, /*No Board sResource.*/
|
||||
smGetPRErr = -314, /*Error occured during _sGetPRAMRec (See SIMStatus).*/
|
||||
smGetPRErr = -314, /*Error occurred during _sGetPRAMRec (See SIMStatus).*/
|
||||
smNoBoardId = -315, /*No Board Id.*/
|
||||
smInitStatVErr = -316, /*The InitStatusV field was negative after primary or secondary init.*/
|
||||
smInitTblVErr = -317, /*An error occured while trying to initialize the Slot Resource Table.*/
|
||||
smInitTblVErr = -317, /*An error occurred while trying to initialize the Slot Resource Table.*/
|
||||
smNoJmpTbl = -318, /*SDM jump table could not be created.*/
|
||||
smBadBoardId = -319, /*BoardId was wrong; re-init the PRAM record.*/
|
||||
smBusErrTO = -320, /*BusError time out.*/
|
||||
|
@ -273,31 +280,31 @@ but a special error is needed to patch secondary inits.*/
|
|||
smBadRefId = -330, /*Reference Id not found in List*/
|
||||
smBadsList = -331, /*Bad sList: Id1 < Id2 < Id3 ...format is not followed.*/
|
||||
smReservedErr = -332, /*Reserved field not zero*/
|
||||
smCodeRevErr = -333 /*Code revision is wrong*/
|
||||
};
|
||||
enum {
|
||||
smCodeRevErr = -333, /*Code revision is wrong*/
|
||||
|
||||
|
||||
smCPUErr = -334, /*Code revision is wrong*/
|
||||
smsPointerNil = -335, /*LPointer is nil From sOffsetData. If this error occurs; check sInfo rec for more information.*/
|
||||
smNilsBlockErr = -336, /*Nil sBlock error (Dont allocate and try to use a nil sBlock)*/
|
||||
smNilsBlockErr = -336, /*Nil sBlock error (Don't allocate and try to use a nil sBlock)*/
|
||||
smSlotOOBErr = -337, /*Slot out of bounds error*/
|
||||
smSelOOBErr = -338, /*Selector out of bounds error*/
|
||||
smNewPErr = -339, /*_NewPtr error*/
|
||||
smBlkMoveErr = -340, /*_BlockMove error*/
|
||||
smCkStatusErr = -341, /*Status of slot = fail.*/
|
||||
smGetDrvrNamErr = -342, /*Error occured during _sGetDrvrName.*/
|
||||
smDisDrvrNamErr = -343, /*Error occured during _sDisDrvrName.*/
|
||||
smGetDrvrNamErr = -342, /*Error occurred during _sGetDrvrName.*/
|
||||
smDisDrvrNamErr = -343, /*Error occurred during _sDisDrvrName.*/
|
||||
smNoMoresRsrcs = -344, /*No more sResources*/
|
||||
smsGetDrvrErr = -345, /*Error occurred during _sGetDriver.*/
|
||||
smBadsPtrErr = -346, /*Bad pointer was passed to sCalcsPointer*/
|
||||
smByteLanesErr = -347, /*NumByteLanes was determined to be zero.*/
|
||||
smOffsetErr = -348, /*Offset was too big (temporary error*/
|
||||
smNoGoodOpens = -349, /*No opens were successfull in the loop.*/
|
||||
smNoGoodOpens = -349, /*No opens were successful in the loop.*/
|
||||
smSRTOvrFlErr = -350, /*SRT over flow.*/
|
||||
smRecNotFnd = -351, /*Record not found in the SRT.*/
|
||||
editionMgrInitErr = -450, /*edition manager not inited by this app*/
|
||||
badSectionErr = -451 /*not a valid SectionRecord*/
|
||||
};
|
||||
enum {
|
||||
badSectionErr = -451, /*not a valid SectionRecord*/
|
||||
|
||||
|
||||
notRegisteredSectionErr = -452, /*not a registered SectionRecord*/
|
||||
badEditionFileErr = -453, /*edition file is corrupt*/
|
||||
badSubPartErr = -454, /*can not use sub parts in this release*/
|
||||
|
@ -321,12 +328,12 @@ enum {
|
|||
notEnoughMemoryErr = -620, /*insufficient physical memory*/
|
||||
notHeldErr = -621, /*specified range of memory is not held*/
|
||||
cannotMakeContiguousErr = -622, /*cannot make specified range contiguous*/
|
||||
notLockedErr = -623 /*specified range of memory is not locked*/
|
||||
};
|
||||
enum {
|
||||
interruptsMaskedErr = -624, /*donÕt call with interrupts masked*/
|
||||
notLockedErr = -623, /*specified range of memory is not locked*/
|
||||
|
||||
|
||||
interruptsMaskedErr = -624, /*don't call with interrupts masked*/
|
||||
cannotDeferErr = -625, /*unable to defer additional functions*/
|
||||
ddpSktErr = -91, /*error in soket number*/
|
||||
ddpSktErr = -91, /*error in socket number*/
|
||||
ddpLenErr = -92, /*data length too big*/
|
||||
noBridgeErr = -93, /*no network bridge for non-local send*/
|
||||
lapProtErr = -94, /*error in attaching/detaching protocol*/
|
||||
|
@ -343,9 +350,9 @@ enum {
|
|||
aspBufTooSmall = -1067, /*Buffer too small*/
|
||||
aspNoMoreSess = -1068, /*No more sessions on server*/
|
||||
aspNoServers = -1069, /*No servers at that address*/
|
||||
aspParamErr = -1070 /*Parameter error*/
|
||||
};
|
||||
enum {
|
||||
aspParamErr = -1070, /*Parameter error*/
|
||||
|
||||
|
||||
aspServerBusy = -1071, /*Server cannot open another session*/
|
||||
aspSessClosed = -1072, /*Session closed*/
|
||||
aspSizeErr = -1073, /*Command block too big*/
|
||||
|
@ -365,9 +372,9 @@ enum {
|
|||
noMPPErr = -3102,
|
||||
ckSumErr = -3103,
|
||||
extractErr = -3104,
|
||||
readQErr = -3105
|
||||
};
|
||||
enum {
|
||||
readQErr = -3105,
|
||||
|
||||
|
||||
atpLenErr = -3106,
|
||||
atpBadRsp = -3107,
|
||||
recNotFnd = -3108,
|
||||
|
@ -387,9 +394,9 @@ enum {
|
|||
afpItemNotFound = -5012,
|
||||
afpLockErr = -5013,
|
||||
afpMiscErr = -5014,
|
||||
afpNoMoreLocks = -5015
|
||||
};
|
||||
enum {
|
||||
afpNoMoreLocks = -5015,
|
||||
|
||||
|
||||
afpNoServer = -5016,
|
||||
afpObjectExists = -5017,
|
||||
afpObjectNotFound = -5018,
|
||||
|
@ -409,9 +416,9 @@ enum {
|
|||
afpObjectLocked = -5032, /*Object is M/R/D/W inhibited*/
|
||||
afpContainsSharedErr = -5033, /*$FFFFEC57 the folder being shared contains a shared folder */
|
||||
afpIDNotFound = -5034, /*$FFFFEC56*/
|
||||
afpIDExists = -5035 /*$FFFFEC55*/
|
||||
};
|
||||
enum {
|
||||
afpIDExists = -5035, /*$FFFFEC55*/
|
||||
|
||||
|
||||
afpDiffVolErr = -5036, /*$FFFFEC54*/
|
||||
afpCatalogChanged = -5037, /*$FFFFEC53*/
|
||||
afpSameObjectErr = -5038, /*$FFFFEC52*/
|
||||
|
@ -433,9 +440,9 @@ enum {
|
|||
noSessionErr = -908, /* Invalid session reference number */
|
||||
badReqErr = -909, /* bad parameter or invalid state for operation */
|
||||
portNameExistsErr = -910, /* port is already open (perhaps in another app) */
|
||||
noUserNameErr = -911 /* user name unknown on destination machine */
|
||||
};
|
||||
enum {
|
||||
noUserNameErr = -911, /* user name unknown on destination machine */
|
||||
|
||||
|
||||
userRejectErr = -912, /* Destination rejected the session request */
|
||||
noMachineNameErr = -913, /* user hasn't named his Macintosh in the Network Setup Control Panel */
|
||||
noToolboxNameErr = -914, /* A system resource is missing, not too likely */
|
||||
|
@ -446,7 +453,7 @@ enum {
|
|||
noDefaultUserErr = -922, /* user hasn't typed in owners name in Network Setup Control Pannel */
|
||||
notLoggedInErr = -923, /* The default userRefNum does not yet exist */
|
||||
noUserRefErr = -924, /* unable to create a new userRefNum */
|
||||
networkErr = -925, /* An error has occured in the network, not too likely */
|
||||
networkErr = -925, /* An error has occurred in the network, not too likely */
|
||||
noInformErr = -926, /* PPCStart failed because destination did not have inform pending */
|
||||
authFailErr = -927, /* unable to authenticate user at destination */
|
||||
noUserRecErr = -928, /* Invalid user reference number */
|
||||
|
@ -455,9 +462,9 @@ enum {
|
|||
guestNotAllowedErr = -932, /* destination port requires authentication */
|
||||
swOverrunErr = 1, /*serial driver error masks*/
|
||||
parityErr = 16, /*serial driver error masks*/
|
||||
hwOverrunErr = 32 /*serial driver error masks*/
|
||||
};
|
||||
enum {
|
||||
hwOverrunErr = 32, /*serial driver error masks*/
|
||||
|
||||
|
||||
framingErr = 64, /*serial driver error masks*/
|
||||
dsBusError = 1, /*bus error */
|
||||
dsAddressErr = 2, /*address error*/
|
||||
|
@ -477,9 +484,9 @@ enum {
|
|||
dsFPErr = 16, /*Floating point error*/
|
||||
dsNoPackErr = 17, /*package 0 not present*/
|
||||
dsNoPk1 = 18, /*package 1 not present*/
|
||||
dsNoPk2 = 19 /*package 2 not present*/
|
||||
};
|
||||
enum {
|
||||
dsNoPk2 = 19, /*package 2 not present*/
|
||||
|
||||
|
||||
dsNoPk3 = 20, /*package 3 not present*/
|
||||
dsNoPk4 = 21, /*package 4 not present*/
|
||||
dsNoPk5 = 22, /*package 5 not present*/
|
||||
|
@ -493,16 +500,16 @@ enum {
|
|||
dsFinderErr = 41, /*can't load the Finder error*/
|
||||
dsBadSlotInt = 51, /*unserviceable slot interrupt*/
|
||||
dsBadSANEOpcode = 81, /*bad opcode given to SANE Pack4*/
|
||||
dsBadPatchHeader = 83, /*SetTrapAddress saw the Òcome-fromÓ header*/
|
||||
dsBadPatchHeader = 83, /*SetTrapAddress saw the "come-from" header*/
|
||||
menuPrgErr = 84, /*happens when a menu is purged*/
|
||||
dsMBarNFnd = 85, /*Menu Manager Errors*/
|
||||
dsHMenuFindErr = 86, /*Menu Manager Errors*/
|
||||
dsWDEFNotFound = 87, /*could not load WDEF*/
|
||||
dsCDEFNotFound = 88, /*could not load CDEF*/
|
||||
dsMDEFNotFound = 89 /*could not load MDEF*/
|
||||
};
|
||||
enum {
|
||||
dsNoFPU = 90, /*an FPU instruction was executed and the machine doesnÕt have one*/
|
||||
dsMDEFNotFound = 89, /*could not load MDEF*/
|
||||
|
||||
|
||||
dsNoFPU = 90, /*an FPU instruction was executed and the machine doesn't have one*/
|
||||
dsNoPatch = 98, /*Can't patch for particular Model Mac*/
|
||||
dsBadPatch = 99, /*Can't load patch resource*/
|
||||
dsParityErr = 101, /*memory parity error*/
|
||||
|
@ -518,34 +525,85 @@ enum {
|
|||
dsForcedQuit = 20002, /*allow the user to ExitToShell, return if Cancel*/
|
||||
|
||||
/*System Errors that are used after MacsBug is loaded to put up dialogs since these should not cause MacsBug to stop, they must be in the range (30, 42, 16384-32767) negative numbers add to an existing dialog without putting up a whole new dialog*/
|
||||
dsMacsBugInstalled = -10, /*say ÒMacsBug InstalledÓ*/
|
||||
dsDisassemblerInstalled = -11, /*say ÒDisassembler InstalledÓ*/
|
||||
dsExtensionsDisabled = -13, /*say ÒExtensions DisabledÓ*/
|
||||
dsMacsBugInstalled = -10, /*say "MacsBug Installed"*/
|
||||
dsDisassemblerInstalled = -11, /*say "Disassembler Installed"*/
|
||||
dsExtensionsDisabled = -13, /*say "Extensions Disabled"*/
|
||||
dsGreeting = 40, /*welcome to Macintosh greeting*/
|
||||
dsSysErr = 32767, /*general system error*/
|
||||
|
||||
/*old names here for compatibilityÕs sake*/
|
||||
WDEFNFnd = dsWDEFNotFound
|
||||
};
|
||||
enum {
|
||||
/*old names here for compatibility's sake*/
|
||||
WDEFNFnd = dsWDEFNotFound,
|
||||
|
||||
|
||||
CDEFNFnd = dsCDEFNotFound,
|
||||
dsNotThe1 = 31, /*not the disk I wanted*/
|
||||
dsBadStartupDisk = 42, /*unable to mount boot volume (sad Mac only)*/
|
||||
dsSystemFileErr = 43, /*canÕt find System file to open (sad Mac only)*/
|
||||
dsHD20Installed = -12, /*say ÒHD20 StartupÓ*/
|
||||
dsSystemFileErr = 43, /*can't find System file to open (sad Mac only)*/
|
||||
dsHD20Installed = -12, /*say "HD20 Startup"*/
|
||||
mBarNFnd = -126, /*system error code for MBDF not found*/
|
||||
hMenuFindErr = -127, /*could not find HMenu's parent in MenuKey*/
|
||||
userBreak = -490, /*user debugger break*/
|
||||
strUserBreak = -491, /*user debugger break; display string on stack*/
|
||||
exUserBreak = -492, /*user debugger break; execute debugger commands on stack*/
|
||||
|
||||
/*obsolete errors that are no longer used, but I donÕt have the guts to remove from this file*/
|
||||
/*obsolete errors that are no longer used, but I don't have the guts to remove from this file*/
|
||||
selectorErr = paramErr /* bad selector, for selector-based traps */
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <system_error>
|
||||
|
||||
namespace MacOS {
|
||||
|
||||
macos_error macos_error_from_errno();
|
||||
macos_error macos_error_from_errno(int error);
|
||||
|
||||
// c++11 error stuff
|
||||
const std::error_category& macos_system_category();
|
||||
|
||||
inline std::error_code make_error_code(macos_error e) noexcept
|
||||
{
|
||||
return std::error_code(static_cast<int>(e), macos_system_category());
|
||||
}
|
||||
|
||||
inline std::error_condition make_error_condition(macos_error e) noexcept
|
||||
{
|
||||
return std::error_condition(static_cast<int>(e), macos_system_category());
|
||||
}
|
||||
|
||||
inline void throw_macos_error(int e)
|
||||
{
|
||||
throw std::system_error(e, macos_system_category());
|
||||
}
|
||||
inline void throw_macos_error(int e, const char *what)
|
||||
{
|
||||
throw std::system_error(e, macos_system_category(), what);
|
||||
}
|
||||
inline void throw_macos_error(int e, const std::string &what)
|
||||
{
|
||||
throw std::system_error(e, macos_system_category(), what);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace std {
|
||||
|
||||
template<>
|
||||
struct is_error_code_enum<MacOS::macos_error> : public true_type {};
|
||||
|
||||
template<>
|
||||
struct is_error_condition_enum<MacOS::macos_error> : public true_type {};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -60,7 +60,7 @@ enum {
|
|||
SMGlobals = 0x0CC4, /* (long) pointer to Sound Manager Globals*/
|
||||
TheGDevice = 0x0CC8, /*[GLOBAL VAR] (long) the current graphics device*/
|
||||
CQDGlobals = 0x0CCC, /* (long) quickDraw global extensions*/
|
||||
ADBBase = 0x0CF8, /*[GLOBAL VAR] (long) pointer to Front Desk Buss Variables*/
|
||||
ADBBase = 0x0CF8, /*[GLOBAL VAR] (long) pointer to Front Desk Bus Variables*/
|
||||
WarmStart = 0x0CFC, /*[GLOBAL VAR] (long) flag to indicate it is a warm start*/
|
||||
TimeDBRA = 0x0D00, /*[GLOBAL VAR] (word) number of iterations of DBRA per millisecond*/
|
||||
TimeSCCDB = 0x0D02, /*[GLOBAL VAR] (word) number of iter's of SCC access & DBRA.*/
|
||||
|
@ -263,7 +263,7 @@ enum {
|
|||
enum {
|
||||
SysParam = 0x1F8, /*[GLOBAL VAR] Low-memory copy of parameter RAM (20 bytes)
|
||||
system parameter memory [20 bytes]*/
|
||||
CrsrThresh = 0x8EC, /*[GLOBAL VAR] Mouse-scaling threshold (word)
|
||||
CrsrThresh = 0x8EC, /*[GLOBAL VAR] Mouse-scaling threshold (word)
|
||||
delta threshold for mouse scaling [word]*/
|
||||
JCrsrTask = 0x8EE, /*[GLOBAL VAR] address of CrsrVBLTask [long]*/
|
||||
MTemp = 0x828, /*[GLOBAL VAR] Low-level interrupt mouse location [long]*/
|
||||
|
@ -318,7 +318,7 @@ enum {
|
|||
MaskPtr = 0x31A, /*[GLOBAL VAR] Memory Manager Pointer Mask [long]*/
|
||||
MinStack = 0x31E, /*[GLOBAL VAR] Minimum space allotment for stack (long)
|
||||
min stack size used in InitApplZone [long]*/
|
||||
DefltStack = 0x322, /*[GLOBAL VAR] Default space allotment for stack (long)
|
||||
DefltStack = 0x322, /*[GLOBAL VAR] Default space allotment for stack (long)
|
||||
default size of stack [long]*/
|
||||
MMDefFlags = 0x326, /*[GLOBAL VAR] default zone flags [word]*/
|
||||
DSAlertTab = 0x2BA, /*[GLOBAL VAR] Pointer to system error alert table in use
|
||||
|
@ -362,7 +362,7 @@ enum {
|
|||
TagData = 0x2FA, /*[GLOBAL VAR] sector tag info for disk drivers [14 bytes]*/
|
||||
BufTgFNum = 0x2FC, /*[GLOBAL VAR] File tags buffer: file number (long)
|
||||
file number [long]*/
|
||||
BufTgFFlg = 0x300, /*[GLOBAL VAR] File tags buffer: flags (word: bit 1=1 if resource fork)
|
||||
BufTgFFlg = 0x300, /*[GLOBAL VAR] File tags buffer: flags (word: bit 1=1 if resource fork)
|
||||
flags [word]*/
|
||||
BufTgFBkNum = 0x302, /*[GLOBAL VAR] File tags buffer: logical block number (word)
|
||||
logical block number [word]*/
|
||||
|
@ -400,7 +400,7 @@ enum {
|
|||
Z-ordered linked list of windows [pointer]*/
|
||||
PaintWhite = 0x9DC, /*[GLOBAL VAR] Flag for whether to paint window white before update event (word)
|
||||
erase newly drawn windows? [word]*/
|
||||
WMgrPort = 0x9DE, /*[GLOBAL VAR] Pointer to Window Manager port
|
||||
WMgrPort = 0x9DE, /*[GLOBAL VAR] Pointer to Window Manager port
|
||||
window manager's grafport [pointer]*/
|
||||
GrayRgn = 0x9EE, /*[GLOBAL VAR] Handle to region drawn as desktop
|
||||
rounded gray desk region [handle]*/
|
||||
|
@ -439,7 +439,7 @@ enum {
|
|||
system map [handle]*/
|
||||
SysMap = 0xA58, /*[GLOBAL VAR] Reference number of system resource file (word)
|
||||
reference number of system map [word]*/
|
||||
CurMap = 0xA5A, /*[GLOBAL VAR] Reference number of current resource file (word)
|
||||
CurMap = 0xA5A, /*[GLOBAL VAR] Reference number of current resource file (word)
|
||||
reference number of current map [word]*/
|
||||
ResReadOnly = 0xA5C, /*[GLOBAL VAR] Read only flag [word]*/
|
||||
ResLoad = 0xA5E, /*[GLOBAL VAR] Current SetResLoad state (word)
|
||||
|
|
137
macos/tool_return.h
Normal file
137
macos/tool_return.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
#ifndef __tool_return__
|
||||
#define __tool_return__
|
||||
|
||||
#include "errors.h"
|
||||
#include <utility>
|
||||
|
||||
namespace MacOS {
|
||||
|
||||
namespace internal {
|
||||
|
||||
class tool_return_base
|
||||
{
|
||||
protected:
|
||||
macos_error _error;
|
||||
|
||||
tool_return_base() : _error(static_cast<macos_error>(0))
|
||||
{}
|
||||
|
||||
tool_return_base(macos_error error) : _error(error)
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
macos_error error() const
|
||||
{
|
||||
return _error;
|
||||
}
|
||||
|
||||
|
||||
template<class... Args>
|
||||
void throw_macos_error(Args&&... args) const
|
||||
{
|
||||
if (_error) MacOS::throw_macos_error(_error, std::forward<Args>(args)...);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
} // namespace
|
||||
|
||||
template<class T>
|
||||
class tool_return : public internal::tool_return_base
|
||||
{
|
||||
private:
|
||||
T _value;
|
||||
|
||||
tool_return() = delete;
|
||||
|
||||
operator T() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
tool_return(T value) : _value(value)
|
||||
{}
|
||||
|
||||
tool_return(macos_error error) : tool_return_base(error)
|
||||
{}
|
||||
|
||||
|
||||
tool_return &operator=(T value)
|
||||
{
|
||||
_value = value;
|
||||
_error = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
tool_return &operator=(macos_error error)
|
||||
{
|
||||
_value = T();
|
||||
_error = error;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
constexpr const T* operator->() const
|
||||
{
|
||||
return &_value;
|
||||
}
|
||||
|
||||
|
||||
constexpr const T& operator *() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
||||
T value() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
template<class U>
|
||||
T value_or(U&& u) const
|
||||
{
|
||||
if (_error) return u;
|
||||
return _value;
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
T value_or_throw(Args&&... args) const
|
||||
{
|
||||
if (_error) throw_macos_error(std::forward<Args>(args)...);
|
||||
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
class tool_return<void> : public internal::tool_return_base
|
||||
{
|
||||
public:
|
||||
|
||||
tool_return()
|
||||
{}
|
||||
|
||||
tool_return(macos_error error) : tool_return_base(error)
|
||||
{}
|
||||
|
||||
tool_return &operator=(macos_error error)
|
||||
{
|
||||
_error = error;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
#endif
|
190
macos/traps.c
190
macos/traps.c
|
@ -7,10 +7,10 @@ const char *TrapName(uint16_t trap)
|
|||
|
||||
switch(trap)
|
||||
{
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; QuickDraw
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA817: return "_CopyMask";
|
||||
|
@ -196,10 +196,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA8FB: return "_MapRgn";
|
||||
case 0xA8FC: return "_MapPoly";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Toolbox
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA80D: return "_Count1Resources";
|
||||
|
@ -511,34 +511,34 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xABF2: return "_ThreadDispatch";
|
||||
case 0xABFF: return "_DebugStr";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Resource Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA822: return "_ResourceDispatch";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; PPCToolbox
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA0DD: return "_PPC";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Alias Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA823: return "_AliasDispatch";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Device Manager (some shared by the File Manager)
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA000: return "_Open";
|
||||
|
@ -549,10 +549,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA005: return "_Status";
|
||||
case 0xA006: return "_KillIO";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; File Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA007: return "_GetVolInfo";
|
||||
|
@ -595,27 +595,27 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA241: return "_HSetFLock";
|
||||
case 0xA242: return "_HRstFLock";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; dispatch trap for remaining File Manager (and Desktop Manager) calls
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA060: return "_FSDispatch";
|
||||
case 0xA260: return "_HFSDispatch";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; High level FSSpec calls
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xAA52: return "_HighLevelHFSDispatch";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Memory Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA019: return "_InitZone";
|
||||
|
@ -652,10 +652,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA08F: return "_DeferUserFn";
|
||||
case 0xA08D: return "_DebugUtil";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Event Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA02F: return "_PostEvent";
|
||||
|
@ -697,8 +697,8 @@ const char *TrapName(uint16_t trap)
|
|||
// case 0xA057: return "_SetApplBase";
|
||||
case 0xA198: return "_HWPriv";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; New names for (mostly) new flavors of old LwrString trap (redone <13>)
|
||||
*/
|
||||
|
||||
|
@ -707,10 +707,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA456: return "_UpperText";
|
||||
case 0xA656: return "_StripUpperText";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Temporary Memory routines
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA88F: return "_OSDispatch";
|
||||
|
@ -765,10 +765,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA087: return "_IOPMsgRequest";
|
||||
case 0xA088: return "_IOPMoveData";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Power Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA09F: return "_PowerDispatch";
|
||||
|
@ -782,19 +782,19 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA48A: return "_SleepQRemove";
|
||||
// case 0xA48A: return "_SlpQRemove";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Comm. Toolbox
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA08B: return "_CommToolboxDispatch";
|
||||
case 0xA090: return "_SysEnvirons";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Egret Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA092: return "_EgretDispatch";
|
||||
|
@ -809,10 +809,10 @@ const char *TrapName(uint16_t trap)
|
|||
// case 0xA9C3: return "_KeyTrans";
|
||||
case 0xA9C3: return "_KeyTranslate";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; TextEdit
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA9CB: return "_TEGetText";
|
||||
|
@ -842,10 +842,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA83D: return "_TEDispatch";
|
||||
case 0xA83E: return "_TEStyleNew";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Color Quickdraw
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xAA00: return "_OpenCPort";
|
||||
|
@ -899,10 +899,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xAA4F: return "_CalcCMask";
|
||||
case 0xAA51: return "_CopyDeepMask";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Routines for video devices
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xAA27: return "_GetMaxDevice";
|
||||
|
@ -920,10 +920,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xAA32: return "_GetGDevice";
|
||||
case 0xABCA: return "_DeviceLoop";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Color Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xAA33: return "_Color2Index";
|
||||
|
@ -933,10 +933,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xAA37: return "_GetSubTable";
|
||||
case 0xAA38: return "_UpdatePixMap";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Dialog Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// case 0xAA4B: return "_NewCDialog";
|
||||
|
@ -956,10 +956,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xAA4E: return "_SetStdCProcs";
|
||||
case 0xABF8: return "_StdOpcodeProc";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; added to Toolbox for color
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xAA41: return "_SetWinColor";
|
||||
|
@ -976,10 +976,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA809: return "_GetControlVariant";
|
||||
case 0xA80A: return "_GetWVariant";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; added to Menu Manager for color
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// case 0xAA60: return "_DelMCEntries";
|
||||
|
@ -991,36 +991,36 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xAA64: return "_GetMCEntry";
|
||||
case 0xAA65: return "_SetMCEntries";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Menu Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xAA66: return "_MenuChoice";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Dialog Manager?
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xAA67: return "_ModalDialogMenuSetup";
|
||||
case 0xAA68: return "_DialogDispatch";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Font Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA814: return "_SetFractEnable";
|
||||
case 0xA854: return "_FontDispatch";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Palette Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xAA90: return "_InitPalettes";
|
||||
|
@ -1044,10 +1044,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xAAA1: return "_CopyPalette";
|
||||
case 0xAAA2: return "_PaletteDispatch";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Sound Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA800: return "_SoundDispatch";
|
||||
|
@ -1079,26 +1079,26 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xA05E: return "_NMInstall";
|
||||
case 0xA05F: return "_NMRemove";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; All QDOffscreen Routines go through one trap with a selector
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xAB1D: return "_QDExtensions";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; UserDelay
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA84C: return "_UserDelay";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Component Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xA82A: return "_ComponentDispatch";
|
||||
|
@ -1114,10 +1114,10 @@ const char *TrapName(uint16_t trap)
|
|||
case 0xAA59: return "_MixedModeDispatch";
|
||||
case 0xAA5A: return "_CodeFragmentDispatch";
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
; Translation Manager
|
||||
|
||||
|
||||
*/
|
||||
|
||||
case 0xABFC: return "_TranslationDispatch";
|
||||
|
|
|
@ -1,22 +1,29 @@
|
|||
/*
|
||||
File: Traps.h
|
||||
|
||||
|
||||
Contains: A-Trap constants.
|
||||
|
||||
|
||||
Version: Technology: Mac OS 9
|
||||
Release: Universal Interfaces 3.4
|
||||
|
||||
|
||||
Copyright: © 1985-2001 by Apple Computer, Inc., all rights reserved
|
||||
|
||||
|
||||
Bugs?: For bug reports, consult the following page on
|
||||
the World Wide Web:
|
||||
|
||||
|
||||
http://developer.apple.com/bugreporter/
|
||||
|
||||
|
||||
*/
|
||||
#ifndef __macos_traps__
|
||||
#define __macos_traps__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
const char *TrapName(uint16_t trap);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace MacOS {
|
||||
|
@ -1040,7 +1047,7 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
_ALMDispatch = 0xAAA4 /* Apple Location Manger*/
|
||||
_ALMDispatch = 0xAAA4 /* Apple Location Manager*/
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -1072,4 +1079,3 @@ enum {
|
|||
#endif
|
||||
|
||||
#endif /* __TRAPS__ */
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(MPLITE_SRC mplite.c)
|
||||
|
||||
add_library(MPLITE_LIB ${MPLITE_SRC})
|
|
@ -33,7 +33,7 @@ struct mplite_link {
|
|||
|
||||
/*
|
||||
** Assuming mplite_t.zPool is divided up into an array of mplite_link_t
|
||||
** structures, return a pointer to the idx-th such lik.
|
||||
** structures, return a pointer to the idx-th such link.
|
||||
*/
|
||||
#define mplite_getlink(handle, idx) ((mplite_link_t *) \
|
||||
(&handle->zPool[(idx) * handle->szAtom]))
|
||||
|
@ -49,7 +49,6 @@ static int mplite_logarithm(const int iValue);
|
|||
static int mplite_size(const mplite_t *handle, const void *p);
|
||||
static void mplite_link(mplite_t *handle, const int i, const int iLogsize);
|
||||
static void mplite_unlink(mplite_t *handle, const int i, const int iLogsize);
|
||||
static int mplite_unlink_first(mplite_t *handle, const int iLogsize);
|
||||
static void *mplite_malloc_unsafe(mplite_t *handle, const int nByte);
|
||||
static void mplite_free_unsafe(mplite_t *handle, const void *pOld);
|
||||
|
||||
|
@ -308,19 +307,17 @@ static int mplite_logarithm(const int iValue)
|
|||
}
|
||||
|
||||
/*
|
||||
** Return the size of an outstanding allocation, in bytes. The
|
||||
** size returned omits the 8-byte header overhead. This only
|
||||
** works for chunks that are currently checked out.
|
||||
** Return the size of an outstanding allocation, in bytes.
|
||||
** This only works for chunks that are currently checked out.
|
||||
*/
|
||||
static int mplite_size(const mplite_t *handle, const void *p)
|
||||
{
|
||||
int iSize = 0;
|
||||
if (p) {
|
||||
int i = ((uint8_t *) p - handle->zPool) / handle->szAtom;
|
||||
assert(i >= 0 && i < handle->nBlock);
|
||||
iSize = handle->szAtom *
|
||||
(1 << (handle->aCtrl[i] & MPLITE_CTRL_LOGSIZE));
|
||||
}
|
||||
int iSize, i;
|
||||
assert( p!=0 );
|
||||
i = (int)((uint8_t *) p - handle->zPool) / handle->szAtom;
|
||||
assert(i >= 0 && i < handle->nBlock);
|
||||
iSize = handle->szAtom * (1 << (handle->aCtrl[i] & MPLITE_CTRL_LOGSIZE));
|
||||
|
||||
return iSize;
|
||||
}
|
||||
|
||||
|
@ -368,31 +365,12 @@ static void mplite_unlink(mplite_t *handle, const int i, const int iLogsize)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Find the first entry on the freelist iLogsize. Unlink that
|
||||
** entry and return its index.
|
||||
*/
|
||||
static int mplite_unlink_first(mplite_t *handle, const int iLogsize)
|
||||
{
|
||||
int i;
|
||||
int iFirst;
|
||||
|
||||
assert(iLogsize >= 0 && iLogsize <= MPLITE_LOGMAX);
|
||||
i = iFirst = handle->aiFreelist[iLogsize];
|
||||
assert(iFirst >= 0);
|
||||
while (i > 0) {
|
||||
if (i < iFirst) iFirst = i;
|
||||
i = mplite_getlink(handle, i)->next;
|
||||
}
|
||||
mplite_unlink(handle, iFirst, iLogsize);
|
||||
return iFirst;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a block of memory of at least nBytes in size.
|
||||
** Return NULL if unable. Return NULL if nBytes==0.
|
||||
**
|
||||
** The caller guarantees that nByte positive.
|
||||
** The caller guarantees that nByte is positive.
|
||||
**
|
||||
** The caller has obtained a lock prior to invoking this
|
||||
** routine so there is never any chance that two or more
|
||||
|
@ -408,19 +386,15 @@ static void *mplite_malloc_unsafe(mplite_t *handle, const int nByte)
|
|||
/* nByte must be a positive */
|
||||
assert(nByte > 0);
|
||||
|
||||
/* No more than 1GiB per allocation */
|
||||
if( nByte > MPLITE_MAX_ALLOC_SIZE ) return 0;
|
||||
|
||||
/* Keep track of the maximum allocation request. Even unfulfilled
|
||||
** requests are counted */
|
||||
if ((uint32_t) nByte > handle->maxRequest) {
|
||||
handle->maxRequest = nByte;
|
||||
}
|
||||
|
||||
/* Abort if the requested allocation size is larger than the largest
|
||||
** power of two that we can represent using 32-bit signed integers.
|
||||
*/
|
||||
if (nByte > MPLITE_MAX_ALLOC_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Round nByte up to the next valid power of two */
|
||||
for (iFullSz = handle->szAtom, iLogsize = 0; iFullSz < nByte; iFullSz *= 2,
|
||||
iLogsize++) {
|
||||
|
@ -430,13 +404,16 @@ static void *mplite_malloc_unsafe(mplite_t *handle, const int nByte)
|
|||
** block. If not, then split a block of the next larger power of
|
||||
** two in order to create a new free block of size iLogsize.
|
||||
*/
|
||||
for (iBin = iLogsize; handle->aiFreelist[iBin] < 0 && iBin <= MPLITE_LOGMAX;
|
||||
for (iBin = iLogsize; iBin <= MPLITE_LOGMAX && handle->aiFreelist[iBin] < 0;
|
||||
iBin++) {
|
||||
}
|
||||
if (iBin > MPLITE_LOGMAX) {
|
||||
return NULL;
|
||||
}
|
||||
i = mplite_unlink_first(handle, iBin);
|
||||
|
||||
i = handle->aiFreelist[iBin];
|
||||
mplite_unlink(handle, i, iBin);
|
||||
|
||||
while (iBin > iLogsize) {
|
||||
int newSize;
|
||||
|
||||
|
@ -460,6 +437,12 @@ static void *mplite_malloc_unsafe(mplite_t *handle, const int nByte)
|
|||
handle->maxOut = handle->currentOut;
|
||||
}
|
||||
|
||||
#ifdef MPLITE_DEBUG
|
||||
/* Make sure the allocated memory does not assume that it is set to zero
|
||||
** or retains a value from a previous allocation */
|
||||
memset(&handle->zPool[i * handle->szAtom], 0xAA, iFullSz);
|
||||
#endif
|
||||
|
||||
/* Return a pointer to the allocated memory. */
|
||||
return (void*) &handle->zPool[i * handle->szAtom];
|
||||
}
|
||||
|
@ -475,7 +458,7 @@ static void mplite_free_unsafe(mplite_t *handle, const void *pOld)
|
|||
/* Set iBlock to the index of the block pointed to by pOld in
|
||||
** the array of handle->szAtom byte blocks pointed to by handle->zPool.
|
||||
*/
|
||||
iBlock = ((uint8_t *) pOld - handle->zPool) / handle->szAtom;
|
||||
iBlock = (int)((uint8_t *) pOld - handle->zPool) / handle->szAtom;
|
||||
|
||||
/* Check that the pointer pOld points to a valid, non-free block. */
|
||||
assert(iBlock >= 0 && iBlock < handle->nBlock);
|
||||
|
@ -500,12 +483,12 @@ static void mplite_free_unsafe(mplite_t *handle, const void *pOld)
|
|||
int iBuddy;
|
||||
if ((iBlock >> iLogsize) & 1) {
|
||||
iBuddy = iBlock - size;
|
||||
assert(iBuddy >= 0);
|
||||
}
|
||||
else {
|
||||
iBuddy = iBlock + size;
|
||||
if (iBuddy >= handle->nBlock) break;
|
||||
}
|
||||
assert(iBuddy >= 0);
|
||||
if ((iBuddy + (1 << iLogsize)) > handle->nBlock) break;
|
||||
if (handle->aCtrl[iBuddy] != (MPLITE_CTRL_FREE | iLogsize)) break;
|
||||
mplite_unlink(handle, iBuddy, iLogsize);
|
||||
iLogsize++;
|
||||
|
@ -520,5 +503,12 @@ static void mplite_free_unsafe(mplite_t *handle, const void *pOld)
|
|||
}
|
||||
size *= 2;
|
||||
}
|
||||
|
||||
#ifdef MPLITE_DEBUG
|
||||
/* Overwrite freed memory with the 0x55 bit pattern to verify that it is
|
||||
** not used after being freed */
|
||||
memset(&handle->zPool[iBlock * handle->szAtom], 0x55, size);
|
||||
#endif
|
||||
|
||||
mplite_link(handle, iBlock, iLogsize);
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
*
|
||||
* This memory allocator uses the following algorithm:
|
||||
*
|
||||
* 1. All memory allocations sizes are rounded up to a power of 2.
|
||||
* 1. All memory allocation sizes are rounded up to a power of 2.
|
||||
*
|
||||
* 2. If two adjacent free blocks are the halves of a larger block,
|
||||
* then the two blocks are coalesed into the single larger block.
|
||||
* then the two blocks are coalesced into the single larger block.
|
||||
*
|
||||
* 3. New memory is allocated from the first available free block.
|
||||
*
|
||||
|
@ -40,11 +40,7 @@
|
|||
#ifndef MPLITE_H
|
||||
#define MPLITE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "pstdint.h"
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif /* #ifdef _WIN32 */
|
||||
|
||||
/**
|
||||
* @brief The function call returns success
|
||||
|
@ -114,9 +110,12 @@ typedef struct mplite {
|
|||
uint32_t maxCount; /**< Maximum instantaneous currentCount */
|
||||
uint32_t maxRequest; /**< Largest allocation (exclusive of internal frag) */
|
||||
|
||||
int aiFreelist[MPLITE_LOGMAX + 1]; /**< List of free blocks. aiFreelist[0]
|
||||
is a list of free blocks of size mplite_t.szAtom. aiFreelist[1] holds
|
||||
blocks of size szAtom * 2 and so forth.*/
|
||||
/**
|
||||
* Lists of free blocks. aiFreelist[0] is a list of free blocks of
|
||||
* size mplite_t.szAtom. aiFreelist[1] holds blocks of size szAtom*2.
|
||||
* aiFreelist[2] holds free blocks of size szAtom*4. And so forth.
|
||||
*/
|
||||
int aiFreelist[MPLITE_LOGMAX + 1];
|
||||
|
||||
uint8_t *aCtrl; /**< Space for tracking which blocks are checked out and the
|
||||
size of each block. One byte per block. */
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
* include stdint.h. The hope is that one or the other can be
|
||||
* used with no real difference.
|
||||
*
|
||||
* 5) In the current verison, if your platform can't represent
|
||||
* 5) In the current version, if your platform can't represent
|
||||
* int32_t, int16_t and int8_t, it just dumps out with a compiler
|
||||
* error.
|
||||
*
|
||||
|
|
|
@ -1,11 +1,22 @@
|
|||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -g")
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
add_definitions(-I ${CMAKE_SOURCE_DIR}/)
|
||||
|
||||
set(MPW_SRC mpw.cpp mpw_io.cpp mpw_close.cpp mpw_access.cpp mpw_ioctl.cpp environ.cpp)
|
||||
set(MPW_SRC mpw.cpp mpw_io.cpp mpw_close.cpp mpw_access.cpp mpw_ioctl.cpp mpw_errno.cpp
|
||||
environment.cpp)
|
||||
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT environment.cpp
|
||||
COMMAND "${RAGEL}" -p -G2 -o environment.cpp "${CMAKE_CURRENT_SOURCE_DIR}/environment.rl"
|
||||
MAIN_DEPENDENCY environment.rl
|
||||
)
|
||||
|
||||
|
||||
set_source_files_properties(
|
||||
environment.cpp # environ.cpp ep.cpp epv.cpp
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -Wno-unused-variable"
|
||||
)
|
||||
|
||||
add_library(MPW_LIB ${MPW_SRC})
|
356
mpw/environ.cpp
356
mpw/environ.cpp
|
@ -1,356 +0,0 @@
|
|||
/* Generated by re2c 0.13.5 on Sat May 18 16:26:02 2013 */
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
/*
|
||||
* #...comment
|
||||
* var=value
|
||||
* where value may contain $var and ${var} interpolations.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace MPW {
|
||||
std::string EvalString(std::string &s, std::unordered_map<std::string, std::string> &env)
|
||||
{
|
||||
|
||||
std::string rv;
|
||||
const char *cp = s.c_str();
|
||||
const char *marker = NULL;
|
||||
|
||||
while (*cp)
|
||||
{
|
||||
const char *begin = cp;
|
||||
|
||||
|
||||
{
|
||||
char yych;
|
||||
|
||||
yych = (char)*cp;
|
||||
switch (yych) {
|
||||
case '\n': goto yy5;
|
||||
case '$': goto yy2;
|
||||
default: goto yy4;
|
||||
}
|
||||
yy2:
|
||||
yych = (char)*(marker = ++cp);
|
||||
switch (yych) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
case 'G':
|
||||
case 'H':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'K':
|
||||
case 'L':
|
||||
case 'M':
|
||||
case 'N':
|
||||
case 'O':
|
||||
case 'P':
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 'U':
|
||||
case 'V':
|
||||
case 'W':
|
||||
case 'X':
|
||||
case 'Y':
|
||||
case 'Z':
|
||||
case '_':
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'h':
|
||||
case 'i':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'q':
|
||||
case 'r':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'v':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'y':
|
||||
case 'z': goto yy9;
|
||||
case '{': goto yy7;
|
||||
default: goto yy3;
|
||||
}
|
||||
yy3:
|
||||
{
|
||||
rv.push_back(*begin);
|
||||
continue;
|
||||
}
|
||||
yy4:
|
||||
yych = (char)*++cp;
|
||||
goto yy3;
|
||||
yy5:
|
||||
++cp;
|
||||
{
|
||||
break;
|
||||
}
|
||||
yy7:
|
||||
yych = (char)*++cp;
|
||||
switch (yych) {
|
||||
case '}': goto yy8;
|
||||
default: goto yy13;
|
||||
}
|
||||
yy8:
|
||||
cp = marker;
|
||||
goto yy3;
|
||||
yy9:
|
||||
++cp;
|
||||
yych = (char)*cp;
|
||||
switch (yych) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
case 'G':
|
||||
case 'H':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'K':
|
||||
case 'L':
|
||||
case 'M':
|
||||
case 'N':
|
||||
case 'O':
|
||||
case 'P':
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 'U':
|
||||
case 'V':
|
||||
case 'W':
|
||||
case 'X':
|
||||
case 'Y':
|
||||
case 'Z':
|
||||
case '_':
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'h':
|
||||
case 'i':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'q':
|
||||
case 'r':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'v':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'y':
|
||||
case 'z': goto yy9;
|
||||
default: goto yy11;
|
||||
}
|
||||
yy11:
|
||||
{
|
||||
std::string tmp(begin + 1, cp);
|
||||
|
||||
// lookup value...
|
||||
// append to rv.
|
||||
auto iter = env.find(tmp);
|
||||
if (iter != env.end())
|
||||
{
|
||||
rv.append(iter->second);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
yy12:
|
||||
++cp;
|
||||
yych = (char)*cp;
|
||||
yy13:
|
||||
switch (yych) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
case 'G':
|
||||
case 'H':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'K':
|
||||
case 'L':
|
||||
case 'M':
|
||||
case 'N':
|
||||
case 'O':
|
||||
case 'P':
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 'U':
|
||||
case 'V':
|
||||
case 'W':
|
||||
case 'X':
|
||||
case 'Y':
|
||||
case 'Z':
|
||||
case '_':
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'h':
|
||||
case 'i':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'q':
|
||||
case 'r':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'v':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'y':
|
||||
case 'z': goto yy12;
|
||||
case '}': goto yy14;
|
||||
default: goto yy8;
|
||||
}
|
||||
yy14:
|
||||
++cp;
|
||||
{
|
||||
|
||||
std::string tmp(begin + 2, cp - 1);
|
||||
|
||||
auto iter = env.find(tmp);
|
||||
if (iter != env.end())
|
||||
{
|
||||
rv.append(iter->second);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
void LoadEnvironment(std::string &envfile, std::unordered_map<std::string, std::string> &env)
|
||||
{
|
||||
|
||||
FILE *fp;
|
||||
|
||||
|
||||
fp = fopen(envfile.c_str(), "r");
|
||||
|
||||
if (!fp) return;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char *begin;
|
||||
char *end;
|
||||
char *iter;
|
||||
|
||||
size_t length;
|
||||
|
||||
begin = fgetln(fp, &length);
|
||||
if (!begin) break; // eof or error.
|
||||
|
||||
if (!length) continue;
|
||||
if (begin[0] == '#') continue;
|
||||
|
||||
while (length && isspace(begin[length - 1])) --length;
|
||||
if (!length) continue;
|
||||
|
||||
// key=value
|
||||
|
||||
// ehh, this could really check for [A-Za-z0-9_]+ '='
|
||||
|
||||
end = begin + length;
|
||||
iter = std::find(begin, end, '=');
|
||||
|
||||
if (iter == end || iter == begin)
|
||||
{
|
||||
fprintf(stderr, "Invalid Environment entry: %.*s\n", (int)length, begin);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string key(begin, iter);
|
||||
std::string value(iter + 1, end);
|
||||
|
||||
value = EvalString(value, env);
|
||||
|
||||
//fprintf(stdout, "%s = %s\n", key.c_str(), value.c_str());
|
||||
|
||||
// todo -- does this replace an existing value?
|
||||
env.emplace(key, value);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
}
|
|
@ -29,7 +29,7 @@ std::string EvalString(std::string &s, std::unordered_map<std::string, std::stri
|
|||
re2c:yyfill:enable = 0;
|
||||
re2c:yych:conversion = 1;
|
||||
re2c:indent:top = 1;
|
||||
|
||||
|
||||
'$' [A-Za-z0-9_]+ {
|
||||
std::string tmp(begin + 1, cp);
|
||||
|
||||
|
@ -44,7 +44,7 @@ std::string EvalString(std::string &s, std::unordered_map<std::string, std::stri
|
|||
}
|
||||
|
||||
'${' [A-Za-z0-9_]+ '}' {
|
||||
|
||||
|
||||
std::string tmp(begin + 2, cp - 1);
|
||||
|
||||
auto iter = env.find(tmp);
|
||||
|
@ -86,7 +86,7 @@ void LoadEnvironment(std::string &envfile, std::unordered_map<std::string, std::
|
|||
char *end;
|
||||
char *iter;
|
||||
|
||||
size_t length;
|
||||
size_t length;
|
||||
|
||||
begin = fgetln(fp, &length);
|
||||
if (!begin) break; // eof or error.
|
||||
|
@ -124,4 +124,4 @@ void LoadEnvironment(std::string &envfile, std::unordered_map<std::string, std::
|
|||
fclose(fp);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
483
mpw/environment.rl
Normal file
483
mpw/environment.rl
Normal file
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
|
||||
extern char **environ;
|
||||
|
||||
|
||||
namespace _env_rl {
|
||||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
|
||||
#define _GETDELIM_GROWBY 128 /* amount to grow line buffer by */
|
||||
#define _GETDELIM_MINLEN 4 /* minimum line buffer size */
|
||||
|
||||
ssize_t getdelim(char ** lineptr, size_t * n, int delimiter, FILE * stream) {
|
||||
char *buf, *pos;
|
||||
int c;
|
||||
ssize_t bytes;
|
||||
|
||||
if (lineptr == NULL || n == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (stream == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* resize (or allocate) the line buffer if necessary */
|
||||
buf = *lineptr;
|
||||
if (buf == NULL || *n < _GETDELIM_MINLEN) {
|
||||
buf = (char*)realloc(*lineptr, _GETDELIM_GROWBY);
|
||||
if (buf == NULL) {
|
||||
/* ENOMEM */
|
||||
return -1;
|
||||
}
|
||||
*n = _GETDELIM_GROWBY;
|
||||
*lineptr = buf;
|
||||
}
|
||||
|
||||
/* read characters until delimiter is found, end of file is reached, or an
|
||||
error occurs. */
|
||||
bytes = 0;
|
||||
pos = buf;
|
||||
while ((c = getc(stream)) != EOF) {
|
||||
if (bytes + 1 >= SSIZE_MAX) {
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
bytes++;
|
||||
if (bytes >= *n - 1) {
|
||||
buf = (char*)realloc(*lineptr, *n + _GETDELIM_GROWBY);
|
||||
if (buf == NULL) {
|
||||
/* ENOMEM */
|
||||
return -1;
|
||||
}
|
||||
*n += _GETDELIM_GROWBY;
|
||||
pos = buf + bytes - 1;
|
||||
*lineptr = buf;
|
||||
}
|
||||
|
||||
*pos++ = (char) c;
|
||||
if (c == delimiter) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror(stream) || (feof(stream) && (bytes == 0))) {
|
||||
/* EOF, or an error from getc(). */
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pos = '\0';
|
||||
return bytes;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ssize_t getline(char ** lineptr, size_t * n, FILE * stream) {
|
||||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
|
||||
return getdelim(lineptr, n, '\n', stream);
|
||||
#else
|
||||
return ::getline(lineptr, n, stream);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
extern std::unordered_map<std::string, std::string> Environment;
|
||||
|
||||
std::string ExpandVariables(const std::string &s, bool pathname = false);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
%%{
|
||||
machine name;
|
||||
|
||||
main :=
|
||||
|
||||
[A-Za-z0-9_]+ @{
|
||||
name.push_back(fc);
|
||||
}
|
||||
;
|
||||
|
||||
write data;
|
||||
}%%
|
||||
|
||||
%%{
|
||||
machine assign;
|
||||
|
||||
ws = [ \t\r\n];
|
||||
main :=
|
||||
|
||||
ws*
|
||||
(
|
||||
'=' @{
|
||||
op = 1;
|
||||
}
|
||||
|
|
||||
'+=' @{
|
||||
op = 2;
|
||||
}
|
||||
|
|
||||
'?=' @{
|
||||
op = 3;
|
||||
}
|
||||
)
|
||||
ws*
|
||||
;
|
||||
|
||||
write data;
|
||||
}%%
|
||||
|
||||
%%{
|
||||
machine variables;
|
||||
|
||||
coalesce_colon := |*
|
||||
|
||||
':' {
|
||||
if (rv.length() && rv.back() != ':')
|
||||
rv.push_back(':');
|
||||
|
||||
fgoto main;
|
||||
};
|
||||
any {
|
||||
fhold;
|
||||
fgoto main;
|
||||
};
|
||||
*|;
|
||||
|
||||
main := |*
|
||||
|
||||
'{' [A-Za-z0-9_]+ '}' {
|
||||
|
||||
std::string name(ts + 1, te - 1);
|
||||
auto iter = Environment.find(name);
|
||||
if (iter != Environment.end())
|
||||
rv.append(iter->second);
|
||||
|
||||
fgoto coalesce_colon;
|
||||
};
|
||||
|
||||
# backwards compatibility.
|
||||
'${' [A-Za-z0-9_]+ '}' {
|
||||
|
||||
if (pathname) {
|
||||
rv.append(ts, te);
|
||||
} else {
|
||||
std::string name(ts + 2, te - 1);
|
||||
auto iter = Environment.find(name);
|
||||
if (iter != Environment.end())
|
||||
rv.append(iter->second);
|
||||
|
||||
fgoto coalesce_colon;
|
||||
}
|
||||
};
|
||||
|
||||
# backwards compatibility.
|
||||
# lcc generates temporary files named $xxx$
|
||||
# so don't replace in pathnames.
|
||||
'$' [A-Za-z0-9_]+ {
|
||||
if (pathname) {
|
||||
rv.append(ts, te);
|
||||
} else {
|
||||
std::string name(ts + 1, te);
|
||||
auto iter = Environment.find(name);
|
||||
if (iter != Environment.end())
|
||||
rv.append(iter->second);
|
||||
|
||||
fgoto coalesce_colon;
|
||||
}
|
||||
};
|
||||
|
||||
any {
|
||||
rv.push_back(*ts);
|
||||
};
|
||||
*|;
|
||||
|
||||
write data;
|
||||
}%%
|
||||
|
||||
// split out since goto names conflict.
|
||||
const char* GetName(const char *p, const char *pe, std::string &name)
|
||||
{
|
||||
const char *eof = pe;
|
||||
int cs;
|
||||
|
||||
%%{
|
||||
machine name;
|
||||
write init;
|
||||
write exec;
|
||||
}%%
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
const char *GetAssignment(const char *p, const char *pe, unsigned &op)
|
||||
{
|
||||
const char *eof = pe;
|
||||
int cs;
|
||||
|
||||
%%{
|
||||
machine assign;
|
||||
write init;
|
||||
write exec;
|
||||
}%%
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
bool ParseLine(const char *p, const char *pe)
|
||||
{
|
||||
/*
|
||||
* name = value
|
||||
* name += value
|
||||
* name ?= value
|
||||
*/
|
||||
|
||||
std::string name;
|
||||
unsigned op = 0;
|
||||
|
||||
const char *begin = p;
|
||||
|
||||
// 1. get the name
|
||||
p = GetName(p, pe, name);
|
||||
if (!name.length())
|
||||
{
|
||||
#ifdef TESTING
|
||||
fprintf(stderr, "No Name\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. get the op
|
||||
p = GetAssignment(p, pe, op);
|
||||
if (!op)
|
||||
{
|
||||
fprintf(stderr, "No assignment\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string value(p, pe);
|
||||
value = MPW::ExpandVariables(value);
|
||||
|
||||
auto iter = MPW::Environment.find(name);
|
||||
if (iter == MPW::Environment.end())
|
||||
{
|
||||
MPW::Environment.emplace(std::move(name), std::move(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(op)
|
||||
{
|
||||
case 1: // =
|
||||
iter->second = std::move(value);
|
||||
break;
|
||||
case 2: // +=
|
||||
iter->second += value;
|
||||
break;
|
||||
case 3: // ?=
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace MPW {
|
||||
|
||||
|
||||
std::string GetEnv(const std::string &key)
|
||||
{
|
||||
auto iter = Environment.find(key);
|
||||
if (iter == Environment.end()) return "";
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
std::string ExpandVariables(const std::string &s, bool pathname)
|
||||
{
|
||||
if (s.find_first_of("{$") == s.npos) return s;
|
||||
|
||||
std::string rv;
|
||||
const char *p = s.c_str();
|
||||
const char *pe = p + s.length();
|
||||
const char *eof = pe;
|
||||
const char *te;
|
||||
const char *ts;
|
||||
|
||||
int cs;
|
||||
int act;
|
||||
|
||||
%%{
|
||||
machine variables;
|
||||
|
||||
write init;
|
||||
write exec;
|
||||
}%%
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void EnvLoadArray(const std::vector<std::string> &data)
|
||||
{
|
||||
for (const auto &s : data)
|
||||
{
|
||||
const char *begin = s.c_str();
|
||||
const char *end = begin + s.length();
|
||||
if (!s.length()) continue;
|
||||
if (!ParseLine(begin, end))
|
||||
{
|
||||
fprintf(stderr, "Error in variable: %s\n", s.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnvLoadEnv() {
|
||||
/* load from environ */
|
||||
|
||||
for (unsigned i = 0; environ[i]; ++i) {
|
||||
if (memcmp(environ[i], "mpw$", 4)) continue;
|
||||
|
||||
std::string s(environ[i] + 4);
|
||||
auto pos = s.find('=');
|
||||
if (pos == 0) continue;
|
||||
if (pos == s.npos) {
|
||||
MPW::Environment.emplace(std::move(s), "");
|
||||
} else {
|
||||
MPW::Environment.emplace(s.substr(0, pos), s.substr(pos+1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void EnvLoadFile(const std::string &envfile)
|
||||
{
|
||||
|
||||
FILE *fp;
|
||||
|
||||
|
||||
fp = fopen(envfile.c_str(), "r");
|
||||
|
||||
if (!fp) return;
|
||||
|
||||
|
||||
/*
|
||||
* getline(3) is 2008 posix. it allocates (and resizes as appropriate)
|
||||
* the buffer.
|
||||
*
|
||||
*/
|
||||
char *lineBuffer = NULL;
|
||||
size_t lineSize = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
char *line;
|
||||
ssize_t length;
|
||||
|
||||
length = _env_rl::getline(&lineBuffer, &lineSize, fp);
|
||||
if (!length) continue; //?
|
||||
if (length < 0) break; // eof or error.
|
||||
|
||||
line = lineBuffer;
|
||||
|
||||
// skip any leading space.
|
||||
while (length && isspace(*line))
|
||||
{
|
||||
++line;
|
||||
--length;
|
||||
}
|
||||
if (!length) continue;
|
||||
|
||||
// comments
|
||||
if (*line == '#') continue;
|
||||
|
||||
|
||||
// strip any trailing space.
|
||||
// (will be \n terminated unless there was no \n)
|
||||
while (length && isspace(line[length - 1]))
|
||||
{
|
||||
line[--length] = 0;
|
||||
}
|
||||
if (!length) continue;
|
||||
|
||||
if (!ParseLine(line, line + length))
|
||||
{
|
||||
fprintf(stderr, "Error in variable: %s\n", line);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef TESTING
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
std::unordered_map<std::string, std::string> Environment;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
char *cp = argv[i];
|
||||
int len = strlen(cp);
|
||||
|
||||
if (!ParseLine(cp, cp + len))
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", cp);
|
||||
}
|
||||
}
|
||||
|
||||
MPW::EnvLoadFile("/Users/kelvin/mpw/Environment.text");
|
||||
|
||||
for (auto kv : MPW::Environment)
|
||||
{
|
||||
printf("%s --> %s\n", kv.first.c_str(), kv.second.c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
158
mpw/ep.rl
Normal file
158
mpw/ep.rl
Normal file
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* file -> file
|
||||
* :directory:file -> directory/file
|
||||
* volume:directory -> /volume/directory
|
||||
* :: -> ../
|
||||
* ::: -> ../../
|
||||
*/
|
||||
|
||||
%%{
|
||||
|
||||
machine m;
|
||||
|
||||
main := |*
|
||||
|
||||
|
||||
':' {2,} {
|
||||
|
||||
// :: = ..
|
||||
// ::: = ../..
|
||||
// etc
|
||||
unsigned count = te - ts;
|
||||
|
||||
if (ts != begin)
|
||||
{
|
||||
rv.push_back('/');
|
||||
}
|
||||
for (unsigned i = 1; i < count; ++i)
|
||||
{
|
||||
rv.append("../");
|
||||
}
|
||||
};
|
||||
|
||||
':' {
|
||||
if (ts != begin)
|
||||
rv.push_back('/');
|
||||
};
|
||||
|
||||
|
||||
any {
|
||||
rv.push_back(*ts);
|
||||
};
|
||||
|
||||
|
||||
*|;
|
||||
|
||||
}%%
|
||||
|
||||
#include <string>
|
||||
#include "mpw.h"
|
||||
|
||||
namespace {
|
||||
|
||||
%%write data;
|
||||
|
||||
}
|
||||
|
||||
namespace MPW {
|
||||
|
||||
std::string ExpandPathVariables(std::string);
|
||||
|
||||
std::string ExpandPath(std::string s)
|
||||
{
|
||||
std::string rv;
|
||||
|
||||
|
||||
// 1. expand any variables.
|
||||
|
||||
#ifndef TESTING
|
||||
if (s.find('{') != s.npos)
|
||||
{
|
||||
s = ExpandPathVariables(s);
|
||||
}
|
||||
#endif
|
||||
// 2. does it even need it?
|
||||
unsigned sep = 0;
|
||||
for (char c : s)
|
||||
{
|
||||
if (c == ':' || c == '/')
|
||||
{
|
||||
sep = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sep) return s;
|
||||
|
||||
// convert volume:path to /volume/path
|
||||
// leading / manually placed.
|
||||
if (sep == ':' && s.front() != ':')
|
||||
rv.push_back('/');
|
||||
|
||||
auto begin = s.c_str();
|
||||
auto p = begin;
|
||||
auto pe = p + s.length();
|
||||
auto eof = pe;
|
||||
|
||||
const char *ts;
|
||||
const char *te;
|
||||
|
||||
int cs;
|
||||
int act;
|
||||
|
||||
%%write init;
|
||||
|
||||
%%write exec;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if TESTING
|
||||
|
||||
#include <cstdio>
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::string s(argv[i]);
|
||||
printf("%s -> ", s.c_str());
|
||||
s = MPW::ExpandPath(s);
|
||||
printf("%s\n", s.c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
156
mpw/mpw.cpp
156
mpw/mpw.cpp
|
@ -1,9 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpw.h"
|
||||
#include "mpw_errno.h"
|
||||
#include "mpw_internal.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
|
||||
|
@ -19,7 +46,7 @@
|
|||
|
||||
#include <cpu/defs.h>
|
||||
#include <cpu/fmem.h>
|
||||
#include <cpu/cpuModule.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
|
||||
#include <toolbox/toolbox.h>
|
||||
#include <toolbox/mm.h>
|
||||
|
@ -30,68 +57,24 @@
|
|||
extern char **environ;
|
||||
|
||||
|
||||
namespace MPW { namespace Internal {
|
||||
namespace MPW {
|
||||
|
||||
// for dup counts, etc.
|
||||
//std::vector<int> FDTable;
|
||||
|
||||
uint32_t MacProgramInfo = 0;
|
||||
|
||||
} }
|
||||
std::unordered_map<std::string, std::string> Environment;
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
using namespace Internal;
|
||||
|
||||
bool Trace = false;
|
||||
|
||||
int errno_to_errno(int xerrno)
|
||||
{
|
||||
switch (xerrno)
|
||||
{
|
||||
case EPERM: return kEPERM;
|
||||
case ENOENT: return kENOENT;
|
||||
|
||||
#ifdef ENORSRC
|
||||
case ENORSRC: return kENORSRC;
|
||||
#endif
|
||||
|
||||
case EINTR: return kEINTR;
|
||||
case EIO: return kEIO;
|
||||
case ENXIO: return kENXIO;
|
||||
case E2BIG: return kE2BIG;
|
||||
case ENOEXEC: return kENOEXEC;
|
||||
case EBADF: return kEBADF;
|
||||
case ECHILD: return kECHILD;
|
||||
case EAGAIN: return kEAGAIN;
|
||||
case ENOMEM: return kENOMEM;
|
||||
case EACCES: return kEACCES;
|
||||
case EFAULT: return kEFAULT;
|
||||
case ENOTBLK: return kENOTBLK;
|
||||
case EBUSY: return kEBUSY;
|
||||
case EEXIST: return kEEXIST;
|
||||
case EXDEV: return kEXDEV;
|
||||
case ENODEV: return kENODEV;
|
||||
case ENOTDIR: return kENOTDIR;
|
||||
case EISDIR: return kEISDIR;
|
||||
case EINVAL: return kEINVAL;
|
||||
case ENFILE: return kENFILE;
|
||||
case EMFILE: return kEMFILE;
|
||||
case ENOTTY: return kENOTTY;
|
||||
case ETXTBSY: return kETXTBSY;
|
||||
case EFBIG: return kEFBIG;
|
||||
case ENOSPC: return kENOSPC;
|
||||
case ESPIPE: return kESPIPE;
|
||||
case EROFS: return kEROFS;
|
||||
case EMLINK: return kEMLINK;
|
||||
case EPIPE: return kEPIPE;
|
||||
case EDOM: return kEDOM;
|
||||
case ERANGE: return kERANGE;
|
||||
}
|
||||
return kEINVAL;
|
||||
|
||||
}
|
||||
|
||||
static bool isdir(const std::string &path)
|
||||
{
|
||||
|
@ -100,6 +83,15 @@ namespace MPW
|
|||
return S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
std::string RootDirPathForFile(const std::string &file)
|
||||
{
|
||||
std::string dir(RootDir());
|
||||
if (dir.length() && dir.back() != '/') dir.push_back('/');
|
||||
dir.append(file);
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
const std::string RootDir()
|
||||
{
|
||||
static bool initialized = false;
|
||||
|
@ -160,7 +152,7 @@ namespace MPW
|
|||
{
|
||||
std::string s(pwd.pw_dir);
|
||||
if (s.back() != '/') s.push_back('/');
|
||||
s.append("mpw");
|
||||
s.append("mpw");
|
||||
if (isdir(s))
|
||||
{
|
||||
path = std::move(s);
|
||||
|
@ -185,8 +177,36 @@ namespace MPW
|
|||
return path; // unknown.
|
||||
}
|
||||
|
||||
uint16_t InitEnvironment(const std::vector<std::string> &defines)
|
||||
{
|
||||
void EnvLoadFile(const std::string &envfile);
|
||||
void EnvLoadArray(const std::vector<std::string> &data);
|
||||
void EnvLoadEnv();
|
||||
|
||||
|
||||
std::string m(RootDir());
|
||||
if (!m.empty())
|
||||
{
|
||||
std::string mm = ToolBox::UnixToMac(m);
|
||||
if (mm.back() != ':') mm.push_back(':');
|
||||
|
||||
Environment.emplace(std::string("MPW"), mm);
|
||||
}
|
||||
|
||||
EnvLoadEnv(); // should do this first since it could set MPW??
|
||||
|
||||
if (defines.size())
|
||||
EnvLoadArray(defines);
|
||||
|
||||
if (!m.empty())
|
||||
{
|
||||
std::string path(RootDirPathForFile("Environment.text"));
|
||||
EnvLoadFile(path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t Init(int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
|
@ -206,7 +226,7 @@ namespace MPW
|
|||
FDTable[STDOUT_FILENO].text = true;
|
||||
|
||||
FDTable[STDERR_FILENO].refcount = 1;
|
||||
FDTable[STDERR_FILENO].text = true;
|
||||
FDTable[STDERR_FILENO].text = true;
|
||||
*/
|
||||
|
||||
OS::Internal::FDEntry::allocate(STDIN_FILENO).text = true;
|
||||
|
@ -222,7 +242,7 @@ namespace MPW
|
|||
argv[0] = basename(argv[0]);
|
||||
|
||||
|
||||
// 0x0910 CurApName
|
||||
// 0x0910 CurApName
|
||||
{
|
||||
char str32[32];
|
||||
|
||||
|
@ -285,35 +305,13 @@ namespace MPW
|
|||
|
||||
}
|
||||
|
||||
// environment,
|
||||
// just use $MPW and synthesize the other ones.
|
||||
// environment
|
||||
{
|
||||
std::unordered_map<std::string, std::string> env;
|
||||
|
||||
std::string m(RootDir());
|
||||
if (!m.empty())
|
||||
{
|
||||
std::string mm = ToolBox::UnixToMac(m);
|
||||
if (mm.back() != ':') mm.push_back(':');
|
||||
|
||||
env.emplace(std::string("MPW"), mm);
|
||||
}
|
||||
env.emplace(std::string("Command"), command);
|
||||
|
||||
if (!m.empty())
|
||||
{
|
||||
|
||||
void LoadEnvironment(std::string &envfile, std::unordered_map<std::string, std::string> &env);
|
||||
|
||||
if (m.back() != '/') m.push_back('/');
|
||||
m.append("Environment");
|
||||
|
||||
LoadEnvironment(m, env);
|
||||
}
|
||||
Environment.emplace(std::string("Command"), command);
|
||||
|
||||
std::deque<std::string> e;
|
||||
|
||||
for (const auto &iter : env)
|
||||
for (const auto &iter : Environment)
|
||||
{
|
||||
std::string tmp;
|
||||
tmp.append(iter.first);
|
||||
|
@ -324,7 +322,7 @@ namespace MPW
|
|||
|
||||
|
||||
uint32_t size = 0;
|
||||
for(const std::string &s : e)
|
||||
for (const std::string &s : e)
|
||||
{
|
||||
int l = s.length() + 1;
|
||||
if (l & 0x01) l++;
|
||||
|
@ -377,7 +375,7 @@ namespace MPW
|
|||
memoryWriteWord(0x4E75, fptr + 6); // rts
|
||||
|
||||
memoryWriteWord(fClose, fptr + 8);
|
||||
memoryWriteWord(0x4E75, fptr + 10); // rts
|
||||
memoryWriteWord(0x4E75, fptr + 10); // rts
|
||||
|
||||
memoryWriteWord(fRead, fptr + 12);
|
||||
memoryWriteWord(0x4E75, fptr + 14); // rts
|
||||
|
|
13
mpw/mpw.h
13
mpw/mpw.h
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace MPW {
|
||||
|
||||
|
@ -30,7 +31,7 @@ namespace MPW {
|
|||
|
||||
enum
|
||||
{
|
||||
kF_GTABINFO = (('e' << 8) | 0x00), /* get tab offset for file */
|
||||
kF_GTABINFO = (('e' << 8) | 0x00), /* get tab offset for file */
|
||||
kF_STABINFO = (('e' << 8) | 0x01), /* set " " " " */
|
||||
kF_GFONTINFO = (('e' << 8) | 0x02), /* get font number and size for file */
|
||||
kF_SFONTINFO = (('e' << 8) | 0x03), /* set " " " " " " */
|
||||
|
@ -93,8 +94,14 @@ namespace MPW {
|
|||
|
||||
|
||||
const std::string RootDir();
|
||||
std::string RootDirPathForFile(const std::string &file);
|
||||
|
||||
std::string GetEnv(const std::string &);
|
||||
std::string ExpandVariables(const std::string &s, bool pathname = false);
|
||||
|
||||
|
||||
// should add argc/argv/envp...
|
||||
uint16_t InitEnvironment(const std::vector<std::string> &defines);
|
||||
uint16_t Init(int argc, char **argv);
|
||||
|
||||
uint32_t ExitStatus();
|
||||
|
@ -113,8 +120,6 @@ namespace MPW {
|
|||
void ftrap_write(uint16_t trap);
|
||||
void ftrap_ioctl(uint16_t trap);
|
||||
|
||||
// native errno to an MPW errno.
|
||||
int errno_to_errno(int xerrno);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpw.h"
|
||||
#include "mpw_internal.h"
|
||||
#include "mpw_errno.h"
|
||||
|
@ -18,12 +44,14 @@
|
|||
|
||||
#include <cpu/defs.h>
|
||||
#include <cpu/fmem.h>
|
||||
#include <cpu/cpuModule.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
|
||||
#include <toolbox/toolbox.h>
|
||||
#include <toolbox/os.h>
|
||||
#include <toolbox/os_internal.h>
|
||||
|
||||
#include <macos/errors.h>
|
||||
|
||||
/*
|
||||
* access return errors are |= 0x40000000. Not entirely sure why...
|
||||
* may return an errno or an oserr, too, apparently.
|
||||
|
@ -34,9 +62,68 @@ namespace MPW
|
|||
{
|
||||
|
||||
|
||||
|
||||
uint32_t ftrap_set_font_info(uint32_t name, uint32_t parm)
|
||||
{
|
||||
// set_font_info(const char *name, uint32_t fontSize);
|
||||
|
||||
std::string sname = ToolBox::ReadCString(name, true);
|
||||
uint32_t fontSize = parm;
|
||||
|
||||
Log(" set_font_info(%s, %04x)\n", sname.c_str(), fontSize);
|
||||
|
||||
return 0x40000000 | kEINVAL;
|
||||
}
|
||||
|
||||
uint32_t ftrap_get_font_info(uint32_t name, uint32_t parm)
|
||||
{
|
||||
// get_font_info(const char *name, uint32 *fontSize)
|
||||
|
||||
std::string sname = ToolBox::ReadCString(name, true);
|
||||
|
||||
Log(" get_font_info(%s, %04x)\n", sname.c_str(), parm);
|
||||
|
||||
// default to 9pt
|
||||
if (parm) memoryWriteLong(9, parm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ftrap_get_tab_info(uint32_t name, uint32_t parm)
|
||||
{
|
||||
// get_tab_info(const char *name, uint32_t *tabSize)
|
||||
|
||||
// hard code for now.
|
||||
// Could check xattr for actual value.
|
||||
// That would be rather pointless unless some editor respected
|
||||
// it.
|
||||
// Could check an environment variable.
|
||||
|
||||
std::string sname = ToolBox::ReadCString(name, true);
|
||||
|
||||
Log(" get_tab_info(%s)\n", sname.c_str());
|
||||
|
||||
|
||||
if (parm) memoryWriteLong(8, parm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ftrap_set_tab_info(uint32_t name, uint32_t parm)
|
||||
{
|
||||
// set_tab_info(const char *name, uint32_t tabSize)
|
||||
|
||||
std::string sname = ToolBox::ReadCString(name, true);
|
||||
uint32_t tabSize = parm;
|
||||
|
||||
Log(" set_tab_info(%s, %04x)\n", sname.c_str(), tabSize);
|
||||
|
||||
// setxattr?
|
||||
return 0x40000000 | kEINVAL;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ftrap_delete(uint32_t name)
|
||||
{
|
||||
|
||||
std::string sname;
|
||||
int rv;
|
||||
|
||||
|
@ -45,13 +132,69 @@ namespace MPW
|
|||
Log(" delete(%s)\n", sname.c_str());
|
||||
|
||||
rv = ::unlink(sname.c_str());
|
||||
if (rv < 0) return 0x40000000 | errno_to_errno(errno);
|
||||
|
||||
if (rv < 0) return 0x40000000 | mpw_errno_from_errno();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ftrap_rename(uint32_t src, uint32_t dest)
|
||||
{
|
||||
std::string sname;
|
||||
std::string dname;
|
||||
int rv;
|
||||
|
||||
sname = ToolBox::ReadCString(src, true);
|
||||
dname = ToolBox::ReadCString(dest, true);
|
||||
|
||||
Log(" rename(%s, %s)\n", sname.c_str(), dname.c_str());
|
||||
rv = rename(sname.c_str(), dname.c_str());
|
||||
if (rv < 0) return 0x40000000 | mpw_errno_from_errno();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
MPW's open logic pseudo code:
|
||||
|
||||
if (flags & 0x1000) { // undocumented - use old tool calls
|
||||
oserr = flags & O_RSRC ? PBOPENRF() : PBOPEN();
|
||||
} else {
|
||||
oserr = flags & O_RSRC ? PBHOPENRF() : PBHOPEN();
|
||||
}
|
||||
if (!oserr) {
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
|
||||
errno = EEXIST;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (oserr == file not found) {
|
||||
if (flags & O_CREAT) {
|
||||
oserr = PBCreate();
|
||||
if (!oserr) {
|
||||
oserr = flag & O_RSRC ? PBOpenRF() : PBOpen();
|
||||
}
|
||||
}
|
||||
|
||||
PBGETFCBINFO();
|
||||
if (file size) {
|
||||
if (flags & O_TRUNC) {
|
||||
oserr = PBSetEOF();
|
||||
}
|
||||
if (!permission check) {
|
||||
errno = EPERM;
|
||||
PBClose();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
uint32_t ftrap_open(uint32_t name, uint32_t parm)
|
||||
{
|
||||
uint32_t d0;
|
||||
|
@ -59,7 +202,7 @@ namespace MPW
|
|||
std::string sname;
|
||||
|
||||
MPWFile f;
|
||||
int nativeFlags;
|
||||
int nativeFlags = 0;
|
||||
std::memset(&f, 0, sizeof(f));
|
||||
|
||||
f.flags = memoryReadWord(parm);
|
||||
|
@ -91,21 +234,36 @@ namespace MPW
|
|||
|
||||
Log(" open(%s, %04x)\n", sname.c_str(), f.flags);
|
||||
|
||||
// TODO -- can you create a resource file like this?
|
||||
|
||||
if (f.flags & kO_RSRC)
|
||||
sname.append(_PATH_RSRCFORKSPEC);
|
||||
if (f.flags & kO_RSRC) {
|
||||
|
||||
if (f.flags & kO_CREAT)
|
||||
// O_CREAT and O_EXCL apply to the file, not the fork.
|
||||
int flags = O_RDONLY | (nativeFlags & (O_CREAT | O_EXCL));
|
||||
|
||||
int parent = ::open(sname.c_str(), flags, 0666);
|
||||
|
||||
fd = -1;
|
||||
if (parent >= 0) {
|
||||
|
||||
sname.append(_PATH_RSRCFORKSPEC);
|
||||
|
||||
nativeFlags &= ~O_EXCL;
|
||||
// APFS, etc - resource fork doesn't automatically exist so
|
||||
// need O_CREAT.
|
||||
if ((nativeFlags & O_ACCMODE) != O_RDONLY) nativeFlags |= O_CREAT;
|
||||
fd = ::open(sname.c_str(), nativeFlags, 0666);
|
||||
close(parent);
|
||||
}
|
||||
|
||||
} else {
|
||||
fd = ::open(sname.c_str(), nativeFlags, 0666);
|
||||
else
|
||||
fd = ::open(sname.c_str(), nativeFlags);
|
||||
}
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
// return an errno.
|
||||
d0 = 0x40000000 | errno_to_errno(errno);
|
||||
f.error = -36; // ioErr ... whatever.
|
||||
d0 = 0x40000000 | mpw_errno_from_errno();
|
||||
f.error = MacOS::ioErr;
|
||||
f.cookie = 0;
|
||||
}
|
||||
else
|
||||
|
@ -116,7 +274,7 @@ namespace MPW
|
|||
|
||||
|
||||
// adjust the binary flags...
|
||||
// some apps are good about this but
|
||||
// some apps are good about this but
|
||||
// dumpobj, makelib, linkiigs don't set O_BINARY (but should)
|
||||
// MPW Assembler sets O_BINARY (but shouldn't)
|
||||
|
||||
|
@ -153,7 +311,7 @@ namespace MPW
|
|||
uint32_t parm = memoryReadLong(sp + 12);
|
||||
|
||||
Log("%04x Access(%08x, %04x, %08x)\n", trap, name, op, parm);
|
||||
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case kF_OPEN:
|
||||
|
@ -164,22 +322,36 @@ namespace MPW
|
|||
d0 = ftrap_delete(name);
|
||||
break;
|
||||
|
||||
case kF_RENAME:
|
||||
d0 = ftrap_rename(name, parm);
|
||||
break;
|
||||
|
||||
case kF_GTABINFO:
|
||||
d0 = 0x40000000 | kEINVAL;
|
||||
d0 = ftrap_get_tab_info(name, parm);
|
||||
break;
|
||||
|
||||
case kF_STABINFO:
|
||||
d0 = 0x40000000 | kEINVAL;
|
||||
d0 = ftrap_set_tab_info(name, parm);
|
||||
break;
|
||||
|
||||
|
||||
case kF_GFONTINFO:
|
||||
d0 = ftrap_get_font_info(name, parm);
|
||||
break;
|
||||
|
||||
case kF_SFONTINFO:
|
||||
d0 = ftrap_set_font_info(name, parm);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
d0 = 0x40000000 | kEINVAL;
|
||||
fprintf(stderr, "faccess - unsupported op %04x\n", op);
|
||||
exit(1);
|
||||
fprintf(stderr, "faccess - unsupported op %04x\n", op);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cpuSetDReg(0, d0);
|
||||
cpuSetDReg(0, d0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpw.h"
|
||||
#include "mpw_internal.h"
|
||||
#include "mpw_errno.h"
|
||||
|
@ -10,7 +36,7 @@
|
|||
|
||||
#include <cpu/defs.h>
|
||||
#include <cpu/fmem.h>
|
||||
#include <cpu/cpuModule.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
|
||||
#include <macos/errors.h>
|
||||
|
||||
|
@ -81,7 +107,7 @@ namespace MPW
|
|||
f.error = OS::notOpenErr;
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if (--e.refcount == 0)
|
||||
{
|
||||
|
|
225
mpw/mpw_errno.cpp
Normal file
225
mpw/mpw_errno.cpp
Normal file
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <cerrno>
|
||||
|
||||
#include "mpw_errno.h"
|
||||
|
||||
namespace MPW {
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
class __system_category : public std::error_category
|
||||
{
|
||||
public:
|
||||
virtual const char* name() const noexcept;
|
||||
virtual std::string message(int ev) const;
|
||||
virtual std::error_condition default_error_condition(int ev) const noexcept;
|
||||
|
||||
private:
|
||||
static int remap(mpw_errno e);
|
||||
|
||||
};
|
||||
|
||||
|
||||
const char *__system_category::name() const noexcept
|
||||
{
|
||||
return "mpw/errno";
|
||||
}
|
||||
|
||||
std::string __system_category::message(int ev) const
|
||||
{
|
||||
|
||||
switch (ev)
|
||||
{
|
||||
case kEPERM: return "Permission denied";
|
||||
case kENOENT: return "No such file or directory";
|
||||
case kENORSRC: return "No such resource";
|
||||
case kEINTR: return "Interrupted system service";
|
||||
case kEIO: return "I/O error";
|
||||
case kENXIO: return "No such device or address";
|
||||
case kE2BIG: return "Argument list too long";
|
||||
case kENOEXEC: return "Exec format error";
|
||||
case kEBADF: return "Bad file number";
|
||||
case kECHILD: return "No children processes";
|
||||
case kEAGAIN: return "Resource temporarily unavailable, try again later";
|
||||
case kENOMEM: return "Not enough space";
|
||||
case kEACCES: return "Permission denied";
|
||||
case kEFAULT: return "Bad address";
|
||||
case kENOTBLK: return "Block device required";
|
||||
case kEBUSY: return "Device or resource busy";
|
||||
case kEEXIST: return "File exists";
|
||||
case kEXDEV: return "Cross-device link";
|
||||
case kENODEV: return "No such device";
|
||||
case kENOTDIR: return "Not a directory";
|
||||
case kEISDIR: return "Is a directory";
|
||||
case kEINVAL: return "Invalid argument";
|
||||
case kENFILE: return "File table overflow";
|
||||
case kEMFILE: return "Too many open files";
|
||||
case kENOTTY: return "Not a character device";
|
||||
case kETXTBSY: return "Text file busy";
|
||||
case kEFBIG: return "File too large";
|
||||
case kENOSPC: return "No space left on device";
|
||||
case kESPIPE: return "Illegal seek";
|
||||
case kEROFS: return "Read only file system";
|
||||
case kEMLINK: return "Too many links";
|
||||
case kEPIPE: return "Broken pipe";
|
||||
case kEDOM: return "Math arg out of domain of func";
|
||||
case kERANGE: return "Math result not representable";
|
||||
}
|
||||
|
||||
std::string tmp("Unknown error: ");
|
||||
tmp += std::to_string(ev);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
std::error_condition __system_category::default_error_condition(int ev) const noexcept
|
||||
{
|
||||
|
||||
int x = remap(static_cast<mpw_errno>(ev));
|
||||
if (x >= 0) return std::error_condition(x, std::generic_category());
|
||||
|
||||
return std::error_condition(ev, mpw_system_category());
|
||||
}
|
||||
|
||||
int __system_category::remap(mpw_errno e)
|
||||
{
|
||||
switch(e)
|
||||
{
|
||||
case kEPERM: return EPERM;
|
||||
case kENOENT: return ENOENT;
|
||||
#ifdef ENORSRC
|
||||
case kENORSRC: return ENORSRC;
|
||||
#endif
|
||||
case kEINTR: return EINTR;
|
||||
case kEIO: return EIO;
|
||||
case kENXIO: return ENXIO;
|
||||
case kE2BIG: return E2BIG;
|
||||
case kENOEXEC: return ENOEXEC;
|
||||
case kEBADF: return EBADF;
|
||||
case kECHILD: return ECHILD;
|
||||
case kEAGAIN: return EAGAIN;
|
||||
case kENOMEM: return ENOMEM;
|
||||
case kEACCES: return EACCES;
|
||||
case kEFAULT: return EFAULT;
|
||||
case kENOTBLK: return ENOTBLK;
|
||||
case kEBUSY: return EBUSY;
|
||||
case kEEXIST: return EEXIST;
|
||||
case kEXDEV: return EXDEV;
|
||||
case kENODEV: return ENODEV;
|
||||
case kENOTDIR: return ENOTDIR;
|
||||
case kEISDIR: return EISDIR;
|
||||
case kEINVAL: return EINVAL;
|
||||
case kENFILE: return ENFILE;
|
||||
case kEMFILE: return EMFILE;
|
||||
case kENOTTY: return ENOTTY;
|
||||
case kETXTBSY: return ETXTBSY;
|
||||
case kEFBIG: return EFBIG;
|
||||
case kENOSPC: return ENOSPC;
|
||||
case kESPIPE: return ESPIPE;
|
||||
case kEROFS: return EROFS;
|
||||
case kEMLINK: return EMLINK;
|
||||
case kEPIPE: return EPIPE;
|
||||
case kEDOM: return EDOM;
|
||||
case kERANGE: return ERANGE;
|
||||
|
||||
default: return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::error_category& mpw_system_category()
|
||||
{
|
||||
static __system_category s;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
mpw_errno mpw_errno_from_errno()
|
||||
{
|
||||
return mpw_errno_from_errno(errno);
|
||||
}
|
||||
|
||||
mpw_errno mpw_errno_from_errno(int error)
|
||||
{
|
||||
|
||||
switch(error)
|
||||
{
|
||||
case 0: return static_cast<mpw_errno>(0);
|
||||
|
||||
case EPERM: return kEPERM;
|
||||
case ENOENT: return kENOENT;
|
||||
|
||||
#ifdef ENORSRC
|
||||
case ENORSRC: return kENORSRC;
|
||||
#endif
|
||||
|
||||
case EINTR: return kEINTR;
|
||||
case EIO: return kEIO;
|
||||
case ENXIO: return kENXIO;
|
||||
case E2BIG: return kE2BIG;
|
||||
case ENOEXEC: return kENOEXEC;
|
||||
case EBADF: return kEBADF;
|
||||
case ECHILD: return kECHILD;
|
||||
case EAGAIN: return kEAGAIN;
|
||||
case ENOMEM: return kENOMEM;
|
||||
case EACCES: return kEACCES;
|
||||
case EFAULT: return kEFAULT;
|
||||
case ENOTBLK: return kENOTBLK;
|
||||
case EBUSY: return kEBUSY;
|
||||
case EEXIST: return kEEXIST;
|
||||
case EXDEV: return kEXDEV;
|
||||
case ENODEV: return kENODEV;
|
||||
case ENOTDIR: return kENOTDIR;
|
||||
case EISDIR: return kEISDIR;
|
||||
case EINVAL: return kEINVAL;
|
||||
case ENFILE: return kENFILE;
|
||||
case EMFILE: return kEMFILE;
|
||||
case ENOTTY: return kENOTTY;
|
||||
case ETXTBSY: return kETXTBSY;
|
||||
case EFBIG: return kEFBIG;
|
||||
case ENOSPC: return kENOSPC;
|
||||
case ESPIPE: return kESPIPE;
|
||||
case EROFS: return kEROFS;
|
||||
case EMLINK: return kEMLINK;
|
||||
case EPIPE: return kEPIPE;
|
||||
case EDOM: return kEDOM;
|
||||
case ERANGE: return kERANGE;
|
||||
|
||||
default:
|
||||
return kEINVAL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
#ifndef __mpw_errno_h__
|
||||
#define __mpw_errno_h__
|
||||
|
||||
#include <system_error>
|
||||
|
||||
namespace MPW {
|
||||
|
||||
// from MPW errno.h
|
||||
enum {
|
||||
enum mpw_errno {
|
||||
kEPERM = 1, /* Permission denied */
|
||||
kENOENT = 2, /* No such file or directory */
|
||||
kENORSRC = 3, /* No such resource */
|
||||
|
@ -41,6 +43,34 @@ namespace MPW {
|
|||
kERANGE = 34, /* Math result not representable */
|
||||
};
|
||||
|
||||
|
||||
mpw_errno mpw_errno_from_errno();
|
||||
mpw_errno mpw_errno_from_errno(int error);
|
||||
|
||||
// c++11 error stuff
|
||||
const std::error_category& mpw_system_category();
|
||||
|
||||
inline std::error_code make_error_code(mpw_errno e) noexcept
|
||||
{
|
||||
return std::error_code(static_cast<int>(e), mpw_system_category());
|
||||
}
|
||||
|
||||
inline std::error_condition make_error_condition(mpw_errno e) noexcept
|
||||
{
|
||||
return std::error_condition(static_cast<int>(e), mpw_system_category());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
namespace std {
|
||||
|
||||
template<>
|
||||
struct is_error_code_enum<MPW::mpw_errno> : public true_type {};
|
||||
|
||||
template<>
|
||||
struct is_error_condition_enum<MPW::mpw_errno> : public true_type {};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,14 +13,6 @@ namespace MPW
|
|||
if (Trace) fprintf(stderr, format, args...);
|
||||
}
|
||||
|
||||
/*
|
||||
namespace Internal
|
||||
{
|
||||
// for dup counts, etc.
|
||||
extern std::vector<int> FDTable;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpw.h"
|
||||
#include "mpw_internal.h"
|
||||
#include "mpw_errno.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
@ -11,7 +38,7 @@
|
|||
|
||||
#include <cpu/defs.h>
|
||||
#include <cpu/fmem.h>
|
||||
#include <cpu/cpuModule.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
|
||||
#include <macos/errors.h>
|
||||
|
||||
|
@ -47,7 +74,7 @@ namespace MPW
|
|||
int fd = f.cookie;
|
||||
ssize_t size;
|
||||
|
||||
Log(" read(%04x, %08x, %08x)", fd, f.buffer, f.count);
|
||||
Log(" read(%04x, %08x, %08x)\n", fd, f.buffer, f.count);
|
||||
size = OS::Internal::FDEntry::read(fd, memoryPointer(f.buffer), f.count);
|
||||
//Log(" -> %ld\n", size);
|
||||
|
||||
|
@ -55,7 +82,7 @@ namespace MPW
|
|||
{
|
||||
//f.count = 0;
|
||||
f.error = MacOS::ioErr; // ioErr
|
||||
d0 = errno_to_errno(errno);
|
||||
d0 = mpw_errno_from_errno();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -100,7 +127,7 @@ namespace MPW
|
|||
{
|
||||
//f.count = 0;
|
||||
f.error = MacOS::ioErr; // ioErr
|
||||
d0 = errno_to_errno(errno);
|
||||
d0 = mpw_errno_from_errno();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -111,8 +138,8 @@ namespace MPW
|
|||
// write back...
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
memoryWriteLong(f.count, parm + 12);
|
||||
|
||||
cpuSetDReg(0, d0);
|
||||
|
||||
cpuSetDReg(0, d0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Kelvin W Sherlock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpw.h"
|
||||
#include "mpw_internal.h"
|
||||
#include "mpw_errno.h"
|
||||
|
@ -18,17 +44,20 @@
|
|||
|
||||
#include <cpu/defs.h>
|
||||
#include <cpu/fmem.h>
|
||||
#include <cpu/cpuModule.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
|
||||
|
||||
#include <macos/errors.h>
|
||||
|
||||
#include <toolbox/os.h>
|
||||
#include <toolbox/os_internal.h>
|
||||
|
||||
|
||||
using MacOS::macos_error_from_errno;
|
||||
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
|
||||
|
||||
uint32_t ftrap_dup(uint32_t parm, uint32_t arg)
|
||||
{
|
||||
uint32_t d0;
|
||||
|
@ -67,7 +96,7 @@ namespace MPW
|
|||
{
|
||||
d0 = 0;
|
||||
fd.refcount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
|
@ -110,7 +139,7 @@ namespace MPW
|
|||
|
||||
uint32_t ftrap_interactive(uint32_t parm, uint32_t arg)
|
||||
{
|
||||
// return 0 if interactive, an error if
|
||||
// return 0 if interactive, an error if
|
||||
// non-interactive.
|
||||
|
||||
uint32_t d0;
|
||||
|
@ -124,8 +153,8 @@ namespace MPW
|
|||
f.count = memoryReadLong(parm + 12);
|
||||
f.buffer = memoryReadLong(parm + 16);
|
||||
|
||||
// linkgs reads from stdin and
|
||||
// doesn't work quite right when
|
||||
// linkgs reads from stdin and
|
||||
// doesn't work quite right when
|
||||
// this returns 0. So, don't.
|
||||
|
||||
f.error = 0;
|
||||
|
@ -154,7 +183,7 @@ namespace MPW
|
|||
{
|
||||
int tty = ::isatty(fd);
|
||||
d0 = tty ? 0 : kEINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
|
@ -223,7 +252,7 @@ namespace MPW
|
|||
return kEINVAL;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
#if 0
|
||||
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||
{
|
||||
|
@ -306,9 +335,9 @@ namespace MPW
|
|||
off_t rv = ::lseek(fd, offset, nativeWhence);
|
||||
if (rv < 0)
|
||||
{
|
||||
d0 = errno_to_errno(errno);
|
||||
f.error = 0;
|
||||
perror(NULL);
|
||||
d0 = mpw_errno_from_errno();
|
||||
f.error = macos_error_from_errno();
|
||||
//perror(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -322,6 +351,44 @@ namespace MPW
|
|||
}
|
||||
|
||||
|
||||
uint32_t ftrap_seteof(uint32_t parm, uint32_t arg)
|
||||
{
|
||||
|
||||
uint32_t d0;
|
||||
|
||||
MPWFile f;
|
||||
|
||||
f.flags = memoryReadWord(parm);
|
||||
f.error = memoryReadWord(parm + 2);
|
||||
f.device = memoryReadLong(parm + 4);
|
||||
f.cookie = memoryReadLong(parm + 8);
|
||||
f.count = memoryReadLong(parm + 12);
|
||||
f.buffer = memoryReadLong(parm + 16);
|
||||
|
||||
f.error = 0;
|
||||
|
||||
int fd = f.cookie;
|
||||
|
||||
Log(" seteof(%02x, %08x)\n", fd, arg);
|
||||
|
||||
d0 = OS::Internal::FDEntry::action(fd,
|
||||
[arg, &f](int fd, OS::Internal::FDEntry &e){
|
||||
int ok = ftruncate(fd, arg);
|
||||
if (ok == 0) return 0;
|
||||
f.error = macos_error_from_errno();
|
||||
return (int)mpw_errno_from_errno();
|
||||
},
|
||||
[](int fd){
|
||||
return kEINVAL;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
return d0;
|
||||
}
|
||||
|
||||
|
||||
void ftrap_ioctl(uint16_t trap)
|
||||
{
|
||||
// returns an mpw_errno in d0 [???]
|
||||
|
@ -363,7 +430,11 @@ namespace MPW
|
|||
break;
|
||||
|
||||
case kFIOSETEOF:
|
||||
fprintf(stderr, "ioctl - unsupported op %04x\n", cmd);
|
||||
d0 = ftrap_seteof(fd, arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "ioctl - unsupported op %04x\n", cmd);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
|
@ -372,4 +443,4 @@ namespace MPW
|
|||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
60
test/makefile
Normal file
60
test/makefile
Normal file
|
@ -0,0 +1,60 @@
|
|||
|
||||
# ignore built-in rules, don't delete intermediate .o files.
|
||||
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
.SUFFIXES:
|
||||
.SECONDARY:
|
||||
|
||||
MPWFLAGS = -DMPWVersion=3.2
|
||||
MPW ?= mpw
|
||||
|
||||
LIBS = \
|
||||
{Libraries}Stubs.o \
|
||||
{CLibraries}StdCLib.o \
|
||||
{Libraries}Interface.o \
|
||||
{Libraries}Runtime.o \
|
||||
{Libraries}ToolLibs.o
|
||||
|
||||
PPC_LIBS = {SharedLibraries}InterfaceLib \
|
||||
{SharedLibraries}StdCLib \
|
||||
{PPCLibraries}StdCRuntime.o \
|
||||
{PPCLibraries}PPCCRuntime.o
|
||||
|
||||
LDFLAGS = -w -c 'MPS ' -t MPST \
|
||||
-sn STDIO=Main -sn INTENV=Main -sn %A5Init=Main
|
||||
|
||||
SCFLAGS = -p
|
||||
|
||||
TARGETS = test_new_handle test_new_handle_2 test_new_pointer test_volumes \
|
||||
test_createresfile test_hwpriv test_sane
|
||||
|
||||
all : $(TARGETS)
|
||||
|
||||
clean :
|
||||
rm -f $(TARGETS) o/*
|
||||
|
||||
# test_new_handle : o/test_new_handle.o
|
||||
# mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
# test_new_handle_2 : o/test_new_handle_2.o
|
||||
# mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
# test_new_pointer : o/test_new_pointer.o
|
||||
# mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
# test_volumes : o/test_volumes.o
|
||||
# mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
test_sane: o/nan.o o/test_sane.o
|
||||
$(MPW) $(MPWFLAGS) Link $(LDFLAGS) -o $@ $^ $(LIBS) {CLibraries}CSANELib.o
|
||||
|
||||
% : o/%.o
|
||||
$(MPW) $(MPWFLAGS) Link $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
o/%.o : %.c
|
||||
$(MPW) $(MPWFLAGS) SC $(SCFLAGS) $< -o $@
|
||||
|
||||
o/%.o : %.asm
|
||||
$(MPW) $(MPWFLAGS) Asm $(ASMFLAGS) $< -o $@
|
||||
|
||||
|
35
test/nan.asm
Normal file
35
test/nan.asm
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
case on
|
||||
|
||||
export nan, __inf, inf
|
||||
|
||||
nan proc
|
||||
; The MPW 3.2 version of nan is broken. This what it's supposed to do.
|
||||
; extended (80-bit) returns via d0, d1, a0
|
||||
|
||||
MOVEM.L data,D0/D1/A0
|
||||
MOVE.W #$4000,D1
|
||||
MOVE.B $0004(A7),D1
|
||||
BNE.S swap
|
||||
MOVE.B #$15,D1
|
||||
swap
|
||||
SWAP D1
|
||||
RTS
|
||||
|
||||
entry inf
|
||||
entry __inf
|
||||
|
||||
inf
|
||||
__inf
|
||||
|
||||
MOVEM.L data,D0/D1/A0
|
||||
RTS
|
||||
|
||||
data
|
||||
dc.l $00007fff
|
||||
dc.l $00000000
|
||||
dc.l $00000000
|
||||
|
||||
end
|
||||
endp
|
||||
|
132
test/test_createresfile.c
Normal file
132
test/test_createresfile.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
#include <Resources.h>
|
||||
#include <Files.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/*
|
||||
* Test the three (thanks, Apple) ways to create a resource file.
|
||||
*
|
||||
*/
|
||||
|
||||
ConstStr255Param fname = (ConstStr255Param)"\pxxx-test-resource-xxx";
|
||||
|
||||
|
||||
void test_fspcreateresfile(void)
|
||||
{
|
||||
OSErr err;
|
||||
FSSpec spec;
|
||||
|
||||
err = FSMakeFSSpec(0, 0, fname, &spec);
|
||||
if (err) {
|
||||
|
||||
fprintf(stderr, "FSMakeFSSpec failed: %d\n", err);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
FSpDelete(&spec);
|
||||
FSpCreateResFile(&spec, 'TEST', 'BINA', 0);
|
||||
if ( (err = ResError()) != 0) {
|
||||
fprintf(stderr, "FSpCreateResFile failed (File does not exist): %d\n", err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Verify it doesn't fail if the file/fork already exist.
|
||||
FSpCreateResFile(&spec, 'TEST', 'BINA', 0);
|
||||
if ( (err = ResError()) != 0) {
|
||||
fprintf(stderr, "FSpCreateResFile (File/Fork exist) failed: %d\n", err);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
// Verify it doesn't fail if the file exists w/o a resource fork.
|
||||
FSpDelete(&spec);
|
||||
FSpCreate(&spec, 'TEST', 'BINA', 0);
|
||||
FSpCreateResFile(&spec, 'TEST', 'BINA', 0);
|
||||
if ( (err = ResError()) != 0) {
|
||||
fprintf(stderr, "FSpCreateResFile (File exists) failed: %d\n", err);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
FSpDelete(&spec);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void test_hcreateresfile(void)
|
||||
{
|
||||
OSErr err;
|
||||
|
||||
// will 0, 0 work on real macos?
|
||||
|
||||
HDelete(0, 0, fname);
|
||||
HCreateResFile(0, 0, fname);
|
||||
if ( (err = ResError()) != 0) {
|
||||
fprintf(stderr, "HCreateResFile failed (File does not exist): %d\n", err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Verify it doesn't fail if the file/fork already exist.
|
||||
HCreateResFile(0, 0, fname);
|
||||
if ( (err = ResError()) != 0) {
|
||||
fprintf(stderr, "HCreateResFile (File/Fork exist) failed: %d\n", err);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
// Verify it doesn't fail if the file exists w/o a resource fork.
|
||||
HDelete(0, 0, fname);
|
||||
HCreate(0, 0, fname, 'TEST', 'BINA');
|
||||
HCreateResFile(0, 0, fname);
|
||||
if ( (err = ResError()) != 0) {
|
||||
fprintf(stderr, "HCreateResFile (File exists) failed: %d\n", err);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
HDelete(0, 0, fname);
|
||||
}
|
||||
|
||||
void test_createresfile(void)
|
||||
{
|
||||
OSErr err;
|
||||
|
||||
FSDelete(fname, 0);
|
||||
CreateResFile(fname);
|
||||
if ( (err = ResError()) != 0) {
|
||||
fprintf(stderr, "CreateResFile failed (File does not exist): %d\n", err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Verify it does fail if the file/fork already exist.
|
||||
CreateResFile(fname);
|
||||
if ( (err = ResError()) != dupFNErr) {
|
||||
fprintf(stderr, "CreateResFile (File/Fork exist) failed: %d\n", err);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
// Verify it doesn't fail if the file exists w/o a resource fork.
|
||||
FSDelete(fname, 0);
|
||||
Create(fname, 0, 'TEST', 'BINA');
|
||||
CreateResFile(fname);
|
||||
if ( (err = ResError()) != 0) {
|
||||
fprintf(stderr, "CreateResFile (File exists) failed: %d\n", err);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
FSDelete(fname, 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
|
||||
test_createresfile();
|
||||
test_hcreateresfile();
|
||||
test_fspcreateresfile();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
30
test/test_hwpriv.c
Normal file
30
test/test_hwpriv.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include <OSUtils.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
// these are all nops in mpw. Just verify it doesn't crash.
|
||||
|
||||
SwapInstructionCache(1);
|
||||
SwapInstructionCache(0);
|
||||
|
||||
FlushInstructionCache();
|
||||
|
||||
|
||||
SwapDataCache(1);
|
||||
SwapDataCache(0);
|
||||
|
||||
FlushDataCache();
|
||||
FlushCodeCache();
|
||||
|
||||
FlushCodeCacheRange(&main, 4);
|
||||
|
||||
// ? selector 6? listed in OSUtils.a, not listed in pascal or c headers.
|
||||
//FlushExternalCache();
|
||||
|
||||
return 0;
|
||||
}
|
30
test/test_new_handle.c
Normal file
30
test/test_new_handle.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include <MacMemory.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void test_new_handle(unsigned size)
|
||||
{
|
||||
unsigned long total = 0;
|
||||
unsigned long count = 0;
|
||||
|
||||
for(;;) {
|
||||
|
||||
Handle h = NewHandle(size);
|
||||
if (!h) {
|
||||
fprintf(stdout, "memory error: %d\n", MemError());
|
||||
break;
|
||||
}
|
||||
|
||||
total += size;
|
||||
count++;
|
||||
}
|
||||
|
||||
fprintf(stdout, "%ld handles allocated\n", count);
|
||||
fprintf(stdout, "%ld bytes allocated\n", total);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_new_handle(1024 * 1024);
|
||||
return 0;
|
||||
}
|
110
test/test_new_handle_2.c
Normal file
110
test/test_new_handle_2.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
#include <MacMemory.h>
|
||||
#include <stdio.h>
|
||||
|
||||
enum {
|
||||
TimeLM = 0x020C
|
||||
};
|
||||
|
||||
/* arc4random */
|
||||
|
||||
struct {
|
||||
unsigned char i;
|
||||
unsigned char j;
|
||||
unsigned char s[256];
|
||||
} rs;
|
||||
|
||||
void arc4_init(void)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
rs.s[n] = n;
|
||||
|
||||
rs.i = 0;
|
||||
rs.j = 0;
|
||||
}
|
||||
|
||||
void arc4_addrandom(const unsigned char *dat, int datlen)
|
||||
{
|
||||
int n;
|
||||
unsigned char si;
|
||||
|
||||
rs.i--;
|
||||
for (n = 0; n < 256; n++) {
|
||||
rs.i = (rs.i + 1);
|
||||
si = rs.s[rs.i];
|
||||
rs.j = (rs.j + si + dat[n % datlen]);
|
||||
rs.s[rs.i] = rs.s[rs.j];
|
||||
rs.s[rs.j] = si;
|
||||
}
|
||||
rs.j = rs.i;
|
||||
}
|
||||
|
||||
|
||||
unsigned char arc4_getbyte(void)
|
||||
{
|
||||
unsigned char si, sj;
|
||||
|
||||
rs.i = (rs.i + 1);
|
||||
si = rs.s[rs.i];
|
||||
rs.j = (rs.j + si);
|
||||
sj = rs.s[rs.j];
|
||||
rs.s[rs.i] = sj;
|
||||
rs.s[rs.j] = si;
|
||||
return (rs.s[(si + sj) & 0xff]);
|
||||
}
|
||||
|
||||
unsigned long arc4_get24(void)
|
||||
{
|
||||
unsigned long val;
|
||||
|
||||
val |= arc4_getbyte() << 16;
|
||||
val |= arc4_getbyte() << 8;
|
||||
val |= arc4_getbyte();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void test(void)
|
||||
{
|
||||
|
||||
unsigned i,j;
|
||||
unsigned errors = 0;
|
||||
unsigned success = 0;
|
||||
|
||||
for (i = 0; i < 10000; ++i)
|
||||
{
|
||||
Handle h[5];
|
||||
for (j = 0; j < 5; ++j) {
|
||||
unsigned long size = arc4_get24() >> 3;
|
||||
Handle hh = NewHandle(size);
|
||||
|
||||
if (hh) {
|
||||
success++;
|
||||
} else {
|
||||
fprintf(stdout, "NewHandle failed (%u): %d\n", size, MemError());
|
||||
errors++;
|
||||
}
|
||||
|
||||
h[j] = hh;
|
||||
}
|
||||
|
||||
for (j = 0; j < 5; ++j) {
|
||||
DisposeHandle(h[j]);
|
||||
}
|
||||
|
||||
}
|
||||
fprintf(stdout, "NewHandle failed: %u\n", errors);
|
||||
fprintf(stdout, "NewHandle succeeded: %u\n", success);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
// init with the time.
|
||||
arc4_init();
|
||||
arc4_addrandom((const unsigned char *)TimeLM, 4);
|
||||
|
||||
test();
|
||||
return 0;
|
||||
}
|
31
test/test_new_pointer.c
Normal file
31
test/test_new_pointer.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include <MacMemory.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void test_new_pointer(unsigned size)
|
||||
{
|
||||
unsigned long total = 0;
|
||||
unsigned long count = 0;
|
||||
|
||||
for(;;) {
|
||||
|
||||
void *p = NewPtr(size);
|
||||
if (!p) {
|
||||
fprintf(stdout, "memory error: %d\n", MemError());
|
||||
break;
|
||||
}
|
||||
|
||||
total += size;
|
||||
count++;
|
||||
}
|
||||
|
||||
fprintf(stdout, "%ld pointers allocated\n", count);
|
||||
fprintf(stdout, "%ld bytes allocated\n", total);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_new_pointer(1024 * 1024);
|
||||
return 0;
|
||||
}
|
380
test/test_sane.c
Normal file
380
test/test_sane.c
Normal file
|
@ -0,0 +1,380 @@
|
|||
#include <Math.h>
|
||||
#include <SANE.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
//extern pascal extended NAN(short x);
|
||||
|
||||
void dump_decimal(const decimal *d)
|
||||
{
|
||||
fprintf(stdout, "%d : %d : %.*s\n",
|
||||
d->sgn, d->exp, d->sig.length, d->sig.text);
|
||||
}
|
||||
|
||||
|
||||
void test_inf(void)
|
||||
{
|
||||
|
||||
decimal d;
|
||||
decform df;
|
||||
char buffer[80+1];
|
||||
|
||||
printf("\nInfinity\n");
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 10;
|
||||
num2dec(&df,-inf(), &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
dec2str(&df, &d, buffer);
|
||||
fprintf(stdout, "%s\n", buffer);
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 10;
|
||||
num2dec(&df, -inf(), &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
dec2str(&df, &d, buffer);
|
||||
fprintf(stdout, "%s\n", buffer);
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 0;
|
||||
num2dec(&df, inf(), &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
dec2str(&df, &d, buffer);
|
||||
fprintf(stdout, "%s\n", buffer);
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 0;
|
||||
num2dec(&df, inf(), &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
dec2str(&df, &d, buffer);
|
||||
fprintf(stdout, "%s\n", buffer);
|
||||
|
||||
}
|
||||
|
||||
void test_nan(void)
|
||||
{
|
||||
|
||||
|
||||
// num2dec generates N[16-digit]
|
||||
// str2dec generates NAN(001) -- NAN(255)
|
||||
|
||||
decimal d;
|
||||
decform df;
|
||||
char buffer[80+1];
|
||||
|
||||
printf("\nNaN\n");
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 0;
|
||||
num2dec(&df,nan(1), &d);
|
||||
dump_decimal(&d);
|
||||
// 7 : N4001000000000000
|
||||
dec2str(&df, &d, buffer);
|
||||
fprintf(stdout, "%s\n", buffer);
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 0;
|
||||
num2dec(&df, nan(2), &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
dec2str(&df, &d, buffer);
|
||||
fprintf(stdout, "%s\n", buffer);
|
||||
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 10;
|
||||
num2dec(&df,-nan(3), &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
dec2str(&df, &d, buffer);
|
||||
fprintf(stdout, "%s\n", buffer);
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 10;
|
||||
num2dec(&df, nan(4), &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
dec2str(&df, &d, buffer);
|
||||
fprintf(stdout, "%s\n", buffer);
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 10;
|
||||
num2dec(&df, nan(255), &d);
|
||||
dump_decimal(&d);
|
||||
// 7 : N40FF000000000000
|
||||
|
||||
dec2str(&df, &d, buffer);
|
||||
fprintf(stdout, "%s\n", buffer);
|
||||
}
|
||||
|
||||
void test_fxc2dec(void)
|
||||
{
|
||||
decimal d;
|
||||
decform df;
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 100;
|
||||
num2dec(&df, 1.125, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : -18 : 1125000000000000000
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 10;
|
||||
num2dec(&df, 1.125, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : -9 : 1125000000
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 2;
|
||||
num2dec(&df, 1.125, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : -1 : 11
|
||||
|
||||
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 100;
|
||||
num2dec(&df, 1.125, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : -18 : 1125000000000000000
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 10;
|
||||
num2dec(&df, 1.125, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : -10 : 11250000000
|
||||
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 2;
|
||||
num2dec(&df, 1.125, &d);
|
||||
dump_decimal(&d);
|
||||
//0 : -2 : 112
|
||||
|
||||
//
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 100;
|
||||
num2dec(&df, 1e25, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : 7 : 1000000000000000000
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 10;
|
||||
num2dec(&df, 1e25, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : 16 : 1000000000
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 2;
|
||||
num2dec(&df, 1e25, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : 24 : 10
|
||||
|
||||
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 100;
|
||||
num2dec(&df, 1e25, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : 7 : 1000000000000000000
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 10;
|
||||
num2dec(&df, 1e25, &d);
|
||||
dump_decimal(&d);
|
||||
// 0 : 7 : 1000000000000000000
|
||||
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 2;
|
||||
num2dec(&df, 1e25, &d);
|
||||
dump_decimal(&d);
|
||||
//0 : 7 : 1000000000000000000
|
||||
|
||||
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 10;
|
||||
num2dec(&df, 0, &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 10;
|
||||
num2dec(&df, 0, &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 0;
|
||||
num2dec(&df, -0.0, &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 0;
|
||||
num2dec(&df, -0.0, &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 10;
|
||||
num2dec(&df, 0.125, &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 10;
|
||||
num2dec(&df, 0.125, &d);
|
||||
dump_decimal(&d);
|
||||
//
|
||||
|
||||
df.style = 0;
|
||||
df.digits = 4;
|
||||
num2dec(&df, 0.00000125, &d);
|
||||
dump_decimal(&d);
|
||||
// s/b -9 1250
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 4;
|
||||
num2dec(&df, 0.00000125, &d);
|
||||
dump_decimal(&d);
|
||||
// s/b -4 0
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 6;
|
||||
num2dec(&df, 0.0625, &d);
|
||||
dump_decimal(&d);
|
||||
// s/b -6 62500
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 6;
|
||||
num2dec(&df, 1.125, &d);
|
||||
dump_decimal(&d);
|
||||
// s/b -6 1125000
|
||||
|
||||
df.style = 1;
|
||||
df.digits = 6;
|
||||
num2dec(&df, 1.0625, &d);
|
||||
dump_decimal(&d);
|
||||
// s/b -6 1062500
|
||||
}
|
||||
|
||||
pascal void fp68k_3(void *, void *, unsigned short) = 0xA9EB;
|
||||
|
||||
void test_fx2l(void) {
|
||||
|
||||
long double x;
|
||||
long int l;
|
||||
int i;
|
||||
|
||||
static long double data[] = {
|
||||
1.25,
|
||||
1.5,
|
||||
1.75,
|
||||
2.25,
|
||||
2.5,
|
||||
2.75,
|
||||
-1.25,
|
||||
-1.5,
|
||||
-1.75,
|
||||
-2.25,
|
||||
-2.5,
|
||||
-2.75,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
x = inf(); // 1.0 / 0.0;
|
||||
fp68k_3(&x, &l, 0x2810);
|
||||
printf("fx2l(inf) = %lx\n", l);
|
||||
|
||||
|
||||
x = -inf(); // -1.0 / 0.0;
|
||||
fp68k_3(&x, &l, 0x2810);
|
||||
printf("fx2l(-inf) = %lx\n", l);
|
||||
|
||||
x = nan(1); // -1.0 / 0.0;
|
||||
fp68k_3(&x, &l, 0x2810);
|
||||
printf("fx2l(nan) = %lx\n", l);
|
||||
|
||||
|
||||
x = 1e21;
|
||||
fp68k_3(&x, &l, 0x2810);
|
||||
printf("fx2l(1e21) = %lx\n", l);
|
||||
|
||||
x = -1e21;
|
||||
fp68k_3(&x, &l, 0x2810);
|
||||
printf("fx2l(-1e21) = %lx\n", l);
|
||||
|
||||
|
||||
|
||||
setround(UPWARD);
|
||||
for (i = 0; i < 12; ++i) {
|
||||
x = data[i];
|
||||
fp68k_3(&x, &l, 0x2810);
|
||||
printf("fx2l(%f) = %ld\n", x, l);
|
||||
}
|
||||
setround(DOWNWARD);
|
||||
for (i = 0; i < 12; ++i) {
|
||||
x = data[i];
|
||||
fp68k_3(&x, &l, 0x2810);
|
||||
printf("fx2l(%f) = %ld\n", x, l);
|
||||
}
|
||||
|
||||
setround(TONEAREST);
|
||||
for (i = 0; i < 12; ++i) {
|
||||
x = data[i];
|
||||
fp68k_3(&x, &l, 0x2810);
|
||||
printf("fx2l(%f) = %ld\n", x, l);
|
||||
}
|
||||
setround(TOWARDZERO);
|
||||
for (i = 0; i < 12; ++i) {
|
||||
x = data[i];
|
||||
fp68k_3(&x, &l, 0x2810);
|
||||
printf("fx2l(%f) = %ld\n", x, l);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
//extended x;
|
||||
//decimal d;
|
||||
|
||||
//short index;
|
||||
//short valid;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
//index = 0;
|
||||
//valid = 0;
|
||||
//str2dec("1.125", &index, &d, &valid);
|
||||
//x = dec2num(&d);
|
||||
|
||||
|
||||
test_inf();
|
||||
test_nan();
|
||||
|
||||
test_fxc2dec();
|
||||
test_fx2l();
|
||||
|
||||
return 0;
|
||||
}
|
56
test/test_volumes.c
Normal file
56
test/test_volumes.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include <Files.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
*
|
||||
* MacOS/Basilisk:
|
||||
*
|
||||
* GetVol(): vRefNum = -32637
|
||||
* GetVol(MacOS): vRefNum = -32637
|
||||
* HGetVol(): vRefNum = -32637 dirID = 3382
|
||||
* HGetVol(MacOS): vRefNum = -32637 dirID = 3382
|
||||
*
|
||||
*/
|
||||
|
||||
void gv(StringPtr name)
|
||||
{
|
||||
OSErr err;
|
||||
short vRefNum;
|
||||
err = GetVol(name, &vRefNum);
|
||||
|
||||
if (err) fprintf(stdout, "GetVol(%s): Error = %d\n", name ? name + 1 : (StringPtr)"", err);
|
||||
else fprintf(stdout, "GetVol(%s): vRefNum = %d\n", name ? name + 1 : (StringPtr)"", vRefNum);
|
||||
}
|
||||
|
||||
|
||||
void hgv(StringPtr name)
|
||||
{
|
||||
OSErr err;
|
||||
short vRefNum;
|
||||
long dirID;
|
||||
|
||||
err = HGetVol(name, &vRefNum, &dirID);
|
||||
|
||||
if (err) fprintf(stdout, "HGetVol(%s): Error = %d\n", name ? name + 1 : (StringPtr)"", err);
|
||||
else fprintf(stdout, "HGetVol(%s): vRefNum = %d dirID = %d\n",
|
||||
name ? name + 1 : (StringPtr)"", vRefNum, dirID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
gv(NULL);
|
||||
gv((StringPtr)"\pMacOS");
|
||||
|
||||
|
||||
hgv(NULL);
|
||||
hgv((StringPtr)"\pMacOS");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,24 +1,52 @@
|
|||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -Wno-deprecated-declarations -g")
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
# Clang or AppleClang
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
|
||||
endif()
|
||||
|
||||
add_definitions(-I ${CMAKE_SOURCE_DIR}/)
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
set(TOOLBOX_SRC
|
||||
toolbox.cpp
|
||||
rm.cpp
|
||||
mm.cpp
|
||||
loader.cpp
|
||||
rm.cpp
|
||||
os.cpp
|
||||
os_internal.cpp
|
||||
os_hfs_dispatch.cpp
|
||||
os_highlevel.cpp
|
||||
os_alias.cpp
|
||||
os_fileinfo.cpp
|
||||
os_gestalt.cpp
|
||||
os_hfs_dispatch.cpp
|
||||
os_highlevel.cpp
|
||||
os_hwpriv.cpp
|
||||
os_internal.cpp
|
||||
os_volume.cpp
|
||||
qd.cpp
|
||||
sane.cpp
|
||||
packages.cpp
|
||||
pathnames.cpp
|
||||
process.cpp
|
||||
utility.cpp
|
||||
fs_spec.cpp
|
||||
realpath.c
|
||||
dispatch.cpp
|
||||
fpinfo.cpp
|
||||
debug.cpp
|
||||
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT pathnames.cpp
|
||||
COMMAND "${RAGEL}" -p -G2 -o pathnames.cpp "${CMAKE_CURRENT_SOURCE_DIR}/pathnames.rl"
|
||||
MAIN_DEPENDENCY pathnames.rl
|
||||
)
|
||||
|
||||
set_source_files_properties(
|
||||
pathnames.cpp
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -Wno-unused-variable"
|
||||
)
|
||||
|
||||
|
||||
|
||||
add_library(TOOLBOX_LIB ${TOOLBOX_SRC})
|
||||
add_library(TOOLBOX_LIB ${TOOLBOX_SRC})
|
||||
target_link_libraries(TOOLBOX_LIB MACOS_LIB sane)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user