openc166 0.1.15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openc166-0.1.15/.gitattributes +2 -0
- openc166-0.1.15/.github/workflows/ci.yml +41 -0
- openc166-0.1.15/.github/workflows/wheels.yml +185 -0
- openc166-0.1.15/.gitignore +22 -0
- openc166-0.1.15/CMakeLists.txt +61 -0
- openc166-0.1.15/LICENSE +21 -0
- openc166-0.1.15/PKG-INFO +308 -0
- openc166-0.1.15/README.md +285 -0
- openc166-0.1.15/cli/CMakeLists.txt +10 -0
- openc166-0.1.15/cli/main.cpp +260 -0
- openc166-0.1.15/cmake/embed_files.cmake +24 -0
- openc166-0.1.15/docs/compatibility.md +1160 -0
- openc166-0.1.15/docs/phase1-feasibility.md +424 -0
- openc166-0.1.15/docs/releasing.md +73 -0
- openc166-0.1.15/docs/tasking.md +170 -0
- openc166-0.1.15/examples/mtos/README.md +43 -0
- openc166-0.1.15/examples/mtos/bsl_shim.a66 +26 -0
- openc166-0.1.15/examples/mtos/driver_patch.a66 +26 -0
- openc166-0.1.15/examples/mtos/kline_hello.a66 +35 -0
- openc166-0.1.15/examples/mtos/loader.a66 +52 -0
- openc166-0.1.15/examples/mtos/marker.a66 +18 -0
- openc166-0.1.15/examples/mtos/memory_dump.a66 +33 -0
- openc166-0.1.15/examples/mtos/stage2_hello.a66 +28 -0
- openc166-0.1.15/examples/payload.a66 +26 -0
- openc166-0.1.15/examples/sections.a66 +25 -0
- openc166-0.1.15/inc/REG167.INC +631 -0
- openc166-0.1.15/include/openc166/openc166.h +300 -0
- openc166-0.1.15/pyproject.toml +65 -0
- openc166-0.1.15/python/openc166/__init__.py +574 -0
- openc166-0.1.15/python/openc166/_native.py +155 -0
- openc166-0.1.15/python/openc166/py.typed +0 -0
- openc166-0.1.15/python/tests/test_openc166.py +503 -0
- openc166-0.1.15/src/CMakeLists.txt +99 -0
- openc166-0.1.15/src/assembler.cpp +4714 -0
- openc166-0.1.15/src/assembler.hpp +192 -0
- openc166-0.1.15/src/bundled.cpp +35 -0
- openc166-0.1.15/src/bundled.hpp +19 -0
- openc166-0.1.15/src/capi.cpp +377 -0
- openc166-0.1.15/src/capi.map +5 -0
- openc166-0.1.15/src/diag.hpp +60 -0
- openc166-0.1.15/src/encode.cpp +414 -0
- openc166-0.1.15/src/encode.hpp +60 -0
- openc166-0.1.15/src/expr.cpp +650 -0
- openc166-0.1.15/src/expr.hpp +134 -0
- openc166-0.1.15/src/isa/c166.tbl +368 -0
- openc166-0.1.15/src/isa/isa.cpp +39 -0
- openc166-0.1.15/src/isa/isa.hpp +32 -0
- openc166-0.1.15/src/isa/isa_types.hpp +135 -0
- openc166-0.1.15/src/lexer.cpp +144 -0
- openc166-0.1.15/src/lexer.hpp +42 -0
- openc166-0.1.15/src/m166.cpp +559 -0
- openc166-0.1.15/src/m166.hpp +68 -0
- openc166-0.1.15/src/operand.cpp +62 -0
- openc166-0.1.15/src/operand.hpp +33 -0
- openc166-0.1.15/src/output.cpp +151 -0
- openc166-0.1.15/src/predef.cpp +306 -0
- openc166-0.1.15/src/predef.hpp +51 -0
- openc166-0.1.15/src/value.hpp +109 -0
- openc166-0.1.15/tests/CMakeLists.txt +152 -0
- openc166-0.1.15/tests/acceptance/minimon.py +269 -0
- openc166-0.1.15/tests/capi/test_capi.c +425 -0
- openc166-0.1.15/tests/check_binary.cmake +23 -0
- openc166-0.1.15/tests/diff/cases/alignment.a66 +83 -0
- openc166-0.1.15/tests/diff/cases/bit_section_errors.a66 +72 -0
- openc166-0.1.15/tests/diff/cases/bit_sections.a66 +91 -0
- openc166-0.1.15/tests/diff/cases/bits.a66 +102 -0
- openc166-0.1.15/tests/diff/cases/branches.a66 +135 -0
- openc166-0.1.15/tests/diff/cases/cond.a66 +255 -0
- openc166-0.1.15/tests/diff/cases/cond_errors.a66 +117 -0
- openc166-0.1.15/tests/diff/cases/controls.a66 +29 -0
- openc166-0.1.15/tests/diff/cases/defs.a66 +131 -0
- openc166-0.1.15/tests/diff/cases/directives.a66 +109 -0
- openc166-0.1.15/tests/diff/cases/dpp.a66 +129 -0
- openc166-0.1.15/tests/diff/cases/expressions.a66 +92 -0
- openc166-0.1.15/tests/diff/cases/group_errors.a66 +80 -0
- openc166-0.1.15/tests/diff/cases/groups.a66 +108 -0
- openc166-0.1.15/tests/diff/cases/inc/code.inc +4 -0
- openc166-0.1.15/tests/diff/cases/inc/comments.inc +2 -0
- openc166-0.1.15/tests/diff/cases/inc/count.inc +2 -0
- openc166-0.1.15/tests/diff/cases/inc/crlf.inc +3 -0
- openc166-0.1.15/tests/diff/cases/inc/ignored.inc +2 -0
- openc166-0.1.15/tests/diff/cases/inc/lit.inc +3 -0
- openc166-0.1.15/tests/diff/cases/inc/nested.inc +4 -0
- openc166-0.1.15/tests/diff/cases/inc/noeol.inc +2 -0
- openc166-0.1.15/tests/diff/cases/inc/regs.inc +6 -0
- openc166-0.1.15/tests/diff/cases/inc/sub/deep.inc +3 -0
- openc166-0.1.15/tests/diff/cases/inc/sub/level3.inc +1 -0
- openc166-0.1.15/tests/diff/cases/include.a66 +30 -0
- openc166-0.1.15/tests/diff/cases/link/bits/1main.a66 +38 -0
- openc166-0.1.15/tests/diff/cases/link/bits/2lib.a66 +29 -0
- openc166-0.1.15/tests/diff/cases/link/bits/3more.a66 +25 -0
- openc166-0.1.15/tests/diff/cases/link/calls/1main.a66 +39 -0
- openc166-0.1.15/tests/diff/cases/link/calls/2lib.a66 +40 -0
- openc166-0.1.15/tests/diff/cases/link/combine/1first.a66 +42 -0
- openc166-0.1.15/tests/diff/cases/link/combine/2second.a66 +33 -0
- openc166-0.1.15/tests/diff/cases/link/combine/3third.a66 +36 -0
- openc166-0.1.15/tests/diff/cases/link/fixups/1use.a66 +35 -0
- openc166-0.1.15/tests/diff/cases/link/fixups/2def.a66 +28 -0
- openc166-0.1.15/tests/diff/cases/link/groups/1main.a66 +45 -0
- openc166-0.1.15/tests/diff/cases/link/groups/2lib.a66 +34 -0
- openc166-0.1.15/tests/diff/cases/link/mixed/1seg.a66 +14 -0
- openc166-0.1.15/tests/diff/cases/link/mixed/2flat.a66 +11 -0
- openc166-0.1.15/tests/diff/cases/link/mixed/3seg.a66 +12 -0
- openc166-0.1.15/tests/diff/cases/link/regbanks/1main.a66 +39 -0
- openc166-0.1.15/tests/diff/cases/link/regbanks/2lib.a66 +25 -0
- openc166-0.1.15/tests/diff/cases/link/sections/1first.a66 +25 -0
- openc166-0.1.15/tests/diff/cases/link/sections/2second.a66 +22 -0
- openc166-0.1.15/tests/diff/cases/link/sections/3third.a66 +13 -0
- openc166-0.1.15/tests/diff/cases/link/segmented/1main.a66 +34 -0
- openc166-0.1.15/tests/diff/cases/link/segmented/2lib.a66 +25 -0
- openc166-0.1.15/tests/diff/cases/link/unresolved/1main.a66 +16 -0
- openc166-0.1.15/tests/diff/cases/link/unresolved/2one.a66 +12 -0
- openc166-0.1.15/tests/diff/cases/link/unresolved/3two.a66 +11 -0
- openc166-0.1.15/tests/diff/cases/link/values/1use.a66 +29 -0
- openc166-0.1.15/tests/diff/cases/link/values/2def.a66 +28 -0
- openc166-0.1.15/tests/diff/cases/lit.a66 +64 -0
- openc166-0.1.15/tests/diff/cases/lit_errors.a66 +38 -0
- openc166-0.1.15/tests/diff/cases/locate.a66 +129 -0
- openc166-0.1.15/tests/diff/cases/macro_args.a66 +64 -0
- openc166-0.1.15/tests/diff/cases/macro_errors.a66 +63 -0
- openc166-0.1.15/tests/diff/cases/macros.a66 +133 -0
- openc166-0.1.15/tests/diff/cases/operands.a66 +119 -0
- openc166-0.1.15/tests/diff/cases/primary.a66 +34 -0
- openc166-0.1.15/tests/diff/cases/redefine.a66 +74 -0
- openc166-0.1.15/tests/diff/cases/regbank_errors.a66 +82 -0
- openc166-0.1.15/tests/diff/cases/regbanks.a66 +51 -0
- openc166-0.1.15/tests/diff/cases/reloc.a66 +157 -0
- openc166-0.1.15/tests/diff/cases/section_errors.a66 +178 -0
- openc166-0.1.15/tests/diff/cases/section_length.a66 +91 -0
- openc166-0.1.15/tests/diff/cases/segmented.a66 +175 -0
- openc166-0.1.15/tests/diff/cases/type_operator_errors.a66 +49 -0
- openc166-0.1.15/tests/diff/cases/type_operators.a66 +87 -0
- openc166-0.1.15/tests/diff/gen_sweep.py +77 -0
- openc166-0.1.15/tests/diff/keil_diff.py +664 -0
- openc166-0.1.15/tests/expected/driver_patch.hex +4 -0
- openc166-0.1.15/tests/expected/driver_patch.s28 +5 -0
- openc166-0.1.15/tests/expected/payload.srec +6 -0
- openc166-0.1.15/tests/unit/helpers.hpp +60 -0
- openc166-0.1.15/tests/unit/main.cpp +3 -0
- openc166-0.1.15/tests/unit/test_assembler.cpp +271 -0
- openc166-0.1.15/tests/unit/test_bits.cpp +239 -0
- openc166-0.1.15/tests/unit/test_branches.cpp +288 -0
- openc166-0.1.15/tests/unit/test_cond.cpp +232 -0
- openc166-0.1.15/tests/unit/test_defs.cpp +193 -0
- openc166-0.1.15/tests/unit/test_dpp.cpp +246 -0
- openc166-0.1.15/tests/unit/test_encode.cpp +100 -0
- openc166-0.1.15/tests/unit/test_expr.cpp +263 -0
- openc166-0.1.15/tests/unit/test_groups.cpp +175 -0
- openc166-0.1.15/tests/unit/test_include.cpp +293 -0
- openc166-0.1.15/tests/unit/test_lexer.cpp +77 -0
- openc166-0.1.15/tests/unit/test_link.cpp +184 -0
- openc166-0.1.15/tests/unit/test_lit.cpp +253 -0
- openc166-0.1.15/tests/unit/test_macros.cpp +292 -0
- openc166-0.1.15/tests/unit/test_output.cpp +114 -0
- openc166-0.1.15/tests/unit/test_regbanks.cpp +121 -0
- openc166-0.1.15/tests/unit/test_sections.cpp +221 -0
- openc166-0.1.15/tests/unit/test_tasking.cpp +287 -0
- openc166-0.1.15/third_party/doctest/LICENSE.txt +21 -0
- openc166-0.1.15/third_party/doctest/doctest.h +7106 -0
- openc166-0.1.15/tools/CMakeLists.txt +5 -0
- openc166-0.1.15/tools/isagen.cpp +432 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
# Pushes to main run this from the release workflow (wheels.yml) instead.
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches-ignore: [main]
|
|
7
|
+
pull_request:
|
|
8
|
+
workflow_call:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
name: ${{ matrix.os }}
|
|
16
|
+
runs-on: ${{ matrix.os }}
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v7
|
|
23
|
+
- name: Configure
|
|
24
|
+
# MSVC warnings have not been reviewed yet, so they do not fail the build.
|
|
25
|
+
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DOPENC166_WERROR=${{ runner.os != 'Windows' }}
|
|
26
|
+
- name: Build
|
|
27
|
+
run: cmake --build build --config Release --parallel
|
|
28
|
+
- name: Test
|
|
29
|
+
run: ctest --test-dir build --build-config Release --output-on-failure
|
|
30
|
+
|
|
31
|
+
sanitizers:
|
|
32
|
+
name: ubuntu-latest (ASan + UBSan)
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v7
|
|
36
|
+
- name: Configure
|
|
37
|
+
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DOPENC166_WERROR=ON -DOPENC166_SANITIZE=ON
|
|
38
|
+
- name: Build
|
|
39
|
+
run: cmake --build build --parallel
|
|
40
|
+
- name: Test
|
|
41
|
+
run: ctest --test-dir build --output-on-failure
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Builds and tests the Python packages (sdist and wheels) on every push to
|
|
2
|
+
# main and every pull request. Every push to main is also released: once CI
|
|
3
|
+
# and the packages pass, they go to PyPI and to a GitHub release. See
|
|
4
|
+
# docs/releasing.md.
|
|
5
|
+
name: Build and release
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
pull_request:
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
version:
|
|
18
|
+
name: Version
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
outputs:
|
|
21
|
+
version: ${{ steps.version.outputs.version }}
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v7
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
- name: Work out the version
|
|
28
|
+
id: version
|
|
29
|
+
env:
|
|
30
|
+
EVENT: ${{ github.event_name }}
|
|
31
|
+
# x.y.z from CMakeLists.txt, with z raised by the number of commits
|
|
32
|
+
# since the commit that last changed that version.
|
|
33
|
+
run: |
|
|
34
|
+
base=$(perl -0777 -ne 'print $1 if /project\(openc166\s+VERSION\s+([0-9]+\.[0-9]+\.[0-9]+)/' CMakeLists.txt)
|
|
35
|
+
if [ -z "$base" ]; then
|
|
36
|
+
echo "::error::CMakeLists.txt has no project(openc166 VERSION x.y.z)"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
IFS=. read -r major minor patch <<< "$base"
|
|
40
|
+
since=$(git log -1 --format=%H -G 'VERSION [0-9][0-9]*[.][0-9][0-9]*[.][0-9]' -- CMakeLists.txt)
|
|
41
|
+
count=$(git rev-list --count "$since..HEAD")
|
|
42
|
+
version="$major.$minor.$((patch + count))"
|
|
43
|
+
if [ "$EVENT" = push ] &&
|
|
44
|
+
tagged=$(git rev-parse -q --verify "refs/tags/v$version^{commit}") &&
|
|
45
|
+
[ "$tagged" != "$(git rev-parse HEAD)" ]; then
|
|
46
|
+
echo "::error::v$version was already released from another commit; raise the version in CMakeLists.txt"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
50
|
+
echo "Version $version" >> "$GITHUB_STEP_SUMMARY"
|
|
51
|
+
|
|
52
|
+
sdist:
|
|
53
|
+
name: Source package
|
|
54
|
+
needs: version
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
env:
|
|
57
|
+
VERSION: ${{ needs.version.outputs.version }}
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v7
|
|
60
|
+
with:
|
|
61
|
+
persist-credentials: false
|
|
62
|
+
- name: Set the version
|
|
63
|
+
shell: bash
|
|
64
|
+
run: |
|
|
65
|
+
perl -0777 -pi.orig -e 's/(project\(openc166\s+VERSION\s+)[0-9][0-9.]*/${1}$ENV{VERSION}/' CMakeLists.txt
|
|
66
|
+
rm CMakeLists.txt.orig
|
|
67
|
+
set=$(perl -0777 -ne 'print $1 if /project\(openc166\s+VERSION\s+([0-9.]+)/' CMakeLists.txt)
|
|
68
|
+
if [ "$set" != "$VERSION" ]; then
|
|
69
|
+
echo "::error::Could not set the version in CMakeLists.txt"
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
- uses: actions/setup-python@v7
|
|
73
|
+
with:
|
|
74
|
+
python-version: "3.x"
|
|
75
|
+
- name: Build
|
|
76
|
+
run: |
|
|
77
|
+
python -m pip install build twine
|
|
78
|
+
python -m build --sdist
|
|
79
|
+
python -m twine check --strict dist/*
|
|
80
|
+
test -f "dist/openc166-$VERSION.tar.gz"
|
|
81
|
+
- name: Install and test
|
|
82
|
+
env:
|
|
83
|
+
OPENC166_TEST_COMMAND: "1"
|
|
84
|
+
run: |
|
|
85
|
+
python -m pip install dist/*.tar.gz
|
|
86
|
+
python -m unittest discover -s python/tests -v
|
|
87
|
+
- uses: actions/upload-artifact@v7
|
|
88
|
+
with:
|
|
89
|
+
name: sdist
|
|
90
|
+
path: dist/*.tar.gz
|
|
91
|
+
|
|
92
|
+
wheels:
|
|
93
|
+
name: Wheels (${{ matrix.os }})
|
|
94
|
+
needs: version
|
|
95
|
+
runs-on: ${{ matrix.os }}
|
|
96
|
+
env:
|
|
97
|
+
VERSION: ${{ needs.version.outputs.version }}
|
|
98
|
+
strategy:
|
|
99
|
+
fail-fast: false
|
|
100
|
+
matrix:
|
|
101
|
+
# Linux x86-64 and ARM64 (glibc and musl), Windows x64, x86 and ARM64,
|
|
102
|
+
# macOS Intel and Apple silicon (see [tool.cibuildwheel] in pyproject.toml).
|
|
103
|
+
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-latest]
|
|
104
|
+
steps:
|
|
105
|
+
- uses: actions/checkout@v7
|
|
106
|
+
with:
|
|
107
|
+
persist-credentials: false
|
|
108
|
+
- name: Set the version
|
|
109
|
+
shell: bash
|
|
110
|
+
run: |
|
|
111
|
+
perl -0777 -pi.orig -e 's/(project\(openc166\s+VERSION\s+)[0-9][0-9.]*/${1}$ENV{VERSION}/' CMakeLists.txt
|
|
112
|
+
rm CMakeLists.txt.orig
|
|
113
|
+
set=$(perl -0777 -ne 'print $1 if /project\(openc166\s+VERSION\s+([0-9.]+)/' CMakeLists.txt)
|
|
114
|
+
if [ "$set" != "$VERSION" ]; then
|
|
115
|
+
echo "::error::Could not set the version in CMakeLists.txt"
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
- uses: pypa/cibuildwheel@v4.3.5
|
|
119
|
+
- uses: actions/upload-artifact@v7
|
|
120
|
+
with:
|
|
121
|
+
name: wheels-${{ matrix.os }}
|
|
122
|
+
path: wheelhouse/*.whl
|
|
123
|
+
|
|
124
|
+
# The CI workflow (.github/workflows/ci.yml): nothing is released unless it
|
|
125
|
+
# passes.
|
|
126
|
+
ci:
|
|
127
|
+
name: CI
|
|
128
|
+
if: github.event_name == 'push'
|
|
129
|
+
uses: ./.github/workflows/ci.yml
|
|
130
|
+
|
|
131
|
+
publish:
|
|
132
|
+
name: Publish to PyPI
|
|
133
|
+
needs: [version, sdist, wheels, ci]
|
|
134
|
+
if: github.event_name == 'push'
|
|
135
|
+
runs-on: ubuntu-latest
|
|
136
|
+
environment:
|
|
137
|
+
name: pypi
|
|
138
|
+
url: https://pypi.org/project/openc166/${{ needs.version.outputs.version }}/
|
|
139
|
+
permissions:
|
|
140
|
+
id-token: write
|
|
141
|
+
steps:
|
|
142
|
+
- uses: actions/download-artifact@v8
|
|
143
|
+
with:
|
|
144
|
+
path: dist
|
|
145
|
+
merge-multiple: true
|
|
146
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
147
|
+
with:
|
|
148
|
+
# Lets a failed upload be re-run.
|
|
149
|
+
skip-existing: true
|
|
150
|
+
|
|
151
|
+
github-release:
|
|
152
|
+
name: GitHub release
|
|
153
|
+
needs: [version, publish]
|
|
154
|
+
runs-on: ubuntu-latest
|
|
155
|
+
permissions:
|
|
156
|
+
contents: write
|
|
157
|
+
env:
|
|
158
|
+
VERSION: ${{ needs.version.outputs.version }}
|
|
159
|
+
GH_TOKEN: ${{ github.token }}
|
|
160
|
+
steps:
|
|
161
|
+
- uses: actions/checkout@v7
|
|
162
|
+
with:
|
|
163
|
+
fetch-depth: 0
|
|
164
|
+
persist-credentials: false
|
|
165
|
+
- uses: actions/download-artifact@v8
|
|
166
|
+
with:
|
|
167
|
+
path: dist
|
|
168
|
+
merge-multiple: true
|
|
169
|
+
- name: Create the release
|
|
170
|
+
run: |
|
|
171
|
+
tag="v$VERSION"
|
|
172
|
+
previous=$(git describe --tags --abbrev=0 --match 'v[0-9]*' HEAD^ 2>/dev/null || true)
|
|
173
|
+
{
|
|
174
|
+
echo "Install it with \`pip install openc166==$VERSION\`."
|
|
175
|
+
echo
|
|
176
|
+
echo "## Changes"
|
|
177
|
+
echo
|
|
178
|
+
git log --no-merges --format='- %s' "${previous:+$previous..}HEAD"
|
|
179
|
+
} > notes.md
|
|
180
|
+
if gh release view "$tag" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
|
|
181
|
+
gh release upload "$tag" dist/* --repo "$GITHUB_REPOSITORY" --clobber
|
|
182
|
+
else
|
|
183
|
+
gh release create "$tag" dist/* --repo "$GITHUB_REPOSITORY" --target "$GITHUB_SHA" \
|
|
184
|
+
--title "openc166 $VERSION" --notes-file notes.md
|
|
185
|
+
fi
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Build trees
|
|
2
|
+
/build*/
|
|
3
|
+
/cmake-build-*/
|
|
4
|
+
/out/
|
|
5
|
+
|
|
6
|
+
# IDEs
|
|
7
|
+
/.idea/
|
|
8
|
+
/.vscode/
|
|
9
|
+
/.vs/
|
|
10
|
+
*.swp
|
|
11
|
+
|
|
12
|
+
# Python
|
|
13
|
+
__pycache__/
|
|
14
|
+
*.pyc
|
|
15
|
+
/.pytest_cache/
|
|
16
|
+
|
|
17
|
+
# Local test corpora and tool outputs that must never be committed
|
|
18
|
+
# (third-party sources such as Infineon MiniMon, Keil-generated files)
|
|
19
|
+
/tests/local/
|
|
20
|
+
*.LST
|
|
21
|
+
*.lst
|
|
22
|
+
*.OBJ
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.20)
|
|
2
|
+
project(openc166
|
|
3
|
+
VERSION 0.1.15
|
|
4
|
+
DESCRIPTION "Keil A166-compatible assembler for the Infineon C166/C167 family"
|
|
5
|
+
LANGUAGES CXX)
|
|
6
|
+
|
|
7
|
+
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
|
8
|
+
set(OPENC166_TOP_LEVEL ON)
|
|
9
|
+
else()
|
|
10
|
+
set(OPENC166_TOP_LEVEL OFF)
|
|
11
|
+
endif()
|
|
12
|
+
|
|
13
|
+
option(OPENC166_BUILD_CLI "Build the openc166 command-line tool" ON)
|
|
14
|
+
option(OPENC166_BUILD_SHARED "Build the shared library with the C interface" ON)
|
|
15
|
+
option(OPENC166_BUILD_TESTS "Build the unit tests" ${OPENC166_TOP_LEVEL})
|
|
16
|
+
option(OPENC166_SANITIZE "Build with AddressSanitizer and UndefinedBehaviorSanitizer" OFF)
|
|
17
|
+
option(OPENC166_WERROR "Treat compiler warnings as errors" OFF)
|
|
18
|
+
set(OPENC166_ISAGEN_EXECUTABLE "" CACHE FILEPATH
|
|
19
|
+
"Prebuilt host isagen to use when cross-compiling (empty: build it)")
|
|
20
|
+
|
|
21
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
22
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
23
|
+
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
24
|
+
|
|
25
|
+
# Link the C++ runtime statically with MSVC, so that openc166.exe and
|
|
26
|
+
# openc166.dll run without the Visual C++ Redistributable.
|
|
27
|
+
if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
|
|
28
|
+
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
|
29
|
+
endif()
|
|
30
|
+
|
|
31
|
+
# Shared warning and sanitizer settings for every target in this project.
|
|
32
|
+
add_library(openc166_options INTERFACE)
|
|
33
|
+
if(MSVC)
|
|
34
|
+
target_compile_options(openc166_options INTERFACE /W4 /utf-8 $<$<COMPILE_LANGUAGE:CXX>:/permissive->)
|
|
35
|
+
if(OPENC166_WERROR)
|
|
36
|
+
target_compile_options(openc166_options INTERFACE /WX)
|
|
37
|
+
endif()
|
|
38
|
+
else()
|
|
39
|
+
target_compile_options(openc166_options INTERFACE
|
|
40
|
+
-Wall -Wextra -Wpedantic -Wshadow -Wconversion -Wno-sign-conversion)
|
|
41
|
+
if(OPENC166_WERROR)
|
|
42
|
+
target_compile_options(openc166_options INTERFACE -Werror)
|
|
43
|
+
endif()
|
|
44
|
+
if(OPENC166_SANITIZE)
|
|
45
|
+
target_compile_options(openc166_options INTERFACE
|
|
46
|
+
-fsanitize=address,undefined -fno-omit-frame-pointer -fno-sanitize-recover=all)
|
|
47
|
+
target_link_options(openc166_options INTERFACE -fsanitize=address,undefined)
|
|
48
|
+
endif()
|
|
49
|
+
endif()
|
|
50
|
+
|
|
51
|
+
add_subdirectory(tools)
|
|
52
|
+
add_subdirectory(src)
|
|
53
|
+
|
|
54
|
+
if(OPENC166_BUILD_CLI)
|
|
55
|
+
add_subdirectory(cli)
|
|
56
|
+
endif()
|
|
57
|
+
|
|
58
|
+
if(OPENC166_BUILD_TESTS)
|
|
59
|
+
enable_testing()
|
|
60
|
+
add_subdirectory(tests)
|
|
61
|
+
endif()
|
openc166-0.1.15/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Piotr Zdolski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
openc166-0.1.15/PKG-INFO
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openc166
|
|
3
|
+
Version: 0.1.15
|
|
4
|
+
Summary: Keil A166-compatible assembler for the Infineon C166/C167 microcontrollers
|
|
5
|
+
Keywords: c166,c167,st10,assembler,keil,a166,infineon,ecu
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Operating System :: MacOS
|
|
11
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Assembly
|
|
14
|
+
Classifier: Programming Language :: C++
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Software Development :: Assemblers
|
|
17
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Project-URL: Homepage, https://github.com/Dante383/openc166
|
|
20
|
+
Project-URL: Issues, https://github.com/Dante383/openc166/issues
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# openc166
|
|
25
|
+
|
|
26
|
+
An open-source assembler for the Infineon C166 and C167 microcontroller
|
|
27
|
+
family (including ST10 parts), compatible with the Keil A166 assembler.
|
|
28
|
+
|
|
29
|
+
It turns Keil-style assembly source into a **raw binary image** at a fixed
|
|
30
|
+
address, or into an Intel HEX or Motorola S-record file. That suits small
|
|
31
|
+
programs loaded into RAM or flash and started directly, such as ECU
|
|
32
|
+
payloads, bootstrap loaders, and test code. No linker or object-file
|
|
33
|
+
converter is needed.
|
|
34
|
+
|
|
35
|
+
openc166 runs on Linux, Windows and macOS. It needs only a C++20 compiler and
|
|
36
|
+
CMake.
|
|
37
|
+
|
|
38
|
+
## Status
|
|
39
|
+
|
|
40
|
+
Early development (version 0.x). What works today:
|
|
41
|
+
|
|
42
|
+
- **The complete C166 and C167 instruction set**, with all addressing modes.
|
|
43
|
+
Every instruction form is checked byte for byte against Keil A166 V5.38:
|
|
44
|
+
over 5,000 checks of code bytes, addresses and symbol values, all
|
|
45
|
+
identical.
|
|
46
|
+
- Keil expression syntax: operators, `HIGH`/`LOW`, `SOF`/`SEG`/`PAG`/`POF`,
|
|
47
|
+
`BOF`, `DATA3`/`DATA4`/`DATA8`/`DATA16`, character constants, bit
|
|
48
|
+
addresses such as `PSW.3` or `0FD00H.5`, and extended-SFR checks inside
|
|
49
|
+
`EXTR` sequences.
|
|
50
|
+
- Sections with an address (`SECTION CODE AT 0E000H`) and without one.
|
|
51
|
+
openc166 places sections without `AT` as Keil's L166 linker would, or at
|
|
52
|
+
addresses you give (`--section NAME=ADDR`), so code that leaves placement
|
|
53
|
+
to the linker can still be assembled straight to a binary. `DGROUP` and
|
|
54
|
+
`CGROUP` keep sections in one data page or code segment, as in L166.
|
|
55
|
+
`BIT` sections and `DBIT` hold bit variables, placed bit by bit as L166
|
|
56
|
+
places them.
|
|
57
|
+
- `PROC`/`ENDP`, `ORG`, `EVEN`, `EQU`/`SET`/`BIT`, `DB`/`DW`/`DD`,
|
|
58
|
+
`DS`/`DSB`/`DSW`/`DSD`, and `DPPTR`/`DSPTR`/`DBPTR`, including Keil's
|
|
59
|
+
automatic alignment of word data.
|
|
60
|
+
- Segmented mode (`$SEGMENTED`): `ASSUME`, `DPPn:` prefixes, and Keil's
|
|
61
|
+
rules for which data page register an address goes through.
|
|
62
|
+
- `DEFR`/`DEFA`/`DEFB`, the register-definition directives that register
|
|
63
|
+
files use, with Keil's rules for repeated definitions.
|
|
64
|
+
- A built-in `REG167.INC` register file, written from Infineon's manuals, so
|
|
65
|
+
`$INCLUDE(REG167.INC)` works without Keil installed.
|
|
66
|
+
- Keil's rules for label arithmetic, which decide between short and long
|
|
67
|
+
instruction forms.
|
|
68
|
+
- Generic `JMP` and `CALL`: like Keil, openc166 picks the shortest
|
|
69
|
+
instruction that reaches the target and shortens forward jumps over
|
|
70
|
+
several passes. Label types (`NEAR`, `FAR`, `WORD`, ...) and the `SHORT`
|
|
71
|
+
and type operators (`FAR x`, `WORD PTR x`, ...) work as in Keil.
|
|
72
|
+
- `$INCLUDE` and `$INCDIR`, with Keil's search order and listing format.
|
|
73
|
+
- Conditional assembly: `$SET`/`$RESET`, `$IF`/`$ELSEIF`/`$ELSE`/`$ENDIF`
|
|
74
|
+
and the `IF`/`ELSEIF`/`ELSE`/`ENDIF` statements, with Keil's quirks (only
|
|
75
|
+
bit 0 of a condition counts) and listing format.
|
|
76
|
+
- `LIT` text replacement (`PORT LIT 'R2'`), with Keil's rules for where
|
|
77
|
+
names are replaced.
|
|
78
|
+
- Keil's standard macros: `MACRO`/`ENDM` with parameters and `LOCAL`
|
|
79
|
+
labels, `REPT`, `IRP`, `IRPC`, `EXITM`, `NUL`, `&` and `%`, with Keil's
|
|
80
|
+
rules for splitting arguments. `$GEN`/`$NOGEN` choose whether the listing
|
|
81
|
+
shows expanded lines.
|
|
82
|
+
- The `$MOD167`, `$CASE`, `$SEGMENTED` and `$TABS` controls, with Keil's
|
|
83
|
+
rule that these come before the first statement. Listing-only controls
|
|
84
|
+
are accepted and ignored.
|
|
85
|
+
- Keil error and warning codes (A74, A111, ...), so messages line up with
|
|
86
|
+
the Keil manual.
|
|
87
|
+
- Raw binary, Intel HEX and Motorola S-record output. The HEX records match
|
|
88
|
+
Keil OH166's `H167` format.
|
|
89
|
+
- Several source files linked into one program, as L166 does: `EXTERN`,
|
|
90
|
+
`PUBLIC` and `GLOBAL` symbols, and sections of the same name combined
|
|
91
|
+
across files. Each file is assembled separately (a "module"), so a name
|
|
92
|
+
that is not `PUBLIC` stays private to its file.
|
|
93
|
+
- Register banks (`REGBANK`/`REGDEF`), placed in `0FC00H..0FDFFH` as L166
|
|
94
|
+
places them, and the `NAME`, `SSKDEF`, `PECDEF` and `TYPEDEC` directives.
|
|
95
|
+
- **TASKING sources** (`--dialect tasking`): the common part of TASKING's
|
|
96
|
+
m166 preprocessor (`@SET`, `@EVAL`, `@IF`/`@ELSE`/`@ENDI`, `@DEFINED`),
|
|
97
|
+
TASKING's controls and `STDNAMES` register files, and the places where
|
|
98
|
+
its assembler differs from Keil's. Infineon's MiniMon monitor and flash
|
|
99
|
+
drivers, which gkflasher's ECU code comes from, rebuild byte for byte
|
|
100
|
+
from their TASKING sources. See
|
|
101
|
+
[docs/tasking.md](https://github.com/Dante383/openc166/blob/main/docs/tasking.md).
|
|
102
|
+
- A Python package and a C API, for tools that assemble code themselves.
|
|
103
|
+
|
|
104
|
+
Not done yet:
|
|
105
|
+
|
|
106
|
+
- Keil's MPL macro language (`%DEFINE` and the like); put `$NOMPL` at the
|
|
107
|
+
top of the file to use `%` as text
|
|
108
|
+
- OMF-166 object files and libraries
|
|
109
|
+
- TASKING's m166 macros with parameters (`@DEFINE`), loops and string
|
|
110
|
+
functions
|
|
111
|
+
|
|
112
|
+
See [docs/compatibility.md](https://github.com/Dante383/openc166/blob/main/docs/compatibility.md) for exact behaviour and
|
|
113
|
+
the few places where openc166 deliberately differs from Keil.
|
|
114
|
+
|
|
115
|
+
## Building
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
cmake -S . -B build
|
|
119
|
+
cmake --build build
|
|
120
|
+
ctest --test-dir build
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The program is `build/cli/openc166`. On Windows with Visual Studio it is
|
|
124
|
+
under `build\cli\Debug\` or `build\cli\Release\`. The shared library with
|
|
125
|
+
the C API is built in `build/src/`.
|
|
126
|
+
|
|
127
|
+
## Usage
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
openc166 payload.a66 # writes payload.bin
|
|
131
|
+
openc166 payload.a66 -o out.bin -l out.lst # choose names, add a listing
|
|
132
|
+
openc166 payload.a66 -o payload.hex # Intel HEX
|
|
133
|
+
openc166 payload.a66 -o payload.s19 # S-records (S1)
|
|
134
|
+
openc166 main.a66 lib.a66 -o payload.bin # link two source files
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Several source files are linked into one program, the way Keil's L166
|
|
138
|
+
linker joins the object files of A166:
|
|
139
|
+
|
|
140
|
+
- An `EXTERN` name in one file takes the value of the `PUBLIC` or `GLOBAL`
|
|
141
|
+
name in another. A name that no file exports is an error.
|
|
142
|
+
- Sections with the same name and class are joined into one: the parts of
|
|
143
|
+
a `PUBLIC` or `GLOBAL` section follow one another, the parts of a
|
|
144
|
+
`COMMON` section lie on top of each other.
|
|
145
|
+
- Without `-o`, the output is named after the first file. With `-l`, the
|
|
146
|
+
listing has one part per file and a symbol table that names the file
|
|
147
|
+
each symbol comes from.
|
|
148
|
+
- Code outside sections starts at `--origin` in every file, so normally
|
|
149
|
+
each file puts its code in sections.
|
|
150
|
+
|
|
151
|
+
`$INCLUDE` looks in each file's own directory.
|
|
152
|
+
[docs/compatibility.md](https://github.com/Dante383/openc166/blob/main/docs/compatibility.md#linking-several-files)
|
|
153
|
+
has the exact rules.
|
|
154
|
+
|
|
155
|
+
The output format follows the extension of the `-o` file: `.hex`, `.h86`
|
|
156
|
+
and `.ihx` give Intel HEX; `.srec`, `.s19`, `.s28`, `.s37`, `.mot` and
|
|
157
|
+
`.sx` give S-records; anything else gives a raw binary. `--format` chooses
|
|
158
|
+
it explicitly.
|
|
159
|
+
|
|
160
|
+
A raw binary starts at the lowest address used. For example, code in
|
|
161
|
+
`SECTION CODE AT 0E000H` produces a file whose first byte belongs at
|
|
162
|
+
`0E000H`. Gaps between pieces of code are filled. HEX and S-record files
|
|
163
|
+
carry the address of every record, so they hold only the bytes used.
|
|
164
|
+
|
|
165
|
+
| Option | Meaning |
|
|
166
|
+
|---|---|
|
|
167
|
+
| `-f, --format FMT` | `bin`, `hex` or `srec` (default: from the output extension) |
|
|
168
|
+
| `--origin ADDR` | address of code outside sections, and the lowest address for sections without `AT` (default 0) |
|
|
169
|
+
| `--section NAME=ADDR` | put section `NAME`, which has no `AT`, at `ADDR` (may be repeated) |
|
|
170
|
+
| `--base ADDR` | binary: address of the first byte of the file |
|
|
171
|
+
| `--fill BYTE` | binary: value of gaps between pieces of code (default `0FFh`) |
|
|
172
|
+
| `--record-size N` | HEX and S-records: data bytes per record (default 16) |
|
|
173
|
+
| `--cpu c166\|c167` | instruction set (`$MOD167` in the source also selects C167) |
|
|
174
|
+
| `-I DIR` | also search `DIR` for `$INCLUDE` files (may be repeated) |
|
|
175
|
+
| `--dialect D` | `keil` (default) or `tasking`, for TASKING a166 sources |
|
|
176
|
+
| `-c, --control TEXT` | controls read before the sources, e.g. `-c "CASE STDNAMES(reg167.def)"` (may be repeated) |
|
|
177
|
+
|
|
178
|
+
Sections without `AT` go in order of first appearance to the first free,
|
|
179
|
+
suitably aligned place from the origin on, as L166 places them by default.
|
|
180
|
+
`--section` overrides that for chosen sections, like L166's `SECTIONS`
|
|
181
|
+
control. The listing ends with a table of where each section went.
|
|
182
|
+
[examples/sections.a66](https://github.com/Dante383/openc166/blob/main/examples/sections.a66) shows both.
|
|
183
|
+
|
|
184
|
+
Intel HEX files use extended linear address records (type 04) for addresses
|
|
185
|
+
above 64 KB, like OH166 with its `H167` option. S-records use S1, S2 or S3
|
|
186
|
+
records by extension (`.s19`, `.s28`, `.s37`); otherwise the smallest kind
|
|
187
|
+
that holds every address.
|
|
188
|
+
|
|
189
|
+
The exit status is 0 on success, 1 on assembly errors (no output is
|
|
190
|
+
written), and 2 for usage or file errors. Messages use the format
|
|
191
|
+
`file:line:column: error A74: ...`.
|
|
192
|
+
|
|
193
|
+
[examples/payload.a66](https://github.com/Dante383/openc166/blob/main/examples/payload.a66) is a short, commented example.
|
|
194
|
+
[examples/mtos/](https://github.com/Dante383/openc166/tree/main/examples/mtos) holds real ECU payloads for Siemens SIMK43
|
|
195
|
+
ECUs, taken from gkflasher.
|
|
196
|
+
|
|
197
|
+
## Python
|
|
198
|
+
|
|
199
|
+
```sh
|
|
200
|
+
pip install openc166 # or "pip install ." in a checkout
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Wheels are published for Linux, Windows and macOS on x86 and ARM; other
|
|
204
|
+
systems build from source, which needs CMake and a C++20 compiler. To get
|
|
205
|
+
just the `openc166` command, `pipx install openc166` works too.
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
import openc166
|
|
209
|
+
|
|
210
|
+
result = openc166.assemble("""
|
|
211
|
+
$MOD167
|
|
212
|
+
PROG SECTION CODE AT 0E000H
|
|
213
|
+
MOV R4, #0BEEFH
|
|
214
|
+
RET
|
|
215
|
+
PROG ENDS
|
|
216
|
+
END
|
|
217
|
+
""")
|
|
218
|
+
image = result.image() # raises openc166.AssemblyError if there are errors
|
|
219
|
+
image.base # 0xE000, the address of image.data[0]
|
|
220
|
+
image.data # b'\xe6\xf4\xef\xbe\xcb\x00'
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
- `openc166.assemble(source, *, file_name=None, cpu=None, origin=0, include_dirs=(), sections=None, dialect="keil", controls=())`
|
|
224
|
+
assembles a `str` or `bytes`. `sections` gives addresses for sections
|
|
225
|
+
without `AT`, e.g. `{"VARS": 0xF600}`. `dialect="tasking"` reads TASKING
|
|
226
|
+
source; `controls` is a list of controls read before the source, as with
|
|
227
|
+
`-c`. `openc166.assemble_file(path, ...)`
|
|
228
|
+
reads a file; `$INCLUDE` then also searches the file's directory.
|
|
229
|
+
- The result has `ok`, `diagnostics` (each with `severity`, `code`,
|
|
230
|
+
`message`, `file`, `line`, `column`; `str()` gives the usual one-line
|
|
231
|
+
message), `errors`, `warnings`, `chunks` (address and bytes of each piece
|
|
232
|
+
of code), `symbols` (a dict of name to `Symbol`), `symbol(name)` (lookup
|
|
233
|
+
ignoring case), `sections` (a dict of name to `Section`: `type`, `align`,
|
|
234
|
+
`address`, `size`, and `placement`, which is `"at"`, `"given"` or
|
|
235
|
+
`"located"`), `listing` and `cpu`.
|
|
236
|
+
- `openc166.assemble_many({"main.a66": text1, "lib.a66": text2}, ...)`
|
|
237
|
+
links several sources into one program, like several files on the
|
|
238
|
+
command line; `openc166.assemble_files([path1, path2], ...)` reads them
|
|
239
|
+
from files. Each `Symbol` then says which file defines it (`module`) and
|
|
240
|
+
whether it is `PUBLIC` or `GLOBAL` (`exported`). `result.modules` lists
|
|
241
|
+
the file names; `result.symbols` holds one symbol per name (the exported
|
|
242
|
+
one if there is one), `result.all_symbols` all of them. Each `Section`
|
|
243
|
+
has its `class_name` and `group`.
|
|
244
|
+
- `result.image(base=None, fill=0xFF)` lays all code out as one block, like
|
|
245
|
+
the command-line tool.
|
|
246
|
+
- `result.intel_hex(record_size=16)` and
|
|
247
|
+
`result.srec(record_size=16, address_size=None)` return Intel HEX and
|
|
248
|
+
S-record text (`address_size` 2, 3 or 4 picks S1, S2 or S3 records).
|
|
249
|
+
|
|
250
|
+
The package needs Python 3.9 or newer. It also installs the `openc166`
|
|
251
|
+
command. It loads the library through `ctypes`, so one wheel works with
|
|
252
|
+
every Python version.
|
|
253
|
+
|
|
254
|
+
## C API
|
|
255
|
+
|
|
256
|
+
[include/openc166/openc166.h](https://github.com/Dante383/openc166/blob/main/include/openc166/openc166.h) declares a plain C
|
|
257
|
+
interface, exported by the shared library (`libopenc166.so`,
|
|
258
|
+
`libopenc166.dylib` or `openc166.dll`). Any language that can call C can
|
|
259
|
+
use it: `oc166_assemble` assembles one source, `oc166_assemble_many`
|
|
260
|
+
links several. The header documents every function; the Python package is
|
|
261
|
+
an example of a complete binding.
|
|
262
|
+
|
|
263
|
+
## Testing
|
|
264
|
+
|
|
265
|
+
- `ctest --test-dir build` runs the unit tests, the C API test and the
|
|
266
|
+
Python package tests, and assembles the examples, checking every byte.
|
|
267
|
+
- `tests/acceptance/minimon.py` rebuilds Infineon's MiniMon from its
|
|
268
|
+
TASKING sources and compares the result with its HEX files. MiniMon is
|
|
269
|
+
not included; set `MINIMON_DIR` to its directory (the one that holds
|
|
270
|
+
`MCPROG` and `Driver`) and `ctest` runs it too.
|
|
271
|
+
- `tests/diff/` contains the differential test against Keil A166. Keil is
|
|
272
|
+
**not** included. If you have your own copy, run:
|
|
273
|
+
|
|
274
|
+
```sh
|
|
275
|
+
KEIL_A166=/path/to/A166.EXE python3 tests/diff/keil_diff.py tests/diff/cases/*.a66
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
It compares every line: address, code bytes, warnings and errors, and
|
|
279
|
+
the final value of every symbol. Add `--image` to also link Keil's output
|
|
280
|
+
with L166 and OH166 and compare the complete memory image, and `--codes`
|
|
281
|
+
to list lines where both assemblers report an error but with different
|
|
282
|
+
codes. Lines marked `; DIVERGES:` are deliberate differences (see
|
|
283
|
+
[docs/compatibility.md](https://github.com/Dante383/openc166/blob/main/docs/compatibility.md)) and are skipped.
|
|
284
|
+
|
|
285
|
+
Given a directory instead of a file, it treats each `.a66` file in it as
|
|
286
|
+
one module, links Keil's objects with L166, and compares the linked
|
|
287
|
+
image and the linker's errors with openc166's:
|
|
288
|
+
|
|
289
|
+
```sh
|
|
290
|
+
KEIL_A166=/path/to/A166.EXE python3 tests/diff/keil_diff.py tests/diff/cases/link/*/
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
On Linux and macOS, Keil runs under Wine. To generate test lines that
|
|
294
|
+
cover the whole instruction set, run
|
|
295
|
+
`tests/diff/gen_sweep.py build/generated/openc166/isa.json c167 > sweep.a66`.
|
|
296
|
+
|
|
297
|
+
The test inputs were written independently for this project. Keil's output
|
|
298
|
+
is used only for the local comparison and is never stored in the
|
|
299
|
+
repository.
|
|
300
|
+
|
|
301
|
+
## License
|
|
302
|
+
|
|
303
|
+
MIT; see [LICENSE](https://github.com/Dante383/openc166/blob/main/LICENSE). The bundled [doctest](https://github.com/Dante383/openc166/tree/main/third_party/doctest)
|
|
304
|
+
test framework is also MIT.
|
|
305
|
+
|
|
306
|
+
openc166 is not affiliated with Arm/Keil or Infineon. "Keil", "A166",
|
|
307
|
+
"C166", "C167" and "TASKING" are trademarks of their respective owners. The
|
|
308
|
+
names are used only to describe compatibility.
|