Compare commits

..

228 Commits

Author SHA1 Message Date
ISSOtm
08f3e360c9 Release v0.7.0 2023-12-31 13:18:52 +01:00
ISSOtm
0524eeb61a Remove .Tg macro
Downstream support seems to be too sparse for the time being,
not worth the tiny gain we get from it
2023-12-31 13:18:37 +01:00
Rangi
b0f2f0ffd6 Allow fewer tRNS entries than PLTE colors (#1284) 2023-12-31 12:47:53 +01:00
ISSOtm
528a4c0b70 Get rid of macOS hack to try having the filesystem cake and eat it too 2023-12-30 23:20:04 -05:00
ISSOtm
6b559e99b2 Revert "Switch to using std::filesystem (#1235)"
This reverts commit cf62ff772f.
Some functions used by this break on macOS before 10.15,
which we want to keep supporting.
2023-12-30 23:20:04 -05:00
ISSOtm
93d1d85f94 Generate macOS static bins under correct name
168950855 only did one half of the job, lol.
2023-12-29 23:25:28 +01:00
Rangi
1f3985a164 Fix build compatibility for macOS 10.14 and below (#1280)
macOS 10.15 introduced full `std::filesystem::path` support.
Before that our use of it would cause the build to fail.
This was not caught because "-mmacosx-version-min=10.9" was only
being passed to clang++ for release builds.

This passes that flag in a new static CI test build, and introduces
a hack developed by @LIJI32 to silence the availability errors,
since we use features already available in macOS 10.9.

This means we are testing both "vanilla" building,
and building static binaries using the same configuration
as during release, which should help avoiding last-minute
surprises.
2023-12-29 22:47:11 +01:00
Ron Nelson
dc5d3a7342 Fix "build from source" link in README (#1281) 2023-12-29 02:35:59 +01:00
Eldred Habert
ccf9dcb851 Improve linker scripts a little (#1275)
* Allow for optional sections in linker scripts
  These are more useful for frameworks/toolchains.

* Check for an active mem region everywhere
  Do you like segfaults? Too bad!

* Allow the address to be floating in linker scripts
  Try and make the life of SDCC interop easier.

* Also validate alignment when floating

* Overhaul the linker script manual page
  Documenting the new features, but also restructuring the
  existing documentation to make the manual page (hopefully)
  easier to understand.
2023-12-24 23:29:11 -05:00
Rangi42
7b199d7550 Fix documentation for ATAN2's (y, x) argument order 2023-12-24 03:59:01 -05:00
ISSOtm
98cecaee9e Fix some formatting errors in man pages 2023-12-24 17:12:38 +01:00
Rangi
d5cddb202c Update the man pages' dates and history (#1279) 2023-12-23 00:15:35 +01:00
Rangi42
09dbc50447 Some refactoring 2023-12-18 15:51:13 -05:00
Rangi
fdd45ab1dc Improve linker script align (#1271)
An offset is now supported, and invalid values are no longer silently
truncated, aligning behaviour with other instances of the directive.
2023-12-18 07:16:48 +01:00
Rangi
39018174c5 Scramble banks from the end of the ROM (#1273)
This is more likely to test edge cases, such as having content in banks with their highest bit set.
2023-12-17 20:14:03 -05:00
Rangi
5a3a215b0e Don't delete script.cpp after building (#1272)
Ensure consistency in linker script parser interface

Make the declaration and definition visible when compiling
so that the compiler can warn about inconsistencies.

Co-authored-by: ISSOtm <me@eldred.fr>
2023-12-17 11:42:07 -05:00
Rangi
495d701022 Use RANGE macro to abbreviate begin/end pairs (#1269) 2023-12-11 14:10:20 -05:00
Rangi
b886b7e611 Add LADX disassembly to test suite (#1265) 2023-12-11 18:21:38 +01:00
Eldred Habert
fd78a9ae83 Port linkerscript parser to Bison (#1266)
Notable side effects:
* Use the standard-conformant MSVC preproc
* Add test for linker script INCLUDE
* Improve wording of placement conflict errors
* Fix errors from not newline-terminated files
* Teach checkdiff about the linker script doc
* Call linker script "commands" "directives" instead

---------

Co-authored-by: Rangi42 <remy.oukaour+rangi42@gmail.com>
2023-12-11 02:29:37 +01:00
Antonio Vivace
ab30690854 readme: improve wording on how to reach maintainers 2023-12-10 23:10:43 +01:00
Rangi
34b2543c8b Implement -X/--max-errors for RGBASM (#1262)
Co-authored-by: Eldred Habert <me@eldred.fr>
2023-12-07 11:42:47 +01:00
Rangi
1fa289f2ee Add SameBoy's BootROMs to the test suite (#1264) 2023-12-06 22:37:59 +01:00
Rangi
22ff7ff101 Add PinoBatch's game Libbet to the test suite (#1260) 2023-12-06 10:30:11 +01:00
Rangi
1402615bc0 Refactor how Makefile invokes Bison for reusability (#1259)
Co-authored-by: Eldred Habert <eldredhabert0@gmail.com>
2023-12-01 13:29:05 -05:00
Rangi
6132b77c1e Add more tests for RGBASM code coverage (#1257)
* Add more tests for RGBASM code coverage

* Use C++ unnamed parameters, not `(void)` casting

* Fix crash in `sect_AlignPC` from #1253
2023-12-01 10:21:43 -05:00
Rangi
cee3d1c859 Add more test coverage for RGBASM (#1256)
This also fixes two bugs: `-1 >>> 32` was -1 not 0, and `macro_FreeArgs` should have been called but wasn't.
2023-11-29 15:16:05 -05:00
Rangi42
b46aa0f55b colour->color, behaviour->behavior
These spellings are more common elsewhere in the codebase
2023-11-27 16:02:17 -05:00
Eldred Habert
e1220d6fc6 Acknowledge Liji's contribution to RGBGFX
Make their help with #1241 more prominent, since it won't appear in the commit log
2023-11-27 18:04:30 +01:00
Rangi
2ebd7f2ea3 Allow negative alignment offsets (#1255) 2023-11-25 09:40:20 +01:00
Rangi
756f2866bb Refactor alignment spec parsing (#1253) 2023-11-25 00:06:05 +01:00
Rangi
92836408cc Remove empty .out and .err test files (#1249)
Co-authored-by: ISSOtm <me@eldred.fr>
2023-11-24 17:52:55 -05:00
ISSOtm
c5721b749c Use proper style to document long opts
Correct mandoc style is to use `Fl \-`, not `Fl Fl`, apparently.
2023-11-24 21:41:21 +01:00
ISSOtm
6f0defbfe5 Fix shellcheck warnings in the test scripts
Making them more robust to changes.
We ought to automate this some day.

My version of ShellCheck (v0.9.0) errors on test/gfx/test.sh, though...
2023-11-24 20:54:28 +01:00
Eldred Habert
f4463b1708 Honor -c with rgbgfx -r (#1254)
Fixes #1166
2023-11-24 13:19:04 -05:00
Rangi
39e85c6dec Document pre-ASMotor history and add links (#1252) 2023-11-24 18:54:33 +01:00
ISSOtm
aa5b163944 Clean up RGBGFX's "SEE ALSO" section
Applying the previous fix there, plus reordering xrefs more usefully.
2023-11-23 18:10:45 +01:00
ISSOtm
eb237ea4e1 Update link to Pan Docs gfx overview
"Rendering" is now a much lower-level description of the rendering
process, not exactly what we are looking for there :)
2023-11-23 18:08:18 +01:00
ISSOtm
27c1237daa Fix formatting errors in man pages
As reported by the following command:
mandoc -T lint man/* | grep -v "input text line longer than 80 bytes"
(One of them also showed up as a warning while setting up Debian packaging.)
2023-11-23 18:05:55 +01:00
Rangi
a218622d73 Remove checkpatch, since it's tuned for C not C++ (#1250)
Co-authored-by: Eldred Habert <eldredhabert0@gmail.com>
2023-11-22 19:26:08 +01:00
Rangi
46e29de66f Implement ds align[alignment, offset] (#1181) 2023-11-21 23:57:47 +01:00
Rangi
6f0ffcf3e1 Remove deprecated RGBGFX options (#1246) 2023-11-21 23:30:34 +01:00
Rangi
c7b39f094c Update the reverse color curve (#1241)
Based on SameBoy's "accurate modern" colour mapping.

Special thanks to @Rangi42 for her patience throughout development, @LIJI32 for researching the colour curve and helping with the creation of the reverse mapping (colour spaces are *fun*!), and @coffeevalenbat for testing :)
2023-11-21 19:41:18 +01:00
Rangi
f5ae6a80f0 Rename the RGBGFX --output-* options to --auto-* (#1245)
Fixes #1243
2023-11-21 17:52:16 +01:00
Rangi42
482160ea04 Prefer rpn_isKnown(expr) accessor to expr->isKnown directly 2023-11-21 10:46:59 -05:00
Rangi42
ad62421264 Use rpn_isKnown wrapper outside rpn.cpp 2023-11-21 10:33:35 -05:00
Rangi
083a82f6d1 Implement rgbgfx -O (#1240) 2023-11-21 10:19:44 -05:00
Eldred Habert
99671b8eb5 Avoid building test support programs by default with CMake (#1244)
Copy CMake-built test executables to test directory

Fixes CI failures on Windows.
CI should also have failed on Unices, but it turns out
we instead merely hit the fallback that the `make` path
relies on (building those executables with `make`),
which fails on Windows since `make` is not set up to
find libpng.
2023-11-21 09:54:22 -05:00
Rangi
3c0879a3c6 Fix spurious truncation warning (#1238) 2023-11-20 22:51:51 +01:00
Rangi
232416b30d Fix the hack for File::c_str to work (#1242) 2023-11-14 13:38:18 +01:00
Rangi
cf62ff772f Switch to using std::filesystem (#1235)
Allows better platform-agnostic path manipulation.
Also, using `std::optional` rather than empty strings allows
correctly handling empty arguments (treating them as such,
instead of acting as they were never passed).
2023-11-13 18:10:09 +01:00
Rangi
e824e34526 Use an iterator template for enum sequence loops (#1228) 2023-11-12 09:19:19 +01:00
Eldred Habert
d390db5c57 Remove references to C compiler from CI (#1234) 2023-11-11 20:50:36 -05:00
Rangi
31529524c8 Use some more C++20 features (#1231) 2023-11-11 20:47:53 -05:00
Rangi
dde9f2bb79 Rename some RPN constants for consistency (#1230) 2023-11-08 21:30:27 +01:00
Rangi
5711c088e5 Add exact dates for history (#1233)
Citations (I think these would be excessive in the readme itself, but maybe the dates could have links?):

- Carsten Sørensen's ASMotor: <http://otakunozoku.com/RGBDSdocs/geninfo.htm>
- Justin Lloyd's RGBDS: <http://otakunozoku.com/rednex-gameboy-development-system/>
- Vegard Nossum's rgbds-linux: <e895832b2b>
- Anthony J. Bentley's fork: <https://github.com/bentley/rgbds_/commits/?after=60451fd41fc6dd0446798c8598f5effaacc2d065+69> (prior to <https://gbdev.gg8.se/forums/viewtopic.php?id=81>)
- Rednex move: <0588e42520>
- MIT relicensing: <1a5c423984>
- Gbdev move: <6eb284f99e>

The "neutral name" is clarified as Rednex, since we still use that name elsewhere in the readme, the sidebar, etc.
2023-11-08 21:25:27 +01:00
Rangi
765ae3f484 Build a code coverage report with gcov and lcov (#1221) 2023-11-08 00:03:26 +01:00
Rangi
f3dbf17b78 AUTHORS and more copyright comments are redundant with CONTRIBUTORS.rst (#1227) 2023-11-07 17:57:59 -05:00
Rangi
8eeb40cca8 Implement #"raw strings" (#1122)
Fixes #1121
2023-11-07 23:48:23 +01:00
Rangi
9fc088dcb0 Fix the FOR loop count formula (#1222) 2023-11-07 23:43:46 +01:00
Rangi
5379e51094 Make requested revisions to recent PRs (#1195) 2023-11-07 23:11:08 +01:00
Rangi
05a0905582 Fix the rgbgfx color curve (#1200) 2023-11-07 22:24:37 +01:00
Rangi
1e70e703a7 Build everything as C++ (#1176) 2023-11-07 21:45:56 +01:00
Rangi
78d83be2b2 Have the eqn preprocessor run on rgbasm(5) and rgbgfx(1) (#1225) 2023-11-07 18:08:13 +01:00
Rangi
a28f32a8a0 Download libpng source from GitHub, not SourceForge (#1223) 2023-11-07 08:29:01 +01:00
Rangi42
7a1e052b58 Factor out one shared enum FileStackNodeType 2023-11-07 08:27:03 +01:00
Rangi42
02f9128d07 Make some changes noticed while porting to C++ 2023-11-07 08:27:03 +01:00
Rangi
6ac1dd8966 Fix RGBGFX -r with -d 1 (#1224) 2023-11-07 08:25:30 +01:00
Eldred Habert
968c6f7ab7 Compute height and width directly in tile units
Co-authored-by: Rangi <35663410+Rangi42@users.noreply.github.com>
2023-11-06 08:14:13 +01:00
ISSOtm
93285f8ea8 Fix use of input slice without dedup active 2023-11-06 08:14:13 +01:00
Rangi
28358b55fe Separate multiple instructions per line with :: (#1210) 2023-11-05 19:13:33 +01:00
Rangi
0afb6cd53c Reminder to update the Dockerfile version for a release (#1219) 2023-11-05 18:54:15 +01:00
Rangi
143e76b7e3 Output the map file summary at the top of the file (#1203) 2023-11-05 15:43:58 +01:00
Rangi
f8af569680 Shorten license comments and consolidate an AUTHORS file (#1217) 2023-11-05 09:54:32 +01:00
Rangi
259ec58140 Implement ENDSECTION (#1211) 2023-11-04 23:41:17 +01:00
Rangi
99727cbe99 #!/bin/bash -> #!/usr/bin/env bash (#1216) 2023-11-04 23:37:34 +01:00
Rangi
46e67ee078 Remove deprecated RGBASM features (#1215)
- Escaped commas "\," inside strings
- `name: MACRO` syntax
- `__FILE__` and `__LINE__`
- `-H/--nop-after-halt` and `-l/--auto-ldh` on by default
2023-11-04 23:22:46 +01:00
Rangi
28d92b7be3 Update ucity for testing (#1212) 2023-11-04 10:23:27 +01:00
Rangi
c869edd1d2 Implement SIZEOF and STARTOF for section types (#1205) 2023-11-03 08:50:04 +01:00
Rangi
8f3369fe29 Implement DS for linker scripts (#1206) 2023-11-03 08:47:22 +01:00
Rangi
477e9812d4 Actually use PNGCFLAGS to build rgbgfx (#1209) 2023-11-03 08:37:18 +01:00
Rangi
9e4b9e75e3 Sort symbols by address, then parentage, then index (#1186) 2023-11-02 23:58:25 +01:00
Rangi
55f946198b Update the ucity repo being tested (#1207) 2023-11-02 23:57:13 +01:00
Rangi
181512ad9d Implement INCHARMAP function (#1184) 2023-11-02 20:14:54 +01:00
Rangi
5a25c547ab Allow rgbgfx to generate a palette from a spec, without an image (#1192) 2023-11-02 20:12:48 +01:00
Rangi
0d72ba886b Consistent behavior with missing or incorrect parameters (#1179) 2023-11-02 17:40:40 +01:00
Rangi42
a64f28de5c Avoid using %# printf specifier 2023-11-02 17:38:10 +01:00
Rangi42
b4dbb5093a Warn when SGB compatibility is set without old licensee 0x33 2023-11-02 17:38:10 +01:00
Rangi
e7d0428a2e Explicitly specify which files build with PNGCFLAGS (#1201) 2023-11-02 17:36:46 +01:00
Rangi
bb7c34db65 Deprecate DEF-less definitions (#1193) 2023-11-02 10:18:59 +01:00
Rangi
02f06407b1 Correct documentation for rgbgfx -r (#1197) 2023-11-02 07:59:46 +01:00
Rangi
73e9aac135 Update the pret repos being tested (#1198) 2023-11-01 23:07:41 +01:00
Rangi
32bc68d06d Don't export anonymous labels (#1185) 2023-11-01 00:06:28 +01:00
Antonio Vivace
a5d51b4330 readme: update email 2023-10-31 20:21:51 +01:00
Rangi
79948be3a0 Improve incorrect object file revision error (#1189)
Fixes #1118
2023-10-31 15:04:27 -04:00
Rangi42
ab42eb2c50 Document STRUPR/STRLWR as ASCII-only 2023-10-31 14:28:38 -04:00
Rangi42
45c2a5e4ec Consistently use uppercase hex digits 2023-10-31 14:28:38 -04:00
Rangi
ae38ebaf6f Clarify documentation of RGBGFX deduplication (#1191)
Fixes #1169
2023-10-31 14:28:14 -04:00
Rangi
80bdc889f8 Revise documentation for rgbasm -p (#1190)
Fixes #1125
2023-10-31 14:27:59 -04:00
Rangi
84f3cb4075 ENDL restores the label scope from before LOAD (#1180) 2023-10-26 22:58:36 +02:00
Rangi
22def89760 Save and restore opt r on the stack. (#1178)
Fixes #1174
2023-10-26 22:54:42 +02:00
Rangi
a15f1a52c7 contributing: update repository links (rednex -> gbdev org) (#1177) 2023-10-26 00:44:01 +02:00
Quinn
944c5f0cd0 Implement order-independent purge (#1173)
Each symbol passed to purge is collected in a list before mass removal.
Fixes the issue described in gbdev/rgbds issue #1152.

---------

Co-authored-by: Rangi42 <remy.oukaour+rangi42@gmail.com>
2023-10-25 22:34:56 +02:00
Antonio Vivace
7a39e9e569 Add dockerfile to build and run RGBDS (#1167) 2023-09-14 17:17:53 +02:00
ISSOtm
cfe432ea65 Enforce that transparent colours take slot #0 in all palettes 2023-08-26 23:23:28 +02:00
ISSOtm
36bfeea8dc Silence spurious GCC warning 2023-08-26 22:57:06 +02:00
Damian Yerrick
7b3a05eea8 Add --only-free and --help options to test scripts (#1161) 2023-08-20 13:46:00 -04:00
Damian Yerrick
e1f0a13e5a Allow defining local labels for another scope (#1159)
fix #1157 for the following source code

```
section "hSAVE_locals",HRAM
func3.hSpam: ds 1  ; no longer produces an error
;.hEggs: ds 1      ; uncomment this to see the new error

section "demo",ROM0
func3:
  ldh a, [.hSpam]
  ret
```

Remove two errors:
- `Not currently in the scope of 'func3'`
- `Local label 'func3.hSpam' in main scope`

Add one error:
- `Relative local label '.hSpam' in main scope`

Co-authored-by: Rangi <35663410+Rangi42@users.noreply.github.com>
2023-08-20 02:29:53 +02:00
Eldred Habert
e634888a50 Improve description of rgblink -O (#1162) 2023-08-19 11:52:09 +02:00
Eldred Habert
168950855d Create statically-linked Linux binaries on release (#1148)
Co-authored-by: Antonio Vivace <avivace4@gmail.com>
2023-07-08 22:04:00 +02:00
Robbi-Blechdose
a2e0ac2872 Fix typos reported by lintian (#1147)
From https://mentors.debian.net/package/rgbds/#upload-1
2023-06-24 16:26:04 +02:00
ISSOtm
6d806238fb Improve bit rotation/shift explanations by using Unicode box diagrams
The existing explanations have proven confusing to many,
and presenting the instructions in a more visual manner should help a lot.

Additionally, the Unicode codepoints are typed as-is in the source,
because that allows much more WYSIWYG editing, and god damn it this is the year
two thousand and twenty three, if your man and/or terminal software does't
support Unicode, then what are you *doing*.
2023-06-17 12:38:52 +02:00
Evie
a0dfa916e6 Fix off-by-one error in "scramble spec" validation (#1144) 2023-06-16 09:28:19 +02:00
Eldred Habert
9748524ef6 Fix incorrect options in RGBGFX zsh completions 2023-06-13 07:57:24 +02:00
Tian(Maxwell) Yang
718cfa133f Fix SRL [HL] Flags link 2023-05-23 08:29:40 +02:00
Rangi
4cadc6f0fe \en not \n is a newline in troff 2023-03-04 18:36:22 -05:00
Eldred Habert
2023d9ed99 Fix palmap option using wrong file name 2023-02-21 12:05:39 +01:00
ISSOtm
6828f7bf49 "Hook up" new releases' docs 2023-02-08 01:45:35 +01:00
ISSOtm
33a0857b8d Properly detect tiles with more than 4 colours
Fixes #1127, which was caused by a dumb logic error. Duh me.
2023-02-08 00:21:05 +01:00
Antonio Vivace
4e712807d7 funding: add GitHub sponsors 2023-01-19 22:07:14 +01:00
ISSOtm
2d15e40539 Fix WRAM0/WRAMX test
The previous test did not expect failure when trying to stuff
$3000 bytes into $2000-byte WRAM; this is now fixed, and we
also test the reverse now (that we cannot stuff more than
$1000 bytes into WRAM0 without `-d`/`-w`.
2023-01-07 22:20:42 +01:00
Eldred Habert
50aaa6524d Fix -w not coercing WRAMX sections to WRAM0
Fixes #1116
2022-12-21 23:43:57 +01:00
Rangi
01f1703dfb Preserve \@ through INCLUDE
Fixes #1112
2022-12-11 18:56:03 +01:00
Rangi
69a573923f Version 0.6.1 2022-12-02 22:48:37 -05:00
ISSOtm
7eb4ecea8b Remove use of std::filesystem
This appears to break compatibility with macOS 10.9
2022-12-03 01:51:14 +01:00
ISSOtm
599ce757a1 Force Windows builds to use our zlib and libpng
Otherwise we will have a few problems if, say, a system version was
detected and picked up instead of ours...
2022-12-03 00:58:50 +01:00
ISSOtm
75a07a90f8 Always initialise section->data to avoid an uninit read
The addition of SDCC objects required a change in the logic of
`mergeSections()` to dispatch based on `->data` instead of
`sect_HasData`, which implicitly assumes that `->data` is
always initialised (maybe NULL).
However, RGBDS sections did not do that!
2022-12-02 22:39:31 +01:00
ISSOtm
ec2d1312ef Remove auto parameter to -flto
Not all supported compilers support the argument;
the move was a bit premature.
2022-11-15 19:49:04 +01:00
ISSOtm
03b6dd9321 Only cache dependency directories instead of whole test/
Otherwise, changes made to the test suite are not picked up
2022-11-15 19:49:04 +01:00
ISSOtm
a16d3d6405 Fail RGBGFX test suite if support test programs fail to be built 2022-11-15 19:49:04 +01:00
ISSOtm
3e5cd8ce1a Use a special name for stdin/stdout in diagnostics 2022-11-15 19:49:04 +01:00
ISSOtm
6902387991 Allow rgbgfx - for stdin and stdout
Closes #1087
2022-11-15 19:49:04 +01:00
ISSOtm
62b4f2b264 Upgrade to checkout action v3
No code changes, just uses Node 16 instead of the
deprecated Node 12
2022-11-13 14:33:03 +01:00
Rangi
79748afdc4 Align the "; Next union/fragment" comments with their symbols 2022-11-06 23:55:15 +01:00
Rangi
32cb0558e4 Print "; Next union/fragment" between "pieces" in .map file
Resolves #1099
2022-11-06 23:55:15 +01:00
rlewicki
92b2ac3c8c Remove duplicated EMPTY label in case no bank memory is used 2022-11-03 19:54:21 +01:00
rlewicki
0e67298dff Fix indention when writing EMPTY label inside link output.c file 2022-11-03 19:54:21 +01:00
Robert Lewicki
f6d218ed36 Fix regression tests failing due to invalid cache being restored (#1104) 2022-11-01 14:27:40 +01:00
Robert Lewicki
1a9fc964df #1082 Add cache check for external repositories used during testing (#1100)
Co-authored-by: Rangi <35663410+Rangi42@users.noreply.github.com>
Co-authored-by: Eldred Habert <eldredhabert0@gmail.com>
2022-10-25 08:39:19 +02:00
ISSOtm
48248faab0 Suppress CMake project maintainer warnings in CI 2022-10-16 12:21:54 +02:00
ISSOtm
58181c2d73 Hoist common Windows dep grabbing code to a script
Function courtesy of @aaaaaa123456789
2022-10-16 12:21:54 +02:00
ISSOtm
0f86084e08 Rename actions folder as scripts
It's clearer this way.
2022-10-16 12:21:54 +02:00
ISSOtm
c8e602dec1 Mangle the name of absolute sections
They are unlikely to be unique across files, actually
2022-10-15 23:16:04 +02:00
ISSOtm
b168717e91 Update zlib to 1.2.13
1.2.12 is no longer provided by upstream anymore,
which fails Windows CI
2022-10-15 22:02:34 +02:00
ISSOtm
930c2ac328 Require Bison 3.0.0 in CMakeLists
We actually require that version, so be explicit about it
to provide better error messages.
2022-10-13 11:02:33 +02:00
ISSOtm
28737d5778 Enable GLIBCXX_ASSERTIONS in make develop
Not sure it's very portable, but this is only the dev config
2022-10-12 01:23:37 +02:00
ISSOtm
12ba057b4f Check that colour slot is non-empty before checking for gray-ness
This is otherwise UB, and trips a GLIBCXX assertion (when enabled).
2022-10-11 21:39:32 +02:00
ISSOtm
0e0876b17f Print addr ranges for empty blocks as well
Mirrors what sections do, for clarity & consistency
2022-10-07 16:04:02 +02:00
Eldred Habert
b28eea24fc Update .github/workflows/create-release-artifacts.yaml
Co-authored-by: Rangi <35663410+Rangi42@users.noreply.github.com>
2022-10-04 12:50:46 -04:00
ISSOtm
a1e59ddc3d Avoid -x c++ affecting ${PNGLDLIBS}
version.c doesn't link to anything from libpng, so it'll be fine
2022-10-04 12:50:46 -04:00
ISSOtm
3fbdba31bf Build macOS binaries as well for releases 2022-10-04 12:50:46 -04:00
ISSOtm
d90a7e4302 Terminate RGBGFX when opening a file fails
`std::filebuf::open`'s result must be checked, though that's not obvious.
2022-10-04 13:58:05 +02:00
ISSOtm
7377a14245 Improve RGBASM's "input files" error messages slightly 2022-10-03 17:17:19 +02:00
Eldred Habert
e2136d60b2 Print a more user-friendly error message for leftover diff marks (#1089) 2022-10-03 16:52:29 +02:00
ISSOtm
74e40654e6 Sync release docs CI workflow with master
We should look into reusable workflows, really.
https://docs.github.com/en/actions/using-workflows/reusing-workflows
2022-10-03 01:50:17 +02:00
Rangi
f90857032c Version 0.6.0 2022-10-02 19:08:13 -04:00
Rangi
1653a9a3f2 Use -flto=auto 2022-10-02 13:50:35 -04:00
Rangi
3c049983f1 Fixed-point functions can take specific precision (#1086) 2022-10-02 16:56:08 +02:00
Rangi
8553b61a94 Fixed-point values can use all 32-Q magnitude bits (#1085) 2022-10-02 11:08:38 +02:00
ISSOtm
ab12c474d2 Properly exclude GCC from macOS matrices 2022-10-02 02:50:38 -04:00
ISSOtm
8ccbd9dc36 Properly build and link against libpng
Doing it right this time.
Also bundling the newly required DLLs.
2022-10-02 02:50:38 -04:00
ISSOtm
b8307432b8 Fix use of bitwise OR instead of logical
Thanks, Clang!
2022-10-02 02:50:38 -04:00
ISSOtm
80a62a8a03 Update CI target OSes
Remove platforms deprecated by GitHub Actions
Add new platforms supported by the same
2022-10-02 02:50:38 -04:00
Rangi
bbe28faab4 Sort rgbgfx's -r option alphabetically 2022-10-01 21:22:39 -04:00
Rangi
106ad30e5a Allow fixed-point constants to have unsigned range (#1084)
For example with Q.4, $F0 is 15.0, which no longer warns
2022-10-01 23:32:34 +02:00
Rangi
a1107fc5cf Refactor !!x to x != 0
Also limit comments and docs to single "!"s
2022-10-01 14:09:02 -04:00
Rangi
969412af24 Parse HEX palettes (#1081)
Addresses one item of #1065
2022-10-01 12:45:00 -04:00
Eldred Habert
c10345f26d Comply with sym file spec (#1078)
Co-authored-by: Rangi <35663410+Rangi42@users.noreply.github.com>
2022-10-01 12:35:00 -04:00
ISSOtm
6fd5c94b27 Document gbc pal spec format
I *knew* I had forgotten something!
2022-10-01 10:48:40 +02:00
Rangi
ddb1d0b6aa Parse GPL palettes, and fix PSP palette parsing (#1080)
Addresses one item of #1065
2022-10-01 10:46:13 +02:00
Rangi
08545643cf Only define @ and _NARG when they have values (#1073)
Fixes #1069

Co-authored-by: Eldred Habert <eldredhabert0@gmail.com>
2022-10-01 01:04:03 +02:00
Rangi
140c6b169e Patch pokecrystal to use embedded palettes 2022-10-01 00:51:14 +02:00
Rangi
d86d24bdc1 Remove legacy support for generating a palette with unused colors
If you need an explicit set of colors, possibly including
unused ones, use `-c`.

Fixes #1062
2022-10-01 00:51:14 +02:00
Eldred Habert
a1a919579c Add support for GBC palette dumps to -c (#1075)
Fixes #1063
2022-09-30 17:09:28 -04:00
Rangi
a47da5f71f Deprecate __FILE__ and __LINE__ (#1072)
Unlike C, these constants are not convenient for logging in macros,
since they always report the same data (their location in the macro).

Fixes #1068
2022-09-30 19:48:30 +02:00
Rangi
68ad926279 Patch projects so CI will build (#1071)
Fixes #1070
2022-09-30 12:19:11 +02:00
Rangi
dec4133e84 SECTION(symbol) returns the name of a symbol's section (#1066)
Fixes #963

Co-authored-by: Eldred Habert <eldredhabert0@gmail.com>
2022-09-30 01:59:33 +02:00
Rangi
c35cb6ac32 Warning levels -Wunmapped-char=0/1/2 (#1061)
Fixes #1058
2022-09-29 18:14:04 -04:00
Rangi
023884d2b0 Redefine the trig functions to divide circles into 1.0 turns (#1060)
This makes their behavior consistent across Q settings

Fixes #1059
2022-09-29 10:57:29 +02:00
ISSOtm
3567faf395 Use backslash escape instead of "backwards slash" in man pages
The latter is in the "Lines" category, which seems inappropriate.
2022-09-26 09:45:25 +02:00
Eldred Habert
6502ed3919 Add -I as an alias for -i in rgbasm (#1056)
Co-authored-by: Rangi <35663410+Rangi42@users.noreply.github.com>
2022-09-26 03:42:30 -04:00
Rangi
b1a241233e Preserve Unix line endings for .bash and .flags files (#1054)
Fixes #955
2022-09-25 11:18:44 +02:00
Rangi
f88968ec20 Fix rgbasm -b and rgbasm -g (#1052)
Fixes #1051
2022-09-25 10:22:55 +02:00
Rangi
5ad8a8c958 Warn when a duplicate CLI argument overrides a previous one (#1053)
Fixes #1050
2022-09-25 10:04:30 +02:00
Rangi
2827374505 Use STD*_FILENO constants (#1055)
These are defined in platform.h, but not consistently used

Co-authored-by: Eldred Habert <eldredhabert0@gmail.com>
2022-09-25 10:02:53 +02:00
Rangi
b8385a50e3 Support -P/--preinclude to pre-INCLUDE a file (#1043)
Fixes #1041

Co-authored-by: ISSOtm <eldredhabert0@gmail.com>
2022-09-24 12:37:16 -04:00
ISSOtm
02923a67f3 Use tabs for indentation in map files
As requested by #1012
2022-09-24 12:58:48 +02:00
Rangi
f5b1990604 Document that symbol interpolation works outside of strings too 2022-09-22 01:15:17 -04:00
ISSOtm
0794da22bc Clarify at-files documentation 2022-09-13 08:34:41 +02:00
Rangi
6df75f7af3 Summarize used and free space at the end of the .map file
Fixes #1046
2022-09-12 23:16:09 +02:00
Rangi
7ae23e6cdb Release 0.6.0-rc2 2022-09-08 17:07:47 -04:00
Rangi
98a6dffbca Implement opt Q for fixed-point precision, and q literals (e.g. 12.34q8) (#958)
Fixes #957

Co-authored-by: ISSOtm <eldredhabert0@gmail.com>
2022-09-05 00:47:32 +02:00
Rangi
889302a9e2 Document the -H and -l flags
Fixes #1042
2022-09-02 08:43:41 +02:00
Rangi
c01317e08d Only increment the unique \@ ID when it is first used per context (#1030)
This avoids changes to generated `\@` labels just by adding or
removing macros or loops which do not actually use `\@`.

Fixes #1019
2022-08-31 17:45:21 -04:00
Rangi
a52a00a9ca macro_UndefUniqueID uses 0 to mean \@ is undefined 2022-08-30 16:50:34 -04:00
Rangi
fa13611bbf Make comments more consistent
- Changes most `/* comments */` to `// comments`
- Changes `/**` block comments consistently to `/*`
- Adds consistent license comments to all files

Also renames `T_POP_SET` to `T_Z80_SET`
2022-08-30 07:51:32 +02:00
Rangi
dca24a6d50 Test that OPT r fails immediately if the recursion depth is already exceeded
Fixes #1034
2022-08-28 22:21:24 +02:00
Rangi
4363ffcad4 Clarify the JR documentation based on its usage (#1032)
Fixes #1020
2022-08-28 15:42:04 -04:00
Rangi
14e6a79adc Deprecate the old macro syntax (#1025)
Fixes #1011
2022-08-28 15:22:21 -04:00
Rangi
7a2ee26792 rgbasm -r sets the maximum recursion depth (#1026)
Previously it set the minimum failure depth (off by one)

Fixes #978
2022-08-28 15:21:29 -04:00
Rangi
425339ccf6 Implement FMOD function for fixed-point modulo
Fixes #1021
2022-08-28 21:21:10 +02:00
Rangi
1a1f1365e6 Clarify the FOR loop documentation (#1031)
Clarify the FOR loop documentation

Fixes #1003

Co-authored-by: Eldred Habert <eldredhabert0@gmail.com>
2022-08-28 15:16:49 -04:00
Rangi
f97139461c Clarify the linkerscript example (#1028)
* Clarify the linkerscript example

* Explain that backslash escape sequences are supported

Fixes #1006
2022-08-28 15:13:43 -04:00
Rangi
8207dc57b7 Add a -Wunmapped-char warning for characters not in the charmap (#1023)
Fixes #1022
2022-08-28 15:12:43 -04:00
Rangi
d29057e747 Indent "SLACK:" to match the "SECTION" headers 2022-08-28 20:35:21 +02:00
Rangi
f1b74fa610 Report empty space between sections in map file 2022-08-28 20:35:21 +02:00
Rangi
c7a92d3104 rgblink -M omits symbol names from .map file 2022-08-28 20:35:21 +02:00
ISSOtm
0105779789 Fix incorrect Bash completions after --long-opt=
This is because `$COMP_CWORD` points to that `=` "word".
2022-08-10 08:44:41 +02:00
ISSOtm
9ef7954670 Fix some lint warnings in Bash completions 2022-08-10 00:16:05 +02:00
ISSOtm
d7d524294b Fix shebangs in Bash completion scripts
Not that you are really supposed to run them stand-alone?
2022-08-09 22:32:18 +02:00
ISSOtm
12fed4c68e Harden Bash completion scripts against invalid states
Printing an error message is better than locking the shell up, honestly.
2022-08-09 22:30:50 +02:00
ISSOtm
3db3421f07 Correct wrong state transitions in RGBGFX Bash completion script
Isn't strinly-typed programming just lovely?
Fixes #1018
2022-08-09 22:28:12 +02:00
ISSOtm
92eb0a133b Allow rgbgfx -r to read an infinite amount of tiles without tilemap
Previously, indices would be wrapped after 256 even without a tilemap;
since RGBGFX can generate arbitrarily large tile data if `-N` is not used,
it should be possible to read those in.

Of course, this won't work if a tilemap is provided, but such "big blobs"
can't generate a meaningful tilemap anyway.
2022-08-04 20:50:08 +02:00
ISSOtm
b02ccf8f4a Check before attempting to generate empty image
This causes a libpng warning then error, but print a better error message
Fixes #1016
2022-08-04 20:40:20 +02:00
ISSOtm
2e0991f32b Use proper 16-bit type for image reversing width
Fixes #1015
2022-08-04 20:40:20 +02:00
Eldred Habert
f3f2c2ca16 Improve object file format documentation (#1010)
Replacing the big pre-formatted text block with a list brings:
- Better accessibility, obviously
- Responsiveness
- Better formatting (bold, etc.)
- Sub-sections that can now be linked to
- Hyperlink cross-refs to other pages

The slight disadvantage is that `ENDC` etc. are now individual
list items, whereas they'd be better as part of the same item.
No big deal though, it was much worse before.

Some descriptions have been overhauled for clarity, and some
outright corrected (such as Assertions' "Offset" field).

Co-authored-by: Antonio Vivace <avivace4@gmail.com>
2022-07-29 22:48:55 +02:00
ISSOtm
9ec8186ac6 Switch linkdefs from scattered arrays to an array of structs
The info is better organized this way
2022-07-19 19:11:02 +02:00
ISSOtm
ab9945c1ee Avoid using fscanf to detect RGBDS object files
This function is made for text, e.g. accepts spaces, leading zeros, etc. before `%u`.
This way checks that the correct amount of bytes are read instead.
2022-07-19 19:10:58 +02:00
ISSOtm
18e4f132a8 Fix labels subtraction docs
Fixes #1009
2022-07-14 13:43:36 +02:00
ISSOtm
828b2adcdf Make RGBLINK able to link SDCC object files
This requires a LOT of tricky code, mostly due to the format itself being,
er, not the most straightforward.
Everything is converted to existing RGBLINK concepts (sections, patches,
etc.), so the core code is essentially unchanged.
(A couple of genuine RGBLINK bugs were uncovered along the way, so some of
the core code *is* changed, notably regarding `SECTION FRAGMENT`s.)

All of this code was clean-roomed, so SDCC's GPLv2 license does not apply.
2022-07-11 21:17:34 +02:00
ISSOtm
1c2965467d Process linker script before doing sanity checks 2022-07-11 21:17:34 +02:00
ISSOtm
d243e50390 Do not perform any sanity checks for bad section types
Otherwise, the arrays get overflowed
2022-07-11 21:17:34 +02:00
ISSOtm
acb33777c6 Sort RGB colors as specified in the docs 2022-07-10 12:36:10 +02:00
ISSOtm
d15916b1bd Clarify sorting order of RGB colors 2022-07-10 12:32:57 +02:00
ISSOtm
28fcef0ecd Improve some wording slightly 2022-07-10 12:30:18 +02:00
ISSOtm
b53c115ec2 Fix width and height being reported in wrong order 2022-07-10 12:14:24 +02:00
ISSOtm
6a51e39a5c Print error if reverse() fails to open a file 2022-07-10 11:55:56 +02:00
Antonio Vivace
e348f70866 Remove funding options, leaving only OpenCollective 2022-07-08 21:22:28 +02:00
ISSOtm
43a487f0bf Fix two inverted column widths 2022-07-02 17:48:28 +02:00
689 changed files with 10432 additions and 6878 deletions

View File

@@ -1,88 +0,0 @@
# Configuration for checkpatch.pl
# ===============================
# Enable more tests
--strict
# Quiet
--quiet
# No per-file summary
--no-summary
# Don't expect the Linux kernel tree
--no-tree
# Show file line, not input line
--showfile
# Don't expect SPDX tag in the first line of a file
--ignore SPDX_LICENSE_TAG
# Don't expect Signed-off-by lines in commit messages
--no-signoff
# List of ignored rules
# ---------------------
# There's no BIT macro
--ignore BIT_MACRO
# Don't complain when bools are used in structs
--ignore BOOL_MEMBER
# Allow CamelCase
--ignore CAMELCASE
# Comparing to NULL explicitly isn't a bad thing
--ignore COMPARISON_TO_NULL
# Causes false positives
--ignore COMPLEX_MACRO
# Don't complain about structs not being const
--ignore CONST_STRUCT
# Don't complain about printing "warning:" without the function name, as warning
# printing is relevant to the code being parsed, not RGBDS' code
--ignore EMBEDDED_FUNCTION_NAME
# Do not check the format of commit messages
--ignore GIT_COMMIT_ID
# Do not check for global initializers (this is specific to the kernel)
--ignore GLOBAL_INITIALISERS
# Don't complain about initializing statics (this is specific to the kernel)
--ignore INITIALISED_STATIC
# We don't have a MAINTAINERS file, don't complain about it.
--ignore FILE_PATH_CHANGES
# Writing the continuation on the start of the line can make it clearer
--ignore LOGICAL_CONTINUATIONS
# Don't complain if a line that contains a string is too long. It's better to
# have a really long line that can be found with grep.
--ignore LONG_LINE_STRING
# Don't complain when files are modified in 'include/asm'
--ignore MODIFIED_INCLUDE_ASM
# Allow new typedefs
--ignore NEW_TYPEDEFS
# We allow lines ending with parentheses for the usage prints
--ignore OPEN_ENDED_LINE
# Prefer stdint.h types over kernel types
--ignore PREFER_KERNEL_TYPES
# Don't ask to replace sscanf by kstrto
--ignore SSCANF_TO_KSTRTO
# Parentheses can make the code clearer
--ignore UNNECESSARY_PARENTHESES
# We don't have `fallthrough;` */
--ignore PREFER_FALLTHROUGH

View File

@@ -93,7 +93,7 @@ SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: c++17
Standard: c++20
TabWidth: 4
UseCRLF: false
UseTab: ForIndentation

View File

@@ -1,7 +1,3 @@
# This file is part of RGBDS.
#
# Copyright (c) 2018-2019, Phil Smith and RGBDS contributors.
#
# SPDX-License-Identifier: MIT
.git
docs

4
.gitattributes vendored
View File

@@ -1,2 +1,6 @@
# Shell scripts need Unix line endings (see https://github.com/gbdev/rgbds/issues/841)
*.sh text eol=lf
*.bash text eol=lf
# Flags also need Unix line endings (see https://github.com/gbdev/rgbds/issues/955)
*.flags text eol=lf

3
.github/FUNDING.yml vendored
View File

@@ -1,3 +1,2 @@
github: avivace
patreon: gbdev01
open_collective: gbdev
github: gbdev

View File

@@ -1,17 +0,0 @@
#!/bin/bash
source mingw-env @TRIPLE@
echo LAST IS: $last
# check if last arg is a path to configure, else use parent
for last; do true; done
if test -x "${last}/configure"; then
config_path="$last"
else
config_path=".."
fi
${config_path}/configure \
--host=@TRIPLE@ --target=@TRIPLE@ --build="$CHOST" \
--prefix=/usr/@TRIPLE@ --libdir=/usr/@TRIPLE@/lib --includedir=/usr/@TRIPLE@/include \
--enable-shared --enable-static "$@"

View File

@@ -1,16 +0,0 @@
#!/bin/sh
_arch=$1
default_mingw_pp_flags="-D_FORTIFY_SOURCE=2"
default_mingw_compiler_flags="$default_mingw_pp_flags -O2 -pipe -fno-plt -fexceptions --param=ssp-buffer-size=4"
default_mingw_linker_flags="-Wl,-O1,--sort-common,--as-needed -fstack-protector"
export CPPFLAGS="${MINGW_CPPFLAGS:-$default_mingw_pp_flags $CPPFLAGS}"
export CFLAGS="${MINGW_CFLAGS:-$default_mingw_compiler_flags $CFLAGS}"
export CXXFLAGS="${MINGW_CXXFLAGS:-$default_mingw_compiler_flags $CXXFLAGS}"
export LDFLAGS="${MINGW_LDFLAGS:-$default_mingw_linker_flags $LDFLAGS}"
mingw_prefix=/usr/${_arch}
export PKG_CONFIG_SYSROOT_DIR="${mingw_prefix}"
export PKG_CONFIG_LIBDIR="${mingw_prefix}/lib/pkgconfig:${mingw_prefix}/share/pkgconfig"

View File

@@ -1,44 +0,0 @@
#!/bin/sh
# This script was written by ISSOtm while looking at Arch Linux's PKGBUILD for
# the corresponding package. (And its dependencies)
# https://aur.archlinux.org/packages/mingw-w64-libpng/
set -e
pngver=1.6.37
_apngver=$pngver
_arch="$1"
## Install mingw-configure and mingw-env (both build dependencies)
install -m 755 .github/actions/mingw-env.sh /usr/bin/mingw-env
sed "s|@TRIPLE@|${_arch}|g" .github/actions/mingw-configure.sh > ${_arch}-configure
install -m 755 ${_arch}-configure /usr/bin/
## Grab sources and check them
wget http://downloads.sourceforge.net/sourceforge/libpng/libpng-$pngver.tar.xz
wget http://downloads.sourceforge.net/project/apng/libpng/libpng16/libpng-$_apngver-apng.patch.gz
sha256sum -c .github/actions/mingw-w64-libpng-dev.sha256sums
## Extract sources
tar -xf libpng-$pngver.tar.xz
gunzip libpng-$_apngver-apng.patch.gz
## Start building!
cd libpng-$pngver
# Patch in apng support
patch -p0 ../libpng-$_apngver-apng.patch
mkdir -p build-${_arch}
cd build-${_arch}
${_arch}-configure LDFLAGS=-static-libgcc
make
make install

23
.github/scripts/get_win_deps.ps1 vendored Normal file
View File

@@ -0,0 +1,23 @@
function getlibrary ([string] $URI, [string] $filename, [string] $hash, [string] $destdir) {
$wc = New-Object Net.WebClient
[string] $downloadhash = $null
try {
$wc.DownloadFile($URI, $filename)
$downloadhash = $(Get-FileHash $filename -Algorithm SHA256).Hash
} catch {
Write-Host "${filename}: failed to download"
exit 1
}
if ($hash -ne $downloadhash) {
Write-Host "${filename}: SHA256 mismatch ($downloadhash)"
exit 1
}
Expand-Archive -DestinationPath $destdir $filename
}
getlibrary 'https://www.zlib.net/zlib13.zip' 'zlib.zip' 'c561d09347f674f0d72692e7c75d9898919326c532aab7f8c07bb43b07efeb38' .
getlibrary 'https://github.com/glennrp/libpng/archive/refs/tags/v1.6.37.zip' 'libpng.zip' 'c2c50c13a727af73ecd3fc0167d78592cf5e0bca9611058ca414b6493339c784' .
getlibrary 'https://github.com/lexxmark/winflexbison/releases/download/v2.5.24/win_flex_bison-2.5.24.zip' 'winflexbison.zip' '39c6086ce211d5415500acc5ed2d8939861ca1696aee48909c7f6daf5122b505' install_dir
Move-Item zlib-1.3 zlib
Move-Item libpng-1.6.37 libpng

7
.github/scripts/install.sh vendored Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
install -d /usr/local/bin/ /usr/local/share/man/man1/ /usr/local/share/man/man5/ /usr/local/share/man/man7/
install -s -m 755 rgbasm rgblink rgbfix rgbgfx /usr/local/bin/
install -m 644 rgbasm.1 rgblink.1 rgbfix.1 rgbgfx.1 /usr/local/share/man/man1/
install -m 644 rgbds.5 rgbasm.5 rgblink.5 /usr/local/share/man/man5/
install -m 644 rgbds.7 gbz80.7 /usr/local/share/man/man7/

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
case "${1%-*}" in

33
.github/scripts/mingw-w64-libpng-dev.sh vendored Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/sh
set -e
pngver=1.6.37
arch="$1"
## Grab sources and check them
wget http://downloads.sourceforge.net/project/libpng/libpng16/$pngver/libpng-$pngver.tar.xz
wget http://downloads.sourceforge.net/project/apng/libpng/libpng16/libpng-$pngver-apng.patch.gz
sha256sum -c .github/scripts/mingw-w64-libpng-dev.sha256sums
## Extract sources and patch them
tar -xf libpng-$pngver.tar.xz
gunzip libpng-$pngver-apng.patch.gz
# Patch in apng support
env -C libpng-$pngver patch -p0 ../libpng-$pngver-apng.patch
## Start building!
mkdir -p build
cd build
../libpng-$pngver/configure \
--host="$arch" --target="$arch" \
--prefix="/usr/$arch" \
--enable-shared --disable-static \
CPPFLAGS="-D_FORTIFY_SOURCE=2" \
CFLAGS="-O2 -pipe -fno-plt -fexceptions --param=ssp-buffer-size=4" \
LDFLAGS="-Wl,-O1,--sort-common,--as-needed -fstack-protector"
make -kj
make install

View File

@@ -1,25 +0,0 @@
name: "Code style checking"
on: pull_request
jobs:
checkpatch:
runs-on: ubuntu-latest
steps:
- name: Set up repo
run: |
git clone -b "${{ github.event.pull_request.head.ref }}" "${{ github.event.pull_request.head.repo.clone_url }}" rgbds
cd rgbds
git remote add upstream "${{ github.event.pull_request.base.repo.clone_url }}"
git fetch upstream
- name: Set up checkpatch
working-directory: rgbds
run: |
wget 'https://raw.githubusercontent.com/torvalds/linux/master/scripts/checkpatch.pl'
chmod +x checkpatch.pl
wget 'https://raw.githubusercontent.com/torvalds/linux/master/scripts/const_structs.checkpatch'
wget 'https://raw.githubusercontent.com/torvalds/linux/master/scripts/spelling.txt'
- name: Checkpatch
working-directory: rgbds
run: |
make checkpatch CHECKPATCH=./checkpatch.pl "BASE_REF=${{ github.event.pull_request.base.sha }}" Q= | tee log
if grep -q ERROR: log; then exit 1; else exit 0; fi

View File

@@ -1,96 +0,0 @@
name: "Create release artifacts"
on:
push:
tags:
- v[0-9]*
jobs:
windows:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- name: Get version from tag
shell: bash
run: | # Turn "refs/tags/vX.Y.Z" into "X.Y.Z"
VERSION="${{ github.ref }}"
echo "version=${VERSION##*/v}" >> $GITHUB_ENV
- name: Get zlib, libpng and bison
run: | # TODO: use an array
$wc = New-Object System.Net.WebClient
$wc.DownloadFile('https://www.zlib.net/zlib1212.zip', 'zlib.zip')
$hash = (Get-FileHash "zlib.zip" -Algorithm SHA256).Hash
if ($hash -ne '173e89893dcb8b4a150d7731cd72f0602f1d6b45e60e2a54efdf7f3fc3325fd7') {
Write-Host "zlib SHA256 mismatch! ($hash)"
exit 1
}
$wc.DownloadFile('https://download.sourceforge.net/libpng/lpng1637.zip', 'libpng.zip')
$hash = (Get-FileHash "libpng.zip" -Algorithm SHA256).Hash
if ($hash -ne '3b4b1cbd0bae6822f749d39b1ccadd6297f05e2b85a83dd2ce6ecd7d09eabdf2') {
Write-Host "libpng SHA256 mismatch! ($hash)"
exit 1
}
$wc.DownloadFile('https://github.com/lexxmark/winflexbison/releases/download/v2.5.24/win_flex_bison-2.5.24.zip', 'winflexbison.zip')
$hash = (Get-FileHash "winflexbison.zip" -Algorithm SHA256).Hash
if ($hash -ne '39c6086ce211d5415500acc5ed2d8939861ca1696aee48909c7f6daf5122b505') {
Write-Host "bison SHA256 mismatch! ($hash)"
}
Expand-Archive -DestinationPath . "zlib.zip"
Expand-Archive -DestinationPath . "libpng.zip"
Expand-Archive -DestinationPath install_dir "winflexbison.zip"
Move-Item zlib-1.2.12 zlib
Move-Item lpng1637 libpng
- name: Build 32-bit zlib
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
cmake -S zlib -B zbuild32 -A Win32 -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
cmake --build zbuild32 --config Release
cmake --install zbuild32
- name: Build 32-bit libpng
run: |
cmake -S libpng -B pngbuild32 -A Win32 -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=ON -DPNG_TESTS=OFF
cmake --build pngbuild32 --config Release
cmake --install pngbuild32
- name: Build 32-bit Windows binaries
run: |
cmake -S . -B build32 -A Win32 -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
cmake --build build32 --config Release
cmake --install build32
- name: Package 32-bit binaries
run: |
Compress-Archive -LiteralPath @("install_dir/bin/rgbasm.exe", "install_dir/bin/rgblink.exe", "install_dir/bin/rgbfix.exe", "install_dir/bin/rgbgfx.exe", "install_dir/bin/zlib1.dll", "install_dir/bin/libpng16.dll") "rgbds-${{ env.version }}-win32.zip"
- name: Build 64-bit zlib
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
cmake -S zlib -B zbuild64 -A x64 -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
cmake --build zbuild64 --config Release
cmake --install zbuild64
- name: Build 64-bit libpng
run: |
cmake -S libpng -B pngbuild64 -A x64 -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=ON -DPNG_TESTS=OFF
cmake --build pngbuild64 --config Release
cmake --install pngbuild64
- name: Build 64-bit Windows binaries
run: |
cmake -S . -B build64 -A x64 -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
cmake --build build64 --config Release
cmake --install build64
- name: Package 64-bit binaries
run: |
Compress-Archive -LiteralPath @("install_dir/bin/rgbasm.exe", "install_dir/bin/rgblink.exe", "install_dir/bin/rgbfix.exe", "install_dir/bin/rgbgfx.exe", "install_dir/bin/zlib1.dll", "install_dir/bin/libpng16.dll") "rgbds-${{ env.version }}-win64.zip"
- name: Package sources
run: |
make dist
- name: Release
uses: softprops/action-gh-release@v1
with:
body: |
Please ensure that the three assets below work properly.
Once that's done, replace this text with the changelog, un-draft the release, and update the `release` branch.
By the way, if you forgot to update `include/version.h`, RGBASM's version test is gonna fail in the tag's regression testing! (Use `git push --delete origin <tag>` to delete it)
draft: true # Don't publish the release quite yet...
prerelease: ${{ contains(github.ref, '-rc') }}
files: |
rgbds-${{ env.version }}-win32.zip
rgbds-${{ env.version }}-win64.zip
rgbds-${{ env.version }}.tar.gz
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,153 @@
name: "Create release artifacts"
on:
push:
tags:
- v[0-9]*
jobs:
windows:
runs-on: windows-2022
strategy:
matrix:
bits: [32, 64]
include:
- bits: 32
arch: x86
platform: Win32
- bits: 64
arch: x86_x64
platform: x64
fail-fast: false
steps:
- name: Get version from tag
shell: bash
run: | # Turn "vX.Y.Z" into "X.Y.Z"
VERSION="${{ github.ref_name }}"
echo "version=${VERSION#v}" >> $GITHUB_ENV
- uses: actions/checkout@v3
- name: Install deps
run: .github/scripts/get_win_deps.ps1
- uses: actions/cache@v3
id: cache
with:
path: |
zbuild
pngbuild
key: ${{ matrix.arch }}-${{ hashFiles('zlib/**', 'libpng/**') }}
- name: Build zlib
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
cmake -S zlib -B zbuild -A ${{ matrix.platform }} -Wno-dev -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
cmake --build zbuild --config Release -j
if: steps.cache.outputs.cache-hit != 'true'
- name: Install zlib
run: |
cmake --install zbuild
- name: Build libpng
shell: bash
run: |
cmake -S libpng -B pngbuild -A ${{ matrix.platform }} -Wno-dev -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=OFF -DPNG_TESTS=OFF -DPNG_BUILD_ZLIB=ON -DZLIB_INCLUDE_DIR="$PWD"/install_dir/include -DZLIB_LIBRARY="$PWD"/install_dir/lib/zlib.lib
cmake --build pngbuild --config Release -j
if: steps.cache.outputs.cache-hit != 'true'
- name: Install libpng
run: |
cmake --install pngbuild
- name: Build Windows binaries
shell: bash
run: |
cmake -S . -B build -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release -DZLIB_LIBRARY="$PWD"/install_dir/lib/zlib.lib -DZLIB_INCLUDE_DIR="$PWD"/install_dir/include -DPNG_LIBRARY="$PWD"/install_dir/lib/libpng16.lib -DPNG_INCLUDE_DIR="$PWD"/install_dir/include
cmake --build build --config Release -j --verbose
cmake --install build --verbose --prefix install_dir --strip
- name: Package binaries
run: |
Compress-Archive -LiteralPath @("install_dir/bin/rgbasm.exe", "install_dir/bin/rgblink.exe", "install_dir/bin/rgbfix.exe", "install_dir/bin/rgbgfx.exe", "install_dir/bin/zlib1.dll", "install_dir/bin/libpng16.dll") "rgbds-${{ env.version }}-win${{ matrix.bits }}.zip"
- name: Upload Windows binaries
uses: actions/upload-artifact@v3
with:
name: win${{ matrix.bits }}
path: rgbds-${{ env.version }}-win${{ matrix.bits }}.zip
macos:
runs-on: macos-12
steps:
- name: Get version from tag
shell: bash
run: | # Turn "refs/tags/vX.Y.Z" into "X.Y.Z"
VERSION="${{ github.ref_name }}"
echo "version=${VERSION#v}" >> $GITHUB_ENV
- uses: actions/checkout@v3
- name: Install deps
shell: bash
run: |
./.github/scripts/install_deps.sh macos-latest
# We force linking libpng statically; the other libs are provided by macOS itself
- name: Build binaries
run: |
export PATH="/usr/local/opt/bison/bin:$PATH"
make -j CXXFLAGS="-O3 -flto -DNDEBUG -mmacosx-version-min=10.9" PKG_CONFIG="pkg-config --static" PNGLDLIBS="$(pkg-config --static --libs-only-L libpng | cut -c 3-)/libpng.a $(pkg-config --static --libs-only-l libpng | sed s/-lpng[0-9]*//g)" Q=
- name: Package binaries
run: |
zip --junk-paths rgbds-${{ env.version }}-macos-x86_64.zip rgb{asm,link,fix,gfx} man/* .github/scripts/install.sh
- name: Upload macOS binaries
uses: actions/upload-artifact@v3
with:
name: macos
path: rgbds-${{ env.version }}-macos-x86_64.zip
linux:
runs-on: ubuntu-20.04 # Oldest supported, for best glibc compatibility.
steps:
- name: Get version from tag
shell: bash
run: | # Turn "refs/tags/vX.Y.Z" into "X.Y.Z"
VERSION="${{ github.ref_name }}"
echo "version=${VERSION#v}" >> $GITHUB_ENV
- uses: actions/checkout@v3
- name: Install deps
shell: bash
run: |
./.github/scripts/install_deps.sh ubuntu-20.04
- name: Build binaries
run: |
make -j WARNFLAGS="-Wall -Wextra -pedantic -static" PKG_CONFIG="pkg-config --static" Q=
- name: Package binaries
run: |
tar caf rgbds-${{ env.version }}-linux-x86_64.tar.xz --transform='s#.*/##' rgb{asm,link,fix,gfx} man/* .github/scripts/install.sh
- name: Upload Linux binaries
uses: actions/upload-artifact@v3
with:
name: linux
path: rgbds-${{ env.version }}-linux-x86_64.tar.xz
release:
runs-on: ubuntu-latest
needs: [windows, macos, linux]
steps:
- name: Get version from tag
shell: bash
run: | # Turn "refs/tags/vX.Y.Z" into "X.Y.Z"
VERSION="${{ github.ref_name }}"
echo "version=${VERSION#v}" >> $GITHUB_ENV
- uses: actions/checkout@v3
- name: Package sources
run: |
make dist Q=
ls
- uses: actions/download-artifact@v3
- name: Release
uses: softprops/action-gh-release@v1
with:
body: |
Please ensure that the four packages below work properly.
Once that's done, replace this text with the changelog, un-draft the release, and update the `release` branch.
By the way, if you forgot to update `include/version.hpp`, RGBASM's version test is gonna fail in the tag's regression testing! (Use `git push --delete origin <tag>` to delete it)
draft: true # Don't publish the release quite yet...
prerelease: ${{ contains(github.ref, '-rc') }}
files: |
win32/rgbds-${{ env.version }}-win32.zip
win64/rgbds-${{ env.version }}-win64.zip
macos/rgbds-${{ env.version }}-macos-x86_64.zip
linux/rgbds-${{ env.version }}-linux-x86_64.tar.xz
rgbds-${{ env.version }}.tar.gz
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -7,32 +7,26 @@ on:
jobs:
build:
if: github.repository_owner == 'gbdev'
runs-on: ubuntu-18.04
runs-on: ubuntu-22.04
steps:
- name: Checkout rgbds@release
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: rgbds
- name: Checkout rgbds-www@master
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: ${{ github.repository_owner }}/rgbds-www
path: rgbds-www
# `-O toc` was added in 1.14.5, but the repos only have 1.14.4
- name: Build and install mandoc + install groff
- name: Install groff and mandoc
run: |
sudo apt-get -qq update
sudo apt-get install -yq groff zlib1g-dev
wget 'http://mandoc.bsd.lv/snapshots/mandoc-1.14.6.tar.gz'
tar xf mandoc-1.14.6.tar.gz
cd mandoc-1.14.6
./configure
make
sudo make install
sudo apt-get install -yq groff mandoc
- name: Update pages
working-directory: rgbds/man
run: | # The ref appears to be in the format "refs/tags/<version>", so strip that
../../rgbds-www/.github/actions/get-pages.sh ${GITHUB_REF##*/} *
../../rgbds-www/maintainer/man_to_html.sh ${GITHUB_REF##*/} *
../../rgbds-www/maintainer/new_release.sh ${GITHUB_REF##*/}
- name: Push new pages
working-directory: rgbds-www
run: |

View File

@@ -4,48 +4,44 @@ on:
- pull_request
jobs:
unix-testing:
unix:
strategy:
matrix:
os: [ubuntu-20.04, ubuntu-18.04, macos-11.0, macos-10.15]
cc: [gcc, clang]
os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12]
cxx: [g++, clang++]
buildsys: [make, cmake]
exclude:
# `gcc` is just an alias to `clang` on macOS, don't bother
- os: macos-10.15
cc: gcc
- os: macos-11.0
cc: gcc
include:
- cc: gcc
# Don't use `g++` on macOS; it's just an alias to `clang++`.
- os: macos-11
cxx: g++
- os: macos-12
cxx: g++
- cc: clang
cxx: clang++
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install deps
shell: bash
run: |
./.github/actions/install_deps.sh ${{ matrix.os }}
# The `export` lines are to allow working on macOS...
# Apple's base version is severely outdated, not even supporting -Wall,
# but it overrides Homebrew's version nonetheless...
./.github/scripts/install_deps.sh ${{ matrix.os }}
# Export `bison` to allow using the version we install from Homebrew,
# instead of the outdated one preinstalled on macOS (which doesn't
# even support `-Wall`...).
- name: Build & install using Make
if: matrix.buildsys == 'make'
run: |
export PATH="/usr/local/opt/bison/bin:$PATH"
make develop -j Q= CC=${{ matrix.cc }} CXX=${{ matrix.cxx }}
make develop -j Q= CXX=${{ matrix.cxx }}
sudo make install -j Q=
- name: Build & install using CMake
if: matrix.buildsys == 'cmake'
run: |
export PATH="/usr/local/opt/bison/bin:$PATH"
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=${{ matrix.cc }} -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} -DSANITIZERS=ON -DMORE_WARNINGS=ON
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} -DSANITIZERS=ON -DMORE_WARNINGS=ON
cmake --build build -j --verbose
cp build/src/rgb{asm,link,fix,gfx} .
sudo cmake --install build --verbose
cmake --install build --verbose --component "Test support programs"
- name: Package binaries
run: |
mkdir bins
@@ -53,17 +49,98 @@ jobs:
- name: Upload binaries
uses: actions/upload-artifact@v3
with:
name: rgbds-canary-${{ matrix.os }}-${{ matrix.cc }}-${{ matrix.buildsys }}
name: rgbds-canary-${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.buildsys }}
path: bins
- name: Test
- name: Compute test dependency cache params
id: test-deps-cache-params
shell: bash
run: |
paths=$(test/fetch-test-deps.sh --get-paths)
hash=$(test/fetch-test-deps.sh --get-hash)
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
- name: Check test dependency repositories cache
id: test-deps-cache
uses: actions/cache@v3
with:
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
key: ${{ matrix.os }}-${{ steps.test-deps-cache-params.outputs.hash }}
- if: steps.test-deps-cache.outputs.cache-hit != 'true'
name: Fetch test dependency repositories
continue-on-error: true
run: |
test/fetch-test-deps.sh
- name: Install test dependency dependencies
shell: bash
run: |
test/fetch-test-deps.sh --get-deps ${{ matrix.os }}
- name: Run tests
shell: bash
run: |
test/run-tests.sh
windows-testing:
macos-static:
strategy:
matrix:
# Don't run on macOS 11; our setup makes clang segfault (YES).
os: [macos-12]
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Install deps
shell: bash
run: |
./.github/scripts/install_deps.sh ${{ matrix.os }}
# Export `bison` to allow using the version we install from Homebrew,
# instead of the outdated one preinstalled on macOS (which doesn't
# even support `-Wall`...).
- name: Build & install
run: |
export PATH="/usr/local/opt/bison/bin:$PATH"
make -j CXXFLAGS="-O3 -flto -DNDEBUG -mmacosx-version-min=10.9" PKG_CONFIG="pkg-config --static" PNGLDLIBS="$(pkg-config --static --libs-only-L libpng | cut -c 3-)/libpng.a $(pkg-config --static --libs-only-l libpng | sed s/-lpng[0-9]*//g)" Q=
- name: Package binaries
run: |
mkdir bins
cp rgb{asm,link,fix,gfx} bins
- name: Upload binaries
uses: actions/upload-artifact@v3
with:
name: rgbds-canary-${{ matrix.os }}-${{ matrix.buildsys }}
path: bins
- name: Compute test dependency cache params
id: test-deps-cache-params
shell: bash
run: |
paths=$(test/fetch-test-deps.sh --get-paths)
hash=$(test/fetch-test-deps.sh --get-hash)
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
- name: Check test dependency repositories cache
id: test-deps-cache
uses: actions/cache@v3
with:
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
key: ${{ matrix.os }}-${{ steps.test-deps-cache-params.outputs.hash }}
- if: steps.test-deps-cache.outputs.cache-hit != 'true'
name: Fetch test dependency repositories
continue-on-error: true
run: |
test/fetch-test-deps.sh
- name: Install test dependency dependencies
shell: bash
run: |
test/fetch-test-deps.sh --get-deps ${{ matrix.os }}
- name: Run tests
shell: bash
run: |
test/run-tests.sh
windows:
strategy:
matrix:
bits: [32, 64]
os: [windows-2019, windows-2022]
include:
- bits: 32
arch: x86
@@ -72,34 +149,11 @@ jobs:
arch: x86_x64
platform: x64
fail-fast: false
runs-on: windows-2019
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Get zlib, libpng and bison
run: | # TODO: use an array; remember to update the versions being downloaded, *and* the paths being extracted! (`Move-Item`)
$wc = New-Object System.Net.WebClient
$wc.DownloadFile('https://www.zlib.net/zlib1212.zip', 'zlib.zip')
$hash = (Get-FileHash "zlib.zip" -Algorithm SHA256).Hash
if ($hash -ne '173e89893dcb8b4a150d7731cd72f0602f1d6b45e60e2a54efdf7f3fc3325fd7') {
Write-Host "zlib SHA256 mismatch! ($hash)"
exit 1
}
$wc.DownloadFile('https://download.sourceforge.net/libpng/lpng1637.zip', 'libpng.zip')
$hash = (Get-FileHash "libpng.zip" -Algorithm SHA256).Hash
if ($hash -ne '3b4b1cbd0bae6822f749d39b1ccadd6297f05e2b85a83dd2ce6ecd7d09eabdf2') {
Write-Host "libpng SHA256 mismatch! ($hash)"
exit 1
}
$wc.DownloadFile('https://github.com/lexxmark/winflexbison/releases/download/v2.5.24/win_flex_bison-2.5.24.zip', 'winflexbison.zip')
$hash = (Get-FileHash "winflexbison.zip" -Algorithm SHA256).Hash
if ($hash -ne '39c6086ce211d5415500acc5ed2d8939861ca1696aee48909c7f6daf5122b505') {
Write-Host "bison SHA256 mismatch! ($hash)"
}
Expand-Archive -DestinationPath . "zlib.zip"
Expand-Archive -DestinationPath . "libpng.zip"
Expand-Archive -DestinationPath install_dir "winflexbison.zip"
Move-Item zlib-1.2.12 zlib
Move-Item lpng1637 libpng
- uses: actions/checkout@v3
- name: Install deps
run: .github/scripts/get_win_deps.ps1
- uses: actions/cache@v3
id: cache
with:
@@ -109,25 +163,28 @@ jobs:
key: ${{ matrix.arch }}-${{ hashFiles('zlib/**', 'libpng/**') }}
- name: Build zlib
run: | # BUILD_SHARED_LIBS causes the output DLL to be correctly called `zlib1.dll`
cmake -S zlib -B zbuild -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
cmake -S zlib -B zbuild -A ${{ matrix.platform }} -Wno-dev -DCMAKE_INSTALL_PREFIX=install_dir -DBUILD_SHARED_LIBS=ON
cmake --build zbuild --config Release -j
if: steps.cache.outputs.cache-hit != 'true'
- name: Install zlib
run: |
cmake --install zbuild
- name: Build libpng
shell: bash
run: |
cmake -S libpng -B pngbuild -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=ON -DPNG_TESTS=OFF
cmake -S libpng -B pngbuild -A ${{ matrix.platform }} -Wno-dev -DCMAKE_INSTALL_PREFIX=install_dir -DPNG_SHARED=ON -DPNG_STATIC=OFF -DPNG_TESTS=OFF -DPNG_BUILD_ZLIB=ON -DZLIB_INCLUDE_DIR="$PWD"/install_dir/include -DZLIB_LIBRARY="$PWD"/install_dir/lib/zlib.lib
cmake --build pngbuild --config Release -j
if: steps.cache.outputs.cache-hit != 'true'
- name: Install libpng
run: |
cmake --install pngbuild
- name: Build Windows binaries
shell: bash
run: |
cmake -S . -B build -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release
cmake -S . -B build -A ${{ matrix.platform }} -DCMAKE_INSTALL_PREFIX=install_dir -DCMAKE_BUILD_TYPE=Release -DZLIB_LIBRARY="$PWD"/install_dir/lib/zlib.lib -DZLIB_INCLUDE_DIR="$PWD"/install_dir/include -DPNG_LIBRARY="$PWD"/install_dir/lib/libpng16.lib -DPNG_INCLUDE_DIR="$PWD"/install_dir/include
cmake --build build --config Release -j --verbose
cmake --install build --verbose --prefix install_dir
cmake --install build --verbose --component "Test support programs"
- name: Package binaries
shell: bash
run: |
@@ -138,18 +195,41 @@ jobs:
with:
name: rgbds-canary-win${{ matrix.bits }}
path: bins
- name: Test
- name: Compute test dependency cache params
id: test-deps-cache-params
shell: bash
run: |
paths=$(test/fetch-test-deps.sh --get-paths)
hash=$(test/fetch-test-deps.sh --get-hash)
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
- name: Check test dependency repositories cache
id: test-deps-cache
uses: actions/cache@v3
with:
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
key: ${{ matrix.os }}-${{ matrix.bits }}-${{ steps.test-deps-cache-params.outputs.hash }}
- if: steps.test-deps-cache.outputs.cache-hit != 'true'
name: Fetch test dependency repositories
shell: bash
continue-on-error: true
run: |
test/fetch-test-deps.sh
- name: Install test dependency dependencies
shell: bash
run: |
test/fetch-test-deps.sh --get-deps ${{ matrix.os }}
- name: Run tests
shell: bash
run: |
cp bins/* .
cp bins/*.dll test/gfx
test/run-tests.sh
windows-xbuild:
windows-mingw-build:
strategy:
matrix:
bits: [32, 64]
os: [ubuntu-18.04]
include:
- bits: 32
arch: i686
@@ -158,36 +238,32 @@ jobs:
arch: x86-64
triplet: x86_64-w64-mingw32
fail-fast: false
runs-on: ${{ matrix.os }}
runs-on: ubuntu-22.04
env:
DIST_DIR: win${{ matrix.bits }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install deps
shell: bash
run: |
./.github/actions/install_deps.sh ${{ matrix.os }}
./.github/scripts/install_deps.sh ${{ matrix.os }}
- name: Install MinGW
run: |
sudo apt-get install {gcc,g++}-mingw-w64-${{ matrix.arch }} mingw-w64-tools libz-mingw-w64-dev
run: | # dpkg-dev is apparently required for pkg-config for cross-building
sudo apt-get install g++-mingw-w64-${{ matrix.arch }}-win32 mingw-w64-tools libz-mingw-w64-dev dpkg-dev
- name: Install libpng dev headers for MinGW
run: |
sudo ./.github/actions/mingw-w64-libpng-dev.sh ${{ matrix.triplet }}
sudo ./.github/scripts/mingw-w64-libpng-dev.sh ${{ matrix.triplet }}
- name: Cross-build Windows binaries
run: |
make mingw${{ matrix.bits }} -j Q=
- name: Package binaries
run: |
run: | # DLL dependencies can be figured out using e.g. Dependency Walker or objdump -p
mkdir bins
mv rgbasm bins/rgbasm.exe
mv rgblink bins/rgblink.exe
mv rgbfix bins/rgbfix.exe
mv rgbgfx bins/rgbgfx.exe
cp /usr/${{ matrix.triplet }}/lib/zlib1.dll bins
cp /usr/${{ matrix.triplet }}/bin/libpng16-16.dll bins
if [ ${{ matrix.bits }} -eq 32 ]; then cp /usr/lib/gcc/${{ matrix.triplet }}/7.3-win32/lib{gcc_s_sjlj-1,stdc++-6}.dll bins; fi
mv test/gfx/randtilegen{,.exe}
mv test/gfx/rgbgfx_test{,.exe}
mv -v rgb{asm,link,fix,gfx}.exe bins/
cp -v /usr/${{ matrix.triplet }}/lib/zlib1.dll bins
cp -v /usr/${{ matrix.triplet }}/bin/libpng16-16.dll bins
cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/lib{ssp-0,stdc++-6}.dll bins
[ "${{ matrix.bits }}" -ne 32 ] || cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/libgcc_s_dw2-1.dll bins
- name: Upload Windows binaries
uses: actions/upload-artifact@v3
with:
@@ -201,15 +277,16 @@ jobs:
test/gfx/randtilegen.exe
test/gfx/rgbgfx_test.exe
windows-xtesting:
needs: windows-xbuild
windows-mingw-testing:
needs: windows-mingw-build
strategy:
matrix:
os: [windows-2019, windows-2022]
bits: [32, 64]
fail-fast: false
runs-on: windows-2019
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Retrieve binaries
uses: actions/download-artifact@v3
with:
@@ -225,6 +302,30 @@ jobs:
run: |
cp bins/* .
cp bins/*.dll test/gfx
- name: Compute test dependency cache params
id: test-deps-cache-params
shell: bash
run: |
paths=$(test/fetch-test-deps.sh --get-paths)
hash=$(test/fetch-test-deps.sh --get-hash)
tee -a <<<"paths=\"${paths//,/\\n}\"" $GITHUB_OUTPUT
tee -a <<<"hash=${hash%-}" $GITHUB_OUTPUT
- name: Check test dependency repositories cache
id: test-deps-cache
uses: actions/cache@v3
with:
path: ${{ fromJSON(steps.test-deps-cache-params.outputs.paths) }}
key: mingw-${{ matrix.bits }}-${{ steps.test-deps-cache-params.outputs.hash }}
- if: steps.test-deps-cache.outputs.cache-hit != 'true'
name: Fetch test dependency repositories
shell: bash
continue-on-error: true
run: |
test/fetch-test-deps.sh
- name: Install test dependency dependencies
shell: bash
run: |
test/fetch-test-deps.sh --get-deps ${{ matrix.os }}
- name: Run tests
shell: bash
run: |

View File

@@ -17,30 +17,24 @@ on:
jobs:
build:
if: github.repository_owner == 'gbdev'
runs-on: ubuntu-18.04
runs-on: ubuntu-22.04
steps:
- name: Checkout rgbds@master
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: gbdev/rgbds
ref: master
path: rgbds
- name: Checkout rgbds-www@master
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: gbdev/rgbds-www
ref: master
path: rgbds-www
- name: Build and install mandoc + install groff
- name: Install groff and mandoc
run: |
sudo apt-get -qq update
sudo apt-get install -yq groff zlib1g-dev
wget 'http://mandoc.bsd.lv/snapshots/mandoc-1.14.6.tar.gz'
tar xf mandoc-1.14.6.tar.gz
cd mandoc-1.14.6
./configure
make
sudo make install
sudo apt-get install -yq groff mandoc
- name: Update pages
working-directory: rgbds/man
run: |

5
.gitignore vendored
View File

@@ -3,10 +3,13 @@
/rgbfix
/rgbgfx
/rgbshim.sh
/coverage/
*.o
*.exe
*.dll
.checkpatch-camelcase.*
*.gcno
*.gcda
*.gcov
CMakeCache.txt
CMakeFiles/
cmake_install.cmake

View File

@@ -1,16 +1,10 @@
#
# This file is part of RGBDS.
#
# Copyright (c) 2020 RGBDS contributors.
#
# SPDX-License-Identifier: MIT
#
# 3.9 required for LTO checks
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
project(rgbds
LANGUAGES C CXX)
LANGUAGES CXX)
# get real path of source and binary directories
get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
@@ -29,12 +23,9 @@ option(MORE_WARNINGS "Turn on more warnings" OFF) # Ignored on MSVC
if(MSVC)
# MSVC's standard library triggers warning C5105,
# "macro expansion producing 'defined' has undefined behavior"
add_compile_options(/MP /wd5105)
# We also opt into the C++20-conformant preprocessor.
add_compile_options(/MP /wd5105 /Zc:preprocessor)
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
# Also, CMake appears not to pass the C11-enabling flag, so we must add it manually... but only for C!
if(NOT CMAKE_C_FLAGS MATCHES "std:c11") # The flag may already have been injected by an earlier CMake invocation, so don't add it twice
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std:c11" CACHE STRING "Flags used by the C compiler during all build types." FORCE)
endif()
if(SANITIZERS)
set(SAN_FLAGS /fsanitize=address)
@@ -42,8 +33,12 @@ if(MSVC)
add_link_options(${SAN_FLAGS})
endif()
else()
add_compile_options(-Wall -pedantic)
add_definitions(-D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE)
# TODO: use -pedantic after non-C++ idioms are gone
add_compile_options(-Wall)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Wno-c99-designator)
endif()
add_definitions(-D_POSIX_C_SOURCE=200809L)
if(SANITIZERS)
set(SAN_FLAGS -fsanitize=shift -fsanitize=integer-divide-by-zero
-fsanitize=unreachable -fsanitize=vla-bound
@@ -52,9 +47,9 @@ else()
-fsanitize=alignment -fsanitize=null -fsanitize=address)
add_compile_options(${SAN_FLAGS})
add_link_options(${SAN_FLAGS})
add_definitions(-D_GLIBCXX_ASSERTIONS)
# A non-zero optimization level is desired in debug mode, but allow overriding it nonetheless
# TODO: this overrides anything previously set... that's a bit sloppy!
set(CMAKE_C_FLAGS_DEBUG "-g -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-g -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE STRING "" FORCE)
endif()
@@ -97,9 +92,7 @@ endif()
include_directories("${PROJECT_SOURCE_DIR}/include")
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED True)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_subdirectory(src)

View File

@@ -12,14 +12,14 @@ Bug reports are essential to improve RGBDS and they are always welcome. If you
want to report a bug:
1. Make sure that there isn't a similar issue already reported
`here <https://github.com/rednex/rgbds/issues>`__.
`here <https://github.com/gbdev/rgbds/issues>`__.
2. Figure out a way of reproducing it reliably.
3. If there is a piece of code that triggers the bug, try to reduce it to the
smallest file you can.
4. Create a new `issue <https://github.com/rednex/rgbds/issues>`__.
4. Create a new `issue <https://github.com/gbdev/rgbds/issues>`__.
Of course, it may not always be possible to give an accurate bug report, but it
always helps to fix it.
@@ -30,7 +30,7 @@ Requesting new features
If you come up with a good idea that could be implemented, you can propose it to
be done.
1. Create a new `issue <https://github.com/rednex/rgbds/issues>`__.
1. Create a new `issue <https://github.com/gbdev/rgbds/issues>`__.
2. Try to be as accurate as possible. Describe what you need and why you need
it, maybe with examples.
@@ -49,7 +49,7 @@ if your change is going to be small (and likely to be accepted as-is) or big
(and will have to go through some rework).
Big changes will most likely require some discussion, so open an
`issue <https://github.com/rednex/rgbds/issues>`__ and explain what you want to
`issue <https://github.com/gbdev/rgbds/issues>`__ and explain what you want to
do and how you intend to do it. If you already have a prototype, it's always a
good idea to show it. Tests help, too.
@@ -74,22 +74,10 @@ copyright and the reference to the MIT License.
new warning (but it may be possible to remove some warning checks if it makes
the code much easier).
5. Follow the Linux kernel coding style, which can be found in the file
``Documentation/process/coding-style.rst`` in the Linux kernel repository.
Note that the coding style isn't written in stone, if there is a good reason
to deviate from it, it should be fine.
5. Format your changes according to ``clang-format``, which will reformat the
coding style according to our standards defined in ``.clang-format``.
6. Download the files ``checkpatch.pl``, ``const_structs.checkpatch`` and
``spelling.txt`` from the folder ``scripts`` in the Linux kernel repository.
6. Create a pull request against the branch ``master``.
7. To use ``checkpatch.pl`` you can use ``make checkpatch``, which will check
the coding style of all patches between the current one and the upstream
code. By default, the Makefile expects the script (and associate files) to be
located in ``../linux/scripts/``, but you can place them anywhere you like as
long as you specify it when executing the command:
``make checkpatch CHECKPATCH=../path/to/folder``.
8. Create a pull request against the branch ``master``.
9. Be prepared to get some comments about your code and to modify it. Tip: Use
7. Be prepared to get some comments about your code and to modify it. Tip: Use
``git rebase -i origin/master`` to modify chains of commits.

View File

@@ -21,7 +21,7 @@ Main contributors
- Eldred "ISSOtm" Habert <eldredhabert0@gmail.com>
- Rangi <http://github.com/Rangi42>
- Sylvie "Rangi" Oukaour <http://github.com/Rangi42>
Other contributors
------------------

View File

@@ -1,24 +1,14 @@
# This file is part of RGBDS.
#
# Copyright (c) 2018-2019, Phil Smith and RGBDS contributors.
#
# SPDX-License-Identifier: MIT
# docker build -t rgbds:vX.X.X-alpine
FROM alpine:latest
RUN apk add --update \
build-base \
bison \
libpng-dev
COPY . /rgbds
FROM debian:11-slim
LABEL org.opencontainers.image.source=https://github.com/gbdev/rgbds
ARG version=0.7.0
WORKDIR /rgbds
RUN make Q='' all
FROM alpine:latest
RUN apk add --update \
libpng
COPY --from=0 \
/rgbds/rgbasm \
/rgbds/rgbfix \
/rgbds/rgblink \
/rgbds/rgbgfx \
/bin/
COPY . .
RUN apt-get update && \
apt-get install sudo make cmake gcc build-essential -y
RUN ./.github/scripts/install_deps.sh ubuntu-20.04
RUN make -j CXXFLAGS="-O3 -flto -DNDEBUG -static" PKG_CONFIG="pkg-config --static" Q=
RUN tar caf rgbds-${version}-linux-x86_64.tar.xz --transform='s#.*/##' rgbasm rgblink rgbfix rgbgfx man/* .github/scripts/install.sh

View File

@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 1997-2020, Carsten Sorensen and RGBDS contributors.
Copyright (c) 1997-2023, Carsten Sørensen and RGBDS contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to

178
Makefile
View File

@@ -1,13 +1,9 @@
#
# This file is part of RGBDS.
#
# Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
#
# SPDX-License-Identifier: MIT
#
.SUFFIXES:
.SUFFIXES: .h .y .c .cpp .o
.SUFFIXES: .cpp .y .o
.PHONY: all clean install checkdiff develop debug coverage mingw32 mingw64 wine-shim dist
# User-defined variables
@@ -18,7 +14,6 @@ mandir := ${PREFIX}/share/man
STRIP := -s
BINMODE := 755
MANMODE := 644
CHECKPATCH := ../linux/scripts/checkpatch.pl
# Other variables
@@ -27,19 +22,16 @@ PNGCFLAGS := `${PKG_CONFIG} --cflags libpng`
PNGLDFLAGS := `${PKG_CONFIG} --libs-only-L libpng`
PNGLDLIBS := `${PKG_CONFIG} --libs-only-l libpng`
# Note: if this comes up empty, `version.c` will automatically fall back to last release number
# Note: if this comes up empty, `version.cpp` will automatically fall back to last release number
VERSION_STRING := `git describe --tags --dirty --always 2>/dev/null`
WARNFLAGS := -Wall -pedantic
# TODO: use -pedantic after non-C++ idioms are gone
WARNFLAGS := -Wall -Wno-unknown-warning-option -Wno-c99-designator
# Overridable CFLAGS
CFLAGS ?= -O3 -flto -DNDEBUG
# Overridable CXXFLAGS
CXXFLAGS ?= -O3 -flto -DNDEBUG
# Non-overridable CFLAGS
# _ISOC11_SOURCE is required on certain platforms to get C11 on top of the C99-based POSIX 2008
REALCFLAGS := ${CFLAGS} ${WARNFLAGS} -std=gnu11 -I include \
-D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE
REALCXXFLAGS := ${CXXFLAGS} ${WARNFLAGS} -std=c++17 -I include \
# Non-overridable CXXFLAGS
REALCXXFLAGS := ${CXXFLAGS} ${WARNFLAGS} -std=c++2a -I include \
-D_POSIX_C_SOURCE=200809L -fno-exceptions -fno-rtti
# Overridable LDFLAGS
LDFLAGS ?=
@@ -47,9 +39,9 @@ LDFLAGS ?=
REALLDFLAGS := ${LDFLAGS} ${WARNFLAGS} \
-DBUILD_VERSION_STRING=\"${VERSION_STRING}\"
YFLAGS ?= -Wall
# Wrapper around bison that passes flags depending on what the version supports
BISON := src/bison.sh
BISON := bison
RM := rm -rf
# Used for checking pull requests
@@ -73,16 +65,16 @@ rgbasm_obj := \
src/asm/rpn.o \
src/asm/section.o \
src/asm/symbol.o \
src/asm/util.o \
src/asm/warning.o \
src/extern/getopt.o \
src/extern/utf8decoder.o \
src/error.o \
src/hashmap.o \
src/linkdefs.o \
src/opmath.o
src/opmath.o \
src/util.o
src/asm/lexer.o src/asm/main.o: src/asm/parser.h
src/asm/lexer.o src/asm/main.o: src/asm/parser.hpp
rgblink_obj := \
src/link/assign.o \
@@ -91,13 +83,18 @@ rgblink_obj := \
src/link/output.o \
src/link/patch.o \
src/link/script.o \
src/link/sdas_obj.o \
src/link/section.o \
src/link/symbol.o \
src/extern/getopt.o \
src/extern/utf8decoder.o \
src/error.o \
src/hashmap.o \
src/linkdefs.o \
src/opmath.o
src/opmath.o \
src/util.o
src/link/main.o: src/link/script.hpp
rgbfix_obj := \
src/fix/main.o \
@@ -117,19 +114,19 @@ rgbgfx_obj := \
src/error.o
rgbasm: ${rgbasm_obj}
$Q${CC} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCFLAGS} src/version.c -lm
$Q${CXX} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCXXFLAGS} src/version.cpp -lm
rgblink: ${rgblink_obj}
$Q${CC} ${REALLDFLAGS} -o $@ ${rgblink_obj} ${REALCFLAGS} src/version.c
$Q${CXX} ${REALLDFLAGS} -o $@ ${rgblink_obj} ${REALCXXFLAGS} src/version.cpp
rgbfix: ${rgbfix_obj}
$Q${CC} ${REALLDFLAGS} -o $@ ${rgbfix_obj} ${REALCFLAGS} src/version.c
$Q${CXX} ${REALLDFLAGS} -o $@ ${rgbfix_obj} ${REALCXXFLAGS} src/version.cpp
rgbgfx: ${rgbgfx_obj}
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ ${rgbgfx_obj} ${REALCXXFLAGS} -x c++ src/version.c ${PNGLDLIBS}
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ ${rgbgfx_obj} ${REALCXXFLAGS} ${PNGLDLIBS} src/version.cpp
test/gfx/randtilegen: test/gfx/randtilegen.c
$Q${CC} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCFLAGS} ${PNGCFLAGS} ${PNGLDLIBS}
test/gfx/randtilegen: test/gfx/randtilegen.cpp
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGCFLAGS} ${PNGLDLIBS}
test/gfx/rgbgfx_test: test/gfx/rgbgfx_test.cpp
$Q${CXX} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ $^ ${REALCXXFLAGS} ${PNGLDLIBS}
@@ -139,30 +136,35 @@ test/gfx/rgbgfx_test: test/gfx/rgbgfx_test.cpp
# We want the Bison invocation to pass through our rules, not default ones
.y.o:
# Bison-generated C files have an accompanying header
src/asm/parser.h: src/asm/parser.c
.y.cpp:
$Q${BISON} $@ $<
# Bison-generated C++ files have an accompanying header
src/asm/parser.hpp: src/asm/parser.cpp
$Qtouch $@
src/link/script.hpp: src/link/script.cpp
$Qtouch $@
src/asm/parser.c: src/asm/parser.y
$QDEFS=; \
add_flag(){ \
if src/check_bison_ver.sh $$1 $$2; then \
DEFS="-D$$3 $$DEFS"; \
fi \
}; \
add_flag 3 5 api.token.raw=true; \
add_flag 3 6 parse.error=detailed; \
add_flag 3 0 parse.error=verbose; \
add_flag 3 0 parse.lac=full; \
add_flag 3 0 lr.type=ielr; \
echo "DEFS=$$DEFS"; \
${BISON} $$DEFS -d ${YFLAGS} -o $@ $<
.c.o:
$Q${CC} ${REALCFLAGS} -c -o $@ $<
# Only RGBGFX uses libpng (POSIX make doesn't support pattern rules to cover all these)
src/gfx/main.o: src/gfx/main.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/pal_packing.o: src/gfx/pal_packing.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/pal_sorting.o: src/gfx/pal_sorting.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/pal_spec.o: src/gfx/pal_spec.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/process.o: src/gfx/process.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/proto_palette.o: src/gfx/proto_palette.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/reverse.o: src/gfx/reverse.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
src/gfx/rgba.o: src/gfx/rgba.cpp
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
.cpp.o:
$Q${CXX} ${REALCXXFLAGS} ${PNGCFLAGS} -c -o $@ $<
$Q${CXX} ${REALCXXFLAGS} -c -o $@ $<
# Target used to remove all files generated by other Makefile targets
@@ -172,52 +174,20 @@ clean:
$Q${RM} rgbfix rgbfix.exe
$Q${RM} rgbgfx rgbgfx.exe
$Qfind src/ -name "*.o" -exec rm {} \;
$Qfind . -type f \( -name "*.gcno" -o -name "*.gcda" -o -name "*.gcov" \) -exec rm {} \;
$Q${RM} rgbshim.sh
$Q${RM} src/asm/parser.c src/asm/parser.h
$Q${RM} src/asm/parser.cpp src/asm/parser.hpp
$Q${RM} src/link/script.cpp src/link/script.hpp src/link/stack.hh
$Q${RM} test/gfx/randtilegen test/gfx/rgbgfx_test
# Target used to install the binaries and man pages.
install: all
$Qmkdir -p ${DESTDIR}${bindir}
$Qinstall ${STRIP} -m ${BINMODE} rgbasm ${DESTDIR}${bindir}/rgbasm
$Qinstall ${STRIP} -m ${BINMODE} rgbfix ${DESTDIR}${bindir}/rgbfix
$Qinstall ${STRIP} -m ${BINMODE} rgblink ${DESTDIR}${bindir}/rgblink
$Qinstall ${STRIP} -m ${BINMODE} rgbgfx ${DESTDIR}${bindir}/rgbgfx
$Qmkdir -p ${DESTDIR}${mandir}/man1 ${DESTDIR}${mandir}/man5 ${DESTDIR}${mandir}/man7
$Qinstall -m ${MANMODE} man/rgbds.7 ${DESTDIR}${mandir}/man7/rgbds.7
$Qinstall -m ${MANMODE} man/gbz80.7 ${DESTDIR}${mandir}/man7/gbz80.7
$Qinstall -m ${MANMODE} man/rgbds.5 ${DESTDIR}${mandir}/man5/rgbds.5
$Qinstall -m ${MANMODE} man/rgbasm.1 ${DESTDIR}${mandir}/man1/rgbasm.1
$Qinstall -m ${MANMODE} man/rgbasm.5 ${DESTDIR}${mandir}/man5/rgbasm.5
$Qinstall -m ${MANMODE} man/rgbfix.1 ${DESTDIR}${mandir}/man1/rgbfix.1
$Qinstall -m ${MANMODE} man/rgblink.1 ${DESTDIR}${mandir}/man1/rgblink.1
$Qinstall -m ${MANMODE} man/rgblink.5 ${DESTDIR}${mandir}/man5/rgblink.5
$Qinstall -m ${MANMODE} man/rgbgfx.1 ${DESTDIR}${mandir}/man1/rgbgfx.1
# Target used to check the coding style of the whole codebase.
# `extern/` is excluded, as it contains external code that should not be patched
# to meet our coding style, so applying upstream patches is easier.
# `.y` files aren't checked, unfortunately...
checkcodebase:
$Qfor file in `git ls-files | grep -E '(\.c|\.h)$$' | grep -Ev '(src|include)/extern/'`; do \
${CHECKPATCH} -f "$$file"; \
done
# Target used to check the coding style of the patches from the upstream branch
# to the HEAD. Runs checkpatch once for each commit between the current HEAD and
# the first common commit between the HEAD and origin/master.
# `.y` files aren't checked, unfortunately...
checkpatch:
$QCOMMON_COMMIT=`git merge-base HEAD ${BASE_REF}`; \
for commit in `git rev-list $$COMMON_COMMIT..HEAD`; do \
echo "[*] Analyzing commit '$$commit'"; \
git format-patch --stdout "$$commit~..$$commit" \
-- src include '!src/extern' '!include/extern' \
| ${CHECKPATCH} - || true; \
done
$Qinstall -d ${DESTDIR}${bindir}/ ${DESTDIR}${mandir}/man1/ ${DESTDIR}${mandir}/man5/ ${DESTDIR}${mandir}/man7/
$Qinstall ${STRIP} -m ${BINMODE} rgbasm rgblink rgbfix rgbgfx ${DESTDIR}${bindir}/
$Qinstall -m ${MANMODE} man/rgbasm.1 man/rgblink.1 man/rgbfix.1 man/rgbgfx.1 ${DESTDIR}${mandir}/man1/
$Qinstall -m ${MANMODE} man/rgbds.5 man/rgbasm.5 man/rgblink.5 ${DESTDIR}${mandir}/man5/
$Qinstall -m ${MANMODE} man/rgbds.7 man/gbz80.7 ${DESTDIR}${mandir}/man7/
# Target used to check for suspiciously missing changed files.
@@ -230,24 +200,35 @@ checkdiff:
# The rationale for some of the flags is documented in the CMakeLists.
develop:
$Qenv ${MAKE} WARNFLAGS="-Werror -Wextra \
$Q${MAKE} WARNFLAGS="${WARNFLAGS} -Werror -Wextra \
-Walloc-zero -Wcast-align -Wcast-qual -Wduplicated-branches -Wduplicated-cond \
-Wfloat-equal -Wlogical-op -Wnull-dereference -Wshift-overflow=2 \
-Wstringop-overflow=4 -Wstrict-overflow=5 -Wundef -Wuninitialized -Wunused \
-Wshadow \
-Wformat=2 -Wformat-overflow=2 -Wformat-truncation=1 \
-Wno-format-nonliteral \
-Wno-format-nonliteral -Wno-strict-overflow \
-Wno-type-limits -Wno-tautological-constant-out-of-range-compare \
-Wvla \
-Wno-unknown-warning-option \
-D_GLIBCXX_ASSERTIONS \
-fsanitize=shift -fsanitize=integer-divide-by-zero \
-fsanitize=unreachable -fsanitize=vla-bound \
-fsanitize=signed-integer-overflow -fsanitize=bounds \
-fsanitize=object-size -fsanitize=bool -fsanitize=enum \
-fsanitize=alignment -fsanitize=null -fsanitize=address" \
CFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls" \
CXXFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls"
# This target is used during development in order to more easily debug with gdb.
debug:
$Qenv ${MAKE} \
CXXFLAGS="-ggdb3 -Og -fno-omit-frame-pointer -fno-optimize-sibling-calls"
# This target is used during development in order to inspect code coverage with gcov.
coverage:
$Qenv ${MAKE} \
CXXFLAGS="-ggdb3 -Og --coverage -fno-omit-frame-pointer -fno-optimize-sibling-calls"
# Targets for the project maintainer to easily create Windows exes.
# This is not for Windows users!
# If you're building on Windows with Cygwin or Mingw, just follow the Unix
@@ -255,16 +236,17 @@ develop:
mingw32:
$Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \
CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ \
BISON=bison PKG_CONFIG=i686-w64-mingw32-pkg-config -j
CXX=i686-w64-mingw32-g++ \
CXXFLAGS="-O3 -flto -DNDEBUG -static-libgcc" \
PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/i686-w64-mingw32 pkg-config"
mingw64:
$Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ \
BISON=bison PKG_CONFIG=x86_64-w64-mingw32-pkg-config -j
CXX=x86_64-w64-mingw32-g++ \
PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/x86_64-w64-mingw32 pkg-config"
wine-shim:
$Qecho '#!/bin/bash' > rgbshim.sh
$Qecho '#!/usr/bin/env bash' > rgbshim.sh
$Qecho 'WINEDEBUG=-all wine $$0.exe "$${@:1}"' >> rgbshim.sh
$Qchmod +x rgbshim.sh
$Qln -s rgbshim.sh rgbasm

View File

@@ -14,16 +14,20 @@ other UNIX tools.
This toolchain is maintained `on GitHub <https://github.com/gbdev/rgbds>`__.
The documentation of this toolchain can be viewed online `here <https://rgbds.gbdev.io/docs/>`__, it is generated from the man pages found in this repository.
The source code of the website itself is on GitHub as well under the repo `rgbds-www <https://github.com/gbdev/rgbds-www>`__.
The documentation of this toolchain can be viewed online `here <https://rgbds.gbdev.io/docs/>`__.
It is generated from the man pages found in this repository.
The source code of the website itself is on GitHub as well under the repo
`rgbds-www <https://github.com/gbdev/rgbds-www>`__.
If you want to contribute or maintain RGBDS, and have questions regarding the code, its organisation, etc. you can find me `on GBDev <https://gbdev.io/chat>`__ or via mail at ``rgbds at eldred dot fr``.
If you want to contribute or maintain RGBDS, and have questions regarding the code, its
organisation, etc. you can find the maintainers `on the gbdev community channels <https://gbdev.io/chat>`__
or via mail at ``rgbds at gbdev dot io``.
1. Installing RGBDS
-------------------
The `installation procedure <https://rgbds.gbdev.io/install>`__ is available
online for various platforms. `Building from source <https://rgbds.gbdev.io/install/#building-from-source>`__
online for various platforms. `Building from source <https://rgbds.gbdev.io/install/source>`__
is possible using ``make`` or ``cmake``; follow the link for more detailed instructions.
.. code:: sh
@@ -40,13 +44,13 @@ is possible using ``make`` or ``cmake``; follow the link for more detailed instr
2. RGBDS Folder Organization
----------------------------
The RGBDS source code file structure somewhat resembles the following:
The RGBDS source code file structure is as follows:
::
.
├── .github/
│ ├── actions/
│ ├── scripts/
│ │ └── ...
│ └── workflows/
│ └── ...
@@ -76,6 +80,7 @@ The RGBDS source code file structure somewhat resembles the following:
│ └── run-tests.sh
├── .clang-format
├── CMakeLists.txt
├── Dockerfile
├── Makefile
└── README.rst
@@ -85,50 +90,75 @@ The RGBDS source code file structure somewhat resembles the following:
- ``.github/`` - files and scripts related to the integration of the RGBDS codebase with
GitHub.
* ``actions/`` - scripts used by workflow files.
* ``scripts/`` - scripts used by workflow files.
* ``workflows/`` - CI workflow description files.
- ``contrib/`` - scripts and other resources which may be useful to users and developers of
RGBDS.
* ``zsh_compl`` contains tab completion scripts for use with zsh. Put them somewhere in your ``fpath``, and they should auto-load.
* ``zsh_compl`` contains tab completion scripts for use with zsh. Put them somewhere in
your ``fpath``, and they should auto-load.
* ``bash_compl`` contains tab completion scripts for use with bash. Run them with ``source`` somewhere in your ``.bashrc``, and they should load every time you open a shell.
* ``bash_compl`` contains tab completion scripts for use with bash. Run them with ``source``
somewhere in your ``.bashrc``, and they should load every time you open a shell.
- ``include/`` - header files for each respective C files in `src`.
- ``include/`` - header files for the respective source files in `src`.
- ``man/`` - manual pages.
- ``src/`` - source code of RGBDS.
* Note that the code unique to each RGBDS tool is stored in its respective subdirectory
(rgbasm -> ``src/asm/``, for example). ``src/extern/`` contains code imported from external sources.
(rgbasm -> ``src/asm/``, for example). ``src/extern/`` contains code imported from
external sources.
- ``test/`` - testing framework used to verify that changes to the code don't break or modify the behavior of RGBDS.
- ``test/`` - testing framework used to verify that changes to the code don't break or
modify the behavior of RGBDS.
- ``.clang-format`` - code style for automated formatting with |clang-format|_. The C code does not currently follow this style, but all C++ code should.
- ``.clang-format`` - code style for automated C++ formatting with |clang-format|_.
- ``Dockerfile`` - defines how to build RGBDS with Docker.
3. History
----------
- Around 1997, Carsten Sørensen (AKA SurfSmurf) writes ASMotor as a
general-purpose assembler/linker system for DOS/Win32
- 1996-10-01: Carsten Sørensen (a.k.a. SurfSmurf) releases
`xAsm <http://otakunozoku.com/RGBDSdocs/asm.htm>`__,
`xLink <http://otakunozoku.com/RGBDSdocs/link.htm>`__, and
`RGBFix <http://otakunozoku.com/RGBDSdocs/fix.htm>`__,
a Game Boy SM83 (GBZ80) assembler/linker system for DOS/Win32.
- Around 1999, Justin Lloyd (AKA Otaku no Zoku) adapts ASMotor to read and
produce GBZ80 assembly/machine code, and releases this version as RGBDS.
- 1997-07-03: Sørensen releases `ASMotor <http://otakunozoku.com/RGBDSdocs/geninfo.htm>`__,
packaging the three programs together and moving towards making them a
general-purpose target-independent system.
- 2009, Vegard Nossum adapts the code to be more UNIX-like and releases
this version as rgbds-linux on
`GitHub <https://github.com/vegard/rgbds-linux>`__.
- 1999-08-01: Justin Lloyd (a.k.a. Otaku no Zoku) adapts ASMotor to re-focus
on SM83 assembly/machine code, and releases this version as
`RGBDS <http://otakunozoku.com/rednex-gameboy-development-system/>`__.
- 2010, Anthony J. Bentley forks that repository. The fork becomes the reference
implementation of rgbds.
- 2009-06-11: Vegard Nossum adapts the code to be more UNIX-like and releases
this version as `rgbds-linux <https://github.com/vegard/rgbds-linux>`__.
- 2017, Bentley's repository is moved to a neutral name.
- 2010-01-12: Anthony J. Bentley `forks <https://github.com/bentley>`__ Nossum's
repository. The fork becomes the reference implementation of RGBDS.
- 2018, codebase relicensed under the MIT license.
- 2015-01-18: stag019 begins implementing `rgbgfx <https://github.com/stag019/rgbgfx>`__,
a PNGtoGame Boy graphics converter, for eventual integration into RGBDS.
- 2020, repository is moved to the `gbdev <https://github.com/gbdev>`__ organisation. The `rgbds.gbdev.io <https://rgbds.gbdev.io>`__ website serving documentation and downloads is created.
- 2016-09-05: rgbgfx is `integrated <https://github.com/gbdev/rgbds/commit/c3c31138ddbd8680d4e67957e387f2816798a71b>`__
into Bentley's repository.
- 2017-02-23: Bentley's repository is moved to the `rednex <https://github.com/rednex>`__
organization.
- 2018-01-26: The codebase is `relicensed <https://github.com/gbdev/rgbds/issues/128>`__
under the MIT license.
- 2020-09-15: The repository is `moved <https://github.com/gbdev/rgbds/issues/567>`__
to the `gbdev <https://github.com/gbdev>`__ organization.
- 2022-05-17: The `rgbds.gbdev.io <https://rgbds.gbdev.io>`__ website for RGBDS
documentation and downloads is published.
4. Acknowledgements
-------------------
@@ -137,3 +167,5 @@ RGBGFX generates palettes using algorithms found in the paper
`"Algorithms for the Pagination Problem, a Bin Packing with Overlapping Items" <http://arxiv.org/abs/1605.00558>`__
(`GitHub <https://github.com/pagination-problem/pagination>`__, MIT license),
by Aristide Grange, Imed Kacem, and Sébastien Martin.
RGBGFX's color palette was taken from `SameBoy <https://sameboy.github.io>`__, with permission and help by `LIJI <https://github.com/LIJI32>`__.

View File

@@ -4,16 +4,17 @@ Releasing
This describes for the maintainers of RGBDS how to publish a new release on
GitHub.
1. Update, commit, and push `include/version.h <include/version.h>`__ with
1. Update, commit, and push `include/version.hpp <include/version.hpp>`__ with
values for ``PACKAGE_VERSION_MAJOR``, ``PACKAGE_VERSION_MINOR``,
``PACKAGE_VERSION_PATCH``, and ``PACKAGE_VERSION_RC``. Only define
``PACKAGE_VERSION_PATCH``, and ``PACKAGE_VERSION_RC``, as well as
`Dockerfile <Dockerfile>`__ with a value for ``ARG version``. Only define
``PACKAGE_VERSION_RC`` if you are publishing a release candidate! You can
use ``git commit -m "Release <version>"`` and ``git push origin master``.
2. Create a Git tag formatted as ``v<MAJOR>.<MINOR>.<PATCH>``, or
``v<MAJOR>.<MINOR>.<PATCH>-rc<RC>`` for a release candidate. ``MAJOR``,
``MINOR``, ``PATCH``, and ``RC`` should match their values from
`include/version.h <include/version.h>`__. You can use ``git tag <tag>``.
`include/version.hpp <include/version.hpp>`__. You can use ``git tag <tag>``.
3. Push the tag to GitHub. You can use ``git push origin <tag>``.

View File

@@ -1,4 +1,4 @@
#/usr/bin/env bash
#!/usr/bin/env bash
# Known bugs:
# - Newlines in file/directory names break this script
@@ -11,7 +11,7 @@
# - Directories are not completed as such in "coalesced" short-opt arguments. For example,
# `rgbasm -M d<tab>` can autocomplete to `rgbasm -M dir/` (no space), but
# `rgbasm -Md<tab>` would autocomplete to `rgbasm -Mdir ` (trailing space) instead.
# This is because dircetory handling is performed by Readline, whom we can't tell about the short
# This is because directory handling is performed by Readline, whom we can't tell about the short
# opt kerfuffle. The user can work around by separating the argument, as shown above.
# (Also, there might be more possible bugs if `-Mdir` is actually a directory. Ugh.)
@@ -20,27 +20,30 @@
# Thus, we don't need to do much to handle that form of argument passing: skip '=' after long opts.
_rgbasm_completions() {
COMPREPLY=()
# Format: "long_opt:state_after"
# Empty long opt = it doesn't exit
# See the `state` variable below for info about `state_after`
declare -A opts=(
[V]="version:normal"
[E]="export-all:normal"
[H]="nop-after-halt:normal"
[h]="halt-without-nop:normal"
[L]="preserve-ld:normal"
[l]="auto-ldh:normal"
[v]="verbose:normal"
[w]=":normal"
[b]="binary-digits:unk"
[D]="define:unk"
[g]="gfx-chars:unk"
[i]="include:dir"
[I]="include:dir"
[M]="dependfile:glob-*.mk *.d"
[o]="output:glob-*.o"
[P]="preinclude:glob-*.asm *.inc"
[p]="pad-value:unk"
[Q]="q-precision:unk"
[r]="recursion-depth:unk"
[W]="warning:warning"
[X]="max-errors:unk"
)
# Parse command-line up to current word
local opt_ena=true
@@ -58,6 +61,18 @@ _rgbasm_completions() {
# "normal" is not returned, `optlen` will be set to the length (dash included) of the "option"
# part of the argument.
parse_short_opt() {
# These options act like a long option (= takes up the entire word), but only use a single dash
# So, they need some special handling
if [[ "$1" = "-M"[GP] ]]; then
state=normal
optlen=${#1}
return;
elif [[ "$1" = "-M"[QT] ]]; then
state='glob-*.d *.mk *.o'
optlen=${#1}
return;
fi
for (( i = 1; i < "${#1}"; i++ )); do
# If the option is not known, assume it doesn't take an argument
local opt="${opts["${1:$i:1}"]:-":normal"}"
@@ -71,7 +86,7 @@ _rgbasm_completions() {
optlen=0
}
for (( i = 1; i < $COMP_CWORD; i++ )); do
for (( i = 1; i < COMP_CWORD; i++ )); do
local word="${COMP_WORDS[$i]}"
# If currently processing an argument, skip this word
@@ -87,7 +102,7 @@ _rgbasm_completions() {
fi
# Check if it's a long option
if [[ "${word:0:2}" = '--' ]]; then
if [[ "$word" = '--'* ]]; then
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
for long_opt in "${opts[@]}"; do
if [[ "$word" = "--${long_opt%%:*}" ]]; then
@@ -103,25 +118,16 @@ _rgbasm_completions() {
fi
done
# Check if it's a short option
elif [[ "${word:0:1}" = '-' ]]; then
# The `-M?` ones are a mix of short and long, augh
# They must match the *full* word, but only take a single dash
# So, handle them here
if [[ "$1" = "-M"[GP] ]]; then
state=normal
elif [[ "$1" = "-M"[TQ] ]]; then
state='glob-*.d *.mk *.o'
else
parse_short_opt "$word"
# The last option takes an argument...
if [[ "$state" != 'normal' ]]; then
if [[ "$optlen" -ne "${#word}" ]]; then
# If it's contained within the word, we won't complete it, revert to "normal"
state=normal
else
# Otherwise, complete it, but start at the beginning of *that* word
optlen=0
fi
elif [[ "$word" = '-'* ]]; then
parse_short_opt "$word"
# The last option takes an argument...
if [[ "$state" != 'normal' ]]; then
if [[ "$optlen" -ne "${#word}" ]]; then
# If it's contained within the word, we won't complete it, revert to "normal"
state=normal
else
# Otherwise, complete it, but start at the beginning of *that* word
optlen=0
fi
fi
fi
@@ -129,48 +135,48 @@ _rgbasm_completions() {
# Parse current word
# Careful that it might look like an option, so use `--` aggressively!
local cur_word="${COMP_WORDS[$COMP_CWORD]}"
local cur_word="${COMP_WORDS[$i]}"
# Process options, as short ones may change the state
if $opt_ena && [[ "$state" = 'normal' && "${cur_word:0:1}" = '-' ]]; then
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
# We might want to complete to an option or an arg to that option
# Parse the option word to check
# There's no whitespace in the option names, so we can ride a little dirty...
# Is this a long option?
if [[ "${cur_word:1:1}" = '-' ]]; then
if [[ "$cur_word" = '--'* ]]; then
# It is, try to complete one
COMPREPLY+=( $(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}") )
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
return 0
elif [[ "$cur_word" = '-M'[GPQT] ]]; then
# These options act like long opts with no arguments, so return them and exactly them
COMPREPLY=( "$cur_word" )
return 0
else
# Short options may be grouped, parse them to determine what to complete
# The `-M?` ones may not be followed by anything
if [[ "$1" != "-M"[GPTQ] ]]; then
parse_short_opt "$cur_word"
# We got some short options that behave like long ones
COMPREPLY+=( $(compgen -W '-MG -MP -MT -MQ' -- "$cur_word") )
parse_short_opt "$cur_word"
if [[ "$state" = 'normal' ]]; then
COMPREPLY+=( $(compgen -W "${!opts[*]}" -P "$cur_word" '') )
return 0
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
# This short option group only awaits its argument!
# Post the option group as-is as a reply so that Readline inserts a space,
# so that the next completion request switches to the argument
# An exception is made for warnings, since it's idiomatic to stick them to the
# `-W`, and it doesn't break anything.
COMPREPLY+=( "$cur_word" )
return 0
fi
if [[ "$state" = 'normal' ]]; then
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" ''; compgen -W '-MG -MP -MQ -MT' "$cur_word")
return 0
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
# This short option group only awaits its argument!
# Post the option group as-is as a reply so that Readline inserts a space,
# so that the next completion request switches to the argument
# An exception is made for warnings, since it's idiomatic to stick them to the
# `-W`, and it doesn't break anything.
COMPREPLY=( "$cur_word" )
return 0
fi
fi
fi
COMPREPLY=()
case "$state" in
unk) # Return with no replies: no idea what to complete!
;;
warning)
COMPREPLY+=( $(compgen -W "
mapfile -t COMPREPLY < <(compgen -W "
assert
backwards-for
builtin-args
@@ -188,11 +194,12 @@ _rgbasm_completions() {
shift
shift-amount
truncation
unmapped-char
user
all
extra
everything
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}") )
error" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
;;
normal) # Acts like a glob...
state="glob-*.asm *.inc *.sm83"
@@ -209,6 +216,10 @@ _rgbasm_completions() {
done < <(compgen -A directory -- "${cur_word:$optlen}")
compopt -o filenames
;;
*)
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
return 1
;;
esac
}

View File

@@ -1,10 +1,8 @@
#/usr/bin/env bash
#!/usr/bin/env bash
# Same notes as RGBASM
_rgbfix_completions() {
COMPREPLY=()
# Format: "long_opt:state_after"
# Empty long opt = it doesn't exit
# See the `state` variable below for info about `state_after`
@@ -54,7 +52,7 @@ _rgbfix_completions() {
optlen=0
}
for (( i = 1; i < $COMP_CWORD; i++ )); do
for (( i = 1; i < COMP_CWORD; i++ )); do
local word="${COMP_WORDS[$i]}"
# If currently processing an argument, skip this word
@@ -70,7 +68,7 @@ _rgbfix_completions() {
fi
# Check if it's a long option
if [[ "${word:0:2}" = '--' ]]; then
if [[ "$word" = '--'* ]]; then
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
for long_opt in "${opts[@]}"; do
if [[ "$word" = "--${long_opt%%:*}" ]]; then
@@ -86,7 +84,7 @@ _rgbfix_completions() {
fi
done
# Check if it's a short option
elif [[ "${word:0:1}" = '-' ]]; then
elif [[ "$word" = '-'* ]]; then
parse_short_opt "$word"
# The last option takes an argument...
if [[ "$state" != 'normal' ]]; then
@@ -103,25 +101,25 @@ _rgbfix_completions() {
# Parse current word
# Careful that it might look like an option, so use `--` aggressively!
local cur_word="${COMP_WORDS[$COMP_CWORD]}"
local cur_word="${COMP_WORDS[$i]}"
# Process options, as short ones may change the state
if $opt_ena && [[ "$state" = 'normal' && "${cur_word:0:1}" = '-' ]]; then
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
# We might want to complete to an option or an arg to that option
# Parse the option word to check
# There's no whitespace in the option names, so we can ride a little dirty...
# Is this a long option?
if [[ "${cur_word:1:1}" = '-' ]]; then
if [[ "$cur_word" = '--'* ]]; then
# It is, try to complete one
COMPREPLY+=( $(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}") )
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
return 0
else
# Short options may be grouped, parse them to determine what to complete
parse_short_opt "$cur_word"
if [[ "$state" = 'normal' ]]; then
COMPREPLY+=( $(compgen -W "${!opts[*]}" -P "$cur_word" '') )
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
return 0
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
# This short option group only awaits its argument!
@@ -129,22 +127,25 @@ _rgbfix_completions() {
# so that the next completion request switches to the argument
# An exception is made for warnings, since it's idiomatic to stick them to the
# `-W`, and it doesn't break anything.
COMPREPLY+=( "$cur_word" )
COMPREPLY=( "$cur_word" )
return 0
fi
fi
fi
COMPREPLY=()
case "$state" in
unk) # Return with no replies: no idea what to complete!
;;
fix-spec)
COMPREPLY+=( "${cur_word}"{l,h,g,L,H,G} )
COMPREPLY=( "${cur_word}"{l,h,g,L,H,G} )
;;
mbc)
local cur_arg="${cur_word:$optlen}"
cur_arg="${cur_arg@U}"
COMPREPLY=( $(compgen -W "
compopt -o nosort # Keep `help` first in the list, mainly
mapfile -t COMPREPLY < <(compgen -W "help" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}")
mapfile -t COMPREPLY -O ${#COMPREPLY} < <(compgen -W "
ROM_ONLY
MBC1{,+RAM,+RAM+BATTERY}
MBC2{,+BATTERY}
@@ -157,8 +158,7 @@ _rgbfix_completions() {
BANDAI_TAMA5
HUC3
HUC1+RAM+BATTERY
TPP1_1.0{,+BATTERY}{,+RTC}{,+RUMBLE,+MULTIRUMBLE}" -P "${cur_word:0:$optlen}" -- "`tr 'a-z ' 'A-Z_' <<<"${cur_word/ /_}"`") )
COMPREPLY+=( $(compgen -W "help" -P "${cur_word:0:$optlen}" -- "${cur_word:$optlen}") )
TPP1_1.0{,+BATTERY}{,+RTC}{,+RUMBLE,+MULTIRUMBLE}" -P "${cur_word:0:$optlen}" -- "${cur_word/ /_}")
;;
normal) # Acts like a glob...
state="glob-*.gb *.gbc *.sgb"
@@ -175,6 +175,10 @@ _rgbfix_completions() {
done < <(compgen -A directory -- "${cur_word:$optlen}")
compopt -o filenames
;;
*)
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
return 1
;;
esac
}

View File

@@ -1,10 +1,8 @@
#/usr/bin/env bash
#!/usr/bin/env bash
# Same notes as RGBASM
_rgbgfx_completions() {
COMPREPLY=()
# Format: "long_opt:state_after"
# Empty long opt = it doesn't exit
# See the `state` variable below for info about `state_after`
@@ -12,25 +10,26 @@ _rgbgfx_completions() {
[V]="version:normal"
[C]="color-curve:normal"
[m]="mirror-tiles:normal"
[O]="group-outputs:normal"
[u]="unique-tiles:normal"
[v]="verbose:normal"
[Z]="columns:normal"
[a]="attr-map:*.attrmap"
[A]="output-attr-map:normal"
[a]="attr-map:glob-*.attrmap"
[A]="auto-attr-map:normal"
[b]="base-tiles:unk"
[d]="depth:unk"
[L]="slice:unk"
[N]="nb-tiles:unk"
[n]="nb-palettes:unk"
[o]="output:glob *.2bpp"
[p]="palette:glob *.pal"
[P]="output-palette:normal"
[q]="palette-map:glob *.palmap"
[Q]="output-palette-map:normal"
[o]="output:glob-*.2bpp"
[p]="palette:glob-*.pal"
[P]="auto-palette:normal"
[q]="palette-map:glob-*.palmap"
[Q]="auto-palette-map:normal"
[r]="reverse:unk"
[s]="palette-size:unk"
[t]="tilemap:glob *.tilemap"
[T]="output-tilemap:normal"
[t]="tilemap:glob-*.tilemap"
[T]="auto-tilemap:normal"
[x]="trim-end:unk"
)
# Parse command-line up to current word
@@ -62,7 +61,7 @@ _rgbgfx_completions() {
optlen=0
}
for (( i = 1; i < $COMP_CWORD; i++ )); do
for (( i = 1; i < COMP_CWORD; i++ )); do
local word="${COMP_WORDS[$i]}"
# If currently processing an argument, skip this word
@@ -78,7 +77,7 @@ _rgbgfx_completions() {
fi
# Check if it's a long option
if [[ "${word:0:2}" = '--' ]]; then
if [[ "$word" = '--'* ]]; then
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
for long_opt in "${opts[@]}"; do
if [[ "$word" = "--${long_opt%%:*}" ]]; then
@@ -94,7 +93,7 @@ _rgbgfx_completions() {
fi
done
# Check if it's a short option
elif [[ "${word:0:1}" = '-' ]]; then
elif [[ "$word" = '-'* ]]; then
parse_short_opt "$word"
# The last option takes an argument...
if [[ "$state" != 'normal' ]]; then
@@ -111,25 +110,25 @@ _rgbgfx_completions() {
# Parse current word
# Careful that it might look like an option, so use `--` aggressively!
local cur_word="${COMP_WORDS[$COMP_CWORD]}"
local cur_word="${COMP_WORDS[$i]}"
# Process options, as short ones may change the state
if $opt_ena && [[ "$state" = 'normal' && "${cur_word:0:1}" = '-' ]]; then
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
# We might want to complete to an option or an arg to that option
# Parse the option word to check
# There's no whitespace in the option names, so we can ride a little dirty...
# Is this a long option?
if [[ "${cur_word:1:1}" = '-' ]]; then
if [[ "$cur_word" = '--'* ]]; then
# It is, try to complete one
COMPREPLY+=( $(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}") )
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
return 0
else
# Short options may be grouped, parse them to determine what to complete
parse_short_opt "$cur_word"
if [[ "$state" = 'normal' ]]; then
COMPREPLY+=( $(compgen -W "${!opts[*]}" -P "$cur_word" '') )
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
return 0
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
# This short option group only awaits its argument!
@@ -137,12 +136,13 @@ _rgbgfx_completions() {
# so that the next completion request switches to the argument
# An exception is made for warnings, since it's idiomatic to stick them to the
# `-W`, and it doesn't break anything.
COMPREPLY+=( "$cur_word" )
COMPREPLY=( "$cur_word" )
return 0
fi
fi
fi
COMPREPLY=()
case "$state" in
unk) # Return with no replies: no idea what to complete!
;;
@@ -161,6 +161,10 @@ _rgbgfx_completions() {
done < <(compgen -A directory -- "${cur_word:$optlen}")
compopt -o filenames
;;
*)
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
return 1
;;
esac
}

View File

@@ -1,10 +1,8 @@
#/usr/bin/env bash
#!/usr/bin/env bash
# Same notes as RGBASM
_rgblink_completions() {
COMPREPLY=()
# Format: "long_opt:state_after"
# Empty long opt = it doesn't exit
# See the `state` variable below for info about `state_after`
@@ -16,6 +14,7 @@ _rgblink_completions() {
[w]="wramx:normal"
[x]="nopad:normal"
[l]="linkerscript:glob-*"
[M]="no-sym-in-map:normal"
[m]="map:glob-*.map"
[n]="sym:glob-*.sym"
[O]="overlay:glob-*.gb *.gbc *.sgb"
@@ -52,7 +51,7 @@ _rgblink_completions() {
optlen=0
}
for (( i = 1; i < $COMP_CWORD; i++ )); do
for (( i = 1; i < COMP_CWORD; i++ )); do
local word="${COMP_WORDS[$i]}"
# If currently processing an argument, skip this word
@@ -68,7 +67,7 @@ _rgblink_completions() {
fi
# Check if it's a long option
if [[ "${word:0:2}" = '--' ]]; then
if [[ "$word" = '--'* ]]; then
# If the option is unknown, assume it takes no arguments: keep the state at "normal"
for long_opt in "${opts[@]}"; do
if [[ "$word" = "--${long_opt%%:*}" ]]; then
@@ -84,7 +83,7 @@ _rgblink_completions() {
fi
done
# Check if it's a short option
elif [[ "${word:0:1}" = '-' ]]; then
elif [[ "$word" = '-'* ]]; then
parse_short_opt "$word"
# The last option takes an argument...
if [[ "$state" != 'normal' ]]; then
@@ -101,25 +100,25 @@ _rgblink_completions() {
# Parse current word
# Careful that it might look like an option, so use `--` aggressively!
local cur_word="${COMP_WORDS[$COMP_CWORD]}"
local cur_word="${COMP_WORDS[$i]}"
# Process options, as short ones may change the state
if $opt_ena && [[ "$state" = 'normal' && "${cur_word:0:1}" = '-' ]]; then
if $opt_ena && [[ "$state" = 'normal' && "$cur_word" = '-'* ]]; then
# We might want to complete to an option or an arg to that option
# Parse the option word to check
# There's no whitespace in the option names, so we can ride a little dirty...
# Is this a long option?
if [[ "${cur_word:1:1}" = '-' ]]; then
if [[ "$cur_word" = '--'* ]]; then
# It is, try to complete one
COMPREPLY+=( $(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}") )
mapfile -t COMPREPLY < <(compgen -W "${opts[*]%%:*}" -P '--' -- "${cur_word#--}")
return 0
else
# Short options may be grouped, parse them to determine what to complete
parse_short_opt "$cur_word"
if [[ "$state" = 'normal' ]]; then
COMPREPLY+=( $(compgen -W "${!opts[*]}" -P "$cur_word" '') )
mapfile -t COMPREPLY < <(compgen -W "${!opts[*]}" -P "$cur_word" '')
return 0
elif [[ "$optlen" = "${#cur_word}" && "$state" != "warning" ]]; then
# This short option group only awaits its argument!
@@ -127,12 +126,13 @@ _rgblink_completions() {
# so that the next completion request switches to the argument
# An exception is made for warnings, since it's idiomatic to stick them to the
# `-W`, and it doesn't break anything.
COMPREPLY+=( "$cur_word" )
COMPREPLY=( "$cur_word" )
return 0
fi
fi
fi
COMPREPLY=()
case "$state" in
unk) # Return with no replies: no idea what to complete!
;;
@@ -151,6 +151,10 @@ _rgblink_completions() {
done < <(compgen -A directory -- "${cur_word:$optlen}")
compopt -o filenames
;;
*)
echo >&2 "Internal completion error: invalid state \"$state\", please report this bug"
return 1
;;
esac
}

View File

@@ -1,26 +1,6 @@
#!/bin/bash
#!/usr/bin/env bash
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2021 Rangi
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
declare -A FILES
while read -r -d '' file; do
@@ -40,46 +20,49 @@ dependency () {
# Pull requests that edit the first file without the second may be correct,
# but are suspicious enough to require review.
dependency include/linkdefs.h man/rgbds.5 \
dependency include/linkdefs.hpp man/rgbds.5 \
"Was the object file format changed?"
dependency src/asm/parser.y man/rgbasm.5 \
dependency src/asm/parser.y man/rgbasm.5 \
"Was the rgbasm grammar changed?"
dependency include/asm/warning.h man/rgbasm.1 \
dependency src/link/script.y man/rgblink.5 \
"Was the linker script grammar changed?"
dependency include/asm/warning.hpp man/rgbasm.1 \
"Were the rgbasm warnings changed?"
dependency src/asm/object.c include/linkdefs.h \
dependency src/asm/object.cpp include/linkdefs.hpp \
"Should the object file revision be bumped?"
dependency src/link/object.c include/linkdefs.h \
dependency src/link/object.cpp include/linkdefs.hpp \
"Should the object file revision be bumped?"
dependency Makefile CMakeLists.txt \
dependency Makefile CMakeLists.txt \
"Did the build process change?"
dependency Makefile src/CMakeLists.txt \
dependency Makefile src/CMakeLists.txt \
"Did the build process change?"
dependency src/asm/main.c man/rgbasm.1 \
dependency src/asm/main.cpp man/rgbasm.1 \
"Did the rgbasm CLI change?"
dependency src/asm/main.c contrib/zsh_compl/_rgbasm \
dependency src/asm/main.cpp contrib/zsh_compl/_rgbasm \
"Did the rgbasm CLI change?"
dependency src/asm/main.c contrib/bash_compl/_rgbasm.bash \
dependency src/asm/main.cpp contrib/bash_compl/_rgbasm.bash \
"Did the rgbasm CLI change?"
dependency src/link/main.c man/rgblink.1 \
dependency src/link/main.cpp man/rgblink.1 \
"Did the rgblink CLI change?"
dependency src/link/main.c contrib/zsh_compl/_rgblink \
dependency src/link/main.cpp contrib/zsh_compl/_rgblink \
"Did the rgblink CLI change?"
dependency src/link/main.c contrib/bash_compl/_rgblink.bash \
dependency src/link/main.cpp contrib/bash_compl/_rgblink.bash \
"Did the rgblink CLI change?"
dependency src/fix/main.c man/rgbfix.1 \
dependency src/fix/main.cpp man/rgbfix.1 \
"Did the rgbfix CLI change?"
dependency src/fix/main.c contrib/zsh_compl/_rgbfix \
dependency src/fix/main.cpp contrib/zsh_compl/_rgbfix \
"Did the rgbfix CLI change?"
dependency src/fix/main.c contrib/bash_compl/_rgbfix.bash \
dependency src/fix/main.cpp contrib/bash_compl/_rgbfix.bash \
"Did the rgbfix CLI change?"
dependency src/gfx/main.cpp man/rgbgfx.1 \
dependency src/gfx/main.cpp man/rgbgfx.1 \
"Did the rgbgfx CLI change?"
dependency src/gfx/main.cpp contrib/zsh_compl/_rgbgfx \
dependency src/gfx/main.cpp contrib/zsh_compl/_rgbgfx \
"Did the rgbgfx CLI change?"
dependency src/gfx/main.cpp contrib/bash_compl/_rgbgfx.bash \
dependency src/gfx/main.cpp contrib/bash_compl/_rgbgfx.bash \
"Did the rgbgfx CLI change?"

27
contrib/coverage.bash Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -e
# Build RGBDS with gcov support
make coverage -j
# Run the tests
for dir in asm link fix gfx; do
pushd test/$dir
./test.sh
popd
done
# Generate coverage logs
gcov src/**/*.{c,cpp}
mkdir -p coverage
# Generate coverage report
lcov -c --no-external -d . -o coverage/coverage.info
genhtml -f -s -o coverage/ coverage/coverage.info
# Open report in web browser
if [ "$(uname)" == "Darwin" ]; then
open coverage/index.html
else
xdg-open coverage/index.html
fi

View File

@@ -1,26 +1,6 @@
#!/bin/bash
#!/usr/bin/env bash
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2020 Eldred Habert
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
STATE=0
diff <(xxd "$1") <(xxd "$2") | while read -r LINE; do
@@ -57,7 +37,7 @@ diff <(xxd "$1") <(xxd "$2") | while read -r LINE; do
while read -r SYMADDR SYM; do
SYMADDR=$((0x${SYMADDR#*:}))
if [[ $SYMADDR -le $ADDR ]]; then
printf " (%s+%#x)\n" "$SYM" $((ADDR - SYMADDR))
printf " (%s+0x%x)\n" "$SYM" $((ADDR - SYMADDR))
fi
# TODO: assumes sorted sym files
done | tail -n 1

View File

@@ -25,10 +25,11 @@ _rgbasm_warnings() {
'shift:Warn when shifting negative values'
'shift-amount:Warn when a shift'\''s operand it negative or \> 32'
'truncation:Warn when implicit truncation loses bits'
'unmapped-char:Warn on unmapped character'
'user:Warn when executing the WARN built-in'
)
# TODO: handle `no-` and `error=` somehow?
# TODO: handle `=0|1|2` levels for `numeric-string` and `truncation`?
# TODO: handle `=0|1|2` levels for `numeric-string`, `truncation`, and `unmapped-char`?
_describe warning warnings
}
@@ -37,24 +38,29 @@ local args=(
'(- : * options)'{-V,--version}'[Print version number]'
'(-E --export-all)'{-E,--export-all}'[Export all symbols]'
'(-h --halt-without-nop)'{-h,--halt-without-nop}'[Avoid outputting a `nop` after `halt`]'
'(-L ---preserve-ld)'{-L,--preserve-ld}'[Prevent auto-optimizing `ld` into `ldh`]'
'(-H --nop-after-halt)'{-H,--nop-after-halt}'[Output a `nop` after `halt`]'
'(-h --halt-without-nop)'{-h,--halt-without-nop}'[Prevent outputting a `nop` after `halt`]'
'(-L --preserve-ld)'{-L,--preserve-ld}'[Prevent optimizing `ld` into `ldh`]'
'(-l --auto-ldh)'{-l,--auto-ldh}'[Optimize `ld` into `ldh`]'
'(-v --verbose)'{-v,--verbose}'[Print additional messages regarding progression]'
-w'[Disable all warnings]'
'(-b --binary-digits)'{-b,--binary-digits}'+[Change chars for binary constants]:digit spec:'
'*'{-D,--define}'+[Define a string symbol]:name + value (default 1):'
'(-g --gfx-chars)'{-g,--gfx-chars}'+[Change chars for gfx constants]:chars spec:'
'(-i --include)'{-i,--include}'+[Add an include directory]:include path:_files -/'
'(-I --include)'{-I,--include}'+[Add an include directory]:include path:_files -/'
'(-M --dependfile)'{-M,--dependfile}"+[List deps in make format]:output file:_files -g '*.{d,mk}'"
-MG'[Assume missing files should be generated]'
-MP'[Add phony targets to all deps]'
'*'-MT"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
'*'-MQ"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
'(-o --output)'{-o,--output}'+[Output file]:output file:_files'
'(-P --preinclude)'{-P,--preinclude}"+[Pre-include a file]:include file:_files -g '*.{asm,inc}'"
'(-p --pad-value)'{-p,--pad-value}'+[Set padding byte]:padding byte:'
'(-Q --q-precision)'{-Q,--q-precision}'+[Set fixed-point precision]:precision:'
'(-r --recursion-depth)'{-r,--recursion-depth}'+[Set maximum recursion depth]:depth:'
'(-W --warning)'{-W,--warning}'+[Toggle warning flags]:warning flag:_rgbasm_warnings'
'(-X --max-errors)'{-X,--max-errors}'+[Set maximum errors before aborting]:maximum errors:'
":assembly sources:_files -g '*.asm'"
)

View File

@@ -13,28 +13,29 @@ local args=(
# Arguments are listed here in the same order as in the manual, except for the version
'(- : * options)'{-V,--version}'[Print version number]'
'(-a --attr-map -A --output-attr-map)'{-A,--output-attr-map}'[Shortcut for -a <file>.attrmap]'
'(-a --attr-map -A --auto-attr-map)'{-A,--auto-attr-map}'[Shortcut for -a <file>.attrmap]'
'(-C --color-curve)'{-C,--color-curve}'[Generate palettes using GBC color curve]'
'(-m --mirror-tiles)'{-m,--mirror-tiles}'[Eliminate mirrored tiles from output]'
'(-p --palette -P --output-palette)'{-P,--output-palette}'[Shortcut for -p <file>.pal]'
'(-q --palette-map -Q --output-palette-map)'{-Q,--output-palette-map}'[Shortcut for -p <file>.palmap]'
'(-t --tilemap -T --output-tilemap)'{-T,--output-tilemap}'[Shortcut for -t <file>.tilemap]'
'(-O --group-outputs)'{-O,--group-outputs}'[Base "shortcut" options on the output path, not input]'
'(-p --palette -P --auto-palette)'{-P,--auto-palette}'[Shortcut for -p <file>.pal]'
'(-q --palette-map -Q --auto-palette-map)'{-Q,--auto-palette-map}'[Shortcut for -p <file>.palmap]'
'(-t --tilemap -T --auto-tilemap)'{-T,--auto-tilemap}'[Shortcut for -t <file>.tilemap]'
'(-u --unique-tiles)'{-u,--unique-tiles}'[Eliminate redundant tiles]'
{-v,--verbose}'[Enable verbose output]'
'(-h --horizontal -Z --columns)'{-Z,--columns}'[Read the image in column-major order]'
'(-Z --columns)'{-Z,--columns}'[Read the image in column-major order]'
'(-a --attr-map -A --output-attr-map)'{-a,--attr-map}'+[Generate a map of tile attributes (mirroring)]:attrmap file:_files'
'(-a --attr-map -A --auto-attr-map)'{-a,--attr-map}'+[Generate a map of tile attributes (mirroring)]:attrmap file:_files'
'(-b --base-tiles)'{-b,--base-tiles}'+[Base tile IDs for tile map output]:base tile IDs:'
'(-d --depth)'{-d,--depth}'+[Set bit depth]:bit depth:_depths'
'(-L --slice)'{-L,--slice}'+[Only process a portion of the image]:input slice:'
'(-N --nb-tiles)'{-n,--nb-tiles}'+[Limit number of tiles]:tile count:'
'(-N --nb-tiles)'{-N,--nb-tiles}'+[Limit number of tiles]:tile count:'
'(-n --nb-palettes)'{-n,--nb-palettes}'+[Limit number of palettes]:palette count:'
'(-o --output)'{-o,--output}'+[Set output file]:output file:_files'
'(-p --palette -P --output-palette)'{-p,--palette}"+[Output the image's palette in little-endian native RGB555 format]:palette file:_files"
'(-q --palette-map -Q --output-palette-map)'{-p,--palette-map}"+[Output the image's palette map]:palette map file:_files"
'(-p --palette -P --auto-palette)'{-p,--palette}"+[Output the image's palette in little-endian native RGB555 format]:palette file:_files"
'(-q --palette-map -Q --auto-palette-map)'{-q,--palette-map}"+[Output the image's palette map]:palette map file:_files"
'(-r --reverse)'{-r,--reverse}'+[Yield an image from binary data]:image width (in tiles):'
'(-s --palette-size)'{-s,--palette-size}'+[Limit palette size]:palette size:'
'(-t --tilemap -T --output-tilemap)'{-t,--tilemap}'+[Generate a map of tile indices]:tilemap file:_files'
'(-t --tilemap -T --auto-tilemap)'{-t,--tilemap}'+[Generate a map of tile indices]:tilemap file:_files'
'(-x --trim-end)'{-x,--trim-end}'+[Trim end of output by this many tiles]:tile count:'
":input png file:_files -g '*.png'"

View File

@@ -11,6 +11,7 @@ local args=(
'(-x --nopad)'{-x,--nopad}'[Disable padding the end of the final file]'
'(-l --linkerscript)'{-l,--linkerscript}"+[Use a linker script]:linker script:_files -g '*.link'"
'(-M --no-sym-in-map)'{-M,--no-sym-in-map}'[Do not output symbol names in map file]'
'(-m --map)'{-m,--map}"+[Produce a map file]:map file:_files -g '*.map'"
'(-n --sym)'(-n,--sym)"+[Produce a symbol file]:sym file:_files -g '*.sym'"
'(-O --overlay)'{-O,--overlay}'+[Overlay sections over on top of bin file]:base overlay:_files'

View File

@@ -1,23 +1,20 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_ASM_CHARMAP_H
#define RGBDS_ASM_CHARMAP_H
#include <stdbool.h>
#include <stdint.h>
#define DEFAULT_CHARMAP_NAME "main"
struct Charmap *charmap_New(char const *name, char const *baseName);
void charmap_Delete(struct Charmap *charmap);
void charmap_Set(char const *name);
void charmap_Push(void);
void charmap_Pop(void);
void charmap_Add(char *mapping, uint8_t value);
bool charmap_HasChar(char const *input);
size_t charmap_Convert(char const *input, uint8_t *output);
size_t charmap_ConvertNext(char const **input, uint8_t **output);
#endif /* RGBDS_ASM_CHARMAP_H */
#endif // RGBDS_ASM_CHARMAP_H

View File

@@ -1,30 +0,0 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2021, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_FIXPOINT_H
#define RGBDS_ASM_FIXPOINT_H
#include <stdint.h>
void fix_Print(int32_t i);
int32_t fix_Sin(int32_t i);
int32_t fix_Cos(int32_t i);
int32_t fix_Tan(int32_t i);
int32_t fix_ASin(int32_t i);
int32_t fix_ACos(int32_t i);
int32_t fix_ATan(int32_t i);
int32_t fix_ATan2(int32_t i, int32_t j);
int32_t fix_Mul(int32_t i, int32_t j);
int32_t fix_Div(int32_t i, int32_t j);
int32_t fix_Pow(int32_t i, int32_t j);
int32_t fix_Log(int32_t i, int32_t j);
int32_t fix_Round(int32_t i);
int32_t fix_Ceil(int32_t i);
int32_t fix_Floor(int32_t i);
#endif /* RGBDS_ASM_FIXPOINT_H */

28
include/asm/fixpoint.hpp Normal file
View File

@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_ASM_FIXPOINT_H
#define RGBDS_ASM_FIXPOINT_H
#include <stdint.h>
extern uint8_t fixPrecision;
uint8_t fix_Precision(void);
double fix_PrecisionFactor(void);
int32_t fix_Sin(int32_t i, int32_t q);
int32_t fix_Cos(int32_t i, int32_t q);
int32_t fix_Tan(int32_t i, int32_t q);
int32_t fix_ASin(int32_t i, int32_t q);
int32_t fix_ACos(int32_t i, int32_t q);
int32_t fix_ATan(int32_t i, int32_t q);
int32_t fix_ATan2(int32_t i, int32_t j, int32_t q);
int32_t fix_Mul(int32_t i, int32_t j, int32_t q);
int32_t fix_Mod(int32_t i, int32_t j, int32_t q);
int32_t fix_Div(int32_t i, int32_t j, int32_t q);
int32_t fix_Pow(int32_t i, int32_t j, int32_t q);
int32_t fix_Log(int32_t i, int32_t j, int32_t q);
int32_t fix_Round(int32_t i, int32_t q);
int32_t fix_Ceil(int32_t i, int32_t q);
int32_t fix_Floor(int32_t i, int32_t q);
#endif // RGBDS_ASM_FIXPOINT_H

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2020, RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_FORMAT_SPEC_H
#define RGBDS_FORMAT_SPEC_H
@@ -60,4 +54,4 @@ void fmt_FinishCharacters(struct FormatSpec *fmt);
void fmt_PrintString(char *buf, size_t bufLen, struct FormatSpec const *fmt, char const *value);
void fmt_PrintNumber(char *buf, size_t bufLen, struct FormatSpec const *fmt, uint32_t value);
#endif /* RGBDS_FORMAT_SPEC_H */
#endif // RGBDS_FORMAT_SPEC_H

View File

@@ -1,14 +1,6 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
/*
* Contains some assembler-wide defines and externs
*/
// Contains some assembler-wide defines and externs
#ifndef RGBDS_ASM_FSTACK_H
#define RGBDS_ASM_FSTACK_H
@@ -17,37 +9,35 @@
#include <stdint.h>
#include <stdio.h>
#include "asm/lexer.h"
#include "asm/lexer.hpp"
#include "linkdefs.hpp"
struct FileStackNode {
struct FileStackNode *parent; /* Pointer to parent node, for error reporting */
/* Line at which the parent context was exited; meaningless for the root level */
struct FileStackNode *parent; // Pointer to parent node, for error reporting
// Line at which the parent context was exited; meaningless for the root level
uint32_t lineNo;
struct FileStackNode *next; /* Next node in the output linked list */
bool referenced; /* If referenced, don't free! */
uint32_t ID; /* Set only if referenced: ID within the object file, -1 if not output yet */
struct FileStackNode *next; // Next node in the output linked list
bool referenced; // If referenced, don't free!
uint32_t ID; // Set only if referenced: ID within the object file, -1 if not output yet
enum {
NODE_REPT,
NODE_FILE,
NODE_MACRO,
} type;
enum FileStackNodeType type;
};
struct FileStackReptNode { /* NODE_REPT */
struct FileStackReptNode { // NODE_REPT
struct FileStackNode node;
uint32_t reptDepth;
/* WARNING: if changing this type, change overflow check in `fstk_Init` */
uint32_t iters[]; /* REPT iteration counts since last named node, in reverse depth order */
// WARNING: if changing this type, change overflow check in `fstk_Init`
uint32_t iters[]; // REPT iteration counts since last named node, in reverse depth order
};
struct FileStackNamedNode { /* NODE_FILE, NODE_MACRO */
struct FileStackNamedNode { // NODE_FILE, NODE_MACRO
struct FileStackNode node;
char name[]; /* File name for files, file::macro name for macros */
char name[]; // File name for files, file::macro name for macros
};
#define DEFAULT_MAX_DEPTH 64
extern size_t maxRecursionDepth;
struct MacroArgs;
@@ -55,11 +45,12 @@ struct MacroArgs;
void fstk_Dump(struct FileStackNode const *node, uint32_t lineNo);
void fstk_DumpCurrent(void);
struct FileStackNode *fstk_GetFileStack(void);
/* The lifetime of the returned chars is until reaching the end of that file */
// The lifetime of the returned chars is until reaching the end of that file
char const *fstk_GetFileName(void);
void fstk_AddIncludePath(char const *s);
/**
void fstk_SetPreIncludeFile(char const *s);
/*
* @param path The user-provided file name
* @param fullPath The address of a pointer, which will be made to point at the full path
* The pointer's value must be a valid argument to `realloc`, including NULL
@@ -80,4 +71,4 @@ bool fstk_Break(void);
void fstk_NewRecursionDepth(size_t newDepth);
void fstk_Init(char const *mainPath, size_t maxDepth);
#endif /* RGBDS_ASM_FSTACK_H */
#endif // RGBDS_ASM_FSTACK_H

View File

@@ -1,17 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_ASM_LEXER_H
#define RGBDS_ASM_LEXER_H
#include <stdbool.h>
#define MAXSTRLEN 255
#define MAXSTRLEN 255
struct LexerState;
extern struct LexerState *lexerState;
@@ -49,9 +43,7 @@ static inline void lexer_SetGfxDigits(char const digits[4])
gfxDigits[3] = digits[3];
}
/*
* `path` is referenced, but not held onto..!
*/
// `path` is referenced, but not held onto..!
struct LexerState *lexer_OpenFile(char const *path);
struct LexerState *lexer_OpenFileView(char const *path, char *buf, size_t size, uint32_t lineNo);
void lexer_RestartRept(uint32_t lineNo);
@@ -92,6 +84,11 @@ int yylex(void);
bool lexer_CaptureRept(struct CaptureBody *capture);
bool lexer_CaptureMacroBody(struct CaptureBody *capture);
struct AlignmentSpec {
uint8_t alignment;
uint16_t alignOfs;
};
#define INITIAL_DS_ARG_SIZE 2
struct DsArgList {
size_t nbArgs;
@@ -99,4 +96,11 @@ struct DsArgList {
struct Expression *args;
};
#endif /* RGBDS_ASM_LEXER_H */
#define INITIAL_PURGE_ARG_SIZE 2
struct PurgeArgList {
size_t nbArgs;
size_t capacity;
char **args;
};
#endif // RGBDS_ASM_LEXER_H

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2020, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_MACRO_H
#define RGBDS_MACRO_H
@@ -13,9 +7,9 @@
#include <stdbool.h>
#include <stdlib.h>
#include "asm/warning.h"
#include "asm/warning.hpp"
#include "helpers.h"
#include "helpers.hpp"
struct MacroArgs;
@@ -31,7 +25,8 @@ uint32_t macro_GetUniqueID(void);
char const *macro_GetUniqueIDStr(void);
void macro_SetUniqueID(uint32_t id);
uint32_t macro_UseNewUniqueID(void);
uint32_t macro_UndefUniqueID(void);
void macro_ShiftCurrentArgs(int32_t count);
uint32_t macro_NbArgs(void);
#endif
#endif // RGBDS_MACRO_H

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2021, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_MAIN_H
#define RGBDS_MAIN_H
@@ -13,14 +7,14 @@
#include <stdint.h>
#include <stdio.h>
#include "helpers.h"
#include "helpers.hpp"
extern bool haltnop;
extern bool haltNop;
extern bool warnOnHaltNop;
extern bool optimizeLoads;
extern bool warnOnLdOpt;
extern bool verbose;
extern bool warnings; /* True to enable warnings, false to disable them. */
extern bool warnings; // True to enable warnings, false to disable them.
extern FILE *dependfile;
extern char *targetFileName;
@@ -28,4 +22,4 @@ extern bool generatedMissingIncludes;
extern bool failedOnMissingInclude;
extern bool generatePhonyDeps;
#endif /* RGBDS_MAIN_H */
#endif // RGBDS_MAIN_H

View File

@@ -1,25 +0,0 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2021, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_OPT_H
#define RGBDS_OPT_H
#include <stdbool.h>
#include <stdint.h>
void opt_B(char const chars[2]);
void opt_G(char const chars[4]);
void opt_P(uint8_t fill);
void opt_L(bool optimize);
void opt_W(char const *flag);
void opt_Parse(char const *option);
void opt_Push(void);
void opt_Pop(void);
#endif

20
include/asm/opt.hpp Normal file
View File

@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_OPT_H
#define RGBDS_OPT_H
#include <stdbool.h>
#include <stdint.h>
void opt_B(char const chars[2]);
void opt_G(char const chars[4]);
void opt_P(uint8_t padByte);
void opt_Q(uint8_t precision);
void opt_L(bool optimize);
void opt_W(char *flag);
void opt_Parse(char *option);
void opt_Push(void);
void opt_Pop(void);
#endif // RGBDS_OPT_H

View File

@@ -1,17 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_ASM_OUTPUT_H
#define RGBDS_ASM_OUTPUT_H
#include <stdint.h>
#include "linkdefs.h"
#include "linkdefs.hpp"
struct Expression;
struct FileStackNode;
@@ -27,4 +21,4 @@ bool out_CreateAssert(enum AssertionType type, struct Expression const *expr,
char const *message, uint32_t ofs);
void out_WriteObject(void);
#endif /* RGBDS_ASM_OUTPUT_H */
#endif // RGBDS_ASM_OUTPUT_H

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_ASM_RPN_H
#define RGBDS_ASM_RPN_H
@@ -12,7 +6,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "linkdefs.h"
#include "linkdefs.hpp"
#define MAXRPNLEN 1048576
@@ -27,17 +21,13 @@ struct Expression {
uint32_t rpnPatchSize; // Size the expression will take in the object file
};
/*
* Determines if an expression is known at assembly time
*/
// Determines if an expression is known at assembly time
static inline bool rpn_isKnown(struct Expression const *expr)
{
return expr->isKnown;
}
/*
* Determines if an expression is a symbol suitable for const diffing
*/
// Determines if an expression is a symbol suitable for const diffing
static inline bool rpn_isSymbol(const struct Expression *expr)
{
return expr->isSymbol;
@@ -54,17 +44,19 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
void rpn_HIGH(struct Expression *expr, const struct Expression *src);
void rpn_LOW(struct Expression *expr, const struct Expression *src);
void rpn_ISCONST(struct Expression *expr, const struct Expression *src);
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
void rpn_NEG(struct Expression *expr, const struct Expression *src);
void rpn_NOT(struct Expression *expr, const struct Expression *src);
void rpn_BankSymbol(struct Expression *expr, char const *symName);
void rpn_BankSection(struct Expression *expr, char const *sectionName);
void rpn_BankSelf(struct Expression *expr);
void rpn_SizeOfSection(struct Expression *expr, char const *sectionName);
void rpn_StartOfSection(struct Expression *expr, char const *sectionName);
void rpn_SizeOfSectionType(struct Expression *expr, enum SectionType type);
void rpn_StartOfSectionType(struct Expression *expr, enum SectionType type);
void rpn_Free(struct Expression *expr);
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
void rpn_CheckRST(struct Expression *expr, const struct Expression *src);
void rpn_CheckNBit(struct Expression const *expr, uint8_t n);
int32_t rpn_GetConstVal(struct Expression const *expr);
#endif /* RGBDS_ASM_RPN_H */
#endif // RGBDS_ASM_RPN_H

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2020, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_SECTION_H
#define RGBDS_SECTION_H
@@ -12,8 +6,8 @@
#include <stdint.h>
#include <stdbool.h>
#include "linkdefs.h"
#include "platform.h" // NONNULL
#include "linkdefs.hpp"
#include "platform.hpp" // NONNULL
extern uint8_t fillByte;
@@ -23,8 +17,8 @@ struct Section {
char *name;
enum SectionType type;
enum SectionModifier modifier;
struct FileStackNode *src; /* Where the section was defined */
uint32_t fileLine; /* Line where the section was defined */
struct FileStackNode *src; // Where the section was defined
uint32_t fileLine; // Line where the section was defined
uint32_t size;
uint32_t org;
uint32_t bank;
@@ -44,15 +38,16 @@ struct SectionSpec {
extern struct Section *currentSection;
struct Section *sect_FindSectionByName(char const *name);
void sect_NewSection(char const *name, uint32_t secttype, uint32_t org,
void sect_NewSection(char const *name, enum SectionType type, uint32_t org,
struct SectionSpec const *attributes, enum SectionModifier mod);
void sect_SetLoadSection(char const *name, uint32_t secttype, uint32_t org,
void sect_SetLoadSection(char const *name, enum SectionType type, uint32_t org,
struct SectionSpec const *attributes, enum SectionModifier mod);
void sect_EndLoadSection(void);
struct Section *sect_GetSymbolSection(void);
uint32_t sect_GetSymbolOffset(void);
uint32_t sect_GetOutputOffset(void);
uint32_t sect_GetAlignBytes(uint8_t alignment, uint16_t offset);
void sect_AlignPC(uint8_t alignment, uint16_t offset);
void sect_StartUnion(void);
@@ -65,7 +60,6 @@ void sect_AbsByteGroup(uint8_t const *s, size_t length);
void sect_AbsWordGroup(uint8_t const *s, size_t length);
void sect_AbsLongGroup(uint8_t const *s, size_t length);
void sect_Skip(uint32_t skip, bool ds);
void sect_String(char const *s);
void sect_RelByte(struct Expression *expr, uint32_t pcShift);
void sect_RelBytes(uint32_t n, struct Expression *exprs, size_t size);
void sect_RelWord(struct Expression *expr, uint32_t pcShift);
@@ -74,9 +68,10 @@ void sect_PCRelByte(struct Expression *expr, uint32_t pcShift);
void sect_BinaryFile(char const *s, int32_t startPos);
void sect_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length);
void sect_EndSection(void);
void sect_PushSection(void);
void sect_PopSection(void);
bool sect_IsSizeKnown(struct Section const NONNULL(name));
#endif
#endif // RGBDS_SECTION_H

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2020, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_SYMBOL_H
#define RGBDS_SYMBOL_H
@@ -14,9 +8,9 @@
#include <string.h>
#include <time.h>
#include "asm/section.h"
#include "asm/section.hpp"
#include "platform.h" // MIN_NB_ELMS
#include "platform.hpp" // MIN_NB_ELMS
#define MAXSYMLEN 255
@@ -32,28 +26,28 @@ enum SymbolType {
struct Symbol {
char name[MAXSYMLEN + 1];
enum SymbolType type;
bool isExported; /* Whether the symbol is to be exported */
bool isBuiltin; /* Whether the symbol is a built-in */
bool isExported; // Whether the symbol is to be exported
bool isBuiltin; // Whether the symbol is a built-in
struct Section *section;
struct FileStackNode *src; /* Where the symbol was defined */
uint32_t fileLine; /* Line where the symbol was defined */
struct FileStackNode *src; // Where the symbol was defined
uint32_t fileLine; // Line where the symbol was defined
bool hasCallback;
union {
/* If sym_IsNumeric */
// If sym_IsNumeric
int32_t value;
int32_t (*numCallback)(void);
/* For SYM_MACRO and SYM_EQUS; TODO: have separate fields */
// For SYM_MACRO and SYM_EQUS; TODO: have separate fields
struct {
size_t macroSize;
char *macro;
};
/* For SYM_EQUS */
// For SYM_EQUS
char const *(*strCallback)(void);
};
uint32_t ID; /* ID of the symbol in the object file (-1 if none) */
struct Symbol *next; /* Next object to output in the object file */
uint32_t ID; // ID of the symbol in the object file (-1 if none)
struct Symbol *next; // Next object to output in the object file
};
bool sym_IsPC(struct Symbol const *sym);
@@ -98,9 +92,7 @@ static inline bool sym_IsExported(struct Symbol const *sym)
return sym->isExported;
}
/*
* Get a string equate's value
*/
// Get a string equate's value
static inline char const *sym_GetStringValue(struct Symbol const *sym)
{
if (sym->hasCallback)
@@ -123,18 +115,12 @@ struct Symbol *sym_AddVar(char const *symName, int32_t value);
uint32_t sym_GetPCValue(void);
uint32_t sym_GetConstantSymValue(struct Symbol const *sym);
uint32_t sym_GetConstantValue(char const *symName);
/*
* Find a symbol by exact name, bypassing expansion checks
*/
// Find a symbol by exact name, bypassing expansion checks
struct Symbol *sym_FindExactSymbol(char const *symName);
/*
* Find a symbol by exact name; may not be scoped, produces an error if it is
*/
struct Symbol *sym_FindUnscopedSymbol(char const *symName);
/*
* Find a symbol, possibly scoped, by name
*/
// Find a symbol, possibly scoped, by name
struct Symbol *sym_FindScopedSymbol(char const *symName);
// Find a scoped symbol by name; do not return `@` or `_NARG` when they have no value
struct Symbol *sym_FindScopedValidSymbol(char const *symName);
struct Symbol const *sym_GetPC(void);
struct Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char *body, size_t size);
struct Symbol *sym_Ref(char const *symName);
@@ -143,8 +129,8 @@ struct Symbol *sym_RedefString(char const *symName, char const *value);
void sym_Purge(char const *symName);
void sym_Init(time_t now);
/* Functions to save and restore the current symbol scope. */
// Functions to save and restore the current symbol scope.
char const *sym_GetCurrentSymbolScope(void);
void sym_SetCurrentSymbolScope(char const *newScope);
#endif /* RGBDS_SYMBOL_H */
#endif // RGBDS_SYMBOL_H

View File

@@ -1,17 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2019, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef WARNING_H
#define WARNING_H
#include "helpers.h"
#include "helpers.hpp"
extern unsigned int nbErrors;
extern unsigned int nbErrors, maxErrors;
enum WarningState {
WARNING_DEFAULT,
@@ -24,7 +18,7 @@ enum WarningID {
WARNING_ASSERT, // Assertions
WARNING_BACKWARDS_FOR, // `for` loop with backwards range
WARNING_BUILTIN_ARG, // Invalid args to builtins
WARNING_CHARMAP_REDEF, // Charmap entry re-definition
WARNING_CHARMAP_REDEF, // Charmap entry re-definition
WARNING_DIV, // Division undefined behavior
WARNING_EMPTY_DATA_DIRECTIVE, // `db`, `dw` or `dl` directive without data in ROM
WARNING_EMPTY_MACRO_ARG, // Empty macro argument
@@ -48,6 +42,9 @@ enum WarningID {
// Implicit truncation loses some bits
WARNING_TRUNCATION_1,
WARNING_TRUNCATION_2,
// Character without charmap entry
WARNING_UNMAPPED_CHAR_1,
WARNING_UNMAPPED_CHAR_2,
NB_PLAIN_AND_PARAM_WARNINGS,
#define NB_PARAM_WARNINGS (NB_PLAIN_AND_PARAM_WARNINGS - PARAM_WARNINGS_START)
@@ -80,7 +77,7 @@ void warning(enum WarningID id, char const *fmt, ...) format_(printf, 2, 3);
* It is also used when the assembler goes into an invalid state (for example,
* when it fails to allocate memory).
*/
_Noreturn void fatalerror(char const *fmt, ...) format_(printf, 1, 2);
[[noreturn]] void fatalerror(char const *fmt, ...) format_(printf, 1, 2);
/*
* Used for errors that make it impossible to assemble correctly, but don't
@@ -90,4 +87,4 @@ _Noreturn void fatalerror(char const *fmt, ...) format_(printf, 1, 2);
*/
void error(char const *fmt, ...) format_(printf, 1, 2);
#endif
#endif // WARNING_H

View File

@@ -1,4 +1,4 @@
/**
/*
* Allocator adaptor that interposes construct() calls to convert value-initialization
* (which is what you get with e.g. `vector::resize`) into default-initialization (which does not
* zero out non-class types).
@@ -36,4 +36,4 @@ public:
template<typename T>
using DefaultInitVec = std::vector<T, default_init_allocator<T>>;
#endif
#endif // DEFAULT_INIT_ALLOC_H

View File

@@ -1,29 +0,0 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2021, RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ERROR_H
#define RGBDS_ERROR_H
#include "helpers.h"
#include "platform.h"
#ifdef __cplusplus
extern "C" {
#endif
void warn(char const NONNULL(fmt), ...) format_(printf, 1, 2);
void warnx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
_Noreturn void err(char const NONNULL(fmt), ...) format_(printf, 1, 2);
_Noreturn void errx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
#ifdef __cplusplus
}
#endif
#endif /* RGBDS_ERROR_H */

19
include/error.hpp Normal file
View File

@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_ERROR_H
#define RGBDS_ERROR_H
#include "helpers.hpp"
#include "platform.hpp"
extern "C" {
void warn(char const NONNULL(fmt), ...) format_(printf, 1, 2);
void warnx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
[[noreturn]] void err(char const NONNULL(fmt), ...) format_(printf, 1, 2);
[[noreturn]] void errx(char const NONNULL(fmt), ...) format_(printf, 1, 2);
}
#endif // RGBDS_ERROR_H

View File

@@ -1,54 +0,0 @@
/*
* Copyright © 2005-2020 Rich Felker, et al.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* This implementation was taken from musl and modified for RGBDS */
#ifndef RGBDS_EXTERN_GETOPT_H
#define RGBDS_EXTERN_GETOPT_H
#ifdef __cplusplus
extern "C" {
#endif
extern char *musl_optarg;
extern int musl_optind, musl_opterr, musl_optopt, musl_optreset;
struct option {
char const *name;
int has_arg;
int *flag;
int val;
};
int musl_getopt_long_only(int argc, char **argv, char const *optstring,
const struct option *longopts, int *idx);
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#ifdef __cplusplus
} // extern "C"
#endif
#endif

29
include/extern/getopt.hpp vendored Normal file
View File

@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: MIT */
/* This implementation was taken from musl and modified for RGBDS */
#ifndef RGBDS_EXTERN_GETOPT_H
#define RGBDS_EXTERN_GETOPT_H
extern "C" {
extern char *musl_optarg;
extern int musl_optind, musl_opterr, musl_optopt, musl_optreset;
struct option {
char const *name;
int has_arg;
int *flag;
int val;
};
int musl_getopt_long_only(int argc, char **argv, char const *optstring,
const struct option *longopts, int *idx);
#define no_argument 0
#define required_argument 1
#define optional_argument 2
} // extern "C"
#endif

View File

@@ -1,14 +0,0 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2018, Antonio Nino Diaz and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef EXTERN_UTF8DECODER_H
#define EXTERN_UTF8DECODER_H
uint32_t decode(uint32_t *state, uint32_t *codep, uint8_t byte);
#endif /* EXTERN_UTF8DECODER_H */

8
include/extern/utf8decoder.hpp vendored Normal file
View File

@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: MIT */
#ifndef EXTERN_UTF8DECODER_H
#define EXTERN_UTF8DECODER_H
uint32_t decode(uint32_t *state, uint32_t *codep, uint8_t byte);
#endif // EXTERN_UTF8DECODER_H

98
include/file.hpp Normal file
View File

@@ -0,0 +1,98 @@
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_FILE_HPP
#define RGBDS_FILE_HPP
#include <array>
#include <assert.h>
#include <cassert>
#include <fcntl.h>
#include <fstream>
#include <ios>
#include <iostream>
#include <streambuf>
#include <string>
#include <string.h>
#include <string_view>
#include <variant>
#include "helpers.hpp"
#include "platform.hpp"
#include "gfx/main.hpp"
// Convenience feature for visiting the below.
template<typename... Ts>
struct Visitor : Ts... {
using Ts::operator()...;
};
template<typename... Ts>
Visitor(Ts...) -> Visitor<Ts...>;
class File {
// Construct a `std::streambuf *` by default, since it's probably lighter than a `filebuf`.
std::variant<std::streambuf *, std::filebuf> _file;
public:
File() {}
~File() { close(); }
/**
* This should only be called once, and before doing any `->` operations.
* Returns `nullptr` on error, and a non-null pointer otherwise.
*/
File *open(std::string const &path, std::ios_base::openmode mode) {
if (path != "-") {
return _file.emplace<std::filebuf>().open(path, mode) ? this : nullptr;
} else if (mode & std::ios_base::in) {
assert(!(mode & std::ios_base::out));
_file.emplace<std::streambuf *>(std::cin.rdbuf());
if (setmode(STDIN_FILENO, mode & std::ios_base::binary ? O_BINARY : O_TEXT) == -1) {
fatal("Failed to set stdin to %s mode: %s",
mode & std::ios_base::binary ? "binary" : "text", strerror(errno));
}
} else {
assert(mode & std::ios_base::out);
_file.emplace<std::streambuf *>(std::cout.rdbuf());
}
return this;
}
std::streambuf &operator*() {
return std::visit(Visitor{[](std::filebuf &file) -> std::streambuf & { return file; },
[](std::streambuf *buf) -> std::streambuf & { return *buf; }},
_file);
}
std::streambuf const &operator*() const {
// The non-`const` version does not perform any modifications, so it's okay.
return **const_cast<File *>(this);
}
std::streambuf *operator->() { return &**this; }
std::streambuf const *operator->() const {
// See the `operator*` equivalent.
return const_cast<File *>(this)->operator->();
}
File *close() {
return std::visit(Visitor{[this](std::filebuf &file) {
// This is called by the destructor, and an explicit `close`
// shouldn't close twice.
_file.emplace<std::streambuf *>(nullptr);
return file.close() != nullptr;
},
[](std::streambuf *buf) { return buf != nullptr; }},
_file)
? this
: nullptr;
}
char const *c_str(std::string const &path) const {
return std::visit(Visitor{[&path](std::filebuf const &) { return path.c_str(); },
[](std::streambuf const *buf) {
return buf == std::cin.rdbuf()
? "<stdin>" : "<stdout>";
}},
_file);
}
};
#endif // RGBDS_FILE_HPP

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2022, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_GFX_MAIN_HPP
#define RGBDS_GFX_MAIN_HPP
@@ -16,12 +10,12 @@
#include <utility>
#include <vector>
#include "helpers.h"
#include "helpers.hpp"
#include "gfx/rgba.hpp"
struct Options {
uint8_t reversedWidth = 0; // -r, in pixels
uint16_t reversedWidth = 0; // -r, in tiles
bool reverse() const { return reversedWidth != 0; }
bool useColorCurve = false; // -C
@@ -71,19 +65,19 @@ struct Options {
extern Options options;
/**
/*
* Prints the error count, and exits with failure
*/
[[noreturn]] void giveUp();
/**
/*
* Prints a warning, and does not change the error count
*/
void warning(char const *fmt, ...);
/**
/*
* Prints an error, and increments the error count
*/
void error(char const *fmt, ...);
/**
/*
* Prints a fatal error, increments the error count, and gives up
*/
[[noreturn]] void fatal(char const *fmt, ...);
@@ -116,8 +110,9 @@ static constexpr auto flipTable(std::integer_sequence<T, i...>) {
return byte;
}(i)...};
}
}
} // namespace detail
// Flipping tends to happen fairly often, so take a bite out of dcache to speed it up
static constexpr auto flipTable = detail::flipTable(std::make_integer_sequence<uint16_t, 256>());
#endif /* RGBDS_GFX_MAIN_HPP */
#endif // RGBDS_GFX_MAIN_HPP

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2022, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_GFX_PAL_PACKING_HPP
#define RGBDS_GFX_PAL_PACKING_HPP
@@ -21,12 +15,12 @@ class ProtoPalette;
namespace packing {
/**
/*
* Returns which palette each proto-palette maps to, and how many palettes are necessary
*/
std::tuple<DefaultInitVec<size_t>, size_t>
overloadAndRemove(std::vector<ProtoPalette> const &protoPalettes);
}
} // namespace packing
#endif /* RGBDS_GFX_PAL_PACKING_HPP */
#endif // RGBDS_GFX_PAL_PACKING_HPP

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2022, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_GFX_PAL_SORTING_HPP
#define RGBDS_GFX_PAL_SORTING_HPP
@@ -22,11 +16,11 @@ struct Palette;
namespace sorting {
void indexed(std::vector<Palette> &palettes, int palSize, png_color const *palRGB,
png_byte *palAlpha);
int palAlphaSize, png_byte *palAlpha);
void grayscale(std::vector<Palette> &palettes,
std::array<std::optional<Rgba>, 0x8001> const &colors);
void rgb(std::vector<Palette> &palettes);
}
} // namespace sorting
#endif /* RGBDS_GFX_PAL_SORTING_HPP */
#endif // RGBDS_GFX_PAL_SORTING_HPP

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2022, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_GFX_PAL_SPEC_HPP
#define RGBDS_GFX_PAL_SPEC_HPP
@@ -12,4 +6,4 @@
void parseInlinePalSpec(char const * const arg);
void parseExternalPalSpec(char const *arg);
#endif /* RGBDS_GFX_PAL_SPEC_HPP */
#endif // RGBDS_GFX_PAL_SPEC_HPP

View File

@@ -1,14 +1,9 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2022, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_GFX_CONVERT_HPP
#define RGBDS_GFX_CONVERT_HPP
void processPalettes();
void process();
#endif /* RGBDS_GFX_CONVERT_HPP */
#endif // RGBDS_GFX_CONVERT_HPP

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2022, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_GFX_PROTO_PALETTE_HPP
#define RGBDS_GFX_PROTO_PALETTE_HPP
@@ -15,15 +9,20 @@
#include <stdint.h>
class ProtoPalette {
public:
static constexpr size_t capacity = 4;
private:
// Up to 4 colors, sorted, and where SIZE_MAX means the slot is empty
// (OK because it's not a valid color index)
// Sorting is done on the raw numerical values to lessen `compare`'s complexity
std::array<uint16_t, 4> _colorIndices{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
std::array<uint16_t, capacity> _colorIndices{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
public:
/**
* Adds the specified color to the set
* Returns false if the set is full
/*
* Adds the specified color to the set, or **silently drops it** if the set is full.
*
* Returns whether the color was unique.
*/
bool add(uint16_t color);
@@ -41,4 +40,4 @@ public:
decltype(_colorIndices)::const_iterator end() const;
};
#endif /* RGBDS_GFX_PROTO_PALETTE_HPP */
#endif // RGBDS_GFX_PROTO_PALETTE_HPP

View File

@@ -1,14 +1,8 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2022, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_GFX_REVERSE_HPP
#define RGBDS_GFX_REVERSE_HPP
void reverse();
#endif /* RGBDS_GFX_REVERSE_HPP */
#endif // RGBDS_GFX_REVERSE_HPP

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2022, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_GFX_RGBA_HPP
#define RGBDS_GFX_RGBA_HPP
@@ -20,7 +14,7 @@ struct Rgba {
constexpr Rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
: red(r), green(g), blue(b), alpha(a) {}
/**
/*
* Constructs the color from a "packed" RGBA representation (0xRRGGBBAA)
*/
explicit constexpr Rgba(uint32_t rgba = 0)
@@ -35,7 +29,7 @@ struct Rgba {
(uint8_t)(cgbColor & 0x8000 ? 0x00 : 0xFF)};
}
/**
/*
* Returns this RGBA as a 32-bit number that can be printed in hex (`%08x`) to yield its CSS
* representation
*/
@@ -43,9 +37,10 @@ struct Rgba {
auto shl = [](uint8_t val, unsigned shift) { return static_cast<uint32_t>(val) << shift; };
return shl(red, 24) | shl(green, 16) | shl(blue, 8) | shl(alpha, 0);
}
friend bool operator==(Rgba const &lhs, Rgba const &rhs) { return lhs.toCSS() == rhs.toCSS(); }
friend bool operator!=(Rgba const &lhs, Rgba const &rhs) { return lhs.toCSS() != rhs.toCSS(); }
/**
/*
* CGB colors are RGB555, so we use bit 15 to signify that the color is transparent instead
* Since the rest of the bits don't matter then, we return 0x8000 exactly.
*/
@@ -55,7 +50,7 @@ struct Rgba {
bool isTransparent() const { return alpha < transparency_threshold; }
static constexpr uint8_t opacity_threshold = 0xF0;
bool isOpaque() const { return alpha >= opacity_threshold; }
/**
/*
* Computes the equivalent CGB color, respects the color curve depending on options
*/
uint16_t cgbColor() const;
@@ -64,4 +59,4 @@ struct Rgba {
uint8_t grayIndex() const;
};
#endif /* RGBDS_GFX_RGBA_HPP */
#endif // RGBDS_GFX_RGBA_HPP

View File

@@ -1,12 +1,6 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
/* Generic hashmap implementation (C++ templates are calling...) */
// Generic hashmap implementation (C++ templates are calling...)
#ifndef RGBDS_LINK_HASHMAP_H
#define RGBDS_LINK_HASHMAP_H
@@ -18,10 +12,10 @@
static_assert(HALF_HASH_NB_BITS * 2 == HASH_NB_BITS, "");
#define HASHMAP_NB_BUCKETS (1 << HALF_HASH_NB_BITS)
/* HashMapEntry is internal, please do not attempt to use it */
// HashMapEntry is internal, please do not attempt to use it
typedef struct HashMapEntry *HashMap[HASHMAP_NB_BUCKETS];
/**
/*
* Adds an element to a hashmap.
* @warning Adding a new element with an already-present key will not cause an
* error, this must be handled externally.
@@ -33,7 +27,7 @@ typedef struct HashMapEntry *HashMap[HASHMAP_NB_BUCKETS];
*/
void **hash_AddElement(HashMap map, char const *key, void *element);
/**
/*
* Removes an element from a hashmap.
* @param map The HashMap to remove the element from
* @param key The key to search the element with
@@ -41,7 +35,7 @@ void **hash_AddElement(HashMap map, char const *key, void *element);
*/
bool hash_RemoveElement(HashMap map, char const *key);
/**
/*
* Finds an element in a hashmap, and returns a pointer to its value field.
* @param map The map to consider the elements of
* @param key The key to search an element for
@@ -49,7 +43,7 @@ bool hash_RemoveElement(HashMap map, char const *key);
*/
void **hash_GetNode(HashMap const map, char const *key);
/**
/*
* Finds an element in a hashmap.
* @param map The map to consider the elements of
* @param key The key to search an element for
@@ -58,7 +52,7 @@ void **hash_GetNode(HashMap const map, char const *key);
*/
void *hash_GetElement(HashMap const map, char const *key);
/**
/*
* Executes a function on each element in a hashmap.
* @param map The map to consider the elements of
* @param func The function to run. The first argument will be the element,
@@ -67,11 +61,11 @@ void *hash_GetElement(HashMap const map, char const *key);
*/
void hash_ForEach(HashMap const map, void (*func)(void *, void *), void *arg);
/**
/*
* Cleanly empties a hashmap from its contents.
* This does not `free` the data structure itself!
* @param map The map to empty
*/
void hash_EmptyMap(HashMap map);
#endif /* RGBDS_LINK_HASHMAP_H */
#endif // RGBDS_LINK_HASHMAP_H

View File

@@ -1,19 +1,8 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2014-2020, RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef HELPERS_H
#define HELPERS_H
// Of course, MSVC does not support C11, so no _Noreturn there...
#ifdef _MSC_VER
#define _Noreturn __declspec(noreturn)
#endif
// Ideally, we'd use `__has_attribute` and `__has_builtin`, but these were only introduced in GCC 9
#ifdef __GNUC__ // GCC or compatible
#define format_(archetype, str_index, first_arg) \
@@ -30,8 +19,8 @@
#define format_(archetype, str_index, first_arg)
#define attr_(...)
// This seems to generate similar code to __builtin_unreachable, despite different semantics
// Note that executing this is undefined behavior (declared _Noreturn, but does return)
static inline _Noreturn void unreachable_(void) {}
// Note that executing this is undefined behavior (declared [[noreturn]], but does return)
[[noreturn]] static inline void unreachable_(void) {}
#endif
// Use builtins whenever possible, and shim them otherwise
@@ -93,4 +82,7 @@
// (Having two instances of `arr` is OK because the contents of `sizeof` are not evaluated.)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof *(arr))
#endif /* HELPERS_H */
// For lack of <ranges>, this adds some more brevity
#define RANGE(s) std::begin(s), std::end(s)
#endif // HELPERS_H

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2022, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_ITERTOOLS_HPP
#define RGBDS_ITERTOOLS_HPP
@@ -12,11 +6,49 @@
#include <tuple>
#include <utility>
#include "platform.hpp" // __PRETTY_FUNCTION__
template<typename... Ts>
static inline void report() {
puts(__PRETTY_FUNCTION__);
}
template<typename T>
class EnumSeqIterator {
T _value;
public:
explicit EnumSeqIterator(T value) : _value(value) {}
EnumSeqIterator &operator++() {
_value = (T)(_value + 1);
return *this;
}
auto operator*() const { return _value; }
friend auto operator==(EnumSeqIterator const &lhs, EnumSeqIterator const &rhs) {
return lhs._value == rhs._value;
}
friend auto operator!=(EnumSeqIterator const &lhs, EnumSeqIterator const &rhs) {
return lhs._value != rhs._value;
}
};
template<typename T>
class EnumSeq {
T _start;
T _stop;
public:
explicit EnumSeq(T stop) : _start((T)0), _stop(stop) {}
explicit EnumSeq(T start, T stop) : _start(start), _stop(stop) {}
EnumSeqIterator<T> begin() { return EnumSeqIterator(_start); }
EnumSeqIterator<T> end() { return EnumSeqIterator(_stop); }
};
// This is not a fully generic implementation; its current use cases only require for-loop behavior.
// We also assume that all iterators have the same length.
template<typename... Iters>
@@ -77,14 +109,12 @@ public:
template<typename T>
using Holder = std::conditional_t<std::is_lvalue_reference_v<T>, T,
std::remove_cv_t<std::remove_reference_t<T>>>;
}
} // namespace detail
/**
* Does the same number of iterations as the first container's iterator!
*/
// Does the same number of iterations as the first container's iterator!
template<typename... Containers>
static constexpr auto zip(Containers &&...cs) {
return detail::ZipContainer<detail::Holder<Containers>...>(std::forward<Containers>(cs)...);
}
#endif /* RGBDS_ITERTOOLS_HPP */
#endif // RGBDS_ITERTOOLS_HPP

View File

@@ -1,27 +0,0 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* Assigning all sections a place */
#ifndef RGBDS_LINK_ASSIGN_H
#define RGBDS_LINK_ASSIGN_H
#include <stdint.h>
extern uint64_t nbSectionsToAssign;
/**
* Assigns all sections a slice of the address space
*/
void assign_AssignSections(void);
/**
* `free`s all assignment memory that was allocated.
*/
void assign_Cleanup(void);
#endif /* RGBDS_LINK_ASSIGN_H */

17
include/link/assign.hpp Normal file
View File

@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: MIT */
// Assigning all sections a place
#ifndef RGBDS_LINK_ASSIGN_H
#define RGBDS_LINK_ASSIGN_H
#include <stdint.h>
extern uint64_t nbSectionsToAssign;
// Assigns all sections a slice of the address space
void assign_AssignSections(void);
// `free`s all assignment memory that was allocated
void assign_Cleanup(void);
#endif // RGBDS_LINK_ASSIGN_H

View File

@@ -1,12 +1,6 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
/* Declarations that all modules use, as well as `main` and related */
// Declarations that all modules use, as well as `main` and related
#ifndef RGBDS_LINK_MAIN_H
#define RGBDS_LINK_MAIN_H
@@ -14,12 +8,14 @@
#include <stdbool.h>
#include <stdio.h>
#include "helpers.h"
#include "helpers.hpp"
#include "linkdefs.hpp"
/* Variables related to CLI options */
// Variables related to CLI options
extern bool isDmgMode;
extern char *linkerScriptName;
extern char const *mapFileName;
extern bool noSymInMap;
extern char const *symFileName;
extern char const *overlayFileName;
extern char const *outputFileName;
@@ -34,30 +30,26 @@ extern bool disablePadding;
struct FileStackNode {
struct FileStackNode *parent;
/* Line at which the parent context was exited; meaningless for the root level */
// Line at which the parent context was exited; meaningless for the root level
uint32_t lineNo;
enum {
NODE_REPT,
NODE_FILE,
NODE_MACRO,
} type;
enum FileStackNodeType type;
union {
char *name; /* NODE_FILE, NODE_MACRO */
struct { /* NODE_REPT */
char *name; // NODE_FILE, NODE_MACRO
struct { // NODE_REPT
uint32_t reptDepth;
uint32_t *iters;
};
};
};
/* Helper macro for printing verbose-mode messages */
// Helper macro for printing verbose-mode messages
#define verbosePrint(...) do { \
if (beVerbose) \
fprintf(stderr, __VA_ARGS__); \
} while (0)
/**
/*
* Dump a file stack to stderr
* @param node The leaf node to dump the context of
*/
@@ -69,10 +61,10 @@ void warning(struct FileStackNode const *where, uint32_t lineNo,
void error(struct FileStackNode const *where, uint32_t lineNo,
char const *fmt, ...) format_(printf, 3, 4);
_Noreturn void fatal(struct FileStackNode const *where, uint32_t lineNo,
[[noreturn]] void fatal(struct FileStackNode const *where, uint32_t lineNo,
char const *fmt, ...) format_(printf, 3, 4);
/**
/*
* Opens a file if specified, and aborts on error.
* @param fileName The name of the file to open; if NULL, no file will be opened
* @param mode The mode to open the file with
@@ -86,4 +78,4 @@ FILE *openFile(char const *fileName, char const *mode);
fclose(tmp); \
} while (0)
#endif /* RGBDS_LINK_MAIN_H */
#endif // RGBDS_LINK_MAIN_H

View File

@@ -1,42 +1,36 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
/* Declarations related to processing of object (.o) files */
// Declarations related to processing of object (.o) files
#ifndef RGBDS_LINK_OBJECT_H
#define RGBDS_LINK_OBJECT_H
/**
/*
* Read an object (.o) file, and add its info to the data structures.
* @param fileName A path to the object file to be read
* @param i The ID of the file
*/
void obj_ReadFile(char const *fileName, unsigned int i);
/**
/*
* Perform validation on the object files' contents
*/
void obj_DoSanityChecks(void);
/**
/*
* Evaluate all assertions
*/
void obj_CheckAssertions(void);
/**
/*
* Sets up object file reading
* @param nbFiles The number of object files that will be read
*/
void obj_Setup(unsigned int nbFiles);
/**
/*
* `free`s all object memory that was allocated.
*/
void obj_Cleanup(void);
#endif /* RGBDS_LINK_OBJECT_H */
#endif // RGBDS_LINK_OBJECT_H

View File

@@ -1,35 +1,29 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
/* Outputting the result of linking */
// Outputting the result of linking
#ifndef RGBDS_LINK_OUTPUT_H
#define RGBDS_LINK_OUTPUT_H
#include <stdint.h>
#include "link/section.h"
#include "link/section.hpp"
/**
/*
* Registers a section for output.
* @param section The section to add
*/
void out_AddSection(struct Section const *section);
/**
/*
* Finds an assigned section overlapping another one.
* @param section The section that is being overlapped
* @return A section overlapping it
*/
struct Section const *out_OverlappingSection(struct Section const *section);
/**
/*
* Writes all output (bin, sym, map) files.
*/
void out_WriteFiles(void);
#endif /* RGBDS_LINK_OUTPUT_H */
#endif // RGBDS_LINK_OUTPUT_H

View File

@@ -1,21 +1,15 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
/* Applying patches to SECTIONs */
// Applying patches to SECTIONs
#ifndef RGBDS_LINK_PATCH_H
#define RGBDS_LINK_PATCH_H
#include <stdbool.h>
#include <stdint.h>
#include "link/section.h"
#include "link/section.hpp"
#include "linkdefs.h"
#include "linkdefs.hpp"
struct Assertion {
struct Patch patch;
@@ -27,15 +21,15 @@ struct Assertion {
struct Assertion *next;
};
/**
/*
* Checks all assertions
* @return true if assertion failed
*/
void patch_CheckAssertions(struct Assertion *assertion);
/**
/*
* Applies all SECTIONs' patches to them
*/
void patch_ApplyPatches(void);
#endif /* RGBDS_LINK_PATCH_H */
#endif // RGBDS_LINK_PATCH_H

View File

@@ -1,36 +0,0 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* Parsing a linker script */
#ifndef RGBDS_LINK_SCRIPT_H
#define RGBDS_LINK_SCRIPT_H
#include <stdint.h>
extern FILE * linkerScript;
struct SectionPlacement {
struct Section *section;
uint16_t org;
uint32_t bank;
};
extern uint64_t script_lineNo;
/**
* Parses the linker script to return the next section constraint
* @return A pointer to a struct, or NULL on EOF. The pointer shouldn't be freed
*/
struct SectionPlacement *script_NextSection(void);
/**
* `free`s all assignment memory that was allocated.
*/
void script_Cleanup(void);
#endif /* RGBDS_LINK_SCRIPT_H */

13
include/link/sdas_obj.hpp Normal file
View File

@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: MIT */
// Assigning all sections a place
#ifndef RGBDS_LINK_SDAS_OBJ_H
#define RGBDS_LINK_SDAS_OBJ_H
#include <stdio.h>
struct FileStackNode;
void sdobj_ReadFile(struct FileStackNode const *fileName, FILE *file);
#endif // RGBDS_LINK_SDAS_OBJ_H

View File

@@ -1,23 +1,17 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
/* Declarations manipulating symbols */
// Declarations manipulating symbols
#ifndef RGBDS_LINK_SECTION_H
#define RGBDS_LINK_SECTION_H
/* GUIDELINE: external code MUST NOT BE AWARE of the data structure used!! */
// GUIDELINE: external code MUST NOT BE AWARE of the data structure used!
#include <stdint.h>
#include <stdbool.h>
#include "link/main.h"
#include "link/main.hpp"
#include "linkdefs.h"
#include "linkdefs.hpp"
struct FileStackNode;
struct Section;
@@ -41,27 +35,29 @@ struct Patch {
};
struct Section {
/* Info contained in the object files */
// Info contained in the object files
char *name;
uint16_t size;
uint16_t offset;
enum SectionType type;
enum SectionModifier modifier;
bool isAddressFixed;
// This `struct`'s address in ROM.
// Importantly for fragments, this does not include `offset`!
uint16_t org;
bool isBankFixed;
uint32_t bank;
bool isAlignFixed;
uint16_t alignMask;
uint16_t alignOfs;
uint8_t *data; /* Array of size `size`*/
uint8_t *data; // Array of size `size`
uint32_t nbPatches;
struct Patch *patches;
/* Extra info computed during linking */
// Extra info computed during linking
struct Symbol **fileSymbols;
uint32_t nbSymbols;
struct Symbol const **symbols;
struct Section *nextu; /* The next "component" of this unionized sect */
struct Symbol **symbols;
struct Section *nextu; // The next "component" of this unionized sect
};
/*
@@ -74,27 +70,27 @@ struct Section {
*/
void sect_ForEach(void (*callback)(struct Section *, void *), void *arg);
/**
/*
* Registers a section to be processed.
* @param section The section to register.
*/
void sect_AddSection(struct Section *section);
/**
/*
* Finds a section by its name.
* @param name The name of the section to look for
* @return A pointer to the section, or NULL if it wasn't found
*/
struct Section *sect_GetSection(char const *name);
/**
/*
* `free`s all section memory that was allocated.
*/
void sect_CleanupSections(void);
/**
/*
* Checks if all sections meet reasonable criteria, such as max size
*/
void sect_DoSanityChecks(void);
#endif /* RGBDS_LINK_SECTION_H */
#endif // RGBDS_LINK_SECTION_H

View File

@@ -1,25 +1,19 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
/* Declarations manipulating symbols */
// Declarations manipulating symbols
#ifndef RGBDS_LINK_SYMBOL_H
#define RGBDS_LINK_SYMBOL_H
/* GUIDELINE: external code MUST NOT BE AWARE of the data structure used!! */
// GUIDELINE: external code MUST NOT BE AWARE of the data structure used!
#include <stdint.h>
#include "linkdefs.h"
#include "linkdefs.hpp"
struct FileStackNode;
struct Symbol {
/* Info contained in the object files */
// Info contained in the object files
char *name;
enum ExportLevel type;
char const *objFileName;
@@ -27,10 +21,11 @@ struct Symbol {
int32_t lineNo;
int32_t sectionID;
union {
// Both types must be identical
int32_t offset;
int32_t value;
};
/* Extra info computed during linking */
// Extra info computed during linking
struct Section *section;
};
@@ -46,16 +41,16 @@ void sym_ForEach(void (*callback)(struct Symbol *, void *), void *arg);
void sym_AddSymbol(struct Symbol *symbol);
/**
/*
* Finds a symbol in all the defined symbols.
* @param name The name of the symbol to look for
* @return A pointer to the symbol, or NULL if not found.
*/
struct Symbol *sym_GetSymbol(char const *name);
/**
/*
* `free`s all symbol memory that was allocated.
*/
void sym_CleanupSymbols(void);
#endif /* RGBDS_LINK_SYMBOL_H */
#endif // RGBDS_LINK_SYMBOL_H

View File

@@ -1,19 +1,14 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_LINKDEFS_H
#define RGBDS_LINKDEFS_H
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string>
#define RGBDS_OBJECT_VERSION_STRING "RGB%1u"
#define RGBDS_OBJECT_VERSION_NUMBER 9U
#define RGBDS_OBJECT_VERSION_STRING "RGB9"
#define RGBDS_OBJECT_REV 9U
enum AssertionType {
@@ -28,17 +23,17 @@ enum RPNCommand {
RPN_MUL = 0x02,
RPN_DIV = 0x03,
RPN_MOD = 0x04,
RPN_UNSUB = 0x05, // FIXME: should be renamed to "NEG" for consistency
RPN_NEG = 0x05,
RPN_EXP = 0x06,
RPN_OR = 0x10,
RPN_AND = 0x11,
RPN_XOR = 0x12,
RPN_UNNOT = 0x13, // FIXME: should be renamed to "NOT" for consistency
RPN_NOT = 0x13,
RPN_LOGAND = 0x21,
RPN_LOGOR = 0x22,
RPN_LOGUNNOT = 0x23, // FIXME: should be renamed to "LOGNOT" for consistency
RPN_LOGNOT = 0x23,
RPN_LOGEQ = 0x30,
RPN_LOGNE = 0x31,
@@ -56,6 +51,8 @@ enum RPNCommand {
RPN_BANK_SELF = 0x52,
RPN_SIZEOF_SECT = 0x53,
RPN_STARTOF_SECT = 0x54,
RPN_SIZEOF_SECTTYPE = 0x55,
RPN_STARTOF_SECTTYPE = 0x56,
RPN_HRAM = 0x60,
RPN_RST = 0x61,
@@ -74,9 +71,56 @@ enum SectionType {
SECTTYPE_SRAM,
SECTTYPE_OAM,
// In RGBLINK, this is used for "indeterminate" sections; this is primarily for SDCC
// areas, which do not carry any section type info and must be told from the linker script
SECTTYPE_INVALID
};
enum FileStackNodeType {
NODE_REPT,
NODE_FILE,
NODE_MACRO,
};
// Nont-`const` members may be patched in RGBLINK depending on CLI flags
extern struct SectionTypeInfo {
std::string const name;
uint16_t const startAddr;
uint16_t size;
uint32_t const firstBank;
uint32_t lastBank;
} sectionTypeInfo[SECTTYPE_INVALID];
/*
* Tells whether a section has data in its object file definition,
* depending on type.
* @param type The section's type
* @return `true` if the section's definition includes data
*/
static inline bool sect_HasData(enum SectionType type)
{
assert(type != SECTTYPE_INVALID);
return type == SECTTYPE_ROM0 || type == SECTTYPE_ROMX;
}
/*
* Computes a memory region's end address (last byte), eg. 0x7FFF
* @return The address of the last byte in that memory region
*/
static inline uint16_t endaddr(enum SectionType type)
{
return sectionTypeInfo[type].startAddr + sectionTypeInfo[type].size - 1;
}
/*
* Computes a memory region's number of banks
* @return The number of banks, 1 for regions without banking
*/
static inline uint32_t nbbanks(enum SectionType type)
{
return sectionTypeInfo[type].lastBank - sectionTypeInfo[type].firstBank + 1;
}
enum SectionModifier {
SECTION_NORMAL,
SECTION_UNION,
@@ -85,17 +129,6 @@ enum SectionModifier {
extern char const * const sectionModNames[];
/**
* Tells whether a section has data in its object file definition,
* depending on type.
* @param type The section's type
* @return `true` if the section's definition includes data
*/
static inline bool sect_HasData(enum SectionType type)
{
return type == SECTTYPE_ROM0 || type == SECTTYPE_ROMX;
}
enum ExportLevel {
SYMTYPE_LOCAL,
SYMTYPE_IMPORT,
@@ -111,45 +144,4 @@ enum PatchType {
PATCHTYPE_INVALID
};
#define BANK_MIN_ROM0 0
#define BANK_MAX_ROM0 0
#define BANK_MIN_ROMX 1
#define BANK_MAX_ROMX 511
#define BANK_MIN_VRAM 0
#define BANK_MAX_VRAM 1
#define BANK_MIN_SRAM 0
#define BANK_MAX_SRAM 15
#define BANK_MIN_WRAM0 0
#define BANK_MAX_WRAM0 0
#define BANK_MIN_WRAMX 1
#define BANK_MAX_WRAMX 7
#define BANK_MIN_OAM 0
#define BANK_MAX_OAM 0
#define BANK_MIN_HRAM 0
#define BANK_MAX_HRAM 0
extern uint16_t startaddr[];
extern uint16_t maxsize[];
extern uint32_t bankranges[][2];
/**
* Computes a memory region's end address (last byte), eg. 0x7FFF
* @return The address of the last byte in that memory region
*/
static inline uint16_t endaddr(enum SectionType type)
{
return startaddr[type] + maxsize[type] - 1;
}
/**
* Computes a memory region's number of banks
* @return The number of banks, 1 for regions without banking
*/
static inline uint32_t nbbanks(enum SectionType type)
{
return bankranges[type][1] - bankranges[type][0] + 1;
}
extern char const * const typeNames[SECTTYPE_INVALID];
#endif /* RGBDS_LINKDEFS_H */
#endif // RGBDS_LINKDEFS_H

View File

@@ -1,10 +1,4 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2021, RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_OP_MATH_H
#define RGBDS_OP_MATH_H
@@ -18,4 +12,4 @@ int32_t op_shift_left(int32_t value, int32_t amount);
int32_t op_shift_right(int32_t value, int32_t amount);
int32_t op_shift_right_unsigned(int32_t value, int32_t amount);
#endif /* RGBDS_OP_MATH_H */
#endif // RGBDS_OP_MATH_H

View File

@@ -1,12 +1,6 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2020 RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
/* platform-specific hacks */
// platform-specific hacks
#ifndef RGBDS_PLATFORM_H
#define RGBDS_PLATFORM_H
@@ -20,20 +14,29 @@
# include <strings.h>
#endif
/* MSVC has deprecated strdup in favor of _strdup */
// MSVC has deprecated strdup in favor of _strdup
#ifdef _MSC_VER
# define strdup _strdup
#endif
/* MSVC prefixes the names of S_* macros with underscores,
and doesn't define any S_IS* macros. Define them ourselves */
// MSVC prefixes the names of S_* macros with underscores,
// and doesn't define any S_IS* macros; define them ourselves
#ifdef _MSC_VER
# define S_IFMT _S_IFMT
# define S_IFDIR _S_IFDIR
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
/* MSVC doesn't use POSIX types or defines for `read` */
// gcc has __PRETTY_FUNCTION__, MSVC has __FUNCSIG__, __func__ is standard
#ifndef __PRETTY_FUNCTION__
# ifdef __FUNCSIG__
# define __PRETTY_FUNCTION__ __FUNCSIG__
# else
# define __PRETTY_FUNCTION__ __func__
# endif
#endif
// MSVC doesn't use POSIX types or defines for `read`
#ifdef _MSC_VER
# include <io.h>
# define STDIN_FILENO 0
@@ -46,15 +49,17 @@
# include <unistd.h>
#endif
/* MSVC doesn't support `[static N]` for array arguments from C99 or C11 */
#ifdef _MSC_VER
# define MIN_NB_ELMS(N)
# define ARR_QUALS(...)
# define NONNULL(ptr) *ptr
// C++ doesn't support `[static N]` for array arguments from C99 or C11
#define MIN_NB_ELMS(N) // static (N)
#define ARR_QUALS(...) // __VA_ARGS__
#define NONNULL(ptr) *ptr // ptr[static 1]
#define restrict
// C++ doesn't support designated array initializers, but they're a gcc extension
#ifdef __GNUC__
# define AT(index) [index] =
#else
# define MIN_NB_ELMS(N) static (N)
# define ARR_QUALS(...) __VA_ARGS__
# define NONNULL(ptr) ptr[static 1]
# define AT(index)
#endif
// MSVC uses a different name for O_RDWR, and needs an additional _O_BINARY flag
@@ -63,8 +68,10 @@
# define O_RDWR _O_RDWR
# define S_ISREG(field) ((field) & _S_IFREG)
# define O_BINARY _O_BINARY
# define O_TEXT _O_TEXT
#elif !defined(O_BINARY) // Cross-compilers define O_BINARY
# define O_BINARY 0 // POSIX says we shouldn't care!
# define O_TEXT 0 // Assume that it's not defined either
#endif // _MSC_VER
// Windows has stdin and stdout open as text by default, which we may not want
@@ -72,7 +79,7 @@
# include <io.h>
# define setmode(fd, mode) _setmode(fd, mode)
#else
# define setmode(fd, mode) ((void)0)
# define setmode(fd, mode) (0)
#endif
#endif /* RGBDS_PLATFORM_H */
#endif // RGBDS_PLATFORM_H

View File

@@ -1,14 +1,9 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/* SPDX-License-Identifier: MIT */
#ifndef RGBDS_UTIL_H
#define RGBDS_UTIL_H
#include <stddef.h>
#include <stdint.h>
char const *printChar(int c);
@@ -18,4 +13,4 @@ char const *printChar(int c);
*/
size_t readUTF8Char(uint8_t *dest, char const *src);
#endif /* RGBDS_UTIL_H */
#endif // RGBDS_UTIL_H

View File

@@ -1,27 +0,0 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2017-2021, Antonio Nino Diaz and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef EXTERN_VERSION_H
#define EXTERN_VERSION_H
#ifdef __cplusplus
extern "C" {
#endif
#define PACKAGE_VERSION_MAJOR 0
#define PACKAGE_VERSION_MINOR 6
#define PACKAGE_VERSION_PATCH 0
#define PACKAGE_VERSION_RC 1
char const *get_package_version_string(void);
#ifdef __cplusplus
}
#endif
#endif /* EXTERN_VERSION_H */

16
include/version.hpp Normal file
View File

@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: MIT */
#ifndef EXTERN_VERSION_H
#define EXTERN_VERSION_H
extern "C" {
#define PACKAGE_VERSION_MAJOR 0
#define PACKAGE_VERSION_MINOR 7
#define PACKAGE_VERSION_PATCH 0
char const *get_package_version_string(void);
}
#endif // EXTERN_VERSION_H

View File

@@ -1,11 +1,6 @@
.\"
.\" This file is part of RGBDS.
.\"
.\" Copyright (c) 2017-2021, Antonio Nino Diaz and RGBDS contributors.
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
.Dt GBZ80 7
.Os
.Sh NAME
@@ -171,8 +166,8 @@ and
.It Sx JP HL
.It Sx JP n16
.It Sx JP cc,n16
.It Sx JR e8
.It Sx JR cc,e8
.It Sx JR n16
.It Sx JR cc,n16
.It Sx RET cc
.It Sx RET
.It Sx RETI
@@ -633,7 +628,7 @@ Enter CPU low-power consumption mode until an interrupt occurs.
The exact behavior of this instruction depends on the state of the
.Sy IME
flag.
.Bl -tag -width indent
.Bl -tag -width Ds
.It Sy IME No set
The CPU enters low-power mode until
.Em after
@@ -645,7 +640,7 @@ when that returns.
The behavior depends on whether an interrupt is pending (i.e.\&
.Ql [IE] & [IF]
is non-zero).
.Bl -tag -width indent
.Bl -tag -width Ds
.It None pending
As soon as an interrupt becomes pending, the CPU resumes execution.
This is like the above, except that the handler is
@@ -754,22 +749,34 @@ Cycles: 1
Bytes: 1
.Pp
Flags: None affected.
.Ss JR e8
Relative Jump by adding
.Ar e8
to the address of the instruction following the
.Sy JR .
To clarify, an operand of 0 is equivalent to no jumping.
.Ss JR n16
Relative Jump to address
.Ar n16 .
The address is encoded as a signed 8-bit offset from the address immediately following the
.Ic JR
instruction, so the target address
.Ar n16
must be between
.Sy -128
and
.Sy 127
bytes away.
For example:
.Bd -literal -offset indent
JR Label ; no-op; encoded offset of 0
Label:
JR Label ; infinite loop; encoded offset of -2
.Ed
.Pp
Cycles: 3
.Pp
Bytes: 2
.Pp
Flags: None affected.
.Ss JR cc,e8
Relative Jump by adding
.Ar e8
to the current address if condition
.Ss JR cc,n16
Relative Jump to address
.Ar n16
if condition
.Ar cc
is met.
.Pp
@@ -1309,9 +1316,13 @@ Flags: None affected.
.Ss RL r8
Rotate bits in register
.Ar r8
left through carry.
.Pp
.D1 C <- [7 <- 0] <- C
left, through the carry flag.
.Bd -literal
┏━ Flags ━┓ ┏━━━━━━━ r8 ━━━━━━┓
┌─╂─ C ←╂─╂─ b7 ← ... ← b0 ←╂─┐
│ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━┛ │
└─────────────────────────────────┘
.Ed
.Pp
Cycles: 2
.Pp
@@ -1331,9 +1342,13 @@ Set according to result.
.Ss RL [HL]
Rotate the byte pointed to by
.Sy HL
left through carry.
.Pp
.D1 C <- [7 <- 0] <- C
left, through the carry flag.
.Bd -literal
┏━ Flags ━┓ ┏━━━━━━ [HL] ━━━━━┓
┌─╂─ C ←╂─╂─ b7 ← ... ← b0 ←╂─┐
│ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━┛ │
└─────────────────────────────────┘
.Ed
.Pp
Cycles: 4
.Pp
@@ -1344,9 +1359,13 @@ Flags: See
.Ss RLA
Rotate register
.Sy A
left through carry.
.Pp
.D1 C <- [7 <- 0] <- C
left, through the carry flag.
.Bd -literal
┏━ Flags ━┓ ┏━━━━━━━ A ━━━━━━━┓
┌─╂─ C ←╂─╂─ b7 ← ... ← b0 ←╂─┐
│ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━┛ │
└─────────────────────────────────┘
.Ed
.Pp
Cycles: 1
.Pp
@@ -1367,8 +1386,12 @@ Set according to result.
Rotate register
.Ar r8
left.
.Pp
.D1 C <- [7 <- 0] <- [7]
.Bd -literal
┏━ Flags ━┓ ┏━━━━━━━ r8 ━━━━━━┓
┃ C ←╂─┬─╂─ b7 ← ... ← b0 ←╂─┐
┗━━━━━━━━━┛ │ ┗━━━━━━━━━━━━━━━━━┛ │
└─────────────────────┘
.Ed
.Pp
Cycles: 2
.Pp
@@ -1389,8 +1412,12 @@ Set according to result.
Rotate the byte pointed to by
.Sy HL
left.
.Pp
.D1 C <- [7 <- 0] <- [7]
.Bd -literal
┏━ Flags ━┓ ┏━━━━━━ [HL] ━━━━━┓
┃ C ←╂─┬─╂─ b7 ← ... ← b0 ←╂─┐
┗━━━━━━━━━┛ │ ┗━━━━━━━━━━━━━━━━━┛ │
└─────────────────────┘
.Ed
.Pp
Cycles: 4
.Pp
@@ -1402,8 +1429,12 @@ Flags: See
Rotate register
.Sy A
left.
.Pp
.D1 C <- [7 <- 0] <- [7]
.Bd -literal
┏━ Flags ━┓ ┏━━━━━━━ A ━━━━━━━┓
┃ C ←╂─┬─╂─ b7 ← ... ← b0 ←╂─┐
┗━━━━━━━━━┛ │ ┗━━━━━━━━━━━━━━━━━┛ │
└─────────────────────┘
.Ed
.Pp
Cycles: 1
.Pp
@@ -1423,9 +1454,13 @@ Set according to result.
.Ss RR r8
Rotate register
.Ar r8
right through carry.
.Pp
.D1 C -> [7 -> 0] -> C
right, through the carry flag.
.Bd -literal
┏━━━━━━━ r8 ━━━━━━┓ ┏━ Flags ━┓
┌─╂→ b7 → ... → b0 ─╂─╂→ C ─╂─┐
│ ┗━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━┛ │
└─────────────────────────────────┘
.Ed
.Pp
Cycles: 2
.Pp
@@ -1445,9 +1480,13 @@ Set according to result.
.Ss RR [HL]
Rotate the byte pointed to by
.Sy HL
right through carry.
.Pp
.D1 C -> [7 -> 0] -> C
right, through the carry flag.
.Bd -literal
┏━━━━━━ [HL] ━━━━━┓ ┏━ Flags ━┓
┌─╂→ b7 → ... → b0 ─╂─╂→ C ─╂─┐
│ ┗━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━┛ │
└─────────────────────────────────┘
.Ed
.Pp
Cycles: 4
.Pp
@@ -1458,9 +1497,13 @@ Flags: See
.Ss RRA
Rotate register
.Sy A
right through carry.
.Pp
.D1 C -> [7 -> 0] -> C
right, through the carry flag.
.Bd -literal
┏━━━━━━━ A ━━━━━━━┓ ┏━ Flags ━┓
┌─╂→ b7 → ... → b0 ─╂─╂→ C ─╂─┐
│ ┗━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━┛ │
└─────────────────────────────────┘
.Ed
.Pp
Cycles: 1
.Pp
@@ -1481,8 +1524,12 @@ Set according to result.
Rotate register
.Ar r8
right.
.Pp
.D1 [0] -> [7 -> 0] -> C
.Bd -literal
┏━━━━━━━ r8 ━━━━━━┓ ┏━ Flags ━┓
┌─╂→ b7 → ... → b0 ─╂─┬─╂→ C ┃
│ ┗━━━━━━━━━━━━━━━━━┛ │ ┗━━━━━━━━━┛
└─────────────────────┘
.Ed
.Pp
Cycles: 2
.Pp
@@ -1503,8 +1550,12 @@ Set according to result.
Rotate the byte pointed to by
.Sy HL
right.
.Pp
.D1 [0] -> [7 -> 0] -> C
.Bd -literal
┏━━━━━━ [HL] ━━━━━┓ ┏━ Flags ━┓
┌─╂→ b7 → ... → b0 ─╂─┬─╂→ C ┃
│ ┗━━━━━━━━━━━━━━━━━┛ │ ┗━━━━━━━━━┛
└─────────────────────┘
.Ed
.Pp
Cycles: 4
.Pp
@@ -1516,8 +1567,12 @@ Flags: See
Rotate register
.Sy A
right.
.Pp
.D1 [0] -> [7 -> 0] -> C
.Bd -literal
┏━━━━━━━ A ━━━━━━━┓ ┏━ Flags ━┓
┌─╂→ b7 → ... → b0 ─╂─┬─╂→ C ┃
│ ┗━━━━━━━━━━━━━━━━━┛ │ ┗━━━━━━━━━┛
└─────────────────────┘
.Ed
.Pp
Cycles: 1
.Pp
@@ -1641,8 +1696,11 @@ Flags: None affected.
.Ss SLA r8
Shift Left Arithmetically register
.Ar r8 .
.Pp
.D1 C <- [7 <- 0] <- 0
.Bd -literal
┏━ Flags ━┓ ┏━━━━━━━ r8 ━━━━━━┓
┃ C ←╂─╂─ b7 ← ... ← b0 ←╂─ 0
┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━┛
.Ed
.Pp
Cycles: 2
.Pp
@@ -1662,8 +1720,11 @@ Set according to result.
.Ss SLA [HL]
Shift Left Arithmetically the byte pointed to by
.Sy HL .
.Pp
.D1 C <- [7 <- 0] <- 0
.Bd -literal
┏━ Flags ━┓ ┏━━━━━━ [HL] ━━━━━┓
┃ C ←╂─╂─ b7 ← ... ← b0 ←╂─ 0
┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━┛
.Ed
.Pp
Cycles: 4
.Pp
@@ -1673,9 +1734,13 @@ Flags: See
.Sx SLA r8
.Ss SRA r8
Shift Right Arithmetically register
.Ar r8 .
.Pp
.D1 [7] -> [7 -> 0] -> C
.Ar r8
.Pq bit 7 of Ar r8 No is unchanged .
.Bd -literal
┏━━━━━━ r8 ━━━━━━┓ ┏━ Flags ━┓
┃ b7 → ... → b0 ─╂─╂→ C ┃
┗━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━┛
.Ed
.Pp
Cycles: 2
.Pp
@@ -1694,9 +1759,13 @@ Set according to result.
.El
.Ss SRA [HL]
Shift Right Arithmetically the byte pointed to by
.Sy HL .
.Pp
.D1 [7] -> [7 -> 0] -> C
.Sy HL
.Pq bit 7 of the byte pointed to by Sy HL No is unchanged .
.Bd -literal
┏━━━━━ [HL] ━━━━━┓ ┏━ Flags ━┓
┃ b7 → ... → b0 ─╂─╂→ C ┃
┗━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━┛
.Ed
.Pp
Cycles: 4
.Pp
@@ -1707,8 +1776,11 @@ Flags: See
.Ss SRL r8
Shift Right Logically register
.Ar r8 .
.Pp
.D1 0 -> [7 -> 0] -> C
.Bd -literal
┏━━━━━━━ r8 ━━━━━━┓ ┏━ Flags ━┓
0 ─╂→ b7 → ... → b0 ─╂─╂→ C ┃
┗━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━┛
.Ed
.Pp
Cycles: 2
.Pp
@@ -1728,15 +1800,18 @@ Set according to result.
.Ss SRL [HL]
Shift Right Logically the byte pointed to by
.Sy HL .
.Pp
.D1 0 -> [7 -> 0] -> C
.Bd -literal
┏━━━━━━ [HL] ━━━━━┓ ┏━ Flags ━┓
0 ─╂→ b7 → ... → b0 ─╂─╂→ C ┃
┗━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━┛
.Ed
.Pp
Cycles: 4
.Pp
Bytes: 2
.Pp
Flags: See
.Sx SRA r8
.Sx SRL r8
.Ss STOP
Enter CPU very low power mode.
Also used to switch between double and normal speed CPU modes in GBC.
@@ -1872,10 +1947,15 @@ Flags: See
.Sx XOR A,r8
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgblink 1 ,
.Xr rgbfix 1 ,
.Xr rgbgfx 1 ,
.Xr rgbds 7
.Sh HISTORY
.Nm rgbds
was originally written by Carsten S\(/orensen as part of the ASMotor package,
and was later packaged in RGBDS by Justin Lloyd.
.Xr rgbasm 1
was originally written by
.An Carsten S\(/orensen
as part of the ASMotor package, and was later repackaged in RGBDS by
.An Justin Lloyd .
It is now maintained by a number of contributors at
.Lk https://github.com/gbdev/rgbds .

View File

@@ -1,11 +1,6 @@
.\"
.\" This file is part of RGBDS.
.\"
.\" Copyright (c) 2010-2021, Anthony J. Bentley and RGBDS contributors.
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
.Dt RGBASM 1
.Os
.Sh NAME
@@ -13,46 +8,51 @@
.Nd Game Boy assembler
.Sh SYNOPSIS
.Nm
.Op Fl EhLVvw
.Op Fl EHhLlVvw
.Op Fl b Ar chars
.Op Fl D Ar name Ns Op = Ns Ar value
.Op Fl g Ar chars
.Op Fl i Ar path
.Op Fl I Ar path
.Op Fl M Ar depend_file
.Op Fl MG
.Op Fl MP
.Op Fl MT Ar target_file
.Op Fl MQ Ar target_file
.Op Fl o Ar out_file
.Op Fl P Ar include_file
.Op Fl p Ar pad_value
.Op Fl Q Ar fix_precision
.Op Fl r Ar recursion_depth
.Op Fl W Ar warning
.Ar
.Op Fl X Ar max_errors
.Ar asmfile
.Sh DESCRIPTION
The
.Nm
program creates an RGB object file from an assembly source file.
The object file format is documented in
.Xr rgbds 5 .
.Pp
The input
.Ar file
can be a file path, or
.Ar asmfile
can be a path to a file, or
.Cm \-
denoting
.Cm stdin .
to read from standard input.
.Pp
Note that options can be abbreviated as long as the abbreviation is unambiguous:
.Fl Fl verb
.Fl \-verb
is
.Fl Fl verbose ,
.Fl \-verbose ,
but
.Fl Fl ver
.Fl \-ver
is invalid because it could also be
.Fl Fl version .
.Fl \-version .
The arguments are as follows:
.Bl -tag -width Ds
.It Fl b Ar chars , Fl Fl binary-digits Ar chars
.It Fl b Ar chars , Fl \-binary-digits Ar chars
Change the two characters used for binary constants.
The defaults are 01.
.It Fl D Ar name Ns Oo = Ns Ar value Oc , Fl Fl define Ar name Ns Oo = Ns Ar value Oc
.It Fl D Ar name Ns Oo = Ns Ar value Oc , Fl \-define Ar name Ns Oo = Ns Ar value Oc
Add a string symbol to the compiled source code.
This is equivalent to
.Ql Ar name Ic EQUS No \(dq Ns Ar value Ns \(dq
@@ -61,31 +61,44 @@ in code, or
if
.Ar value
is not specified.
.It Fl E , Fl Fl export-all
.It Fl E , Fl \-export-all
Export all labels, including unreferenced and local labels.
.It Fl g Ar chars , Fl Fl gfx-chars Ar chars
.It Fl g Ar chars , Fl \-gfx-chars Ar chars
Change the four characters used for gfx constants.
The defaults are 0123.
.It Fl h , Fl Fl halt-without-nop
By default,
.Nm
inserts a
.It Fl H , Fl \-nop-after-halt
Inserts a
.Ic nop
instruction immediately after any
.Ic halt
instruction.
The
.Fl h
option disables this behavior.
.It Fl i Ar path , Fl Fl include Ar path
Add an include path.
.It Fl L , Fl Fl preserve-ld
Disable the optimization that turns loads of the form
This option is deprecated and will be removed in the next version.
.It Fl h , Fl \-halt-without-nop
This option is redundant and will be removed in the next version.
.It Fl I Ar path , Fl \-include Ar path
Add a new
.Dq include path ;
.Ar path
must point to a directory.
When a
.Ic INCLUDE
.Pq including the implicit one from Fl P
or
.Ic INCBIN
is attempted,
.Nm
first looks up the provided path from its working directory; if this fails, it tries again from each of the
.Dq include path
directories, in the order they were provided.
.It Fl L , Fl \-preserve-ld
This option is redundant and will be removed in the next version.
.It Fl l , Fl \-auto-ldh
Optimize loads of the form
.Ic LD [$FF00+n8],A
into the opcode
.Ic LDH [$FF00+n8],A
in order to have full control of the result in the final ROM.
.It Fl M Ar depend_file , Fl Fl dependfile Ar depend_file
.Ic LDH [$FF00+n8],A .
This option is deprecated and will be removed in the next version.
.It Fl M Ar depend_file , Fl \-dependfile Ar depend_file
Print
.Xr make 1
dependencies to
@@ -97,6 +110,7 @@ This makes
.Nm
assume that missing files are auto-generated: when
.Ic INCLUDE
.Pq including the implicit one from Fl P
or
.Ic INCBIN
is attempted on a non-existent file, it is added as a dependency, then
@@ -125,18 +139,34 @@ but additionally escapes any special
.Xr make 1
characters, essentially
.Sq $ .
.It Fl o Ar out_file , Fl Fl output Ar out_file
.It Fl o Ar out_file , Fl \-output Ar out_file
Write an object file to the given filename.
.It Fl p Ar pad_value , Fl Fl pad-value Ar pad_value
When padding an image, pad with this value.
.It Fl P Ar include_file , Fl \-preinclude Ar include_file
Pre-include a file.
This acts as if a
.Ql Ic INCLUDE Qq Ar include_file
was read before the input
.Ar asmfile .
.It Fl p Ar pad_value , Fl \-pad-value Ar pad_value
Use this as the value for
.Ic DS
directives in ROM sections, unless overridden.
The default is 0x00.
.It Fl r Ar recursion_depth , Fl Fl recursion-depth Ar recursion_depth
Specifies the recursion depth at which RGBASM will assume being in an infinite loop.
.It Fl V , Fl Fl version
.It Fl Q Ar fix_precision , Fl \-q-precision Ar fix_precision
Use this as the precision of fixed-point numbers after the decimal point, unless they specify their own precision.
The default is 16, so fixed-point numbers are Q16.16 (since they are 32-bit integers).
The argument may start with a
.Ql \&.
to match the Q notation, for example,
.Ql Fl Q Ar .16 .
.It Fl r Ar recursion_depth , Fl \-recursion-depth Ar recursion_depth
Specifies the recursion depth past which RGBASM will assume being in an infinite loop.
The default is 64.
.It Fl V , Fl \-version
Print the version of the program and exit.
.It Fl v , Fl Fl verbose
.It Fl v , Fl \-verbose
Be verbose.
.It Fl W Ar warning , Fl Fl warning Ar warning
.It Fl W Ar warning , Fl \-warning Ar warning
Set warning flag
.Ar warning .
A warning message will be printed if
@@ -147,6 +177,13 @@ See the
section for a list of warnings.
.It Fl w
Disable all warning output, even when turned into errors.
.It Fl X Ar max_errors , Fl \-max-errors Ar max_errors
If more than this number of errors (not warnings) occur, then abort the assembly process;
.Fl X 0
disables this behavior.
The default is 100 if
.Nm
is printing errors to a terminal, and 0 otherwise.
.El
.Sh DIAGNOSTICS
Warnings are diagnostic messages that indicate possibly erroneous behavior that does not necessarily compromise the assembling process.
@@ -269,11 +306,24 @@ or
.Fl Wno-truncation
disables this warning.
.Fl Wtruncation=1
warns when an N-bit value's absolute value is 2**N or greater.
warns when an N-bit value is 2**N or greater, or less than -2**N.
.Fl Wtruncation=2
or just
.Fl Wtruncation
also warns when an N-bit value is less than -2**(N-1), which will not fit in two's complement encoding.
.It Fl Wunmapped-char=
Warn when a character goes through charmap conversion but has no defined mapping.
.Fl Wunmapped-char=0
or
.Fl Wunmapped-char
disables this warning.
.Fl Wunmapped-char=1
or just
.Fl Wunmapped-char
only warns if the active charmap is not empty.
.Fl Wunmapped-char=2
warns if the active charmap is empty, and/or is not the default charmap
.Sq main .
.It Fl Wno-user
Warn when the
.Ic WARN
@@ -303,13 +353,17 @@ Please report bugs on
.Lk https://github.com/gbdev/rgbds/issues GitHub .
.Sh SEE ALSO
.Xr rgbasm 5 ,
.Xr rgbfix 1 ,
.Xr rgblink 1 ,
.Xr rgbfix 1 ,
.Xr rgbgfx 1 ,
.Xr gbz80 7 ,
.Xr rgbds 5 ,
.Xr rgbds 7 ,
.Xr gbz80 7
.Xr rgbds 7
.Sh HISTORY
.Nm
was originally written by Carsten S\(/orensen as part of the ASMotor package, and was later packaged in RGBDS by Justin Lloyd.
was originally written by
.An Carsten S\(/orensen
as part of the ASMotor package, and was later repackaged in RGBDS by
.An Justin Lloyd .
It is now maintained by a number of contributors at
.Lk https://github.com/gbdev/rgbds .

View File

@@ -1,12 +1,8 @@
'\" e
.\"
.\" This file is part of RGBDS.
.\"
.\" Copyright (c) 2017-2021, Antonio Nino Diaz and RGBDS contributors.
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
.Dt RGBASM 5
.Os
.Sh NAME
@@ -18,7 +14,7 @@ This is the full description of the language used by
The description of the instructions supported by the Game Boy CPU is in
.Xr gbz80 7 .
.Pp
It is strongly recommended to have some familiarity with the Game Boy hardware before reading this document.
It is advisable to have some familiarity with the Game Boy hardware before reading this document.
RGBDS is specifically targeted at the Game Boy, and thus a lot of its features tie directly to its concepts.
This document is not intended to be a Game Boy hardware reference.
.Pp
@@ -30,54 +26,72 @@ but any program that processes RGBDS object files (described in
.Xr rgbds 5 )
can be used in its place.
.Sh SYNTAX
The syntax is line-based, just as in any other assembler, meaning that you do one instruction or directive per line:
The syntax is line-based, just as in any other assembler.
Each line may have components in this order:
.Pp
.Dl Oo Ar label Oc Oo Ar instruction Oc Oo Ar ;\ comment Oc
.Dl Oo Ar directive Oc Oo ;\ Ns Ar comment Oc
.Dl Oo Ar label : Oc Oo Ar instruction Oo :: Ar instruction ... Oc Oc Oo ;\ Ns Ar comment Oc
.Pp
Example:
.Bd -literal -offset indent
John: ld a,87 ;Weee
.Ed
Directives are commands to the assembler itself, such as
.Ic PRINTLN ,
.Ic SECTION ,
or
.Ic OPT .
.Pp
All reserved keywords (directives, mnemonics, registers, etc.) are case-insensitive;
all identifiers (symbol names) are case-sensitive.
Labels tie a name to a specific location within a section (see
.Sx Labels
below).
They must come first in the line.
.Pp
Instructions are assembled into Game Boy opcodes.
Multiple instructions on one line can be separated by double colons
.Ql :: .
.Pp
All reserved keywords (directives, register names, etc.) are case-insensitive;
all identifiers (labels and other symbol names) are case-sensitive.
.Pp
Comments are used to give humans information about the code, such as explanations.
The assembler
.Em always
ignores comments and their contents.
.Pp
There are two syntaxes for comments.
The most common is that anything that follows a semicolon
There are two kinds of comments, inline and block.
Inline comments are anything that follows a semicolon
.Ql \&;
not inside a string, is a comment until the end of the line.
The second is a block comment, beginning with
not inside a string, until the end of the line.
Block comments, beginning with
.Ql /*
and ending with
.Ql */ .
It can be split across multiple lines, or occur in the middle of an expression:
.Ql */ ,
can be split across multiple lines, or occur in the middle of an expression.
.Pp
An example demonstrating these syntax features:
.Bd -literal -offset indent
X = /* the value of x
should be 3 */ 3
SECTION "My Code", ROM0\ \ ;\ a directive
MyFunction:\ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ a label
push hl\ \ \ \ \ \ \ \ \ \ \ \ \ \ ;\ an instruction
/* ...and multiple instructions,
with mixed case */
ld a, [hli] :: LD H, [HL] :: Ld l, a
pop /*wait for it*/ hl
ret
.Ed
.Pp
Sometimes lines can be too long and it may be necessary to split them.
To do so, put a backslash at the end of the line:
.Bd -literal -offset indent
DB 1, 2, 3,\ \[rs]
4, 5, 6,\ \[rs]\ ;\ Put it before any comments
DB 1, 2, 3,\ \e
4, 5, 6,\ \e\ ;\ Put it before any comments
7, 8, 9
DB "Hello,\ \[rs]\ \ ;\ Space before the \[rs] is included
DB "Hello,\ \e\ \ ;\ Space before the \e is included
world!"\ \ \ \ \ \ \ \ \ \ \ ;\ Any leading space is included
.Ed
.Ss Symbol interpolation
A funky feature is
.Ql {symbol}
within a string, called
A funky feature is writing a symbol between
.Ql {braces} ,
called
.Dq symbol interpolation .
This will paste the contents of
.Ql symbol
as if they were part of the source file.
This will paste the symbol's contents as if they were part of the source file.
If it is a string symbol, its characters are simply inserted as-is.
If it is a numeric symbol, its value is converted to hexadecimal notation with a dollar sign
.Sq $
@@ -85,7 +99,7 @@ prepended.
.Pp
Symbol interpolations can be nested, too!
.Bd -literal -offset indent
DEF topic EQUS "life, the universe, and \[rs]"everything\[rs]""
DEF topic EQUS "life, the universe, and \e"everything\e""
DEF meaning EQUS "answer"
;\ Defines answer = 42
DEF {meaning} = 42
@@ -170,27 +184,27 @@ Valid print types are:
Examples:
.Bd -literal -offset indent
SECTION "Test", ROM0[2]
X: ;\ This works with labels **whose address is known**
Y = 3 ;\ This also works with variables
SUM equ X + Y ;\ And likewise with numeric constants
X: ;\ This works with labels **whose address is known**
DEF Y = 3 ;\ This also works with variables
DEF SUM EQU X + Y ;\ And likewise with numeric constants
; Prints "%0010 + $3 == 5"
PRINTLN "{#05b:X} + {#x:Y} == {d:SUM}"
rsset 32
PERCENT rb 1 ;\ Same with offset constants
VALUE = 20
RESULT = MUL(20.0, 0.32)
DEF PERCENT rb 1 ;\ Same with offset constants
DEF VALUE = 20
DEF RESULT = MUL(20.0, 0.32)
; Prints "32% of 20 = 6.40"
PRINTLN "{d:PERCENT}% of {d:VALUE} = {f:RESULT}"
WHO equs STRLWR("WORLD")
DEF WHO EQUS STRLWR("WORLD")
; Prints "Hello world!"
PRINTLN "Hello {s:WHO}!"
.Ed
.Pp
Although, for these examples,
.Ic STRFMT
would be more approriate; see
would be more appropriate; see
.Sx String expressions
further below.
.Sh EXPRESSIONS
@@ -208,13 +222,14 @@ section.
The instructions in the macro-language generally require constant expressions.
.Ss Numeric formats
There are a number of numeric formats.
.Bl -column -offset indent "Fixed point (Q16.16)" "Prefix"
.Bl -column -offset indent "Precise fixed-point" "Prefix"
.It Sy Format type Ta Sy Prefix Ta Sy Accepted characters
.It Hexadecimal Ta $ Ta 0123456789ABCDEF
.It Decimal Ta none Ta 0123456789
.It Octal Ta & Ta 01234567
.It Binary Ta % Ta 01
.It Fixed point (Q16.16) Ta none Ta 01234.56789
.It Fixed-point Ta none Ta 01234.56789
.It Precise fixed-point Ta none Ta 12.34q8
.It Character constant Ta none Ta \(dqABYZ\(dq
.It Gameboy graphics Ta \` Ta 0123
.El
@@ -301,9 +316,19 @@ and
.Ic \&!
returns 1 if the operand was 0, and 0 otherwise.
.Ss Fixed-point expressions
Fixed-point numbers are basically normal (32-bit) integers, which count 65536ths instead of entire units, offering better precision than integers but limiting the range of values.
The upper 16 bits are used for the integer part and the lower 16 bits are used for the fraction (65536ths).
Since they are still akin to integers, you can use them in normal integer expressions, and some integer operators like
Fixed-point numbers are basically normal (32-bit) integers, which count fractions instead of whole numbers.
They offer better precision than integers but limit the range of values.
By default, the upper 16 bits are used for the integer part and the lower 16 bits are used for the fraction (65536ths).
The default number of fractional bits can be changed with the
.Fl Q
command-line option.
You can also specify a precise fixed-point value by appending a
.Dq q
to it followed by the number of fractional bits, such as
.Ql 12.34q8 .
.Pp
Since fixed-point values are still just integers, you can use them in normal integer expressions.
Some integer operators like
.Sq +
and
.Sq -
@@ -315,10 +340,11 @@ The following functions are designed to operate with fixed-point numbers:
.EQ
delim $$
.EN
.Bl -column -offset indent "ATAN2(x, y)"
.Bl -column -offset indent "ATAN2(y, x)"
.It Sy Name Ta Sy Operation
.It Fn DIV x y Ta $x \[di] y$
.It Fn MUL x y Ta $x \[mu] y$
.It Fn DIV x y Ta Fixed-point division $( x \[di] y ) \[mu] ( 2 ^ precision )$
.It Fn MUL x y Ta Fixed-point multiplication $( x \[mu] y ) \[di] ( 2 ^ precision )$
.It Fn FMOD x y Ta Fixed-point modulo $( x % y ) \[di] ( 2 ^ precision )$
.It Fn POW x y Ta $x$ to the $y$ power
.It Fn LOG x y Ta Logarithm of $x$ to the base $y$
.It Fn ROUND x Ta Round $x$ to the nearest integer
@@ -330,60 +356,78 @@ delim $$
.It Fn ASIN x Ta Inverse sine of $x$
.It Fn ACOS x Ta Inverse cosine of $x$
.It Fn ATAN x Ta Inverse tangent of $x$
.It Fn ATAN2 x y Ta Angle between $( x , y )$ and $( 1 , 0 )$
.It Fn ATAN2 y x Ta Angle between $( x , y )$ and $( 1 , 0 )$
.El
.EQ
delim off
.EN
.Pp
All of these fixed-point functions can take an optional final argument, which is the precision to use.
For example,
.Ql MUL(6.0q8, 7.0q8, 8)
will evaluate to
.Ql 42.0q8
no matter what value is set as the current
.Cm Q
option.
.Pp
The trigonometry functions (
.Ic SIN ,
.Ic COS ,
.Ic TAN ,
etc) are defined in terms of a circle divided into 65535.0 degrees.
etc) are defined in terms of a circle divided into 1.0 "turns" (equal to 2pi radians or 360 degrees).
.Pp
These functions are useful for automatic generation of various tables.
For example:
.Bd -literal -offset indent
; Generate a 256-byte sine table with values in the range [0, 128]
; (shifted and scaled from the range [-1.0, 1.0])
ANGLE = 0.0
REPT 256
db (MUL(64.0, SIN(ANGLE)) + 64.0) >> 16
ANGLE = ANGLE + 256.0 ; 256.0 = 65536 degrees / 256 entries
ENDR
; Generate a table of sine values from sin(0.0) to sin(1.0), with
; amplitude scaled from [-1.0, 1.0] to [0.0, 128.0]
DEF turns = 0.0
REPT 256
db MUL(64.0, SIN(turns) + 1.0) >> 16
DEF turns += 1.0 / 256
ENDR
.Ed
.Ss String expressions
The most basic string expression is any number of characters contained in double quotes
.Pq Ql \&"for instance" .
The backslash character
.Ql \[rs]
.Ql \e
is special in that it causes the character following it to be
.Dq escaped ,
meaning that it is treated differently from normal.
There are a number of escape sequences you can use within a string:
.Bl -column -offset indent "Qo \[rs]1 Qc \[en] Qo \[rs]9 Qc"
.Bl -column -offset indent "Qo \e1 Qc \[en] Qo \e9 Qc"
.It Sy String Ta Sy Meaning
.It Ql \[rs]\[rs] Ta Produces a backslash
.It Ql \[rs]" Ta Produces a double quote without terminating
.It Ql \[rs]{ Ta Curly bracket left
.It Ql \[rs]} Ta Curly bracket right
.It Ql \[rs]n Ta Newline ($0A)
.It Ql \[rs]r Ta Carriage return ($0D)
.It Ql \[rs]t Ta Tab ($09)
.It Qo \[rs]1 Qc \[en] Qo \[rs]9 Qc Ta Macro argument (Only in the body of a macro; see Sx Invoking macros )
.It Ql \[rs]# Ta All Dv _NARG No macro arguments, separated by commas (Only in the body of a macro)
.It Ql \[rs]@ Ta Label name suffix (Only in the body of a macro or a Ic REPT No block)
.It Ql \e\e Ta Produces a backslash
.It Ql \e" Ta Produces a double quote without terminating
.It Ql \e{ Ta Curly bracket left
.It Ql \e} Ta Curly bracket right
.It Ql \en Ta Newline ($0A)
.It Ql \er Ta Carriage return ($0D)
.It Ql \et Ta Tab ($09)
.It Qo \e1 Qc \[en] Qo \e9 Qc Ta Macro argument Pq Only in the body of a macro; see Sx Invoking macros
.It Ql \e# Ta All Dv _NARG No macro arguments, separated by commas Pq Only in the body of a macro
.It Ql \e@ Ta Label name suffix Pq Only in the body of a macro or a Ic REPT No block
.El
(Note that some of those can be used outside of strings, when noted further in this document.)
.Pp
Multi-line strings are contained in triple quotes
.Pq Ql \&"\&"\&"for instance\&"\&"\&" .
Escape sequences work the same way in multi-line strings; however, literal newline
characters will be included as-is, without needing to escape them with
.Ql \[rs]r
Escape sequences work the same way in multi-line strings; however, literal newline characters will be included as-is, without needing to escape them with
.Ql \er
or
.Ql \[rs]n .
.Ql \en .
.Pp
Raw strings are prefixed by a hash
.Sq # .
Inside them, backslashes and braces are treated like regular characters, so they will not be expanded as macro arguments, interpolated symbols, or escape sequences.
For example, the raw string
.Ql #"\et\e1{s}\e"
is equivalent to the regular string
.Ql "\e\et\e\e1\e{s}\e\e" .
(Note that this prevents raw strings from including the double quote character.)
Raw strings also may be contained in triple quotes for them to be multi-line, so they can include literal newline or quote characters (although still not three quotes in a row).
.Pp
The following functions operate on string expressions.
Most of them return a string, however some of these functions actually return an integer and can be used as part of an integer expression!
@@ -395,8 +439,12 @@ Most of them return a string, however some of these functions actually return an
.It Fn STRIN str1 str2 Ta Returns the first position of Ar str2 No in Ar str1 No or zero if it's not present Pq first character is position 1 .
.It Fn STRRIN str1 str2 Ta Returns the last position of Ar str2 No in Ar str1 No or zero if it's not present Pq first character is position 1 .
.It Fn STRSUB str pos len Ta Returns a substring from Ar str No starting at Ar pos No (first character is position 1, last is position -1) and Ar len No characters long. If Ar len No is not specified the substring continues to the end of Ar str .
.It Fn STRUPR str Ta Returns Ar str No with all letters in uppercase.
.It Fn STRLWR str Ta Returns Ar str No with all letters in lowercase.
.It Fn STRUPR str Ta Returns Ar str No with all ASCII letters
.Pq Ql a-z
in uppercase.
.It Fn STRLWR str Ta Returns Ar str No with all ASCII letters
.Pq Ql A-Z
in lowercase.
.It Fn STRRPL str old new Ta Returns Ar str No with each non-overlapping occurrence of the substring Ar old No replaced with Ar new .
.It Fn STRFMT fmt args... Ta Returns the string Ar fmt No with each
.Ql %spec
@@ -406,8 +454,9 @@ pattern replaced by interpolating the format
with its corresponding argument in
.Ar args
.Pq So %% Sc is replaced by the So % Sc character .
.It Fn CHARLEN str Ta Returns the number of charmap entries in Ar str No with the current charmap.
.It Fn CHARSUB str pos Ta Returns the substring for the charmap entry at Ar pos No in Ar str No (first character is position 1, last is position -1) with the current charmap.
.It Fn INCHARMAP str Ta Returns 1 if Ar str No has an entry in the current charmap, and 0 otherwise .
.It Fn CHARLEN str Ta Returns the number of charmap entries in Ar str No with the current charmap .
.It Fn CHARSUB str pos Ta Returns the substring for the charmap entry at Ar pos No in Ar str No (first character is position 1, last is position -1) with the current charmap .
.El
.Ss Character maps
When writing text strings that are meant to be displayed on the Game Boy, the character encoding in the ROM may need to be different than the source file encoding.
@@ -419,6 +468,7 @@ CHARMAP "<LF>", 10
CHARMAP "&iacute", 20
CHARMAP "A", 128
.Ed
.Pp
This would result in
.Ql db \(dqAmen<LF>\(dq
being equivalent to
@@ -434,14 +484,14 @@ and it is automatically selected as the current character map from the beginning
There is also a character map stack that can be used to save and restore which character map is currently active.
.Bl -column "NEWCHARMAP name, basename"
.It Sy Command Ta Sy Meaning
.It Ic NEWCHARMAP Ar name Ta Creates a new, empty character map called Ar name No and switches to it.
.It Ic NEWCHARMAP Ar name , basename Ta Creates a new character map called Ar name , No copied from character map Ar basename , No and switches to it.
.It Ic NEWCHARMAP Ar name Ta Creates a new, empty character map called Ar name No and switches to it .
.It Ic NEWCHARMAP Ar name , basename Ta Creates a new character map called Ar name , No copied from character map Ar basename , No and switches to it .
.It Ic SETCHARMAP Ar name Ta Switch to character map Ar name .
.It Ic PUSHC Ta Push the current character map onto the stack.
.It Ic POPC Ta Pop a character map off the stack and switch to it.
.El
.Pp
.Sy Note:
.Sy Note :
Modifications to a character map take effect immediately from that point onward.
.Ss Other functions
There are a few other functions that do various useful things:
@@ -462,17 +512,32 @@ is a label, it returns the bank number the label is in.
The result may be constant if
.Nm
is able to compute it.
.It Fn SIZEOF arg Ta Returns the size of the section named
.It Fn SECTION symbol Ta Returns the name of the section that
.Ar symbol
is in.
.Ar symbol
must have been defined already.
.It Fn SIZEOF arg Ta If
.Ar arg
is a string, this function returns the size of the section named
.Ar arg .
If
.Ar arg
is a section type keyword, it returns the size of that section type.
The result is not constant, since only RGBLINK can compute its value.
.It Fn STARTOF arg Ta Returns the starting address of the section named
.It Fn STARTOF arg Ta If
.Ar arg
is a string, this function returns the starting address of the section named
.Ar arg .
If
.Ar arg
is a section type keyword, it returns the starting address of that section type.
The result is not constant, since only RGBLINK can compute its value.
.It Fn DEF symbol Ta Returns TRUE (1) if
.Ar symbol
has been defined, FALSE (0) otherwise.
String constants are not expanded within the parentheses.
.It Fn HIGH arg Ta Returns the top 8 bits of the operand if Ar arg No is a label or constant, or the top 8-bit register if it is a 16-bit register.
.It Fn HIGH arg Ta Returns the top 8 bits of the operand if Ar arg No is a label or constant, or the top 8-bit register if it is a 16-bit register .
.It Fn LOW arg Ta Returns the bottom 8 bits of the operand if Ar arg No is a label or constant, or the bottom 8-bit register if it is a 16-bit register Pq Cm AF No isn't a valid register for this function .
.It Fn ISCONST arg Ta Returns 1 if Ar arg Ap s value is known by RGBASM (e.g. if it can be an argument to
.Ic IF ) ,
@@ -617,14 +682,14 @@ Place the section at an address whose
.Ar align
least-significant bits are equal to
.Ar offset .
(Note that
Note that
.Ic ALIGN Ns Bq Ar align
is a shorthand for
.Ic ALIGN Ns Bq Ar align , No 0 ) .
.Ic ALIGN Ns Bq Ar align , No 0 .
This option can be used with
.Bq Ar addr ,
as long as they don't contradict eachother.
It's also possible to request alignment in the middle of a section, see
as long as they don't contradict each other.
It's also possible to request alignment in the middle of a section; see
.Sx Requesting alignment
below.
.El
@@ -679,6 +744,11 @@ SECTION "OAM Data",WRAM0,ALIGN[8] ;\ align to 256 bytes
SECTION "VRAM Data",ROMX,BANK[2],ALIGN[4] ;\ align to 16 bytes
.Ed
.El
.Pp
The current section can be ended without starting a new section by using
.Ic ENDSECTION .
This directive will clear the section context, so you can no longer write code until you start another section.
It can be useful to avoid accidentally defining code or data in the wrong section.
.Ss Section stack
.Ic POPS
and
@@ -750,7 +820,7 @@ The former is situated in ROM, where the code is stored, the latter in RAM, wher
.Pp
You cannot nest
.Ic LOAD
blocks, nor can you change the current section within them.
blocks, nor can you change or stop the current section within them.
.Pp
.Ic LOAD
blocks can use the
@@ -800,7 +870,7 @@ or
.Ic ROMX .
.El
.Pp
Different declarations of the same unionized section are not appended, but instead overlaid on top of eachother, just like
Different declarations of the same unionized section are not appended, but instead overlaid on top of each other, just like
.Sx Unions .
Similarly, the size of an unionized section is the largest of all its declarations.
.Ss Section fragments
@@ -945,9 +1015,9 @@ assuming the section ends up at
.Ad $80C0 :
.Bd -literal -offset indent
SECTION "Player tiles", VRAM
PlayerTiles:
vPlayerTiles:
ds 6 * 16
.end
\&.end
.Ed
.Pp
A label's location (and thus value) is usually not determined until the linking stage, so labels usually cannot be used as constants.
@@ -1001,7 +1071,7 @@ DEF ARRAY_SIZE EQU 4
DEF COUNT = 2
DEF COUNT = 3
DEF COUNT = ARRAY_SIZE + COUNT
COUNT = COUNT*2
DEF COUNT *= 2
;\ COUNT now has the value 14
.Ed
.Pp
@@ -1054,7 +1124,7 @@ This can be used, for example, to update a constant using a macro, without makin
def NUM_ITEMS equ 0
MACRO add_item
redef NUM_ITEMS equ NUM_ITEMS + 1
def ITEM_{02x:NUM_ITEMS} equ \[rs]1
def ITEM_{02x:NUM_ITEMS} equ \e1
ENDM
add_item 1
add_item 4
@@ -1119,7 +1189,7 @@ will not expand string constants in their names.
DEF COUNTREG EQUS "[hl+]"
ld a,COUNTREG
DEF PLAYER_NAME EQUS "\[rs]"John\[rs]""
DEF PLAYER_NAME EQUS "\e"John\e""
db PLAYER_NAME
.Ed
.Pp
@@ -1131,7 +1201,7 @@ This will be interpreted as:
.Pp
String constants can also be used to define small one-line macros:
.Bd -literal -offset indent
DEF pusha EQUS "push af\[rs]npush bc\[rs]npush de\[rs]npush hl\[rs]n"
DEF pusha EQUS "push af\enpush bc\enpush de\enpush hl\en"
.Ed
.Pp
Note that colons
@@ -1149,7 +1219,7 @@ For example:
DEF s EQUS "Hello, "
REDEF s EQUS "{s}world!"
; prints "Hello, world!"
PRINTLN "{s}\n"
PRINTLN "{s}\en"
.Ed
.Pp
.Sy Important note :
@@ -1213,14 +1283,6 @@ The example above defines
.Ql MyMacro
as a new macro.
String constants are not expanded within the name of the macro.
You may use the older syntax
.Ql MyMacro: MACRO
instead of
.Ql MACRO MyMacro ,
with a single colon
.Ql \&:
following the macro's name.
With the older syntax, string constants may be expanded for the name.
.Pp
Macros can't be exported or imported.
.Pp
@@ -1238,18 +1300,18 @@ ENDM
But this will:
.Bd -literal -offset indent
MACRO outer
DEF definition EQUS "MACRO inner\[rs]nPRINTLN \[rs]"Hello!\[rs]"\[rs]nENDM"
DEF definition EQUS "MACRO inner\enPRINTLN \e"Hello!\e"\enENDM"
definition
PURGE definition
ENDM
.Ed
.Pp
Macro arguments support all the escape sequences of strings, as well as
.Ql \[rs],
.Ql \e,
to escape commas, as well as
.Ql \[rs](
.Ql \e(
and
.Ql \[rs])
.Ql \e)
to escape parentheses, since those otherwise separate and enclose arguments, respectively.
.Ss Exporting and importing symbols
Importing and exporting of symbols is a feature that is very useful when your project spans many source files and, for example, you need to jump to a routine defined in another file.
@@ -1266,13 +1328,13 @@ and so on to be accessible to other files during the link process:
For example, if you have the following three files:
.Pp
.Ql a.asm :
.Bd -literal -compact
.Bd -literal -offset indent -compact
SECTION "a", WRAM0
LabelA:
.Ed
.Pp
.Ql b.asm :
.Bd -literal -compact
.Bd -literal -offset indent -compact
SECTION "b", WRAM0
ExportedLabelB1::
ExportedLabelB2:
@@ -1280,7 +1342,7 @@ ExportedLabelB2:
.Ed
.Pp
.Ql c.asm :
.Bd -literal -compact
.Bd -literal -offset indent -compact
SECTION "C", ROM0[0]
dw LabelA
dw ExportedLabelB1
@@ -1296,7 +1358,7 @@ and
but not
.Ql LabelA ,
so linking them together will fail:
.Bd -literal
.Bd -literal -offset indent
$ rgbasm -o a.o a.asm
$ rgbasm -o b.o b.asm
$ rgbasm -o c.o c.asm
@@ -1310,7 +1372,7 @@ Note also that only exported symbols will appear in symbol and map files produce
.Ss Purging symbols
.Ic PURGE
allows you to completely remove a symbol from the symbol table as if it had never existed.
.Em USE WITH EXTREME CAUTION!!!
.Em USE WITH EXTREME CAUTION !
I can't stress this enough,
.Sy you seriously need to know what you are doing .
DON'T purge a symbol that you use in expressions the linker needs to calculate.
@@ -1324,13 +1386,11 @@ DEF AOLer EQUS "Me too"
String constants are not expanded within the symbol names.
.Ss Predeclared symbols
The following symbols are defined by the assembler:
.Bl -column -offset indent "EQUS" "__ISO_8601_LOCAL__"
.Bl -column -offset indent "__ISO_8601_LOCAL__" "EQUS"
.It Sy Name Ta Sy Type Ta Sy Contents
.It Dv @ Ta Ic EQU Ta PC value (essentially, the current memory address)
.It Dv _RS Ta Ic = Ta _RS Counter
.It Dv _NARG Ta Ic EQU Ta Number of arguments passed to macro, updated by Ic SHIFT
.It Dv __LINE__ Ta Ic EQU Ta The current line number
.It Dv __FILE__ Ta Ic EQUS Ta The current filename
.It Dv __DATE__ Ta Ic EQUS Ta Today's date
.It Dv __TIME__ Ta Ic EQUS Ta The current time
.It Dv __ISO_8601_LOCAL__ Ta Ic EQUS Ta ISO 8601 timestamp (local)
@@ -1374,6 +1434,27 @@ In ROM sections, it will be filled with the value passed to the
.Fl p
command-line option, except when using overlays with
.Fl O .
.Pp
Instead of an exact number of bytes, you can specify
.Ic ALIGN Ns Bq Ar align , offset
to allocate however many bytes are required to align the subsequent data.
Thus,
.Sq Ic DS ALIGN Ns Bo Ar align , offset Bc , No ...
is equivalent to
.Sq Ic DS Ar n , No ...
followed by
.Sq Ic ALIGN Ns Bq Ar align , offset ,
where
.Ar n
is the minimum value needed to satisfy the
.Ic ALIGN
constraint (see
.Sx Requesting alignment
below).
Note that
.Ic ALIGN Ns Bq Ar align
is a shorthand for
.Ic ALIGN Ns Bq Ar align , No 0 .
.Ss Defining constant data in ROM
.Ic DB
defines a list of bytes that will be stored in the final image.
@@ -1547,19 +1628,19 @@ ENDM
.Pp
This is fine, but only if you use the macro no more than once per scope.
To get around this problem, there is the escape sequence
.Ic \[rs]@
.Ic \e@
that expands to a unique string.
.Pp
.Ic \[rs]@
.Ic \e@
also works in
.Ic REPT
blocks.
.Bd -literal -offset indent
MACRO LoopyMacro
xor a,a
\&.loop\[rs]@ ld [hl+],a
\&.loop\e@ ld [hl+],a
dec c
jr nz,.loop\[rs]@
jr nz,.loop\e@
ENDM
.Ed
.Pp
@@ -1579,18 +1660,18 @@ which references the same macro, which has the same problem.
.Pp
It's possible to pass arguments to macros as well!
You retrieve the arguments by using the escape sequences
.Ic \[rs]1
.Ic \e1
through
.Ic \[rs]9 , \[rs]1
.Ic \e9 , \e1
being the first argument specified on the macro invocation.
.Bd -literal -offset indent
MACRO LoopyMacro
ld hl,\[rs]1
ld c,\[rs]2
ld hl,\e1
ld c,\e2
xor a,a
\&.loop\[rs]@ ld [hl+],a
\&.loop\e@ ld [hl+],a
dec c
jr nz,.loop\[rs]@
jr nz,.loop\e@
ENDM
.Ed
.Pp
@@ -1603,14 +1684,14 @@ LoopyMacro MyVars,54
Arguments are passed as string constants, although there's no need to enclose them in quotes.
Thus, an expression will not be evaluated first but kind of copy-pasted.
This means that it's probably a very good idea to use brackets around
.Ic \[rs]1
.Ic \e1
to
.Ic \[rs]9
.Ic \e9
if you perform further calculations on them.
For instance, consider the following:
.Bd -literal -offset indent
MACRO print_double
PRINTLN \[rs]1 * 2
PRINTLN \e1 * 2
ENDM
print_double 1 + 2
.Ed
@@ -1625,15 +1706,15 @@ Line continuations work as usual inside macros or lists of macro arguments.
However, some characters need to be escaped, as in the following example:
.Bd -literal -offset indent
MACRO PrintMacro1
PRINTLN STRCAT(\[rs]1)
PRINTLN STRCAT(\e1)
ENDM
PrintMacro1 "Hello "\[rs], \[rs]
PrintMacro1 "Hello "\e, \e
"world"
MACRO PrintMacro2
PRINT \[rs]1
PRINT \e1
ENDM
PrintMacro2 STRCAT("Hello ", \[rs]
"world\[rs]n")
PrintMacro2 STRCAT("Hello ", \e
"world\en")
.Ed
.Pp
The comma in
@@ -1643,34 +1724,34 @@ The comma in
.Ql PrintMacro2
does not need escaping because it is inside parentheses, similar to macro arguments in C.
The backslash in
.Ql \[rs]n
.Ql \en
also does not need escaping because string literals work as usual inside macro arguments.
.Pp
Since there are only nine digits, you can only access the first nine macro arguments like this.
To use the rest, you need to put the multi-digit argument number in angle brackets, like
.Ql \[rs]<10> .
.Ql \e<10> .
This bracketed syntax supports decimal numbers and numeric constant symbols.
For example,
.Ql \[rs]<_NARG>
.Ql \e<_NARG>
will get the last argument.
.Pp
Other macro arguments and symbol interpolations will be expanded inside the angle brackets.
For example, if
.Ql \[rs]1
.Ql \e1
is
.Ql 13 ,
then
.Ql \[rs]<\[rs]1>
.Ql \e<\e1>
will expand to
.Ql \[rs]<13> .
.Ql \e<13> .
Or if
.Ql v10 = 42
and
.Ql x = 10 ,
then
.Ql \[rs]<v{d:x}>
.Ql \e<v{d:x}>
will expand to
.Ql \[rs]<42> .
.Ql \e<42> .
.Pp
Another way to access more than nine macro arguments is the
.Ic SHIFT
@@ -1678,11 +1759,11 @@ command, a special command only available in macros.
It will shift the arguments by one to the left, and decrease
.Dv _NARG
by 1.
.Ic \[rs]1
.Ic \e1
will get the value of
.Ic \[rs]2 , \[rs]2
.Ic \e2 , \e2
will get the value of
.Ic \[rs]3 ,
.Ic \e3 ,
and so forth.
.Pp
.Ic SHIFT
@@ -1701,9 +1782,9 @@ and
commands print text and values to the standard output.
Useful for debugging macros, or wherever you may feel the need to tell yourself some important information.
.Bd -literal -offset indent
PRINT "Hello world!\[rs]n"
PRINT "Hello world!\en"
PRINTLN "Hello world!"
PRINT _NARG, " arguments\[rs]n"
PRINT _NARG, " arguments\en"
PRINTLN "sum: ", 2+3, " product: ", 2*3
PRINTLN "Line #", __LINE__
PRINTLN STRFMT("E = %f", 2.718)
@@ -1717,7 +1798,7 @@ For different formats, use
.Ic STRFMT .
.It Ic PRINTLN
prints out each of its comma-separated arguments, if any, followed by a line feed
.Pq Ql \[rs]n .
.Pq Ql \en .
.El
.Ss Automatically repeating blocks of code
Suppose you want to unroll a time consuming loop without copy-pasting it.
@@ -1741,17 +1822,16 @@ You can also use
.Ic REPT
to generate tables on the fly:
.Bd -literal -offset indent
; Generate a 256-byte sine table with values in the range [0, 128]
; (shifted and scaled from the range [-1.0, 1.0])
ANGLE = 0.0
REPT 256
db (MUL(64.0, SIN(ANGLE)) + 64.0) >> 16
ANGLE = ANGLE + 256.0 ; 256.0 = 65536 degrees / 256 entries
ENDR
; Generate a table of square values from 0**2 = 0 to 100**2 = 10000
DEF x = 0
REPT 101
dw x * x
DEF x += 1
ENDR
.Ed
.Pp
As in macros, you can also use the escape sequence
.Ic \[rs]@ .
.Ic \e@ .
.Ic REPT
blocks can be nested.
.Pp
@@ -1804,11 +1884,29 @@ The
value will be updated by
.Ar step
until it reaches or exceeds
.Ar stop .
.Ar stop ,
i.e. it covers the half-open range from
.Ar start
(inclusive) to
.Ar stop
(exclusive).
The variable
.Ar V
will be assigned this value at the beginning of each new iteration; any changes made to it within the
.Ic FOR
loop's body will be overwritten.
So the symbol
.Ar V
need not be already defined before any iterations of the
.Ic FOR
loop, but it must be a variable
.Pq Sx Variables
if so.
For example:
.Bd -literal -offset indent
FOR V, 4, 25, 5
PRINT "{d:V} "
DEF V *= 2
ENDR
PRINTLN "done {d:V}"
.Ed
@@ -1821,7 +1919,7 @@ This will print:
Just like with
.Ic REPT
blocks, you can use the escape sequence
.Ic \[rs]@
.Ic \e@
inside of
.Ic FOR
blocks, and they can be nested.
@@ -1942,6 +2040,13 @@ calls infinitely (or until you run out of memory, whichever comes first).
.Bd -literal -offset indent
INCLUDE "irq.inc"
.Ed
.Pp
You may also implicitly
.Ic INCLUDE
a file before the source file with the
.Fl P
option of
.Xr rgbasm 1 .
.Ss Conditional assembling
The four commands
.Ic IF , ELIF , ELSE ,
@@ -2013,17 +2118,15 @@ POPO
The options that
.Ic OPT
can modify are currently:
.Cm b , g , p , r , h , L ,
.Cm b , g , p , Q , r , h , L ,
and
.Cm W .
The Boolean flag options
.Cm h
.Cm H , h , L ,
and
.Cm L
can be negated as
.Ql OPT !h
and
.Ql OPT !L
.Cm l
can be negated like
.Ql OPT !H
to act like omitting them from the command-line.
.Pp
.Ic POPO
@@ -2056,16 +2159,31 @@ Note that
.Ic ALIGN Ar align
is a shorthand for
.Ic ALIGN Ar align , No 0 .
.Pp
There may be times when you don't just want to specify an alignment constraint at the current location, but also skip ahead until the constraint can be satisfied.
In that case, you can use
.Ic DS ALIGN Ns Bq Ar align , offset
to allocate however many bytes are required to align the subsequent data.
.Pp
If the constraint cannot be met by skipping any amount of space, an error is produced.
Note that
.Ic ALIGN Ns Bq Ar align
is a shorthand for
.Ic ALIGN Ns Bq Ar align , No 0 .
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgblink 1 ,
.Xr rgblink 5 ,
.Xr rgbfix 1 ,
.Xr rgbgfx 1 ,
.Xr gbz80 7 ,
.Xr rgbds 5 ,
.Xr rgbds 7 ,
.Xr gbz80 7
.Xr rgbds 7
.Sh HISTORY
.Nm
was originally written by Carsten S\(/orensen as part of the ASMotor package,
and was later packaged in RGBDS by Justin Lloyd.
.Xr rgbasm 1
was originally written by
.An Carsten S\(/orensen
as part of the ASMotor package, and was later repackaged in RGBDS by
.An Justin Lloyd .
It is now maintained by a number of contributors at
.Lk https://github.com/gbdev/rgbds .

View File

@@ -1,11 +1,6 @@
.\"
.\" This file is part of RGBDS.
.\"
.\" Copyright (c) 2017-2021, Antonio Nino Diaz and RGBDS contributors.
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
.Dt RGBDS 5
.Os
.Sh NAME
@@ -16,260 +11,406 @@ This is the description of the object files used by
.Xr rgbasm 1
and
.Xr rgblink 1 .
.Em Please note that the specifications may change .
This toolchain is in development and new features may require adding more information to the current format, or modifying some fields, which would break compatibility with older versions.
.Em Please note that the specification is not stable yet.
RGBDS is still in active development, and some new features require adding more information to the object file, or modifying some fields, both of which break compatibility with older versions.
.Sh FILE STRUCTURE
The following types are used:
.Pp
.Ar LONG
.Cm LONG
is a 32-bit integer stored in little-endian format.
.Ar BYTE
.Cm BYTE
is an 8-bit integer.
.Ar STRING
.Cm STRING
is a 0-terminated string of
.Ar BYTE .
.Bd -literal
; Header
BYTE ID[4] ; "RGB9"
LONG RevisionNumber ; The format's revision number this file uses.
LONG NumberOfSymbols ; The number of symbols used in this file.
LONG NumberOfSections ; The number of sections used in this file.
; File info
LONG NumberOfNodes ; The number of nodes contained in this file.
REPT NumberOfNodes ; IMPORTANT NOTE: the nodes are actually written in
; **reverse** order, meaning the node with ID 0 is
; the last one in the file!
LONG ParentID ; ID of the parent node, -1 means this is the root.
LONG ParentLineNo ; Line at which the parent context was exited.
; Meaningless on the root node.
BYTE Type ; 0 = REPT node
; 1 = File node
; 2 = Macro node
IF Type != 0 ; If the node is not a REPT...
STRING Name ; The node's name: either a file name, or macro name
; prefixed by its definition file name.
ELSE ; If the node is a REPT, it also contains the iter
; counts of all the parent REPTs.
LONG Depth ; Size of the array below.
LONG Iter[Depth] ; The number of REPT iterations by increasing depth.
ENDC
ENDR
; Symbols
REPT NumberOfSymbols ; Number of symbols defined in this object file.
STRING Name ; The name of this symbol. Local symbols are stored
; as "Scope.Symbol".
BYTE Type ; 0 = LOCAL symbol only used in this file.
; 1 = IMPORT this symbol from elsewhere
; 2 = EXPORT this symbol to other objects.
IF (Type & 0x7F) != 1 ; If symbol is defined in this object file.
LONG SourceFile ; File where the symbol is defined.
LONG LineNum ; Line number in the file where the symbol is defined.
LONG SectionID ; The section number (of this object file) in which
; this symbol is defined. If it doesn't belong to any
; specific section (like a constant), this field has
; the value -1.
LONG Value ; The symbols value. It's the offset into that
; symbol's section.
ENDC
ENDR
; Sections
REPT NumberOfSections
STRING Name ; Name of the section
LONG Size ; Size in bytes of this section
BYTE Type ; 0 = WRAM0
; 1 = VRAM
; 2 = ROMX
; 3 = ROM0
; 4 = HRAM
; 5 = WRAMX
; 6 = SRAM
; 7 = OAM
; Bits 7 and 6 are independent from the above value:
; Bit 7 encodes whether the section is unionized
; Bit 6 encodes whether the section is a fragment
; Bits 6 and 7 may not be both set at the same time!
LONG Org ; Address to fix this section at. -1 if the linker should
; decide (floating address).
LONG Bank ; Bank to load this section into. -1 if the linker should
; decide (floating bank). This field is only valid for ROMX,
; VRAM, WRAMX and SRAM sections.
BYTE Align ; Alignment of this section, as N bits. 0 when not specified.
LONG Ofs ; Offset relative to the alignment specified above.
; Must be below 1 << Align.
IF (Type == ROMX) || (Type == ROM0) ; Sections that can contain data.
BYTE Data[Size] ; Raw data of the section.
LONG NumberOfPatches ; Number of patches to apply.
REPT NumberOfPatches
LONG SourceFile ; ID of the source file node (for printing
; error messages).
LONG LineNo ; Line at which the patch was created.
LONG Offset ; Offset into the section where patch should
; be applied (in bytes).
LONG PCSectionID ; Index within the file of the section in which
; PC is located.
; This is usually the same section that the
; patch should be applied into, except e.g.
; with LOAD blocks.
LONG PCOffset ; PC's offset into the above section.
; Used because the section may be floating, so
; PC's value is not known to RGBASM.
BYTE Type ; 0 = BYTE patch.
; 1 = little endian WORD patch.
; 2 = little endian LONG patch.
; 3 = JR offset value BYTE patch.
LONG RPNSize ; Size of the buffer with the RPN.
; expression.
BYTE RPN[RPNSize] ; RPN expression. Definition below.
ENDR
ENDC
ENDR
; Assertions
LONG NumberOfAssertions
REPT NumberOfAssertions
LONG SourceFile ; ID of the source file node (for printing the failure).
LONG LineNo ; Line at which the assertion was created.
LONG Offset ; Offset into the section where the assertion is located.
LONG SectionID ; Index within the file of the section in which PC is
; located, or -1 if defined outside a section.
LONG PCOffset ; PC's offset into the above section.
; Used because the section may be floating, so PC's value
; is not known to RGBASM.
BYTE Type ; 0 = Prints the message but allows linking to continue
; 1 = Prints the message and evaluates other assertions,
; but linking fails afterwards
; 2 = Prints the message and immediately fails linking
LONG RPNSize ; Size of the RPN expression's buffer.
BYTE RPN[RPNSize] ; RPN expression, same as patches. Assert fails if == 0.
STRING Message ; A message displayed when the assert fails. If set to
; the empty string, a generic message is printed instead.
ENDR
.Ed
.Ss RPN DATA
Expressions in the object file are stored as RPN.
This is an expression of the form
.Dq 2 5 + .
This will first push the value
.Do 2 Dc to the stack, then
.Cm BYTE .
Brackets after a type
.Pq e.g. Cm LONG Ns Bq Ar n
indicate
.Ar n
consecutive elements
.Pq here, Cm LONG Ns s .
All items are contiguous, with no padding anywhere\(emthis also means that they may not be aligned in the file!
.Pp
.Cm REPT Ar n
indicates that the fields between the
.Cm REPT
and corresponding
.Cm ENDR
are repeated
.Ar n
times.
.Pp
All IDs refer to objects within the file; for example, symbol ID $0001 refers to the second symbol defined in
.Em this
object file's
.Sx Symbols
array.
The only exception is the
.Sx Source file info
nodes, whose IDs are backwards, i.e. source node ID $0000 refers to the
.Em last
node in the array, not the first one.
References to other object files are made by imports (symbols), by name (sections), etc.\(embut never by ID.
.Ss Header
.Bl -tag -width Ds -compact
.It Cm BYTE Ar Magic[4]
"RGB9"
.It Cm LONG Ar RevisionNumber
The format's revision number this file uses.
.Pq This is always in the same place in all revisions.
.It Cm LONG Ar NumberOfSymbols
How many symbols are defined in this object file.
.It Cm LONG Ar NumberOfSections
How many sections are defined in this object file.
.El
.Ss Source file info
.Bl -tag -width Ds -compact
.It Cm LONG Ar NumberOfNodes
The number of source context nodes contained in this file.
.It Cm REPT Ar NumberOfNodes
.Bl -tag -width Ds -compact
.It Cm LONG Ar ParentID
ID of the parent node, -1 meaning that this is the root node.
.Pp
.Sy Important :
the nodes are actually written in
.Sy reverse
order, meaning the node with ID 0 is the last one in the list!
.It Cm LONG Ar ParentLineNo
Line at which the parent node's context was exited; meaningless for the root node.
.It Cm BYTE Ar Type
.Bl -column "Value" -compact
.It Sy Value Ta Sy Meaning
.It 0 Ta REPT node
.It 1 Ta File node
.It 2 Ta Macro node
.El
.It Cm IF Ar Type No \(!= 0
If the node is not a REPT node...
.Pp
.Bl -tag -width Ds -compact
.It Cm STRING Ar Name
The node's name: either a file name, or the macro's name prefixes by its definition's file name
.Pq e.g. Ql src/includes/defines.asm::error .
.El
.It Cm ELSE
If the node is a REPT, it also contains the iteration counter of all parent REPTs.
.Pp
.Bl -tag -width Ds -compact
.It Cm LONG Ar Depth
.It Cm LONG Ar Iter Ns Bq Ar Depth
The number of REPT iterations, by increasing depth.
.El
.It Cm ENDC
.El
.It Cm ENDR
.El
.Ss Symbols
.Bl -tag -width Ds -compact
.It Cm REPT Ar NumberOfSymbols
.Bl -tag -width Ds -compact
.It Cm STRING Ar Name
This symbol's name.
Local symbols are stored as their full name
.Pq Ql Scope.symbol .
.It Cm BYTE Ar Type
.Bl -column "Value" -compact
.It Sy Value Ta Sy Meaning
.It 0 Ta Sy Local No symbol only used in this file .
.It 1 Ta Sy Import No of an exported symbol (by name) from another object file .
.It 2 Ta Sy Exported No symbol visible from other object files .
.El
.It Cm IF Ar Type No \(!= 1
If the symbol is defined in this object file...
.Pp
.Bl -tag -width Ds -compact
.It Cm LONG Ar NodeID
Context in which the symbol was defined.
.It Cm LONG Ar LineNo
Line number in the context at which the symbol was defined.
.It Cm LONG Ar SectionID
The ID of the section in which the symbol is defined.
If the symbol doesn't belong to any specific section (i.e. it's a constant), this field contains -1.
.It Cm LONG Ar Value
The symbol's value.
If the symbol belongs to a section, this is the offset within that symbol's section.
.El
.It Cm ENDC
.El
.It Cm ENDR
.El
.Ss Sections
.Bl -tag -width Ds -compact
.It Cm REPT Ar NumberOfSections
.Bl -tag -width Ds -compact
.It Cm STRING Ar Name
The section's name.
.It Cm LONG Ar Size
The section's size, in bytes.
.It Cm BYTE Ar Type
Bits 0\(en2 indicate the section's type:
.Bl -column "Value" -compact
.It Sy Value Ta Sy Meaning
.It 0 Ta WRAM0
.It 1 Ta VRAM
.It 2 Ta ROMX
.It 3 Ta ROM0
.It 4 Ta HRAM
.It 5 Ta WRAMX
.It 6 Ta SRAM
.It 7 Ta OAM
.El
.Pp
Bit\ 7 being set means that the section is a "union"
.Pq see Do Unionized sections Dc in Xr rgbasm 5 .
Bit\ 6 being set means that the section is a "fragment"
.Pq see Do Section fragments Dc in Xr rgbasm 5 .
These two bits are mutually exclusive.
.It Cm LONG Ar Address
Address this section must be placed at.
This must either be valid for the section's
.Ar Type
(as affected by flags like
.Fl t
or
.Fl d
in
.Xr rgblink 1 ) ,
or -1 to indicate that the linker should automatically decide
.Pq the section is Dq floating .
.It Cm LONG Ar Bank
ID of the bank this section must be placed in.
This must either be valid for the section's
.Ar Type
(with the same caveats as for the
.Ar Address ) ,
or -1 to indicate that the linker should automatically decide.
.It Cm BYTE Ar Alignment
How many bits of the section's address should be equal to
.Ar AlignOfs ,
starting from the least-significant bit.
.It Cm LONG Ar AlignOfs
Alignment offset.
Must be strictly less than
.Ql 1 << Ar Alignment .
.It Cm IF Ar Type No \(eq 2 || Ar Type No \(eq 3
If the section has ROM type, it contains data.
.Pp
.Bl -tag -width Ds -compact
.It Cm BYTE Ar Data Ns Bq Size
The section's raw data.
Bytes that will be patched over must be present, even though their contents will be overwritten.
.It Cm LONG Ar NumberOfPatches
How many patches must be applied to this section's
.Ar Data .
.It Cm REPT Ar NumberOfPatches
.Bl -tag -width Ds -compact
.It Cm LONG Ar NodeID
Context in which the patch was defined.
.It Cm LONG Ar LineNo
Line number in the context at which the patch was defined.
.It Cm LONG Ar Offset
Offset within the section's
.Ar Data
at which the patch should be applied.
Must not be greater than the section's
.Ar Size
minus the patch's size
.Pq see Ar Type No below .
.It Cm LONG Ar PCSectionID
ID of the section in which PC is located.
(This is usually the same section within which the patch is applied, except for e.g.\&
.Ql LOAD
blocks, see
.Do RAM code Dc in Xr rgbasm 5 . )
.It Cm LONG Ar PCOffset
Offset of the PC symbol within the section designated by
.Ar PCSectionID .
It is expected that PC points to the instruction's first byte for instruction operands (i.e.\&
.Ql jp @
must be an infinite loop), and to the patch's first byte otherwise
.Ql ( db ,
.Ql dw ,
.Ql dl ) .
.It Cm BYTE Ar Type
.Bl -column "Value" -compact
.It Sy Value Ta Sy Meaning
.It 0 Ta Single-byte patch
.It 1 Ta Little-endian two-byte patch
.It 2 Ta Little-endian four-byte patch
.It 3 Ta Single-byte Ql jr
patch; the patch's value will be subtracted to PC + 2 (i.e.\&
.Ql jr @
must be the infinite loop
.Ql 18 FE ) .
.El
.It Cm LONG Ar RPNSize
Size of the
.Ar RPNExpr
below.
.It Cm BYTE Ar RPNExpr Ns Bq RPNSize
The patch's value, encoded as a RPN expression
.Pq see Sx RPN EXPRESSIONS .
.El
.It Cm ENDR
.El
.It Cm ENDC
.El
.El
.Ss Assertions
.Bl -tag -width Ds -compact
.It Cm LONG Ar NumberOfAssertions
How many assertions this object file contains.
.It Cm REPT Ar NumberOfAssertions
Assertions are essentially patches with a message.
.Pp
.Bl -tag -width Ds -compact
.It Cm LONG Ar NodeID
Context in which the assertions was defined.
.It Cm LONG Ar LineNo
Line number in the context at which the assertion was defined.
.It Cm LONG Ar Offset
Unused leftover from the patch structure.
.It Cm LONG Ar PCSectionID
ID of the section in which PC is located.
.It Cm LONG Ar PCOffset
Offset of the PC symbol within the section designated by
.Ar PCSectionID .
.It Cm BYTE Ar Type
Describes what should happen if the expression evaluates to a non-zero value.
.Bl -column "Value" -compact
.It Sy Value Ta Sy Meaning
.It 0 Ta Print a warning message, and continue linking normally.
.It 1 Ta Print an error message, so linking will fail, but allow other assertions to be evaluated.
.It 2 Ta Print a fatal error message, and abort immediately.
.El
.It Cm LONG Ar RPNSize
Size of the
.Ar RPNExpr
below.
.It Cm BYTE Ar RPNExpr Ns Bq RPNSize
The patch's value, encoded as a RPN expression
.Pq see Sx RPN EXPRESSIONS .
.It Cm STRING Ar Message
The message displayed if the expression evaluates to a non-zero value.
If empty, a generic message is displayed instead.
.El
.It Cm ENDR
.El
.Ss RPN EXPRESSIONS
Expressions in the object file are stored as RPN, or
.Dq Reverse Polish Notation ,
which is a notation that allows computing arbitrary expressions with just a simple stack.
For example, the expression
.Ql 2 5 -
will first push the value
.Dq 2
to the stack, then
.Dq 5 .
The
.Do + Dc operator pops two arguments from the stack, adds them, and then pushes the result on the stack, effectively replacing the two top arguments with their sum.
In the RGB format, RPN expressions are stored as
.Ar BYTE Ns s
with some bytes being special prefixes for integers and symbols.
.Bl -column -offset indent "Sy String" "Sy String"
.Ql -
operator pops two arguments from the stack, subtracts them, and then pushes back the result
.Pq Dq 3
on the stack.
A well-formed RPN expression never tries to pop from an empty stack, and leaves exactly one value in it at the end.
.Pp
RGBDS encodes RPN expressions as an array of
.Cm BYTE Ns s .
The first byte encodes either an operator, or a literal, which consumes more
.Cm BYTE Ns s
after it:
.Bl -column "Value"
.It Sy Value Ta Sy Meaning
.It Li $00 Ta Li + operator
.It Li $01 Ta Li - operator
.It Li $02 Ta Li * operator
.It Li $03 Ta Li / operator
.It Li $04 Ta Li % operator
.It Li $05 Ta Li unary -
.It Li $06 Ta Li ** operator
.It Li $10 Ta Li \&| operator
.It Li $11 Ta Li & operator
.It Li $12 Ta Li ^ operator
.It Li $13 Ta Li unary ~
.It Li $21 Ta Li && comparison
.It Li $22 Ta Li || comparison
.It Li $23 Ta Li unary \&!
.It Li $30 Ta Li == comparison
.It Li $31 Ta Li != comparison
.It Li $32 Ta Li > comparison
.It Li $33 Ta Li < comparison
.It Li $34 Ta Li >= comparison
.It Li $35 Ta Li <= comparison
.It Li $40 Ta Li << operator
.It Li $41 Ta Li >> operator
.It Li $42 Ta Li >>> operator
.It Li $50 Ta Li BANK(symbol) ,
a
.Ar LONG
Symbol ID follows, where -1 means PC
.It Li $51 Ta Li BANK(section_name) ,
a null-terminated string follows.
.It Li $52 Ta Li Current BANK()
.It Li $53 Ta Li SIZEOF(section_name) ,
a null-terminated string follows.
.It Li $54 Ta Li STARTOF(section_name) ,
a null-terminated string follows.
.It Li $60 Ta Li HRAMCheck .
Checks if the value is in HRAM, ANDs it with 0xFF.
.It Li $61 Ta Li RSTCheck .
Checks if the value is a RST vector, ORs it with 0xC7.
.It Li $80 Ta Ar LONG
integer follows.
.It Li $81 Ta Ar LONG
symbol ID follows.
.It Li $00 Ta Addition operator Pq Ql +
.It Li $01 Ta Subtraction operator Pq Ql -
.It Li $02 Ta Multiplication operator Pq Ql *
.It Li $03 Ta Division operator Pq Ql /
.It Li $04 Ta Modulo operator Pq Ql %
.It Li $05 Ta Negation Pq unary Ql -
.It Li $06 Ta Exponent operator Pq Ql **
.It Li $10 Ta Bitwise OR operator Pq Ql \&|
.It Li $11 Ta Bitwise AND operator Pq Ql &
.It Li $12 Ta Bitwise XOR operator Pq Ql ^
.It Li $13 Ta Bitwise complement operator Pq unary Ql ~
.It Li $21 Ta Logical AND operator Pq Ql &&
.It Li $22 Ta Logical OR operator Pq Ql ||
.It Li $23 Ta Logical complement operator Pq unary Ql \&!
.It Li $30 Ta Equality operator Pq Ql ==
.It Li $31 Ta Non-equality operator Pq Ql !=
.It Li $32 Ta Greater-than operator Pq Ql >
.It Li $33 Ta Less-than operator Pq Ql <
.It Li $34 Ta Greater-than-or-equal operator Pq Ql >=
.It Li $35 Ta Less-than-or-equal operator Pq Ql <=
.It Li $40 Ta Left shift operator Pq Ql <<
.It Li $41 Ta Arithmetic/signed right shift operator Pq Ql >>
.It Li $42 Ta Logical/unsigned right shift operator Pq Ql >>>
.It Li $50 Ta Fn BANK symbol ;
followed by the
.Ar symbol Ap s Cm LONG
ID.
.It Li $51 Ta Fn BANK section ;
followed by the
.Ar section Ap s Cm STRING
name.
.It Li $52 Ta PC's Fn BANK Pq i.e. Ql BANK(@) .
.It Li $53 Ta Fn SIZEOF section ;
followed by the
.Ar section Ap s Cm STRING
name.
.It Li $54 Ta Fn STARTOF section ;
followed by the
.Ar section Ap s Cm STRING
name.
.It Li $55 Ta Fn SIZEOF sectiontype ;
followed by the
.Ar sectiontype Ap s Cm BYTE
value
.Pq see the Ar Type No values in Sx Sections .
.It Li $56 Ta Fn STARTOF sectiontype ;
followed by the
.Ar sectiontype Ap s Cm BYTE
value
.Pq see the Ar Type No values in Sx Sections .
.It Li $60 Ta Ql ldh
check.
Checks if the value is a valid
.Ql ldh
operand
.Pq see Do Load Instructions Dc in Xr gbz80 7 ,
i.e. that it is between either $00 and $FF, or $FF00 and $FFFF, both inclusive.
The value is then ANDed with $00FF
.Pq Ql & $FF .
.It Li $61 Ta Ql rst
check.
Checks if the value is a valid
.Ql rst
.Pq see Do RST vec Dc in Xr gbz80 7
vector, that is one of $00, $08, $10, $18, $20, $28, $30, or $38.
The value is then ORed with $C7
.Pq Ql \&| $C7 .
.It Li $80 Ta Integer literal; followed by the
.Cm LONG
integer.
.It Li $81 Ta A symbol's value; followed by the symbol's
.Cm LONG
ID.
.El
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgbasm 5 ,
.Xr rgblink 1 ,
.Xr rgbds 7 ,
.Xr gbz80 7
.Xr rgblink 5 ,
.Xr rgbfix 1 ,
.Xr rgbgfx 1 ,
.Xr gbz80 7 ,
.Xr rgbds 7
.Sh HISTORY
.Nm
was originally written by Carsten S\(/orensen as part of the ASMotor package,
and was later packaged in RGBDS by Justin Lloyd.
.Xr rgbasm 1
and
.Xr rgblink 1
were originally written by
.An Carsten S\(/orensen
as part of the ASMotor package, and was later repackaged in RGBDS by
.An Justin Lloyd .
It is now maintained by a number of contributors at
.Lk https://github.com/gbdev/rgbds .

View File

@@ -1,11 +1,6 @@
.\"
.\" This file is part of RGBDS.
.\"
.\" Copyright (c) 2010-2021, Anthony J. Bentley and RGBDS contributors.
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
.Dt RGBDS 7
.Os
.Sh NAME
@@ -14,44 +9,65 @@
.Sh EXAMPLES
To get a working ROM image from a single assembly source file:
.Bd -literal -offset indent
$ rgbasm \-o bar.o foo.asm
$ rgblink \-o baz.gb bar.o
$ rgbfix \-v \-p 0 baz.gb
$ rgbasm \-o game.o game.asm
$ rgblink \-o game.gb game.o
$ rgbfix \-v \-p 0 game.gb
.Ed
Or in a single command line:
.Pp
Or in a single command line, without creating an intermediate object file:
.Bd -literal -offset indent
$ rgbasm \-o - foo.asm | rgblink \-o - - | rgbfix \-v \-p 0 - > baz.gb
$ (rgbasm -o - - | rgblink -o - - | rgbfix -v -p 0) < game.asm > game.gb
.Ed
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgbfix 1 ,
.Xr rgbasm 5 ,
.Xr rgblink 1 ,
.Xr rgbds 5 ,
.Xr gbz80 7
.Xr rgblink 5 ,
.Xr rgbfix 1 ,
.Xr rgbgfx 1 ,
.Xr gbz80 7 ,
.Xr rgbds 5
.Sh HISTORY
.Bl -item
.It
1997, Carsten S\(/orensen (AKA SurfSmurf) writes ASMotor as a general-purpose
assembler/linker system for DOS/Win32.
1996-10-01:
.An Carsten S\(/orensen
.Pq a.k.a. SurfSmurf
releases xAsm, xLink, and RGBFix, a Game Boy SM83 (GBZ80) assembler/linker system for DOS/Win32.
.It
1999, Justin Lloyd (AKA Otaku no Zoku) adapts ASMotor to read and produce GBZ80
assembly/machine code, and releases this version as RGBDS.
1997-07-03: S\(/orensen releases ASMotor, packaging the three programs together and moving towards making them a general-purpose target-independent system.
.It
2009, Vegard Nossum adapts the code to be more UNIX-like and releases this
version as rgbds-linux on GitHub.
1999-08-01:
.An Justin Lloyd
.Pq a.k.a. Otaku no Zoku
adapts ASMotor to re-focus on SM83 assembly/machine code, and releases this version as RGBDS.
.It
2010, Anthony J. Bentley forks that repository.
The fork becomes the reference implementation of rgbds.
2009-06-11:
.An Vegard Nossum
adapts the code to be more UNIX-like and releases this version as rgbds-linux.
.It
2017, Bentley's repository is moved to a neutral name.
It is now maintained by a number of contributors at
.Lk https://github.com/rednex/rgbds .
2010-01-12:
.An Anthony J. Bentley
forks Nossum's repository.
The fork becomes the reference implementation of RGBDS.
.It
2018, codebase relicensed under the MIT license.
2015-01-18:
.An stag019
begins implementing rgbgfx, a PNGtoGame Boy graphics converter, for eventual integration into RGBDS.
.It
2020, repository is moved to the gbdev organisation, at
.Lk https://github.com/gbdev/rgbds .
The
2016-09-05: rgbgfx is integrated into Bentley's repository.
.It
2017-02-23: Bentley's repository is moved to the
.Lk https://github.com/rednex/rgbds rednex
organization.
.It
2018-01-26: The codebase is relicensed under the MIT license.
.It
2020-09-15: The repository is moved to the
.Lk https://github.com/gbdev/rgbds gbdev
organization.
.It
2022-05-17: The
.Lk https://rgbds.gbdev.io
website serving documentation and downloads is created.
website for RGBDS documentation and downloads is published.
.El

View File

@@ -1,11 +1,6 @@
.\"
.\" This file is part of RGBDS.
.\"
.\" Copyright (c) 2010-2021, Anthony J. Bentley and RGBDS contributors.
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
.Dt RGBFIX 1
.Os
.Sh NAME
@@ -41,32 +36,38 @@ Developers are advised to fill those fields with 0x00 bytes in their source code
and to have already populated whichever fields they don't specify using
.Nm .
.Pp
The input
.Ar asmfile
can be a path to a file, or
.Cm \-
to read from standard input.
.Pp
Note that options can be abbreviated as long as the abbreviation is unambiguous:
.Fl Fl color-o
.Fl \-color-o
is
.Fl Fl color-only ,
.Fl \-color-only ,
but
.Fl Fl color
.Fl \-color
is invalid because it could also be
.Fl Fl color-compatible .
.Fl \-color-compatible .
Options later in the command line override those set earlier.
Accepted options are as follows:
.Bl -tag -width Ds
.It Fl C , Fl Fl color-only
.It Fl C , Fl \-color-only
Set the Game Boy Color\(enonly flag
.Pq Ad 0x143
to 0xC0.
This overrides
.Fl c
if it was set prior.
.It Fl c , Fl Fl color-compatible
.It Fl c , Fl \-color-compatible
Set the Game Boy Color\(encompatible flag:
.Pq Ad 0x143
to 0x80.
This overrides
.Fl c
if it was set prior.
.It Fl f Ar fix_spec , Fl Fl fix-spec Ar fix_spec
.It Fl f Ar fix_spec , Fl \-fix-spec Ar fix_spec
Fix certain header values that the Game Boy checks for correctness.
Alternatively, intentionally trash these values by writing their binary inverse instead.
.Ar fix_spec
@@ -89,26 +90,26 @@ Fix the global checksum
.It Cm G
Trash the global checksum.
.El
.It Fl i Ar game_id , Fl Fl game-id Ar game_id
.It Fl i Ar game_id , Fl \-game-id Ar game_id
Set the game ID string
.Pq Ad 0x13F Ns \(en Ns Ad 0x142
to a given string.
If it's longer than 4 chars, it will be truncated, and a warning emitted.
.It Fl j , Fl Fl non-japanese
.It Fl j , Fl \-non-japanese
Set the non-Japanese region flag
.Pq Ad 0x14A
to 0x01.
.It Fl k Ar licensee_str , Fl Fl new-licensee Ar licensee_str
.It Fl k Ar licensee_str , Fl \-new-licensee Ar licensee_str
Set the new licensee string
.Pq Ad 0x144 Ns \(en Ns Ad 0x145
to a given string.
If it's longer than 2 chars, it will be truncated, and a warning emitted.
.It Fl l Ar licensee_id , Fl Fl old-licensee Ar licensee_id
.It Fl l Ar licensee_id , Fl \-old-licensee Ar licensee_id
Set the old licensee code
.Pq Ad 0x14B
to a given value from 0 to 0xFF.
This value is deprecated and should be set to 0x33 in all new software.
.It Fl m Ar mbc_type , Fl Fl mbc-type Ar mbc_type
.It Fl m Ar mbc_type , Fl \-mbc-type Ar mbc_type
Set the MBC type
.Pq Ad 0x147
to a given value from 0 to 0xFF.
@@ -121,13 +122,13 @@ Any amount of whitespace (space and tabs) is allowed around plus signs, and the
There are special considerations to take for the TPP1 mapper; see the
.Sx TPP1
section below.
.It Fl n Ar rom_version , Fl Fl rom-version Ar rom_version
.It Fl n Ar rom_version , Fl \-rom-version Ar rom_version
Set the ROM version
.Pq Ad 0x14C
to a given value from 0 to 0xFF.
.It Fl O , Fl Fl overwrite
.It Fl O , Fl \-overwrite
Allow overwriting different non-zero bytes in the header without a warning being emitted.
.It Fl p Ar pad_value , Fl Fl pad-value Ar pad_value
.It Fl p Ar pad_value , Fl \-pad-value Ar pad_value
Pad the ROM image to a valid size with a given pad value from 0 to 255 (0xFF).
.Nm
will automatically pick a size from 32 KiB, 64 KiB, 128 KiB, ..., 8192 KiB.
@@ -135,11 +136,11 @@ The cartridge size byte
.Pq Ad 0x148
will be changed to reflect this new size.
The recommended padding value is 0xFF, to speed up writing the ROM to flash chips, and to avoid "nop slides" into VRAM.
.It Fl r Ar ram_size , Fl Fl ram-size Ar ram_size
.It Fl r Ar ram_size , Fl \-ram-size Ar ram_size
Set the RAM size
.Pq Ad 0x149
to a given value from 0 to 0xFF.
.It Fl s , Fl Fl sgb-compatible
.It Fl s , Fl \-sgb-compatible
Set the SGB flag
.Pq Ad 0x146
to 0x03.
@@ -147,7 +148,7 @@ This flag will be ignored by the SGB unless the old licensee code is 0x33!
If this is given as well as
.Fl l ,
but is not set to 0x33, a warning will be printed.
.It Fl t Ar title , Fl Fl title Ar title
.It Fl t Ar title , Fl \-title Ar title
Set the title string
.Pq Ad 0x134 Ns \(en Ns Ad 0x143
to a given string.
@@ -159,9 +160,9 @@ is specified, 15 characters if the CGB flag
or
.Fl C )
is specified but the game ID is not, and 16 characters otherwise.
.It Fl V , Fl Fl version
.It Fl V , Fl \-version
Print the version of the program and exit.
.It Fl v , Fl Fl validate
.It Fl v , Fl \-validate
Equivalent to
.Fl f Cm lhg .
.El
@@ -235,9 +236,14 @@ Please report bugs on
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgblink 1 ,
.Xr rgbgfx 1 ,
.Xr gbz80 7 ,
.Xr rgbds 7
.Sh HISTORY
.Nm
was originally released by Carsten S\(/orensen as a standalone program called gbfix, and was later packaged in RGBDS by Justin Lloyd.
was originally written by
.An Carsten S\(/orensen
as a standalone program called GBFix, which was then packaged in ASMotor, and was later repackaged in RGBDS by
.An Justin Lloyd .
It is now maintained by a number of contributors at
.Lk https://github.com/gbdev/rgbds .

View File

@@ -1,12 +1,8 @@
'\" e
.\"
.\" This file is part of RGBDS.
.\"
.\" Copyright (c) 2013-2021, stag019 and RGBDS contributors.
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
.Dt RGBGFX 1
.Os
.Sh NAME
@@ -14,8 +10,7 @@
.Nd Game Boy graphics converter
.Sh SYNOPSIS
.Nm
.Op Fl r Ar stride
.Op Fl CmuVZ
.Op Fl CmOuVZ
.Op Fl v Op Fl v No ...
.Op Fl a Ar attrmap | Fl A
.Op Fl b Ar base_ids
@@ -27,6 +22,7 @@
.Op Fl o Ar out_file
.Op Fl p Ar pal_file | Fl P
.Op Fl q Ar pal_map | Fl Q
.Op Fl r Ar stride
.Op Fl s Ar nb_colors
.Op Fl t Ar tilemap | Fl T
.Op Fl x Ar quantity
@@ -44,13 +40,13 @@ convert each of those squares into 1bpp or 2bpp tile data, and save all of the t
It also has options to generate a tile map, attribute map, and/or palette set as well; more on that and how the conversion process can be tweaked below.
.Sh ARGUMENTS
Note that options can be abbreviated as long as the abbreviation is unambiguous:
.Fl Fl verb
.Fl \-verb
is
.Fl Fl verbose ,
.Fl \-verbose ,
but
.Fl Fl ver
.Fl \-ver
is invalid because it could also be
.Fl Fl version .
.Fl \-version .
.Pp
.Nm
accepts decimal, binary, and hexadecimal numbers in option arguments.
@@ -72,9 +68,21 @@ All of these are equivalent:
.Ql 0X2A ,
.Ql 0x2a .
.Pp
Unless otherwise noted, passing
.Ql -
(a single dash) as a file name makes
.Nm
use standard input (for input files) or standard output (for output files).
To suppress this behavior, and open a file in the current directory actually called
.Ql - ,
pass
.Ql ./-
instead.
Using standard input or output more than once in a single command will likely produce unexpected results.
.Pp
The following options are accepted:
.Bl -tag -width Ds
.It Fl a Ar attrmap , Fl Fl attr-map Ar attrmap
.It Fl a Ar attrmap , Fl \-attr-map Ar attrmap
Generate an attribute map, which is a file containing tile
.Dq attributes .
For each square of the input image, its corresponding attribute map byte contains the mirroring bits (if
@@ -90,23 +98,20 @@ The output is written just like the tile map (see
follows the same order
.Pq Fl Z ,
and has the same size.
.It Fl A , Fl Fl output-attr-map
.It Fl A , Fl \-auto-attr-map
Same as
.Fl a Ar path ,
where
.Ar path
is the input image's path with the extension set to
.Pa .attrmap .
.It Fl b Ar base_ids , Fl Fl base-tiles Ar base_ids
.Fl a Ar base_path Ns .attrmap
.Pq see Sx Automatic output paths .
.It Fl b Ar base_ids , Fl \-base-tiles Ar base_ids
Set the base IDs for tile map output.
.Ar base_ids
should be one or two numbers between 0 and 255, separated by a comma; they are for bank 0 and bank 1 respectively.
Both default to 0.
.It Fl C , Fl Fl color-curve
.It Fl C , Fl \-color-curve
When generating palettes, use a color curve mimicking the Game Boy Color's screen.
The resulting colors may look closer to the input image's
.Sy on hardware and accurate emulators .
.It Fl c Ar color_spec , Fl Fl colors Ar color_spec
.It Fl c Ar color_spec , Fl \-colors Ar color_spec
Use the specified color palettes instead of having
.Nm
automatically determine some.
@@ -145,16 +150,18 @@ The expected format is
.Ql format:path ,
where
.Ar path
is a path to a file, which will be processed according to the
is a path to a file
.Ql ( -
is not treated specially), which will be processed according to the
.Ar format .
See
.Sx PALETTE SPECIFICATION FORMATS
for a list of formats and their descriptions.
.El
.It Fl d Ar depth , Fl Fl depth Ar depth
.It Fl d Ar depth , Fl \-depth Ar depth
Set the bit depth of the output tile data, in bits per pixel (bpp), either 1 or 2 (the default).
This changes how tile data is output, and the maximum number of colors per palette (2 and 4 respectively).
.It Fl L Ar slice , Fl Fl slice Ar slice
.It Fl L Ar slice , Fl \-slice Ar slice
Only process a given rectangle of the image.
This is useful for example if the input image is a sheet of some sort, and you want to convert each cel individually.
The default is to process the whole image as-is.
@@ -165,14 +172,19 @@ The numbers must be separated by commas; space is allowed around all punctuation
The first number pair specifies the X and Y coordinates of the top-left pixel that will be processed (anything above it or to its left will be ignored).
The second number pair specifies how many tiles to process horizontally and vertically, respectively.
.Pp
.Sy Fl L Sy is ignored in reverse mode , No no padding is inserted .
.It Fl m , Fl Fl mirror-tiles
Deduplicate tiles that are mirrors of each other.
.Fl L Sy is ignored in reverse mode , No no padding is inserted .
.It Fl m , Fl \-mirror-tiles
Deduplicate tiles that are symmetrical mirror images of each other.
Only one of each unique tile will be saved in the tile data file, with mirror images counting as duplicates.
Tiles are checked for horizontal, vertical, and horizontal-vertical mirroring.
Useful with a tile map and attribute map together to keep track of the duplicated tiles and the dimension(s) mirrored.
Useful with a tile map and attribute map together (see
.Fl a
and
.Fl t )
to keep track of the duplicated tiles and the dimension(s) mirrored.
Implies
.Fl u .
.It Fl N Ar nb_tiles , Fl Fl nb-tiles Ar nb_tiles
.It Fl N Ar nb_tiles , Fl \-nb-tiles Ar nb_tiles
Set a maximum number of tiles that can be placed in each VRAM bank.
.Ar nb_tiles
should be one or two numbers between 0 and 256, separated by a comma; if the latter is omitted, it defaults to 0.
@@ -184,7 +196,7 @@ will abort.
If
.Fl N
is not specified, no limit will be set on the amount of tiles placed in bank 0, and tiles will not be placed in bank 1.
.It Fl n Ar nb_pals , Fl Fl nb-palettes Ar nb_pals
.It Fl n Ar nb_pals , Fl \-nb-palettes Ar nb_pals
Abort if more than
.Ar nb_pals
palettes are generated.
@@ -192,30 +204,31 @@ This may not be more than 256.
.Pp
Note that attribute map output only has 3 bits for the palette ID, so a limit higher than 8 may yield incomplete data unless relying on a palette map
.Pq see Fl q .
.It Fl o Ar out_file , Fl Fl output Ar out_file
.It Fl O , Fl \-group-outputs
Sets the
.Sq base path
to be the output tile data path from
.Fl o
instead of the input image path
.Pq see Sx Automatic output paths .
.It Fl o Ar out_file , Fl \-output Ar out_file
Output the tile data in native 2bpp format or in 1bpp
.Pq depending on Fl d
to this file.
.It Fl p Ar pal_file , Fl Fl palette Ar pal_file
.It Fl p Ar pal_file , Fl \-palette Ar pal_file
Output the image's palette set to this file.
.It Fl P , Fl Fl output-palette
.It Fl P , Fl \-auto-palette
Same as
.Fl p Ar path ,
where
.Ar path
is the input image's path with the extension set to
.Pa .pal .
.It Fl q Ar pal_file , Fl Fl palette-map Ar pal_file
.Fl p Ar base_path Ns .pal
.Pq see Sx Automatic output paths .
.It Fl q Ar pal_file , Fl \-palette-map Ar pal_file
Output the image's palette map to this file.
This is useful if the input image contains more than 8 palettes, as the attribute map only contains the lower 3 bits of the palette indices.
.It Fl Q , Fl Fl output-palette-map
.It Fl Q , Fl \-auto-palette-map
Same as
.Fl q Ar path ,
where
.Ar path
is the input image's path with the extension set to
.Pa .palmap .
.It Fl r Ar width , Fl Fl reverse Ar width
.Fl q Ar base_path Ns .palmap
.Pq see Sx Automatic output paths .
.It Fl r Ar width , Fl \-reverse Ar width
Switches
.Nm
into
@@ -229,15 +242,14 @@ See
below for details.
.Pp
.Ar width
is the image's width, in tiles
.Pq including any margins specified by Fl L .
.It Fl s Ar nb_colors , Fl Fl palette-size Ar nb_colors
is the width of the image to generate, in tiles.
.It Fl s Ar nb_colors , Fl \-palette-size Ar nb_colors
Specify how many colors each palette contains, including the transparent one if any.
.Ar nb_colors
cannot be more than
.Ql 1 << Ar depth
.Pq see Fl d .
.It Fl t Ar tilemap , Fl Fl tilemap Ar tilemap
.It Fl t Ar tilemap , Fl \-tilemap Ar tilemap
Generate a file of tile indices.
For each square of the input image, its corresponding tile map byte contains the index of the associated tile in the tile data file.
The IDs wrap around from 255 back to 0, and do not include the bank bit; use
@@ -248,15 +260,13 @@ Useful in combination with
and/or
.Fl m
to keep track of duplicate tiles.
.It Fl T , Fl Fl output-tilemap
.It Fl T , Fl \-auto-tilemap
Same as
.Fl t Ar path ,
where
.Ar path
is the input image's path with the extension set to
.Pa .tilemap .
.It Fl u , Fl Fl unique-tiles
Deduplicate identical tiles, and omit the duplicates from the tile data file.
.Fl t Ar base_path Ns .tilemap
.Pq see Sx Automatic output paths .
.It Fl u , Fl \-unique-tiles
Deduplicate identical tiles.
Only one of each unique tile will be saved in the tile data file.
Useful with a tile map
.Pq see Fl t
to keep track of the duplicated tiles.
@@ -266,12 +276,12 @@ Note that if this option is enabled, no guarantee is made on the order in which
be consistent across identical runs of a given
.Nm
release, the same is not true for different releases.
.It Fl V , Fl Fl version
.It Fl V , Fl \-version
Print the version of the program and exit.
.It Fl v , Fl Fl verbose
.It Fl v , Fl \-verbose
Be verbose.
The verbosity level is increased by one each time the flag is specified, with each level including the previous:
.Bl -enum -width 2n -compact
.Bl -enum -compact
.It
.Nm
prints out its configuration before doing anything.
@@ -285,7 +295,7 @@ Some internal debug printing is enabled.
The verbosity level does not go past 6.
.Pp
Note that verbose output is only intended to be consumed by humans, and may change without notice between RGBDS releases; relying on those for scripts is not advised.
.It Fl x Ar quantity , Fl Fl trim-end Ar quantity
.It Fl x Ar quantity , Fl \-trim-end Ar quantity
Do not output the last
.Ar quantity
tiles to the tile data file; no other output is affected.
@@ -305,7 +315,7 @@ was enabled, so you probably don't want to use this option in combination with
Note also that the tiles that don't get output will not count towards
.Fl N Ap s
limit.
.It Fl Z , Fl Fl columns
.It Fl Z , Fl \-columns
Read squares from the PNG in column-major order (column by column), instead of the default row-major order (line by line).
This primarily affects tile map and attribute map output, although it may also change generated tile data and palettes.
.El
@@ -321,7 +331,22 @@ any command-line argument that begins with an at sign
.Pq Ql @
is interpreted as one.
The rest of the argument (without the @, that is) is interpreted as the path to a file, whose contents are interpreted as if given on the command line.
At-files can be stored right next to the corresponding image, for example.
At-files can be stored right next to the corresponding image, for example:
.Pp
.Dl $ rgbgfx -o image.2bpp -t image.tilemap @image.flags image.png
.Pp
This will read additional flags from file
.Ql image.flags ,
which could contains for example
.Ql -b 128
to specify a base offset for the image's tiles.
The above command could be generated from the following
.Xr make 1
rule, for example:
.Bd -literal -offset indent
%.2bpp %.tilemap: %.flags %.png
rgbgfx -o $*.2bpp -t $*.tilemap @$*.flags $*.png
.Ed
.Pp
Since the contents of at-files are interpreted by
.Nm ,
@@ -336,17 +361,19 @@ optionally preceded by whitespace, are considered comments and also ignored.
Each line can contain any number of arguments, which are separated by whitespace.
.Pq \&No quoting feature to prevent this is provided.
.Pp
Note that this special meaning given to arguments has less precedence than option arguments, and that the standard
Note that a leading
.Ql @
has no special meaning on option arguments, and that the standard
.Ql --
to stop option processing also disables at-file processing.
For example, the following command line processes
.Ql @tilesets/town.png ,
outputs tile data to
.Ql @tilesets/town.2bpp ,
and reads command-line options from
For example, the following command line reads command-line options from
.Ql tilesets/town.flags
then
.Ql tilesets.flags :
.Ql tilesets.flags ,
but processes
.Ql @tilesets/town.png
as the input image and outputs tile data to
.Ql @tilesets/town.2bpp :
.Pp
.Dl $ rgbgfx -o @tilesets/town.2bpp @tilesets/town.flags @tilesets.flags -- @tilesets/town.png
.Pp
@@ -357,11 +384,21 @@ can be used in an at-file (with identical semantics), it is only effective insid
.Sh PALETTE SPECIFICATION FORMATS
The following formats are supported:
.Bl -tag -width Ds
.It Sy act
.It Cm act
.Lk https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1070626 Adobe Photoshop color table .
.It Sy aco
.It Cm aco
.Lk https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1055819 Adobe Photoshop color swatch .
.It Sy psp
.It Cm gbc
A GBC palette memory dump, as emitted by
.Nm Fl p .
Useful to force several images to share the same palette.
.It Cm gpl
.Lk https://docs.gimp.org/2.10/en/gimp-concepts-palettes.html GIMP palette .
.It Cm hex
Plaintext lines of hexadecimal colors in
.Ql rrggbb
format.
.It Cm psp
.Lk https://www.selapa.net/swatches/colors/fileformats.php#psp_pal Paint Shop Pro palette .
.El
.Pp
@@ -421,7 +458,7 @@ be
.Em exactly
the same.
.It
If none of the above apply, colors are sorted from lightest to darkest.
If none of the above apply, colors are sorted from lightest (first) to darkest (last).
The definition of luminance that
.Nm
uses is
@@ -447,7 +484,7 @@ What follows is succinct descriptions of those formats, including
.Nm Ns -specific
details.
For more complete, beginner-friendly descriptions of the native formats with illustrations, please check out
.Lk https://gbdev.io/pandocs/Rendering Pan Docs .
.Lk https://gbdev.io/pandocs/Graphics Pan Docs .
.Ss Tile data
Tile data is output like a binary dump of VRAM, with no padding between tiles.
Each tile is 16 bytes, 2 per row of 8 pixels; the bits of color IDs are split into each byte
@@ -472,7 +509,7 @@ delim off
.EN
Note that
.Fl n
only puts a limit on the amount of palettes, but does not fix this file's size.
only caps how many palettes are generated (and thus this file's size), but fewer may be generated still.
.Ss Tile map data
A tile map is an array of tile IDs, with one byte per tile ID.
The first byte always corresponds to the ID of the tile in top-left corner of the input image; the second byte is either the ID of the tile to its right (by default), or below it
@@ -492,6 +529,29 @@ The contents of individual bytes follows the GBC's native format:
.El
.Pp
Note that if more than 8 palettes are used, only the lowest 3 bits of the palette ID are output.
.Ss Automatic output paths
For convenience,
.Nm
provides shortcuts to generate all files in the same directory.
This is done by using the uppercase version of a flag
.Pq for example, Fl A No instead of Fl a .
The
.Ar base_path
is the input image path
.Pq or the output tile data path from Fl o , No if Fl O No was given
with its extension, if any, removed.
.Pp
For example, these two commands are equivalent:
.Bd -literal -offset indent
$ rgbgfx img/player.png -o build/player.2bpp -P
$ rgbgfx img/player.png -o build/player.2bpp -p img/player.pal
.Ed
.Pp
And so are these two:
.Bd -literal -offset indent
$ rgbgfx img/player.png -o build/player.2bpp -O -P
$ rgbgfx img/player.png -o build/player.2bpp -p build/player.pal
.Ed
.Sh REVERSE MODE
.Nm
can produce a PNG image from valid data.
@@ -554,37 +614,53 @@ It is possible to compute the optimal solution externally (using a solver, for e
via
.Fl c .
.Sh EXAMPLES
The following will only validate the PNG (check its size, that all tiles have a suitable amount of colors, etc.), but output nothing:
The following will only validate the
.Ql tileset.png
image (check its size, that all tiles have a suitable amount of colors, etc.), but output nothing:
.Pp
.Dl $ rgbgfx src/res/maps/overworld/tileset.png
.Pp
The following will convert the image using the two given palettes (and only those), and store the generated 2bpp tile data in
The following will convert the
.Ql tileset.png
image using the two given palettes (and only those), and store the generated 2bpp tile data in
.Ql tileset.2bpp ,
and the attribute map in
.Ql tileset.attrmap .
.Pp
.Dl $ rgbgfx -c '#ffffff,#8d05de, #dc7905,#000000 ; #fff,#8d05de, #7e0000 \&, #000' -A -o tileset.2bpp tileset.png
.Pp
The following will deduplicate the tiles in the
.Ql title_screen.png
image, keeping only one of each unique tile, and store the generated 2bpp tile data in
.Ql title_screen.2bpp ,
and the tile map in
.Ql title_screen.tilemap .
.Pp
.Dl $ rgbgfx -u title_screen.png -o title_screen.2bpp -t title_screen.tilemap
.Pp
The following will convert the given inline palette specification to a palette set, and store the palette set in
.Ql colors.pal ,
without needing an input image.
.Pp
.Dl $ rgbgfx -c '#fff,#ff0,#f80,#000' -p colors.pal
.Pp
TODO: more examples.
.Sh BUGS
Please report bugs and mistakes in this man page on
.Lk https://github.com/gbdev/rgbds/issues GitHub .
Bug reports and feature requests about RGBDS are also welcome!
.Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbasm 1 ,
.Xr rgblink 1 ,
.Xr rgbfix 1 ,
.Xr gbz80 7
.Xr rgbds 7
.Pp
The Game Boy hardware reference
.Lk https://gbdev.io/pandocs/Rendering.html Pan Docs ,
.Lk https://gbdev.io/pandocs/Graphics Pan Docs ,
particularly the section about graphics.
.Sh HISTORY
.Nm
was originally created by
.An stag019
to be included in RGBDS.
was originally written by stag019 as a program to be packaged in RGBDS.
It was later rewritten by
.An ISSOtm ,
and is now maintained by a number of contributors at

View File

@@ -1,11 +1,6 @@
.\"
.\" This file is part of RGBDS.
.\"
.\" Copyright (c) 2010-2021, Anthony J. Bentley and RGBDS contributors.
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
.Dt RGBLINK 1
.Os
.Sh NAME
@@ -13,7 +8,7 @@
.Nd Game Boy linker
.Sh SYNOPSIS
.Nm
.Op Fl dtVvwx
.Op Fl dMtVvwx
.Op Fl l Ar linker_script
.Op Fl m Ar map_file
.Op Fl n Ar sym_file
@@ -29,7 +24,7 @@ The
program links RGB object files, typically created by
.Xr rgbasm 1 ,
into a single Game Boy ROM file.
The format is documented in
The object file format is documented in
.Xr rgbds 5 .
.Pp
ROM0 sections are placed in the first 16 KiB of the output ROM, and ROMX sections are placed in any 16 KiB
@@ -52,45 +47,58 @@ option, which implies
.Fl w
but also prohibits the use of banked VRAM.
.Pp
The input
.Ar asmfile
can be a path to a file, or
.Cm \-
to read from standard input.
.Pp
Note that options can be abbreviated as long as the abbreviation is unambiguous:
.Fl Fl verb
.Fl \-verb
is
.Fl Fl verbose ,
.Fl \-verbose ,
but
.Fl Fl ver
.Fl \-ver
is invalid because it could also be
.Fl Fl version .
.Fl \-version .
The arguments are as follows:
.Bl -tag -width Ds
.It Fl d , Fl Fl dmg
.It Fl d , Fl \-dmg
Enable DMG mode.
Prohibit the use of sections that doesn't exist on a DMG, such as VRAM bank 1.
This option automatically enables
.Fl w .
.It Fl l Ar linker_script , Fl Fl linkerscript Ar linker_script
.It Fl l Ar linker_script , Fl \-linkerscript Ar linker_script
Specify a linker script file that tells the linker how sections must be placed in the ROM.
The attributes assigned in the linker script must be consistent with any assigned in the code.
See
.Xr rgblink 5
for more information about the linker script format.
.It Fl m Ar map_file , Fl Fl map Ar map_file
.It Fl M , Fl \-no-sym-in-map
If specified, the map file will not list symbols, only sections.
.It Fl m Ar map_file , Fl \-map Ar map_file
Write a map file to the given filename, listing how sections and symbols were assigned.
.It Fl n Ar sym_file , Fl Fl sym Ar sym_file
.It Fl n Ar sym_file , Fl \-sym Ar sym_file
Write a symbol file to the given filename, listing the address of all exported symbols.
Several external programs can use this information, for example to help debugging ROMs.
.It Fl O Ar overlay_file , Fl Fl overlay Ar overlay_file
If specified, sections will be overlaid "on top" of the provided ROM image.
In that case, all sections must be fixed.
This may be used to patch an existing binary.
.It Fl o Ar out_file , Fl Fl output Ar out_file
.It Fl O Ar overlay_file , Fl \-overlay Ar overlay_file
If specified, sections will be overlaid "on top" of the ROM image
.Ar overlay_file :
empty space between sections will be filled by the corresponding bytes from
.Ar overlay_file .
This is useful to patch an existing ROM.
Note that all sections must be fixed (forced bank
.Sy and
address)!
.It Fl o Ar out_file , Fl \-output Ar out_file
Write the ROM image to the given file.
.It Fl p Ar pad_value , Fl Fl pad Ar pad_value
.It Fl p Ar pad_value , Fl \-pad Ar pad_value
When inserting padding between sections, pad with this value.
Has no effect if
.Fl O
is specified.
The default is 0.
.It Fl S Ar spec , Fl Fl scramble Ar spec
.It Fl S Ar spec , Fl \-scramble Ar spec
Enables a different
.Dq scrambling
algorithm for placing sections.
@@ -98,22 +106,22 @@ See
.Sx Scrambling algorithm
below for an explanation and a description of
.Ar spec .
.It Fl s Ar symbol , Fl Fl smart Ar symbol
.It Fl s Ar symbol , Fl \-smart Ar symbol
This option is ignored.
It was supposed to perform smart linking but fell into disrepair, and so has been removed.
It will be reimplemented at some point.
.It Fl t , Fl Fl tiny
.It Fl t , Fl \-tiny
Expand the ROM0 section size from 16 KiB to the full 32 KiB assigned to ROM.
ROMX sections that are fixed to a bank other than 1 become errors, other ROMX sections are treated as ROM0.
Useful for ROMs that fit in 32 KiB.
.It Fl V , Fl Fl version
.It Fl V , Fl \-version
Print the version of the program and exit.
.It Fl v , Fl Fl verbose
.It Fl v , Fl \-verbose
Verbose: enable printing more information to standard error.
.It Fl w , Fl Fl wramx
.It Fl w , Fl \-wramx
Expand the WRAM0 section size from 4 KiB to the full 8 KiB assigned to WRAM.
WRAMX sections that are fixed to a bank other than 1 become errors, other WRAMX sections are treated as WRAM0.
.It Fl x , Fl Fl nopad
.It Fl x , Fl \-nopad
Disables padding the end of the final file.
This option automatically enables
.Fl t .
@@ -196,10 +204,15 @@ Please report bugs on
.Xr rgbasm 1 ,
.Xr rgblink 5 ,
.Xr rgbfix 1 ,
.Xr rgbgfx 1 ,
.Xr gbz80 7 ,
.Xr rgbds 5 ,
.Xr rgbds 7
.Sh HISTORY
.Nm
was originally written by Carsten S\(/orensen as part of the ASMotor package, and was later packaged in RGBDS by Justin Lloyd.
was originally written by
.An Carsten S\(/orensen
as part of the ASMotor package, and was later repackaged in RGBDS by
.An Justin Lloyd .
It is now maintained by a number of contributors at
.Lk https://github.com/gbdev/rgbds .

View File

@@ -1,90 +1,175 @@
.\"
.\" This file is part of RGBDS.
.\"
.\" Copyright (c) 2017-2021, Antonio Nino Diaz and RGBDS contributors.
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
.Dt RGBLINK 5
.Os
.Sh NAME
.Nm rgblink
.Nd linker script file format
.Sh DESCRIPTION
The linker script is an external file that allows the user to specify the order of sections at link time and in a centralized manner.
The linker script is a file that allows specifying attributes for sections at link time, and in a centralized manner.
There can only be one linker script per invocation of
.Nm ,
but it can be split into several files
.Pq using the Ic INCLUDE No directive .
.Ss Basic syntax
The linker script syntax is line-based.
Each line may have a directive or section name, a comment, both, or neither.
Whitespace (space and tab characters) is used to separate syntax elements, but is otherwise ignored.
.Pp
A linker script consists on a series of banks followed by a list of sections and, optionally, commands.
They can be lowercase or uppercase, it is ignored.
Any line can contain a comment starting with
Comments begin with a semicolon
.Ql \&;
that ends at the end of the line:
character, until the end of the line.
They are simply ignored.
.Pp
Keywords are composed of letters and digits (but they can't start with a digit); they are all case-insensitive.
.Pp
Numbers can be written in decimal format, or in binary using the
.Ql %
prefix, or in hexadecimal using the
.Ql $
prefix (hexadecimal digits are case-insensitive).
Note that unlike
.Xr rgbasm 5 ,
an octal
.Ql &
prefix is not supported, nor are
.Ql _
digit separators.
.Pp
Strings begin with a double quote, and end at the next (non-escaped) double quote.
Strings must not contain literal newline characters.
Most of the same character escapes as
.Xr rgbasm 5
are supported, specifically
.Ql \e\e ,
.Ql \e" ,
.Ql \en ,
.Ql \er ,
and
.Ql \et .
Other backslash escape sequences in
.Xr rgbasm 5
are only relevant to assembly code and do not apply in linker scripts.
.Ss Directives
.Bl -tag -width Ds
.It Including other files
.Ql Ic INCLUDE Ar path
acts as if the contents of the file at
.Ar path
were copy-pasted in place of the
.Ic INCLUDE
directive.
.Ar path
must be a string.
.It Specifying the active bank
The active bank can be set by specifying its type (memory region) and number.
The possible types are:
.Ic ROM0 , ROMX , VRAM , SRAM , WRAM0 , WRAMX , OAM ,
and
.Ic HRAM .
The bank number can be omitted from the types that only contain a single bank, which are:
.Ic ROM0 ,
.Ic ROMX No if Fl t No is passed to Xr rgblink 1 ,
.Ic VRAM No if Fl d No is passed to Xr rgblink 1 ,
.Ic WRAM0 ,
.Ic WRAMX No if Fl w No is passed to Xr rgblink 1 ,
.Ic OAM ,
and
.Ic HRAM .
.Pq Ic SRAM No is the only type that can never have its bank number omitted.
.Pp
After a bank specification, the
.Dq current address
is set to the last value it had for that bank.
If the bank has never been active thus far, the
.Dq current address
defaults to the beginning of the bank
.Pq e.g. Ad $4000 No for Ic ROMX No sections .
.It Changing the current address
A bank must be active for any of these directives to be used.
.Pp
.Ql Ic ORG Ar addr
sets the
.Dq current address
to
.Ar addr .
This directive cannot be used to move the address backwards:
.Ar addr
must be greater than or equal to the
.Dq current address .
.Pp
.Ql Ic FLOATING
causes all sections between it and the next
.Ic ORG
or bank specification to be placed at addresses automatically determined by
.Nm .
.Pp
.Ql Ic ALIGN Ar addr , Ar offset
increases the
.Dq current address
until it is aligned to the specified boundary (i.e. the
.Ar align
lowest bits of the address are equal to
.Ar offset ) .
If
.Ar offset
is omitted, it is implied to be 0.
For example, if the
.Dq current address
is $0007,
.Ql ALIGN 8
would set it to $0100, and
.Ql ALIGN 8 , 10
would set it to $000A.
.Pp
.Ql Ic DS Ar size
increases the
.Dq current address
by
.Ar size .
The gap is not allocated, so smaller floating sections can later be placed there.
.El
.Ss Section placement
A section can be placed simply by naming it (with a string).
Its bank is set to the active bank, and its address to the
.Dq current address .
Any constraints the section already possesses (whether from earlier in the linker script, or from the object files being linked) must be consistent with what the linker script specifies: the section's type must match, the section's bank number (if set) must match the active bank, etc.
In particular, if the section has an alignment constraint, the address at which it is placed by the linker script must obey that constraint; otherwise, an error will occur.
.Pp
After a section is placed, the
.Dq current address
is increased by the section's size.
This must not increase it past the end of the active memory region.
.Pp
The section must have been defined in the object files being linked, unless the section name is followed by the keyword
.Ic OPTIONAL .
.Sh EXAMPLES
.Bd -literal -offset indent
ROMX $F ; This is a comment
"Functions to read array"
ALIGN 8
"Array aligned to 256 bytes"
; This line contains only a comment
ROMX $F ; start a bank
"Some functions" ; a section name
ALIGN 8 ; a directive
"Some \e"array\e""
WRAMX 2
WRAMX 2 ; start another bank
org $d123 ; another directive
"Some variables"
.Ed
.Pp
Numbers can be in decimal or hexadecimal format
.Pq the prefix is Ql $ .
It is an error if any section name or command is found before setting a bank.
.Pp
Files can be included by using the
.Ic INCLUDE
keyword, followed by a string with the path of the file that has to be included.
.Pp
The possible bank types are:
.Cm ROM0 , ROMX , VRAM , SRAM , WRAM0 , WRAMX , OAM
and
.Cm HRAM .
Unless there is a single bank, which can occur with types
.Cm ROMX , VRAM , SRAM
and
.Cm WRAMX ,
it is needed to specify a bank number after the type.
.Pp
When a new bank statement is found, sections found after it will be placed right from the beginning of that bank.
If the linker script switches to a different bank and then comes back to a previous one, it will continue from the last address that was used.
.Pp
The only two commands are
.Ic ORG
and
.Ic ALIGN :
.Bl -bullet
.It
.Ic ORG
sets the address in which new sections will be placed.
It can not be lower than the current address.
.It
.Ic ALIGN
will increase the address until it is aligned to the specified boundary
.Po it tries to set to 0 the number of bits specified after the command:
.Ql ALIGN 8
will align to $100
.Pc .
.El
.Pp
.Sy Note:
The bank, alignment, address and type of sections can be specified both in the source code and in the linker script.
For a section to be able to be placed with the linker script, the bank, address and alignment must be left unassigned in the source code or be compatible with what is specified in the linker script.
For example,
.Ql ALIGN[8]
in the source code is compatible with
.Ql ORG $F00
in the linker script.
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgbasm 5 ,
.Xr rgblink 1 ,
.Xr rgbfix 1 ,
.Xr rgbgfx 1 ,
.Xr gbz80 7 ,
.Xr rgbds 5 ,
.Xr rgbds 7
.Sh HISTORY
.Nm
was originally written by Carsten S\(/orensen as part of the ASMotor package,
and was later packaged in RGBDS by Justin Lloyd.
.Xr rgblink 1
was originally written by
.An Carsten S\(/orensen
as part of the ASMotor package, and was later repackaged in RGBDS by
.An Justin Lloyd .
It is now maintained by a number of contributors at
.Lk https://github.com/gbdev/rgbds .

2
src/.gitignore vendored
View File

@@ -1,2 +1,2 @@
# Generated by CMake
/.version.c
/.version.cpp

View File

@@ -1,64 +1,63 @@
#
# This file is part of RGBDS.
#
# Copyright (c) 2020 RGBDS contributors.
#
# SPDX-License-Identifier: MIT
#
configure_file(version.c _version.c ESCAPE_QUOTES)
configure_file(version.cpp _version.cpp ESCAPE_QUOTES)
set(common_src
"error.c"
"extern/getopt.c"
"_version.c"
"error.cpp"
"extern/getopt.cpp"
"_version.cpp"
)
find_package(BISON REQUIRED)
find_package(BISON 3.0.0 REQUIRED)
set(BISON_FLAGS "-Wall")
# Set sompe optimization flags on versions that support them
# Set some optimization flags on versions that support them
if(BISON_VERSION VERSION_GREATER_EQUAL "3.5")
set(BISON_FLAGS "${BISON_FLAGS} -Dapi.token.raw=true")
endif()
if(BISON_VERSION VERSION_GREATER_EQUAL "3.6")
set(BISON_FLAGS "${BISON_FLAGS} -Dparse.error=detailed")
elseif(BISON_VERSION VERSION_GREATER_EQUAL "3.0")
else()
set(BISON_FLAGS "${BISON_FLAGS} -Dparse.error=verbose")
endif()
if(BISON_VERSION VERSION_GREATER_EQUAL "3.0")
set(BISON_FLAGS "${BISON_FLAGS} -Dparse.lac=full")
set(BISON_FLAGS "${BISON_FLAGS} -Dlr.type=ielr")
endif()
BISON_TARGET(PARSER "asm/parser.y"
"${PROJECT_SOURCE_DIR}/src/asm/parser.c"
set(BISON_FLAGS "${BISON_FLAGS} -Dparse.lac=full")
set(BISON_FLAGS "${BISON_FLAGS} -Dlr.type=ielr")
BISON_TARGET(ASM_PARSER "asm/parser.y"
"${PROJECT_SOURCE_DIR}/src/asm/parser.cpp"
COMPILE_FLAGS "${BISON_FLAGS}"
DEFINES_FILE "${PROJECT_SOURCE_DIR}/src/asm/parser.h"
DEFINES_FILE "${PROJECT_SOURCE_DIR}/src/asm/parser.hpp"
)
BISON_TARGET(LINKER_SCRIPT_PARSER "link/script.y"
"${PROJECT_SOURCE_DIR}/src/link/script.cpp"
COMPILE_FLAGS "${BISON_FLAGS}"
DEFINES_FILE "${PROJECT_SOURCE_DIR}/src/link/script.hpp"
)
set(rgbasm_src
"${BISON_PARSER_OUTPUT_SOURCE}"
"asm/charmap.c"
"asm/fixpoint.c"
"asm/format.c"
"asm/fstack.c"
"asm/lexer.c"
"asm/macro.c"
"asm/main.c"
"asm/opt.c"
"asm/output.c"
"asm/rpn.c"
"asm/section.c"
"asm/symbol.c"
"asm/util.c"
"asm/warning.c"
"extern/utf8decoder.c"
"hashmap.c"
"linkdefs.c"
"opmath.c"
"${BISON_ASM_PARSER_OUTPUT_SOURCE}"
"asm/charmap.cpp"
"asm/fixpoint.cpp"
"asm/format.cpp"
"asm/fstack.cpp"
"asm/lexer.cpp"
"asm/macro.cpp"
"asm/main.cpp"
"asm/opt.cpp"
"asm/output.cpp"
"asm/rpn.cpp"
"asm/section.cpp"
"asm/symbol.cpp"
"asm/warning.cpp"
"extern/utf8decoder.cpp"
"hashmap.cpp"
"linkdefs.cpp"
"opmath.cpp"
"util.cpp"
)
set(rgbfix_src
"fix/main.c"
"fix/main.cpp"
)
set(rgbgfx_src
@@ -70,22 +69,25 @@ set(rgbgfx_src
"gfx/proto_palette.cpp"
"gfx/reverse.cpp"
"gfx/rgba.cpp"
"extern/getopt.c"
"error.c"
"extern/getopt.cpp"
"error.cpp"
)
set(rgblink_src
"link/assign.c"
"link/main.c"
"link/object.c"
"link/output.c"
"link/patch.c"
"link/script.c"
"link/section.c"
"link/symbol.c"
"hashmap.c"
"linkdefs.c"
"opmath.c"
"${BISON_LINKER_SCRIPT_PARSER_OUTPUT_SOURCE}"
"link/assign.cpp"
"link/main.cpp"
"link/object.cpp"
"link/output.cpp"
"link/patch.cpp"
"link/sdas_obj.cpp"
"link/section.cpp"
"link/symbol.cpp"
"extern/utf8decoder.cpp"
"hashmap.cpp"
"linkdefs.cpp"
"opmath.cpp"
"util.cpp"
)
foreach(PROG "asm" "fix" "gfx" "link")

4
src/asm/.gitignore vendored
View File

@@ -1,2 +1,2 @@
/parser.c
/parser.h
/parser.cpp
/parser.hpp

Some files were not shown because too many files have changed in this diff Show More