mirror of
https://github.com/ksherlock/mpw.git
synced 2024-06-06 19:29:45 +00:00
Compare commits
541 Commits
pre_cleanu
...
master
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 | ||
|
4abfcc2e52 | ||
|
1828c9e5f2 | ||
|
1e27acd16a | ||
|
66ac4363cf | ||
|
d0715138f9 | ||
|
73e37d205e | ||
|
2eb632892c | ||
|
f50c1dca32 | ||
|
71a81ffacb | ||
|
159198adcb | ||
|
9584a6ee88 | ||
|
3ad993ab3f | ||
|
044efc7169 | ||
|
386dc18ad1 | ||
|
722aa2e18a | ||
|
be3c728185 | ||
|
bc8885c2ab | ||
|
caa0b8b74f | ||
|
2fb4e67323 | ||
|
c6e4867c25 | ||
|
40d3f9a69b | ||
|
5293a49d7f | ||
|
0d6874ae08 | ||
|
7536e05a6c | ||
|
20a1e81d60 | ||
|
6952c106b6 | ||
|
e920ee230e | ||
|
e1a3269cea | ||
|
6d76fae173 | ||
|
80e55b8c82 | ||
|
288aa35cc1 | ||
|
af3af77433 | ||
|
cbbab65d2c | ||
|
05baff21ad | ||
|
231e34627d | ||
|
6f93bd0826 | ||
|
3f5efae581 | ||
|
84598e0ac7 | ||
|
828dc94c90 | ||
|
b8a17eb0f1 | ||
|
2b66aeae0e | ||
|
18fa1a760a | ||
|
a95efd9e3f | ||
|
240ac7b898 | ||
|
09b0eb102f | ||
|
af98ca4bfd | ||
|
dd14402c2e | ||
|
33899e5495 | ||
|
57f46bc374 | ||
|
44f1c5a048 | ||
|
cab4ae2b65 | ||
|
906d07759d | ||
|
31b41bf174 | ||
|
aa73cc55cb | ||
|
77feba11f5 | ||
|
fea833311a | ||
|
184ecf2922 | ||
|
0fa19adbc5 | ||
|
07e4e3686e | ||
|
ee44e1ce42 | ||
|
372fab3dc5 | ||
|
9b1afa3d00 | ||
|
a8bd0248da | ||
|
db9fa7aa23 | ||
|
68852c9d16 | ||
|
ceeabfb1b0 | ||
|
1871f85e7b | ||
|
673fc4f492 | ||
|
adba68c724 | ||
|
7578fbce73 | ||
|
233c625cb0 | ||
|
9c951a221c | ||
|
e84aff6812 | ||
|
ddf73f04ee | ||
|
dbe264d591 | ||
|
8cdede6104 | ||
|
df66ea44b3 | ||
|
6bc34f2085 | ||
|
55a255f44f | ||
|
528e19b1d9 | ||
|
b5be3a4924 | ||
|
a9553a11b5 | ||
|
95f41785eb | ||
|
e4dff8bc81 | ||
|
d59222d02f | ||
|
c206573a17 | ||
|
82d760ebf1 | ||
|
9e6176001a | ||
|
1aa5c048ad | ||
|
feed83ebf0 | ||
|
c5f07d4706 | ||
|
6ae8b870a0 | ||
|
8235193554 | ||
|
5c00dc1ca5 | ||
|
675170ae72 | ||
|
d8bbaf2265 | ||
|
4136209d84 | ||
|
e3a3c4a933 | ||
|
bba0679650 | ||
|
e56a311c2e | ||
|
a497d5ec85 | ||
|
9ed82d7639 | ||
|
bf47a41ecc | ||
|
0d165d9525 | ||
|
486bc5001b | ||
|
ab63801242 | ||
|
4e247a0c46 | ||
|
3300006953 | ||
|
fa03797e98 | ||
|
3a24ce64b6 | ||
|
c67dad27e4 | ||
|
24611657a8 | ||
|
27168ed419 | ||
|
3fc0839807 | ||
|
276b0c18eb | ||
|
1cbccbc30f | ||
|
c2f23c8f5e | ||
|
9564f13d85 | ||
|
4917ca2acc | ||
|
2059327323 | ||
|
add2d6b5a3 | ||
|
f7800ece1e | ||
|
a737da619d | ||
|
1bb0369223 | ||
|
4f4fde9cfb | ||
|
53c42e1ee2 |
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,13 +1,38 @@
|
|||
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)
|
||||
add_subdirectory(toolbox)
|
||||
add_subdirectory(mplite)
|
||||
add_subdirectory(mpw)
|
||||
add_subdirectory(macos)
|
||||
|
||||
add_subdirectory(libsane)
|
||||
|
|
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.
|
||||
|
94
TODO.txt
94
TODO.txt
|
@ -1,18 +1,98 @@
|
|||
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:
|
||||
- move trace-cpu code into a logger callback
|
||||
- add support for tool traps
|
||||
- add support for global vars [?]
|
||||
- improve MOVEM disassembly [?]
|
||||
|
||||
---
|
||||
|
||||
- check for stack range errors
|
||||
- add memory manager code
|
||||
- add stand-alone disasm utility
|
||||
- log memory access to global vars
|
||||
- --24 flag for non-32-bit clean code
|
||||
|
||||
- since code segments are loaded from a resource and the code may try to reload itself (ResourceByName), it really needs to be done via the emulated ResourceMgr/Memory Manager.
|
||||
|
||||
- ftrap_editor_tabs
|
||||
|
||||
|
||||
- move time to OS::, add OS::Init to set start time global / ticks
|
||||
- use alarm / ualarm to update ticks/ time global?
|
||||
|
||||
- duplicate / duplicate iigs replacement
|
||||
|
||||
- stdout -- convert macroman to utf8 on output?
|
||||
|
||||
|
||||
|
||||
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.
|
||||
- GetFileInfo -- create fake finderinfo record from extension.
|
||||
- check for stack range errors
|
||||
- add memory manager code
|
||||
- add stand-alone disasm utility
|
||||
- log memory access to global vars
|
||||
- --trace-cpu: add support for tool traps
|
||||
- --trace-cpu: move trace-cpu code into a logger callback
|
||||
|
||||
- ftrap_delete
|
||||
- if file doesn't exist, check in $MPW/Tools/
|
||||
|
||||
- include file w/ all global names
|
||||
- include file w/ all os errors
|
|
@ -1,17 +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 traps.c)
|
||||
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 traps.c)
|
||||
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
|
135
bin/disasm.cpp
135
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)
|
||||
{
|
||||
|
||||
|
@ -95,7 +164,7 @@ void disasm(const char *name, int segment, uint32_t data_size)
|
|||
|
||||
uint16_t op = memoryReadWord(pc);
|
||||
|
||||
if (prevOP == 0x4E75 || prevOP == 0x4ED0)
|
||||
if (prevOP == 0x4E75 || prevOP == 0x4ED0 || prevOP == 0x4E74)
|
||||
{
|
||||
if (op > 0x8000)
|
||||
{
|
||||
|
@ -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
|
930
bin/loader.cpp
930
bin/loader.cpp
File diff suppressed because it is too large
Load Diff
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.
|
||||
|
||||
#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
150
cpu/fmem.h
150
cpu/fmem.h
|
@ -1,39 +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 void memoryWriteByte(UBY data, ULO address);
|
||||
extern void memoryWriteWord(UWO data, ULO address);
|
||||
extern void memoryWriteLong(ULO 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];
|
||||
|
@ -41,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 */
|
||||
|
@ -74,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];
|
||||
|
@ -88,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,
|
||||
|
@ -97,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 */
|
||||
|
||||
|
@ -146,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
|
||||
|
|
113
cpu/memory.c
113
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,48 +88,55 @@ 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 + 1 < MemorySize)
|
||||
return (Memory[address++] << 24)
|
||||
| (Memory[address++] << 16)
|
||||
| (Memory[address++] << 8)
|
||||
| (Memory[address++] << 0);
|
||||
if (address + 3 < MemorySize)
|
||||
return (Memory[address + 0] << 24)
|
||||
| (Memory[address + 1] << 16)
|
||||
| (Memory[address + 2] << 8)
|
||||
| (Memory[address + 3] << 0);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
void memoryWriteByte(UBY data, ULO address)
|
||||
|
||||
|
||||
uint64_t memoryReadLongLong(uint32_t address)
|
||||
{
|
||||
if (address < MemoryGlobalLog)
|
||||
{
|
||||
fprintf(stderr, "memoryWriteByte(%02x, %08x)\n", data, address);
|
||||
}
|
||||
uint64_t tmp;
|
||||
|
||||
tmp = memoryReadLong(address);
|
||||
tmp <<= 32;
|
||||
tmp |= memoryReadLong(address + 4);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void memoryWriteByte(uint8_t data, uint32_t address)
|
||||
{
|
||||
|
||||
if (MemoryLoggingFunc)
|
||||
MemoryLoggingFunc(address, 1, 1, data);
|
||||
|
||||
if (address < MemorySize)
|
||||
{
|
||||
|
@ -130,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);
|
||||
|
||||
|
@ -147,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);
|
||||
|
@ -168,3 +178,22 @@ void memoryWriteLong(ULO data, ULO address)
|
|||
}
|
||||
|
||||
|
||||
void memoryWriteLongLong(uint64_t data, uint32_t address)
|
||||
{
|
||||
|
||||
if (address & 0x01) memoryOddWrite(address);
|
||||
|
||||
if (address + 7 < MemorySize)
|
||||
{
|
||||
Memory[address++] = data >> 56;
|
||||
Memory[address++] = data >> 48;
|
||||
Memory[address++] = data >> 40;
|
||||
Memory[address++] = data >> 32;
|
||||
Memory[address++] = data >> 24;
|
||||
Memory[address++] = data >> 16;
|
||||
Memory[address++] = data >> 8;
|
||||
Memory[address++] = data >> 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
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
|
3
macos/CMakeLists.txt
Normal file
3
macos/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
609
macos/errors.h
Normal file
609
macos/errors.h
Normal file
|
@ -0,0 +1,609 @@
|
|||
/************************************************************
|
||||
|
||||
Created: Thursday, March 14, 1991 at 3:53 PM
|
||||
Errors.h
|
||||
C Interface to the Macintosh Libraries
|
||||
|
||||
|
||||
Copyright Apple Computer, Inc. 1985-1990
|
||||
All rights reserved
|
||||
|
||||
************************************************************/
|
||||
|
||||
|
||||
#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 macos_error {
|
||||
noErr = 0,
|
||||
paramErr = -50, /*error in user parameter list*/
|
||||
noHardwareErr = -200, /*Sound Manager Error Returns*/
|
||||
notEnoughHardwareErr = -201, /*Sound Manager Error Returns*/
|
||||
userCanceledErr = -128,
|
||||
qErr = -1, /*queue element not found during deletion*/
|
||||
vTypErr = -2, /*invalid queue element*/
|
||||
corErr = -3, /*core routine number out of range*/
|
||||
unimpErr = -4, /*unimplemented core routine*/
|
||||
SlpTypeErr = -5, /*invalid queue element*/
|
||||
seNoDB = -8, /*no debugger installed to handle debugger command*/
|
||||
controlErr = -17, /*I/O System Errors*/
|
||||
statusErr = -18, /*I/O System Errors*/
|
||||
readErr = -19, /*I/O System Errors*/
|
||||
writErr = -20, /*I/O System Errors*/
|
||||
badUnitErr = -21, /*I/O System Errors*/
|
||||
unitEmptyErr = -22, /*I/O System Errors*/
|
||||
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 */
|
||||
|
||||
|
||||
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*/
|
||||
unitTblFullErr = -29, /*unit table has no more entries*/
|
||||
dceExtErr = -30, /*dce extension error*/
|
||||
slotNumErr = -360, /*invalid slot # error*/
|
||||
gcrOnMFMErr = -400, /*gcr format on high density media error*/
|
||||
dirFulErr = -33, /*Directory full*/
|
||||
dskFulErr = -34, /*disk full*/
|
||||
nsvErr = -35, /*no such volume*/
|
||||
ioErr = -36, /*I/O error (bummers)*/
|
||||
bdNamErr = -37, /*there may be no bad names in the final system!*/
|
||||
fnOpnErr = -38, /*File not open*/
|
||||
eofErr = -39, /*End of file*/
|
||||
posErr = -40, /*tried to position to before start of file (r/w)*/
|
||||
mFulErr = -41, /*memory full (open) or file won't fit (load)*/
|
||||
tmfoErr = -42, /*too many files open*/
|
||||
fnfErr = -43, /*File not found*/
|
||||
wPrErr = -44, /*diskette is write protected.*/
|
||||
fLckdErr = -45, /*file is locked*/
|
||||
|
||||
|
||||
vLckdErr = -46, /*volume is locked*/
|
||||
fBsyErr = -47, /*File is busy (delete)*/
|
||||
dupFNErr = -48, /*duplicate filename (rename)*/
|
||||
opWrErr = -49, /*file already open with with write permission*/
|
||||
rfNumErr = -51, /*refnum error*/
|
||||
gfpErr = -52, /*get file position error*/
|
||||
volOffLinErr = -53, /*volume not on line error (was Ejected)*/
|
||||
permErr = -54, /*permissions error (on file open)*/
|
||||
volOnLinErr = -55, /*drive volume already on-line at MountVol*/
|
||||
nsDrvErr = -56, /*no such drive (tried to mount a bad drive num)*/
|
||||
noMacDskErr = -57, /*not a mac diskette (sig bytes are wrong)*/
|
||||
extFSErr = -58, /*volume in question belongs to an external fs*/
|
||||
fsRnErr = -59, /*file system internal error:during rename the old entry was deleted but could not be restored.*/
|
||||
badMDBErr = -60, /*bad master directory block*/
|
||||
wrPermErr = -61, /*write permissions error*/
|
||||
dirNFErr = -120, /*Directory not found*/
|
||||
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.*/
|
||||
|
||||
|
||||
fidNotFound = -1300, /*no file thread exists.*/
|
||||
fidExists = -1301, /*file id already exists*/
|
||||
notAFileErr = -1302, /*directory specified*/
|
||||
diffVolErr = -1303, /*files on different volumes*/
|
||||
catChangedErr = -1304, /*the catalog has been modified*/
|
||||
desktopDamagedErr = -1305, /*desktop database files are corrupted*/
|
||||
sameFileErr = -1306, /*can't exchange a file with itself*/
|
||||
badFidErr = -1307, /*file id is dangling or doesn't match with the file number*/
|
||||
envNotPresent = -5500, /*returned by glue.*/
|
||||
envBadVers = -5501, /*Version non-positive*/
|
||||
envVersTooBig = -5502, /*Version bigger than call can handle*/
|
||||
fontDecError = -64, /*error during font declaration*/
|
||||
fontNotDeclared = -65, /*font not declared*/
|
||||
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*/
|
||||
|
||||
|
||||
noAdrMkErr = -67, /*couldn't find valid addr mark*/
|
||||
dataVerErr = -68, /*read verify compare failed*/
|
||||
badCksmErr = -69, /*addr mark checksum didn't check*/
|
||||
badBtSlpErr = -70, /*bad addr mark bit slip nibbles*/
|
||||
noDtaMkErr = -71, /*couldn't find a data mark header*/
|
||||
badDCksum = -72, /*bad data mark checksum*/
|
||||
badDBtSlp = -73, /*bad data mark bit slip nibbles*/
|
||||
wrUnderrun = -74, /*write underrun occurred*/
|
||||
cantStepErr = -75, /*step handshake failed*/
|
||||
tk0BadErr = -76, /*track 0 detect doesn't change*/
|
||||
initIWMErr = -77, /*unable to initialize IWM*/
|
||||
twoSideErr = -78, /*tried to read 2nd side on a 1-sided drive*/
|
||||
spdAdjErr = -79, /*unable to correctly adjust disk speed*/
|
||||
seekErr = -80, /*track number wrong on address mark*/
|
||||
sectNFErr = -81, /*sector number never found on a track*/
|
||||
fmt1Err = -82, /*can't find sector 0 after track format*/
|
||||
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*/
|
||||
|
||||
|
||||
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)*/
|
||||
breakRecd = -90, /*Break received (SCC)*/
|
||||
|
||||
/*Power Manager Errors*/
|
||||
pmBusyErr = -13000, /*Power Mgr never ready to start handshake*/
|
||||
pmReplyTOErr = -13001, /*Timed out waiting for reply*/
|
||||
pmSendStartErr = -13002, /*during send, pmgr did not start hs*/
|
||||
pmSendEndErr = -13003, /*during send, pmgr did not finish hs*/
|
||||
pmRecvStartErr = -13004, /*during receive, pmgr did not start hs*/
|
||||
pmRecvEndErr = -13005, /*during receive, pmgr did not finish hs configured for this connection*/
|
||||
|
||||
/*Scrap Manager errors*/
|
||||
noScrapErr = -100, /*No scrap exists error*/
|
||||
noTypeErr = -102, /*No object of that type in scrap*/
|
||||
memROZWarn = -99, /*soft error in ROZ*/
|
||||
memROZError = -99, /*hard error in ROZ*/
|
||||
memROZErr = -99, /*hard error in ROZ*/
|
||||
memFullErr = -108, /*Not enough room in heap zone*/
|
||||
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*/
|
||||
|
||||
|
||||
memAZErr = -113, /*Address in zone check failed*/
|
||||
memPCErr = -114, /*Pointer Check failed*/
|
||||
memBCErr = -115, /*Block Check failed*/
|
||||
memSCErr = -116, /*Size Check failed*/
|
||||
memLockedErr = -117, /*trying to move a locked block (MoveHHi)*/
|
||||
resNotFound = -192, /*Resource not found*/
|
||||
resFNotFound = -193, /*Resource file not found*/
|
||||
addResFailed = -194, /*AddResource failed*/
|
||||
addRefFailed = -195, /*AddReference failed*/
|
||||
rmvResFailed = -196, /*RmveResource failed*/
|
||||
rmvRefFailed = -197, /*RmveReference failed*/
|
||||
resAttrErr = -198, /*attribute inconsistent with operation*/
|
||||
mapReadErr = -199, /*map inconsistent with operation*/
|
||||
CantDecompress = -186, /*resource bent ("the bends") - can't decompress a compressed resource*/
|
||||
badExtResource = -185, /*extended resource has a bad format.*/
|
||||
evtNotEnb = 1, /*event not enabled at PostEvent*/
|
||||
noMemForPictPlaybackErr = -145,
|
||||
rgnTooBigError = -147,
|
||||
pixMapTooDeepErr = -148,
|
||||
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*/
|
||||
cRangeErr = -153, /*range error on colorTable request*/
|
||||
cProtectErr = -154, /*colorTable entry protection violation*/
|
||||
cDevErr = -155, /*invalid type of graphics device*/
|
||||
cResErr = -156, /*invalid resolution for MakeITable*/
|
||||
rgnTooBigErr = -500,
|
||||
updPixMemErr = -125, /*insufficient memory to update a pixmap*/
|
||||
pictInfoVersionErr = -11000, /* wrong version of the PictInfo structure */
|
||||
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 */
|
||||
pictureDataErr = -11005, /* the picture data was invalid */
|
||||
|
||||
/*Sound Manager errors*/
|
||||
noHardware = noHardwareErr, /* *** obsolete spelling */
|
||||
notEnoughHardware = notEnoughHardwareErr, /* *** obsolete spelling */
|
||||
queueFull = -203, /*Sound Manager Error Returns*/
|
||||
resProblem = -204, /*Sound Manager Error Returns*/
|
||||
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 */
|
||||
channelBusy = -209, /* the Channel is being used for a PFD already */
|
||||
buffersTooSmall = -210, /* can not operate in the memory allowed */
|
||||
channelNotBusy = -211,
|
||||
noMoreRealTime = -212, /* not enough CPU cycles left to add another task */
|
||||
siNoSoundInHardware = -220, /*no Sound Input hardware*/
|
||||
siBadSoundInDevice = -221, /*invalid index passed to SoundInGetIndexedDevice*/
|
||||
siNoBufferSpecified = -222, /*returned by synchronous SPBRecord if nil buffer passed*/
|
||||
siInvalidCompression = -223, /*invalid compression type*/
|
||||
siHardDriveTooSlow = -224, /*hard drive too slow to record to disk*/
|
||||
siInvalidSampleRate = -225, /*invalid sample rate*/
|
||||
siInvalidSampleSize = -226, /*invalid sample size*/
|
||||
siDeviceBusyErr = -227, /*input device already in use*/
|
||||
siBadDeviceName = -228, /*input device could not be opened*/
|
||||
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)*/
|
||||
|
||||
|
||||
/*Notification Manager errors*/
|
||||
nmTypErr = -299, /*wrong queue type*/
|
||||
siInitSDTblErr = 1, /*slot int dispatch table could not be initialized.*/
|
||||
siInitVBLQsErr = 2, /*VBLqueues for all slots could not be initialized.*/
|
||||
siInitSPTblErr = 3, /*slot priority table could not be initialized.*/
|
||||
sdmJTInitErr = 10, /*SDM Jump Table could not be initialized.*/
|
||||
sdmInitErr = 11, /*SDM could not be initialized.*/
|
||||
sdmSRTInitErr = 12, /*Slot Resource Table could not be initialized.*/
|
||||
sdmPRAMInitErr = 13, /*Slot PRAM could not be initialized.*/
|
||||
sdmPriInitErr = 14, /*Cards could not be initialized.*/
|
||||
smSDMInitErr = -290, /*Error; SDM could not be initialized.*/
|
||||
smSRTInitErr = -291, /*Error; Slot Resource Table could not be initialized.*/
|
||||
smPRAMInitErr = -292, /*Error; Slot Resource Table could not be initialized.*/
|
||||
smPriInitErr = -293, /*Error; Cards could not be initialized.*/
|
||||
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 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.*/
|
||||
|
||||
|
||||
smResrvErr = -307, /*Fatal reserved error. Resreved field <> 0.*/
|
||||
smUnExBusErr = -308, /*Unexpected BusError*/
|
||||
smBLFieldBad = -309, /*ByteLanes field was bad.*/
|
||||
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 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 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.*/
|
||||
|
||||
/* The following errors are for primary or secondary init code. The errors are logged in the
|
||||
vendor status field of the sInfo record. Normally the vendor error is not Apple's concern,
|
||||
but a special error is needed to patch secondary inits.*/
|
||||
|
||||
|
||||
svTempDisable = -32768, /*Temporarily disable card but run primary init.*/
|
||||
svDisabled = -32640, /*Reserve range -32640 to -32768 for Apple temp disables.*/
|
||||
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*/
|
||||
|
||||
|
||||
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 (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 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 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*/
|
||||
|
||||
|
||||
notRegisteredSectionErr = -452, /*not a registered SectionRecord*/
|
||||
badEditionFileErr = -453, /*edition file is corrupt*/
|
||||
badSubPartErr = -454, /*can not use sub parts in this release*/
|
||||
multiplePublisherWrn = -460, /*A Publisher is already registered for that container*/
|
||||
containerNotFoundWrn = -461, /*could not find editionContainer at this time*/
|
||||
containerAlreadyOpenWrn = -462, /*container already opened by this section*/
|
||||
notThePublisherWrn = -463, /*not the first registered publisher for that container*/
|
||||
teScrapSizeErr = -501, /*scrap item too big for text edit record*/
|
||||
hwParamErr = -502, /*bad selector for _HWPriv*/
|
||||
|
||||
/* Process Manager errors */
|
||||
procNotFound = -600, /* no eligible process with specified descriptor */
|
||||
memFragErr = -601, /* not enough room to launch app w/special requirements */
|
||||
appModeErr = -602, /* memory mode is 32-bit, but app not 32-bit clean */
|
||||
protocolErr = -603, /* app made module calls in improper order */
|
||||
hardwareConfigErr = -604, /* hardware configuration not correct for call */
|
||||
appMemFullErr = -605, /* application SIZE not big enough for launch */
|
||||
appIsDaemon = -606, /* app is BG-only, and launch flags disallow this */
|
||||
|
||||
/*MemoryDispatch errors*/
|
||||
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*/
|
||||
|
||||
|
||||
interruptsMaskedErr = -624, /*don't call with interrupts masked*/
|
||||
cannotDeferErr = -625, /*unable to defer additional functions*/
|
||||
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*/
|
||||
excessCollsns = -95, /*excessive collisions on write*/
|
||||
portInUse = -97, /*driver Open error code (port is in use)*/
|
||||
portNotCf = -98, /*driver Open error code (parameter RAM not configured for this connection)*/
|
||||
nbpBuffOvr = -1024, /*Buffer overflow in LookupName*/
|
||||
nbpNoConfirm = -1025,
|
||||
nbpConfDiff = -1026, /*Name confirmed at different socket*/
|
||||
nbpDuplicate = -1027, /*Duplicate name exists already*/
|
||||
nbpNotFound = -1028, /*Name not found on remove*/
|
||||
nbpNISErr = -1029, /*Error trying to open the NIS*/
|
||||
aspBadVersNum = -1066, /*Server cannot support this ASP version*/
|
||||
aspBufTooSmall = -1067, /*Buffer too small*/
|
||||
aspNoMoreSess = -1068, /*No more sessions on server*/
|
||||
aspNoServers = -1069, /*No servers at that address*/
|
||||
aspParamErr = -1070, /*Parameter error*/
|
||||
|
||||
|
||||
aspServerBusy = -1071, /*Server cannot open another session*/
|
||||
aspSessClosed = -1072, /*Session closed*/
|
||||
aspSizeErr = -1073, /*Command block too big*/
|
||||
aspTooMany = -1074, /*Too many clients (server error)*/
|
||||
aspNoAck = -1075, /*No ack on attention request (server err)*/
|
||||
reqFailed = -1096,
|
||||
tooManyReqs = -1097,
|
||||
tooManySkts = -1098,
|
||||
badATPSkt = -1099,
|
||||
badBuffNum = -1100,
|
||||
noRelErr = -1101,
|
||||
cbNotFound = -1102,
|
||||
noSendResp = -1103,
|
||||
noDataArea = -1104,
|
||||
reqAborted = -1105,
|
||||
buf2SmallErr = -3101,
|
||||
noMPPErr = -3102,
|
||||
ckSumErr = -3103,
|
||||
extractErr = -3104,
|
||||
readQErr = -3105,
|
||||
|
||||
|
||||
atpLenErr = -3106,
|
||||
atpBadRsp = -3107,
|
||||
recNotFnd = -3108,
|
||||
sktClosedErr = -3109,
|
||||
afpAccessDenied = -5000,
|
||||
afpAuthContinue = -5001,
|
||||
afpBadUAM = -5002,
|
||||
afpBadVersNum = -5003,
|
||||
afpBitmapErr = -5004,
|
||||
afpCantMove = -5005,
|
||||
afpDenyConflict = -5006,
|
||||
afpDirNotEmpty = -5007,
|
||||
afpDiskFull = -5008,
|
||||
afpEofError = -5009,
|
||||
afpFileBusy = -5010,
|
||||
afpFlatVol = -5011,
|
||||
afpItemNotFound = -5012,
|
||||
afpLockErr = -5013,
|
||||
afpMiscErr = -5014,
|
||||
afpNoMoreLocks = -5015,
|
||||
|
||||
|
||||
afpNoServer = -5016,
|
||||
afpObjectExists = -5017,
|
||||
afpObjectNotFound = -5018,
|
||||
afpParmErr = -5019,
|
||||
afpRangeNotLocked = -5020,
|
||||
afpRangeOverlap = -5021,
|
||||
afpSessClosed = -5022,
|
||||
afpUserNotAuth = -5023,
|
||||
afpCallNotSupported = -5024,
|
||||
afpObjectTypeErr = -5025,
|
||||
afpTooManyFilesOpen = -5026,
|
||||
afpServerGoingDown = -5027,
|
||||
afpCantRename = -5028,
|
||||
afpDirNotFound = -5029,
|
||||
afpIconTypeError = -5030,
|
||||
afpVolLocked = -5031, /*Volume is Read-Only*/
|
||||
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*/
|
||||
|
||||
|
||||
afpDiffVolErr = -5036, /*$FFFFEC54*/
|
||||
afpCatalogChanged = -5037, /*$FFFFEC53*/
|
||||
afpSameObjectErr = -5038, /*$FFFFEC52*/
|
||||
afpBadIDErr = -5039, /*$FFFFEC51*/
|
||||
afpPwdSameErr = -5040, /*$FFFFEC50 someone tried to change their password to the same password on a mantadory password change */
|
||||
afpPwdTooShortErr = -5041, /*$FFFFEC4F the password being set is too short: there is a minimum length that must be met or exceeded */
|
||||
afpPwdExpiredErr = -5042, /*$FFFFEC4E the password being used is too old: this requires the user to change the password before log-in can continue */
|
||||
afpInsideSharedErr = -5043, /*$FFFFEC4D the folder being shared is inside a shared folder OR the folder contains a shared folder and is being moved into a shared folder OR the folder contains a shared folder and is being moved into the descendent of a shared folder. */
|
||||
afpInsideTrashErr = -5044, /*$FFFFEC4C the folder being shared is inside the trash folder OR the shared folder is being moved into the trash folder OR the folder is being moved to the trash and it contains a shared folder */
|
||||
|
||||
/*PPC errors*/
|
||||
notInitErr = -900, /* PPCToolBox not initialized */
|
||||
nameTypeErr = -902, /* Invalid or inappropriate locationKindSelector in locationName */
|
||||
noPortErr = -903, /* Unable to open port or bad portRefNum */
|
||||
noGlobalsErr = -904, /* The system is hosed, better re-boot */
|
||||
localOnlyErr = -905, /* Network activity is currently disabled */
|
||||
destPortErr = -906, /* Port does not exist at destination */
|
||||
sessTableErr = -907, /* Out of session tables, try again later */
|
||||
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 */
|
||||
|
||||
|
||||
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 */
|
||||
noResponseErr = -915, /* unable to contact destination */
|
||||
portClosedErr = -916, /* port was closed */
|
||||
sessClosedErr = -917, /* session was closed */
|
||||
badPortNameErr = -919, /* PPCPortRec malformed */
|
||||
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 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 */
|
||||
badServiceMethodErr = -930, /* illegal service type, or not supported */
|
||||
badLocNameErr = -931, /* location name malformed */
|
||||
guestNotAllowedErr = -932, /* destination port requires authentication */
|
||||
swOverrunErr = 1, /*serial driver error masks*/
|
||||
parityErr = 16, /*serial driver error masks*/
|
||||
hwOverrunErr = 32, /*serial driver error masks*/
|
||||
|
||||
|
||||
framingErr = 64, /*serial driver error masks*/
|
||||
dsBusError = 1, /*bus error */
|
||||
dsAddressErr = 2, /*address error*/
|
||||
dsIllInstErr = 3, /*illegal instruction error*/
|
||||
dsZeroDivErr = 4, /*zero divide error*/
|
||||
dsChkErr = 5, /*check trap error*/
|
||||
dsOvflowErr = 6, /*overflow trap error*/
|
||||
dsPrivErr = 7, /*privilege violation error*/
|
||||
dsTraceErr = 8, /*trace mode error*/
|
||||
dsLineAErr = 9, /*line 1010 trap error*/
|
||||
dsLineFErr = 10, /*line 1111 trap error*/
|
||||
dsMiscErr = 11, /*miscellaneous hardware exception error*/
|
||||
dsCoreErr = 12, /*unimplemented core routine error*/
|
||||
dsIrqErr = 13, /*uninstalled interrupt error*/
|
||||
dsIOCoreErr = 14, /*IO Core Error*/
|
||||
dsLoadErr = 15, /*Segment Loader Error*/
|
||||
dsFPErr = 16, /*Floating point error*/
|
||||
dsNoPackErr = 17, /*package 0 not present*/
|
||||
dsNoPk1 = 18, /*package 1 not present*/
|
||||
dsNoPk2 = 19, /*package 2 not present*/
|
||||
|
||||
|
||||
dsNoPk3 = 20, /*package 3 not present*/
|
||||
dsNoPk4 = 21, /*package 4 not present*/
|
||||
dsNoPk5 = 22, /*package 5 not present*/
|
||||
dsNoPk6 = 23, /*package 6 not present*/
|
||||
dsNoPk7 = 24, /*package 7 not present*/
|
||||
dsMemFullErr = 25, /*out of memory!*/
|
||||
dsBadLaunch = 26, /*can't launch file*/
|
||||
dsFSErr = 27, /*file system map has been trashed*/
|
||||
dsStknHeap = 28, /*stack has moved into application heap*/
|
||||
negZcbFreeErr = 33, /*ZcbFree has gone negative*/
|
||||
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*/
|
||||
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*/
|
||||
|
||||
|
||||
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*/
|
||||
dsOldSystem = 102, /*System is too old for this ROM*/
|
||||
ds32BitMode = 103, /*booting in 32-bit on a 24-bit sys*/
|
||||
dsNeedToWriteBootBlocks = 104, /*need to write new boot blocks*/
|
||||
dsNotEnoughRAMToBoot = 105, /*must have at least 1.5MB of RAM to boot 7.0*/
|
||||
dsBufPtrTooLow = 106, /*bufPtr moved too far during boot*/
|
||||
dsReinsert = 30, /*request user to reinsert off-line volume*/
|
||||
shutDownAlert = 42, /*handled like a shutdown error*/
|
||||
dsShutDownOrRestart = 20000, /*user choice between ShutDown and Restart*/
|
||||
dsSwitchOffOrRestart = 20001, /*user choice between switching off and Restart*/
|
||||
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"*/
|
||||
dsGreeting = 40, /*welcome to Macintosh greeting*/
|
||||
dsSysErr = 32767, /*general system error*/
|
||||
|
||||
/*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"*/
|
||||
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*/
|
||||
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
|
296
macos/sysequ.c
Normal file
296
macos/sysequ.c
Normal file
|
@ -0,0 +1,296 @@
|
|||
|
||||
#include <stddef.h> // null
|
||||
#include <stdint.h>
|
||||
|
||||
const char *GlobalName(uint32_t address)
|
||||
{
|
||||
switch(address)
|
||||
{
|
||||
case 0x0008: return "BusErrVct";
|
||||
case 0x0100: return "MonkeyLives";
|
||||
case 0x0102: return "ScrVRes";
|
||||
case 0x0104: return "ScrHRes";
|
||||
case 0x0106: return "ScreenRow";
|
||||
case 0x0108: return "MemTop";
|
||||
case 0x010C: return "BufPtr";
|
||||
case 0x0110: return "StkLowPt";
|
||||
case 0x0114: return "HeapEnd";
|
||||
case 0x0118: return "TheZone";
|
||||
case 0x011C: return "UTableBase";
|
||||
case 0x012C: return "DskVerify";
|
||||
case 0x012D: return "LoadTrap";
|
||||
case 0x012E: return "MmInOK";
|
||||
case 0x012F: return "CPUFlag";
|
||||
case 0x0130: return "ApplLimit";
|
||||
case 0x0142: return "DskErr";
|
||||
case 0x0144: return "SysEvtMask";
|
||||
case 0x0146: return "SysEvtBuf";
|
||||
case 0x014A: return "EventQueue";
|
||||
case 0x0154: return "EvtBufCnt";
|
||||
case 0x0156: return "RndSeed";
|
||||
case 0x015A: return "SysVersion";
|
||||
case 0x015C: return "SEvtEnb";
|
||||
case 0x015D: return "DSWndUpdate";
|
||||
case 0x015F: return "IntFlag";
|
||||
case 0x0160: return "VBLQueue";
|
||||
case 0x016A: return "Ticks";
|
||||
case 0x016E: return "MBTicks";
|
||||
case 0x0172: return "MBState";
|
||||
case 0x0174: return "KeyMapLM";
|
||||
case 0x017C: return "KeypadMap";
|
||||
case 0x0184: return "KeyLast";
|
||||
case 0x0186: return "KeyTime";
|
||||
case 0x018A: return "KeyRepTime";
|
||||
case 0x018E: return "KeyThresh";
|
||||
case 0x0190: return "KeyRepThresh";
|
||||
case 0x0192: return "Lvl1DT";
|
||||
case 0x01B2: return "Lvl2DT";
|
||||
case 0x01D2: return "UnitNtryCnt";
|
||||
case 0x01D4: return "VIA";
|
||||
case 0x01D8: return "SCCRd";
|
||||
case 0x01DC: return "SCCWr";
|
||||
case 0x01E0: return "IWM";
|
||||
case 0x01E4: return "GetParam";
|
||||
//case 0x01E4: return "Scratch20";
|
||||
//case 0x01F8: return "SPValid";
|
||||
case 0x01F8: return "SysParam";
|
||||
case 0x01F9: return "SPATalkA";
|
||||
case 0x01FA: return "SPATalkB";
|
||||
case 0x01FB: return "SPConfig";
|
||||
case 0x01FC: return "SPPortA";
|
||||
case 0x01FE: return "SPPortB";
|
||||
case 0x0200: return "SPAlarm";
|
||||
case 0x0204: return "SPFont";
|
||||
case 0x0206: return "SPKbd";
|
||||
case 0x0207: return "SPPrint";
|
||||
case 0x0208: return "SPVolCtl";
|
||||
case 0x0209: return "SPClikCaret";
|
||||
case 0x020A: return "SPMisc1";
|
||||
case 0x020B: return "PCDeskPat";
|
||||
//case 0x020B: return "SPMisc2";
|
||||
case 0x020C: return "TimeLM";
|
||||
case 0x0210: return "BootDrive";
|
||||
case 0x0214: return "SFSaveDisk";
|
||||
case 0x0216: return "HiKeyLast";
|
||||
//case 0x0216: return "KbdVars";
|
||||
case 0x0218: return "KbdLast";
|
||||
case 0x021A: return "JKybdTask";
|
||||
case 0x021E: return "KbdType";
|
||||
case 0x021F: return "AlarmState";
|
||||
case 0x0220: return "MemErr";
|
||||
case 0x0260: return "SdVolume";
|
||||
case 0x0262: return "SoundPtr";
|
||||
case 0x0266: return "SoundBase";
|
||||
case 0x026A: return "SoundVBL";
|
||||
case 0x027A: return "SoundDCE";
|
||||
case 0x027E: return "SoundActive";
|
||||
case 0x027F: return "SoundLevel";
|
||||
case 0x0280: return "CurPitch";
|
||||
case 0x0286: return "SwitcherTPtr";
|
||||
case 0x028E: return "ROM85";
|
||||
case 0x0290: return "PortAUse";
|
||||
case 0x0291: return "PortBUse";
|
||||
case 0x029A: return "JGNEFilter";
|
||||
case 0x029E: return "Key1Trans";
|
||||
case 0x02A2: return "Key2Trans";
|
||||
case 0x02A6: return "SysZone";
|
||||
case 0x02AA: return "ApplZone";
|
||||
case 0x02AE: return "ROMBase";
|
||||
case 0x02B2: return "RAMBase";
|
||||
case 0x02B6: return "ExpandMem";
|
||||
case 0x02BA: return "DSAlertTab";
|
||||
case 0x02BE: return "ExtStsDT";
|
||||
case 0x02CE: return "SCCASts";
|
||||
case 0x02CF: return "SCCBSts";
|
||||
case 0x02D0: return "SerialVars";
|
||||
case 0x02D8: return "ABusVars";
|
||||
case 0x02DC: return "ABusDCE";
|
||||
case 0x02F0: return "DoubleTime";
|
||||
case 0x02F4: return "CaretTime";
|
||||
case 0x02F8: return "ScrDmpEnb";
|
||||
case 0x02F9: return "ScrDmpType";
|
||||
case 0x02FA: return "TagData";
|
||||
case 0x02FC: return "BufTgFNum";
|
||||
case 0x0300: return "BufTgFFlg";
|
||||
case 0x0302: return "BufTgFBkNum";
|
||||
case 0x0304: return "BufTgDate";
|
||||
case 0x0308: return "DrvQHdr";
|
||||
case 0x0312: return "PWMBuf2";
|
||||
case 0x0316: return "HpChk";
|
||||
case 0x031A: return "Lo3Bytes";
|
||||
//case 0x031A: return "MaskBC";
|
||||
//case 0x031A: return "MaskHandle";
|
||||
//case 0x031A: return "MaskPtr";
|
||||
case 0x031E: return "MinStack";
|
||||
case 0x0322: return "DefltStack";
|
||||
case 0x0326: return "MMDefFlags";
|
||||
case 0x0328: return "GZRootHnd";
|
||||
case 0x032C: return "GZRootPtr";
|
||||
case 0x0330: return "GZMoveHnd";
|
||||
case 0x0334: return "DSDrawProc";
|
||||
case 0x0338: return "EjectNotify";
|
||||
case 0x033C: return "IAZNotify";
|
||||
case 0x0398: return "CurDirStore";
|
||||
case 0x03F8: return "DSAlertRect";
|
||||
case 0x0824: return "ScrnBase";
|
||||
case 0x0828: return "MTemp";
|
||||
case 0x082C: return "RawMouse";
|
||||
case 0x0830: return "Mouse";
|
||||
case 0x0834: return "CrsrPin";
|
||||
case 0x083C: return "CrsrRect";
|
||||
case 0x0844: return "TheCrsr";
|
||||
case 0x0888: return "CrsrAddr";
|
||||
case 0x088C: return "CrsrSave";
|
||||
//case 0x088C: return "JAllocCrsr";
|
||||
//case 0x088C: return "NewCrsrJTbl";
|
||||
case 0x0890: return "JSetCCrsr";
|
||||
case 0x0894: return "JOpcodeProc";
|
||||
case 0x0898: return "CrsrBase";
|
||||
case 0x089C: return "CrsrDevice";
|
||||
case 0x08A0: return "SrcDevice";
|
||||
case 0x08A4: return "MainDevice";
|
||||
case 0x08A8: return "DeviceList";
|
||||
case 0x08AC: return "CrsrRow";
|
||||
case 0x08B0: return "QDColors";
|
||||
case 0x08CC: return "CrsrVis";
|
||||
case 0x08CD: return "CrsrBusy";
|
||||
case 0x08CE: return "CrsrNew";
|
||||
case 0x08CF: return "CrsrCouple";
|
||||
case 0x08D0: return "CrsrState";
|
||||
case 0x08D2: return "CrsrObscure";
|
||||
case 0x08D3: return "CrsrScale";
|
||||
case 0x08D6: return "MouseMask";
|
||||
case 0x08DA: return "MouseOffset";
|
||||
case 0x08DE: return "JournalFlag";
|
||||
case 0x08E8: return "JournalRef";
|
||||
case 0x08EC: return "CrsrThresh";
|
||||
case 0x08EE: return "JCrsrTask";
|
||||
case 0x08F2: return "WWExist";
|
||||
case 0x08F3: return "QDExist";
|
||||
case 0x08F4: return "JFetch";
|
||||
case 0x08F8: return "JStash";
|
||||
case 0x08FC: return "JIODone";
|
||||
case 0x0900: return "CurApRefNum";
|
||||
case 0x0902: return "LaunchFlag";
|
||||
case 0x0904: return "CurrentA5";
|
||||
case 0x0908: return "CurStackBase";
|
||||
case 0x0910: return "CurApName";
|
||||
case 0x0930: return "SaveSegHandle";
|
||||
case 0x0934: return "CurJTOffset";
|
||||
case 0x0936: return "CurPageOption";
|
||||
case 0x0938: return "HiliteMode";
|
||||
case 0x093A: return "LoaderPBlock";
|
||||
//case 0x0960: return "ScrapInfo";
|
||||
//case 0x0960: return "ScrapSize";
|
||||
case 0x0960: return "ScrapVars";
|
||||
case 0x0964: return "ScrapHandle";
|
||||
case 0x0968: return "ScrapCount";
|
||||
case 0x096A: return "ScrapState";
|
||||
case 0x096C: return "ScrapName";
|
||||
case 0x0970: return "ScrapTag";
|
||||
case 0x0980: return "ScrapEnd";
|
||||
case 0x09D6: return "WindowList";
|
||||
case 0x09DC: return "PaintWhite";
|
||||
case 0x09DE: return "WMgrPort";
|
||||
case 0x09EE: return "GrayRgn";
|
||||
case 0x09F6: return "DragHook";
|
||||
case 0x09FA: return "Scratch8";
|
||||
case 0x0A02: return "OneOne";
|
||||
case 0x0A06: return "MinusOne";
|
||||
case 0x0A3C: return "DeskPattern";
|
||||
case 0x0A50: return "TopMapHndl";
|
||||
case 0x0A54: return "SysMapHndl";
|
||||
case 0x0A58: return "SysMap";
|
||||
case 0x0A5A: return "CurMap";
|
||||
case 0x0A5C: return "ResReadOnly";
|
||||
case 0x0A5E: return "ResLoad";
|
||||
case 0x0A60: return "ResErr";
|
||||
case 0x0A64: return "CurActivate";
|
||||
case 0x0A68: return "CurDeactive";
|
||||
case 0x0A6C: return "DeskHook";
|
||||
case 0x0A70: return "TEDoText";
|
||||
case 0x0A74: return "TERecal";
|
||||
case 0x0A84: return "GhostWindow";
|
||||
//case 0x0A8C: return "RestProc";
|
||||
case 0x0A8C: return "ResumeProc";
|
||||
case 0x0AB0: return "TEScrpLength";
|
||||
case 0x0AB4: return "TEScrpHandle";
|
||||
case 0x0AD8: return "SysResName";
|
||||
case 0x0AF0: return "DSErrCode";
|
||||
case 0x0AF2: return "ResErrProc";
|
||||
case 0x0AF6: return "TEWdBreak";
|
||||
case 0x0B04: return "KeyMVars";
|
||||
case 0x0B06: return "ROMMapHndl";
|
||||
case 0x0B9E: return "RomMapInsert";
|
||||
case 0x0B9F: return "TmpResLoad";
|
||||
case 0x0BA0: return "IntlSpec";
|
||||
case 0x0BA5: return "WordRedraw";
|
||||
case 0x0BAA: return "MBarHeight";
|
||||
case 0x0BAC: return "TESysJust";
|
||||
case 0x0BAE: return "HiHeapMark";
|
||||
case 0x0BB2: return "SegHiEnable";
|
||||
case 0x0BB4: return "CommToolboxGlobals";
|
||||
case 0x0C00: return "SCSIBase";
|
||||
case 0x0C04: return "SCSIDMA";
|
||||
case 0x0C08: return "SCSIHsk";
|
||||
case 0x0C0C: return "SCSIGlobals";
|
||||
case 0x0C10: return "RGBBlack";
|
||||
case 0x0C16: return "RGBWhite";
|
||||
case 0x0C20: return "RowBits";
|
||||
case 0x0C22: return "ColLines";
|
||||
case 0x0C24: return "ScreenBytes";
|
||||
case 0x0C2C: return "NMIFlag";
|
||||
case 0x0C2D: return "VidType";
|
||||
case 0x0C2E: return "VidMode";
|
||||
case 0x0C2F: return "SCSIPoll";
|
||||
case 0x0C30: return "SEVarBase";
|
||||
case 0x0CB0: return "MMUFlags";
|
||||
case 0x0CB1: return "MMUType";
|
||||
case 0x0CB2: return "MMU32bit";
|
||||
case 0x0CB3: return "MMUFluff";
|
||||
case 0x0CB4: return "MMUTbl";
|
||||
case 0x0CB8: return "MMUTblSize";
|
||||
case 0x0CBC: return "SInfoPtr";
|
||||
case 0x0CC0: return "ASCBase";
|
||||
case 0x0CC4: return "SMGlobals";
|
||||
case 0x0CC8: return "TheGDevice";
|
||||
case 0x0CCC: return "CQDGlobals";
|
||||
case 0x0CF8: return "ADBBase";
|
||||
case 0x0CFC: return "WarmStart";
|
||||
case 0x0D00: return "TimeDBRA";
|
||||
case 0x0D02: return "TimeSCCDB";
|
||||
case 0x0D04: return "SlotQDT";
|
||||
case 0x0D08: return "SlotPrTbl";
|
||||
case 0x0D0C: return "SlotVBLQ";
|
||||
case 0x0D10: return "ScrnVBLPtr";
|
||||
case 0x0D14: return "SlotTICKS";
|
||||
case 0x0D20: return "TableSeed";
|
||||
case 0x0D24: return "SRsrcTblPtr";
|
||||
case 0x0D28: return "JVBLTask";
|
||||
case 0x0D2C: return "WMgrCPort";
|
||||
case 0x0D30: return "VertRRate";
|
||||
case 0x0D60: return "ChunkyDepth";
|
||||
case 0x0D62: return "CrsrPtr";
|
||||
case 0x0D66: return "PortList";
|
||||
case 0x0D6A: return "MickeyBytes";
|
||||
case 0x0D6E: return "QDErrLM";
|
||||
case 0x0D70: return "VIA2DT";
|
||||
case 0x0D90: return "SInitFlags";
|
||||
//case 0x0D92: return "DTQFlags";
|
||||
case 0x0D92: return "DTQueue";
|
||||
case 0x0D94: return "DTskQHdr";
|
||||
case 0x0D98: return "DTskQTail";
|
||||
case 0x0D9C: return "JDTInstall";
|
||||
case 0x0DA0: return "HiliteRGB";
|
||||
case 0x0DA6: return "TimeSCSIDB";
|
||||
case 0x0DA8: return "DSCtrAdj";
|
||||
case 0x0DAC: return "IconTLAddr";
|
||||
case 0x0DB0: return "VideoInfoOK";
|
||||
case 0x0DB4: return "EndSRTPtr";
|
||||
case 0x0DB8: return "SDMJmpTblPtr";
|
||||
case 0x0DBC: return "JSwapMMU";
|
||||
case 0x0DC0: return "SdmBusErr";
|
||||
case 0x0DC4: return "LastTxGDevice";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
470
macos/sysequ.h
Normal file
470
macos/sysequ.h
Normal file
|
@ -0,0 +1,470 @@
|
|||
/************************************************************
|
||||
|
||||
Created: Sunday, January 6, 1991 at 10:07 PM
|
||||
SysEqu.h
|
||||
C Interface to the Macintosh Libraries
|
||||
|
||||
|
||||
Copyright Apple Computer, Inc. 1985-90
|
||||
All rights reserved
|
||||
|
||||
************************************************************/
|
||||
|
||||
|
||||
#ifndef __macos_sysequ__
|
||||
#define __macos_sysequ__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
const char *GlobalName(uint32_t address);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace MacOS {
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
|
||||
PCDeskPat = 0x20B, /*[GLOBAL VAR] desktop pat, top bit only! others are in use*/
|
||||
HiKeyLast = 0x216, /*[GLOBAL VAR] Same as KbdVars*/
|
||||
KbdLast = 0x218, /*[GLOBAL VAR] Same as KbdVars+2*/
|
||||
ExpandMem = 0x2B6, /*[GLOBAL VAR] pointer to expanded memory block*/
|
||||
SCSIBase = 0x0C00, /*[GLOBAL VAR] (long) base address for SCSI chip read*/
|
||||
SCSIDMA = 0x0C04, /*[GLOBAL VAR] (long) base address for SCSI DMA*/
|
||||
SCSIHsk = 0x0C08, /*[GLOBAL VAR] (long) base address for SCSI handshake*/
|
||||
SCSIGlobals = 0x0C0C, /*[GLOBAL VAR] (long) ptr for SCSI mgr locals*/
|
||||
RGBBlack = 0x0C10, /*[GLOBAL VAR] (6 bytes) the black field for color*/
|
||||
RGBWhite = 0x0C16, /*[GLOBAL VAR] (6 bytes) the white field for color*/
|
||||
RowBits = 0x0C20, /*[GLOBAL VAR] (word) screen horizontal pixels*/
|
||||
ColLines = 0x0C22, /*[GLOBAL VAR] (word) screen vertical pixels*/
|
||||
ScreenBytes = 0x0C24, /*[GLOBAL VAR] (long) total screen bytes*/
|
||||
NMIFlag = 0x0C2C, /*[GLOBAL VAR] (byte) flag for NMI debounce*/
|
||||
VidType = 0x0C2D, /*[GLOBAL VAR] (byte) video board type ID*/
|
||||
VidMode = 0x0C2E, /*[GLOBAL VAR] (byte) video mode (4=4bit color)*/
|
||||
SCSIPoll = 0x0C2F, /*[GLOBAL VAR] (byte) poll for device zero only once.*/
|
||||
SEVarBase = 0x0C30, /*[GLOBAL VAR] */
|
||||
MMUFlags = 0x0CB0, /*[GLOBAL VAR] (byte) cleared to zero (reserved for future use)*/
|
||||
MMUType = 0x0CB1 /*[GLOBAL VAR] (byte) kind of MMU present*/
|
||||
};
|
||||
enum {
|
||||
MMU32bit = 0x0CB2, /*[GLOBAL VAR] (byte) boolean reflecting current machine MMU mode*/
|
||||
MMUFluff = 0x0CB3, /*[GLOBAL VAR] (byte) fluff byte forced by reducing MMUMode to MMU32bit.*/
|
||||
MMUTbl = 0x0CB4, /*[GLOBAL VAR] (long) pointer to MMU Mapping table*/
|
||||
MMUTblSize = 0x0CB8, /*[GLOBAL VAR] (long) size of the MMU mapping table*/
|
||||
SInfoPtr = 0x0CBC, /*[GLOBAL VAR] (long) pointer to Slot manager information*/
|
||||
ASCBase = 0x0CC0, /*[GLOBAL VAR] (long) pointer to Sound Chip*/
|
||||
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 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.*/
|
||||
SlotQDT = 0x0D04, /*[GLOBAL VAR] ptr to slot queue table*/
|
||||
SlotPrTbl = 0x0D08, /*[GLOBAL VAR] ptr to slot priority table*/
|
||||
SlotVBLQ = 0x0D0C, /*[GLOBAL VAR] ptr to slot VBL queue table*/
|
||||
ScrnVBLPtr = 0x0D10, /*[GLOBAL VAR] save for ptr to main screen VBL queue*/
|
||||
SlotTICKS = 0x0D14, /*[GLOBAL VAR] ptr to slot tickcount table*/
|
||||
TableSeed = 0x0D20, /*[GLOBAL VAR] (long) seed value for color table ID's*/
|
||||
SRsrcTblPtr = 0x0D24 /*[GLOBAL VAR] (long) pointer to slot resource table.*/
|
||||
};
|
||||
enum {
|
||||
JVBLTask = 0x0D28, /*[GLOBAL VAR] vector to slot VBL task interrupt handler*/
|
||||
WMgrCPort = 0x0D2C, /*[GLOBAL VAR] window manager color port */
|
||||
VertRRate = 0x0D30, /*[GLOBAL VAR] (word) Vertical refresh rate for start manager. */
|
||||
ChunkyDepth = 0x0D60, /*[GLOBAL VAR] depth of the pixels*/
|
||||
CrsrPtr = 0x0D62, /*[GLOBAL VAR] pointer to cursor save area*/
|
||||
PortList = 0x0D66, /*[GLOBAL VAR] list of grafports*/
|
||||
MickeyBytes = 0x0D6A, /*[GLOBAL VAR] long pointer to cursor stuff*/
|
||||
QDErrLM = 0x0D6E, /*[GLOBAL VAR] QDErr has name conflict w/ type. QuickDraw error code [word]*/
|
||||
VIA2DT = 0x0D70, /*[GLOBAL VAR] 32 bytes for VIA2 dispatch table for NuMac*/
|
||||
SInitFlags = 0x0D90, /*[GLOBAL VAR] StartInit.a flags [word]*/
|
||||
DTQueue = 0x0D92, /*[GLOBAL VAR] (10 bytes) deferred task queue header*/
|
||||
DTQFlags = 0x0D92, /*[GLOBAL VAR] flag word for DTQueue*/
|
||||
DTskQHdr = 0x0D94, /*[GLOBAL VAR] ptr to head of queue*/
|
||||
DTskQTail = 0x0D98, /*[GLOBAL VAR] ptr to tail of queue*/
|
||||
JDTInstall = 0x0D9C, /*[GLOBAL VAR] (long) ptr to deferred task install routine*/
|
||||
HiliteRGB = 0x0DA0, /*[GLOBAL VAR] 6 bytes: rgb of hilite color*/
|
||||
TimeSCSIDB = 0x0DA6, /*[GLOBAL VAR] (word) number of iter's of SCSI access & DBRA*/
|
||||
DSCtrAdj = 0x0DA8, /*[GLOBAL VAR] (long) Center adjust for DS rect.*/
|
||||
IconTLAddr = 0x0DAC, /*[GLOBAL VAR] (long) pointer to where start icons are to be put.*/
|
||||
VideoInfoOK = 0x0DB0 /*[GLOBAL VAR] (long) Signals to CritErr that the Video card is ok*/
|
||||
};
|
||||
enum {
|
||||
EndSRTPtr = 0x0DB4, /*[GLOBAL VAR] (long) Pointer to the end of the Slot Resource Table (Not the SRT buffer).*/
|
||||
SDMJmpTblPtr = 0x0DB8, /*[GLOBAL VAR] (long) Pointer to the SDM jump table*/
|
||||
JSwapMMU = 0x0DBC, /*[GLOBAL VAR] (long) jump vector to SwapMMU routine*/
|
||||
SdmBusErr = 0x0DC0, /*[GLOBAL VAR] (long) Pointer to the SDM busErr handler*/
|
||||
LastTxGDevice = 0x0DC4, /*[GLOBAL VAR] (long) copy of TheGDevice set up for fast text measure*/
|
||||
NewCrsrJTbl = 0x88C, /*[GLOBAL VAR] location of new crsr jump vectors*/
|
||||
JAllocCrsr = 0x88C, /*[GLOBAL VAR] (long) vector to routine that allocates cursor*/
|
||||
JSetCCrsr = 0x890, /*[GLOBAL VAR] (long) vector to routine that sets color cursor*/
|
||||
JOpcodeProc = 0x894, /*[GLOBAL VAR] (long) vector to process new picture opcodes*/
|
||||
CrsrBase = 0x898, /*[GLOBAL VAR] (long) scrnBase for cursor*/
|
||||
CrsrDevice = 0x89C, /*[GLOBAL VAR] (long) current cursor device*/
|
||||
SrcDevice = 0x8A0, /*[GLOBAL VAR] (LONG) Src device for Stretchbits*/
|
||||
MainDevice = 0x8A4, /*[GLOBAL VAR] (long) the main screen device*/
|
||||
DeviceList = 0x8A8, /*[GLOBAL VAR] (long) list of display devices*/
|
||||
CrsrRow = 0x8AC, /*[GLOBAL VAR] (word) rowbytes for current cursor screen*/
|
||||
QDColors = 0x8B0, /*[GLOBAL VAR] (long) handle to default colors*/
|
||||
HiliteMode = 0x938, /*[GLOBAL VAR] used for color highlighting*/
|
||||
BusErrVct = 0x08, /*[GLOBAL VAR] bus error vector*/
|
||||
RestProc = 0xA8C, /*[GLOBAL VAR] Resume procedure f InitDialogs [pointer]*/
|
||||
ROM85 = 0x28E /*[GLOBAL VAR] (word) actually high bit - 0 for ROM vers $75 (sic) and later*/
|
||||
};
|
||||
enum {
|
||||
ROMMapHndl = 0xB06, /*[GLOBAL VAR] (long) handle of ROM resource map*/
|
||||
ScrVRes = 0x102, /*[GLOBAL VAR] Pixels per inch vertically (word)
|
||||
screen vertical dots/inch [word]*/
|
||||
ScrHRes = 0x104, /*[GLOBAL VAR] Pixels per inch horizontally (word)
|
||||
screen horizontal dots/inch [word]*/
|
||||
ScrnBase = 0x824, /*[GLOBAL VAR] Address of main screen buffer
|
||||
Screen Base [pointer]*/
|
||||
ScreenRow = 0x106, /*[GLOBAL VAR] rowBytes of screen [word]*/
|
||||
MBTicks = 0x16E, /*[GLOBAL VAR] tick count @ last mouse button [long]*/
|
||||
JKybdTask = 0x21A, /*[GLOBAL VAR] keyboard VBL task hook [pointer]*/
|
||||
KeyLast = 0x184, /*[GLOBAL VAR] ASCII for last valid keycode [word]*/
|
||||
KeyTime = 0x186, /*[GLOBAL VAR] tickcount when KEYLAST was rec'd [long]*/
|
||||
KeyRepTime = 0x18A, /*[GLOBAL VAR] tickcount when key was last repeated [long]*/
|
||||
SPConfig = 0x1FB, /*[GLOBAL VAR] Use types for serial ports (byte)
|
||||
config bits: 4-7 A, 0-3 B (see use type below)*/
|
||||
SPPortA = 0x1FC, /*[GLOBAL VAR] Modem port configuration (word)
|
||||
SCC port A configuration [word]*/
|
||||
SPPortB = 0x1FE, /*[GLOBAL VAR] Printer port configuration (word)
|
||||
SCC port B configuration [word]*/
|
||||
SCCRd = 0x1D8, /*[GLOBAL VAR] SCC read base address
|
||||
SCC base read address [pointer]*/
|
||||
SCCWr = 0x1DC, /*[GLOBAL VAR] SCC write base address
|
||||
SCC base write address [pointer]*/
|
||||
DoubleTime = 0x2F0, /*[GLOBAL VAR] Double-click interval in ticks (long)
|
||||
double click ticks [long]*/
|
||||
CaretTime = 0x2F4, /*[GLOBAL VAR] Caret-blink interval in ticks (long)
|
||||
caret blink ticks [long]*/
|
||||
KeyThresh = 0x18E, /*[GLOBAL VAR] Auto-key threshold (word)
|
||||
threshold for key repeat [word]*/
|
||||
KeyRepThresh = 0x190, /*[GLOBAL VAR] Auto-key rate (word)
|
||||
key repeat speed [word]*/
|
||||
SdVolume = 0x260 /*[GLOBAL VAR] Current speaker volume (byte: low-order three bits only)
|
||||
Global volume(sound) control [byte]*/
|
||||
};
|
||||
enum {
|
||||
Ticks = 0x16A, /*[GLOBAL VAR] Current number of ticks since system startup (long)
|
||||
Tick count, time since boot [unsigned long]*/
|
||||
TimeLM = 0x20C, /*[GLOBAL VAR] Time has name conflict w/ type. Clock time (extrapolated) [long]*/
|
||||
MonkeyLives = 0x100, /*[GLOBAL VAR] monkey lives if >= 0 [word]*/
|
||||
SEvtEnb = 0x15C, /*[GLOBAL VAR] 0 if SystemEvent should return FALSE (byte)
|
||||
enable SysEvent calls from GNE [byte]*/
|
||||
JournalFlag = 0x8DE, /*[GLOBAL VAR] Journaling mode (word)
|
||||
journaling state [word]*/
|
||||
JournalRef = 0x8E8, /*[GLOBAL VAR] Reference number of journaling device driver (word)
|
||||
Journalling driver's refnum [word]*/
|
||||
BufPtr = 0x10C, /*[GLOBAL VAR] Address of end of jump table
|
||||
top of application memory [pointer]*/
|
||||
StkLowPt = 0x110, /*[GLOBAL VAR] Lowest stack as measured in VBL task [pointer]*/
|
||||
TheZone = 0x118, /*[GLOBAL VAR] Address of current heap zone
|
||||
current heap zone [pointer]*/
|
||||
ApplLimit = 0x130, /*[GLOBAL VAR] Application heap limit
|
||||
application limit [pointer]*/
|
||||
SysZone = 0x2A6, /*[GLOBAL VAR] Address of system heap zone
|
||||
system heap zone [pointer]*/
|
||||
ApplZone = 0x2AA, /*[GLOBAL VAR] Address of application heap zone
|
||||
application heap zone [pointer]*/
|
||||
HeapEnd = 0x114, /*[GLOBAL VAR] Address of end of application heap zone
|
||||
end of heap [pointer]*/
|
||||
HiHeapMark = 0xBAE, /*[GLOBAL VAR] (long) highest address used by a zone below sp<01Nov85 JTC>*/
|
||||
MemErr = 0x220, /*[GLOBAL VAR] last memory manager error [word]*/
|
||||
UTableBase = 0x11C, /*[GLOBAL VAR] Base address of unit table
|
||||
unit I/O table [pointer]*/
|
||||
UnitNtryCnt = 0x1D2, /*[GLOBAL VAR] count of entries in unit table [word]*/
|
||||
JFetch = 0x8F4, /*[GLOBAL VAR] Jump vector for Fetch function
|
||||
fetch a byte routine for drivers [pointer]*/
|
||||
JStash = 0x8F8, /*[GLOBAL VAR] Jump vector for Stash function
|
||||
stash a byte routine for drivers [pointer]*/
|
||||
JIODone = 0x8FC /*[GLOBAL VAR] Jump vector for IODone function
|
||||
IODone entry location [pointer]*/
|
||||
};
|
||||
enum {
|
||||
DrvQHdr = 0x308, /*[GLOBAL VAR] Drive queue header (10 bytes)
|
||||
queue header of drives in system [10 bytes]*/
|
||||
BootDrive = 0x210, /*[GLOBAL VAR] drive number of boot drive [word]*/
|
||||
EjectNotify = 0x338, /*[GLOBAL VAR] eject notify procedure [pointer]*/
|
||||
IAZNotify = 0x33C, /*[GLOBAL VAR] world swaps notify procedure [pointer]*/
|
||||
SFSaveDisk = 0x214, /*[GLOBAL VAR] Negative of volume reference number used by Standard File Package (word)
|
||||
last vRefNum seen by standard file [word]*/
|
||||
CurDirStore = 0x398, /*[GLOBAL VAR] save dir across calls to Standard File [long]*/
|
||||
OneOne = 0xA02, /*[GLOBAL VAR] $00010001
|
||||
constant $00010001 [long]*/
|
||||
MinusOne = 0xA06, /*[GLOBAL VAR] $FFFFFFFF
|
||||
constant $FFFFFFFF [long]*/
|
||||
Lo3Bytes = 0x31A, /*[GLOBAL VAR] $00FFFFFF
|
||||
constant $00FFFFFF [long]*/
|
||||
ROMBase = 0x2AE, /*[GLOBAL VAR] Base address of ROM
|
||||
ROM base address [pointer]*/
|
||||
RAMBase = 0x2B2, /*[GLOBAL VAR] Trap dispatch table's base address for routines in RAM
|
||||
RAM base address [pointer]*/
|
||||
SysVersion = 0x15A, /*[GLOBAL VAR] version # of RAM-based system [word]*/
|
||||
RndSeed = 0x156, /*[GLOBAL VAR] Random number seed (long)
|
||||
random seed/number [long]*/
|
||||
Scratch20 = 0x1E4, /*[GLOBAL VAR] 20-byte scratch area
|
||||
scratch [20 bytes]*/
|
||||
Scratch8 = 0x9FA, /*[GLOBAL VAR] 8-byte scratch area
|
||||
scratch [8 bytes]*/
|
||||
ScrapSize = 0x960, /*[GLOBAL VAR] Size in bytes of desk scrap (long)
|
||||
scrap length [long]*/
|
||||
ScrapHandle = 0x964, /*[GLOBAL VAR] Handle to desk scrap in memory
|
||||
memory scrap [handle]*/
|
||||
ScrapCount = 0x968, /*[GLOBAL VAR] Count changed by ZeroScrap (word)
|
||||
validation byte [word]*/
|
||||
ScrapState = 0x96A, /*[GLOBAL VAR] Tells where desk scrap is (word)
|
||||
scrap state [word]*/
|
||||
ScrapName = 0x96C /*[GLOBAL VAR] Pointer to scrap file name (preceded by length byte)
|
||||
pointer to scrap name [pointer]*/
|
||||
};
|
||||
enum {
|
||||
IntlSpec = 0xBA0, /*[GLOBAL VAR] (long) - ptr to extra Intl data */
|
||||
SwitcherTPtr = 0x286, /*[GLOBAL VAR] Switcher's switch table */
|
||||
CPUFlag = 0x12F, /*[GLOBAL VAR] $00=68000, $01=68010, $02=68020 (old ROM inits to $00)*/
|
||||
VIA = 0x1D4, /*[GLOBAL VAR] VIA base address
|
||||
VIA base address [pointer]*/
|
||||
IWM = 0x1E0, /*[GLOBAL VAR] IWM base address [pointer]*/
|
||||
Lvl1DT = 0x192, /*[GLOBAL VAR] Level-1 secondary interrupt vector table (32 bytes)
|
||||
Interrupt level 1 dispatch table [32 bytes]*/
|
||||
Lvl2DT = 0x1B2, /*[GLOBAL VAR] Level-2 secondary interrupt vector table (32 bytes)
|
||||
Interrupt level 2 dispatch table [32 bytes]*/
|
||||
ExtStsDT = 0x2BE, /*[GLOBAL VAR] External/status interrupt vector table (16 bytes)
|
||||
SCC ext/sts secondary dispatch table [16 bytes]*/
|
||||
SPValid = 0x1F8, /*[GLOBAL VAR] Validity status (byte)
|
||||
validation field ($A7) [byte]*/
|
||||
SPATalkA = 0x1F9, /*[GLOBAL VAR] AppleTalk node ID hint for modem port (byte)
|
||||
AppleTalk node number hint for port A*/
|
||||
SPATalkB = 0x1FA, /*[GLOBAL VAR] AppleTalk node ID hint for printer port (byte)
|
||||
AppleTalk node number hint for port B*/
|
||||
SPAlarm = 0x200, /*[GLOBAL VAR] Alarm setting (long)
|
||||
alarm time [long]*/
|
||||
SPFont = 0x204, /*[GLOBAL VAR] Application font number minus 1 (word)
|
||||
default application font number minus 1 [word]*/
|
||||
SPKbd = 0x206, /*[GLOBAL VAR] Auto-key threshold and rate (byte)
|
||||
kbd repeat thresh in 4/60ths [2 4-bit]*/
|
||||
SPPrint = 0x207, /*[GLOBAL VAR] Printer connection (byte)
|
||||
print stuff [byte]*/
|
||||
SPVolCtl = 0x208, /*[GLOBAL VAR] Speaker volume setting in parameter RAM (byte)
|
||||
volume control [byte]*/
|
||||
SPClikCaret = 0x209, /*[GLOBAL VAR] Double-click and caret-blink times (byte)
|
||||
double click/caret time in 4/60ths[2 4-bit]*/
|
||||
SPMisc1 = 0x20A, /*[GLOBAL VAR] miscellaneous [1 byte]*/
|
||||
SPMisc2 = 0x20B, /*[GLOBAL VAR] Mouse scaling, system startup disk, menu blink (byte)
|
||||
miscellaneous [1 byte]*/
|
||||
GetParam = 0x1E4 /*[GLOBAL VAR] system parameter scratch [20 bytes]*/
|
||||
};
|
||||
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)
|
||||
delta threshold for mouse scaling [word]*/
|
||||
JCrsrTask = 0x8EE, /*[GLOBAL VAR] address of CrsrVBLTask [long]*/
|
||||
MTemp = 0x828, /*[GLOBAL VAR] Low-level interrupt mouse location [long]*/
|
||||
RawMouse = 0x82C, /*[GLOBAL VAR] un-jerked mouse coordinates [long]*/
|
||||
CrsrRect = 0x83C, /*[GLOBAL VAR] Cursor hit rectangle [8 bytes]*/
|
||||
TheCrsr = 0x844, /*[GLOBAL VAR] Cursor data, mask & hotspot [68 bytes]*/
|
||||
CrsrAddr = 0x888, /*[GLOBAL VAR] Address of data under cursor [long]*/
|
||||
CrsrSave = 0x88C, /*[GLOBAL VAR] data under the cursor [64 bytes]*/
|
||||
CrsrVis = 0x8CC, /*[GLOBAL VAR] Cursor visible? [byte]*/
|
||||
CrsrBusy = 0x8CD, /*[GLOBAL VAR] Cursor locked out? [byte]*/
|
||||
CrsrNew = 0x8CE, /*[GLOBAL VAR] Cursor changed? [byte]*/
|
||||
CrsrState = 0x8D0, /*[GLOBAL VAR] Cursor nesting level [word]*/
|
||||
CrsrObscure = 0x8D2, /*[GLOBAL VAR] Cursor obscure semaphore [byte]*/
|
||||
KbdVars = 0x216, /*[GLOBAL VAR] Keyboard manager variables [4 bytes]*/
|
||||
KbdType = 0x21E, /*[GLOBAL VAR] keyboard model number [byte]*/
|
||||
MBState = 0x172, /*[GLOBAL VAR] current mouse button state [byte]*/
|
||||
KeyMapLM = 0x174, /*[GLOBAL VAR] KeyMap has name conflict w/ type. Bitmap of the keyboard [4 longs]*/
|
||||
KeypadMap = 0x17C, /*[GLOBAL VAR] bitmap for numeric pad-18bits [long]*/
|
||||
Key1Trans = 0x29E /*[GLOBAL VAR] keyboard translator procedure [pointer]*/
|
||||
};
|
||||
enum {
|
||||
Key2Trans = 0x2A2, /*[GLOBAL VAR] numeric keypad translator procedure [pointer]*/
|
||||
JGNEFilter = 0x29A, /*[GLOBAL VAR] GetNextEvent filter proc [pointer]*/
|
||||
KeyMVars = 0xB04, /*[GLOBAL VAR] (word) for ROM KEYM proc state*/
|
||||
Mouse = 0x830, /*[GLOBAL VAR] processed mouse coordinate [long]*/
|
||||
CrsrPin = 0x834, /*[GLOBAL VAR] cursor pinning rectangle [8 bytes]*/
|
||||
CrsrCouple = 0x8CF, /*[GLOBAL VAR] cursor coupled to mouse? [byte]*/
|
||||
CrsrScale = 0x8D3, /*[GLOBAL VAR] cursor scaled? [byte]*/
|
||||
MouseMask = 0x8D6, /*[GLOBAL VAR] V-H mask for ANDing with mouse [long]*/
|
||||
MouseOffset = 0x8DA, /*[GLOBAL VAR] V-H offset for adding after ANDing [long]*/
|
||||
AlarmState = 0x21F, /*[GLOBAL VAR] Bit7=parity, Bit6=beeped, Bit0=enable [byte]*/
|
||||
VBLQueue = 0x160, /*[GLOBAL VAR] Vertical retrace queue header (10 bytes)
|
||||
VBL queue header [10 bytes]*/
|
||||
SysEvtMask = 0x144, /*[GLOBAL VAR] System event mask (word)
|
||||
system event mask [word]*/
|
||||
SysEvtBuf = 0x146, /*[GLOBAL VAR] system event queue element buffer [pointer]*/
|
||||
EventQueue = 0x14A, /*[GLOBAL VAR] Event queue header (10 bytes)
|
||||
event queue header [10 bytes]*/
|
||||
EvtBufCnt = 0x154, /*[GLOBAL VAR] max number of events in SysEvtBuf - 1 [word]*/
|
||||
GZRootHnd = 0x328, /*[GLOBAL VAR] Handle to relocatable block not to be moved by grow zone function
|
||||
root handle for GrowZone [handle]*/
|
||||
GZRootPtr = 0x32C, /*[GLOBAL VAR] root pointer for GrowZone [pointer]*/
|
||||
GZMoveHnd = 0x330, /*[GLOBAL VAR] moving handle for GrowZone [handle]*/
|
||||
MemTop = 0x108, /*[GLOBAL VAR] Address of end of RAM (on Macintosh XL, end of RAM available to applications)
|
||||
top of memory [pointer]*/
|
||||
MmInOK = 0x12E /*[GLOBAL VAR] initial memory mgr checks ok? [byte]*/
|
||||
};
|
||||
enum {
|
||||
HpChk = 0x316, /*[GLOBAL VAR] heap check RAM code [pointer]*/
|
||||
MaskBC = 0x31A, /*[GLOBAL VAR] Memory Manager Byte Count Mask [long]*/
|
||||
MaskHandle = 0x31A, /*[GLOBAL VAR] Memory Manager Handle Mask [long]*/
|
||||
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)
|
||||
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
|
||||
system error alerts [pointer]*/
|
||||
DSAlertRect = 0x3F8, /*[GLOBAL VAR] Rectangle enclosing system error alert (8 bytes)
|
||||
rectangle for disk-switch alert [8 bytes]*/
|
||||
DSDrawProc = 0x334, /*[GLOBAL VAR] alternate syserror draw procedure [pointer]*/
|
||||
DSWndUpdate = 0x15D, /*[GLOBAL VAR] GNE not to paintBehind DS AlertRect? [byte]*/
|
||||
WWExist = 0x8F2, /*[GLOBAL VAR] window manager initialized? [byte]*/
|
||||
QDExist = 0x8F3, /*[GLOBAL VAR] quickdraw is initialized [byte]*/
|
||||
ResumeProc = 0xA8C, /*[GLOBAL VAR] Address of resume procedure
|
||||
Resume procedure from InitDialogs [pointer]*/
|
||||
DSErrCode = 0xAF0, /*[GLOBAL VAR] Current system error ID (word)
|
||||
last system error alert ID*/
|
||||
IntFlag = 0x15F, /*[GLOBAL VAR] reduce interrupt disable time when bit 7 = 0*/
|
||||
SerialVars = 0x2D0, /*[GLOBAL VAR] async driver variables [16 bytes]*/
|
||||
ABusVars = 0x2D8, /*[GLOBAL VAR] Pointer to AppleTalk variables
|
||||
;Pointer to AppleTalk local variables*/
|
||||
ABusDCE = 0x2DC, /*[GLOBAL VAR] ;Pointer to AppleTalk DCE*/
|
||||
PortAUse = 0x290 /*[GLOBAL VAR] bit 7: 1 = not in use, 0 = in use*/
|
||||
};
|
||||
enum {
|
||||
PortBUse = 0x291, /*[GLOBAL VAR] Current availability of serial port B (byte)
|
||||
port B use, same format as PortAUse*/
|
||||
SCCASts = 0x2CE, /*[GLOBAL VAR] SCC read reg 0 last ext/sts rupt - A [byte]*/
|
||||
SCCBSts = 0x2CF, /*[GLOBAL VAR] SCC read reg 0 last ext/sts rupt - B [byte]*/
|
||||
DskErr = 0x142, /*[GLOBAL VAR] disk routine result code [word]*/
|
||||
PWMBuf2 = 0x312, /*[GLOBAL VAR] PWM buffer 1 (or 2 if sound) [pointer]*/
|
||||
SoundPtr = 0x262, /*[GLOBAL VAR] Pointer to four-tone record
|
||||
4VE sound definition table [pointer]*/
|
||||
SoundBase = 0x266, /*[GLOBAL VAR] Pointer to free-form synthesizer buffer
|
||||
sound bitMap [pointer]*/
|
||||
SoundVBL = 0x26A, /*[GLOBAL VAR] vertical retrace control element [16 bytes]*/
|
||||
SoundDCE = 0x27A, /*[GLOBAL VAR] sound driver DCE [pointer]*/
|
||||
SoundActive = 0x27E, /*[GLOBAL VAR] sound is active? [byte]*/
|
||||
SoundLevel = 0x27F, /*[GLOBAL VAR] Amplitude in 740-byte buffer (byte)
|
||||
current level in buffer [byte]*/
|
||||
CurPitch = 0x280, /*[GLOBAL VAR] Value of count in square-wave synthesizer buffer (word)
|
||||
current pitch value [word]*/
|
||||
DskVerify = 0x12C, /*[GLOBAL VAR] used by 3.5 disk driver for read/verify [byte]*/
|
||||
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)
|
||||
flags [word]*/
|
||||
BufTgFBkNum = 0x302, /*[GLOBAL VAR] File tags buffer: logical block number (word)
|
||||
logical block number [word]*/
|
||||
BufTgDate = 0x304, /*[GLOBAL VAR] File tags buffer: date and time of last modification (long)
|
||||
time stamp [word]*/
|
||||
ScrDmpEnb = 0x2F8, /*[GLOBAL VAR] 0 if GetNextEvent shouldn't process Command-Shift-number combinations (byte)
|
||||
screen dump enabled? [byte]*/
|
||||
ScrDmpType = 0x2F9 /*[GLOBAL VAR] FF dumps screen, FE dumps front window [byte]*/
|
||||
};
|
||||
enum {
|
||||
ScrapVars = 0x960, /*[GLOBAL VAR] scrap manager variables [32 bytes]*/
|
||||
ScrapInfo = 0x960, /*[GLOBAL VAR] scrap length [long]*/
|
||||
ScrapEnd = 0x980, /*[GLOBAL VAR] end of scrap vars*/
|
||||
ScrapTag = 0x970, /*[GLOBAL VAR] scrap file name [STRING[15]]*/
|
||||
LaunchFlag = 0x902, /*[GLOBAL VAR] from launch or chain [byte]*/
|
||||
SaveSegHandle = 0x930, /*[GLOBAL VAR] seg 0 handle [handle]*/
|
||||
CurJTOffset = 0x934, /*[GLOBAL VAR] Offset to jump table from location pointed to by A5 (word)
|
||||
current jump table offset [word]*/
|
||||
CurPageOption = 0x936, /*[GLOBAL VAR] Sound/screen buffer configuration passed to Chain or Launch (word)
|
||||
current page 2 configuration [word]*/
|
||||
LoaderPBlock = 0x93A, /*[GLOBAL VAR] param block for ExitToShell [10 bytes]*/
|
||||
CurApRefNum = 0x900, /*[GLOBAL VAR] Reference number of current application's resource file (word)
|
||||
refNum of application's resFile [word]*/
|
||||
CurrentA5 = 0x904, /*[GLOBAL VAR] Address of boundary between application globals and application parameters
|
||||
current value of A5 [pointer]*/
|
||||
CurStackBase = 0x908, /*[GLOBAL VAR] Address of base of stack; start of application globals
|
||||
current stack base [pointer]*/
|
||||
CurApName = 0x910, /*[GLOBAL VAR] Name of current application (length byte followed by up to 31 characters)
|
||||
name of application [STRING[31]]*/
|
||||
LoadTrap = 0x12D, /*[GLOBAL VAR] trap before launch? [byte]*/
|
||||
SegHiEnable = 0xBB2, /*[GLOBAL VAR] (byte) 0 to disable MoveHHi in LoadSeg*/
|
||||
|
||||
/* Window Manager Globals */
|
||||
WindowList = 0x9D6, /*[GLOBAL VAR] Pointer to first window in window list; 0 if using events but not windows
|
||||
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
|
||||
window manager's grafport [pointer]*/
|
||||
GrayRgn = 0x9EE, /*[GLOBAL VAR] Handle to region drawn as desktop
|
||||
rounded gray desk region [handle]*/
|
||||
CurActivate = 0xA64 /*[GLOBAL VAR] Pointer to window to receive activate event
|
||||
window slated for activate event [pointer]*/
|
||||
};
|
||||
enum {
|
||||
CurDeactive = 0xA68, /*[GLOBAL VAR] Pointer to window to receive deactivate event
|
||||
window slated for deactivate event [pointer]*/
|
||||
DragHook = 0x9F6, /*[GLOBAL VAR] Address of procedure to execute during TrackGoAway, DragWindow, GrowWindow, DragGrayRgn, TrackControl, and DragControl
|
||||
user hook during dragging [pointer]*/
|
||||
DeskPattern = 0xA3C, /*[GLOBAL VAR] Pattern with which desktop is painted (8 bytes)
|
||||
desk pattern [8 bytes]*/
|
||||
DeskHook = 0xA6C, /*[GLOBAL VAR] Address of procedure for painting desktop or responding to clicks on desktop
|
||||
hook for painting the desk [pointer]*/
|
||||
GhostWindow = 0xA84, /*[GLOBAL VAR] Pointer to window never to be considered frontmost
|
||||
window hidden from FrontWindow [pointer]*/
|
||||
|
||||
/* Text Edit Globals */
|
||||
TEDoText = 0xA70, /*[GLOBAL VAR] Address of TextEdit multi-purpose routine
|
||||
textEdit doText proc hook [pointer]*/
|
||||
TERecal = 0xA74, /*[GLOBAL VAR] Address of routine to recalculate line starts for TextEdit
|
||||
textEdit recalText proc hook [pointer]*/
|
||||
TEScrpLength = 0xAB0, /*[GLOBAL VAR] Size in bytes of TextEdit scrap (long)
|
||||
textEdit Scrap Length [word]*/
|
||||
TEScrpHandle = 0xAB4, /*[GLOBAL VAR] Handle to TextEdit scrap
|
||||
textEdit Scrap [handle]*/
|
||||
TEWdBreak = 0xAF6, /*[GLOBAL VAR] default word break routine [pointer]*/
|
||||
WordRedraw = 0xBA5, /*[GLOBAL VAR] (byte) - used by TextEdit RecalDraw*/
|
||||
TESysJust = 0xBAC, /*[GLOBAL VAR] (word) system justification (intl. textEdit)*/
|
||||
|
||||
/* Resource Manager Globals */
|
||||
TopMapHndl = 0xA50, /*[GLOBAL VAR] Handle to resource map of most recently opened resource file
|
||||
topmost map in list [handle]*/
|
||||
SysMapHndl = 0xA54, /*[GLOBAL VAR] Handle to map of system resource file
|
||||
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)
|
||||
reference number of current map [word]*/
|
||||
ResReadOnly = 0xA5C, /*[GLOBAL VAR] Read only flag [word]*/
|
||||
ResLoad = 0xA5E, /*[GLOBAL VAR] Current SetResLoad state (word)
|
||||
Auto-load feature [word]*/
|
||||
ResErr = 0xA60, /*[GLOBAL VAR] Current value of ResError (word)
|
||||
Resource error code [word]*/
|
||||
ResErrProc = 0xAF2 /*[GLOBAL VAR] Address of resource error procedure
|
||||
Resource error procedure [pointer]*/
|
||||
};
|
||||
enum {
|
||||
SysResName = 0xAD8, /*[GLOBAL VAR] Name of system resource file (length byte followed by up to 19 characters)
|
||||
Name of system resource file [STRING[19]]*/
|
||||
RomMapInsert = 0xB9E, /*[GLOBAL VAR] (byte) determines if we should link in map*/
|
||||
TmpResLoad = 0xB9F, /*[GLOBAL VAR] second byte is temporary ResLoad value.*/
|
||||
|
||||
/* Menu Mgr globals */
|
||||
MBarHeight = 0xBAA, /*[GLOBAL VAR] height of the menu bar*/
|
||||
|
||||
/* CommToolbox Global */
|
||||
CommToolboxGlobals = 0x0BB4 /*[GLOBAL VAR] pointer to CommToolbox globals */
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
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
|
|
@ -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 "_HighLevelFSDispatch";
|
||||
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";
|
1081
macos/traps.h
Normal file
1081
macos/traps.h
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,3 @@
|
|||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(MPLITE_SRC mplite.c)
|
||||
|
||||
add_library(MPLITE_LIB ${MPLITE_SRC})
|
126
mplite/mplite.c
126
mplite/mplite.c
|
@ -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);
|
||||
|
||||
|
@ -189,6 +188,54 @@ MPLITE_API int mplite_resize(mplite_t *handle, const void *pPrior,
|
|||
return MPLITE_ERR_INVPAR; // not really, but ok.
|
||||
}
|
||||
|
||||
/* return the largest available block size */
|
||||
MPLITE_API int mplite_maxmem(mplite_t *handle)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (NULL == handle) return 0;
|
||||
|
||||
mplite_enter(handle);
|
||||
for (i = MPLITE_LOGMAX + 1; i; --i)
|
||||
{
|
||||
if (handle->aiFreelist[i - 1] != -1) break;
|
||||
}
|
||||
mplite_leave(handle);
|
||||
if (i) return (1 << (i - 1)) * handle->szAtom;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/* return the total available memory */
|
||||
MPLITE_API int mplite_freemem(mplite_t *handle)
|
||||
{
|
||||
int total;
|
||||
int blocksize;
|
||||
int i;
|
||||
|
||||
if (NULL == handle) return 0;
|
||||
|
||||
total = 0;
|
||||
mplite_enter(handle);
|
||||
for (i = 0, blocksize = 1; i <= MPLITE_LOGMAX; ++i, blocksize <<= 1)
|
||||
{
|
||||
int index = handle->aiFreelist[i];
|
||||
|
||||
while (index != -1)
|
||||
{
|
||||
mplite_link_t *link = mplite_getlink(handle, index);
|
||||
total += blocksize;
|
||||
|
||||
index = link->next;
|
||||
}
|
||||
}
|
||||
mplite_leave(handle);
|
||||
|
||||
return total * handle->szAtom;
|
||||
|
||||
//return handle->szAtom * handle->nBlock - handle->currentOut;
|
||||
}
|
||||
|
||||
|
||||
MPLITE_API int mplite_roundup(mplite_t *handle, const int n)
|
||||
{
|
||||
int iFullSz;
|
||||
|
@ -260,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;
|
||||
}
|
||||
|
||||
|
@ -320,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
|
||||
|
@ -360,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++) {
|
||||
|
@ -382,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;
|
||||
|
||||
|
@ -412,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];
|
||||
}
|
||||
|
@ -427,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);
|
||||
|
@ -452,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++;
|
||||
|
@ -472,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. */
|
||||
|
@ -220,6 +219,13 @@ MPLITE_API void mplite_print_stats(const mplite_t * const handle,
|
|||
*/
|
||||
#define mplite_alloc_count(handle) (((handle) != NULL)? (handle)->nAlloc : 0)
|
||||
|
||||
|
||||
/* return the largest available block size */
|
||||
MPLITE_API int mplite_maxmem(mplite_t *handle);
|
||||
|
||||
/* return the total available memory */
|
||||
MPLITE_API int mplite_freemem(mplite_t *handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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)
|
||||
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})
|
127
mpw/environ.re.cpp
Normal file
127
mpw/environ.re.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
#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;
|
||||
|
||||
/*!re2c
|
||||
re2c:define:YYCTYPE = "char";
|
||||
re2c:define:YYCURSOR = cp;
|
||||
re2c:define:YYMARKER = marker;
|
||||
re2c:yyfill:enable = 0;
|
||||
re2c:yych:conversion = 1;
|
||||
re2c:indent:top = 1;
|
||||
|
||||
'$' [A-Za-z0-9_]+ {
|
||||
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;
|
||||
}
|
||||
|
||||
'${' [A-Za-z0-9_]+ '}' {
|
||||
|
||||
std::string tmp(begin + 2, cp - 1);
|
||||
|
||||
auto iter = env.find(tmp);
|
||||
if (iter != env.end())
|
||||
{
|
||||
rv.append(iter->second);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
. {
|
||||
rv.push_back(*begin);
|
||||
continue;
|
||||
}
|
||||
[^] {
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
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
|
506
mpw/mpw.cpp
506
mpw/mpw.cpp
|
@ -1,8 +1,38 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
@ -10,83 +40,455 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libgen.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <cpu/defs.h>
|
||||
#include <cpu/fmem.h>
|
||||
#include <cpu/cpuModule.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
|
||||
#include <toolbox/toolbox.h>
|
||||
#include <toolbox/mm.h>
|
||||
#include <toolbox/os_internal.h>
|
||||
|
||||
#include <macos/sysequ.h>
|
||||
|
||||
extern char **environ;
|
||||
|
||||
|
||||
namespace MPW { namespace Internal {
|
||||
namespace MPW {
|
||||
|
||||
// for dup counts, etc.
|
||||
std::vector<int> FDTable;
|
||||
//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)
|
||||
|
||||
|
||||
static bool isdir(const std::string &path)
|
||||
{
|
||||
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;
|
||||
|
||||
struct stat st;
|
||||
if (stat(path.c_str(), &st) < 0) return false;
|
||||
return S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
void Init()
|
||||
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;
|
||||
static std::string path;
|
||||
|
||||
static const std::string paths[] = {
|
||||
"/usr/local/share/mpw",
|
||||
"/usr/share/mpw",
|
||||
};
|
||||
|
||||
char *cp;
|
||||
struct passwd *pw;
|
||||
|
||||
if (initialized) return path;
|
||||
|
||||
initialized = true;
|
||||
|
||||
// check $MPW, $HOME/mpw, /usr/local/share/mpw/, /usr/share/mpw
|
||||
// for a directory.
|
||||
|
||||
cp = getenv("MPW");
|
||||
if (cp && *cp)
|
||||
{
|
||||
std::string s(cp);
|
||||
if (isdir(s))
|
||||
{
|
||||
path = std::move(s);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// home/mpw
|
||||
pw = getpwuid(getuid());
|
||||
if (pw && pw->pw_dir && pw->pw_dir[0])
|
||||
{
|
||||
std::string s(pw->pw_dir);
|
||||
if (s.back() != '/') s.push_back('/');
|
||||
s.append("mpw");
|
||||
|
||||
if (isdir(s))
|
||||
{
|
||||
path = std::move(s);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
// thread-safe
|
||||
{
|
||||
int size;
|
||||
|
||||
size = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
if (size >= 0)
|
||||
{
|
||||
struct passwd pwd, *result = nullptr;
|
||||
char *buffer = alloca(size);
|
||||
|
||||
if (getpwuid_r(getuid(), &pwd, buffer, size, &result) == 0 && result)
|
||||
{
|
||||
std::string s(pwd.pw_dir);
|
||||
if (s.back() != '/') s.push_back('/');
|
||||
s.append("mpw");
|
||||
if (isdir(s))
|
||||
{
|
||||
path = std::move(s);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (auto &iter : paths)
|
||||
{
|
||||
if (isdir(iter))
|
||||
{
|
||||
path = iter;
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
/*
|
||||
FDTable.resize(16);
|
||||
|
||||
FDTable[STDIN_FILENO] = 1;
|
||||
FDTable[STDOUT_FILENO] = 1;
|
||||
FDTable[STDERR_FILENO] = 1;
|
||||
*/
|
||||
|
||||
// todo -- should eventually set up the mpw environment.
|
||||
/*
|
||||
OS::Internal::FDTable.resize(3);
|
||||
FDTable[STDIN_FILENO].refcount = 1;
|
||||
FDTable[STDIN_FILENO].text = true;
|
||||
|
||||
FDTable[STDOUT_FILENO].refcount = 1;
|
||||
FDTable[STDOUT_FILENO].text = true;
|
||||
|
||||
FDTable[STDERR_FILENO].refcount = 1;
|
||||
FDTable[STDERR_FILENO].text = true;
|
||||
*/
|
||||
|
||||
OS::Internal::FDEntry::allocate(STDIN_FILENO).text = true;
|
||||
OS::Internal::FDEntry::allocate(STDOUT_FILENO).text = true;
|
||||
OS::Internal::FDEntry::allocate(STDERR_FILENO).text = true;
|
||||
|
||||
|
||||
std::string command = argv[0];
|
||||
|
||||
command = ToolBox::UnixToMac(command);
|
||||
//std::replace(command.begin(), command.end(), '/', ':');
|
||||
|
||||
argv[0] = basename(argv[0]);
|
||||
|
||||
|
||||
// 0x0910 CurApName
|
||||
{
|
||||
char str32[32];
|
||||
|
||||
char * name = argv[0];
|
||||
int l = strlen(name);
|
||||
l = std::min(l, 32);
|
||||
str32[0] = l;
|
||||
std::memcpy(str32 + 1, name, l);
|
||||
while (l < 32) str32[l++] = 0;
|
||||
|
||||
std::memcpy(memoryPointer(MacOS::CurApName), str32, 32);
|
||||
}
|
||||
|
||||
|
||||
uint32_t argvptr = 0;
|
||||
uint32_t envptr = 0;
|
||||
uint32_t ioptr = 0;
|
||||
uint32_t devptr = 0;
|
||||
uint32_t fptr = 0;
|
||||
|
||||
uint16_t error;
|
||||
|
||||
// create the argv-data.
|
||||
{
|
||||
uint32_t size = 0;
|
||||
|
||||
size = 4 * (argc + 1); // argv data.
|
||||
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
int l = strlen(argv[i]) + 1;
|
||||
if (l & 0x01) l++;
|
||||
size += l;
|
||||
}
|
||||
|
||||
error = MM::Native::NewPtr(size, true, argvptr);
|
||||
if (error) return error;
|
||||
|
||||
|
||||
uint8_t *xptr = memoryPointer(argvptr);
|
||||
uint32_t offset = 0;
|
||||
|
||||
offset = 4 * (argc + 1);
|
||||
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
memoryWriteLong(argvptr + offset, argvptr + 4 * i);
|
||||
|
||||
// just use strcat?
|
||||
int l = strlen(argv[i]) + 1;
|
||||
if (l & 0x01) l++;
|
||||
|
||||
strcpy((char *)xptr + offset, argv[i]);
|
||||
|
||||
offset += l;
|
||||
}
|
||||
|
||||
// null-terminate it.
|
||||
memoryWriteLong(0, argvptr + 4 * argc);
|
||||
|
||||
}
|
||||
|
||||
// environment
|
||||
{
|
||||
Environment.emplace(std::string("Command"), command);
|
||||
|
||||
std::deque<std::string> e;
|
||||
|
||||
for (const auto &iter : Environment)
|
||||
{
|
||||
std::string tmp;
|
||||
tmp.append(iter.first);
|
||||
tmp.push_back(0);
|
||||
tmp.append(iter.second);
|
||||
e.emplace_back(std::move(tmp));
|
||||
}
|
||||
|
||||
|
||||
uint32_t size = 0;
|
||||
for (const std::string &s : e)
|
||||
{
|
||||
int l = s.length() + 1;
|
||||
if (l & 0x01) l++;
|
||||
size = size + l + 4;
|
||||
}
|
||||
|
||||
size += 4; // space for null terminator.
|
||||
|
||||
error = MM::Native::NewPtr(size, true, envptr);
|
||||
if (error) return error;
|
||||
|
||||
|
||||
uint8_t *xptr = memoryPointer(envptr);
|
||||
uint32_t offset = 0;
|
||||
|
||||
offset = 4 * (e.size() + 1);
|
||||
unsigned i = 0;
|
||||
for (const std::string &s : e)
|
||||
{
|
||||
// ptr
|
||||
memoryWriteLong(envptr + offset, envptr + i * 4);
|
||||
|
||||
int l = s.length() + 1;
|
||||
|
||||
std::memcpy(xptr + offset, s.c_str(), l);
|
||||
|
||||
if (l & 0x01) l++;
|
||||
offset += l;
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
// null-terminate it.
|
||||
memoryWriteLong(0, envptr + 4 * e.size());
|
||||
}
|
||||
|
||||
// ftable
|
||||
{
|
||||
// these are ftraps for emulated/native function ptrs.
|
||||
uint32_t size = 6 * 4;
|
||||
|
||||
error = MM::Native::NewPtr(size, true, fptr);
|
||||
|
||||
if (error) return error;
|
||||
|
||||
memoryWriteWord(fQuit, fptr + 0);
|
||||
memoryWriteWord(0x4E75, fptr + 2); // rts
|
||||
|
||||
memoryWriteWord(fAccess, fptr + 4);
|
||||
memoryWriteWord(0x4E75, fptr + 6); // rts
|
||||
|
||||
memoryWriteWord(fClose, fptr + 8);
|
||||
memoryWriteWord(0x4E75, fptr + 10); // rts
|
||||
|
||||
memoryWriteWord(fRead, fptr + 12);
|
||||
memoryWriteWord(0x4E75, fptr + 14); // rts
|
||||
|
||||
memoryWriteWord(fWrite, fptr + 16);
|
||||
memoryWriteWord(0x4E75, fptr + 18); // rts
|
||||
|
||||
memoryWriteWord(fIOCtl, fptr + 20);
|
||||
memoryWriteWord(0x4E75, fptr + 22); // rts
|
||||
|
||||
}
|
||||
|
||||
|
||||
// dev table
|
||||
{
|
||||
uint32_t size = 0x78;
|
||||
|
||||
error = MM::Native::NewPtr(size, true, devptr);
|
||||
|
||||
if (error) return error;
|
||||
|
||||
memoryWriteLong(0x46535953, devptr + 0); // 'FSYS'
|
||||
memoryWriteLong(fptr + 4, devptr + 4);
|
||||
memoryWriteLong(fptr + 8, devptr + 8);
|
||||
memoryWriteLong(fptr + 12, devptr + 12);
|
||||
memoryWriteLong(fptr + 16, devptr + 16);
|
||||
memoryWriteLong(fptr + 20, devptr + 20);
|
||||
|
||||
memoryWriteLong(0x45434f4e, devptr + 24); // 'ECON' -- not implemented.
|
||||
memoryWriteLong(0x53595354, devptr + 48); // 'SYST' -- not implemented.
|
||||
|
||||
}
|
||||
|
||||
// io table.
|
||||
{
|
||||
|
||||
uint32_t size = 0x3c;
|
||||
uint32_t ptr;
|
||||
|
||||
error = MM::Native::NewPtr(size, true, ioptr);
|
||||
|
||||
if (error) return error;
|
||||
|
||||
ptr = ioptr;
|
||||
// stdin
|
||||
memoryWriteWord(0x0001, ptr + 0); // open flags (read)
|
||||
memoryWriteWord(0x0000, ptr + 2); // os err
|
||||
memoryWriteLong(devptr, ptr + 4); // -> 'FSYS'
|
||||
memoryWriteLong(STDIN_FILENO, ptr + 8); // cookie
|
||||
memoryWriteLong(0, ptr + 12); // transfer count.
|
||||
memoryWriteLong(0, ptr + 16); // buffer
|
||||
|
||||
ptr = ioptr + 20;
|
||||
// stdout
|
||||
memoryWriteWord(0x0002, ptr + 0); // open flags (write)
|
||||
memoryWriteWord(0x0000, ptr + 2); // os err
|
||||
memoryWriteLong(devptr, ptr + 4); // -> 'FSYS'
|
||||
memoryWriteLong(STDOUT_FILENO, ptr + 8); // cookie
|
||||
memoryWriteLong(0, ptr + 12); // transfer count.
|
||||
memoryWriteLong(0, ptr + 16); // buffer
|
||||
|
||||
ptr = ioptr + 40;
|
||||
// stderr
|
||||
memoryWriteWord(0x0002, ptr + 0); // open flags (write)
|
||||
memoryWriteWord(0x0000, ptr + 2); // os err
|
||||
memoryWriteLong(devptr, ptr + 4); // -> 'FSYS'
|
||||
memoryWriteLong(STDERR_FILENO, ptr + 8); // cookie
|
||||
memoryWriteLong(0, ptr + 12); // transfer count.
|
||||
memoryWriteLong(0, ptr + 16); // buffer
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t mpi = 0;
|
||||
|
||||
error = MM::Native::NewPtr(8 + 0x30, true, mpi);
|
||||
if (error) return error;
|
||||
|
||||
MacProgramInfo = mpi + 8;
|
||||
|
||||
memoryWriteLong(0x4d50474d, mpi); // 'MPGM' - magic
|
||||
memoryWriteLong(mpi + 8, mpi + 4);
|
||||
|
||||
memoryWriteLong(mpi, 0x0316);
|
||||
|
||||
mpi += 8;
|
||||
memoryWriteWord(0x5348, mpi + 0x00); // 'SH' - more magic
|
||||
|
||||
memoryWriteLong(argc, mpi + 0x02);
|
||||
memoryWriteLong(argvptr, mpi + 0x06);
|
||||
memoryWriteLong(envptr, mpi + 0x0a);
|
||||
|
||||
// 0x0e = exit code
|
||||
|
||||
// ??? default fd table size?
|
||||
memoryWriteWord(0x190, mpi + 0x1a);
|
||||
|
||||
// io table - stdin/stdout/stderr
|
||||
memoryWriteLong(ioptr, mpi + 0x1c);
|
||||
|
||||
// device table
|
||||
memoryWriteLong(devptr, mpi + 0x20);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ExitStatus()
|
||||
{
|
||||
if (!MacProgramInfo) return -1;
|
||||
|
||||
return memoryReadLong(MacProgramInfo + 0x0e);
|
||||
}
|
||||
|
||||
|
||||
|
|
20
mpw/mpw.h
20
mpw/mpw.h
|
@ -2,6 +2,8 @@
|
|||
#define __mpw_mpw_h__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace MPW {
|
||||
|
||||
|
@ -29,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 " " " " " " */
|
||||
|
@ -91,9 +93,19 @@ 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...
|
||||
void Init();
|
||||
uint16_t InitEnvironment(const std::vector<std::string> &defines);
|
||||
uint16_t Init(int argc, char **argv);
|
||||
|
||||
uint32_t ExitStatus();
|
||||
|
||||
|
||||
|
||||
void dispatch(uint16_t trap);
|
||||
|
@ -108,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"
|
||||
|
@ -13,22 +39,162 @@
|
|||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/paths.h>
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
using namespace Internal;
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
sname = ToolBox::ReadCString(name, true);
|
||||
|
||||
Log(" delete(%s)\n", sname.c_str());
|
||||
|
||||
rv = ::unlink(sname.c_str());
|
||||
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;
|
||||
|
@ -36,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);
|
||||
|
@ -64,24 +230,40 @@ namespace MPW
|
|||
|
||||
|
||||
sname = ToolBox::ReadCString(name, true);
|
||||
std::string xname = sname;
|
||||
|
||||
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)
|
||||
{
|
||||
// why the 0x40... ??
|
||||
d0 = 0x40000000 | errno_to_errno(errno);
|
||||
f.error = -36; // ioErr ... whatever.
|
||||
// return an errno.
|
||||
d0 = 0x40000000 | mpw_errno_from_errno();
|
||||
f.error = MacOS::ioErr;
|
||||
f.cookie = 0;
|
||||
}
|
||||
else
|
||||
|
@ -90,21 +272,20 @@ namespace MPW
|
|||
f.error = 0;
|
||||
f.cookie = fd;
|
||||
|
||||
if (FDTable.size() <= fd)
|
||||
FDTable.resize(fd + 1);
|
||||
|
||||
FDTable[fd] = 1;
|
||||
|
||||
|
||||
// adjust the binary flags...
|
||||
// most apps are good about this but dumpobj doesn't set O_BINARY (but should)
|
||||
// and MPW Assembler sets O_BINARY (but shouldn't)
|
||||
// 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)
|
||||
|
||||
if (OS::IsTextFile(sname)) f.flags &= ~kO_BINARY;
|
||||
if (OS::IsBinaryFile(sname)) f.flags |= kO_BINARY;
|
||||
|
||||
if (f.flags & kO_RSRC) f.flags |= kO_BINARY;
|
||||
|
||||
auto &e = OS::Internal::FDEntry::allocate(fd, std::move(xname));
|
||||
e.text = !(f.flags & kO_BINARY);
|
||||
e.resource = f.flags & kO_RSRC;
|
||||
}
|
||||
|
||||
memoryWriteWord(f.flags, parm + 0);
|
||||
|
@ -114,6 +295,7 @@ namespace MPW
|
|||
return d0;
|
||||
}
|
||||
|
||||
|
||||
void ftrap_access(uint16_t trap)
|
||||
{
|
||||
// open a file, rename a file, or delete a file.
|
||||
|
@ -129,20 +311,47 @@ namespace MPW
|
|||
uint32_t parm = memoryReadLong(sp + 12);
|
||||
|
||||
Log("%04x Access(%08x, %04x, %08x)\n", trap, name, op, parm);
|
||||
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case kF_OPEN:
|
||||
d0 = ftrap_open(name, parm);
|
||||
break;
|
||||
|
||||
case kF_DELETE:
|
||||
d0 = ftrap_delete(name);
|
||||
break;
|
||||
|
||||
case kF_RENAME:
|
||||
d0 = ftrap_rename(name, parm);
|
||||
break;
|
||||
|
||||
case kF_GTABINFO:
|
||||
d0 = ftrap_get_tab_info(name, parm);
|
||||
break;
|
||||
|
||||
case kF_STABINFO:
|
||||
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);
|
||||
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,14 +36,16 @@
|
|||
|
||||
#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>
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
void ftrap_close(uint16_t trap)
|
||||
{
|
||||
|
@ -25,7 +53,7 @@ namespace MPW
|
|||
// close actually checks the error in the File Entry and converts that to unix.
|
||||
// (sigh)
|
||||
|
||||
uint32_t d0;
|
||||
uint32_t d0 = 0;
|
||||
|
||||
uint32_t sp = cpuGetAReg(7);
|
||||
uint32_t parm = memoryReadLong(sp + 4);
|
||||
|
@ -51,21 +79,46 @@ namespace MPW
|
|||
|
||||
int fd = f.cookie;
|
||||
|
||||
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||
int rv = OS::Internal::FDEntry::close(fd);
|
||||
|
||||
if (rv < 0)
|
||||
{
|
||||
f.error = MacOS::notOpenErr;
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
f.error = 0;
|
||||
d0 = 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
if (fd < 0 || fd >= OS::Internal::FDTable.size())
|
||||
{
|
||||
f.error = OS::notOpenErr;
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--FDTable[fd] == 0)
|
||||
auto &e = OS::Internal::FDTable[fd];
|
||||
if (e.refcount == 0)
|
||||
{
|
||||
Log(" close(%02x)\n", fd);
|
||||
::close(fd);
|
||||
f.error = OS::notOpenErr;
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--e.refcount == 0)
|
||||
{
|
||||
Log(" close(%02x)\n", fd);
|
||||
::close(fd);
|
||||
}
|
||||
f.error = 0;
|
||||
d0 = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
cpuSetDReg(0, 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,12 +13,6 @@ namespace MPW
|
|||
if (Trace) fprintf(stderr, format, args...);
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
// for dup counts, etc.
|
||||
extern std::vector<int> FDTable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
160
mpw/mpw_io.cpp
160
mpw/mpw_io.cpp
|
@ -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,15 +38,17 @@
|
|||
|
||||
#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>
|
||||
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
void ftrap_read(uint16_t trap)
|
||||
{
|
||||
|
@ -39,54 +68,31 @@ namespace MPW
|
|||
f.buffer = memoryReadLong(parm + 16);
|
||||
|
||||
|
||||
Log("%04x Read(%08x)\n", parm);
|
||||
Log("%04x Read(%08x)\n", trap, parm);
|
||||
|
||||
d0 = 0;
|
||||
int fd = f.cookie;
|
||||
ssize_t size;
|
||||
|
||||
if (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);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
ssize_t size;
|
||||
|
||||
int fd = f.cookie;
|
||||
|
||||
Log(" read(%02x, %08x, %08x)\n", f.cookie, f.buffer, f.count);
|
||||
|
||||
|
||||
if (f.flags & kO_BINARY)
|
||||
{
|
||||
size = ::read(fd, memoryPointer(f.buffer), f.count);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unique_ptr<uint8_t[]> buffer(new uint8_t[f.count]);
|
||||
uint8_t *ptr = memoryPointer(f.buffer);
|
||||
|
||||
size = ::read(fd, buffer.get(), f.count);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
std::transform(buffer.get(), buffer.get() + size, ptr,
|
||||
[](uint8_t c) { return c == '\n' ? '\r' : c; }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
//f.count = 0;
|
||||
f.error = OS::ioErr; // ioErr
|
||||
d0 = 0x40000000 | errno_to_errno(errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
f.count -= size;
|
||||
f.error = 0;
|
||||
}
|
||||
|
||||
// write back...
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
memoryWriteLong(f.count, parm + 12);
|
||||
//f.count = 0;
|
||||
f.error = MacOS::ioErr; // ioErr
|
||||
d0 = mpw_errno_from_errno();
|
||||
}
|
||||
else
|
||||
{
|
||||
f.count -= size;
|
||||
f.error = 0;
|
||||
}
|
||||
|
||||
// write back...
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
memoryWriteLong(f.count, parm + 12);
|
||||
|
||||
cpuSetDReg(0, d0);
|
||||
}
|
||||
|
@ -111,49 +117,29 @@ namespace MPW
|
|||
|
||||
|
||||
d0 = 0;
|
||||
if (f.count)
|
||||
int fd = f.cookie;
|
||||
ssize_t size;
|
||||
|
||||
Log(" write(%04x, %08x, %08x)\n", fd, f.buffer, f.count);
|
||||
size = OS::Internal::FDEntry::write(fd, memoryPointer(f.buffer), f.count);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
ssize_t size;
|
||||
|
||||
int fd = f.cookie;
|
||||
|
||||
Log(" write(%02x, %08x, %08x)\n", f.cookie, f.buffer, f.count);
|
||||
|
||||
|
||||
if (f.flags & kO_BINARY)
|
||||
{
|
||||
size = ::write(fd, memoryPointer(f.buffer), f.count);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unique_ptr<uint8_t[]> buffer(new uint8_t[f.count]);
|
||||
uint8_t *ptr = memoryPointer(f.buffer);
|
||||
|
||||
std::transform(ptr, ptr + f.count, buffer.get(),
|
||||
[](uint8_t c) { return c == '\r' ? '\n' : c; }
|
||||
);
|
||||
|
||||
size = ::write(fd, buffer.get(), f.count);
|
||||
}
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
//f.count = 0;
|
||||
f.error = -36; // ioErr
|
||||
d0 = 0x40000000 | errno_to_errno(errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is, apparently, correct.
|
||||
f.count -= size;
|
||||
f.error = 0;
|
||||
}
|
||||
|
||||
// write back...
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
memoryWriteLong(f.count, parm + 12);
|
||||
//f.count = 0;
|
||||
f.error = MacOS::ioErr; // ioErr
|
||||
d0 = mpw_errno_from_errno();
|
||||
}
|
||||
cpuSetDReg(0, d0);
|
||||
else
|
||||
{
|
||||
f.count -= size;
|
||||
f.error = 0;
|
||||
}
|
||||
|
||||
// write back...
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
memoryWriteLong(f.count, parm + 12);
|
||||
|
||||
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"
|
||||
|
@ -5,6 +31,7 @@
|
|||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
@ -17,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
|
||||
{
|
||||
using namespace Internal;
|
||||
|
||||
|
||||
uint32_t ftrap_dup(uint32_t parm, uint32_t arg)
|
||||
{
|
||||
uint32_t d0;
|
||||
|
@ -46,15 +76,37 @@ namespace MPW
|
|||
|
||||
Log(" dup(%02x)\n", fd);
|
||||
|
||||
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||
|
||||
d0 = OS::Internal::FDEntry::action(fd,
|
||||
[](int fd, OS::Internal::FDEntry &e){
|
||||
e.refcount++;
|
||||
return 0;
|
||||
},
|
||||
[](int fd){
|
||||
return kEINVAL;
|
||||
}
|
||||
);
|
||||
|
||||
#if 0
|
||||
try
|
||||
{
|
||||
d0 = kEINVAL; // | 0x40000000 ?
|
||||
auto &e = OS::Internal::FDTable.at(fd);
|
||||
|
||||
if (e.refcount)
|
||||
{
|
||||
d0 = 0;
|
||||
fd.refcount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
catch(std::out_of_range &ex)
|
||||
{
|
||||
FDTable[fd]++;
|
||||
d0 = 0;
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
return d0;
|
||||
|
@ -87,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;
|
||||
|
@ -101,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;
|
||||
|
@ -111,21 +163,37 @@ namespace MPW
|
|||
|
||||
Log(" interactive(%02x)\n", fd);
|
||||
|
||||
//d0 = kEINVAL;
|
||||
d0 = OS::Internal::FDEntry::action(fd,
|
||||
[](int fd, OS::Internal::FDEntry &e){
|
||||
|
||||
// linkgs reads from stdin and
|
||||
// doesn't work quite right when
|
||||
// this returns 0. So, don't.
|
||||
int tty = ::isatty(fd);
|
||||
return tty ? 0 : kEINVAL;
|
||||
},
|
||||
[](int fd){
|
||||
return kEINVAL;
|
||||
}
|
||||
);
|
||||
|
||||
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||
#if 0
|
||||
try
|
||||
{
|
||||
auto &e = OS::Internal::FDTable.at(fd);
|
||||
|
||||
if (e.refcount)
|
||||
{
|
||||
int tty = ::isatty(fd);
|
||||
d0 = tty ? 0 : kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
}
|
||||
catch(std::out_of_range &ex)
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int tty = ::isatty(fd);
|
||||
d0 = tty ? 0 : kEINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
return d0;
|
||||
|
@ -175,6 +243,17 @@ namespace MPW
|
|||
|
||||
Log(" refnum(%02x)\n", fd);
|
||||
|
||||
d0 = OS::Internal::FDEntry::action(fd,
|
||||
[arg](int fd, OS::Internal::FDEntry &e){
|
||||
memoryWriteWord(fd, arg);
|
||||
return 0;
|
||||
},
|
||||
[](int fd){
|
||||
return kEINVAL;
|
||||
}
|
||||
);
|
||||
|
||||
#if 0
|
||||
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
|
@ -184,6 +263,7 @@ namespace MPW
|
|||
d0 = 0;
|
||||
memoryWriteWord(fd, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
return d0;
|
||||
|
@ -255,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
|
||||
{
|
||||
|
@ -271,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 [???]
|
||||
|
@ -312,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;
|
||||
}
|
||||
|
@ -321,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,18 +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_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
|
||||
mpw_time.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)
|
||||
|
|
139
toolbox/complex.h
Normal file
139
toolbox/complex.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
#ifndef __complex_h__
|
||||
#define __complex_h__
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
// comp is an int64_t but 0x8000_0000_0000_0000 is NaN
|
||||
//typedef int64_t complex;
|
||||
|
||||
struct complex {
|
||||
|
||||
public:
|
||||
const uint64_t NaN = 0x8000000000000000;
|
||||
|
||||
complex(const complex &rhs) = default;
|
||||
|
||||
complex(uint64_t rhs) : _data(rhs)
|
||||
{}
|
||||
|
||||
template <class T>
|
||||
complex(T t)
|
||||
{
|
||||
*this = t;
|
||||
}
|
||||
|
||||
bool isnan() const
|
||||
{
|
||||
return _data == NaN;
|
||||
}
|
||||
|
||||
complex &operator=(const complex &rhs) = default;
|
||||
|
||||
complex &operator=(uint64_t rhs)
|
||||
{
|
||||
_data = rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
complex &operator=(T ld)
|
||||
{
|
||||
switch(std::fpclassify(ld))
|
||||
{
|
||||
case FP_NAN:
|
||||
_data = NaN;
|
||||
break;
|
||||
case FP_INFINITE:
|
||||
if (std::signbit(ld))
|
||||
{
|
||||
_data = -INT64_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
_data = INT64_MAX;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_data = ld;
|
||||
break;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
operator uint64_t() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
operator int64_t() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
operator long double() const {
|
||||
if (_data == NaN)
|
||||
return NAN;
|
||||
return _data;
|
||||
}
|
||||
|
||||
operator double() const {
|
||||
if (_data == NaN)
|
||||
return NAN;
|
||||
return _data;
|
||||
}
|
||||
|
||||
operator float() const {
|
||||
if (_data == NaN)
|
||||
return NAN;
|
||||
return _data;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
int64_t _data = 0;
|
||||
|
||||
};
|
||||
|
||||
namespace its_complicated {
|
||||
|
||||
|
||||
std::string to_string(complex c)
|
||||
{
|
||||
if (c.isnan()) return std::string("nan");
|
||||
|
||||
return std::to_string((int64_t)c);
|
||||
}
|
||||
|
||||
inline int fpclassify(complex c) {
|
||||
if (c.isnan()) return FP_NAN;
|
||||
if ((uint64_t)c == (uint64_t)0) return FP_ZERO;
|
||||
return FP_NORMAL;
|
||||
}
|
||||
|
||||
inline int signbit(complex c) {
|
||||
if (c.isnan()) return 0;
|
||||
return ((int64_t)c < (int64_t)0) ? 1 : 0;
|
||||
}
|
||||
|
||||
inline int isnan(complex c) {
|
||||
return c.isnan();
|
||||
}
|
||||
|
||||
inline int isinf(complex c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline int isfinite(complex c) {
|
||||
if (c.isnan()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int isnormal(complex c) {
|
||||
if (c.isnan()) return false;
|
||||
if ((uint64_t)c == 0) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user