├── CMakeLists.txt ├── LICENSE.txt ├── README.md ├── common ├── CMakeLists.txt ├── MPL-v2.0.txt ├── THIRD-PARTY-LICENSES-GBA.txt ├── armv4t-gba.cfg ├── gba_cart.ld └── gba_crt0.s ├── docs └── Debugging.md ├── examples ├── simple-c │ ├── Makefile │ └── test.c ├── simple-cxx │ ├── Makefile │ └── test.cpp ├── simple-etl │ ├── Makefile │ └── test.cpp ├── slides │ ├── AAS_Data │ │ └── FlatOutLies.mod │ ├── Makefile │ ├── README.md │ ├── assets │ │ ├── coremark-clang.png │ │ ├── coremark-comp.png │ │ ├── coremark-gcc.png │ │ ├── coremark.ase │ │ ├── coremark.png │ │ ├── dep-graph-runtimes.ase │ │ ├── dep-graph-runtimes.png │ │ ├── dep-graph.ase │ │ ├── dep-graph.png │ │ ├── gba-cpu.ase │ │ ├── gba-cpu.png │ │ ├── gba-mem-layout-orig.png │ │ ├── gba-mem-layout.png │ │ ├── nokias.png │ │ ├── pointer-left.ase │ │ ├── pointer-left.png │ │ ├── pointer-right.ase │ │ ├── pointer-right.png │ │ ├── qr-code.ase │ │ ├── qr-code.png │ │ ├── timeline.ase │ │ ├── timeline.png │ │ ├── wyvern-left.ase │ │ ├── wyvern-left.png │ │ ├── wyvern-right.ase │ │ ├── wyvern-right.png │ │ └── wyvern-whole.ase │ ├── bg.h │ ├── slides.c │ └── text.h ├── tonc-write-text │ ├── Makefile │ └── test.c └── ubsan │ ├── Makefile │ ├── README.md │ └── test.c └── versions.json /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023, Ties Stuij 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # See repo README.md for more information on how to build 17 | # 18 | # address some MacOs compatibility issues" 19 | # * On MacOs, for libtool, the convention is to rename libtool(ize) to 20 | # glibtool(ize), to avoid a name conflict with NeXT libtool. 21 | # * Homebrew libraries don't seem to propagate 22 | # * MacOs Clang by default compiles with '98. But for grit we need '14 23 | # (g++ is an alias for Clang++) 24 | if(APPLE) 25 | set(LIBTOOLIZE glibtoolize CACHE STRING "set libtoolize binary") 26 | set(GRIT_LDFLAGS LDFLAGS=-L/opt/homebrew/lib CACHE STRING "set LDFLAGS for Grit") 27 | set(GRIT_CPPFLAGS CPPFLAGS=-I/opt/homebrew/include CACHE STRING "set CPPFLAGS for Grit") 28 | set(GRIT_COMPILER "CXX=clang -std=c++14" CACHE STRING "set compiler for Grit") 29 | else() 30 | set(LIBTOOLIZE libtoolize CACHE STRING "set libtoolize binary") 31 | set(GRIT_LDFLAGS "" CACHE STRING "set LDFLAGS for Grit") 32 | set(GRIT_CPPFLAGS "" CACHE STRING "set CPPFLAGS for Grit") 33 | set(GRIT_COMPILER "" CACHE STRING "set compiler for Grit") 34 | endif() 35 | 36 | set(LLVM_DISTRIBUTION_COMPONENTS 37 | clang-format 38 | clang-resource-headers 39 | clang 40 | dsymutil 41 | lld 42 | lldb 43 | lldb-server 44 | lldb-dap 45 | llvm-ar 46 | llvm-config 47 | llvm-cov 48 | llvm-cxxfilt 49 | llvm-dwarfdump 50 | llvm-nm 51 | llvm-lto 52 | llvm-lto2 53 | llvm-objcopy 54 | llvm-objdump 55 | llvm-profdata 56 | llvm-ranlib 57 | llvm-readelf 58 | llvm-readobj 59 | llvm-size 60 | llvm-strip 61 | llvm-strings 62 | llvm-symbolizer 63 | LTO 64 | CACHE INTERNAL "" 65 | ) 66 | 67 | set(LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS 68 | llvm-toolchain-libs 69 | llvm-toolchain-third-party-licenses 70 | gba-toolchain 71 | gba-toolchain-third-party-licenses 72 | gba-toolchain-examples 73 | CACHE INTERNAL "Components defined by this CMakeLists that should be 74 | installed by the install-llvm-toolchain target" 75 | ) 76 | 77 | # set(CPACK_COMPONENTS_ALL ${LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS} ${LLVM_DISTRIBUTION_COMPONENTS} gba_toolchain CACHE INTERNAL "") 78 | 79 | # CONFIGURE_HANDLED_BY_BUILD was introduced in CMake 3.20 and it 80 | # greatly speeds up incremental builds. 81 | cmake_minimum_required(VERSION 3.20) 82 | 83 | set(BUG_REPORT_URL "https://github.com/stuij/gba-llvm/issues" CACHE STRING "") 84 | 85 | # Default to a release build 86 | # (CMAKE_BUILD_TYPE is a special CMake variable so if you want to set 87 | # it then you have to FORCE it). 88 | if(NOT CMAKE_BUILD_TYPE) 89 | set(CMAKE_BUILD_TYPE Release CACHE BOOL "" FORCE) 90 | endif() 91 | 92 | if(NOT CMAKE_C_COMPILER_LAUNCHER AND NOT CMAKE_CXX_COMPILER_LAUNCHER) 93 | # If ccache is available then use it by default. 94 | find_program(CCACHE_EXECUTABLE ccache) 95 | if(CCACHE_EXECUTABLE) 96 | set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE FILEPATH "" FORCE) 97 | set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE FILEPATH "" FORCE) 98 | endif() 99 | endif() 100 | 101 | include(ExternalProject) 102 | include(FetchContent) 103 | 104 | # Read which revisions of the repos to use. 105 | file(READ versions.json VERSIONS_JSON) 106 | function(read_repo_version output_variable_prefix repo) 107 | string(JSON tag GET ${VERSIONS_JSON} "repos" "${repo}" "tag") 108 | string(JSON tagType GET ${VERSIONS_JSON} "repos" "${repo}" "tagType") 109 | if(tagType STREQUAL "commithash") 110 | # GIT_SHALLOW doesn't work with commit hashes. 111 | set(shallow OFF) 112 | elseif(tagType STREQUAL "branch") 113 | set(shallow ON) 114 | # CMake docs recommend that "branch names and tags should 115 | # generally be specified as remote names" 116 | set(tag "origin/${tag}") 117 | elseif(tagType STREQUAL "tag") 118 | set(shallow ON) 119 | set(tag "${tag}") 120 | else() 121 | message(FATAL_ERROR "Unrecognised tagType ${tagType}") 122 | endif() 123 | 124 | set(${output_variable_prefix}_TAG "${tag}" PARENT_SCOPE) 125 | set(${output_variable_prefix}_SHALLOW "${shallow}" PARENT_SCOPE) 126 | endfunction() 127 | read_repo_version(bmt bmt) 128 | 129 | FetchContent_Declare(bmt 130 | GIT_REPOSITORY https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm 131 | GIT_TAG "${bmt_TAG}" 132 | GIT_SHALLOW "${bmt_SHALLOW}" 133 | GIT_PROGRESS TRUE 134 | # PATCH_COMMAND git reset --quiet --hard && git clean --quiet --force -dx 135 | # Add the llvm subdirectory later to ensure that 136 | # BMT is the first project declared. 137 | # Otherwise CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 138 | # can't be used. 139 | SOURCE_SUBDIR do_not_add_bmt_subdir_yet 140 | ) 141 | 142 | FetchContent_Declare(tools 143 | GIT_REPOSITORY https://github.com/devkitPro/gba-tools 144 | GIT_TAG "${tools_TAG}" 145 | GIT_SHALLOW "${tools_SHALLOW}" 146 | GIT_PROGRESS TRUE 147 | # PATCH_COMMAND git reset --quiet --hard && git clean --quiet --force -dx 148 | # Add the llvm subdirectory later to ensure that 149 | # LLVMEmbeddedToolchainForArm is the first project declared. 150 | # Otherwise CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 151 | # can't be used. 152 | SOURCE_SUBDIR do_not_add_tools_subdir_yet 153 | ) 154 | 155 | FetchContent_Declare(grit 156 | GIT_REPOSITORY https://github.com/devkitPro/grit 157 | GIT_TAG "${grit_TAG}" 158 | GIT_SHALLOW "${grit_SHALLOW}" 159 | GIT_PROGRESS TRUE 160 | # PATCH_COMMAND git reset --quiet --hard && git clean --quiet --force -dx 161 | # Add the llvm subdirectory later to ensure that 162 | # LLVMEmbeddedToolchainForArm is the first project declared. 163 | # Otherwise CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 164 | # can't be used. 165 | SOURCE_SUBDIR do_not_add_grit_subdir_yet 166 | ) 167 | 168 | FetchContent_MakeAvailable(bmt) 169 | FetchContent_MakeAvailable(tools) 170 | FetchContent_MakeAvailable(grit) 171 | 172 | project( 173 | gba-llvm-devkit 174 | VERSION 1 175 | DESCRIPTION "LLVM-based C/C++ toolchain for Game Boy Advance development" 176 | HOMEPAGE_URL "https://github.com/stuij/gba-llvm-devkit" 177 | ) 178 | 179 | # We generally want to install to a local directory to see what the 180 | # output will look like rather than install into the system, so change 181 | # the default accordingly. 182 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html 183 | # Note that this code only works after the first call to project so it 184 | # can't be moved after the add_subdirectory command below. 185 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 186 | set(CMAKE_INSTALL_PREFIX 187 | "${CMAKE_BINARY_DIR}/install" 188 | CACHE PATH "" FORCE 189 | ) 190 | endif() 191 | 192 | # Enable limiting the installed components in TGZ and ZIP packages. 193 | set(CPACK_ARCHIVE_COMPONENT_INSTALL TRUE) 194 | # Don't create a separate archive for each component. 195 | set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE) 196 | # Strip debug info from files before packaging them 197 | set(CPACK_STRIP_FILES TRUE) 198 | # When extracting the files put them in an ArmCompiler-.../ directory. 199 | set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY TRUE) 200 | set(CPACK_PACKAGE_NAME "gba-llvm-devkit") 201 | 202 | set(LLVM_ENABLE_PROJECTS clang;lld;lldb CACHE STRING "") 203 | set(LLDB_ENABLE_LIBXML2 ON CACHE INTERNAL "") 204 | # on MacOS we get warnings that LLDB tests won't pass properly 205 | # because of code signing. We disregard for now and see what happens. 206 | # set(LLDB_USE_SYSTEM_DEBUGSERVER ON CACHE STRING "") 207 | # We need libcxx for testing but libcxx is added as an external project 208 | # in the embedded toolchain configuration. So we go without for now. 209 | set(LLDB_INCLUDE_TESTS OFF CACHE INTERNAL "") 210 | 211 | set(LLVM_TOOLCHAIN_LIBRARY_VARIANTS armv4t CACHE INTERNAL "") 212 | 213 | add_subdirectory( 214 | ${bmt_SOURCE_DIR} 215 | ) 216 | 217 | install( 218 | FILES 219 | DESTINATION . 220 | COMPONENT llvm-toolchain 221 | ) 222 | 223 | # Groups all the targets that comprise the toolchain. 224 | add_custom_target(gba-llvm ALL) 225 | 226 | add_dependencies( 227 | install-llvm-toolchain 228 | gba-llvm 229 | ) 230 | 231 | add_custom_target(install-gba-llvm) 232 | add_dependencies( 233 | install-gba-llvm 234 | install-llvm-toolchain 235 | ) 236 | 237 | add_custom_target(package-gba-llvm) 238 | add_dependencies( 239 | package-gba-llvm 240 | package-llvm-toolchain 241 | ) 242 | 243 | add_custom_target(unpack-gba-llvm) 244 | add_dependencies( 245 | unpack-gba-llvm 246 | unpack-llvm-toolchain 247 | ) 248 | 249 | ExternalProject_Add( 250 | tools 251 | DEPENDS llvm-toolchain 252 | SOURCE_DIR ${tools_SOURCE_DIR} 253 | CONFIGURE_COMMAND ${tools_SOURCE_DIR}/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/gba-tools 254 | PREFIX gba-tools 255 | BUILD_COMMAND make 256 | INSTALL_COMMAND "" 257 | BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/gba-tools/src/tools-build/gbafix 258 | ) 259 | 260 | ExternalProject_Add_Step( 261 | tools prepare_configure 262 | WORKING_DIRECTORY ${tools_SOURCE_DIR} 263 | COMMAND aclocal 264 | COMMAND autoconf 265 | COMMAND automake --add-missing 266 | DEPENDERS configure 267 | ) 268 | 269 | foreach(cmd gbafix gbalzss gbfs insgbfs lsgbfs ungbfs) 270 | ExternalProject_Add_Step( 271 | tools ${cmd} 272 | COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/gba-tools/src/tools-build/${cmd} ${LLVM_BINARY_DIR}/bin 273 | DEPENDEES build 274 | ) 275 | endforeach() 276 | 277 | ExternalProject_Add( 278 | grit 279 | DEPENDS llvm-toolchain 280 | SOURCE_DIR ${grit_SOURCE_DIR} 281 | # On MacOS, the system Clang, which 'g++' is an alias of, defaults to '98 282 | CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${GRIT_LDFLAGS} ${GRIT_CPPFLAGS} ${GRIT_COMPILER} ${grit_SOURCE_DIR}/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/grit 283 | PREFIX grit 284 | BUILD_COMMAND ${CMAKE_COMMAND} -E env ${GRIT_LDFLAGS} ${GRIT_CPPFLAGS} make 285 | INSTALL_COMMAND "" 286 | ) 287 | 288 | ExternalProject_Add_Step( 289 | grit prepare_configure 290 | WORKING_DIRECTORY ${grit_SOURCE_DIR} 291 | COMMAND ${LIBTOOLIZE} 292 | COMMAND aclocal 293 | COMMAND autoconf 294 | COMMAND automake --add-missing 295 | DEPENDERS configure 296 | ) 297 | 298 | ExternalProject_Add_Step( 299 | grit put_files 300 | COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/grit/src/grit-build/grit ${LLVM_BINARY_DIR}/bin 301 | DEPENDEES build 302 | ) 303 | 304 | set(config "armv4t-gba.cfg") 305 | set(gba_sources ${CMAKE_SOURCE_DIR}/common) 306 | set(common ${CMAKE_SOURCE_DIR}/common) 307 | 308 | set(target_triple "armv4t-none-eabi") 309 | set(target_flags "-march=armv4t -fno-exceptions -fno-rtti --sysroot ${LLVM_BINARY_DIR}/lib/clang-runtimes/arm-none-eabi/armv4t") 310 | 311 | ExternalProject_Add( 312 | gba_sources 313 | SOURCE_DIR ${gba_sources} 314 | PREFIX gba_sources 315 | DEPENDS llvm-toolchain 316 | CMAKE_ARGS 317 | -DLLVM_BINARY_DIR=${LLVM_BINARY_DIR} 318 | -DCMAKE_AR=${LLVM_BINARY_DIR}/bin/llvm-ar${CMAKE_EXECUTABLE_SUFFIX} 319 | -DCMAKE_ASM_COMPILER_TARGET=${target_triple} 320 | -DCMAKE_ASM_FLAGS=${target_flags} 321 | -DCMAKE_BUILD_TYPE=Release 322 | -DCMAKE_CXX_COMPILER=${LLVM_BINARY_DIR}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX} 323 | -DCMAKE_CXX_COMPILER_TARGET=${target_triple} 324 | -DCMAKE_CXX_FLAGS=${target_flags} 325 | -DCMAKE_C_COMPILER=${LLVM_BINARY_DIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX} 326 | -DCMAKE_C_COMPILER_TARGET=${target_triple} 327 | -DCMAKE_C_FLAGS=${target_flags} 328 | -DCMAKE_INSTALL_PREFIX= 329 | -DCMAKE_NM=${LLVM_BINARY_DIR}/bin/llvm-nm${CMAKE_EXECUTABLE_SUFFIX} 330 | -DCMAKE_RANLIB=${LLVM_BINARY_DIR}/bin/llvm-ranlib${CMAKE_EXECUTABLE_SUFFIX} 331 | # Let CMake know we're cross-compiling 332 | -DCMAKE_SYSTEM_NAME=Generic 333 | INSTALL_COMMAND echo "nop" 334 | ) 335 | 336 | ExternalProject_Add_Step( 337 | gba_sources install_config 338 | COMMAND ${CMAKE_COMMAND} -E copy ${common}/${config} ${LLVM_BINARY_DIR}/bin 339 | COMMAND ${CMAKE_COMMAND} -E copy ${common}/gba_cart.ld ${LLVM_BINARY_DIR}/lib/clang-runtimes/arm-none-eabi/armv4t/lib 340 | DEPENDERS configure 341 | ) 342 | 343 | install( 344 | FILES 345 | ${common}/${config} 346 | DESTINATION bin 347 | COMPONENT gba-toolchain 348 | ) 349 | 350 | install( 351 | FILES 352 | ${common}/gba_cart.ld 353 | DESTINATION lib/clang-runtimes/arm-none-eabi/armv4t/lib 354 | COMPONENT llvm-toolchain 355 | ) 356 | 357 | install( 358 | DIRECTORY 359 | ${CMAKE_CURRENT_BINARY_DIR}/grit/src/grit-build/ 360 | DESTINATION bin 361 | COMPONENT gba-toolchain 362 | FILES_MATCHING PATTERN "grit" 363 | PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ 364 | ) 365 | 366 | install( 367 | DIRECTORY 368 | ${CMAKE_CURRENT_BINARY_DIR}/gba-tools/src/tools-build/ 369 | DESTINATION bin 370 | COMPONENT gba-toolchain 371 | FILES_MATCHING PATTERN "*gb*" 372 | PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ 373 | ) 374 | 375 | install( 376 | FILES 377 | ${CMAKE_CURRENT_BINARY_DIR}/gba_sources/src/gba_sources-build/_deps/aas-src/build/conv2aas/conv2aas 378 | DESTINATION bin 379 | COMPONENT gba-toolchain 380 | PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ 381 | ) 382 | 383 | install( 384 | FILES ${CMAKE_SOURCE_DIR}/README.md 385 | DESTINATION . 386 | COMPONENT gba-toolchain 387 | ) 388 | 389 | set(gba_toolchain_third_party_license_files 390 | ${CMAKE_CURRENT_BINARY_DIR}/gba_sources/src/gba_sources-build/_deps/aas-src/LICENSE apex-audio-system.LICENSE 391 | ${tools_SOURCE_DIR}/COPYING gba-tools.COPYING 392 | ${grit_SOURCE_DIR}/COPYING grit.COPYING 393 | ${CMAKE_CURRENT_BINARY_DIR}/gba_sources/src/gba_sources-build/_deps/libtonc-src/license.txt libtonc.license.txt 394 | ${common}/MPL-v2.0.txt gba_crt0.license.txt 395 | ${CMAKE_CURRENT_BINARY_DIR}/gba_sources/src/gba_sources-build/_deps/etl-src/LICENSE etl.LICENSE 396 | ) 397 | while(gba_toolchain_third_party_license_files) 398 | list(POP_FRONT gba_toolchain_third_party_license_files source_file destination_name) 399 | install( 400 | FILES ${source_file} 401 | DESTINATION third-party-licenses 402 | COMPONENT gba-toolchain-third-party-licenses 403 | RENAME ${destination_name} 404 | ) 405 | endwhile() 406 | 407 | install( 408 | FILES ${common}/THIRD-PARTY-LICENSES-GBA.txt 409 | DESTINATION . 410 | COMPONENT gba-toolchain-third-party-licenses 411 | ) 412 | 413 | set(examples_regex "Makefile|.*\\.(c|cpp|h|ase|png|md)") 414 | install( 415 | DIRECTORY ${CMAKE_SOURCE_DIR}/examples 416 | DESTINATION . 417 | COMPONENT gba-toolchain-examples 418 | FILES_MATCHING REGEX "${examples_files_regex}" 419 | ) 420 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This is a C/C++ Game Boy Advance toolchain based on LLVM. 4 | 5 | Currently there are binary packages available for Linux (x86_64, AArch64) and 6 | macOS (arm64). See the 7 | [https://github.com/stuij/gba-llvm-devkit/releases](release) page to grab the 8 | latest packages. 9 | 10 | The CMakefile.txt file in the source repo will build all the LLVM and GBA tools 11 | and components from scratch. See the [Building from 12 | source](#building-from-source) section below for instructions. 13 | 14 | 15 | # Why 16 | 17 | No good reason but 'seemed like a fun idea at the time'. Mostly to make sure 18 | that LLVM would not loose the ability to compile for ARMv4T. For example 19 | compiler-rt and LLD didn't support ARMv4T before this was fixed as part of this 20 | project. 21 | 22 | Also, the more choice the better. It's good to have an alternative to GCC. And the GBA 23 | is a fun platform to try LLVM concepts on. 24 | 25 | 26 | # Components 27 | 28 | - LLVM compiler suite tools: clang/clang++, lld, lldb, etc.. 29 | - compiler-rt: LLVM builtins runtime support 30 | - LLVM libcxx: C++ library 31 | - ETL: embedded alternative to common C++ STL constructs, can be used in 32 | conjunction with libcxx 33 | - picolibc: embedded C library 34 | - gba_cart.ld: linker script for GBA cart executables (as opposed to multiboot) 35 | - gba_crt0.s: startup code for the GBA 36 | - libtonc: GBA library 37 | - Apex Audio System: play music and sound effects on the GBA 38 | - Grit: GBA graphics swiss army knife 39 | - gbafix: fix up GBA headers 40 | 41 | 42 | # Usage 43 | 44 | ### command-line invocation 45 | 46 | TLDR: use the following invocations to create a GBA program: 47 | 48 | /bin/clang --config armv4t-gba.cfg -Wl,-T,gba_cart.ld program.c -o program.elf 49 | /bin/llvm-objcopy -O binary program.elf program.gba 50 | /bin/gbafix program.gba 51 | 52 | These are essentially the same commands you'd execute when using DevkitArm, 53 | except that `-specs=gba.specs` is replaced with `--config armv4t-gba.cfg`. 54 | 55 | See the below sections for a breakdown of what's involved. 56 | 57 | #### armv4t-gba.cfg 58 | 59 | Specifying `--config armv4t-gba.cfg` will include cmdline arguments found in the 60 | `armv4t-gba.cfg` file found in the same directory as clang. 61 | 62 | Which are: 63 | 64 | - `--target=armv4-none-unknown-eabi` 65 | - `-mfpu=none` 66 | - `-fno-exceptions` 67 | - `-fno-rtti` 68 | - `--sysroot /../lib/clang-runtimes/arm-none-eabi/armv4t` 69 | - `-lcrt0-gba` 70 | - `-D_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT` 71 | 72 | Breakdown: 73 | 74 | For cross-compiling, one of the main differences between GCC and LLVM is that 75 | LLVM can target multiple architectures from the same binary. So LLVM needs to be 76 | told this on the command-line by using what is called a target triple. 77 | 78 | The GBA sports an ARM7TDMI chip, which is from the ARMv4T architecture 79 | family. We're targeting the Arm Embedded ABI in a bare-metal environment, so the 80 | target triple becomes: 81 | 82 | --target=armv4-none-unknown-eabi 83 | 84 | And we have no fpu: 85 | 86 | -mfpu=none 87 | 88 | We currently don't support C++ exceptions or RTTI, so for C++ programs we should 89 | disable those: 90 | 91 | -fno-exceptions 92 | -fno-rtti 93 | 94 | Furthermore the compiler should understand where it can find the correct 95 | libraries and headers. As Clang can potentially target multiple architectures 96 | and multiple library variants, we need to supply a `--sysroot` argument. the 97 | libraries for ARMv4T can be found at 98 | `/lib/clang-runtimes/arm-none-eabi/armv4t`: 99 | 100 | --sysroot /../lib/clang-runtimes/arm-none-eabi/armv4t 101 | 102 | Where \ is a magic variable with points to the config file 103 | directory. This should be handled by Clang's multiboot, but there's currently an 104 | outstanding bug when targetting Thumb, so for now this works too. 105 | 106 | We also need to include the GBA startup code library, which is resolved relative 107 | to `sysroot`. 108 | 109 | -lcrt0-gba 110 | 111 | Lastly as we're on an embedded platform, and we usually don't have stderr and 112 | friends available. Recently in verbose aborting has been enabled by default in 113 | libcxx, which means that on an abort, an error message is printed. To stop the 114 | compiler linking in symbols that don't exist, add: 115 | 116 | -D_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT 117 | 118 | #### gba_cart.ld 119 | 120 | Speaks somewhat for itself. 121 | 122 | The linker file can be found at 123 | `/lib/clang-runtimes/arm-none-eabi/armv4t/lib/gba_cart.ld`. As we've set 124 | `--sysroot`, the linker can resolve `gba_cart.ld`. 125 | 126 | In our example above, as we need to pass the linker file from the driver to the 127 | linker, the cmdline argument becomes: 128 | 129 | -Wl,-T,gba_cart.ld 130 | 131 | This will set up the correct data regions for the GBA, which the startup code 132 | uses to put code and data in the right place. 133 | 134 | ### Targeting memory regions 135 | 136 | There are three memory regions that code and data could reside in: 137 | - `iwram` (internal working ram) 138 | - `ewram` (external working ram) 139 | - the default is cartidge rom 140 | 141 | `iwram` and `ewram` are mapped to linker sections `iwram` and `ewram`, so use 142 | the appropriate C or asm declarations: 143 | 144 | - C: `extern void foobar(void) __attribute__((section("iwram")));` 145 | - arm: `.section iwram` 146 | 147 | Alternately, filenames of the form `*.iwram.c` or `*.ewram.c` will be placed in 148 | the appropriate section. 149 | 150 | ### Env variable 151 | 152 | After unpacking the archive to the desired location, point the GBA_LLVM 153 | environmental variable to the root of the installation: 154 | 155 | export GBA_LLVM=/root/of/your/installation 156 | 157 | This variable will be used by the gba-llvm-devkit examples and some compatible 158 | software packages to configure themselves correctly. Although the examples will 159 | use the relative path to the toolchain if they can't find GBA_LLVM. 160 | 161 | ### Known command-line differences between GCC and LLVM 162 | 163 | There are of course a lot of command line differences between GCC and LLVM. But 164 | if you've used DevkitArm, these are the ones you might have a good chance to run 165 | into: 166 | 167 | - LLVM has no support for `-mthumb-interwork`. This is fine because these days, 168 | this option does nothing (AAPCS calling convention is the default). 169 | - LLVM does not support the `long-call` function attribute. Which is also fine, 170 | because these days the linker automatically places range extention thunks for 171 | long calls. 172 | - LLVM does not support spec files. It copes by using multilib and config files. 173 | 174 | Let us know if you encounter others worth mentioning. 175 | 176 | ### Debugging 177 | 178 | See the [debugging document](docs/Debugging.md). 179 | 180 | # Building from source 181 | 182 | ### repo 183 | 184 | https://github.com/stuij/gba-llvm-devkit 185 | 186 | ### Prerequisites 187 | 188 | Recent versions of the following tools are pre-requisites: 189 | * A toolchain such as GCC/Clang & binutils 190 | * git 191 | * cmake 192 | * make 193 | * meson (Use pip for latest version. 1.2.1 works.) 194 | * ninja 195 | * python3 196 | * autoconf 197 | * automake suite of tools 198 | * libtoolize 199 | * libfreeimage (for Grit) 200 | * qemu to run general LLVM tests 201 | 202 | #### Linux: 203 | 204 | sudo apt-get install python3 git make ninja-build qemu-system-arm libfreeimage-dev libtool automake autoconf cmake clang 205 | pip install meson 206 | 207 | #### macOS: 208 | 209 | - install Xcode from the app store to get Clang 210 | 211 | - then use your favorite package manager (homebrew in the below example) to 212 | install the following dependencies: 213 | 214 | ``` brew install python3 git make ninja qemu libfreeimage libtool automake autoconf cmake clang meson``` 215 | 216 | #### Windows: 217 | 218 | This toolchain hasn't been tested on Windows yet at all, but hopefully not too 219 | much tweaking should be necessary 220 | 221 | 222 | ### Before you build on macOS: 223 | 224 | Some tweaks are necesary for macOS to compile Grit: 225 | 226 | - for macOs silicon you to explicitly set the include and lib paths of your 227 | package manager so Grit can find libfreeimage. This is a known issue: 228 | https://github.com/Homebrew/brew/issues/13481. 229 | - GNU libtool has a name clashes with the macOS libtool which is different. The 230 | conventional workaround is to name GNU libtool glibtool, and consequently name 231 | libtoolize glibtoolize. 232 | - The system/Xcode clang is stuck on c++98 by default. But Grit needs at minimum 233 | c++14. 234 | 235 | To overcome this, CMakeList.txt sets some cache variables, so they can be 236 | overwritten from the command line. The lib/include paths default to the Homebrew 237 | default install location: 238 | 239 | LIBTOOLIZE=glibtoolize 240 | GRIT_LDFLAGS="LDFLAGS=-L/opt/homebrew/lib" 241 | GRIT_CPPFLAGS="CPPFLAGS=-I/opt/homebrew/include" 242 | GRIT_COMPILER="CXX=clang -std=c++14" 243 | 244 | On non-macOS platforms LIBTOOLIZE is set to libtoolize and the rest of the vars 245 | are empty. 246 | 247 | 248 | ### Commands to build: 249 | 250 | mkdir build 251 | cd build 252 | cmake .. -GNinja -DFETCHCONTENT_QUIET=OFF 253 | ninja 254 | 255 | ninja install 256 | # or 257 | ninja package-gba-llvm 258 | 259 | This will (should) create a functional toolchain in the 'build' dir: 260 | 261 | - `ninja package-gba-llvm` will create a package with the general form: 262 | gba-llvm-devkit-1-Linux-AArch64.tar.xz 263 | - `ninja install` will install all the needed files to the `install` directory 264 | that will contains all the install targets of all the CMAKE subtargets, some 265 | of which `ninja package-gba-llvm omits. So this includes a lot more LLVM tools 266 | for example, which might be useful for development of the toolchain itself. 267 | 268 | 269 | ### Testing the toolchain/examples 270 | 271 | ninja check-llvm 272 | ninja check-picolib 273 | ninja check-compiler-rt 274 | ninja check-cxxabi 275 | ninja check-unwind 276 | ninja check-cxx 277 | 278 | The below will check everything, but we're failing some expected llvm tests at 279 | the moment, and after that the picolibc tests won't be run. 280 | 281 | ninja check-llvm-toolchain 282 | 283 | Just checking the runtimes: 284 | 285 | ninja check-llvm-toolchain-runtimes 286 | 287 | The toolchain doesn't have automated GBA tests yet, but you can run the examples 288 | in the 'examples' dir. See below. 289 | 290 | 291 | # Examples 292 | 293 | The distribution package comes with a couple of examples. 294 | 295 | Two very basic ones to just test compiling a GBA program with C and C++ and 296 | another basic one, called `ubsan`, triggers an undefined behaviour sanitizer. 297 | 298 | A more involved one is the `slides` example, which is a poor-persons 299 | integration test of sorts, which uses Tonc, Apex Audio System and Grit. 300 | 301 | If the GBA_LLVM environmental variable is set, the examples will use this to 302 | find the root of the toolchain. If not set, the examples will use the relative 303 | path from the example dir to to the root dir of the toolchain. 304 | 305 | Type `make` within an example directory to build. 306 | 307 | 308 | # Issues 309 | 310 | For bug reports or any questions, create an issue on the source repo: 311 | https://github.com/stuij/gba-llvm-devkit/issues 312 | 313 | # Todo 314 | 315 | - convert/include Maxmod sound library. 316 | - Include posprintf printf replacement. 317 | - The GBFS tools are included in the distribution, but not the GBFS GBA library 318 | and header file. 319 | - linker script for multiboot 320 | - some kind of GBA-specific test suite 321 | - add tonc examples repo 322 | - support stdout/stdwarn/stderr 323 | - debug why memcpy seems to be so slow 324 | - macOS universal libraries 325 | - LLVM currently does no ARMv4T-specific optimizations. Should be a bunch of 326 | low-hanging fruit (for example loop unrolling). 327 | 328 | # Resources 329 | 330 | If you want to learn how to do Game Boy Advance development, but don't know 331 | where to start, this page will get you on your way: 332 | 333 | https://gbadev.net/getting-started.html 334 | 335 | # Changelog 336 | 337 | v1: 338 | 339 | Initial release. Packages for Linux and macOS. Tested by compiling a relatively 340 | involved rom. 341 | 342 | No immediately known issues exept for that memcpy seems to be really slow. Needs 343 | an investigation. Workaround: use memcpy16/memcpy32. 344 | -------------------------------------------------------------------------------- /common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | project( 3 | common 4 | ) 5 | 6 | include(FetchContent) 7 | 8 | FetchContent_Declare(libtonc 9 | GIT_REPOSITORY https://github.com/stuij/libtonc 10 | GIT_TAG "${libtonc_TAG}" 11 | GIT_SHALLOW "${libtonc_SHALLOW}" 12 | GIT_PROGRESS TRUE 13 | # PATCH_COMMAND git reset --quiet --hard && git clean --quiet --force -dx 14 | SOURCE_SUBDIR do_not_add_libtonc_subdir_yet 15 | ) 16 | 17 | FetchContent_Declare(aas 18 | GIT_REPOSITORY https://github.com/stuij/apex-audio-system 19 | GIT_TAG "${aas_TAG}" 20 | GIT_SHALLOW "${aas_SHALLOW}" 21 | GIT_PROGRESS TRUE 22 | # PATCH_COMMAND git reset --quiet --hard && git clean --quiet --force -dx 23 | SOURCE_SUBDIR do_not_add_aas_subdir_yet 24 | ) 25 | 26 | FetchContent_Declare(etl 27 | GIT_REPOSITORY https://github.com/ETLCPP/etl 28 | GIT_TAG "${etl_TAG}" 29 | GIT_SHALLOW "${etl_SHALLOW}" 30 | GIT_PROGRESS TRUE 31 | # PATCH_COMMAND git reset --quiet --hard && git clean --quiet --force -dx 32 | SOURCE_SUBDIR do_not_add_etl_subdir_yet 33 | ) 34 | 35 | FetchContent_MakeAvailable(libtonc) 36 | FetchContent_MakeAvailable(aas) 37 | FetchContent_MakeAvailable(etl) 38 | 39 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 40 | set(CMAKE_INSTALL_PREFIX 41 | "${CMAKE_BINARY_DIR}/install" 42 | CACHE PATH "" FORCE 43 | ) 44 | endif() 45 | 46 | enable_language(ASM) 47 | 48 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${LLVM_BINARY_DIR}/lib/clang-runtimes/arm-none-eabi/armv4t/lib/") 49 | add_library(crt0-gba STATIC gba_crt0.s) 50 | 51 | add_custom_target(libtonc ALL 52 | COMMAND ${CMAKE_COMMAND} -E env GBA_LLVM=${LLVM_BINARY_DIR} make 53 | COMMAND ${CMAKE_COMMAND} -E env GBA_LLVM=${LLVM_BINARY_DIR} make install DESTDIR=${LLVM_BINARY_DIR}/lib/clang-runtimes/arm-none-eabi/armv4t 54 | WORKING_DIRECTORY ${libtonc_SOURCE_DIR} 55 | DEPENDS crt0-gba 56 | ) 57 | 58 | add_custom_target(aas ALL 59 | COMMAND ${CMAKE_COMMAND} -E env GBA_LLVM=${LLVM_BINARY_DIR} make COMPILE_WITH_LLVM=1 60 | COMMAND ${CMAKE_COMMAND} -E copy build/conv2aas/conv2aas ${LLVM_BINARY_DIR}/bin 61 | COMMAND ${CMAKE_COMMAND} -E copy_directory build/aas/lib ${LLVM_BINARY_DIR}/lib/clang-runtimes/arm-none-eabi/armv4t/lib 62 | COMMAND ${CMAKE_COMMAND} -E copy_directory build/aas/include ${LLVM_BINARY_DIR}/lib/clang-runtimes/arm-none-eabi/armv4t/include 63 | WORKING_DIRECTORY ${aas_SOURCE_DIR} 64 | DEPENDS libtonc 65 | ) 66 | 67 | # Calling CMake from within CMake can't be right.. 68 | add_custom_target(etl ALL 69 | COMMAND ${CMAKE_COMMAND} -B build . -DCMAKE_INSTALL_PREFIX=${LLVM_BINARY_DIR}/lib/clang-runtimes/arm-none-eabi/armv4t 70 | COMMAND ${CMAKE_COMMAND} --install build 71 | WORKING_DIRECTORY ${etl_SOURCE_DIR} 72 | ) 73 | 74 | # install(FILES) 75 | -------------------------------------------------------------------------------- /common/MPL-v2.0.txt: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /common/THIRD-PARTY-LICENSES-GBA.txt: -------------------------------------------------------------------------------- 1 | Besides the software mentioned in THIRD-PARTY-LICENSES.txt, this product also 2 | embeds and uses the following Game Boy Advance specific pieces of software which 3 | have additional or alternate licenses: 4 | 5 | - Apex Audio System: apex-audio-system.LICENSE 6 | - ETL: etl.LICENSE 7 | - gba-tools: gba-tools.COPYING 8 | - Grit: grit.COPYING 9 | - libtonc: libtonc.license.txt 10 | - gba_crt0.s: gba_crt0.license.txt 11 | -------------------------------------------------------------------------------- /common/armv4t-gba.cfg: -------------------------------------------------------------------------------- 1 | --target=armv4t-none-unknown-eabi -mfpu=none 2 | -fno-exceptions 3 | -fno-rtti 4 | --sysroot /../lib/clang-runtimes/arm-none-eabi/armv4t 5 | -lcrt0-gba 6 | -D_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT 7 | -------------------------------------------------------------------------------- /common/gba_cart.ld: -------------------------------------------------------------------------------- 1 | /* Linker Script Original v1.3 by Jeff Frohwein */ 2 | /* v1.0 - Original release */ 3 | /* v1.1 - Added proper .data section support */ 4 | /* v1.2 - Added support for c++ & iwram overlays */ 5 | /* - Major contributions by Jason Wilkins. */ 6 | /* v1.3 - .ewram section now can be used when */ 7 | /* compiling for MULTIBOOT mode. This fixes */ 8 | /* malloc() in DevKitAdvance which depends */ 9 | /* on __eheap_start instead of end to define*/ 10 | /* the starting location of heap space. */ 11 | /* External global variable __gba_iwram_heap*/ 12 | /* support added to allow labels end, _end, */ 13 | /* & __end__ to point to end of iwram or */ 14 | /* the end of ewram. */ 15 | /* Additions by WinterMute */ 16 | /* v1.4 - .sbss section added for unitialised */ 17 | /* data in ewram */ 18 | /* v1.5 - padding section added to stop EZF */ 19 | /* stripping important data */ 20 | /* Changes by Ties Stuij to make work with Clang */ 21 | /* v1.6 - Removed overlays for now as LLD can't */ 22 | /* handle the overlay syntax. */ 23 | /* Picolibc expects different heap */ 24 | /* symbols. */ 25 | /* Provide __arm32_tls_tcb_offset as this */ 26 | /* is expected by Picolibc. */ 27 | /* Add support for different C++ sections */ 28 | /* that need to be included. */ 29 | /* Changed .bss and .sbss section syntax */ 30 | /* as LLD didn't accept those. */ 31 | 32 | /* This file is released into the public domain */ 33 | /* for commercial or non-commercial use with no */ 34 | /* restrictions placed upon it. */ 35 | 36 | /* NOTE!!!: This linker script defines the RAM & */ 37 | /* ROM start addresses. In order for it to work */ 38 | /* properly, remove -Ttext and -Tbss linker */ 39 | /* options from your makefile if they are */ 40 | /* present. */ 41 | 42 | /* You can use the following to view section */ 43 | /* addresses in your .elf file: */ 44 | /* objdump -h file.elf */ 45 | /* Please note that empty sections may incorrectly*/ 46 | /* list the lma address as the vma address for */ 47 | /* some versions of objdump. */ 48 | 49 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 50 | OUTPUT_ARCH(arm) 51 | ENTRY(_start) 52 | /* SEARCH_DIR(/bin/arm); */ 53 | 54 | /* The linker script function "var1 += var2;" sometimes */ 55 | /* reports incorrect values in the *.map file but the */ 56 | /* actual value it calculates is usually, if not always, */ 57 | /* correct. If you leave out the ". = ALIGN(4);" at the */ 58 | /* end of each section then the return value of SIZEOF() */ 59 | /* is sometimes incorrect and "var1 += var2;" appears to */ 60 | /* not work as well. "var1 += var2" style functions are */ 61 | /* avoided below as a result. */ 62 | 63 | MEMORY { 64 | 65 | rom : ORIGIN = 0x08000000, LENGTH = 32M 66 | iwram : ORIGIN = 0x03000000, LENGTH = 32K 67 | ewram : ORIGIN = 0x02000000, LENGTH = 256K 68 | } 69 | 70 | __text_start = ORIGIN(rom); 71 | __eheap_end = ORIGIN(ewram) + LENGTH(ewram); 72 | __heap_end = __eheap_end; 73 | __iwram_start = ORIGIN(iwram); 74 | __iwram_top = ORIGIN(iwram) + LENGTH(iwram);; 75 | __sp_irq = __iwram_top - 0x060; 76 | __sp_usr = __sp_irq - 0x0a0; 77 | __irq_flags = 0x03007ff8; 78 | 79 | PROVIDE(__arm32_tls_tcb_offset = 0); 80 | 81 | SECTIONS 82 | { 83 | . = __text_start; 84 | .crt0 : 85 | { 86 | KEEP (*(.crt0)) 87 | . = ALIGN(4); 88 | } >rom =0xff 89 | 90 | 91 | .init : 92 | { 93 | KEEP (*(SORT_NONE(.init))) 94 | } >rom 95 | 96 | .plt : 97 | { 98 | *(.plt) 99 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 100 | } >rom 101 | 102 | .text : /* ALIGN (4): */ 103 | { 104 | *(EXCLUDE_FILE (*.iwram*) .text*) 105 | *(EXCLUDE_FILE (*.ewram*) .text*) 106 | *(.gnu.linkonce.t.*) 107 | KEEP (*(.text.*personality*)) 108 | /* .gnu.warning sections are handled specially by elf32.em. */ 109 | *(.gnu.warning) 110 | *(.glue_7t) *(.glue_7) *(.vfp11_veneer) 111 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 112 | } >rom = 0xff 113 | 114 | __text_end = .; 115 | .fini : 116 | { 117 | KEEP (*(.fini)) 118 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 119 | } >rom =0 120 | 121 | .rodata : 122 | { 123 | *(.rodata) 124 | *all.rodata*(*) 125 | *(.roda) 126 | *(.rodata.*) 127 | *(.gnu.linkonce.r*) 128 | *(.rdata) 129 | *(.srodata.cst16) 130 | *(.srodata.cst8) 131 | *(.srodata.cst4) 132 | *(.srodata.cst2) 133 | *(.srodata .srodata.*) 134 | *(.data.rel.ro .data.rel.ro.*) 135 | 136 | SORT(CONSTRUCTORS) 137 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 138 | } >rom = 0xff 139 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >rom 140 | __exidx_start = .; 141 | .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >rom 142 | __exidx_end = .; 143 | 144 | .ctors : 145 | { 146 | /* gcc uses crtbegin.o to find the start of the constructors, so 147 | we make sure it is first. Because this is a wildcard, it 148 | doesn't matter if the user does not actually link against 149 | crtbegin.o; the linker won't look for a file to match a 150 | wildcard. The wildcard also means that it doesn't matter which 151 | directory crtbegin.o is in. */ 152 | KEEP (*crtbegin.o(.ctors)) 153 | KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 154 | KEEP (*(SORT(.ctors.*))) 155 | KEEP (*(.ctors)) 156 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 157 | } >rom = 0 158 | 159 | .dtors : 160 | { 161 | KEEP (*crtbegin.o(.dtors)) 162 | KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 163 | KEEP (*(SORT(.dtors.*))) 164 | KEEP (*(.dtors)) 165 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 166 | } >rom = 0 167 | 168 | 169 | .eh_frame : 170 | { 171 | KEEP (*(.eh_frame)) 172 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 173 | } >rom = 0 174 | 175 | .gcc_except_table : 176 | { 177 | *(.gcc_except_table) 178 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 179 | } >rom = 0 180 | 181 | __iwram_lma = .; 182 | 183 | .iwram __iwram_start : AT (__iwram_lma) 184 | { 185 | __iwram_start__ = ABSOLUTE(.) ; 186 | *(.iwram .iwram*) 187 | *iwram.*(.text* .data*) 188 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 189 | __iwram_end__ = ABSOLUTE(.) ; 190 | } >iwram = 0xff 191 | 192 | __bss_lma = __iwram_lma + SIZEOF(.iwram) ; 193 | 194 | .bss ALIGN(4) (NOLOAD) : AT (__bss_lma) 195 | { 196 | __bss_start = ABSOLUTE(.); 197 | __bss_start__ = ABSOLUTE(.); 198 | *(.dynbss) 199 | *(.gnu.linkonce.b*) 200 | *(.bss*) 201 | *(COMMON) 202 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 203 | __bss_end__ = ABSOLUTE(.); 204 | 205 | } >iwram 206 | 207 | __data_lma = __bss_lma + SIZEOF(.bss) ; 208 | 209 | .data ALIGN(4) : AT (__data_lma) 210 | { 211 | __data_start__ = ABSOLUTE(.); 212 | *(.data*) 213 | *(.gnu.linkonce.d*) 214 | CONSTRUCTORS 215 | . = ALIGN(4); 216 | } >iwram 217 | 218 | __preinit_lma = __data_lma + SIZEOF(.data); 219 | 220 | .preinit_array ALIGN(4) : AT (__preinit_lma) 221 | { 222 | __preinit_array_start = ABSOLUTE(.); 223 | KEEP (*(.preinit_array)) 224 | __preinit_array_end = ABSOLUTE(.); 225 | } >iwram 226 | 227 | __init_lma = __preinit_lma + SIZEOF(.preinit_array); 228 | 229 | .init_array ALIGN(4) : AT (__init_lma) 230 | { 231 | __init_array_start = ABSOLUTE(.); 232 | KEEP (*(SORT(.init_array.*))) 233 | KEEP (*(.init_array)) 234 | __init_array_end = ABSOLUTE(.); 235 | } >iwram 236 | 237 | __fini_lma = __init_lma + SIZEOF(.init_array); 238 | 239 | .fini_array ALIGN(4) : AT (__fini_lma) 240 | { 241 | __fini_array_start = ABSOLUTE(.); 242 | KEEP (*(SORT(.fini_array.*))) 243 | KEEP (*(.fini_array)) 244 | __fini_array_end = ABSOLUTE(.); 245 | } >iwram 246 | 247 | __jcr_lma = __fini_lma + SIZEOF(.fini_array); 248 | .jcr ALIGN(4) : AT (__jcr_lma) { KEEP (*(.jcr)) } >iwram 249 | 250 | __data_end__ = ABSOLUTE(.); 251 | __ewram_lma = __jcr_lma + SIZEOF(.jcr); 252 | 253 | __iheap_start = . ; 254 | 255 | __ewram_start = ORIGIN(ewram); 256 | .ewram __ewram_start : AT (__ewram_lma) 257 | { 258 | *(.ewram*) 259 | *ewram.*(.text* .data*) 260 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 261 | __ewram_end = ABSOLUTE(.); 262 | __end__ = ABSOLUTE(.); 263 | __eheap_start = ABSOLUTE(.); 264 | PROVIDE(__heap_start = __eheap_start); 265 | }>ewram = 0xff 266 | 267 | __sbss_lma = __ewram_lma + SIZEOF(.ewram); 268 | 269 | .sbss ALIGN(4) (NOLOAD) : AT (__sbss_lma) 270 | { 271 | __sbss_start__ = ABSOLUTE(.); 272 | *(.sbss*) 273 | . = ALIGN(4); 274 | __sbss_end__ = ABSOLUTE(.); 275 | 276 | } >ewram 277 | 278 | __pad_lma = __sbss_lma + SIZEOF(.sbss); 279 | 280 | /* EZF Advance strips trailing 0xff bytes, add a pad section so nothing important is removed */ 281 | .pad ALIGN(4) : AT (__pad_lma) 282 | { 283 | LONG(0x52416b64) 284 | LONG(0x4d) 285 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 286 | } = 0xff 287 | __rom_end__ = __pad_lma + SIZEOF(.pad); 288 | 289 | 290 | /* Stabs debugging sections. */ 291 | .stab 0 : { *(.stab) } 292 | .stabstr 0 : { *(.stabstr) } 293 | .stab.excl 0 : { *(.stab.excl) } 294 | .stab.exclstr 0 : { *(.stab.exclstr) } 295 | .stab.index 0 : { *(.stab.index) } 296 | .stab.indexstr 0 : { *(.stab.indexstr) } 297 | .comment 0 : { *(.comment) } 298 | /* DWARF debug sections. 299 | Symbols in the DWARF debugging sections are relative to the beginning 300 | of the section so we begin them at 0. */ 301 | /* DWARF 1 */ 302 | .debug 0 : { *(.debug) } 303 | .line 0 : { *(.line) } 304 | /* GNU DWARF 1 extensions */ 305 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 306 | .debug_sfnames 0 : { *(.debug_sfnames) } 307 | /* DWARF 1.1 and DWARF 2 */ 308 | .debug_aranges 0 : { *(.debug_aranges) } 309 | .debug_pubnames 0 : { *(.debug_pubnames) } 310 | /* DWARF 2 */ 311 | .debug_info 0 : { *(.debug_info) } 312 | .debug_abbrev 0 : { *(.debug_abbrev) } 313 | .debug_line 0 : { *(.debug_line) } 314 | .debug_frame 0 : { *(.debug_frame) } 315 | .debug_str 0 : { *(.debug_str) } 316 | .debug_loc 0 : { *(.debug_loc) } 317 | .debug_macinfo 0 : { *(.debug_macinfo) } 318 | /* SGI/MIPS DWARF 2 extensions */ 319 | .debug_weaknames 0 : { *(.debug_weaknames) } 320 | .debug_funcnames 0 : { *(.debug_funcnames) } 321 | .debug_typenames 0 : { *(.debug_typenames) } 322 | .debug_varnames 0 : { *(.debug_varnames) } 323 | .stack 0x80000 : { _stack = .; *(.stack) } 324 | /* These must appear regardless of . */ 325 | .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } 326 | .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } 327 | /DISCARD/ : { *(.note.GNU-stack) } 328 | } 329 | -------------------------------------------------------------------------------- /common/gba_crt0.s: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------------- 2 | This Source Code Form is subject to the terms of the Mozilla Public License, 3 | v. 2.0. If a copy of the MPL was not distributed with this file, You can 4 | obtain one at https://mozilla.org/MPL/2.0/. 5 | --------------------------------------------------------------------------------*/ 6 | 7 | .section ".crt0","ax" 8 | .global _start 9 | .align 10 | 11 | .arm 12 | .cpu arm7tdmi 13 | 14 | @--------------------------------------------------------------------------------- 15 | _start: 16 | @--------------------------------------------------------------------------------- 17 | b rom_header_end 18 | 19 | .fill 156,1,0 @ Nintendo Logo Character Data (8000004h) 20 | .fill 16,1,0 @ Game Title 21 | .byte 0x30,0x31 @ Maker Code (80000B0h) 22 | .byte 0x96 @ Fixed Value (80000B2h) 23 | .byte 0x00 @ Main Unit Code (80000B3h) 24 | .byte 0x00 @ Device Type (80000B4h) 25 | .fill 7,1,0 @ unused 26 | .byte 0x00 @ Software Version No (80000BCh) 27 | .byte 0xf0 @ Complement Check (80000BDh) 28 | .byte 0x00,0x00 @ Checksum (80000BEh) 29 | 30 | @--------------------------------------------------------------------------------- 31 | rom_header_end: 32 | @--------------------------------------------------------------------------------- 33 | b start_vector @ This branch must be here for proper 34 | @ positioning of the following header. 35 | 36 | .GLOBAL __boot_method, __slave_number 37 | @--------------------------------------------------------------------------------- 38 | __boot_method: 39 | @--------------------------------------------------------------------------------- 40 | .byte 0 @ boot method (0=ROM boot, 3=Multiplay boot) 41 | @--------------------------------------------------------------------------------- 42 | __slave_number: 43 | @--------------------------------------------------------------------------------- 44 | .byte 0 @ slave # (1=slave#1, 2=slave#2, 3=slave#3) 45 | 46 | .byte 0 @ reserved 47 | .byte 0 @ reserved 48 | .word 0 @ reserved 49 | .word 0 @ reserved 50 | .word 0 @ reserved 51 | .word 0 @ reserved 52 | .word 0 @ reserved 53 | .word 0 @ reserved 54 | 55 | .global start_vector 56 | .align 57 | @--------------------------------------------------------------------------------- 58 | start_vector: 59 | @--------------------------------------------------------------------------------- 60 | mov r0, #0x4000000 @ REG_BASE 61 | str r0, [r0, #0x208] 62 | 63 | mov r0, #0x12 @ Switch to IRQ Mode 64 | msr cpsr, r0 65 | ldr sp, =__sp_irq @ Set IRQ stack 66 | mov r0, #0x1f @ Switch to System Mode 67 | msr cpsr, r0 68 | ldr sp, =__sp_usr @ Set user stack 69 | 70 | @--------------------------------------------------------------------------------- 71 | @ Enter Thumb mode 72 | @--------------------------------------------------------------------------------- 73 | add r0, pc, #1 74 | bx r0 75 | 76 | .thumb 77 | 78 | ldr r0, =__text_start 79 | lsls r0, #5 @ Was code compiled at 0x08000000 or higher? 80 | bcs DoEWRAMClear @ yes, you can not run it in external WRAM 81 | 82 | mov r0, pc 83 | lsls r0, #5 @ Are we running from ROM (0x8000000 or higher) ? 84 | bcc SkipEWRAMClear @ No, so no need to do a copy. 85 | 86 | @--------------------------------------------------------------------------------- 87 | @ We were started in ROM, silly emulators. :P 88 | @ So we need to copy to ExWRAM. 89 | @--------------------------------------------------------------------------------- 90 | movs r2, #2 91 | lsls r2, #24 @ r2= 0x02000000 92 | ldr r3, =__end__ @ last ewram address 93 | subs r3, r2 @ r3= actual binary size 94 | movs r6, r2 @ r6= 0x02000000 95 | lsls r1, r2, #2 @ r1= 0x08000000 96 | 97 | bl CopyMem 98 | 99 | bx r6 @ Jump to the code to execute 100 | 101 | @--------------------------------------------------------------------------------- 102 | DoEWRAMClear: @ Clear External WRAM to 0x00 103 | @--------------------------------------------------------------------------------- 104 | movs r1, #0x40 105 | lsls r1, #12 @ r1 = 0x40000 106 | lsls r0, r1, #7 @ r0 = 0x2000000 107 | bl ClearMem 108 | 109 | @--------------------------------------------------------------------------------- 110 | SkipEWRAMClear: @ Clear Internal WRAM to 0x00 111 | @--------------------------------------------------------------------------------- 112 | 113 | @--------------------------------------------------------------------------------- 114 | @ Clear BSS section to 0x00 115 | @--------------------------------------------------------------------------------- 116 | ldr r0, =__bss_start__ 117 | ldr r1, =__bss_end__ 118 | subs r1, r0 119 | bl ClearMem 120 | 121 | @--------------------------------------------------------------------------------- 122 | @ Clear SBSS section to 0x00 123 | @--------------------------------------------------------------------------------- 124 | ldr r0, =__sbss_start__ 125 | ldr r1, =__sbss_end__ 126 | subs r1, r0 127 | bl ClearMem 128 | 129 | @--------------------------------------------------------------------------------- 130 | @ Copy initialized data (data section) from LMA to VMA (ROM to RAM) 131 | @--------------------------------------------------------------------------------- 132 | ldr r1, =__data_lma 133 | ldr r2, =__data_start__ 134 | ldr r4, =__data_end__ 135 | bl CopyMemChk 136 | 137 | @--------------------------------------------------------------------------------- 138 | @ Copy internal work ram (iwram section) from LMA to VMA (ROM to RAM) 139 | @--------------------------------------------------------------------------------- 140 | ldr r1,= __iwram_lma 141 | ldr r2,= __iwram_start__ 142 | ldr r4,= __iwram_end__ 143 | bl CopyMemChk 144 | 145 | @--------------------------------------------------------------------------------- 146 | CIW0Skip: 147 | @--------------------------------------------------------------------------------- 148 | @ Copy external work ram (ewram section) from LMA to VMA (ROM to RAM) 149 | @--------------------------------------------------------------------------------- 150 | ldr r1, =__ewram_lma 151 | ldr r2, =__ewram_start 152 | ldr r4, =__ewram_end 153 | bl CopyMemChk 154 | 155 | @--------------------------------------------------------------------------------- 156 | CEW0Skip: 157 | @--------------------------------------------------------------------------------- 158 | @ global constructors 159 | @--------------------------------------------------------------------------------- 160 | ldr r3, =__libc_init_array 161 | bl _blx_r3_stub 162 | @--------------------------------------------------------------------------------- 163 | @ Jump to user code 164 | @--------------------------------------------------------------------------------- 165 | movs r0, #0 @ int argc 166 | movs r1, #0 @ char *argv[] 167 | ldr r3, =main 168 | bl _blx_r3_stub 169 | swi #0x00 @ SoftReset 170 | 171 | @--------------------------------------------------------------------------------- 172 | @ Clear memory to 0x00 if length != 0 173 | @--------------------------------------------------------------------------------- 174 | @ r0 = Start Address 175 | @ r1 = Length 176 | @--------------------------------------------------------------------------------- 177 | ClearMem: 178 | @--------------------------------------------------------------------------------- 179 | movs r2,#3 @ These commands are used in cases where 180 | adds r1,r2 @ the length is not a multiple of 4, 181 | bics r1, r1, r2 @ even though it should be. 182 | 183 | beq ClearMX @ Length is zero so exit 184 | 185 | movs r2,#0 186 | @--------------------------------------------------------------------------------- 187 | ClrLoop: 188 | @--------------------------------------------------------------------------------- 189 | stmia r0!, {r2} 190 | subs r1,#4 191 | bne ClrLoop 192 | @--------------------------------------------------------------------------------- 193 | ClearMX: 194 | @--------------------------------------------------------------------------------- 195 | bx lr 196 | 197 | @--------------------------------------------------------------------------------- 198 | _blx_r3_stub: 199 | @--------------------------------------------------------------------------------- 200 | bx r3 201 | 202 | @--------------------------------------------------------------------------------- 203 | @ Copy memory if length != 0 204 | @--------------------------------------------------------------------------------- 205 | @ r1 = Source Address 206 | @ r2 = Dest Address 207 | @ r4 = Dest Address + Length 208 | @--------------------------------------------------------------------------------- 209 | CopyMemChk: 210 | @--------------------------------------------------------------------------------- 211 | subs r3, r4, r2 @ Is there any data to copy? 212 | @--------------------------------------------------------------------------------- 213 | @ Copy memory 214 | @--------------------------------------------------------------------------------- 215 | @ r1 = Source Address 216 | @ r2 = Dest Address 217 | @ r3 = Length 218 | @--------------------------------------------------------------------------------- 219 | CopyMem: 220 | @--------------------------------------------------------------------------------- 221 | movs r0, #3 @ These commands are used in cases where 222 | adds r3, r0 @ the length is not a multiple of 4, 223 | bics r3, r0 @ even though it should be. 224 | beq CIDExit @ Length is zero so exit 225 | 226 | @--------------------------------------------------------------------------------- 227 | CIDLoop: 228 | @--------------------------------------------------------------------------------- 229 | ldmia r1!, {r0} 230 | stmia r2!, {r0} 231 | subs r3, #4 232 | bne CIDLoop 233 | @--------------------------------------------------------------------------------- 234 | CIDExit: 235 | @--------------------------------------------------------------------------------- 236 | bx lr 237 | 238 | @--------------------------------------------------------------------------------- 239 | @ define some stubs expected by picolibc 240 | @--------------------------------------------------------------------------------- 241 | .global _exit 242 | _exit: 243 | swi #0x00 @ SoftReset 244 | 245 | .global kill 246 | kill: 247 | b _exit 248 | 249 | .global getpid 250 | getpid: 251 | movs r0, #1 252 | bx lr 253 | 254 | .align 255 | .pool 256 | 257 | .section .pad 258 | .end 259 | -------------------------------------------------------------------------------- /docs/Debugging.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | This document explains how to debug programs running in the [mGBA](https://mgba.io/) emulator. It assumes that you are on Linux, adapt commands as needed for 4 | anything else. 5 | 6 | ## Building Programs For Debugging 7 | 8 | For debugging, rebuild your program with the `-g` compiler flag added, so that 9 | debug information is included. You will have a better experience if you also 10 | choose a lower optimisation level such as `-O0`. 11 | 12 | ## Running mGBA for Debugging 13 | 14 | Note: mGBA has had various fixes for debugger compatibilty over time. If you 15 | have problems, use the [latest successful Github 16 | build](https://mgba.io/downloads.html#development-downloads) from buildbot 17 | (`About mGBA` shows the commit hash), or build it from source. 18 | 19 | For all the following steps you will be running mGBA either manually or in the 20 | background automatically. This is how you generally do that: 21 | 22 | ``` 23 | mgba --gdb test.gba 24 | ``` 25 | 26 | Note that: 27 | * This command assumes `mgba` is on your `PATH`. 28 | * The default gdb port number is `2345` and this document assumes you have not 29 | changed this. Adjust as needed if you do. 30 | * You must provide the `.gba` file to mGBA, not the `.elf` file. The `.elf` 31 | will be given to the debugger later. 32 | 33 | ## Running a Debugger Manually 34 | 35 | Once you have run the above command, you'll run a debugger to connect to the 36 | port that mGBA is listening on. 37 | 38 | If you are using lldb (which is included with this toolchain) you need to run: 39 | ``` 40 | $ $GBA_LLVM/bin/lldb test.elf -o "gdb-remote 2345" 41 | ``` 42 | 43 | Mac OS's system lldb, or one installed from apt will also likely work. The key 44 | thing is it must have been built with the Arm target included. If it doesn't, 45 | it'll likely crash. 46 | 47 | For GDB you will need `gdb-multiarch` (available in `apt`), or a GDB from an 48 | Arm cross compilation toolchain. 49 | 50 | ``` 51 | $ gdb-multiarch test.elf 52 | (gdb) target remote :2345 53 | ``` 54 | 55 | Note that in both cases we are giving the debugger the `.elf` file, not the 56 | `.gba` file. 57 | 58 | In the debugger you will then see the emulated CPU stopped at the `0x00000000` 59 | reset point. From here you can set breakpoints and continue and do the usual 60 | things you would do when debugging a native program. 61 | 62 | When you exit the debugger, mGBA will continue running so you must stop the mGBA 63 | process manually if needed. 64 | 65 | ## Debugging Using Visual Studio Code 66 | 67 | Note: The information here can likely be adapted to any IDE that supports the 68 | [Debug Adapter Protocol (DAP)](https://microsoft.github.io/debug-adapter-protocol//), 69 | but this has only been tested with Visual Studio Code at this time. 70 | 71 | Within VS Code you have two options for using LLDB. Using GDB has not been 72 | tested. 73 | 74 | If you simply want to debug GBA programs, and may want to to debug native 75 | programs as well, install the 76 | [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb) 77 | plugin. 78 | 79 | This plugin comes with an LLDB build that supports many architectures including 80 | Arm and is the option most people should choose. 81 | 82 | If you are developing the toolchain itself and making changes to LLDB, you can 83 | manually install the `lldb-dap` plugin by following the instructions 84 | [here](https://github.com/llvm/llvm-project/tree/main/lldb/tools/lldb-dap#installation-for-visual-studio-code). Using the `lldb-dap` binary 85 | from this toolchain. 86 | 87 | I will talk about both plugins here as they share a lot of the same 88 | configuration in VS Code. 89 | 90 | The basic setup is this: 91 | * A task to start mGBA in the background. 92 | * A launch configuration which waits for that task, then connects to mGBA using 93 | the plugin. 94 | * A task to stop mGBA when VS Code stops the debug session. 95 | 96 | This is the content of `tasks.json`: 97 | ``` 98 | { 99 | "version": "2.0.0", 100 | "tasks": [ 101 | { 102 | "label": "run-mgba", 103 | "type": "shell", 104 | "isBackground": true, 105 | "presentation": {"reveal": "never"}, 106 | "problemMatcher": { 107 | "owner": "run-mgba", 108 | "pattern": [ 109 | { 110 | "regexp": "_this_is_required_but_unused_", 111 | "file": 1, 112 | "location": 2, 113 | "message": 3, 114 | }, 115 | ], 116 | "background": { 117 | "activeOnStart": true, 118 | "beginsPattern":{"regexp": "Debugger: >"}, 119 | "endsPattern":{"regexp": "Debugger: >"} 120 | }, 121 | }, 122 | "command": "mgba", 123 | "args": ["--gdb", "${workspaceFolder}/test.gba"] 124 | }, 125 | { 126 | "label": "stop-mgba", 127 | "type": "shell", 128 | "isBackground": true, 129 | "presentation": {"reveal": "never"}, 130 | "command": "killall", 131 | "args": ["mgba"] 132 | }, 133 | ] 134 | } 135 | ``` 136 | This content will be the same regardless of plugin being used. 137 | 138 | This is the content of `launch.json`: 139 | ``` 140 | { 141 | "version": "0.2.0", 142 | "configurations": [ 143 | { 144 | "name": "mgba-codelldb", 145 | "type": "lldb", 146 | "request": "custom", 147 | "preLaunchTask": "run-mgba", 148 | "targetCreateCommands": ["target create ${workspaceFolder}/test.elf"], 149 | "processCreateCommands": ["gdb-remote 2345"], 150 | "postDebugTask": "stop-mgba" 151 | }, 152 | { 153 | "name": "mgba-lldb-dap", 154 | "type": "lldb-dap", 155 | "request": "attach", 156 | "program": "${workspaceFolder}/test.elf", 157 | "preLaunchTask": "run-mgba", 158 | "stopOnEntry": true, 159 | "attachCommands": ["gdb-remote 2345"], 160 | "postDebugTask": "stop-mgba" 161 | } 162 | ] 163 | } 164 | ``` 165 | 166 | Remove whichever plugin you chose not to install. If you have both, you can leave this as is. 167 | 168 | With those files setup, you can debug as you would any other program using "Run" 169 | -> "Start Debugging". 170 | 171 | Depending on the plugin used, you may not see the current PC location at first. 172 | Usually it will open a disassembly window showing the entry point but not 173 | always. 174 | 175 | Place breakpoints in your source files and continue as normal. When they are hit 176 | you will see that in the editor as expected. 177 | 178 | If you need to interrupt a running program, the pause button works as you would 179 | expect. It is reported as a `SIGINT` but this is not a bad thing, it's just the 180 | name given to the interrupt signal you the user just sent. 181 | 182 | # References 183 | 184 | * [CodeLLDB user manual](https://github.com/vadimcn/codelldb/blob/master/MANUAL.md) 185 | * [lldb-dap](https://github.com/llvm/llvm-project/tree/main/lldb/tools/lldb-dap) 186 | -------------------------------------------------------------------------------- /examples/simple-c/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(GBA_LLVM)),) 2 | GBA_LLVM = ../.. 3 | endif 4 | 5 | NAME = test 6 | 7 | BIN = $(GBA_LLVM)/bin 8 | CC = $(BIN)/clang 9 | GBAFIX = $(BIN)/gbafix 10 | CFLAGS = -O3 -mthumb --config armv4t-gba.cfg -Wl,-T,gba_cart.ld 11 | 12 | C_FILES = $(NAME).c 13 | 14 | $(NAME).gba: $(NAME).elf 15 | $(BIN)/llvm-objcopy -O binary $^ $@ 16 | $(GBAFIX) $@ 17 | 18 | $(NAME).elf: $(C_FILES) 19 | $(CC) -o $@ $^ $(CFLAGS) $(LFLAGS) 20 | 21 | .PHONY: clean 22 | 23 | clean: 24 | rm $(NAME).elf $(NAME).gba 25 | -------------------------------------------------------------------------------- /examples/simple-c/test.c: -------------------------------------------------------------------------------- 1 | void draw_screen() { 2 | // set background mode 3 (bitmap) and turn on background 2 3 | *(unsigned long*) 0x4000000 = 0x403; 4 | 5 | unsigned short* vram = (unsigned short*) 0x6000000; 6 | // write red to every pixel on the 240x160 screen 7 | for(int x = 0; x < 240; x++) 8 | for(int y = 0; y < 160; y++) 9 | vram[x + y * 240] = 31; 10 | } 11 | 12 | int main() { 13 | draw_screen(); 14 | while(1) {}; 15 | return 1; 16 | } 17 | -------------------------------------------------------------------------------- /examples/simple-cxx/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(GBA_LLVM)),) 2 | GBA_LLVM = ../.. 3 | endif 4 | 5 | NAME = test 6 | 7 | BIN = $(GBA_LLVM)/bin 8 | CC = $(BIN)/clang++ 9 | GBAFIX = $(BIN)/gbafix 10 | CFLAGS = -O3 -mthumb --config armv4t-gba.cfg -Wl,-T,gba_cart.ld 11 | C_FILES = $(NAME).cpp 12 | 13 | $(NAME).gba: $(NAME).elf 14 | $(BIN)/llvm-objcopy -O binary $^ $@ 15 | $(GBAFIX) $@ 16 | 17 | $(NAME).elf: $(C_FILES) 18 | $(CC) -o $@ $^ $(CFLAGS) $(LFLAGS) 19 | 20 | .PHONY: clean 21 | 22 | clean: 23 | rm $(NAME).elf $(NAME).gba 24 | -------------------------------------------------------------------------------- /examples/simple-cxx/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void draw_screen() { 4 | // set background mode 3 (bitmap) and turn on background 2 5 | *(unsigned long*) 0x4000000 = 0x403; 6 | 7 | // put colors red, green and blue in a vector 8 | std::vector v = {31}; 9 | v.push_back(31 << 5); 10 | v.insert(v.end(), 31 << 10); 11 | 12 | // pixel by pixel, paint red, green and blue stripes to the 240x160 screen 13 | unsigned short* vram = (unsigned short*) 0x6000000; 14 | for(int x = 0; x < 240; x++) 15 | for(int y = 0; y < 160; y++) 16 | vram[x + y * 240] = v[y % 3]; 17 | } 18 | 19 | int main(void) { 20 | draw_screen(); 21 | while(1) {}; 22 | return 1; 23 | } 24 | -------------------------------------------------------------------------------- /examples/simple-etl/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(GBA_LLVM)),) 2 | GBA_LLVM = ../.. 3 | endif 4 | 5 | NAME = test 6 | 7 | BIN = $(GBA_LLVM)/bin 8 | CC = $(BIN)/clang++ 9 | GBAFIX = $(BIN)/gbafix 10 | CFLAGS = -O3 -mthumb -nostdlib --config armv4t-gba.cfg -Wl,-T,gba_cart.ld \ 11 | -DETL_NO_STL -ltonc -fno-unwind-tables -fno-threadsafe-statics 12 | C_FILES = $(NAME).cpp 13 | 14 | $(NAME).gba: $(NAME).elf 15 | $(BIN)/llvm-objcopy -O binary $^ $@ 16 | $(GBAFIX) $@ 17 | 18 | $(NAME).elf: $(C_FILES) 19 | $(CC) -o $@ $^ $(CFLAGS) $(LFLAGS) 20 | 21 | .PHONY: clean 22 | 23 | clean: 24 | rm $(NAME).elf $(NAME).gba 25 | -------------------------------------------------------------------------------- /examples/simple-etl/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // These next functions make it possible to in general build with `-nostdlib` 5 | // They are not all necessary for this particular example. 6 | // They should be made into a minimal nostdlib stub library. 7 | 8 | // to compile with -nostdlib we need to define __libc_init_array() 9 | // to initialize our globals 10 | extern const void (*__preinit_array_start[])(void); 11 | extern const void (*__preinit_array_end[])(void); 12 | extern const void (*__init_array_start[])(void); 13 | extern const void (*__init_array_end[])(void); 14 | 15 | extern "C" 16 | void __libc_init_array(void) { 17 | size_t i, n; 18 | 19 | n = __preinit_array_end - __preinit_array_start; 20 | for (i = 0; i < n; i++) 21 | __preinit_array_start[i] (); 22 | 23 | n = __init_array_end - __init_array_start; 24 | for (i = 0; i < n; i++) 25 | __init_array_start[i] (); 26 | } 27 | 28 | 29 | // next two are stubs for fns used when exiting from main 30 | // (which we (should) never do) 31 | extern "C" 32 | int __aeabi_atexit( 33 | void *object, 34 | void (*destructor)(void *), 35 | void *dso_handle) { 36 | static_cast(object); 37 | static_cast(destructor); 38 | static_cast(dso_handle); 39 | return 0; 40 | } 41 | 42 | // handles destructor chain 43 | void* __dso_handle = nullptr; 44 | 45 | 46 | // pure virtual function stubbing 47 | // this one is called when bug 48 | extern "C" 49 | void __cxa_pure_virtual() { 50 | // we could do some better error reporting 51 | while (true) {} 52 | } 53 | 54 | // might sometimes get included, even though we don't do dynamic memory 55 | // allocation 56 | void operator delete(void *) {} 57 | 58 | 59 | void draw_screen() { 60 | // put colors red, green and blue in a vector 61 | etl::vector v = {31}; 62 | v.push_back(31 << 5); 63 | v.insert(v.end(), 31 << 10); 64 | 65 | // pixel by pixel, paint red, green and blue stripes to the 240x160 screen 66 | volatile unsigned short* vram = (unsigned short*) 0x6000000; 67 | for(int x = 0; x < 240; x++) 68 | for(int y = 0; y < 160; y++) 69 | vram[x + y * 240] = v[y % 3]; 70 | } 71 | 72 | int main(void) { 73 | // set background mode 3 (bitmap) and turn on background 2 74 | *(unsigned long*) 0x4000000 = 0x403; 75 | 76 | draw_screen(); 77 | while(1) { 78 | vid_vsync(); 79 | }; 80 | return 1; 81 | } 82 | -------------------------------------------------------------------------------- /examples/slides/AAS_Data/FlatOutLies.mod: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/AAS_Data/FlatOutLies.mod -------------------------------------------------------------------------------- /examples/slides/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(GBA_LLVM)),) 2 | GBA_LLVM=../.. 3 | endif 4 | 5 | NAME = slides 6 | 7 | BIN = $(GBA_LLVM)/bin 8 | CC = $(BIN)/clang 9 | GBAFIX = $(BIN)/gbafix 10 | GRIT = $(BIN)/grit 11 | LFLAGS = -ltonc -lAAS 12 | CFLAGS = -O3 -g -mthumb --config armv4t-gba.cfg -Wl,-T,gba_cart.ld -funroll-loops \ 13 | -fsanitize=array-bounds -fsanitize-trap=array-bounds -ftrap-function=ubsan_alert 14 | 15 | POINTER_LEFT = assets/pointer-left.png assets/wyvern-left.png 16 | POINTER_RIGHT = assets/pointer-right.png assets/wyvern-right.png 17 | POINTER_LEFT_ASM = pointer-left.s 18 | POINTER_RIGHT_ASM = pointer-right.s 19 | 20 | GBA_CPU_BG = assets/gba-cpu.png 21 | GBA_CPU_BG_ASM = gba-cpu.s 22 | COREMARK_GCC_BG = assets/coremark-gcc.png 23 | COREMARK_GCC_BG_ASM = coremark-gcc.s 24 | COREMARK_CLANG_BG = assets/coremark-clang.png 25 | COREMARK_CLANG_BG_ASM = coremark-clang.s 26 | COREMARK_COMP_BG = assets/coremark-comp.png 27 | COREMARK_COMP_BG_ASM = coremark-comp.s 28 | GBA_MEM_MAP_BG = assets/gba-mem-layout.png 29 | GBA_MEM_MAP_BG_ASM = gba-mem-layout.s 30 | DEP_GRAPH_BG = assets/dep-graph.png 31 | DEP_GRAPH_BG_ASM = dep-graph.s 32 | DEP_GRAPH_RUNTIMES_BG = assets/dep-graph-runtimes.png 33 | DEP_GRAPH_RUNTIMES_BG_ASM = dep-graph-runtimes.s 34 | NOKIAS_BG = assets/nokias.png 35 | NOKIAS_BG_ASM = nokias.s 36 | TIMELINE_BG = assets/timeline.png 37 | TIMELINE_BG_ASM = timeline.s 38 | QR_CODE_BG = assets/qr-code.png 39 | QR_CODE_BG_ASM = qr-code.s 40 | 41 | AAS_DATA = AAS_Data 42 | AAS_DATA_ASM = AAS_Data.s 43 | 44 | C_FILES = $(NAME).c 45 | ASM_FILES = $(POINTER_LEFT_ASM) $(POINTER_RIGHT_ASM) $(GBA_CPU_BG_ASM) \ 46 | $(COREMARK_GCC_BG_ASM) $(COREMARK_CLANG_BG_ASM) $(COREMARK_COMP_BG_ASM) \ 47 | $(DEP_GRAPH_BG_ASM) $(DEP_GRAPH_RUNTIMES_BG_ASM) \ 48 | $(NOKIAS_BG_ASM) $(TIMELINE_BG_ASM) \ 49 | $(AAS_DATA_ASM) $(GBA_MEM_MAP_BG_ASM) $(QR_CODE_BG_ASM) \ 50 | 51 | CONV2AAS = $(GBA_LLVM)/bin/conv2aas 52 | ifeq ($(OS),Windows_NT) 53 | CONV2AAS = $(GBA_LLVM)/bin/conv2aas.exe 54 | endif 55 | 56 | $(NAME).gba: $(NAME).elf 57 | $(BIN)/llvm-objcopy -O binary $^ $@ 58 | $(BIN)/gbafix $@ 59 | 60 | $(NAME).elf: $(C_FILES) $(ASM_FILES) 61 | $(CC) -o $@ $^ $(CFLAGS) $(LFLAGS) 62 | 63 | $(POINTER_LEFT_ASM): $(POINTER_LEFT) 64 | $(GRIT) $^ -gB4 -Mw 8 -Mh 8 -pS -o pointer-left -fa -pT1 65 | 66 | $(POINTER_RIGHT_ASM): $(POINTER_RIGHT) 67 | $(GRIT) $^ -gB4 -Mw 4 -Mh 8 -pS -o pointer-right -fa 68 | 69 | $(GBA_CPU_BG_ASM): $(GBA_CPU_BG) 70 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* -pT8 71 | 72 | $(GBA_MEM_MAP_BG_ASM): $(GBA_MEM_MAP_BG) 73 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* -pT5 74 | 75 | $(COREMARK_GCC_BG_ASM): $(COREMARK_GCC_BG) 76 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* 77 | 78 | $(COREMARK_CLANG_BG_ASM): $(COREMARK_CLANG_BG) 79 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* 80 | 81 | $(COREMARK_COMP_BG_ASM): $(COREMARK_COMP_BG) 82 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* 83 | 84 | $(DEP_GRAPH_BG_ASM): $(DEP_GRAPH_BG) 85 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* 86 | 87 | $(DEP_GRAPH_RUNTIMES_BG_ASM): $(DEP_GRAPH_RUNTIMES_BG) 88 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* 89 | 90 | $(QR_CODE_BG_ASM): $(QR_CODE_BG) 91 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* 92 | 93 | $(NOKIAS_BG_ASM): $(NOKIAS_BG) 94 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* 95 | 96 | $(TIMELINE_BG_ASM): $(TIMELINE_BG) 97 | $(GRIT) $^ -mR4 -gB4 -pn16 -o $* 98 | 99 | $(AAS_DATA_ASM): 100 | $(CONV2AAS) $(AAS_DATA) 101 | 102 | .PHONY: clean 103 | 104 | clean: 105 | rm $(NAME).elf $(NAME).gba pointer* gba-cpu* coremark* \ 106 | AAS_Data.* gba-mem-layout* qr-code* dep-graph* nokias* slides.sav \ 107 | timeline* 108 | -------------------------------------------------------------------------------- /examples/slides/README.md: -------------------------------------------------------------------------------- 1 | # What is this 2 | 3 | This is the slide-software for a presentation on this project. As the slides are 4 | meant to show off that the toolchain is actually working, it made sense to 5 | include it as an example. 6 | 7 | The program shows off: 8 | 9 | - using backgrounds and sprites 10 | - converting images with Grit to use as sprites and backgrounds 11 | - converting and playing mod files on the GBA, which involves meeting tight 12 | deadlines to fill up the audio sample queue by heavily using interrupts and 13 | DMA transfers 14 | 15 | 16 | # How to build 17 | 18 | type: 19 | 20 | ```make``` 21 | 22 | 23 | # How to use 24 | 25 | - `d-pad`: move the cursor 26 | - `start`: toggle slide layer on and off 27 | - `b` and `a`: cycle back and forth through slides 28 | - `l` and `r`: cycle back and forth through background images 29 | - `select` + `b`: toggle between wyvern and pointer 30 | - `select` + `a`: tell wyvern to stop flapping 31 | - `select` + `l`: read past end of array, triggering ubsan sanitizer 32 | - `select` + `r`: toggle music 33 | - `select` + `start`: reset background window to coordinates 0,0 34 | 35 | # Attribution 36 | 37 | - The wyvern sprite was adapted from the [LLVM-MOS 38 | logo](https://llvm-mos.org/wiki/File:LLV M-MOS_logo.png), which itself was 39 | adapted from the [LLVM logo](https://llvm.org/Logo.html). -------------------------------------------------------------------------------- /examples/slides/assets/coremark-clang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/coremark-clang.png -------------------------------------------------------------------------------- /examples/slides/assets/coremark-comp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/coremark-comp.png -------------------------------------------------------------------------------- /examples/slides/assets/coremark-gcc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/coremark-gcc.png -------------------------------------------------------------------------------- /examples/slides/assets/coremark.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/coremark.ase -------------------------------------------------------------------------------- /examples/slides/assets/coremark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/coremark.png -------------------------------------------------------------------------------- /examples/slides/assets/dep-graph-runtimes.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/dep-graph-runtimes.ase -------------------------------------------------------------------------------- /examples/slides/assets/dep-graph-runtimes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/dep-graph-runtimes.png -------------------------------------------------------------------------------- /examples/slides/assets/dep-graph.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/dep-graph.ase -------------------------------------------------------------------------------- /examples/slides/assets/dep-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/dep-graph.png -------------------------------------------------------------------------------- /examples/slides/assets/gba-cpu.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/gba-cpu.ase -------------------------------------------------------------------------------- /examples/slides/assets/gba-cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/gba-cpu.png -------------------------------------------------------------------------------- /examples/slides/assets/gba-mem-layout-orig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/gba-mem-layout-orig.png -------------------------------------------------------------------------------- /examples/slides/assets/gba-mem-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/gba-mem-layout.png -------------------------------------------------------------------------------- /examples/slides/assets/nokias.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/nokias.png -------------------------------------------------------------------------------- /examples/slides/assets/pointer-left.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/pointer-left.ase -------------------------------------------------------------------------------- /examples/slides/assets/pointer-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/pointer-left.png -------------------------------------------------------------------------------- /examples/slides/assets/pointer-right.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/pointer-right.ase -------------------------------------------------------------------------------- /examples/slides/assets/pointer-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/pointer-right.png -------------------------------------------------------------------------------- /examples/slides/assets/qr-code.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/qr-code.ase -------------------------------------------------------------------------------- /examples/slides/assets/qr-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/qr-code.png -------------------------------------------------------------------------------- /examples/slides/assets/timeline.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/timeline.ase -------------------------------------------------------------------------------- /examples/slides/assets/timeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/timeline.png -------------------------------------------------------------------------------- /examples/slides/assets/wyvern-left.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/wyvern-left.ase -------------------------------------------------------------------------------- /examples/slides/assets/wyvern-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/wyvern-left.png -------------------------------------------------------------------------------- /examples/slides/assets/wyvern-right.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/wyvern-right.ase -------------------------------------------------------------------------------- /examples/slides/assets/wyvern-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/wyvern-right.png -------------------------------------------------------------------------------- /examples/slides/assets/wyvern-whole.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuij/gba-llvm-devkit/14e4ff388d38c6f9aa902bafd4dbce33fe9b2cdc/examples/slides/assets/wyvern-whole.ase -------------------------------------------------------------------------------- /examples/slides/bg.h: -------------------------------------------------------------------------------- 1 | // backgrounds 2 | #include "coremark-clang.h" 3 | #include "coremark-comp.h" 4 | #include "coremark-gcc.h" 5 | #include "dep-graph.h" 6 | #include "dep-graph-runtimes.h" 7 | #include "gba-cpu.h" 8 | #include "gba-mem-layout.h" 9 | #include "nokias.h" 10 | #include "qr-code.h" 11 | #include "timeline.h" 12 | 13 | struct Background { 14 | const unsigned int* tiles; 15 | u32 tiles_len; 16 | 17 | const unsigned short* map; 18 | u32 map_len; 19 | 20 | const unsigned short* pal; 21 | u32 pal_len; 22 | }; 23 | 24 | #define BG_LIST(NAME) { NAME##Tiles, NAME##TilesLen, NAME##Map, NAME##MapLen, NAME##Pal, NAME##PalLen } 25 | 26 | struct Background bg[] = { 27 | BG_LIST(gba_cpu), 28 | BG_LIST(timeline), 29 | BG_LIST(nokias), 30 | BG_LIST(dep_graph), 31 | BG_LIST(dep_graph_runtimes), 32 | BG_LIST(gba_mem_layout), 33 | BG_LIST(coremark_gcc), 34 | BG_LIST(coremark_clang), 35 | BG_LIST(coremark_comp), 36 | BG_LIST(qr_code), 37 | }; 38 | 39 | u32 bg_cur = 0; 40 | u32 bg_len = sizeof(bg)/sizeof(bg[0]); 41 | 42 | void load_bg() { 43 | // Load tiles into CBB 2 44 | memcpy32(&tile_mem[2][0], bg[bg_cur].tiles, bg[bg_cur].tiles_len / 4); 45 | // Load palette 46 | memcpy16(pal_bg_mem, bg[bg_cur].pal, bg[bg_cur].pal_len / 2); 47 | // Load gba_cpu into SBB 14 48 | memcpy16(&se_mem[14][0], bg[bg_cur].map, bg[bg_cur].map_len / 2); 49 | } 50 | 51 | void update_bg(s32 key_tri, s32* x_view, s32* y_view) { 52 | if (key_tri < 0) { 53 | if (bg_cur == 0) 54 | bg_cur = bg_len - 1; 55 | else 56 | bg_cur--; 57 | load_bg(); 58 | *x_view = 0; *y_view = 0; 59 | } else if (key_tri > 0) { 60 | if (bg_cur == bg_len - 1) 61 | bg_cur = 0; 62 | else 63 | bg_cur++; 64 | load_bg(); 65 | *x_view = 0; *y_view = 0; 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /examples/slides/slides.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "AAS.h" 5 | #include "AAS_Data.h" 6 | #include "text.h" 7 | #include "bg.h" 8 | 9 | // sprites 10 | #include "pointer-left.h" 11 | #include "pointer-right.h" 12 | 13 | OBJ_ATTR obj_buffer[128]; 14 | OBJ_AFFINE *obj_aff_buffer= (OBJ_AFFINE*)obj_buffer; 15 | 16 | u32 tid_offset_left(u32 frame, bool wyvern_p) { 17 | // frame nr * tiles per frame 18 | u32 offset = wyvern_p ? 0 : 512; 19 | return frame * 64 + offset; 20 | } 21 | 22 | u32 tid_offset_right(u32 frame, bool wyvern_p) { 23 | u32 offset = wyvern_p ? 0 : 512; 24 | // frame nr * tiles per frame + left sprite total tiles 25 | return frame * 32 + 256 + offset; 26 | } 27 | 28 | void animate_wyvern(u32* frame_offset, bool* reverse, u32 time, bool flapping) { 29 | u32 duration = 10; 30 | u32 offset = *frame_offset; 31 | u32 total_frames = 4; 32 | 33 | if (!flapping && *frame_offset == 1) { 34 | return; 35 | } 36 | 37 | if (time % duration == 0) { 38 | if (offset == 0) { 39 | *frame_offset = 1; 40 | *reverse = false; 41 | } else if (offset == total_frames - 1) { 42 | *frame_offset = total_frames - 2; 43 | *reverse = true; 44 | } else if (*reverse == true) { 45 | *frame_offset = offset - 1; 46 | } else { 47 | *frame_offset = offset + 1; 48 | } 49 | } 50 | } 51 | 52 | void load_sprite_data() { 53 | // Place the tiles of the 4bpp LLVM wyvern into LOW obj memory (cbb == 4) 54 | // As the wyvern is too big for just one sprite, we had to split it up 55 | // into a 64x64 sprite and a 32x64 sprite. 56 | memcpy32(&tile_mem[4][0], wyvern_leftTiles, wyvern_leftTilesLen / 4); 57 | memcpy16(&tile_mem[4][256], wyvern_rightTiles, wyvern_rightTilesLen / 2); 58 | 59 | // the pointer would really occupy a much smaller tile than the wyvern of 60 | // course, but to keep the implementation elegant(ish), we're keeping it the same 61 | // size and we animate it with the same static image! 62 | memcpy32(&tile_mem[5][0], pointer_leftTiles, pointer_leftTilesLen / 4); 63 | memcpy16(&tile_mem[5][256], pointer_rightTiles, pointer_rightTilesLen); 64 | 65 | // pal data (shared between pointer and wyvern) 66 | memcpy16(pal_obj_mem, pointer_leftSharedPal, pointer_leftSharedPalLen / 2); 67 | // Even though in Aseprite the colors are presented equal, somewhere in the 68 | // conversion process some color indexes get swapped, so we can't use the same 69 | // pal bank for both. Also I couldn't find a way in grit to merge pal data from 70 | // sprites of different sizes. 71 | memcpy16(pal_obj_bank[1], pointer_rightSharedPal, pointer_rightSharedPalLen / 2); 72 | } 73 | 74 | void init_slides() { 75 | // Init for text 76 | tte_init_chr4c( 77 | 0, // BG number. 78 | BG_CBB(0)|BG_SBB(15), // BG control. 79 | 0xF000, // Screen-entry offset 80 | bytes2word(13,15,0,0), // Color attributes. 81 | CLR_WHITE, // Ink color 82 | &verdana9_b4Font, // Verdana 9, with shade. 83 | (fnDrawg)chr4c_drawg_b4cts_fast); // b4cts renderer, asm version 84 | 85 | tte_set_margins(4, 8, 236, 152); // left, top, right, bottom (absolute) 86 | write_slides(); 87 | } 88 | 89 | int main(); 90 | bool ubsan_triggered = false; 91 | void ubsan_alert() { 92 | ubsan_triggered = true; 93 | main(); 94 | } 95 | 96 | void show_ubsan_triggered() { 97 | text_on(); 98 | tte_write("#{es;P}"); 99 | tte_write("Oops!\nAlmost wrote past the end of an array!\n" 100 | "Thanks ubsan sanitizer for catching that!\n" 101 | "\n" 102 | "\n" 103 | "int get_ubsan_arr(int index) {\n" 104 | " const int arr[] = {0, 1};\n" 105 | " return arr[index];\n" 106 | "}\n" 107 | " ...\n" 108 | " get_ubsan_arr(2);\n" 109 | " ..." 110 | ); 111 | 112 | 113 | ubsan_triggered = false; 114 | } 115 | 116 | int get_ubsan_arr(int index) { 117 | const int arr[] = { 118 | 0, 119 | 1, 120 | }; 121 | return arr[index]; 122 | } 123 | 124 | int main() { 125 | // load things 126 | load_bg(); 127 | load_sprite_data(); 128 | 129 | // Initialize all sprites 130 | oam_init(obj_buffer, 128); 131 | 132 | AAS_SetConfig(AAS_CONFIG_MIX_32KHZ, AAS_CONFIG_CHANS_8, 133 | AAS_CONFIG_SPATIAL_STEREO, AAS_CONFIG_DYNAMIC_OFF); 134 | 135 | irq_init(NULL); 136 | irq_add(II_VBLANK, NULL); 137 | irq_add(II_TIMER1, AAS_Timer1InterruptHandler); 138 | 139 | // set up BG0 for a 4bpp 32x32t map, 140 | // using charblock 2 and screenblock 15 141 | REG_BG3CNT= BG_CBB(2) | BG_SBB(14) | BG_4BPP | BG_REG_32x32; 142 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG3 | DCNT_OBJ | DCNT_OBJ_1D; 143 | 144 | init_slides(); 145 | 146 | // prep blend register 147 | REG_BLDCNT= BLD_BUILD( 148 | BLD_BG3, // Top layers 149 | 0, // Bottom layers (NONE) 150 | 0); // mode (OFF) 151 | 152 | REG_BLDY= 0xd; 153 | 154 | // Set object structs with relevant settings/data 155 | // first calculate initial tile id offsets 156 | u32 frame_offset = 1; 157 | bool wyvern_p = false; // show wyvern or pointer 158 | u32 tid_left= tid_offset_left(frame_offset, wyvern_p); 159 | u32 tid_right= tid_offset_right(frame_offset, wyvern_p); 160 | 161 | // pal banks 162 | u32 pb_left= 0, pb_right= 1; 163 | 164 | OBJ_ATTR *wyvern_l= &obj_buffer[0]; 165 | obj_set_attr(wyvern_l, 166 | ATTR0_SQUARE | ATTR0_BLEND, // Square, regular sprite 167 | ATTR1_SIZE_64, // 64x64p, 168 | ATTR2_PALBANK(pb_left) | tid_left); // palbank 0, tile 64 (second frame) 169 | 170 | OBJ_ATTR *wyvern_r= &obj_buffer[1]; 171 | obj_set_attr(wyvern_r, 172 | ATTR0_TALL | ATTR0_BLEND, // Tall 173 | ATTR1_SIZE_64, // 32x64p, 174 | ATTR2_PALBANK(pb_right) | tid_right); // palbank 1, tile 256 + 32 175 | 176 | // obj and bg positioning vars 177 | s32 x_cursor = 240, y_cursor = 42; 178 | s32 x_cursor_min = 0, y_cursor_min = 0; 179 | s32 x_cursor_max = 240, y_cursor_max = 160; 180 | s32 x_view = 0, y_view = 0; // viewport offset (upper left corner) in map 181 | u32 speed = 2; 182 | 183 | u32 wyvern_r_pixel_offset = 64; 184 | 185 | int time = 0; 186 | bool reverse = false; 187 | bool flapping = false; 188 | 189 | bool paused = 0; 190 | 191 | if(ubsan_triggered) 192 | show_ubsan_triggered(); 193 | 194 | while(1){ 195 | vid_vsync(); 196 | key_poll(); 197 | time += 1; 198 | 199 | 200 | if(key_held(KEY_SELECT)) { 201 | if(key_hit(KEY_A)) 202 | flapping = !flapping; 203 | 204 | if(key_hit(KEY_B)) { 205 | // flip sprite 206 | wyvern_p = !wyvern_p; 207 | flapping = false; 208 | } 209 | 210 | if(key_hit(KEY_L)) 211 | get_ubsan_arr(2); 212 | 213 | if(key_hit(KEY_R)) { 214 | if (AAS_MOD_IsPlaying()) 215 | AAS_MOD_Stop(); 216 | else 217 | AAS_MOD_Play(AAS_DATA_MOD_FlatOutLies); 218 | } 219 | 220 | if(key_hit(KEY_START)) { 221 | x_view = 0; y_view = 0; 222 | } 223 | } else { 224 | s32 horz_key = key_tri_horz(); 225 | s32 vert_key = key_tri_vert(); 226 | 227 | // move left/right 228 | if(x_cursor + speed * horz_key >= x_cursor_max || 229 | x_cursor + speed * horz_key <= x_cursor_min) { 230 | // move viewport horizontally 231 | x_view += speed * horz_key; 232 | } else { 233 | // move cursor horizontally 234 | x_cursor += speed * horz_key; 235 | } 236 | x_view = clamp(x_view, 0, 256 + 1 - SCREEN_WIDTH); 237 | 238 | // move up/down 239 | if(y_cursor + speed * vert_key >= y_cursor_max || 240 | y_cursor + speed * vert_key <= y_cursor_min) { 241 | // move viewport vertically 242 | y_view += speed * vert_key; 243 | } else { 244 | // move cursor vertically 245 | y_cursor += speed * vert_key; 246 | } 247 | y_view = clamp(y_view, 0, 256 + 1 - SCREEN_HEIGHT); 248 | 249 | if (horz_key != 0 || vert_key != 0) 250 | flapping = true; 251 | 252 | 253 | // change slides and background 254 | update_slides(bit_tribool(key_hit(-1), KI_A, KI_B)); 255 | update_bg(bit_tribool(key_hit(-1), KI_R, KI_L), &x_view, &y_view); 256 | 257 | if(key_hit(KEY_START)) 258 | toggle_text(); 259 | } 260 | 261 | animate_wyvern(&frame_offset, &reverse, time, flapping); 262 | 263 | // set cursor 264 | wyvern_l->attr2= ATTR2_BUILD(tid_offset_left(frame_offset, wyvern_p), pb_left, 0); 265 | wyvern_r->attr2= ATTR2_BUILD(tid_offset_right(frame_offset, wyvern_p), pb_right, 0); 266 | 267 | obj_set_pos(wyvern_l, x_cursor, y_cursor); 268 | obj_set_pos(wyvern_r, x_cursor + wyvern_r_pixel_offset, y_cursor); 269 | oam_copy(oam_mem, obj_buffer, 2); 270 | 271 | // set background scroll 272 | REG_BG3HOFS= x_view; 273 | REG_BG3VOFS= y_view; 274 | }; 275 | } 276 | -------------------------------------------------------------------------------- /examples/slides/text.h: -------------------------------------------------------------------------------- 1 | char* text_slides[] = { 2 | " Talk about\n\n" 3 | 4 | "- Embedded compiler how\n" 5 | "- GCC toolchain compatibility issues\n" 6 | "- Current LLVM embedded hot topics", 7 | 8 | 9 | " Vehicle\n\n" 10 | 11 | "Game Boy Advance (GBA) toolchain\n" 12 | " - Completely based on LLVM (no GCC)\n" 13 | " - LLVM Embedded Toolchain for Arm (BMT)\n" 14 | " - Completely open source\n" 15 | " - https://github.com/stuij/gba-llvm-devkit\n" 16 | " - 1st release\n" 17 | " - Includes these slides (examples/slides)\n\n" 18 | 19 | "- Some of talk on BMT, some on GBA toolchain\n" 20 | "- Meant to be general tutorial, not BMT specific", 21 | 22 | 23 | " Intro\n\n" 24 | 25 | "- Fairly obsessed with Game Boy Advance\n" 26 | "- Made my first substantial program on it\n" 27 | "- Taught me assembly, made a toy compiler\n" 28 | "- Got my first two programming jobs out of it\n" 29 | "- All good things came from the GBA\n" 30 | "- Got to work at Arm in LLVM Embedded team\n" 31 | "- Wanted LLVM-based toolchain\n" 32 | "- Not obvious how things fit together\n", 33 | 34 | 35 | " Talk overview\n\n" 36 | 37 | "- Short history of embedded LLVM\n" 38 | "- Game Boy Advance (re)introduction\n" 39 | "- Example program\n" 40 | "- Embedded toolchain component overview\n" 41 | "- Build setup\n" 42 | "- Components: Compiler, LLD, etc..\n" 43 | "- Optimization!", 44 | 45 | 46 | "\n\n" 47 | " Creating an embedded toolchain\n" 48 | " for the Game Boy Advance", 49 | 50 | 51 | "\n\n" 52 | " Creating an embedded toolchain\n" 53 | " for the Game Boy Advance\n" 54 | "\n\n\n\n\n\n" 55 | " Taming a dragon bit by bit", 56 | 57 | 58 | " Very short LLVM embedded history\n\n" 59 | 60 | "- LLVM concentrated on hosted systems\n" 61 | "- Up until 2020 baremetal not much love\n" 62 | "- 2020 LLVM talk by Hafiz Abid Qadeer\n" 63 | " * LLVM in a Bare Metal Environment\n" 64 | "- Now also support for RiscV, PowerPC, AArch64\n" 65 | "- LLVM Embedded Toolchains Working group\n", 66 | 67 | 68 | " Game Boy Advance/ARM7TDMI overview\n\n" 69 | 70 | "- Nintendo handheld, successor of Game Boy\n" 71 | "- Released in March 2001, 82M units sold\n" 72 | "- Super Nintendo in your pocket\n" 73 | "- ARM7TDMI processor at 16.78 MHz, ARMv4T\n" 74 | " * Arm, 32 bit instruction format\n" 75 | " * Thumb, 16 bit instruction format\n" 76 | "- Nokia 6110 (1998), 3210 (1999), 3310 (2000)\n" 77 | "- Thought up by Dave Jagger, in trip to Japan in '94\n" 78 | "- 10 billion chips in total, 200M in 2020\n", 79 | 80 | 81 | " Game Boy Advance internals\n\n" 82 | 83 | "- Picture Processing Unit (PPU)\n" 84 | " * bitmap modes, tile modes\n" 85 | "- Orig Game Boy hardware\n" 86 | " * No access, except for..\n" 87 | "- Sound\n" 88 | " * Orig Game Boy PSG\n" 89 | " + Manipulate 4 waveforms, 4 channels\n" 90 | " * 2 channels to convert PGM format to DAC\n" 91 | "- Memory mapped IO all the way\n" 92 | "- Bunch of memory we will talk about later\n", 93 | 94 | 95 | " Example\n\n" 96 | 97 | "Let's paint the screen red:\n" 98 | "\n" 99 | "int main() {\n" 100 | " draw_screen();\n" 101 | " while(1) {};\n" 102 | " return 1;\n" 103 | "}", 104 | 105 | 106 | "\n" 107 | "void draw_screen() {\n" 108 | " // set bg mode 3 (bitmap) and turn on bg 2\n" 109 | " // 0x4000000 == REG_DISPCNT\n" 110 | " *(unsigned long*) 0x4000000 = 0x403;\n" 111 | "\n" 112 | " u16* vram = (u16*) 0x6000000;\n" 113 | " // write red to all pixels on 240x160 screen\n" 114 | " for(int x = 0; x < 240; x++)\n" 115 | " for(int y = 0; y < 160; y++)\n" 116 | " vram[x + y * 240] = 31;\n" 117 | "}", 118 | 119 | 120 | " Toolchain", 121 | 122 | 123 | " Components\n\n" 124 | 125 | "LLVM compiler suite tools\n" 126 | "compiler-rt builtins: target-specific code\n" 127 | "LLVM libcxx: libc++\n" 128 | "picolibc: embedded C library\n" 129 | "gba_cart.ld: linker script\n" 130 | "gba_crt0.s: startup code for the GBA\n" 131 | "libtonc: GBA low-level library\n" 132 | "Apex Audio System: GBA music library\n" 133 | "Grit: GBA graphics swiss army knife\n" 134 | "gbafix: fix up GBA headers", 135 | 136 | 137 | " Invocation\n\n" 138 | 139 | "- grit bg.bmp -gB4 -Mw8 -Mh8 -pS -obg -fa -pT1\n" 140 | "- conv2aas AAS_Data\n" 141 | "- clang --config gba.cfg -Wl,-T,gba_cart.ld\n" 142 | " program.c bg.s AAS_Data.s -o game.elf\n" 143 | "- llvm-objcopy -O binary game.elf game.gba\n" 144 | "- gbafix program.gba", 145 | 146 | 147 | " gba.cfg\n\n" 148 | 149 | "--target=armv4t-none-eabi -mfpu=none\n" 150 | "-fno-exceptions\n" 151 | "-fno-rtti\n" 152 | "--sysroot /../lib/clang-runtimes/\n" 153 | " arm-none-eabi/armv4t\n" 154 | "-lcrt0-gba\n" 155 | "-D_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE\n" 156 | " _ABORT\n", 157 | 158 | 159 | " Toolchain layout\n\n" 160 | 161 | "bin/\n" 162 | " compiler tools, gba tools, gba.cfg\n" 163 | "lib/clang-runtimes/\n" 164 | " multilib.yaml\n" 165 | " arm-none-eabi/armv4t/\n" 166 | " lib/\n" 167 | " libcrt0-gba.a, gba_cart.ld, libraries\n" 168 | " include/\n" 169 | " headers", 170 | 171 | 172 | " Dependency graph", 173 | 174 | 175 | " Build setup\n\n" 176 | 177 | "- GBA toolchain built on top of BMT\n" 178 | "- Uses CMake. Very composable, feels bit icky\n" 179 | " * Download dependency sources\n" 180 | " * ExternalProject_Add -> target\n" 181 | " # Feed them CMAKE_ARGS\n" 182 | " * External project for GBA libraries\n" 183 | "- Loop through library variants\n" 184 | "- Piggyback on everything: CPACK, testing, infra\n" 185 | "- Theme: target/host lib and includes mixing\n" 186 | "- Use BMT as example", 187 | 188 | 189 | " CMake argument themes\n\n" 190 | 191 | "- Set target\n" 192 | "- Specify building for embedded\n" 193 | " * -DLIBCXX_ENABLE_STATIC=ON\n" 194 | " * CMAKE_SYSTEM_NAME=Generic\n" 195 | " * -D*_BAREMETAL*=ON\n" 196 | "- Feature options\n" 197 | "- Where are tools, config files\n" 198 | "- Where is target sysroot\n" 199 | "- test/build configuration", 200 | 201 | 202 | " CMake example: compiler-rt\n\n" 203 | 204 | "-DCMAKE_TRY_COMPILE_TARGET_TYPE=\n" 205 | " STATIC_LIBRARY\n" 206 | "-DCOMPILER_RT_BUILD_BUILTINS=ON\n" 207 | "-DCOMPILER_RT_BUILD_SANITIZERS=OFF\n" 208 | "-DCOMPILER_RT_BUILD_XRAY=OFF\n" 209 | "-DCOMPILER_RT_BUILD_LIBFUZZER=OFF\n" 210 | "-DCOMPILER_RT_BUILD_PROFILE=OFF\n" 211 | "-DCMAKE_C_COMPILER_TARGET=\n" 212 | "-DCMAKE_ASM_COMPILER_TARGET=", 213 | 214 | 215 | " CMake: compiler-rt cont..\n\n" 216 | 217 | "-DCMAKE_C_COMPILER=${BIN}/clang\n" 218 | "-DCMAKE_AR=${BIN}/llvm-ar\n" 219 | "-DCMAKE_NM=${BIN}/llvm-nm\n" 220 | "-DCMAKE_RANLIB=${BIN}/llvm-ranlib\n" 221 | "-DCOMPILER_RT_BAREMETAL_BUILD=ON\n" 222 | "-DCOMPILER_RT_DEFAULT_TARGET_ONLY=\n" 223 | " ON\n" 224 | "-DLLVM_CONFIG_PATH=${BIN}/llvm-config\n" 225 | "-DCOMPILER_RT_INCLUDE_TESTS=OFF", 226 | 227 | 228 | " CMake: runtimes\n\n" 229 | 230 | "-DLIBCXXABI_USE_COMPILER_RT=ON\n" 231 | "-DLIBCXXABI_USE_LLVM_UNWINDER=ON\n" 232 | "-DLIBCXX_ENABLE_RANDOM_DEVICE=OFF\n" 233 | "-DLIBCXX_ENABLE_RTTI=OFF\n" 234 | "-DLIBCXX_ENABLE_WIDE_CHARACTERS=OFF\n" 235 | "-DCMAKE_SYSTEM_NAME=Generic\n" 236 | "-DCMAKE_TRY_COMPILE_TARGET_TYPE=\n" 237 | " STATIC_LIBRARY\n" 238 | "-DLIBC_LINKER_SCRIPT=picolibcpp.ld\n", 239 | 240 | 241 | " CMake: runtimes cont..\n\n" 242 | 243 | "-DLIBCXXABI_BAREMETAL=ON\n" 244 | "-DLIBCXXABI_ENABLE_STATIC=ON\n" 245 | "-DLIBCXXABI_ENABLE_ASSERTIONS=OFF\n" 246 | "-DLIBCXXABI_LIBCXX_INCLUDES=\n" 247 | " '${INSTALL_DIR}/include/c++/v1'\n" 248 | "-DCOMPILER_RT_INCLUDE_TESTS=ON\n" 249 | "-DCMAKE_INSTALL_PREFIX=", 250 | 251 | 252 | "Individual components\n\n" 253 | 254 | "What to look out for\n" 255 | "GBA issues\n" 256 | "Hot topics", 257 | 258 | 259 | "Clang\n\n" 260 | 261 | "- ARMv4 lowest supported Arm arch in LLVM\n" 262 | "- Arm: Clang defaults to ARMv4T/ARM7TDMI\n" 263 | "- Bare metal file:\n" 264 | " clang/lib/Driver/ToolChains/BareMetal.cpp\n" 265 | "- handles things like -nostdinc, multilib\n" 266 | "- Compiling old GBA programs:\n" 267 | " * Not too happy with pre-UAL syntax\n" 268 | " + Thumb: mov -> movs\n" 269 | " + ARM: stmneia -> stmiane\n" 270 | " * No long-call fn attr, no -mthumb-interwork", 271 | 272 | 273 | " Multilib issues\n\n" 274 | 275 | "- embedded affliction, complex build systems\n" 276 | "- GCC has spec files\n" 277 | "- issues to solve\n" 278 | " * need to build lots of libraries for variants\n" 279 | " * Libraries not mapping to target triples\n" 280 | " * hardwiring library paths in C++ code\n", 281 | 282 | 283 | " Multilib solution\n\n" 284 | 285 | "- More flexible option based on:\n" 286 | " * normalizing cmdline arguments\n" 287 | " * yaml files containing rules\n" 288 | " + variant\n" 289 | " + matchers\n" 290 | "- Sets -sysroot, -isystem, -L\n" 291 | "- Can compose multiple matches\n" 292 | "- Currently not working for GBA\n" 293 | " * Tiny bug when building for thumb\n" 294 | " * Can be fixed with matcher rule.\n", 295 | 296 | 297 | " Linking\n\n", 298 | 299 | "- GBA memory region overview\n" 300 | "- Linker script overview\n" 301 | "- Linker issues\n" 302 | "- Linker what's hot", 303 | 304 | 305 | " Linker script/startup code what\n\n" 306 | 307 | "- Linker script\n" 308 | " * Define memory regions\n" 309 | " * What goes in them\n" 310 | "- startup code\n" 311 | " * Copy data from rom to ram\n" 312 | " * Zero initialize .bss\n" 313 | " * Call routines from .init_array\n" 314 | " * Call main\n", 315 | 316 | 317 | " Linker issues\n\n" 318 | 319 | "- For ARMv4T\n" 320 | " * Long branches and Arm/Thumb interworking" 321 | " - uses BLX\n" 322 | " - no MOVW/MOVT\n" 323 | "- For GBA:\n" 324 | " * Using DevkitPro linker script \n" 325 | " * LLD didn't accept overlay syntax\n" 326 | " * C++ data section names\n" 327 | " * clib incompatibilities\n" 328 | " * Add picolibc stubs", 329 | 330 | 331 | " Linker improvements\n\n" 332 | 333 | "- LTO\n" 334 | " * Respect code regions\n" 335 | " * Still bunch of issues\n" 336 | " * Code size can worsen\n" 337 | "- Distribute code over memory locations\n" 338 | "- Compression\n" 339 | "- Debuggability\n" 340 | "- Place section at specific address\n" 341 | "- Automatic overlays", 342 | 343 | 344 | " compiler-rt\n\n" 345 | 346 | "- Runtime support\n" 347 | "- builtins: low-level target-specific hooks\n" 348 | "- libgcc drop-in replacement\n" 349 | "- Also sanitizers, profiling, fuzzing, xray,\n" 350 | " scudo, BlocksRuntime, etc..\n" 351 | "- Currently only builtins\n" 352 | "- For ARMv4(T) there was no builtins target\n" 353 | " * Easy to fix\n" 354 | "- You get ubsan for free. It's cheap.\n" 355 | "- Demo time", 356 | 357 | 358 | " clib\n\n" 359 | 360 | "- Newlib(-nano), picolibc, LLVM Libc, etc..\n" 361 | "- Went with picolibc\n" 362 | " * BSD license\n" 363 | " * Newlib doesn't have LLVM config\n" 364 | " * Responsive maintainers\n" 365 | " * More suitable for embedded development\n" 366 | "- LLVM Libc \n" 367 | " * Looks promising, but needs work\n" 368 | " * Talks underway on scalability\n" 369 | "- GBA: implement stdout and friends", 370 | 371 | 372 | " libcxx\n\n" 373 | 374 | "- LLVM libcxx\n" 375 | " * Make more efficient for embedded\n" 376 | "- On GBA\n" 377 | " * Butano, a popular GBA C++ engine, uses ETL\n" 378 | " (Embedded Template Library)\n" 379 | " + Optimized for embedded applications\n" 380 | "- Distributed as source?\n" 381 | "- carving of functionality", 382 | 383 | 384 | " LLDB\n\n" 385 | 386 | "- Works with mGBA emulator\n" 387 | "- Also works from VSCode\n" 388 | " * Use CodeLLDB or lldb-vscode from toolchain\n" 389 | "- Shout-out to David Spickett", 390 | 391 | 392 | " GBA tools\n\n" 393 | 394 | "- Grit\n" 395 | "- gbafix\n" 396 | "- GBFS\n" 397 | "- Maxmod\n" 398 | "- posprintf\n" 399 | "- Apex Audio System\n" 400 | "- Aseprite\n" 401 | "- Propulse Tracker", 402 | 403 | 404 | " Performance / Coremark\n\n" 405 | 406 | "- Industry standard embedded benchmark\n" 407 | "- (iterations/sec) / Mhz, single-core\n" 408 | "- examples:\n" 409 | " * Cortex-M0 minimal gate-count: 2.33\n" 410 | " * Cortex-M85 high end embedded: 6.28\n" 411 | " * NXP LS2088A (Cortex-A72): 36.10\n" 412 | "- Small binary size (sub 30K), fits in IWRAM\n" 413 | "- loop unrolling: from 26K to 140K\n" 414 | "- jump threading, inline|unroll-threshold\n" 415 | " * less size bloat (~ 1K each)", 416 | 417 | 418 | " Resources\n\n" 419 | 420 | "- Discord: LLVM -> #embedded-toolchains\n" 421 | "- Discourse:\n" 422 | " * LLVM Embedded Toolchains Working group\n" 423 | "\n" 424 | "sites:\n" 425 | "- http://gbadev.net/getting-started.html\n" 426 | "- https://github.com/ARM-software/\n" 427 | " LLVM-embedded-toolchain-for-Arm\n" 428 | "- https://clang.llvm.org/docs/Multilib.html", 429 | 430 | 431 | " The end\n\n" 432 | 433 | "- did we actually manage to get here?\n" 434 | "- questions?" 435 | }; 436 | 437 | u32 text_slide_len = sizeof(text_slides)/sizeof(text_slides[0]); 438 | u32 text_slide_cur = 0; 439 | 440 | void write_slides() { 441 | tte_write("#{es;P}"); 442 | tte_write(text_slides[text_slide_cur]); 443 | } 444 | 445 | void toggle_text() { 446 | REG_BLDCNT ^= 3 << 6; 447 | REG_DISPCNT ^= DCNT_BG0; 448 | } 449 | 450 | void text_on() { 451 | REG_BLDCNT |= 3 << 6; 452 | REG_DISPCNT |= DCNT_BG0; 453 | } 454 | 455 | void update_slides(s32 key_tri) { 456 | if (key_tri < 0) { 457 | if (text_slide_cur == 0) 458 | text_slide_cur = text_slide_len - 1; 459 | else 460 | text_slide_cur--; 461 | text_on(); 462 | write_slides(); 463 | } else if (key_tri > 0) { 464 | if (text_slide_cur == text_slide_len - 1) 465 | text_slide_cur = 0; 466 | else 467 | text_slide_cur++; 468 | text_on(); 469 | write_slides(); 470 | } 471 | } 472 | -------------------------------------------------------------------------------- /examples/tonc-write-text/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(GBA_LLVM)),) 2 | GBA_LLVM = ../.. 3 | endif 4 | 5 | NAME = test 6 | 7 | BIN = $(GBA_LLVM)/bin 8 | CC = $(BIN)/clang 9 | GBAFIX = $(BIN)/gbafix 10 | CFLAGS = -O3 -mthumb --config armv4t-gba.cfg -Wl,-T,gba_cart.ld -ltonc 11 | 12 | C_FILES = $(NAME).c 13 | 14 | $(NAME).gba: $(NAME).elf 15 | $(BIN)/llvm-objcopy -O binary $^ $@ 16 | $(GBAFIX) $@ 17 | 18 | $(NAME).elf: $(C_FILES) 19 | $(CC) -o $@ $^ $(CFLAGS) $(LFLAGS) 20 | 21 | .PHONY: clean 22 | 23 | clean: 24 | rm $(NAME).elf $(NAME).gba 25 | -------------------------------------------------------------------------------- /examples/tonc-write-text/test.c: -------------------------------------------------------------------------------- 1 | #include "tonc.h" 2 | 3 | int main() { 4 | irq_init(NULL); 5 | irq_add(II_VBLANK, NULL); 6 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0; 7 | 8 | tte_init_se( 9 | 0, // Background number (BG 0) 10 | BG_CBB(0)|BG_SBB(31), // BG control (for REG_BGxCNT) 11 | 0, // Tile offset (special cattr) 12 | CLR_GRAY, // Ink color 13 | 14, // BitUnpack offset (on-pixel = 15) 14 | NULL, // Default font (sys8) 15 | NULL); // Default renderer (se_drawg_s) 16 | 17 | tte_write("Hello Tonc World!"); 18 | 19 | while(1) 20 | vid_vsync();; 21 | 22 | return 1; 23 | } 24 | -------------------------------------------------------------------------------- /examples/ubsan/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(GBA_LLVM)),) 2 | GBA_LLVM = ../.. 3 | endif 4 | 5 | NAME = test 6 | 7 | BIN = $(GBA_LLVM)/bin 8 | CC = $(BIN)/clang 9 | GBAFIX = $(BIN)/gbafix 10 | CFLAGS = -O2 -mthumb --config armv4t-gba.cfg -Wl,-T,gba_cart.ld -fsanitize=undefined -fsanitize-trap=undefined -ftrap-function=draw_screen 11 | 12 | C_FILES = $(NAME).c 13 | 14 | $(NAME).gba: $(NAME).elf 15 | $(BIN)/llvm-objcopy -O binary $^ $@ 16 | $(GBAFIX) $@ 17 | 18 | $(NAME).elf: $(C_FILES) 19 | $(CC) -o $@ $^ $(CFLAGS) $(LFLAGS) 20 | 21 | .PHONY: clean 22 | 23 | clean: 24 | rm $(NAME).elf $(NAME).gba 25 | -------------------------------------------------------------------------------- /examples/ubsan/README.md: -------------------------------------------------------------------------------- 1 | # What is this 2 | 3 | This is a very simple undefined behaviour sanitizer test. 4 | 5 | When compiling the example we turn on the [undefined behaviour 6 | sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html), and 7 | specify that when we detect undefined behaviour (read past the end of an array) 8 | we execute the `draw_screen` function, which will paint the screen red: 9 | 10 | -fsanitize=undefined -fsanitize-trap=undefined -ftrap-function=draw_screen 11 | 12 | # How to build 13 | 14 | type: 15 | 16 | ```make``` 17 | -------------------------------------------------------------------------------- /examples/ubsan/test.c: -------------------------------------------------------------------------------- 1 | void draw_screen() { 2 | // set background mode 3 (bitmap) and turn on background 2 3 | *(unsigned long*) 0x4000000 = 0x403; 4 | 5 | unsigned short* vram = (unsigned short*) 0x6000000; 6 | // write red to every pixel on the 240x160 screen 7 | for(int x = 0; x < 240; x++) 8 | for(int y = 0; y < 160; y++) 9 | vram[x + y * 240] = 31; 10 | 11 | const char *arr[] = { 12 | "0", 13 | "1", 14 | }; 15 | 16 | } 17 | 18 | int get_ubsan_arr(int index) { 19 | const int arr[] = { 20 | 0, 21 | 1, 22 | }; 23 | return arr[index]; 24 | } 25 | 26 | int main() { 27 | get_ubsan_arr(2); 28 | while(1) {}; 29 | return 1; 30 | } 31 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": [ 3 | "Set your preferred repo versions.", 4 | "This file is queried by CMake and other automation software." 5 | ], 6 | "repos": { 7 | "bmt": { 8 | "comment": "tagType can be branch, tag or commithash", 9 | "tagType": "branch", 10 | "tag": "main" 11 | } 12 | } 13 | } 14 | --------------------------------------------------------------------------------