Compare commits

..

50 Commits

Author SHA1 Message Date
Antonio Niño Díaz
ea4276c7ac Increase version number to 0.3.6
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-03-20 20:11:38 +00:00
Antonio Niño Díaz
7bce97f817 Fix crash in rgbgfx with height not multiple of 8
Images are allowed to have any arbitrary height if the width is 8. If
the height is not a multiple of 8, the number of tiles calculated won't
be an exact number and it will be rounded down. This patch increases the
number of tiles allocated in this case to prevent rgbgfx from accessing
memory that hasn't been allocated.

The buffers are now initialized to 0 with calloc instead of being
created with malloc.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-03-19 21:47:19 +00:00
Antonio Niño Díaz
483a63156b Document character maps
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-03-15 21:04:43 +00:00
Anthony J. Bentley
5a4bbe4985 Add a new flag, -f, which allows independently fixing or trashing checksums. 2018-03-10 21:48:23 -07:00
Antonio Niño Díaz
f86dbafad0 Fix format in manpage
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-03-07 18:23:44 +00:00
Antonio Niño Díaz
8744d360a3 Fix format of manpage
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-27 19:42:29 +00:00
Antonio Niño Díaz
b6bd57a764 Merge pull request #237 from continue-lines
Allow to continue lines

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-26 21:55:19 +00:00
Antonio Niño Díaz
f2b55527d5 Update html manpages
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-26 21:49:19 +00:00
Antonio Niño Díaz
84a6899c6c Document line continuation syntax
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-26 21:48:28 +00:00
Antonio Niño Díaz
8cffe22295 Fix style of code sections in manpages
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-26 21:48:26 +00:00
Antonio Niño Díaz
0c85240b97 Allow line continuations in list of macro args
For example:

    PrintMacro : MACRO
        PRINTT \1
    ENDM

        PrintMacro STRCAT(\"Hello\"\,  \
                          \" world\\n\")

It is possible to have spaces after the '\' and before the newline
character. This is needed because Windows line endings "\r\n" are
converted to " \n" before the lexer has a chance to handle them.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-26 21:47:52 +00:00
Antonio Niño Díaz
58ab88da82 Allow to scape " in lists of macro args
For example:

    PrintMacro : MACRO
        PRINTT \1
    ENDM

        PrintMacro STRCAT(\"Hello\"\,  \" world\\n\")

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-26 21:47:52 +00:00
Antonio Niño Díaz
3e219dee36 Allow to continuate lines except inside macros
Lines can be continuated after a newline character ('\n'):

    DB 1, 2, 3, 4 \
       5, 6, 7, 8

This doesn't work for now in lists of arguments of macros.

It is possible to have spaces after the '\' and before the newline
character. This is needed because Windows line endings "\r\n" are
converted to " \n" before the lexer has a chance to handle them.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-26 21:47:52 +00:00
Antonio Niño Díaz
6ad5bd2325 Add flag to rgbasm to disable LD->LDH optimization
rgbasm tries to optimize any loads from/to $FF00-$FFFF and generate
LDH 2-byte opcodes instead of regular LD 3-byte opcodes. This is a bit
inconsistent as it only works for constant values. If a load is trying
to access a label in a HRAM floating section, or a section found in a
different object file, this optimization doesn't work.

This means that a simple refactor or code could allow rgbasm to perform
the optimzation or prevent it from doing so. For certain projects, like
disassemblies, this is a problem.

This patch adds flag -L to rgbasm to disable the optimization, and
doesn't change the behaviour of any other existing code.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-26 21:44:00 +00:00
Antonio Niño Díaz
2a97535e75 Add safeguards against string overflows
Use snprintf instead of other unsafe functions. That way it is possible
to limit the size of the buffer and to ensure that it never overflows.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-25 22:58:29 +00:00
Antonio Niño Díaz
0e0e12a769 Add CSS file for the html documentation
It has been obtained from here:

http://mdocml.bsd.lv/cgi-bin/cvsweb/mandoc.css

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-24 16:40:55 +00:00
Antonio Niño Díaz
3bebedf1f8 Handle newlines and comments correctly
Newlines have to be handled before comments or comments won't be able to
handle line endings that don't include at least one LF character.

Also, document an obscure comment syntax: Anything that follows a '*'
placed at the start of a line is also a comment until the end of the
line.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-23 19:24:18 +00:00
Antonio Niño Díaz
2ed937db2c Allow JR between sections
Previously, JR was only allowed if the destination label was in the same
section as the JR. This patch removes this restriction. The check to see
if the relative value overflows is now done when linking the ROM.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-23 19:21:44 +00:00
Antonio Niño Díaz
d243bd04ef Introduce command PRINTI to print integers
PRINTV prints integers in hexadecimal, PRINTI prints them in signed
decimal. For example:

    PRINTT "Error at line "
    PRINTI __LINE__
    PRINTT "\n"

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-23 19:20:52 +00:00
Antonio Niño Díaz
3623638be7 Fix HIGH() and LOW() for constants
HIGH() and LOW() only worked with labels and register pairs.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-22 21:23:25 +00:00
Antonio Niño Díaz
8ea3669a64 Merge pull request #235 from obskyr/rgbgfx-color
Add color support to rgbgfx (again)!

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-20 19:56:39 +00:00
obskyr
8fe5293077 Allow superfluous height for 1-tile-wide images
Currently used here and there for small, icon-like tiles, it seems.

Signed-off-by: obskyr <powpowd@gmail.com>
2018-02-20 10:06:33 +01:00
obskyr
825fa915ee Fix rgbgfx's code style
Signed-off-by: obskyr <powpowd@gmail.com>
2018-02-20 10:06:00 +01:00
obskyr
885e8ea24a Add to contributor list
Signed-off-by: obskyr <powpowd@gmail.com>
2018-02-20 09:35:07 +01:00
obskyr
898f75ce57 Clarify and update rgbgfx documentation
Signed-off-by: obskyr <powpowd@gmail.com>
2018-02-20 09:35:00 +01:00
obskyr
b8af100c63 Handle grayscale images as expected
Signed-off-by: obskyr <powpowd@gmail.com>
2018-02-20 09:34:48 +01:00
obskyr
3075945367 Add color and transparency support to rgbgfx
In addition, fix various bugs.
Among them are minor memory issues and edge cases with certain inputs.

Signed-off-by: obskyr <powpowd@gmail.com>
2018-02-20 09:33:53 +01:00
Antonio Niño Díaz
d602ebfde5 Fix typo in rgblink manpage
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-02-18 19:57:02 +00:00
Antonio Niño Díaz
305512a2b7 Increase version number to 0.3.5
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-28 13:08:00 +00:00
Antonio Niño Díaz
a6b244b12e Move version files out of extern folder
The folder extern is reserved for external contributions, not common
files.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-28 13:07:21 +00:00
Antonio Niño Díaz
ceabbeaa2f Fix linkerscript man page
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-27 17:25:21 +00:00
Antonio Niño Díaz
3995852cc5 Fix nit in rgbasm.5 man page
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-27 15:19:18 +00:00
Antonio Niño Díaz
9793bcba6f Fix local execution of run-tests.sh script
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-27 15:04:17 +00:00
Antonio Niño Díaz
0727eb4374 Add test to verify hex codes of all instructions
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-27 14:38:52 +00:00
Antonio Niño Díaz
f8f67fcbce Add external projects to Travis CI jobs
Small tests like the ones included in this repository are good to test
individual features, but it is also a good idea to test some real
projects.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-27 11:14:10 +00:00
Anthony J. Bentley
abeca2d305 Prefer snprintf to strncpy when outputting C strings
strncpy is designed to output to fixed‐width buffers, not C strings
(hence its weird null termination behavior). In this case it happens to
work correctly due to the length check but, for style reasons, I would
rather use snprintf. Especially in this case, where it shortens the
code a bit.
2018-01-27 01:22:58 +00:00
Antonio Niño Díaz
a7dc86001c Add note about the MIT License in CONTRIBUTING.rst
Also, LICENSE.rst doesn't have any special formatting now, so it has
been renamed to LICENSE.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-27 00:47:06 +00:00
Antonio Niño Díaz
c071586ae5 Remove dependency of reallocarray()
By removing this dependency, all of the code of this repository is
licensed under the MIT license.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-27 00:30:13 +00:00
Antonio Niño Díaz
c6187be210 Remove dependency of strlcpy()
There was only one place where `strlcpy` was still used.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-27 00:02:44 +00:00
Antonio Niño Díaz
f9f3bb7761 Remove dependency of strlcat()
There was only one place where `strlcat` was used, and `snprintf`
actually does a better job at what the code was trying to achieve.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-27 00:02:26 +00:00
Antonio Niño Díaz
1a5c423984 Relicense codebase under MIT license
With permission from the main authors [1], most of the code has been
relicensed under the MIT license.

SPDX license identifiers are used so that the license headers in source
code files aren't too large.

Add CONTRIBUTORS.rst file.

[1] https://github.com/rednex/rgbds/issues/128

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-26 22:59:02 +00:00
Antonio Niño Díaz
b382dffdec Split src/asm/charmap.c into two files
This way it is easier to identify the license of the code.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-26 22:55:13 +00:00
Antonio Niño Díaz
33e9eb098c Exclude html files from checkpatch
Also, fix 2 nits in the codebase.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-26 18:57:25 +00:00
Antonio Niño Díaz
e77ebfe38a Disable OSX builds in Travis CI
Travis seems to be having some problems with OSX builds, so it's better
to disable them temporarily.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-25 22:23:43 +00:00
Antonio Niño Díaz
698ed9d5fc Don't clean html files with make clean
Added a new target to remove html files: `cleanwwwman`.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-25 22:12:31 +00:00
Antonio Niño Díaz
b07a8501d6 Fix linkerscript linking errors
The problems were introduced by the following commits:

- 959bfe2a9d

- 975200834e

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-25 22:07:16 +00:00
Antonio Niño Díaz
f779e724e2 Fix typo in manpage
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-24 20:29:27 +00:00
Antonio Niño Díaz
494b98e46a Fix html doc file name
Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-24 20:29:09 +00:00
Antonio Niño Díaz
d1ff057889 Make clean target of Makefile clean html files
The html files generated with `make wwwman` weren't cleaned correctly
with `clean`.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-23 22:54:37 +00:00
Antonio Niño Díaz
292302c6d1 Move documentation to this repository
Modified Makefile wwwman target to output files inside docs/.

Modified .gitignore to allow *.html files.

Update README.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
2018-01-23 21:28:10 +00:00
99 changed files with 6919 additions and 1135 deletions

1
.gitignore vendored
View File

@@ -4,5 +4,4 @@ rgbfix
rgbgfx
*.o
*.exe
*.html
.checkpatch-camelcase.*

View File

@@ -2,15 +2,13 @@ language: c
sudo: required
install:
- ./.travis-deps.sh
- make
- sudo make install
os:
- linux
- osx
compiler:
- clang
- gcc
script:
- make
- sudo make install
after_success:
- pushd test/asm/ && ./test.sh && popd
- pushd test/link/ && ./test.sh && popd
- cd test
- ./run-tests.sh

View File

@@ -58,6 +58,11 @@ If you are going to work on a specific issue that involves a lot of work, it is
always a good idea to leave a message, just in case someone else is interested
but doesn't know that there's someone working on it.
Note that you must contribute all your changes under the MIT License. If you are
just modifying a file, you don't need to do anything (maybe update the copyright
years). If you are adding new files, you need to use the correct header with the
copyright and the reference to the MIT License.
1. Fork this repository.
2. Checkout the ``develop`` branch.

41
CONTRIBUTORS.rst Normal file
View File

@@ -0,0 +1,41 @@
Contributors to RGBDS
=====================
Original author
---------------
- Carsten Elton Sørensen <csoren@gmail.com>
Main contributors
-----------------
- Justin Lloyd <jlloyd@imf.la>
- Vegard Nossum <vegard.nossum@gmail.com>
- Anthony J. Bentley <anthony@anjbe.name>
- stag019 <stag019@gmail.com>
- Antonio Niño Díaz <antonio_nd@outlook.com>
Other contributors
------------------
- Ben10do
- Björn Höhrmann <bjoern@hoehrmann.de>
- Christophe Staïesse <chastai@skynet.be>
- The Musl C library <http://www.musl-libc.org>
- obskyr <powpowd@gmail.com>
- The OpenBSD Project <http://www.openbsd.org>
- Sanqui <gsanky@gmail.com>
- YamaArashi <shadow962@live.com>
- yenatch <yenatch@gmail.com>

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License
Copyright (c) 1997-2018, Carsten Sorensen 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
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.

View File

@@ -1,81 +0,0 @@
LICENSE
=======
Original code
-------------
Copyright (C) 1997 Carsten Sorensen <surfsmurf@matilde.demon.co.uk>
The ASMotor package (xAsm, xLink, RGBFix, examples and documentation) is
freeware and distributed as is. The author retains his copyright and right to
modify the specifications and operation of the software without notice.
In other words this means I encourage you to...
- use it for whatever purpose even professional work without me charging you a
penny
- copy it to another person (wholly or in part, though I'm sure he'd appreciate
the whole package) in whatever form you find suitable
- mass-distribute the ASMotor package if it is complete (xAsm, xLink, RGBFix and
documentation).
- contact me if you have any problems
This also means you can't...
- blame me for loss of profit, data, sleep, food or other nasty things through
the use or distribution of ASMotor. If you choose to use ASMotor you do so at
your own risk.
- expect me to be able to help you should you have a problem related or not to
ASMotor.
Otaku no Zoku's modifications
-----------------------------
Copyright (C) 1999 Justin Lloyd <jlloyd@imf.la> (?)
::
DO WHATEVER PUBLIC LICENSE*
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You can do whatever you want to with the work.
1. You cannot stop anybody from doing whatever they want to with the work.
2. You cannot revoke anybody elses DO WHATEVER PUBLIC LICENSE in the work.
This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the DO WHATEVER PUBLIC LICENSE
Software originally created by Justin Lloyd @ http://otakunozoku.com/
rgbds-linux
-----------
Copyright (C) 2009 Vegard Nossum <vegard.nossum@gmail.com>
Current
-------
rgbasm and rgblink are derived from Justin Lloyd's RGBDS.
rgbfix was rewritten from scratch by Anthony J. Bentley, and is released under
the ISC license; see the source file for the text of the license.
rgbgfx was written by stag019, and is released under the ISC license.
Some files of rgblink were written by Antonio Niño Díaz, and they are relased
under the ISC license. The affected files have the appropriate license in the
header of the file.
The UTF-8 decoder in src/asm/charmap.c was written by Björn Höhrmann and is
released under the MIT license. The remainder of charmap.c was written by
stag019, and is released under the ISC license.
extern/err.c is derived from the Musl C library, http://www.musl-libc.org, and
is released under the MIT license.
extern/reallocarray.c is derived from the OpenBSD Project,
http://www.openbsd.org, and is released under the ISC license.
extern/strl.c is derived from the OpenBSD Project, http://www.openbsd.org, and
is released under the BSD license.

View File

@@ -1,3 +1,11 @@
#
# This file is part of RGBDS.
#
# Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
#
# SPDX-License-Identifier: MIT
#
# User-defined variables
Q := @
@@ -49,11 +57,8 @@ rgbasm_obj := \
src/asm/rpn.o \
src/asm/symbol.o \
src/extern/err.o \
src/extern/reallocarray.o \
src/extern/strlcpy.o \
src/extern/strlcat.o \
src/extern/version.o
src/extern/utf8decoder.o \
src/version.o
src/asm/asmy.h: src/asm/asmy.c
src/asm/locallex.o src/asm/globlex.o src/asm/lexer.o: src/asm/asmy.h
@@ -71,7 +76,7 @@ rgblink_obj := \
src/link/script.o \
src/link/symbol.o \
src/extern/err.o \
src/extern/version.o
src/version.o
src/link/parser.h: src/link/parser.c
src/link/lexer.o: src/link/parser.h
@@ -79,14 +84,14 @@ src/link/lexer.o: src/link/parser.h
rgbfix_obj := \
src/fix/main.o \
src/extern/err.o \
src/extern/version.o
src/version.o
rgbgfx_obj := \
src/gfx/gb.o \
src/gfx/main.o \
src/gfx/makepng.o \
src/extern/err.o \
src/extern/version.o
src/version.o
rgbasm: ${rgbasm_obj}
$Q${CC} ${REALCFLAGS} -o $@ ${rgbasm_obj} -lm
@@ -114,17 +119,26 @@ rgbgfx: ${rgbgfx_obj}
.c.o:
$Q${CC} ${REALCFLAGS} ${PNGCFLAGS} -c -o $@ $<
# Target used to remove all files generated by other Makefile targets.
# Target used to remove all files generated by other Makefile targets, except
# for the html documentation.
clean:
$Q${RM} rgbds.7.html gbz80.7.html rgbds.5.html
$Q${RM} rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.1.html rgbasm.5.html
$Q${RM} rgblink rgblink.exe ${rgblink_obj} rgblink.1.html rgblink.5.html
$Q${RM} rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.1.html
$Q${RM} rgbgfx rgbgfx.exe ${rgbgfx_obj} rgbgfx.1.html
$Q${RM} rgbasm rgbasm.exe ${rgbasm_obj}
$Q${RM} rgblink rgblink.exe ${rgblink_obj}
$Q${RM} rgbfix rgbfix.exe ${rgbfix_obj}
$Q${RM} rgbgfx rgbgfx.exe ${rgbgfx_obj}
$Q${RM} src/asm/asmy.c src/asm/asmy.h
$Q${RM} src/link/lexer.c src/link/parser.c src/link/parser.h
# Target used to remove all html files generated by the wwwman target
cleanwwwman:
$Q${RM} docs/rgbds.7.html docs/gbz80.7.html docs/rgbds.5.html
$Q${RM} docs/rgbasm.1.html docs/rgbasm.5.html
$Q${RM} docs/rgblink.1.html docs/rgblink.5.html
$Q${RM} docs/rgbfix.1.html
$Q${RM} docs/rgbgfx.1.html
# Target used to install the binaries and man pages.
install: all
@@ -147,8 +161,8 @@ install: all
# Target used to check the coding style of the whole codebase. '.y' and '.l'
# files aren't checked, unfortunately...
checkcodebase:
$Qfor file in `git ls-files | grep -E '\.c|\.h'`; do \
${CHECKPATCH} -f "$$file"; \
$Qfor file in `git ls-files | grep -E '\.c|\.h' | grep -v '\.html'`; do \
${CHECKPATCH} -f "$$file"; \
done
# Target used to check the coding style of the patches from the upstream branch
@@ -166,18 +180,18 @@ checkpatch:
# Target for the project maintainer to easily create web manuals.
# It relies on mandoc: http://mdocml.bsd.lv
MANDOC := -Thtml -Ios=General -Oman=%N.%S.html -Ostyle=manual.css
MANDOC := -Thtml -Ios=General -Oman=%N.%S.html -Ostyle=mandoc.css
wwwman:
$Qmandoc ${MANDOC} src/rgbds.7 > rgbds.7.html
$Qmandoc ${MANDOC} src/gbz80.7 > gbz80.7.html
$Qmandoc ${MANDOC} src/rgbds.5 > rgbds.5.html
$Qmandoc ${MANDOC} src/asm/rgbasm.1 > rgbasm.1.html
$Qmandoc ${MANDOC} src/asm/rgbasm.5 > rgbasm.5.html
$Qmandoc ${MANDOC} src/fix/rgbfix.1 > rgbfix.1.html
$Qmandoc ${MANDOC} src/link/rgblink.1 > rgblink.1.html
$Qmandoc ${MANDOC} src/link/rgblink.5 > rgblink.5.html
$Qmandoc ${MANDOC} src/gfx/rgbgfx.1 > rgbgfx.1.html
$Qmandoc ${MANDOC} src/rgbds.7 > docs/rgbds.7.html
$Qmandoc ${MANDOC} src/gbz80.7 > docs/gbz80.7.html
$Qmandoc ${MANDOC} src/rgbds.5 > docs/rgbds.5.html
$Qmandoc ${MANDOC} src/asm/rgbasm.1 > docs/rgbasm.1.html
$Qmandoc ${MANDOC} src/asm/rgbasm.5 > docs/rgbasm.5.html
$Qmandoc ${MANDOC} src/fix/rgbfix.1 > docs/rgbfix.1.html
$Qmandoc ${MANDOC} src/link/rgblink.1 > docs/rgblink.1.html
$Qmandoc ${MANDOC} src/link/rgblink.5 > docs/rgblink.5.html
$Qmandoc ${MANDOC} src/gfx/rgbgfx.1 > docs/rgbgfx.1.html
# Targets for the project maintainer to easily create Windows exes.
# This is not for Windows users!

View File

@@ -12,12 +12,11 @@ for the Game Boy and Game Boy Color. It consists of:
This is a fork of the original RGBDS which aims to make the programs more like
other UNIX tools.
This toolchain is maintained on `GitHub <https://github.com/rednex/rgbds>`__, as
well as its `documentation <https://github.com/rednex/rednex.github.io>`__.
This toolchain is maintained on `GitHub <https://github.com/rednex/rgbds>`__.
The documentation of this toolchain can be viewed online
`here <https://rednex.github.io/>`__, it is generated from the man pages found
in this repository.
`here <https://rednex.github.io/rgbds/>`__, it is generated from the man pages
found in this repository.
1. Installing RGBDS
-------------------
@@ -171,3 +170,5 @@ This is the complete list of user-defined variables:
implementation of rgbds.
- 2017, Bentley's repository is moved to a neutral name.
- 2018, codebase relicensed under the MIT license.

1701
docs/gbz80.7.html Normal file

File diff suppressed because it is too large Load Diff

36
docs/index.html Normal file
View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>General Information</title>
<link rel="stylesheet" type="text/css" href="mandoc.css">
</head>
<body>
<h1>RGBDS — Rednex Game Boy Development System</h1>
<h2>Table of Contents</h2>
<ol>
<li>General information
<ul>
<li><a href="rgbds.7.html">RGBDS general information</a></li>
<li><a href="rgbds.5.html">RGBDS object file format</a></li>
</ul>
<li>Language description
<ul>
<li><a href="rgbasm.5.html">RGBASM language description</a></li>
<li><a href="rgblink.5.html">RGBLINK linkerscript language description</a></li>
<li><a href="gbz80.7.html">GBZ80 CPU instruction set description</a></li>
</ul>
<li>Command line usage
<ul>
<li><a href="rgbasm.1.html">RGBASM command-line usage</a></li>
<li><a href="rgblink.1.html">RGBLINK command-line usage</a></li>
<li><a href="rgbfix.1.html">RGBFIX command-line usage</a></li>
<li><a href="rgbgfx.1.html">RGBGFX command-line usage</a></li>
</ul>
</ol>
<h2 id="GitHub Repository">GitHub Repository:</h2>
<ul>
<li><a href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a></li>
</ul>
</body>

203
docs/mandoc.css Executable file
View File

@@ -0,0 +1,203 @@
/* $Id: mandoc.css,v 1.22 2017/07/16 18:45:00 schwarze Exp $ */
/*
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
*/
/* Global defaults. */
html { max-width: 100ex; }
body { font-family: Helvetica,Arial,sans-serif; }
table { margin-top: 0em;
margin-bottom: 0em; }
td { vertical-align: top; }
ul, ol, dl { margin-top: 0em;
margin-bottom: 0em; }
li, dt { margin-top: 1em; }
a.selflink { border-bottom: thin dotted;
color: inherit;
font: inherit;
text-decoration: inherit; }
* { clear: both }
/* Search form and search results. */
fieldset { border: thin solid silver;
border-radius: 1em;
text-align: center; }
input[name=expr] {
width: 25%; }
table.results { margin-top: 1em;
margin-left: 2em;
font-size: smaller; }
/* Header and footer lines. */
table.head { width: 100%;
border-bottom: 1px dotted #808080;
margin-bottom: 1em;
font-size: smaller; }
td.head-vol { text-align: center; }
td.head-rtitle {
text-align: right; }
span.Nd { }
table.foot { width: 100%;
border-top: 1px dotted #808080;
margin-top: 1em;
font-size: smaller; }
td.foot-os { text-align: right; }
/* Sections and paragraphs. */
div.manual-text {
margin-left: 5ex; }
h1.Sh { margin-top: 2ex;
margin-bottom: 1ex;
margin-left: -4ex;
font-size: 110%; }
h2.Ss { margin-top: 2ex;
margin-bottom: 1ex;
margin-left: -2ex;
font-size: 105%; }
div.Pp { margin: 1ex 0ex; }
a.Sx { }
a.Xr { }
/* Displays and lists. */
div.Bd { }
div.D1 { margin-left: 5ex; }
ul.Bl-bullet { list-style-type: disc;
padding-left: 1em; }
li.It-bullet { }
ul.Bl-dash { list-style-type: none;
padding-left: 0em; }
li.It-dash:before {
content: "\2014 "; }
ul.Bl-item { list-style-type: none;
padding-left: 0em; }
li.It-item { }
ul.Bl-compact > li {
margin-top: 0ex; }
ol.Bl-enum { padding-left: 2em; }
li.It-enum { }
ol.Bl-compact > li {
margin-top: 0ex; }
dl.Bl-diag { }
dt.It-diag { }
dd.It-diag { margin-left: 0ex; }
b.It-diag { font-style: normal; }
dl.Bl-hang { }
dt.It-hang { }
dd.It-hang { margin-left: 10.2ex; }
dl.Bl-inset { }
dt.It-inset { }
dd.It-inset { margin-left: 0ex; }
dl.Bl-ohang { }
dt.It-ohang { }
dd.It-ohang { margin-left: 0ex; }
dl.Bl-tag { margin-left: 10.2ex; }
dt.It-tag { float: left;
margin-top: 0ex;
margin-left: -10.2ex;
padding-right: 2ex;
vertical-align: top; }
dd.It-tag { clear: right;
width: 100%;
margin-top: 0ex;
margin-left: 0ex;
vertical-align: top;
overflow: auto; }
dl.Bl-compact > dt {
margin-top: 0ex; }
table.Bl-column { }
tr.It-column { }
td.It-column { margin-top: 1em; }
table.Bl-compact > tbody > tr > td {
margin-top: 0ex; }
cite.Rs { font-style: normal;
font-weight: normal; }
span.RsA { }
i.RsB { font-weight: normal; }
span.RsC { }
span.RsD { }
i.RsI { font-weight: normal; }
i.RsJ { font-weight: normal; }
span.RsN { }
span.RsO { }
span.RsP { }
span.RsQ { }
span.RsR { }
span.RsT { text-decoration: underline; }
a.RsU { }
span.RsV { }
span.eqn { }
table.tbl { }
/* Semantic markup for command line utilities. */
table.Nm { }
b.Nm { font-style: normal; }
b.Fl { font-style: normal; }
b.Cm { font-style: normal; }
var.Ar { font-style: italic;
font-weight: normal; }
span.Op { }
b.Ic { font-style: normal; }
code.Ev { font-style: normal;
font-weight: normal;
font-family: monospace; }
i.Pa { font-weight: normal; }
/* Semantic markup for function libraries. */
span.Lb { }
b.In { font-style: normal; }
a.In { }
b.Fd { font-style: normal; }
var.Ft { font-style: italic;
font-weight: normal; }
b.Fn { font-style: normal; }
var.Fa { font-style: italic;
font-weight: normal; }
var.Vt { font-style: italic;
font-weight: normal; }
var.Va { font-style: italic;
font-weight: normal; }
code.Dv { font-style: normal;
font-weight: normal;
font-family: monospace; }
code.Er { font-style: normal;
font-weight: normal;
font-family: monospace; }
/* Various semantic markup. */
span.An { }
a.Lk { }
a.Mt { }
b.Cd { font-style: normal; }
i.Ad { font-weight: normal; }
b.Ms { font-style: normal; }
span.St { }
a.Ux { }
/* Physical markup. */
.No { font-style: normal;
font-weight: normal; }
.Em { font-style: italic;
font-weight: normal; }
.Sy { font-style: normal;
font-weight: bold; }
.Li { font-style: normal;
font-weight: normal;
font-family: monospace; }

157
docs/rgbasm.1.html Normal file
View File

@@ -0,0 +1,157 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
table.head, table.foot { width: 100%; }
td.head-rtitle, td.foot-os { text-align: right; }
td.head-vol { text-align: center; }
div.Pp { margin: 1ex 0ex; }
</style>
<link rel="stylesheet" href="mandoc.css" type="text/css" media="all"/>
<title>RGBASM(1)</title>
</head>
<body>
<table class="head">
<tr>
<td class="head-ltitle">RGBASM(1)</td>
<td class="head-vol">General Commands Manual</td>
<td class="head-rtitle">RGBASM(1)</td>
</tr>
</table>
<div class="manual-text">
<h1 class="Sh" title="Sh" id="NAME"><a class="selflink" href="#NAME">NAME</a></h1>
<b class="Nm" title="Nm">rgbasm</b> &#x2014; <span class="Nd" title="Nd">Game
Boy assembler</span>
<h1 class="Sh" title="Sh" id="SYNOPSIS"><a class="selflink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<table class="Nm">
<tr>
<td><b class="Nm" title="Nm">rgbasm</b></td>
<td>[<span class="Op"><b class="Fl" title="Fl">-EhLVvw</b></span>]
[<span class="Op"><b class="Fl" title="Fl">-b</b>
<var class="Ar" title="Ar">chars</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-D</b>
<var class="Ar" title="Ar">name</var>[<span class="Op">=<var class="Ar" title="Ar">value</var></span>]</span>]
[<span class="Op"><b class="Fl" title="Fl">-g</b>
<var class="Ar" title="Ar">chars</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-i</b>
<var class="Ar" title="Ar">path</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-M</b>
<var class="Ar" title="Ar">dependfile</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-o</b>
<var class="Ar" title="Ar">outfile</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-p</b>
<var class="Ar" title="Ar">pad_value</var></span>]
<var class="Ar" title="Ar">file</var></td>
</tr>
</table>
<h1 class="Sh" title="Sh" id="DESCRIPTION"><a class="selflink" href="#DESCRIPTION">DESCRIPTION</a></h1>
The <b class="Nm" title="Nm">rgbasm</b> program creates an object file from an
assembly source file. Its arguments are as follows:
<dl class="Bl-tag">
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#b"><b class="Fl" title="Fl" id="b">-b</b></a>
<var class="Ar" title="Ar">chars</var></dt>
<dd class="It-tag">Change the two characters used for binary constants. The
defaults are 01.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#D"><b class="Fl" title="Fl" id="D">-D</b></a>
<var class="Ar" title="Ar">name</var>[<span class="Op">=<var class="Ar" title="Ar">value</var></span>]</dt>
<dd class="It-tag">Add string symbol to the compiled source code. This is
equivalent to <var class="Ar" title="Ar">name</var>
<b class="Cm" title="Cm">EQUS</b>
&#x201C;<var class="Ar" title="Ar">value</var>&#x201D; in code. If a value
is not specified, a value of 1 is given.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#E"><b class="Fl" title="Fl" id="E">-E</b></a></dt>
<dd class="It-tag">Export all labels, including unreferenced and local
labels.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#g"><b class="Fl" title="Fl" id="g">-g</b></a>
<var class="Ar" title="Ar">chars</var></dt>
<dd class="It-tag">Change the four characters used for binary constants. The
defaults are 0123.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#h"><b class="Fl" title="Fl" id="h">-h</b></a></dt>
<dd class="It-tag">By default, <b class="Nm" title="Nm">rgbasm</b> inserts a
&#x2018;nop&#x2019; instruction immediately after any &#x2018;halt&#x2019;
instruction. The <b class="Fl" title="Fl">-h</b> option disables this
behavior.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#i"><b class="Fl" title="Fl" id="i">-i</b></a>
<var class="Ar" title="Ar">path</var></dt>
<dd class="It-tag">Add an include path.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#L"><b class="Fl" title="Fl" id="L">-L</b></a></dt>
<dd class="It-tag">Disable the optimization that turns loads of the form
<b class="Sy" title="Sy">LD [$FF00+n8],A</b> into the opcode
<b class="Sy" title="Sy">LDH [$FF00+n8],A</b> in order to have full
control of the result in the final ROM.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#M"><b class="Fl" title="Fl" id="M">-M</b></a>
<var class="Ar" title="Ar">dependfile</var></dt>
<dd class="It-tag">Print <a class="Xr" title="Xr">make(1)</a> dependencies to
<var class="Ar" title="Ar">dependfile</var>.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#o"><b class="Fl" title="Fl" id="o">-o</b></a>
<var class="Ar" title="Ar">outfile</var></dt>
<dd class="It-tag">Write an object file to the given filename.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#p"><b class="Fl" title="Fl" id="p">-p</b></a>
<var class="Ar" title="Ar">pad_value</var></dt>
<dd class="It-tag">When padding an image, pad with this value. The default is
0x00.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#V"><b class="Fl" title="Fl" id="V">-V</b></a></dt>
<dd class="It-tag">Print the version of the program and exit.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#v"><b class="Fl" title="Fl" id="v">-v</b></a></dt>
<dd class="It-tag">Be verbose.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#w"><b class="Fl" title="Fl" id="w">-w</b></a></dt>
<dd class="It-tag">Disable warning output.</dd>
</dl>
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
Assembling a basic source file is simple:
<div class="Pp"></div>
<div class="Bd" style="margin-left: 5.00ex;">
<pre class="Li">
$ rgbasm -o bar.o foo.asm
</pre>
</div>
<div class="Pp"></div>
The resulting object file is not yet a usable ROM image &#x2014; it must first
be run through <a class="Xr" title="Xr">rgblink(1)</a> and
<a class="Xr" title="Xr">rgbfix(1)</a>.
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<a class="Xr" title="Xr">rgbasm(5)</a>, <a class="Xr" title="Xr">rgbfix(1)</a>,
<a class="Xr" title="Xr">rgblink(1)</a>,
<a class="Xr" title="Xr">rgbds(5)</a>, <a class="Xr" title="Xr">rgbds(7)</a>,
<a class="Xr" title="Xr">gbz80(7)</a>
<h1 class="Sh" title="Sh" id="HISTORY"><a class="selflink" href="#HISTORY">HISTORY</a></h1>
<b class="Nm" title="Nm">rgbasm</b> was originally written by Carsten
S&#x00F8;rensen as part of the ASMotor package, and was later packaged in
RGBDS by Justin Lloyd. It is now maintained by a number of contributors at
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
<table class="foot">
<tr>
<td class="foot-date">February 24, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</table>
</body>
</html>

1599
docs/rgbasm.5.html Normal file

File diff suppressed because it is too large Load Diff

307
docs/rgbds.5.html Normal file
View File

@@ -0,0 +1,307 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
table.head, table.foot { width: 100%; }
td.head-rtitle, td.foot-os { text-align: right; }
td.head-vol { text-align: center; }
div.Pp { margin: 1ex 0ex; }
</style>
<link rel="stylesheet" href="mandoc.css" type="text/css" media="all"/>
<title>RGBDS(5)</title>
</head>
<body>
<table class="head">
<tr>
<td class="head-ltitle">RGBDS(5)</td>
<td class="head-vol">File Formats Manual</td>
<td class="head-rtitle">RGBDS(5)</td>
</tr>
</table>
<div class="manual-text">
<h1 class="Sh" title="Sh" id="NAME"><a class="selflink" href="#NAME">NAME</a></h1>
<b class="Nm" title="Nm">rgbds</b> &#x2014; <span class="Nd" title="Nd">object
file format documentation</span>
<h1 class="Sh" title="Sh" id="DESCRIPTION"><a class="selflink" href="#DESCRIPTION">DESCRIPTION</a></h1>
This is the description of the object files used by
<a class="Xr" title="Xr">rgbasm(1)</a> and
<a class="Xr" title="Xr">rgblink(1)</a>. 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.
<h1 class="Sh" title="Sh" id="FILE_STRUCTURE"><a class="selflink" href="#FILE_STRUCTURE">FILE
STRUCTURE</a></h1>
The following types are used:
<div class="Pp"></div>
<var class="Ar" title="Ar">LONG</var> is a 32&#x2010;bit integer stored in
little&#x2010;endian format (Intel). <var class="Ar" title="Ar">BYTE</var> is
an 8&#x2010;bit integer. <var class="Ar" title="Ar">STRING</var> is a
0&#x2010;terminated string of <var class="Ar" title="Ar">BYTE</var>.
<div class="Pp"></div>
<div class="Bd" style="margin-left: 0.00ex;">
<pre class="Li">
; Header
BYTE ID[4] ; &quot;RGB6&quot;
LONG NumberOfSymbols ; The number of symbols used in this file
LONG NumberOfSections ; The number of sections used in this file
; Symbols
REPT NumberOfSymbols ; Number of symbols defined in this object file.
STRING Name ; The name of this symbol. Local symbols are stored
; as &quot;Scope.Symbol&quot;.
BYTE Type ; 0 = LOCAL symbol only used in this file.
; 1 = IMPORT this symbol from elsewhere (unused).
; 2 = EXPORT this symbol to other objects.
IF Type != 1 ; If symbol is defined in this object file.
STRING FileName ; 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.
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
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.
LONG Align ; Alignment of this section (expressed as number of low bits
; to leave as 0). -1 if not defined.
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.
; These types of sections may have patches
REPT NumberOfPatches
STRING SourceFile ; Name of the source file (for printing error
; messages).
LONG Line ; The line of the source file.
LONG Offset ; Offset into the section where patch should
; be applied (in bytes).
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
</pre>
</div>
<h2 class="Ss" title="Ss" id="RPN_DATA"><a class="selflink" href="#RPN_DATA">RPN
DATA</a></h2>
Expressions in the object file are stored as RPN. This is an expression of the
form &#x201C;2 5 +&#x201D;. This will first push the value &#x201C;2&#x201D;
to the stack. Then &#x201C;5&#x201D;. The &#x201C;+&#x201D; 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 BYTEs with some bytes being special prefixes for
integers and symbols.
<table class="Bl-column" style="margin-left: 6.00ex;">
<colgroup>
<col style="width: 15.00ex;"/>
<col style="min-width: 10.00ex;"/>
</colgroup>
<tr class="It-column">
<td class="It-column"><b class="Sy" title="Sy">Value</b></td>
<td class="It-column"><b class="Sy" title="Sy">Meaning</b></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$00"><code class="Li" id="$00">$00</code></a></td>
<td class="It-column"><a class="selflink" href="#+_operator"><code class="Li" id="+_operator">+
operator</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$01"><code class="Li" id="$01">$01</code></a></td>
<td class="It-column"><a class="selflink" href="#-_operator"><code class="Li" id="-_operator">-
operator</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$02"><code class="Li" id="$02">$02</code></a></td>
<td class="It-column"><a class="selflink" href="#*_operator"><code class="Li" id="*_operator">*
operator</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$03"><code class="Li" id="$03">$03</code></a></td>
<td class="It-column"><a class="selflink" href="#/_operator"><code class="Li" id="/_operator">/
operator</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$04"><code class="Li" id="$04">$04</code></a></td>
<td class="It-column"><a class="selflink" href="#%_operator"><code class="Li" id="%_operator">%
operator</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$05"><code class="Li" id="$05">$05</code></a></td>
<td class="It-column"><a class="selflink" href="#unary_-"><code class="Li" id="unary_-">unary
-</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$10"><code class="Li" id="$10">$10</code></a></td>
<td class="It-column">|
<a class="selflink" href="#operator"><code class="Li" id="operator">operator</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$11"><code class="Li" id="$11">$11</code></a></td>
<td class="It-column"><a class="selflink" href="#&amp;_operator"><code class="Li" id="&amp;_operator">&amp;
operator</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$12"><code class="Li" id="$12">$12</code></a></td>
<td class="It-column"><a class="selflink" href="#^_operator"><code class="Li" id="^_operator">^
operator</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$13"><code class="Li" id="$13">$13</code></a></td>
<td class="It-column"><a class="selflink" href="#unary_~"><code class="Li" id="unary_~">unary
~</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$21"><code class="Li" id="$21">$21</code></a></td>
<td class="It-column"><a class="selflink" href="#&amp;&amp;_comparison"><code class="Li" id="&amp;&amp;_comparison">&amp;&amp;
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$22"><code class="Li" id="$22">$22</code></a></td>
<td class="It-column"><a class="selflink" href="#||_comparison"><code class="Li" id="||_comparison">||
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$23"><code class="Li" id="$23">$23</code></a></td>
<td class="It-column"><a class="selflink" href="#unary"><code class="Li" id="unary">unary</code></a>!</td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$30"><code class="Li" id="$30">$30</code></a></td>
<td class="It-column"><a class="selflink" href="#==_comparison"><code class="Li" id="==_comparison">==
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$31"><code class="Li" id="$31">$31</code></a></td>
<td class="It-column"><a class="selflink" href="#!=_comparison"><code class="Li" id="!=_comparison">!=
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$32"><code class="Li" id="$32">$32</code></a></td>
<td class="It-column"><a class="selflink" href="#&gt;_comparison"><code class="Li" id="&gt;_comparison">&gt;
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$33"><code class="Li" id="$33">$33</code></a></td>
<td class="It-column"><a class="selflink" href="#&lt;_comparison"><code class="Li" id="&lt;_comparison">&lt;
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$34"><code class="Li" id="$34">$34</code></a></td>
<td class="It-column"><a class="selflink" href="#&gt;=_comparison"><code class="Li" id="&gt;=_comparison">&gt;=
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$35"><code class="Li" id="$35">$35</code></a></td>
<td class="It-column"><a class="selflink" href="#&lt;=_comparison"><code class="Li" id="&lt;=_comparison">&lt;=
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$40"><code class="Li" id="$40">$40</code></a></td>
<td class="It-column"><a class="selflink" href="#&lt;&lt;_comparison"><code class="Li" id="&lt;&lt;_comparison">&lt;&lt;
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$41"><code class="Li" id="$41">$41</code></a></td>
<td class="It-column"><a class="selflink" href="#&gt;&gt;_comparison"><code class="Li" id="&gt;&gt;_comparison">&gt;&gt;
comparison</code></a></td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$50"><code class="Li" id="$50">$50</code></a></td>
<td class="It-column"><a class="selflink" href="#BANK(symbol),"><code class="Li" id="BANK(symbol),">BANK(symbol),</code></a>
a <var class="Ar" title="Ar">LONG</var> Symbol ID follows.</td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$51"><code class="Li" id="$51">$51</code></a></td>
<td class="It-column"><a class="selflink" href="#BANK(section_name),"><code class="Li" id="BANK(section_name),">BANK(section_name),</code></a>
a null-terminated string follows.</td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$52"><code class="Li" id="$52">$52</code></a></td>
<td class="It-column"><a class="selflink" href="#Current_BANK()"><code class="Li" id="Current_BANK()">Current
BANK()</code></a>.</td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$60"><code class="Li" id="$60">$60</code></a></td>
<td class="It-column"><a class="selflink" href="#HRAMCheck."><code class="Li" id="HRAMCheck.">HRAMCheck.</code></a>
Check if the value is in HRAM, AND it with 0xFF.</td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$80"><code class="Li" id="$80">$80</code></a></td>
<td class="It-column"><var class="Ar" title="Ar">LONG</var> integer
follows.</td>
</tr>
<tr class="It-column">
<td class="It-column"><a class="selflink" href="#$81"><code class="Li" id="$81">$81</code></a></td>
<td class="It-column"><var class="Ar" title="Ar">LONG</var> Symbol ID
follows.</td>
</tr>
</table>
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<a class="Xr" title="Xr">rgbasm(1)</a>, <a class="Xr" title="Xr">rgblink(1)</a>,
<a class="Xr" title="Xr">rgbds(7)</a>, <a class="Xr" title="Xr">gbz80(7)</a>
<h1 class="Sh" title="Sh" id="HISTORY"><a class="selflink" href="#HISTORY">HISTORY</a></h1>
<b class="Nm" title="Nm">rgbds</b> was originally written by Carsten
S&#x00F8;rensen as part of the ASMotor package, and was later packaged in
RGBDS by Justin Lloyd. It is now maintained by a number of contributors at
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
<table class="foot">
<tr>
<td class="foot-date">January 26, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</table>
</body>
</html>

71
docs/rgbds.7.html Normal file
View File

@@ -0,0 +1,71 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
table.head, table.foot { width: 100%; }
td.head-rtitle, td.foot-os { text-align: right; }
td.head-vol { text-align: center; }
div.Pp { margin: 1ex 0ex; }
</style>
<link rel="stylesheet" href="mandoc.css" type="text/css" media="all"/>
<title>RGBDS(7)</title>
</head>
<body>
<table class="head">
<tr>
<td class="head-ltitle">RGBDS(7)</td>
<td class="head-vol">Miscellaneous Information Manual</td>
<td class="head-rtitle">RGBDS(7)</td>
</tr>
</table>
<div class="manual-text">
<h1 class="Sh" title="Sh" id="NAME"><a class="selflink" href="#NAME">NAME</a></h1>
<b class="Nm" title="Nm">rgbds</b> &#x2014; <span class="Nd" title="Nd">Rednex
Game Boy Development System</span>
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
To get a working ROM image from a single assembly source file:
<div class="Pp"></div>
<div class="Bd" style="margin-left: 5.00ex;">
<pre class="Li">
$ rgbasm -o bar.o foo.asm
$ rgblink -o baz.gb bar.o
$ rgbfix -v -p 0 baz.gb
</pre>
</div>
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<a class="Xr" title="Xr">rgbasm(1)</a>, <a class="Xr" title="Xr">rgbfix(1)</a>,
<a class="Xr" title="Xr">rgblink(1)</a>,
<a class="Xr" title="Xr">rgbds(5)</a>, <a class="Xr" title="Xr">gbz80(7)</a>
<h1 class="Sh" title="Sh" id="HISTORY"><a class="selflink" href="#HISTORY">HISTORY</a></h1>
<dl class="Bl-ohang">
<dt class="It-ohang"></dt>
<dd class="It-ohang">1997, Carsten S&#x00F8;rensen (AKA SurfSmurf) writes
ASMotor as a general-purpose assembler/linker system for DOS/Win32.</dd>
<dt class="It-ohang"></dt>
<dd class="It-ohang">1999, Justin Lloyd (AKA Otaku no Zoku) adapts ASMotor to
read and produce GBZ80 assembly/machine code, and releases this version as
RGBDS.</dd>
<dt class="It-ohang"></dt>
<dd class="It-ohang">2009, Vegard Nossum adapts the code to be more UNIX-like
and releases this version as rgbds-linux on GitHub.</dd>
<dt class="It-ohang"></dt>
<dd class="It-ohang">2010, Anthony J. Bentley forks that repository. The fork
becomes the reference implementation of rgbds.</dd>
<dt class="It-ohang"></dt>
<dd class="It-ohang">2017, Bentley's repository is moved to a neutral name. It
is now maintained by a number of contributors at
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</dd>
<dt class="It-ohang"></dt>
<dd class="It-ohang">2018, codebase relicensed under the MIT license.</dd>
</dl>
</div>
<table class="foot">
<tr>
<td class="foot-date">March 7, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</table>
</body>
</html>

213
docs/rgbfix.1.html Normal file
View File

@@ -0,0 +1,213 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
table.head, table.foot { width: 100%; }
td.head-rtitle, td.foot-os { text-align: right; }
td.head-vol { text-align: center; }
div.Pp { margin: 1ex 0ex; }
</style>
<link rel="stylesheet" href="mandoc.css" type="text/css" media="all"/>
<title>RGBFIX(1)</title>
</head>
<body>
<table class="head">
<tr>
<td class="head-ltitle">RGBFIX(1)</td>
<td class="head-vol">General Commands Manual</td>
<td class="head-rtitle">RGBFIX(1)</td>
</tr>
</table>
<div class="manual-text">
<h1 class="Sh" title="Sh" id="NAME"><a class="selflink" href="#NAME">NAME</a></h1>
<b class="Nm" title="Nm">rgbfix</b> &#x2014; <span class="Nd" title="Nd">Game
Boy checksum fixer</span>
<h1 class="Sh" title="Sh" id="SYNOPSIS"><a class="selflink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<table class="Nm">
<tr>
<td><b class="Nm" title="Nm">rgbfix</b></td>
<td>[<span class="Op"><b class="Fl" title="Fl">-CcjsVv</b></span>]
[<span class="Op"><b class="Fl" title="Fl">-f</b>
<var class="Ar" title="Ar">fix_spec</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-i</b>
<var class="Ar" title="Ar">game_id</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-k</b>
<var class="Ar" title="Ar">licensee_str</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-l</b>
<var class="Ar" title="Ar">licensee_id</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-m</b>
<var class="Ar" title="Ar">mbc_type</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-n</b>
<var class="Ar" title="Ar">rom_version</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-p</b>
<var class="Ar" title="Ar">pad_value</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-r</b>
<var class="Ar" title="Ar">ram_size</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-t</b>
<var class="Ar" title="Ar">title_str</var></span>]
<var class="Ar" title="Ar">file</var></td>
</tr>
</table>
<h1 class="Sh" title="Sh" id="DESCRIPTION"><a class="selflink" href="#DESCRIPTION">DESCRIPTION</a></h1>
The <b class="Nm" title="Nm">rgbfix</b> program changes headers of Game Boy ROM
images. It also performs other filetype operations, such as truncation. The
arguments are as follows:
<dl class="Bl-tag">
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#C"><b class="Fl" title="Fl" id="C">-C</b></a></dt>
<dd class="It-tag">Set the Game Boy Color&#x2013;only flag:
<i class="Ad">0x143</i> = 0xC0. If both this and the
<b class="Fl" title="Fl">-c</b> flag are set, this takes precedence.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#c"><b class="Fl" title="Fl" id="c">-c</b></a></dt>
<dd class="It-tag">Set the Game Boy Color&#x2013;compatible flag:
<i class="Ad">0x143</i> = 0x80. If both this and the
<b class="Fl" title="Fl">-C</b> flag are set,
<b class="Fl" title="Fl">-C</b> takes precedence.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#f"><b class="Fl" title="Fl" id="f">-f</b></a>
<var class="Ar" title="Ar">fix_spec</var></dt>
<dd class="It-tag">Fix certain header values that the Game Boy checks for
correctness. Alternatively, intentionally trash these values by writing
their binary inverse instead. <var class="Ar" title="Ar">fix_spec</var> is
a string containing any combination of the following characters:
<div class="Pp"></div>
<dl class="Bl-tag Bl-compact" style="margin-left: 5.40ex;">
<dt class="It-tag" style="margin-left: -5.40ex;"><a class="selflink" href="#l"><b class="Cm" title="Cm" id="l">l</b></a></dt>
<dd class="It-tag">Fix the Nintendo logo
(<i class="Ad">0x104</i>&#x2013;<i class="Ad">0x133</i>).</dd>
<dt class="It-tag" style="margin-left: -5.40ex;"><a class="selflink" href="#L"><b class="Cm" title="Cm" id="L">L</b></a></dt>
<dd class="It-tag">Trash the Nintendo logo.</dd>
<dt class="It-tag" style="margin-left: -5.40ex;"><a class="selflink" href="#h"><b class="Cm" title="Cm" id="h">h</b></a></dt>
<dd class="It-tag">Fix the header checksum (<i class="Ad">0x14D</i>).</dd>
<dt class="It-tag" style="margin-left: -5.40ex;"><a class="selflink" href="#H"><b class="Cm" title="Cm" id="H">H</b></a></dt>
<dd class="It-tag">Trash the header checksum.</dd>
<dt class="It-tag" style="margin-left: -5.40ex;"><a class="selflink" href="#g"><b class="Cm" title="Cm" id="g">g</b></a></dt>
<dd class="It-tag">Fix the global checksum
(<i class="Ad">0x14E</i>&#x2013;<i class="Ad">0x14F</i>).</dd>
<dt class="It-tag" style="margin-left: -5.40ex;"><a class="selflink" href="#G"><b class="Cm" title="Cm" id="G">G</b></a></dt>
<dd class="It-tag">Trash the global checksum.</dd>
</dl>
</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#i"><b class="Fl" title="Fl" id="i">-i</b></a>
<var class="Ar" title="Ar">game_id</var></dt>
<dd class="It-tag">Set the game ID string
(<i class="Ad">0x13F</i>&#x2013;<i class="Ad">0x142</i>) to a given string
of exactly 4 characters. If both this and the title are set, the game ID
will overwrite the overlapping portion of the title.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#j"><b class="Fl" title="Fl" id="j">-j</b></a></dt>
<dd class="It-tag">Set the non-Japanese region flag: <i class="Ad">0x14A</i> =
1.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#k"><b class="Fl" title="Fl" id="k">-k</b></a>
<var class="Ar" title="Ar">licensee_str</var></dt>
<dd class="It-tag">Set the new licensee string
(<i class="Ad">0x144</i>&#x2013;<i class="Ad">0x145</i>) to a given
string, truncated to at most two characters.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#l"><b class="Fl" title="Fl" id="l">-l</b></a>
<var class="Ar" title="Ar">licensee_id</var></dt>
<dd class="It-tag">Set the old licensee code, <i class="Ad">0x14B</i>, to a
given value from 0 to 0xFF. This value is deprecated and should be set to
0x33 in all new software.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#m"><b class="Fl" title="Fl" id="m">-m</b></a>
<var class="Ar" title="Ar">mbc_type</var></dt>
<dd class="It-tag">Set the MBC type, <i class="Ad">0x147</i>, to a given value
from 0 to 0xFF.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#n"><b class="Fl" title="Fl" id="n">-n</b></a>
<var class="Ar" title="Ar">rom_version</var></dt>
<dd class="It-tag">Set the ROM version, <i class="Ad">0x14C</i>, to a given
value from 0 to 0xFF.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#p"><b class="Fl" title="Fl" id="p">-p</b></a>
<var class="Ar" title="Ar">pad_value</var></dt>
<dd class="It-tag">Pad the image to a valid size with a given pad value from 0
to 0xFF. <b class="Nm" title="Nm">rgbfix</b> will automatically pick a
size from 32KiB, 64KiB, 128KiB, ..., 8192KiB and give a warning
thereafter. The cartridge size byte (<i class="Ad">0x148</i>) will be
changed to reflect this new size.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#r"><b class="Fl" title="Fl" id="r">-r</b></a>
<var class="Ar" title="Ar">ram_size</var></dt>
<dd class="It-tag">Set the RAM size, <i class="Ad">0x149</i>, to a given value
from 0 to 0xFF.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#s"><b class="Fl" title="Fl" id="s">-s</b></a></dt>
<dd class="It-tag">Set the SGB flag: <i class="Ad">0x146</i> = 3.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#t"><b class="Fl" title="Fl" id="t">-t</b></a>
<var class="Ar" title="Ar">title</var></dt>
<dd class="It-tag">Set the title string
(<i class="Ad">0x134</i>&#x2013;<i class="Ad">0x143</i>) to a given
string, truncated to at most 16 characters. It is recommended to use 15
characters instead, to avoid clashing with the CGB flag
(<b class="Fl" title="Fl">-c</b> or <b class="Fl" title="Fl">-C</b>). If
both this and the game ID are set, the game ID will overwrite the
overlapping portion of the title.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#V"><b class="Fl" title="Fl" id="V">-V</b></a></dt>
<dd class="It-tag">Print the version of the program and exit.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#v"><b class="Fl" title="Fl" id="v">-v</b></a></dt>
<dd class="It-tag">Equivalent to <b class="Fl" title="Fl">-f</b>
<b class="Cm" title="Cm">lhg</b>.</dd>
</dl>
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
Most values in the ROM header are only cosmetic. The bare minimum requirements
for a workable image are checksums, the Nintendo logo, and (if needed) the
CGB/SGB flags. It is a good idea to pad the image to a valid size as well
(&#x201C;valid&#x201D; meaning a multiple of 32KiB).
<div class="Pp"></div>
The following will make a plain, no-color Game Boy game without checking for a
valid size:
<div class="Pp"></div>
<div class="D1">$ rgbfix -v foo.gb</div>
<div class="Pp"></div>
The following will make a SGB-enabled, color-enabled game with a title of
&#x201C;foobar&#x201D;, and pad it to a multiple of 32KiB. (The Game Boy
itself does not use the title, but some emulators or ROM managers might.)
<div class="Pp"></div>
<div class="D1">$ rgbfix -vcs -l 0x33 -p 0 -t foobar baz.gb</div>
<div class="Pp"></div>
The following will duplicate the header (sans global checksum) of the game
&#x201C;Survival Kids&#x201D;:
<div class="Pp"></div>
<div class="D1">$ rgbfix -cjsv -k A4 -l 0x33 -m 0x1B -p 0xFF -r 3 -t
SURVIVALKIDAVKE SurvivalKids.gbc</div>
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<a class="Xr" title="Xr">rgbasm(1)</a>, <a class="Xr" title="Xr">rgblink(1)</a>,
<a class="Xr" title="Xr">rgbds(7)</a>
<h1 class="Sh" title="Sh" id="HISTORY"><a class="selflink" href="#HISTORY">HISTORY</a></h1>
<b class="Nm" title="Nm">rgbfix</b> was originally released by Carsten
S&#x00F8;rensen as a standalone program called gbfix, and was later packaged
in RGBDS by Justin Lloyd. It is now maintained by a number of contributors at
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
<table class="foot">
<tr>
<td class="foot-date">March 11, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</table>
</body>
</html>

175
docs/rgbgfx.1.html Normal file
View File

@@ -0,0 +1,175 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
table.head, table.foot { width: 100%; }
td.head-rtitle, td.foot-os { text-align: right; }
td.head-vol { text-align: center; }
div.Pp { margin: 1ex 0ex; }
</style>
<link rel="stylesheet" href="mandoc.css" type="text/css" media="all"/>
<title>RGBGFX(1)</title>
</head>
<body>
<table class="head">
<tr>
<td class="head-ltitle">RGBGFX(1)</td>
<td class="head-vol">General Commands Manual</td>
<td class="head-rtitle">RGBGFX(1)</td>
</tr>
</table>
<div class="manual-text">
<h1 class="Sh" title="Sh" id="NAME"><a class="selflink" href="#NAME">NAME</a></h1>
<b class="Nm" title="Nm">rgbgfx</b> &#x2014; <span class="Nd" title="Nd">Game
Boy graphics converter</span>
<h1 class="Sh" title="Sh" id="SYNOPSIS"><a class="selflink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<table class="Nm">
<tr>
<td><b class="Nm" title="Nm">rgbgfx</b></td>
<td>[<span class="Op"><b class="Fl" title="Fl">-DfFhPTVv</b></span>]
[<span class="Op"><b class="Fl" title="Fl">-o</b>
<var class="Ar" title="Ar">outfile</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-d</b>
<var class="Ar" title="Ar">depth</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-p</b>
<var class="Ar" title="Ar">palfile</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-t</b>
<var class="Ar" title="Ar">mapfile</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-x</b>
<var class="Ar" title="Ar">tiles</var></span>]
<var class="Ar" title="Ar">file</var></td>
</tr>
</table>
<h1 class="Sh" title="Sh" id="DESCRIPTION"><a class="selflink" href="#DESCRIPTION">DESCRIPTION</a></h1>
The <b class="Nm" title="Nm">rgbgfx</b> program converts PNG images into the
Nintendo Game Boy's planar tile format.
<div style="height: 1.00em;">&#x00A0;</div>
The resulting colors and their palette indices are determined differently
depending on the input PNG file:
<ul class="Bl-dash">
<li class="It-dash">If the file has an embedded palette, that palette's color
and order are used.</li>
<li class="It-dash">If not, and the image only contains shades of gray, rgbgfx
maps them to the indices appropriate for each shade. Any undetermined
indices are set to respective default shades of gray. For example: if the
bit depth is 2 and the image contains light gray and black, they become
the second and fourth colors - and the first and third colors get set to
default white and dark gray. If the image has multiple shades that map to
the same index, the palette is instead determined as if the image had
color.</li>
<li class="It-dash">If the image has color (or the grayscale method failed),
the colors are sorted from lightest to darkest.</li>
</ul>
<div style="height: 1.00em;">&#x00A0;</div>
The input image may not contain more colors than the selected bit depth allows.
Transparent pixels are set to palette index 0.
<h1 class="Sh" title="Sh" id="ARGUMENTS"><a class="selflink" href="#ARGUMENTS">ARGUMENTS</a></h1>
<dl class="Bl-tag">
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#D"><b class="Fl" title="Fl" id="D">-D</b></a></dt>
<dd class="It-tag">Debug features are enabled.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#f"><b class="Fl" title="Fl" id="f">-f</b></a></dt>
<dd class="It-tag">Fix the input PNG file to be a correctly indexed
image.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#F"><b class="Fl" title="Fl" id="F">-F</b></a></dt>
<dd class="It-tag">Same as <b class="Fl" title="Fl">-f</b>, but additionally,
the supplied command line parameters are saved within the PNG and will be
loaded and automatically used next time.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#d"><b class="Fl" title="Fl" id="d">-d</b></a>
<var class="Ar" title="Ar">depth</var></dt>
<dd class="It-tag">The bit depth of the output image (either 1 or 2). By
default, the bit depth is 2 (two bits per pixel).</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#h"><b class="Fl" title="Fl" id="h">-h</b></a></dt>
<dd class="It-tag">Lay out tiles horizontally rather than vertically.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#o"><b class="Fl" title="Fl" id="o">-o</b></a>
<var class="Ar" title="Ar">outfile</var></dt>
<dd class="It-tag">The name of the output file.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#p"><b class="Fl" title="Fl" id="p">-p</b></a>
<var class="Ar" title="Ar">palfile</var></dt>
<dd class="It-tag">Output the image's palette in standard GBC palette format -
bytes (8 bytes for two bits per pixel, 4 bytes for one bit per pixel)
containing the RGB15 values in little-endian byte order. If the palette
contains too few colors, the remaining entries are set to black.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#P"><b class="Fl" title="Fl" id="P">-P</b></a></dt>
<dd class="It-tag">Same as <b class="Fl" title="Fl">-p</b>, but the palette
file output name is made by taking the input PNG file's filename, removing
the file extension, and appending <i class="Pa" title="Pa">.pal</i>.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#t"><b class="Fl" title="Fl" id="t">-t</b></a>
<var class="Ar" title="Ar">mapfile</var></dt>
<dd class="It-tag">If any tiles are the same, don't place the repeat tiles in
the output file, and make a tilemap file.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#T"><b class="Fl" title="Fl" id="T">-T</b></a></dt>
<dd class="It-tag">Same as <b class="Fl" title="Fl">-t</b>, but the tilemap
file output name is made by taking the input filename, removing the file
extension, and appending <i class="Pa" title="Pa">.tilemap</i>.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#u"><b class="Fl" title="Fl" id="u">-u</b></a></dt>
<dd class="It-tag">Truncate repeated tiles. Useful with tilemaps.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#V"><b class="Fl" title="Fl" id="V">-V</b></a></dt>
<dd class="It-tag">Print the version of the program and exit.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#v"><b class="Fl" title="Fl" id="v">-v</b></a></dt>
<dd class="It-tag">Verbose. Print errors when the command line parameters and
the parameters in the PNG file don't match.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#x"><b class="Fl" title="Fl" id="x">-x</b></a>
<var class="Ar" title="Ar">tiles</var></dt>
<dd class="It-tag">Trim the end of the output file by this many tiles.</dd>
</dl>
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
The following will take a PNG file with a bit depth of 1, 2, or 8, and output
planar 2bpp data:
<div class="Pp"></div>
<div class="D1">$ rgbgfx -o out.2bpp in.png</div>
<div class="Pp"></div>
The following creates a planar 2bpp file with only unique tiles, and its tilemap
<i class="Pa" title="Pa">out.tilemap</i>:
<div class="Pp"></div>
<div class="D1">$ rgbgfx -T -u -o out.2bpp in.png</div>
<div class="Pp"></div>
The following will do nothing:
<div class="Pp"></div>
<div class="D1">$ rgbgfx in.png</div>
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<a class="Xr" title="Xr">rgbds(7)</a>, <a class="Xr" title="Xr">rgbasm(1)</a>,
<a class="Xr" title="Xr">rgblink(1)</a>,
<a class="Xr" title="Xr">rgbfix(1)</a>, <a class="Xr" title="Xr">gbz80(7)</a>
<h1 class="Sh" title="Sh" id="HISTORY"><a class="selflink" href="#HISTORY">HISTORY</a></h1>
<b class="Nm" title="Nm">rgbgfx</b> was created by
<span class="An" title="An">stag019</span> to be included in RGBDS. It is now
maintained by a number of contributors at
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
<table class="foot">
<tr>
<td class="foot-date">January 26, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</table>
</body>
</html>

161
docs/rgblink.1.html Normal file
View File

@@ -0,0 +1,161 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
table.head, table.foot { width: 100%; }
td.head-rtitle, td.foot-os { text-align: right; }
td.head-vol { text-align: center; }
div.Pp { margin: 1ex 0ex; }
</style>
<link rel="stylesheet" href="mandoc.css" type="text/css" media="all"/>
<title>RGBLINK(1)</title>
</head>
<body>
<table class="head">
<tr>
<td class="head-ltitle">RGBLINK(1)</td>
<td class="head-vol">General Commands Manual</td>
<td class="head-rtitle">RGBLINK(1)</td>
</tr>
</table>
<div class="manual-text">
<h1 class="Sh" title="Sh" id="NAME"><a class="selflink" href="#NAME">NAME</a></h1>
<b class="Nm" title="Nm">rgblink</b> &#x2014; <span class="Nd" title="Nd">Game
Boy linker</span>
<h1 class="Sh" title="Sh" id="SYNOPSIS"><a class="selflink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<table class="Nm">
<tr>
<td><b class="Nm" title="Nm">rgblink</b></td>
<td>[<span class="Op"><b class="Fl" title="Fl">-dtVw</b></span>]
[<span class="Op"><b class="Fl" title="Fl">-m</b>
<var class="Ar" title="Ar">mapfile</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-n</b>
<var class="Ar" title="Ar">symfile</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-O</b>
<var class="Ar" title="Ar">overlayfile</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-o</b>
<var class="Ar" title="Ar">outfile</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-p</b>
<var class="Ar" title="Ar">pad_value</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-s</b>
<var class="Ar" title="Ar">symbol</var></span>]
[<span class="Op"><b class="Fl" title="Fl">-l</b>
<var class="Ar" title="Ar">linkerscript</var></span>]
<var class="Ar" title="Ar">file ...</var></td>
</tr>
</table>
<h1 class="Sh" title="Sh" id="DESCRIPTION"><a class="selflink" href="#DESCRIPTION">DESCRIPTION</a></h1>
The <b class="Nm" title="Nm">rgblink</b> program links objects created by
<a class="Xr" title="Xr">rgbasm(1)</a> into a single Game Boy ROM file.
<div class="Pp"></div>
By default, ROM0 sections created by the assembler are placed in the 16KiB bank
0, and ROMX sections are placed in any bank except bank 0. If your ROM will
only be 32KiB, you can use the <b class="Fl" title="Fl">-t</b> option to
override this.
<div class="Pp"></div>
Similarly, WRAM0 sections are placed in the first 4KiB of WRAM bank 0 and WRAMX
sections are placed in any bank except bank 0. If your ROM doesn't use banked
WRAM you can use option <b class="Fl" title="Fl">-w</b> option to override
this.
<div class="Pp"></div>
Also, if your ROM is designed for DMG, you can make sure that you don't use any
prohibited section by using the option <b class="Fl" title="Fl">-d</b>, which
implies <b class="Fl" title="Fl">-w</b> but also prohibits the use of VRAM
bank 1.
<div class="Pp"></div>
The arguments are as follows:
<dl class="Bl-tag">
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#m"><b class="Fl" title="Fl" id="m">-m</b></a>
<var class="Ar" title="Ar">mapfile</var></dt>
<dd class="It-tag">Write a mapfile to the given filename.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#n"><b class="Fl" title="Fl" id="n">-n</b></a>
<var class="Ar" title="Ar">symfile</var></dt>
<dd class="It-tag">Write a symbol file to the given filename.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#O"><b class="Fl" title="Fl" id="O">-O</b></a>
<var class="Ar" title="Ar">overlayfile</var></dt>
<dd class="It-tag">The ROM image to overlay sections over. When an overlay ROM
is provided, all sections must be fixed. This may be used to patch an
existing binary.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#o"><b class="Fl" title="Fl" id="o">-o</b></a>
<var class="Ar" title="Ar">outfile</var></dt>
<dd class="It-tag">Write ROM image to the given filename.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#p"><b class="Fl" title="Fl" id="p">-p</b></a>
<var class="Ar" title="Ar">pad_value</var></dt>
<dd class="It-tag">When padding an image, pad with this value. The default is
0x00.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#s"><b class="Fl" title="Fl" id="s">-s</b></a>
<var class="Ar" title="Ar">symbol</var></dt>
<dd class="It-tag">???</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#w"><b class="Fl" title="Fl" id="w">-w</b></a></dt>
<dd class="It-tag">Expand the WRAM0 section size from 4KiB to the full 8KiB
assigned to WRAM and prohibit the use of WRAMX sections.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#d"><b class="Fl" title="Fl" id="d">-d</b></a></dt>
<dd class="It-tag">Enable DMG mode. Prohibit the use of sections that doesn't
exist on a DMG, such as WRAMX and VRAM bank 1. This option automatically
enables <b class="Fl" title="Fl">-w</b>.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#t"><b class="Fl" title="Fl" id="t">-t</b></a></dt>
<dd class="It-tag">Expand the ROM0 section size from 16KiB to the full 32KiB
assigned to ROM and prohibit the use of ROMX sections. Useful for ROMs
that fit in 32 KiB.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#l"><b class="Fl" title="Fl" id="l">-l</b></a>
<var class="Ar" title="Ar">linkerscript</var></dt>
<dd class="It-tag">Specify a linkerscript file that tells the linker how
sections must be placed in the ROM. This file has priority over the
attributes assigned in the source code, but they have to be consistent.
See <a class="Xr" title="Xr">rgblink(5)</a> for more information about its
format.</dd>
<dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd>
<dt class="It-tag"><a class="selflink" href="#V"><b class="Fl" title="Fl" id="V">-V</b></a></dt>
<dd class="It-tag">Print the version of the program and exit.</dd>
</dl>
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
All you need for a basic ROM is an object file, which can be made into a ROM
image like so:
<div class="Pp"></div>
<div class="D1">$ rgblink -o bar.gb foo.o</div>
<div class="Pp"></div>
The resulting bar.gb will not have correct checksums (unless you put them in the
assembly source). You should use <a class="Xr" title="Xr">rgbfix(1)</a> to fix
these so that the program will actually run in a Game Boy:
<div class="Pp"></div>
<div class="D1">$ rgbfix -v bar.gb</div>
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<a class="Xr" title="Xr">rgbasm(1)</a>, <a class="Xr" title="Xr">rgblink(5)</a>,
<a class="Xr" title="Xr">rgbfix(1)</a>, <a class="Xr" title="Xr">rgbds(5)</a>,
<a class="Xr" title="Xr">rgbds(7)</a>
<h1 class="Sh" title="Sh" id="HISTORY"><a class="selflink" href="#HISTORY">HISTORY</a></h1>
<b class="Nm" title="Nm">rgblink</b> was originally written by Carsten
S&#x00F8;rensen as part of the ASMotor package, and was later packaged in
RGBDS by Justin Lloyd. It is now maintained by a number of contributors at
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
<table class="foot">
<tr>
<td class="foot-date">January 26, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</table>
</body>
</html>

105
docs/rgblink.5.html Normal file
View File

@@ -0,0 +1,105 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
table.head, table.foot { width: 100%; }
td.head-rtitle, td.foot-os { text-align: right; }
td.head-vol { text-align: center; }
div.Pp { margin: 1ex 0ex; }
</style>
<link rel="stylesheet" href="mandoc.css" type="text/css" media="all"/>
<title>RGBLINK(5)</title>
</head>
<body>
<table class="head">
<tr>
<td class="head-ltitle">RGBLINK(5)</td>
<td class="head-vol">File Formats Manual</td>
<td class="head-rtitle">RGBLINK(5)</td>
</tr>
</table>
<div class="manual-text">
<h1 class="Sh" title="Sh" id="NAME"><a class="selflink" href="#NAME">NAME</a></h1>
<b class="Nm" title="Nm">rgblink</b> &#x2014;
<span class="Nd" title="Nd">linkerscript file format</span>
<h1 class="Sh" title="Sh" id="DESCRIPTION"><a class="selflink" href="#DESCRIPTION">DESCRIPTION</a></h1>
The linkerscript is an external file that allows the user to specify the order
of sections without the need for doing so before assembling each object file.
<div class="Pp"></div>
The placement of sections specified in the linkerscript is done before the
sections whose placement is defined in the source code.
<div class="Pp"></div>
A linkerscript 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
&#x2018;<code class="Li">;</code>&#x2019; that ends at the end of the line:
<div class="Pp"></div>
<div class="Bd" style="margin-left: 5.00ex;">
<pre class="Li">
ROMX $F ; This is a comment
&quot;Functions to read array&quot;
ALIGN 8
&quot;Array aligned to 256 bytes&quot;
WRAMX 2
&quot;Some variables&quot;
</pre>
</div>
<div class="Pp"></div>
Numbers can be in decimal or hexadecimal format (the prefix is
&#x2018;<code class="Li">$</code>&#x2019;). It is an error if any section name
or command are found before setting a bank.
<div class="Pp"></div>
Files can be included by using the <var class="Ar" title="Ar">INCLUDE</var>
keyword followed by a string with the path of the file that has to be
included.
<div class="Pp"></div>
The possible bank types are: <b class="Sy" title="Sy">ROM0</b>,
<b class="Sy" title="Sy">ROMX</b>, <b class="Sy" title="Sy">VRAM</b>,
<b class="Sy" title="Sy">WRAM0</b>, <b class="Sy" title="Sy">WRAMX</b>,
<b class="Sy" title="Sy">OAM</b> and <b class="Sy" title="Sy">HRAM</b>. Types
<b class="Sy" title="Sy">ROMX</b>, <b class="Sy" title="Sy">VRAM</b>,
<b class="Sy" title="Sy">WRAMX</b> and <b class="Sy" title="Sy">SRAM</b> are
banked, which means that it is needed to specify a bank after the type.
<div class="Pp"></div>
When a new bank statement is found, sections found after it will be placed right
from the beginning of that bank. If the linkerscript switches to a different
bank and then it comes back to the previous one it will continue from the last
address that was used.
<div class="Pp"></div>
The only two commands are <var class="Ar" title="Ar">ORG</var> and
<var class="Ar" title="Ar">ALIGN</var>:
<ul class="Bl-bullet">
<li class="It-bullet"><var class="Ar" title="Ar">ORG</var> sets the address in
which new sections will be placed. It can not be lower than the current
address.</li>
<li class="It-bullet"><var class="Ar" title="Ar">ALIGN</var> will increase the
address until it is aligned to the specified boundary (it tries to set to
0 the number of bits specified after the command:
<b class="Sy" title="Sy">ALIGN 8</b> will align to $100).</li>
</ul>
<div class="Pp"></div>
Note: The bank, alignment, address and type of sections can be specified both in
the source code and in the linkerscript. For a section to be able to be placed
with the linkerscript the bank must be left unassigned in the source code or
be the same as the one specified in the linkerscript. The address and
alignment musn't be set.
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<a class="Xr" title="Xr">rgbasm(1)</a>, <a class="Xr" title="Xr">rgblink(1)</a>,
<a class="Xr" title="Xr">rgbfix(1)</a>, <a class="Xr" title="Xr">rgbds(5)</a>,
<a class="Xr" title="Xr">rgbds(7)</a>
<h1 class="Sh" title="Sh" id="HISTORY"><a class="selflink" href="#HISTORY">HISTORY</a></h1>
<b class="Nm" title="Nm">rgblink</b> was originally written by Carsten
S&#x00F8;rensen as part of the ASMotor package, and was later packaged in
RGBDS by Justin Lloyd. It is now maintained by a number of contributors at
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
<table class="foot">
<tr>
<td class="foot-date">January 27, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</table>
</body>
</html>

View File

@@ -1,9 +1,13 @@
/*
* asm.h
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/*
* Contains some assembler-wide defines and externs
*
* Copyright 1997 Carsten Sorensen
*/
#ifndef RGBDS_ASM_ASM_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_CHARMAP_H
#define RGBDS_ASM_CHARMAP_H

View File

@@ -1,9 +1,13 @@
/* fstack.h
/*
* This file is part of RGBDS.
*
* Contains some assembler-wide defines and externs
*
* Copyright 1997 Carsten Sorensen
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/*
* Contains some assembler-wide defines and externs
*/
#ifndef RGBDS_ASM_FSTACK_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_LEXER_H
#define RGBDS_ASM_LEXER_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_LOCALASM_H
#define RGBDS_ASM_LOCALASM_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_MAIN_H
#define RGBDS_MAIN_H
@@ -7,12 +15,13 @@
#include "extern/stdnoreturn.h"
struct sOptions {
char gbgfx[4];
char binary[2];
int32_t fillchar;
bool verbose;
bool haltnop;
char gbgfx[4];
bool exportall;
int32_t fillchar;
bool haltnop;
bool optimizeloads;
bool verbose;
bool warnings; /* True to enable warnings, false to disable them. */
};

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_MATH_H
#define RGBDS_ASM_MATH_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_OUTPUT_H
#define RGBDS_ASM_OUTPUT_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_ASM_RPN_H
#define RGBDS_ASM_RPN_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_SYMBOL_H
#define RGBDS_SYMBOL_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_COMMON_H
#define RGBDS_COMMON_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef EXTERN_ERR_H
#define EXTERN_ERR_H

View File

@@ -1,15 +0,0 @@
#ifndef EXTERN_REALLOCARRAY_H
#define EXTERN_REALLOCARRAY_H
#ifdef REALLOCARRAY_IN_LIBC
#include <stdlib.h>
#else /* REALLOCARRAY_IN_LIBC */
#define reallocarray rgbds_reallocarray
void *reallocarray(void *, size_t, size_t);
#endif /* REALLOCARRAY_IN_LIBC */
#endif /* EXTERN_REALLOCARRAY_H */

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2014-2018, RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef EXTERN_STDNORETURN_H
#define EXTERN_STDNORETURN_H

17
include/extern/strl.h vendored
View File

@@ -1,17 +0,0 @@
#ifndef EXTERN_STRL_H
#define EXTERN_STRL_H
#ifdef STRL_IN_LIBC
#include <string.h>
#else /* STRL_IN_LIBC */
#define strlcpy rgbds_strlcpy
#define strlcat rgbds_strlcat
size_t strlcpy(char *dst, const char *src, size_t dsize);
size_t strlcat(char *dst, const char *src, size_t dsize);
#endif /* STRL_IN_LIBC */
#endif /* EXTERN_STRL_H */

14
include/extern/utf8decoder.h vendored Normal file
View File

@@ -0,0 +1,14 @@
/*
* 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, uint32_t byte);
#endif /* EXTERN_UTF8DECODER_H */

View File

@@ -1,26 +0,0 @@
/*
* Copyright (C) 2017 Antonio Nino Diaz <antonio_nd@outlook.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef EXTERN_VERSION_H
#define EXTERN_VERSION_H
#define PACKAGE_VERSION_MAJOR (0)
#define PACKAGE_VERSION_MINOR (3)
#define PACKAGE_VERSION_PATCH (4)
const char *get_package_version_string(void);
#endif /* EXTERN_VERSION_H */

View File

@@ -1,17 +1,9 @@
/*
* Copyright © 2013 stag019 <stag019@gmail.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_GFX_GB_H
@@ -20,14 +12,15 @@
#include <stdint.h>
#include "gfx/main.h"
void png_to_gb(const struct PNGImage png, struct GBImage *gb);
void output_file(const struct Options opts, const struct GBImage gb);
void raw_to_gb(const struct RawIndexedImage *raw_image, struct GBImage *gb);
void output_file(const struct Options *opts, const struct GBImage *gb);
int get_tile_index(uint8_t *tile, uint8_t **tiles, int num_tiles,
int tile_size);
void create_tilemap(const struct Options opts, struct GBImage *gb,
void create_tilemap(const struct Options *opts, struct GBImage *gb,
struct Tilemap *tilemap);
void output_tilemap_file(const struct Options opts,
const struct Tilemap tilemap);
void output_palette_file(const struct Options opts, const struct PNGImage png);
void output_tilemap_file(const struct Options *opts,
const struct Tilemap *tilemap);
void output_palette_file(const struct Options *opts,
const struct RawIndexedImage *raw_image);
#endif

View File

@@ -1,17 +1,9 @@
/*
* Copyright © 2013 stag019 <stag019@gmail.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_GFX_MAIN_H
@@ -39,6 +31,21 @@ struct Options {
char *infile;
};
struct RGBColor {
uint8_t red;
uint8_t green;
uint8_t blue;
};
struct ImageOptions {
bool horizontal;
int trim;
char *mapfile;
bool mapout;
char *palfile;
bool palout;
};
struct PNGImage {
png_struct *png;
png_info *info;
@@ -47,12 +54,14 @@ struct PNGImage {
int height;
png_byte depth;
png_byte type;
bool horizontal;
int trim;
char *mapfile;
bool mapout;
char *palfile;
bool palout;
};
struct RawIndexedImage {
uint8_t **data;
struct RGBColor *palette;
int num_colors;
int width;
int height;
};
struct GBImage {

View File

@@ -1,17 +1,9 @@
/*
* Copyright © 2013 stag019 <stag019@gmail.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_GFX_PNG_H
@@ -19,10 +11,11 @@
#include "gfx/main.h"
void input_png_file(const struct Options opts, struct PNGImage *img);
void get_text(struct PNGImage *png);
void set_text(const struct PNGImage *png);
void output_png_file(const struct Options opts, const struct PNGImage *png);
void free_png_data(const struct PNGImage *png);
struct RawIndexedImage *input_png_file(const struct Options *opts,
struct ImageOptions *png_options);
void output_png_file(const struct Options *opts,
const struct ImageOptions *png_options,
const struct RawIndexedImage *raw_image);
void destroy_raw_image(struct RawIndexedImage **raw_image_ptr_ptr);
#endif /* RGBDS_GFX_PNG_H */

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_ASSIGN_H
#define RGBDS_LINK_ASSIGN_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_LIBRARY_H
#define RGBDS_LINK_LIBRARY_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_MAIN_H
#define RGBDS_LINK_MAIN_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_MAPFILE_H
#define RGBDS_LINK_MAPFILE_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_LINK_H
#define RGBDS_LINK_LINK_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_OBJECT_H
#define RGBDS_LINK_OBJECT_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_OUTPUT_H
#define RGBDS_LINK_OUTPUT_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_PATCH_H
#define RGBDS_LINK_PATCH_H

View File

@@ -1,17 +1,9 @@
/*
* Copyright (C) 2017 Antonio Nino Diaz <antonio_nd@outlook.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_SCRIPT_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINK_SYMBOL_H
#define RGBDS_LINK_SYMBOL_H

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_LINKDEFS_H
#define RGBDS_LINKDEFS_H
@@ -58,7 +66,8 @@ enum eSymbolType {
enum ePatchType {
PATCH_BYTE = 0x00,
PATCH_WORD_L = 0x01,
PATCH_LONG_L = 0x02
PATCH_LONG_L = 0x02,
PATCH_BYTE_JR = 0x03
};
#endif /* RGBDS_LINKDEFS_H */

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RGBDS_TYPES_H
#define RGBDS_TYPES_H

18
include/version.h Normal file
View File

@@ -0,0 +1,18 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#ifndef EXTERN_VERSION_H
#define EXTERN_VERSION_H
#define PACKAGE_VERSION_MAJOR (0)
#define PACKAGE_VERSION_MINOR (3)
#define PACKAGE_VERSION_PATCH (6)
const char *get_package_version_string(void);
#endif /* EXTERN_VERSION_H */

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
%{
#include <ctype.h>
#include <errno.h>
@@ -447,7 +455,6 @@ static void updateUnion(void)
%type <nConstValue> const_3bit
%type <sVal> const_8bit
%type <sVal> const_16bit
%type <sVal> const_PCrel
%type <nConstValue> sectiontype
%type <tzString> string
@@ -496,7 +503,7 @@ static void updateUnion(void)
%token <tzSym> T_POP_SET
%token <tzSym> T_POP_EQUS
%token T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV
%token T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_PRINTI
%token T_POP_IF T_POP_ELIF T_POP_ELSE T_POP_ENDC
%token T_POP_IMPORT T_POP_EXPORT T_POP_GLOBAL
%token T_POP_DB T_POP_DS T_POP_DW T_POP_DL
@@ -640,6 +647,7 @@ simple_pseudoop : include
| printf
| printt
| printv
| printi
| if
| elif
| else
@@ -925,6 +933,13 @@ printv : T_POP_PRINTV const
}
;
printi : T_POP_PRINTI const
{
if (nPass == 1)
printf("%d", $2);
}
;
printf : T_POP_PRINTF const
{
if (nPass == 1)
@@ -1100,14 +1115,6 @@ constlist_32bit_entry_single : /* empty */
}
;
const_PCrel : relocconst
{
if (!rpn_isPCRelative(&$1))
yyerror("Expression must be PC-relative");
$$ = $1;
}
;
const_8bit : relocconst
{
if( (!rpn_isReloc(&$1)) && (($1.nVal < -128) || ($1.nVal > 255)) )
@@ -1226,6 +1233,8 @@ uconst : const
const : T_ID { $$ = sym_GetConstantValue($1); }
| T_NUMBER { $$ = $1; }
| T_OP_HIGH '(' const ')' { $$ = ($3 >> 8) & 0xFF; }
| T_OP_LOW '(' const ')' { $$ = $3 & 0xFF; }
| string { $$ = str2int($1); }
| T_OP_LOGICNOT const %prec NEG { $$ = !$2; }
| const T_OP_LOGICOR const { $$ = $1 || $3; }
@@ -1303,26 +1312,37 @@ const : T_ID { $$ = sym_GetConstantValue($1); }
string : T_STRING
{
strcpy($$, $1);
if (snprintf($$, MAXSTRLEN + 1, "%s", $1) > MAXSTRLEN)
warning("String is too long '%s'", $1);
}
| T_OP_STRSUB '(' string comma uconst comma uconst ')'
{
strncpy($$, $3 + $5 - 1, $7);
$$[$7] = 0;
uint32_t len = $7;
if (len > MAXSTRLEN) {
warning("STRSUB: Length too big: %u", len);
len = MAXSTRLEN;
}
if (snprintf($$, len + 1, "%s", $3 + $5 - 1) > MAXSTRLEN)
warning("STRSUB: String too long '%s'", $$);
}
| T_OP_STRCAT '(' string comma string ')'
{
strcpy($$, $3);
strcat($$, $5);
if (snprintf($$, MAXSTRLEN + 1, "%s%s", $3, $5) > MAXSTRLEN)
warning("STRCAT: String too long '%s%s'", $3, $5);
}
| T_OP_STRUPR '(' string ')'
{
strcpy($$, $3);
if (snprintf($$, MAXSTRLEN + 1, "%s", $3) > MAXSTRLEN)
warning("STRUPR: String too long '%s'", $3);
upperstring($$);
}
| T_OP_STRLWR '(' string ')'
{
strcpy($$, $3);
if (snprintf($$, MAXSTRLEN + 1, "%s", $3) > MAXSTRLEN)
warning("STRUPR: String too long '%s'", $3);
lowerstring($$);
}
;
@@ -1594,12 +1614,12 @@ z80_jp : T_Z80_JP const_16bit
}
;
z80_jr : T_Z80_JR const_PCrel
z80_jr : T_Z80_JR const_16bit
{
out_AbsByte(0x18);
out_PCRelByte(&$2);
}
| T_Z80_JR ccode comma const_PCrel
| T_Z80_JR ccode comma const_16bit
{
out_AbsByte(0x20 | ($2 << 3));
out_PCRelByte(&$4);
@@ -1708,7 +1728,8 @@ z80_ld_mem : T_Z80_LD op_mem_ind comma T_MODE_SP
}
| T_Z80_LD op_mem_ind comma T_MODE_A
{
if ((!rpn_isReloc(&$2)) && ($2.nVal >= 0xFF00)) {
if (CurrentOptions.optimizeloads &&
(!rpn_isReloc(&$2)) && ($2.nVal >= 0xFF00)) {
out_AbsByte(0xE0);
out_AbsByte($2.nVal & 0xFF);
} else {
@@ -1761,7 +1782,8 @@ z80_ld_a : T_Z80_LD reg_r comma T_MODE_C_IND
| T_Z80_LD reg_r comma op_mem_ind
{
if ($2 == REG_A) {
if ((!rpn_isReloc(&$4)) && ($4.nVal >= 0xFF00)) {
if (CurrentOptions.optimizeloads &&
(!rpn_isReloc(&$4)) && ($4.nVal >= 0xFF00)) {
out_AbsByte(0xF0);
out_AbsByte($4.nVal & 0xFF);
} else {

View File

@@ -1,87 +1,12 @@
/*
* UTF-8 decoder copyright © 20082009 Björn Höhrmann <bjoern@hoehrmann.de>
* http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
* This file is part of RGBDS.
*
* 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:
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
*
* 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.
* SPDX-License-Identifier: MIT
*/
#include <stdint.h>
static const uint8_t utf8d[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00..0f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10..1f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20..2f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30..3f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40..4f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50..5f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60..6f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70..7f */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80..8f */
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* 90..9f */
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* a0..af */
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* b0..bf */
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* c0..cf */
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* d0..df */
0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, /* e0..e7 */
0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, /* e8..ef */
0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, /* f0..f7 */
0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, /* f8..ff */
0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, /* s0.. */
0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, /* ..s0 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* s1 */
1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, /* s1 */
1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, /* s3 */
1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, /* s4 */
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, /* s5 */
1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, /* s6 */
1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, /* s7 */
1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* s8 */
};
uint32_t decode(uint32_t *state, uint32_t *codep, uint32_t byte)
{
uint32_t type = utf8d[byte];
*codep = (*state != 0) ?
(byte & 0x3fu) | (*codep << 6) :
(0xff >> type) & (byte);
*state = utf8d[256 + *state * 16 + type];
return *state;
}
/*
* Copyright © 2013 stag019 <stag019@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -91,6 +16,8 @@ uint32_t decode(uint32_t *state, uint32_t *codep, uint32_t byte)
#include "asm/main.h"
#include "asm/output.h"
#include "extern/utf8decoder.h"
struct Charmap globalCharmap = {0};
int32_t readUTF8Char(char *dest, char *src)

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/*
* FileStack routines
*/
@@ -16,7 +24,6 @@
#include "asm/symbol.h"
#include "extern/err.h"
#include "extern/strl.h"
#include "types.h"
@@ -218,7 +225,7 @@ void fstk_AddIncludePath(char *s)
if (NextIncPath == MAXINCPATHS)
fatalerror("Too many include directories passed from command line");
if (strlcpy(IncludePaths[NextIncPath++], s, _MAX_PATH) >= _MAX_PATH)
if (snprintf(IncludePaths[NextIncPath++], _MAX_PATH, "%s", s) >= _MAX_PATH)
fatalerror("Include path too long '%s'", s);
}
@@ -228,6 +235,9 @@ FILE *fstk_FindFile(char *fname)
int32_t i;
FILE *f;
if (fname == NULL)
return NULL;
f = fopen(fname, "rb");
if (f != NULL || errno != ENOENT) {
@@ -238,13 +248,19 @@ FILE *fstk_FindFile(char *fname)
}
for (i = 0; i < NextIncPath; ++i) {
if (strlcpy(path, IncludePaths[i], sizeof(path))
/*
* The function snprintf() does not write more than `size` bytes
* (including the terminating null byte ('\0')). If the output
* was truncated due to this limit, the return value is the
* number of characters (excluding the terminating null byte)
* which would have been written to the final string if enough
* space had been available. Thus, a return value of `size` or
* more means that the output was truncated.
*/
if (snprintf(path, sizeof(path), "%s%s", IncludePaths[i], fname)
>= sizeof(path))
continue;
if (strlcat(path, fname, sizeof(path)) >= sizeof(path))
continue;
f = fopen(path, "rb");
if (f != NULL || errno != ENOENT) {
@@ -331,7 +347,7 @@ void fstk_RunMacroArg(int32_t s)
pushcontext();
nCurrentStatus = STAT_isMacroArg;
sprintf(tzCurrentFileName, "%c", (uint8_t)s);
snprintf(tzCurrentFileName, _MAX_PATH + 1, "%c", (uint8_t)s);
CurrentFlexHandle = yy_scan_bytes(sym, strlen(sym));
yy_switch_to_buffer(CurrentFlexHandle);
}
@@ -394,7 +410,7 @@ void fstk_Init(char *s)
nMacroCount = 0;
nCurrentStatus = STAT_isInclude;
strcpy(tzCurrentFileName, tzFileName);
snprintf(tzCurrentFileName, _MAX_PATH + 1, "%s", tzFileName);
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle);
nLineNo = 1;

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
@@ -360,6 +368,7 @@ const struct sLexInitString lexer_strings[] = {
{"include", T_POP_INCLUDE},
{"printt", T_POP_PRINTT},
{"printi", T_POP_PRINTI},
{"printv", T_POP_PRINTV},
{"printf", T_POP_PRINTF},
{"export", T_POP_EXPORT},

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@@ -151,6 +159,8 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f)
pBuffer->pBuffer[size + 1] = 0;
pBuffer->nBufferSize = size + 1;
/* Convert all line endings to LF and spaces */
char *mem = pBuffer->pBuffer;
uint32_t instring = 0;
@@ -163,20 +173,44 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f)
} else if (instring) {
mem += 1;
} else {
if ((mem[0] == 10 && mem[1] == 13)
|| (mem[0] == 13 && mem[1] == 10)) {
/* LF CR and CR LF */
if (((mem[0] == 10) && (mem[1] == 13))
|| ((mem[0] == 13) && (mem[1] == 10))) {
mem[0] = ' ';
mem[1] = '\n';
mem += 2;
} else if (mem[0] == 10 || mem[0] == 13) {
/* LF and CR */
} else if ((mem[0] == 10) || (mem[0] == 13)) {
mem[0] = '\n';
mem += 1;
} else if (mem[0] == '\n' && mem[1] == '*') {
} else {
mem += 1;
while (!(*mem == '\n' || *mem == '\0'))
}
}
}
/* Remove comments */
mem = pBuffer->pBuffer;
instring = 0;
while (*mem) {
if (*mem == '\"')
instring = 1 - instring;
if ((mem[0] == '\\') && (mem[1] == '\"' || mem[1] == '\\')) {
mem += 2;
} else if (instring) {
mem += 1;
} else {
/* Comments that start with ; anywhere in a line */
if (*mem == ';') {
while (!((*mem == '\n') || (*mem == '\0')))
*mem++ = ' ';
} else if (*mem == ';') {
while (!(*mem == '\n' || *mem == '\0'))
/* Comments that start with * at the start of a line */
} else if ((mem[0] == '\n') && (mem[1] == '*')) {
mem += 1;
while (!((*mem == '\n') || (*mem == '\0')))
*mem++ = ' ';
} else {
mem += 1;
@@ -604,6 +638,44 @@ scanagain:
}
}
/* Check for line continuation character */
if (*pLexBuffer == '\\') {
/*
* Look for line continuation character after a series of
* spaces. This is also useful for files that use Windows line
* endings: "\r\n" is replaced by " \n" before the lexer has the
* opportunity to see it.
*/
if (pLexBuffer[1] == ' ') {
pLexBuffer += 2;
while (1) {
if (*pLexBuffer == ' ') {
pLexBuffer++;
} else if (*pLexBuffer == '\n') {
pLexBuffer++;
nLineNo += 1;
goto scanagain;
} else {
errx(1, "Expected a new line after the continuation character.");
}
}
}
/* Line continuation character */
if (pLexBuffer[1] == '\n') {
pLexBuffer += 2;
nLineNo += 1;
goto scanagain;
}
/*
* If there isn't a newline character or a space, ignore the
* character '\'. It will eventually be handled by other
* functions like PutMacroArg().
*/
}
/*
* Try to match an identifier, macro argument (e.g. \1),
* or numeric literal.
@@ -691,6 +763,9 @@ static uint32_t yylex_MACROARGS(void)
case '\\':
ch = '\\';
break;
case '"':
ch = '\"';
break;
case ',':
ch = ',';
break;
@@ -700,6 +775,32 @@ static uint32_t yylex_MACROARGS(void)
case '}':
ch = '}';
break;
case ' ':
/*
* Look for line continuation character after a
* series of spaces. This is also useful for
* files that use Windows line endings: "\r\n"
* is replaced by " \n" before the lexer has the
* opportunity to see it.
*/
while (1) {
if (*pLexBuffer == ' ') {
pLexBuffer++;
} else if (*pLexBuffer == '\n') {
pLexBuffer++;
nLineNo += 1;
ch = 0;
break;
} else {
errx(1, "Expected a new line after the continuation character.");
}
}
break;
case '\n':
/* Line continuation character */
nLineNo += 1;
ch = 0;
break;
default:
maxLength = MAXSTRLEN - index;
length = CopyMacroArg(&yylval.tzString[index],

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
@@ -14,13 +22,15 @@
#include "asm/main.h"
#include "extern/err.h"
#include "extern/reallocarray.h"
#include "extern/version.h"
#include "version.h"
extern int yyparse(void);
int32_t cldefines_index;
int32_t cldefines_size;
size_t cldefines_index;
size_t cldefines_numindices;
size_t cldefines_bufsize;
const size_t cldefine_entrysize = 2 * sizeof(void *);
char **cldefines;
clock_t nStartClock, nEndClock;
@@ -184,10 +194,18 @@ void opt_AddDefine(char *s)
{
char *value, *equals;
if (cldefines_index >= cldefines_size) {
cldefines_size *= 2;
cldefines = reallocarray(cldefines, cldefines_size,
2 * sizeof(void *));
if (cldefines_index >= cldefines_numindices) {
/* Check for overflows */
if ((cldefines_numindices * 2) < cldefines_numindices)
fatalerror("No memory for command line defines");
if ((cldefines_bufsize * 2) < cldefines_bufsize)
fatalerror("No memory for command line defines");
cldefines_numindices *= 2;
cldefines_bufsize *= 2;
cldefines = realloc(cldefines, cldefines_bufsize);
if (!cldefines)
fatalerror("No memory for command line defines");
}
@@ -264,7 +282,7 @@ void warning(const char *fmt, ...)
static void print_usage(void)
{
printf(
"usage: rgbasm [-EhVvw] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n"
"usage: rgbasm [-EhLVvw] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n"
" [-M dependfile] [-o outfile] [-p pad_value] file.asm\n");
exit(1);
}
@@ -280,8 +298,10 @@ int main(int argc, char *argv[])
dependfile = NULL;
cldefines_size = 32;
cldefines = reallocarray(cldefines, cldefines_size, 2 * sizeof(void *));
/* Initial number of allocated elements in array */
cldefines_numindices = 32;
cldefines_bufsize = cldefines_numindices * cldefine_entrysize;
cldefines = malloc(cldefines_bufsize);
if (!cldefines)
fatalerror("No memory for command line defines");
@@ -296,17 +316,18 @@ int main(int argc, char *argv[])
DefaultOptions.gbgfx[3] = '3';
DefaultOptions.binary[0] = '0';
DefaultOptions.binary[1] = '1';
DefaultOptions.fillchar = 0;
DefaultOptions.verbose = false;
DefaultOptions.haltnop = true;
DefaultOptions.exportall = false;
DefaultOptions.fillchar = 0;
DefaultOptions.optimizeloads = true;
DefaultOptions.haltnop = true;
DefaultOptions.verbose = false;
DefaultOptions.warnings = true;
opt_SetCurrentOptions(&DefaultOptions);
newopt = CurrentOptions;
while ((ch = getopt(argc, argv, "b:D:g:hi:M:o:p:EVvw")) != -1) {
while ((ch = getopt(argc, argv, "b:D:Eg:hi:LM:o:p:Vvw")) != -1) {
switch (ch) {
case 'b':
if (strlen(optarg) == 2) {
@@ -338,6 +359,9 @@ int main(int argc, char *argv[])
case 'i':
fstk_AddIncludePath(optarg);
break;
case 'L':
newopt.optimizeloads = false;
break;
case 'M':
dependfile = fopen(optarg, "w");
if (dependfile == NULL)

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/*
* Fixedpoint math routines
*/

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/*
* Outputs an objectfile
*/
@@ -585,7 +593,7 @@ void out_SetFileName(char *s)
}
/*
* Find a section by name and type. If it doesn't exist, create it
* Find a section by name and type. If it doesn't exist, create it
*/
struct Section *out_FindSection(char *pzName, uint32_t secttype, int32_t org,
int32_t bank, int32_t alignment)
@@ -756,7 +764,7 @@ void out_String(char *s)
}
/*
* Output a relocatable byte. Checking will be done to see if it
* Output a relocatable byte. Checking will be done to see if it
* is an absolute value in disguise.
*/
void out_RelByte(struct Expression *expr)
@@ -795,7 +803,7 @@ void out_AbsWord(int32_t b)
}
/*
* Output a relocatable word. Checking will be done to see if
* Output a relocatable word. Checking will be done to see if
* it's an absolute value in disguise.
*/
void out_RelWord(struct Expression *expr)
@@ -839,7 +847,7 @@ void out_AbsLong(int32_t b)
}
/*
* Output a relocatable longword. Checking will be done to see if
* Output a relocatable longword. Checking will be done to see if
* is an absolute value in disguise.
*/
void out_RelLong(struct Expression *expr)
@@ -867,19 +875,31 @@ void out_RelLong(struct Expression *expr)
}
/*
* Output a PC-relative byte
* Output a PC-relative relocatable byte. Checking will be done to see if it
* is an absolute value in disguise.
*/
void out_PCRelByte(struct Expression *expr)
{
int32_t b = expr->nVal;
checkcodesection();
checksectionoverflow(1);
b = (b & 0xFFFF) - (nPC + 1);
if (nPass == 2 && (b < -128 || b > 127))
yyerror("PC-relative value must be 8-bit");
if (rpn_isReloc(expr)) {
if (nPass == 2) {
pCurrentSection->tData[nPC] = 0;
createpatch(PATCH_BYTE_JR, expr);
}
pCurrentSection->nPC += 1;
nPC += 1;
pPCSymbol->nValue += 1;
} else {
int32_t b = expr->nVal;
out_AbsByte(b);
b = (int16_t)((b & 0xFFFF) - (nPC + 1));
if (nPass == 2 && ((b < -128) || (b > 127)))
yyerror("PC-relative value must be 8-bit");
out_AbsByte(b & 0xFF);
}
rpn_Reset(expr);
}

View File

@@ -1,18 +1,11 @@
.\" Copyright © 2010 Anthony J. Bentley <anthony@anjbe.name>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\" This file is part of RGBDS.
.\"
.\" THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" Copyright (c) 2010-2018, Anthony J. Bentley and RGBDS contributors.
.\"
.Dd April 17, 2017
.\" SPDX-License-Identifier: MIT
.\"
.Dd February 24, 2018
.Dt RGBASM 1
.Os RGBDS Manual
.Sh NAME
@@ -20,7 +13,7 @@
.Nd Game Boy assembler
.Sh SYNOPSIS
.Nm rgbasm
.Op Fl EhVvw
.Op Fl EhLVvw
.Op Fl b Ar chars
.Op Fl D Ar name Ns Op = Ns Ar value
.Op Fl g Ar chars
@@ -62,6 +55,12 @@ The
option disables this behavior.
.It Fl i Ar path
Add an include path.
.It Fl L
Disable the optimization that turns loads of the form
.Sy LD [$FF00+n8],A
into the opcode
.Sy LDH [$FF00+n8],A
in order to have full control of the result in the final ROM.
.It Fl M Ar dependfile
Print
.Xr make 1
@@ -82,7 +81,9 @@ Disable warning output.
.Sh EXAMPLES
Assembling a basic source file is simple:
.Pp
.D1 $ rgbasm -o bar.o foo.asm
.Bd -literal -offset indent
$ rgbasm -o bar.o foo.asm
.Ed
.Pp
The resulting object file is not yet a usable ROM image \(em it must first be
run through

View File

@@ -1,18 +1,11 @@
.\" Copyright (c) 2017-2018 Antonio Nino Diaz <antonio_nd@outlook.com>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\" This file is part of RGBDS.
.\"
.\" THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
.\"
.Dd January 7, 2018
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 13, 2018
.Dt RGBASM 5
.Os RGBDS Manual
.Sh NAME
@@ -33,16 +26,46 @@ one instruction or pseudoop per line:
.Pp
Example:
.Pp
.Dl John: ld a,87 ;Weee
.Bd -literal -offset indent
John: ld a,87 ;Weee
.Ed
.Pp
All pseudoops, mnemonics and registers (reserved keywords) are caseinsensitive
and all labels are casesensitive.
.Pp
There are two syntaxes for comments. In both cases, a comment ends at the end of
the line. The most common one is: anything that follows a semicolon
\[dq]\&;\[dq] (that isn't inside a string) is a comment. There is another
format: anything that follows a \[dq]*\[dq] that is placed right at the start of
a line is a comment. The assembler removes all comments from the code before
doing anything else.
.Pp
Sometimes lines can be too long and it may be necessary to split them. The
syntax to do so is the following one:
.Pp
.Bd -literal -offset indent
DB 1, 2, 3, 4 \[rs]
5, 6, 7, 8
.Ed
.Pp
This works anywhere in the code except inside of strings. To split strings it is
needed to use
.Sy STRCAT
like this:
.Pp
.Bd -literal -offset indent
DB STRCAT("Hello ", \[rs]
"world!")
.Ed
.Pp
.Ss Sections
Before you can start writing code, you must define a section.
This tells the assembler what kind of information follows and, if it is code,
where to put it.
.Pp
.Dl SECTION \[dq]CoolStuff\[dq],ROMX
.Bd -literal -offset indent
SECTION \[dq]CoolStuff\[dq],ROMX
.Ed
.Pp
This switches to the section called "CoolStuff" (or creates it if it doesn't
already exist) and it defines it as a code section.
@@ -111,7 +134,13 @@ and
.Sy LDH A,[$FF00+n8]
syntax instead.
This forces the assembler to emit the correct instruction and the linker to
check if the value is in the correct range.
check if the value is in the correct range. This optimization can be disabled
by passing the
.Fl L
flag to
.Sy rgbasm
as explained in
.Xr rgbasm 1 .
.El
.Pp
A section is usually defined as a floating one, but the code can restrict where
@@ -123,22 +152,30 @@ obligation to follow any specific rules.
The following example defines a section that can be placed anywhere in any ROMX
bank:
.Pp
.Dl SECTION \[dq]CoolStuff\[dq],ROMX
.Bd -literal -offset indent
SECTION \[dq]CoolStuff\[dq],ROMX
.Ed
.Pp
If it is needed, the following syntax can be used to fix the base address of the
section:
.Pp
.Dl SECTION \[dq]CoolStuff\[dq],ROMX[$4567]
.Bd -literal -offset indent
SECTION \[dq]CoolStuff\[dq],ROMX[$4567]
.Ed
.Pp
It won't, however, fix the bank number, which is left to the linker.
If you also want to specify the bank you can do:
.Pp
.Dl SECTION \[dq]CoolStuff\[dq],ROMX[$4567],BANK[3]
.Bd -literal -offset indent
SECTION \[dq]CoolStuff\[dq],ROMX[$4567],BANK[3]
.Ed
.Pp
And if you only want to force the section into a certain bank, and not it's
position within the bank, that's also possible:
.Pp
.Dl SECTION \[dq]CoolStuff\[dq],ROMX,BANK[7]
.Bd -literal -offset indent
SECTION \[dq]CoolStuff\[dq],ROMX,BANK[7]
.Ed
.Pp
In addition, you can specify byte alignment for a section.
This ensures that the section starts at a memory address where the given number
@@ -150,9 +187,11 @@ However, if an alignment is specified, the base address must be left unassigned.
This can be useful when using DMA to copy data or when it is needed to align the
start of an array to 256 bytes to optimize the code that accesses it.
.Pp
.Dl SECTION \[dq]OAM Data\[dq],WRAM0,ALIGN[8] ; align to 256 bytes
.Pp
.Dl SECTION \[dq]VRAM Data\[dq],ROMX,BANK[2],ALIGN[4] ; align to 16 bytes
.Bd -literal -offset indent
SECTION \[dq]OAM Data\[dq],WRAM0,ALIGN[8] ; align to 256 bytes
SECTION \[dq]VRAM Data\[dq],ROMX,BANK[2],ALIGN[4] ; align to 16 bytes
.Ed
.Pp
HINT: If you think this is a lot of typing for doing a simple
.Ic ORG
@@ -250,8 +289,10 @@ EQUates are constant symbols.
They can, for example, be used for things such as bit-definitions of hardware
registers.
.Pp
.Dl EXIT_OK EQU $00
.Dl EXIT_FAILURE EQU $01
.Bd -literal -offset indent
EXIT_OK EQU $00
EXIT_FAILURE EQU $01
.Ed
.Pp
Note that a colon (:) following the label-name is not allowed.
EQUates cannot be exported and imported.
@@ -273,7 +314,9 @@ Note that a colon (:) following the label-name is not allowed.
SETs cannot be exported and imported.
Alternatively you can use = as a synonym for SET.
.Pp
.Dl COUNT = 2
.Bd -literal -offset indent
COUNT = 2
.Ed
.Pp
.It Sy RSSET , RSRESET , RB , RW
.Pp
@@ -300,7 +343,7 @@ There are four commands in the RS group of commands:
.Pp
.Bl -column ".Sy String" ".Sy String"
.It Sy Command Ta Ta Ta Sy Meaning
.It Ic RSRESET No Ta Ta Resets the _RS counter to zero.
.It Ic RSRESET Ta Ta Resets the _RS counter to zero.
.It Ic RSSET Ar constexpr Ta Sets the
.Ic _RS No counter to Ar constexpr .
.It Ic RB Ar constexpr Ta Sets the preceding symbol to
@@ -325,10 +368,10 @@ If you are familiar with C you can think of it as the same as #define.
.Pp
.Bd -literal -offset indent
COUNTREG EQUS "[hl+]"
ld a,COUNTREG
ld a,COUNTREG
PLAYER_NAME EQUS \[dq]\[rs]\[dq]John\[rs]\[dq]\[dq]
db PLAYER_NAME
db PLAYER_NAME
.Ed
.Pp
Note that : following the label-name is not allowed, and that strings must be
@@ -336,12 +379,16 @@ quoted to be useful.
.Pp
This will be interpreted as:
.Pp
.Dl ld a,[hl+]
.Dl db \[dq]John\[dq]
.Bd -literal -offset indent
ld a,[hl+]
db \[dq]John\[dq]
.Ed
.Pp
String-symbols can also be used to define small one-line macros:
.Pp
.Dl PUSHA EQUS \[dq]push af\[rs]npush bc\[rs]npush de\[rs]npush hl\[rs]n\[dq]
.Bd -literal -offset indent
PUSHA EQUS \[dq]push af\[rs]npush bc\[rs]npush de\[rs]npush hl\[rs]n\[dq]
.Ed
.Pp
Note that a colon (:) following the label-name is not allowed.
String equates can't be exported or imported.
@@ -454,7 +501,9 @@ Now I can call the macro specifying two arguments.
The first being the address and the second being a bytecount.
The macro will then reset all bytes in this range.
.Pp
.Dl LoopyMacro MyVars,54
.Bd -literal -offset indent
LoopyMacro MyVars,54
.Ed
.Pp
Arguments are passed as string equates.
There's no need to enclose them in quotes.
@@ -474,6 +523,19 @@ In reality, up to 256 arguments can be passed to a macro, but you can only use
the first 9 like this. If you want to use the rest, you need to use the keyword
.Ic SHIFT .
.Pp
Line continuations work as usual inside macros or lists of arguments of macros.
Strings, however, are a bit trickier. The following example shows how to use
strings as arguments for a macro:
.Pp
.Bd -literal -offset indent
PrintMacro : MACRO
PRINTT \[rs]1
ENDM
PrintMacro STRCAT(\[rs]\[dq]Hello\[rs]\[dq]\[rs], \[rs]
\[rs]\[dq] world\[rs]\[rs]n\[rs]\[dq])
.Ed
.Pp
.Ic SHIFT
is a special command only available in macros.
Very useful in REPT-blocks.
@@ -560,7 +622,9 @@ The following symbols are defined by the assembler:
defines a list of bytes that will be stored in the final image.
Ideal for tables and text (which is not zero-terminated).
.Pp
.Dl DB 1,2,3,4,\[dq]This is a string\[dq]
.Bd -literal -offset indent
DB 1,2,3,4,\[dq]This is a string\[dq]
.Ed
.Pp
Alternatively, you can use
.Ic DW
@@ -604,7 +668,9 @@ and
.Ic DL
without any arguments instead.
.Pp
.Dl DS str_SIZEOF ;allocate str_SIZEOF bytes
.Bd -literal -offset indent
DS str_SIZEOF ;allocate str_SIZEOF bytes
.Ed
.Pp
.Ss Including binary files
You probably have some graphics you'd like to include.
@@ -614,15 +680,19 @@ to include a raw binary file as it is.
If the file isn't found in the current directory, the include-path list passed
to the linker on the command line will be searched.
.Pp
.Dl INCBIN \[dq]titlepic.bin\[dq]
.Dl INCBIN \[dq]sprites/hero.bin\[dq]\ ; UNIX
.Dl INCBIN \[dq]sprites\[rs]\[rs]hero.bin\[dq]\ ; Windows
.Bd -literal -offset indent
INCBIN \[dq]titlepic.bin\[dq]
INCBIN \[dq]sprites/hero.bin\[dq]\ ; UNIX
INCBIN \[dq]sprites\[rs]\[rs]hero.bin\[dq]\ ; Windows
.Ed
.Pp
You can also include only part of a file with
.Ic INCBIN .
The example below includes 256 bytes from data.bin starting from byte 78.
.Pp
.Dl INCBIN \[dq]data.bin\[dq],78,256
.Bd -literal -offset indent
INCBIN \[dq]data.bin\[dq],78,256
.Ed
.Ss Unions
Unions allow multiple memory allocations to share the same space in memory,
like unions in C.
@@ -667,16 +737,19 @@ some important information.
.Pp
.Bd -literal -offset indent
PRINTT \[dq]I'm the greatest programmer in the whole wide world\[rs]n\[dq]
PRINTV (2+3)/5
PRINTF MUL(3.14,3987.0)
PRINTI (2 + 3) / 5
PRINTV $FF00 + $F0
PRINTF MUL(3.14, 3987.0)
.Ed
.Pp
.Bl -inset
.It Ic PRINTT
prints out a string.
.It Ic PRINTV
prints out an integer value or, as in the example, the result of a calculation.
Unsurprisingly, you can also print out a constant symbols value.
prints out an integer value in hexadecimal or, as in the example, the result of
a calculation. Unsurprisingly, you can also print out a constant symbols value.
.It Ic PRINTI
prints out a signed integer value.
.It Ic PRINTF
prints out a fixed point value.
.El
@@ -747,7 +820,9 @@ You may nest
.Ic INCLUDE
calls infinitely (or until you run out of memory, whichever comes first).
.Pp
.Dl INCLUDE \[dq]irq.inc\[dq]
.Bd -literal -offset indent
INCLUDE \[dq]irq.inc\[dq]
.Ed
.Pp
.Ss Conditional assembling
The four commands
@@ -823,7 +898,9 @@ The last one, Gameboy graphics, is quite interesting and useful.
The values are actually pixel values and it converts the
.Do chunky Dc data to Do planar Dc data as used in the Gameboy.
.Pp
.Dl DW \`01012323
.Bd -literal -offset indent
DW \`01012323
.Ed
.Pp
Admittedly, an expression with just a single number is quite boring.
To spice things up a bit there are a few operators you can use to perform
@@ -964,6 +1041,34 @@ new string.
the new string.
.El
.Pp
.Ss Character maps
.Pp
When writing text that is meant to be displayed in the Game Boy, the ASCII
characters used in the source code may not be the same ones used in the tileset
used in the ROM.
For example, the tiles used for uppercase letters may be placed starting at tile
index 128, which makes it difficult to add text strings to the ROM.
.Pp
Character maps allow the code to map strings up to 16 characters long to an
abitrary 8-bit value:
.Pp
.Bd -literal -offset indent
CHARMAP "<LF>", 10
CHARMAP "&iacute", 20
CHARMAP "A", 128
.Ed
.Pp
.Sy Note:
Character maps affect all strings in the file from the point in which they are
defined.
This means that any string that the code may want to print as debug information
will also be affected by it.
.Pp
.Sy Note:
The output value of a mapping can be 0.
If this happens, the assembler will treat this as the end of the string and the
rest of it will be trimmed.
.Pp
.Ss Other functions
There are a few other functions that do various useful things:
.Pp
@@ -1046,6 +1151,7 @@ machine.
.It Sx ATAN
.It Sx ATAN2
.It Sx BANK
.It Sx CHARMAP
.It Sx COS
.It Sx DB
.It Sx DEF
@@ -1075,6 +1181,7 @@ machine.
.It Sx POPO
.It Sx POPS
.It Sx PRINTF
.It Sx PRINTI
.It Sx PRINTT
.It Sx PRINTV
.It Sx PURGE

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/*
* Controls RPN expressions for objectfiles
*/

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/*
* Symboltable and macroargs stuff
*/
@@ -16,7 +24,8 @@
#include "asm/output.h"
#include "extern/err.h"
#include "extern/version.h"
#include "version.h"
struct sSymbol *tHashedSymbols[HASHSIZE];
static struct sSymbol *pScope; /* Current section symbol scope */
@@ -31,7 +40,7 @@ static char SavedTIMESTAMP_ISO8601_LOCAL[256];
static char SavedTIMESTAMP_ISO8601_UTC[256];
static char SavedDAY[3];
static char SavedMONTH[3];
static char SavedYEAR[5];
static char SavedYEAR[20];
static char SavedHOUR[3];
static char SavedMINUTE[3];
static char SavedSECOND[3];
@@ -113,7 +122,9 @@ struct sSymbol *createsymbol(char *s)
return NULL;
}
strcpy((*ppsym)->tzName, s);
if (snprintf((*ppsym)->tzName, MAXSYMLEN + 1, "%s", s) > MAXSYMLEN)
warning("Symbol name is too long: '%s'", s);
(*ppsym)->nValue = 0;
(*ppsym)->nType = 0;
(*ppsym)->pScope = NULL;
@@ -121,7 +132,13 @@ struct sSymbol *createsymbol(char *s)
(*ppsym)->pMacro = NULL;
(*ppsym)->pSection = NULL;
(*ppsym)->Callback = NULL;
strcpy((*ppsym)->tzFileName, tzCurrentFileName);
if (snprintf((*ppsym)->tzFileName, _MAX_PATH + 1, "%s",
tzCurrentFileName) > _MAX_PATH) {
fatalerror("%s: File name is too long: '%s'", __func__,
tzCurrentFileName);
}
(*ppsym)->nFileLine = fstk_GetLine();
return *ppsym;
}
@@ -500,7 +517,7 @@ void sym_SetMacroArgID(uint32_t nMacroCount)
{
char s[256];
sprintf(s, "_%u", nMacroCount);
snprintf(s, sizeof(s), "_%u", nMacroCount);
newmacroargs[MAXMACROARGS] = strdup(s);
}
@@ -551,7 +568,7 @@ void sym_AddEqu(char *tzSym, int32_t value)
*
* If the desired symbol is a string it needs to be passed to this function with
* quotes inside the string, like sym_AddString("name", "\"test\"), or the
* assembler won't be able to use it with DB and similar. This is equivalent as
* assembler won't be able to use it with DB and similar. This is equivalent to
* ``` name EQUS "\"test\"" ```
*
* If the desired symbol is a register or a number, just the terminator quotes
@@ -956,16 +973,22 @@ void sym_Init(void)
* The '?' have to be escaped or they will be treated as
* trigraphs...
*/
strcpy(SavedTIME, "\"\?\?:\?\?:\?\?\"");
strcpy(SavedDATE, "\"\?\? \?\?\? \?\?\?\?\"");
strcpy(SavedTIMESTAMP_ISO8601_LOCAL, "\"\?\?\?\?-\?\?-\?\?T\?\?:\?\?:\?\?+\?\?\?\?\"");
strcpy(SavedTIMESTAMP_ISO8601_UTC, "\"\?\?\?\?-\?\?-\?\?T\?\?:\?\?:\?\?Z\"");
strcpy(SavedDAY, "1");
strcpy(SavedMONTH, "1");
strcpy(SavedYEAR, "1900");
strcpy(SavedHOUR, "0");
strcpy(SavedMINUTE, "0");
strcpy(SavedSECOND, "0");
snprintf(SavedTIME, sizeof(SavedTIME),
"\"\?\?:\?\?:\?\?\"");
snprintf(SavedDATE, sizeof(SavedDATE),
"\"\?\? \?\?\? \?\?\?\?\"");
snprintf(SavedTIMESTAMP_ISO8601_LOCAL,
sizeof(SavedTIMESTAMP_ISO8601_LOCAL),
"\"\?\?\?\?-\?\?-\?\?T\?\?:\?\?:\?\?+\?\?\?\?\"");
snprintf(SavedTIMESTAMP_ISO8601_UTC,
sizeof(SavedTIMESTAMP_ISO8601_UTC),
"\"\?\?\?\?-\?\?-\?\?T\?\?:\?\?:\?\?Z\"");
snprintf(SavedDAY, sizeof(SavedDAY), "1");
snprintf(SavedMONTH, sizeof(SavedMONTH), "1");
snprintf(SavedYEAR, sizeof(SavedYEAR), "1900");
snprintf(SavedHOUR, sizeof(SavedHOUR), "0");
snprintf(SavedMINUTE, sizeof(SavedMINUTE), "0");
snprintf(SavedSECOND, sizeof(SavedSECOND), "0");
}
sym_AddString("__TIME__", SavedTIME);

21
src/extern/err.c vendored
View File

@@ -1,24 +1,9 @@
/*
* Copyright © 2005-2013 Rich Felker, et al.
* This file is part of RGBDS.
*
* 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:
* Copyright (c) 2005-2018, Rich Felker and RGBDS contributors.
*
* 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.
* SPDX-License-Identifier: MIT
*/
#include <stdarg.h>

View File

@@ -1,37 +0,0 @@
/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
/*
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
/*
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
*/
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
void *rgbds_reallocarray(void *optr, size_t nmemb, size_t size)
{
if (((nmemb >= MUL_NO_OVERFLOW) || (size >= MUL_NO_OVERFLOW)) &&
(nmemb > 0) && (SIZE_MAX / nmemb < size)) {
errno = ENOMEM;
return NULL;
}
return realloc(optr, size * nmemb);
}

54
src/extern/strlcat.c vendored
View File

@@ -1,54 +0,0 @@
/* $OpenBSD: strlcat.c,v 1.14 2015/01/15 03:54:12 millert Exp $ */
/*
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include <sys/types.h>
/*
* Appends src to string dst of size dsize (unlike strncat, dsize is the
* full size of dst, not space left). At most dsize-1 characters
* will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
* Returns strlen(src) + MIN(dsize, strlen(initial dst)).
* If retval >= dsize, truncation occurred.
*/
size_t rgbds_strlcat(char *dst, const char *src, size_t dsize)
{
const char *odst = dst;
const char *osrc = src;
size_t n = dsize;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end. */
while (n-- != 0 && *dst != '\0')
dst++;
dlen = dst - odst;
n = dsize - dlen;
if (n-- == 0)
return(dlen + strlen(src));
while (*src != '\0') {
if (n != 0) {
*dst++ = *src;
n--;
}
src++;
}
*dst = '\0';
return dlen + (src - osrc); /* count does not include NUL */
}

52
src/extern/strlcpy.c vendored
View File

@@ -1,52 +0,0 @@
/* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */
/*
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include <sys/types.h>
/*
* Copy string src to buffer dst of size dsize. At most dsize-1
* chars will be copied. Always NUL terminates (unless dsize == 0).
* Returns strlen(src); if retval >= dsize, truncation occurred.
*/
size_t rgbds_strlcpy(char *dst, const char *src, size_t dsize)
{
const char *osrc = src;
size_t nleft = dsize;
/* Copy as many bytes as will fit. */
if (nleft != 0) {
while (--nleft != 0) {
char n = *src++;
*dst++ = n;
if (n == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src. */
if (nleft == 0) {
if (dsize != 0)
*dst = '\0'; /* NUL-terminate dst */
while (*src++)
;
}
return (src - osrc - 1); /* count does not include NUL */
}

54
src/extern/utf8decoder.c vendored Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2008-2009, Björn Höhrmann <bjoern@hoehrmann.de>
*
* SPDX-License-Identifier: MIT
*/
/*
* UTF-8 decoder: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
*/
#include <stdint.h>
static const uint8_t utf8d[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00..0f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10..1f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20..2f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30..3f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40..4f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50..5f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60..6f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70..7f */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80..8f */
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* 90..9f */
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* a0..af */
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* b0..bf */
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* c0..cf */
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* d0..df */
0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, /* e0..e7 */
0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, /* e8..ef */
0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, /* f0..f7 */
0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, /* f8..ff */
0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, /* s0.. */
0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, /* ..s0 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* s1 */
1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, /* s1 */
1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, /* s3 */
1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, /* s4 */
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, /* s5 */
1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, /* s6 */
1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, /* s7 */
1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* s8 */
};
uint32_t decode(uint32_t *state, uint32_t *codep, uint32_t byte)
{
uint32_t type = utf8d[byte];
*codep = (*state != 0) ?
(byte & 0x3fu) | (*codep << 6) :
(0xff >> type) & (byte);
*state = utf8d[256 + *state * 16 + type];
return *state;
}

34
src/extern/version.c vendored
View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) 2017 Antonio Nino Diaz <antonio_nd@outlook.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include "extern/version.h"
const char *get_package_version_string(void)
{
static char s[50];
/* The following conditional should be simplified by the compiler. */
if (strlen(BUILD_VERSION_STRING) == 0) {
snprintf(s, sizeof(s), "v%d.%d.%d", PACKAGE_VERSION_MAJOR,
PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCH);
return s;
} else {
return BUILD_VERSION_STRING;
}
}

View File

@@ -1,17 +1,9 @@
/*
* Copyright © 2010 Anthony J. Bentley <anthonyjbentley@gmail.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2010-2018, Anthony J. Bentley and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
#include <stdbool.h>
@@ -22,14 +14,15 @@
#include <unistd.h>
#include "extern/err.h"
#include "extern/version.h"
#include "version.h"
static void print_usage(void)
{
printf(
"usage: rgbfix [-CcjsVv] [-i game_id] [-k licensee_str] [-l licensee_id]\n"
" [-m mbc_type] [-n rom_version] [-p pad_value] [-r ram_size]\n"
" [-t title_str] file\n");
"usage: rgbfix [-CcjsVv] [-f fix_spec] [-i game_id] [-k licensee_str]\n"
" [-l licensee_id] [-m mbc_type] [-n rom_version] [-p pad_value]\n"
" [-r ram_size] [-t title_str] file\n");
exit(1);
}
@@ -44,7 +37,12 @@ int main(int argc, char *argv[])
*/
/* all flags default to false unless options specify otherwise */
bool validate = false;
bool fixlogo = false;
bool fixheadsum = false;
bool fixglobalsum = false;
bool trashlogo = false;
bool trashheadsum = false;
bool trashglobalsum = false;
bool settitle = false;
bool setid = false;
bool colorcompatible = false;
@@ -68,7 +66,7 @@ int main(int argc, char *argv[])
int version = 0; /* mask ROM version number */
int padvalue = 0; /* to pad the rom with if it changes size */
while ((ch = getopt(argc, argv, "Cci:jk:l:m:n:p:sr:t:Vv")) != -1) {
while ((ch = getopt(argc, argv, "Ccf:i:jk:l:m:n:p:sr:t:Vv")) != -1) {
switch (ch) {
case 'C':
coloronly = true;
@@ -76,6 +74,14 @@ int main(int argc, char *argv[])
case 'c':
colorcompatible = true;
break;
case 'f':
fixlogo = strchr(optarg, 'l');
fixheadsum = strchr(optarg, 'h');
fixglobalsum = strchr(optarg, 'g');
trashlogo = strchr(optarg, 'L');
trashheadsum = strchr(optarg, 'H');
trashglobalsum = strchr(optarg, 'G');
break;
case 'i':
setid = true;
@@ -175,7 +181,9 @@ int main(int argc, char *argv[])
printf("rgbfix %s\n", get_package_version_string());
exit(0);
case 'v':
validate = true;
fixlogo = true;
fixheadsum = true;
fixglobalsum = true;
break;
default:
print_usage();
@@ -202,7 +210,7 @@ int main(int argc, char *argv[])
* Write changes to ROM
*/
if (validate) {
if (fixlogo || trashlogo) {
/*
* Offset 0x1040x133: Nintendo Logo
* This is a bitmap image that displays when the Game Boy is
@@ -212,7 +220,7 @@ int main(int argc, char *argv[])
/*
* See also: global checksums at 0x14D0x14F, They must
* also be correct for the game to boot, so we fix them
* as well when the -v flag is set.
* as well when requested with the -f flag.
*/
uint8_t ninlogo[48] = {
@@ -224,6 +232,10 @@ int main(int argc, char *argv[])
0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E
};
if (trashlogo)
for (int i = 0; i < sizeof(ninlogo); i++)
ninlogo[i] = ~ninlogo[i];
fseek(rom, 0x104, SEEK_SET);
fwrite(ninlogo, 1, 48, rom);
}
@@ -422,7 +434,7 @@ int main(int argc, char *argv[])
fputc(version, rom);
}
if (validate) {
if (fixheadsum || trashheadsum) {
/*
* Offset 0x14D: Header Checksum
*/
@@ -433,9 +445,14 @@ int main(int argc, char *argv[])
for (int i = 0; i < (0x14D - 0x134); ++i)
headcksum = headcksum - fgetc(rom) - 1;
if (trashheadsum)
headcksum = ~headcksum;
fseek(rom, 0x14D, SEEK_SET);
fputc(headcksum, rom);
}
if (fixglobalsum || trashglobalsum) {
/*
* Offset 0x14E0x14F: Global Checksum
*/
@@ -452,6 +469,9 @@ int main(int argc, char *argv[])
while ((byte = fgetc(rom)) != EOF)
globalcksum += byte;
if (trashglobalsum)
globalcksum = ~globalcksum;
fseek(rom, 0x14E, SEEK_SET);
fputc(globalcksum >> 8, rom);
fputc(globalcksum & 0xFF, rom);

View File

@@ -1,18 +1,11 @@
.\" Copyright © 2010 Anthony J. Bentley <anthony@anjbe.name>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\" This file is part of RGBDS.
.\"
.\" THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" Copyright (c) 2010-2017, Anthony J. Bentley and RGBDS contributors.
.\"
.Dd April 17, 2017
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 11, 2018
.Dt RGBFIX 1
.Os RGBDS Manual
.Sh NAME
@@ -21,6 +14,7 @@
.Sh SYNOPSIS
.Nm rgbfix
.Op Fl CcjsVv
.Op Fl f Ar fix_spec
.Op Fl i Ar game_id
.Op Fl k Ar licensee_str
.Op Fl l Ar licensee_id
@@ -53,6 +47,30 @@ If both this and the
flag are set,
.Fl C
takes precedence.
.It Fl f 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
is a string containing any combination of the following characters:
.Pp
.Bl -tag -compact -width xx
.It Cm l
Fix the Nintendo logo
.Pq Ad 0x104 Ns \(en Ns Ad 0x133 .
.It Cm L
Trash the Nintendo logo.
.It Cm h
Fix the header checksum
.Pq Ad 0x14D .
.It Cm H
Trash the header checksum.
.It Cm g
Fix the global checksum
.Pq Ad 0x14E Ns \(en Ns Ad 0x14F .
.It Cm G
Trash the global checksum.
.El
.It Fl i Ar game_id
Set the game ID string
.Pq Ad 0x13F Ns \(en Ns Ad 0x142
@@ -111,12 +129,8 @@ overlapping portion of the title.
.It Fl V
Print the version of the program and exit.
.It Fl v
Validate the header and fix checksums: the Nintendo character area
.Pq Ad 0x104 Ns \(en Ns Ad 0x133 ,
the header checksum
.Pq Ad 0x14D ,
and the global checksum
.Pq Ad 0x14E Ns \(en Ns Ad 0x14F .
Equivalent to
.Fl f Cm lhg .
.El
.Sh EXAMPLES
Most values in the ROM header are only cosmetic.

View File

@@ -1,18 +1,11 @@
.\" Copyright (c) 2017 Antonio Nino Diaz <antonio_nd@outlook.com>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\" This file is part of RGBDS.
.\"
.\" THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
.\"
.Dd April 17, 2017
.\" SPDX-License-Identifier: MIT
.\"
.Dd February 23, 2018
.Dt GBZ80 7
.Os RGBDS Manual
.Sh NAME
@@ -31,8 +24,10 @@ as destination can omit the destination as it is assumed it's register
.Sy A .
The following two lines have the same effect:
.Pp
.Dl OR A,B
.Dl OR B
.Bd -literal -offset indent
OR A,B
OR B
.Ed
.Pp
.Sh LEGEND
List of abbreviations used in this document.
@@ -1669,7 +1664,7 @@ Flags: See
.Sx SRA r8
.Ss STOP
Enter CPU very low power mode.
Also used to switch between doube speed and normal CPU modes in GBC.
Also used to switch between double and normal speed CPU modes in GBC.
.Pp
Cycles: -
.Pp

View File

@@ -1,19 +1,12 @@
/*
* Copyright © 2013 stag019 <stag019@gmail.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -39,23 +32,18 @@ void transpose_tiles(struct GBImage *gb, int width)
gb->data = newdata;
}
void png_to_gb(const struct PNGImage png, struct GBImage *gb)
void raw_to_gb(const struct RawIndexedImage *raw_image, struct GBImage *gb)
{
int x, y, byte;
png_byte index;
uint8_t index;
for (y = 0; y < png.height; y++) {
for (x = 0; x < png.width; x++) {
index = png.data[y][x];
for (y = 0; y < raw_image->height; y++) {
for (x = 0; x < raw_image->width; x++) {
index = raw_image->data[y][x];
index &= (1 << depth) - 1;
if (!gb->horizontal) {
byte = y * depth
+ x / 8 * png.height / 8 * 8 * depth;
} else {
byte = y * depth
+ x / 8 * png.height / 8 * 8 * depth;
}
byte = y * depth
+ x / 8 * raw_image->height / 8 * 8 * depth;
gb->data[byte] |= (index & 1) << (7 - x % 8);
if (depth == 2) {
gb->data[byte + 1] |=
@@ -65,18 +53,18 @@ void png_to_gb(const struct PNGImage png, struct GBImage *gb)
}
if (!gb->horizontal)
transpose_tiles(gb, png.width / 8);
transpose_tiles(gb, raw_image->width / 8);
}
void output_file(const struct Options opts, const struct GBImage gb)
void output_file(const struct Options *opts, const struct GBImage *gb)
{
FILE *f;
f = fopen(opts.outfile, "wb");
f = fopen(opts->outfile, "wb");
if (!f)
err(1, "Opening output file '%s' failed", opts.outfile);
err(1, "Opening output file '%s' failed", opts->outfile);
fwrite(gb.data, 1, gb.size - gb.trim * 8 * depth, f);
fwrite(gb->data, 1, gb->size - gb->trim * 8 * depth, f);
fclose(f);
}
@@ -97,7 +85,7 @@ int get_tile_index(uint8_t *tile, uint8_t **tiles, int num_tiles, int tile_size)
return -1;
}
void create_tilemap(const struct Options opts, struct GBImage *gb,
void create_tilemap(const struct Options *opts, struct GBImage *gb,
struct Tilemap *tilemap)
{
int i, j;
@@ -113,10 +101,15 @@ void create_tilemap(const struct Options opts, struct GBImage *gb,
tile_size = sizeof(uint8_t) * depth * 8;
gb_size = gb->size - (gb->trim * tile_size);
max_tiles = gb_size / tile_size;
tiles = malloc(sizeof(uint8_t *) * max_tiles);
/* If the input image doesn't fill the last tile, increase the count. */
if (gb_size > max_tiles * tile_size)
max_tiles++;
tiles = calloc(max_tiles, sizeof(uint8_t *));
num_tiles = 0;
tilemap->data = malloc(sizeof(uint8_t) * max_tiles);
tilemap->data = calloc(max_tiles, sizeof(uint8_t));
tilemap->size = 0;
gb_i = 0;
@@ -126,7 +119,7 @@ void create_tilemap(const struct Options opts, struct GBImage *gb,
tile[i] = gb->data[gb_i];
gb_i++;
}
if (opts.unique) {
if (opts->unique) {
index = get_tile_index(tile, tiles, num_tiles,
tile_size);
if (index < 0) {
@@ -143,7 +136,7 @@ void create_tilemap(const struct Options opts, struct GBImage *gb,
tilemap->size++;
}
if (opts.unique) {
if (opts->unique) {
free(gb->data);
gb->data = malloc(tile_size * num_tiles);
for (i = 0; i < num_tiles; i++) {
@@ -160,43 +153,44 @@ void create_tilemap(const struct Options opts, struct GBImage *gb,
free(tiles);
}
void output_tilemap_file(const struct Options opts,
const struct Tilemap tilemap)
void output_tilemap_file(const struct Options *opts,
const struct Tilemap *tilemap)
{
FILE *f;
f = fopen(opts.mapfile, "wb");
f = fopen(opts->mapfile, "wb");
if (!f)
err(1, "Opening tilemap file '%s' failed", opts.mapfile);
err(1, "Opening tilemap file '%s' failed", opts->mapfile);
fwrite(tilemap.data, 1, tilemap.size, f);
fwrite(tilemap->data, 1, tilemap->size, f);
fclose(f);
if (opts.mapout)
free(opts.mapfile);
if (opts->mapout)
free(opts->mapfile);
}
void output_palette_file(const struct Options opts, const struct PNGImage png)
void output_palette_file(const struct Options *opts,
const struct RawIndexedImage *raw_image)
{
FILE *f;
int i, colors, color;
png_color *palette;
int i, color;
uint8_t cur_bytes[2];
if (png_get_PLTE(png.png, png.info, &palette, &colors)) {
f = fopen(opts.palfile, "wb");
if (!f) {
err(1, "Opening palette file '%s' failed",
opts.palfile);
}
for (i = 0; i < colors; i++) {
color = palette[i].blue >> 3 << 10
| palette[i].green >> 3 << 5
| palette[i].red >> 3;
fwrite(&color, 2, 1, f);
}
fclose(f);
f = fopen(opts->palfile, "wb");
if (!f)
err(1, "Opening palette file '%s' failed", opts->palfile);
for (i = 0; i < raw_image->num_colors; i++) {
color =
raw_image->palette[i].blue >> 3 << 10 |
raw_image->palette[i].green >> 3 << 5 |
raw_image->palette[i].red >> 3;
cur_bytes[0] = color & 0xFF;
cur_bytes[1] = color >> 8;
fwrite(cur_bytes, 2, 1, f);
}
fclose(f);
if (opts.palout)
free(opts.palfile);
if (opts->palout)
free(opts->palfile);
}

View File

@@ -1,27 +1,20 @@
/*
* Copyright © 2013 stag019 <stag019@gmail.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
#include <png.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "extern/version.h"
#include "gfx/main.h"
#include "version.h"
static void print_usage(void)
{
printf(
@@ -34,7 +27,8 @@ int main(int argc, char *argv[])
{
int ch, size;
struct Options opts = {0};
struct PNGImage png = {0};
struct ImageOptions png_options = {0};
struct RawIndexedImage *raw_image;
struct GBImage gb = {0};
struct Tilemap tilemap = {0};
char *ext;
@@ -110,80 +104,89 @@ int main(int argc, char *argv[])
colors = 1 << depth;
input_png_file(opts, &png);
raw_image = input_png_file(&opts, &png_options);
png.mapfile = "";
png.palfile = "";
png_options.mapfile = "";
png_options.palfile = "";
get_text(&png);
if (png.horizontal != opts.horizontal) {
if (png_options.horizontal != opts.horizontal) {
if (opts.verbose)
warnx(errmsg, "horizontal");
if (opts.hardfix)
png.horizontal = opts.horizontal;
png_options.horizontal = opts.horizontal;
}
if (png.horizontal)
opts.horizontal = png.horizontal;
if (png_options.horizontal)
opts.horizontal = png_options.horizontal;
if (png.trim != opts.trim) {
if (png_options.trim != opts.trim) {
if (opts.verbose)
warnx(errmsg, "trim");
if (opts.hardfix)
png.trim = opts.trim;
png_options.trim = opts.trim;
}
if (png.trim)
opts.trim = png.trim;
if (png_options.trim)
opts.trim = png_options.trim;
if (opts.trim > png.width / 8 - 1) {
errx(1, "Trim (%i) for input png file '%s' too large (max: %i)",
opts.trim, opts.infile, png.width / 8 - 1);
if (raw_image->width % 8) {
errx(1, "Input PNG file %s not sized correctly. The image's width must be a multiple of 8.",
opts.infile);
}
if (raw_image->width / 8 > 1 && raw_image->height % 8) {
errx(1, "Input PNG file %s not sized correctly. If the image is more than 1 tile wide, its height must be a multiple of 8.",
opts.infile);
}
if (strcmp(png.mapfile, opts.mapfile) != 0) {
if (opts.trim &&
opts.trim > (raw_image->width / 8) * (raw_image->height / 8) - 1) {
errx(1, "Trim (%i) for input raw_image file '%s' too large (max: %i)",
opts.trim, opts.infile,
(raw_image->width / 8) * (raw_image->height / 8) - 1);
}
if (strcmp(png_options.mapfile, opts.mapfile) != 0) {
if (opts.verbose)
warnx(errmsg, "tilemap file");
if (opts.hardfix)
png.mapfile = opts.mapfile;
png_options.mapfile = opts.mapfile;
}
if (!*opts.mapfile)
opts.mapfile = png.mapfile;
opts.mapfile = png_options.mapfile;
if (png.mapout != opts.mapout) {
if (png_options.mapout != opts.mapout) {
if (opts.verbose)
warnx(errmsg, "tilemap file");
if (opts.hardfix)
png.mapout = opts.mapout;
png_options.mapout = opts.mapout;
}
if (png.mapout)
opts.mapout = png.mapout;
if (png_options.mapout)
opts.mapout = png_options.mapout;
if (strcmp(png.palfile, opts.palfile) != 0) {
if (strcmp(png_options.palfile, opts.palfile) != 0) {
if (opts.verbose)
warnx(errmsg, "palette file");
if (opts.hardfix)
png.palfile = opts.palfile;
png_options.palfile = opts.palfile;
}
if (!*opts.palfile)
opts.palfile = png.palfile;
opts.palfile = png_options.palfile;
if (png.palout != opts.palout) {
if (png_options.palout != opts.palout) {
if (opts.verbose)
warnx(errmsg, "palette file");
if (opts.hardfix)
png.palout = opts.palout;
png_options.palout = opts.palout;
}
if (png.palout)
opts.palout = png.palout;
if (png_options.palout)
opts.palout = png_options.palout;
if (!*opts.mapfile && opts.mapout) {
ext = strrchr(opts.infile, '.');
@@ -217,31 +220,29 @@ int main(int argc, char *argv[])
}
}
gb.size = png.width * png.height * depth / 8;
gb.size = raw_image->width * raw_image->height * depth / 8;
gb.data = calloc(gb.size, 1);
gb.trim = opts.trim;
gb.horizontal = opts.horizontal;
if (*opts.outfile || *opts.mapfile) {
png_to_gb(png, &gb);
create_tilemap(opts, &gb, &tilemap);
raw_to_gb(raw_image, &gb);
create_tilemap(&opts, &gb, &tilemap);
}
if (*opts.outfile)
output_file(opts, gb);
output_file(&opts, &gb);
if (*opts.mapfile)
output_tilemap_file(opts, tilemap);
output_tilemap_file(&opts, &tilemap);
if (*opts.palfile)
output_palette_file(opts, png);
output_palette_file(&opts, raw_image);
if (opts.fix || opts.debug) {
set_text(&png);
output_png_file(opts, &png);
}
if (opts.fix || opts.debug)
output_png_file(&opts, &png_options, raw_image);
free_png_data(&png);
destroy_raw_image(&raw_image);
free(gb.data);
return 0;

View File

@@ -1,38 +1,155 @@
/*
* Copyright © 2013 stag019 <stag019@gmail.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2013-2018, stag019 and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
#include <png.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gfx/main.h"
void input_png_file(const struct Options opts, struct PNGImage *img)
static void initialize_png(struct PNGImage *img, FILE *f);
static struct RawIndexedImage *indexed_png_to_raw(struct PNGImage *img);
static struct RawIndexedImage *grayscale_png_to_raw(struct PNGImage *img);
static struct RawIndexedImage *truecolor_png_to_raw(struct PNGImage *img);
static void get_text(const struct PNGImage *img,
struct ImageOptions *png_options);
static void set_text(const struct PNGImage *img,
const struct ImageOptions *png_options);
static void free_png_data(const struct PNGImage *png);
struct RawIndexedImage *input_png_file(const struct Options *opts,
struct ImageOptions *png_options)
{
struct PNGImage img;
struct RawIndexedImage *raw_image;
FILE *f;
f = fopen(opts->infile, "rb");
if (!f)
err(1, "Opening input png file '%s' failed", opts->infile);
initialize_png(&img, f);
if (img.depth != depth) {
if (opts->verbose) {
warnx("Image bit depth is not %i (is %i).",
depth, img.depth);
}
}
switch (img.type) {
case PNG_COLOR_TYPE_PALETTE:
raw_image = indexed_png_to_raw(&img); break;
case PNG_COLOR_TYPE_GRAY:
case PNG_COLOR_TYPE_GRAY_ALPHA:
raw_image = grayscale_png_to_raw(&img); break;
case PNG_COLOR_TYPE_RGB:
case PNG_COLOR_TYPE_RGB_ALPHA:
raw_image = truecolor_png_to_raw(&img); break;
default:
/* Shouldn't happen, but might as well handle just in case. */
errx(1, "Input PNG file is of invalid color type.");
}
get_text(&img, png_options);
png_destroy_read_struct(&img.png, &img.info, NULL);
fclose(f);
free_png_data(&img);
return raw_image;
}
void output_png_file(const struct Options *opts,
const struct ImageOptions *png_options,
const struct RawIndexedImage *raw_image)
{
FILE *f;
int i, y, num_trans;
bool has_palette = false;
png_byte *trans_alpha;
png_color_16 *trans_values;
bool *full_alpha;
png_color *palette;
char *outfile;
struct PNGImage img;
png_color *png_palette;
int i;
f = fopen(opts.infile, "rb");
/*
* TODO: Variable outfile is for debugging purposes. Eventually,
* opts.infile will be used directly.
*/
if (opts->debug) {
outfile = malloc(strlen(opts->infile) + 5);
strcpy(outfile, opts->infile);
strcat(outfile, ".out");
} else {
outfile = opts->infile;
}
f = fopen(outfile, "wb");
if (!f)
err(1, "Opening input png file '%s' failed", opts.infile);
err(1, "Opening output png file '%s' failed", outfile);
img.png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL);
if (!img.png)
errx(1, "Creating png structure failed");
img.info = png_create_info_struct(img.png);
if (!img.info)
errx(1, "Creating png info structure failed");
if (setjmp(png_jmpbuf(img.png)))
exit(1);
png_init_io(img.png, f);
png_set_IHDR(img.png, img.info, raw_image->width, raw_image->height,
8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_palette = malloc(sizeof(png_color *) * raw_image->num_colors);
for (i = 0; i < raw_image->num_colors; i++) {
png_palette[i].red = raw_image->palette[i].red;
png_palette[i].green = raw_image->palette[i].green;
png_palette[i].blue = raw_image->palette[i].blue;
}
png_set_PLTE(img.png, img.info, png_palette, raw_image->num_colors);
free(png_palette);
if (opts->fix)
set_text(&img, png_options);
png_write_info(img.png, img.info);
png_write_image(img.png, (png_byte **) raw_image->data);
png_write_end(img.png, NULL);
png_destroy_write_struct(&img.png, &img.info);
fclose(f);
if (opts->debug)
free(outfile);
}
void destroy_raw_image(struct RawIndexedImage **raw_image_ptr_ptr)
{
int y;
struct RawIndexedImage *raw_image = *raw_image_ptr_ptr;
for (y = 0; y < raw_image->height; y++)
free(raw_image->data[y]);
free(raw_image->data);
free(raw_image->palette);
free(raw_image);
*raw_image_ptr_ptr = NULL;
}
static void initialize_png(struct PNGImage *img, FILE *f)
{
img->png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL);
if (!img->png)
@@ -42,7 +159,6 @@ void input_png_file(const struct Options opts, struct PNGImage *img)
if (!img->info)
errx(1, "Creating png info structure failed");
/* TODO: Better error handling here? */
if (setjmp(png_jmpbuf(img->png)))
exit(1);
@@ -54,125 +170,413 @@ void input_png_file(const struct Options opts, struct PNGImage *img)
img->height = png_get_image_height(img->png, img->info);
img->depth = png_get_bit_depth(img->png, img->info);
img->type = png_get_color_type(img->png, img->info);
}
if (img->type & PNG_COLOR_MASK_ALPHA)
png_set_strip_alpha(img->png);
static void read_png(struct PNGImage *img);
static struct RawIndexedImage *create_raw_image(int width, int height,
int num_colors);
static void set_raw_image_palette(struct RawIndexedImage *raw_image,
const png_color *palette, int num_colors);
if (img->depth != depth) {
if (opts.verbose) {
warnx("Image bit depth is not %i (is %i).", depth,
img->depth);
}
}
static struct RawIndexedImage *indexed_png_to_raw(struct PNGImage *img)
{
struct RawIndexedImage *raw_image;
png_color *palette;
int colors_in_PLTE;
int colors_in_new_palette;
png_byte *trans_alpha;
int num_trans;
png_color_16 *trans_color;
png_color *original_palette;
uint8_t *old_to_new_palette;
int i, x, y;
if (img->type == PNG_COLOR_TYPE_GRAY) {
if (img->depth < 8)
png_set_expand_gray_1_2_4_to_8(img->png);
if (img->depth < 8)
png_set_packing(img->png);
png_set_gray_to_rgb(img->png);
} else {
if (img->depth < 8)
png_set_expand_gray_1_2_4_to_8(img->png);
png_get_PLTE(img->png, img->info, &palette, &colors_in_PLTE);
has_palette = png_get_PLTE(img->png, img->info, &palette,
&colors);
}
raw_image = create_raw_image(img->width, img->height, colors);
/*
* Transparent palette entries are removed, and the palette is collapsed.
* Transparent pixels are then replaced with palette index 0.
* This way, an indexed PNG can contain transparent pixels in *addition*
* to 4 normal colors.
*/
if (png_get_tRNS(img->png, img->info, &trans_alpha, &num_trans,
&trans_values)) {
if (img->type == PNG_COLOR_TYPE_PALETTE) {
full_alpha = malloc(sizeof(bool) * num_trans);
&trans_color)) {
original_palette = palette;
palette = malloc(sizeof(png_color) * colors_in_PLTE);
colors_in_new_palette = 0;
old_to_new_palette = malloc(sizeof(uint8_t) * colors_in_PLTE);
for (i = 0; i < num_trans; i++) {
if (trans_alpha[i] > 0)
full_alpha[i] = false;
else
full_alpha[i] = true;
for (i = 0; i < num_trans; i++) {
if (trans_alpha[i] == 0) {
old_to_new_palette[i] = 0;
} else {
old_to_new_palette[i] = colors_in_new_palette;
palette[colors_in_new_palette++] =
original_palette[i];
}
for (i = 0; i < num_trans; i++) {
if (full_alpha[i]) {
palette[i].red = 0xFF;
palette[i].green = 0x00;
palette[i].blue = 0xFF;
/*
* Set to the lightest color in the
* palette.
*/
}
}
free(full_alpha);
} else {
/* Set to the lightest color in the image. */
}
for (i = num_trans; i < colors_in_PLTE; i++) {
old_to_new_palette[i] = colors_in_new_palette;
palette[colors_in_new_palette++] = original_palette[i];
}
png_free_data(img->png, img->info, PNG_FREE_TRNS, -1);
}
if (colors_in_new_palette != colors_in_PLTE) {
palette = realloc(palette,
sizeof(png_color) *
colors_in_new_palette);
}
if (has_palette) {
/* Make sure palette only has the amount of colors you want. */
} else {
/*
* Eventually when this copies colors from the image itself,
* make sure order is lightest to darkest.
* Setting and validating palette before reading
* allows us to error out *before* doing the data
* transformation if the palette is too long.
*/
palette = malloc(sizeof(png_color) * colors);
set_raw_image_palette(raw_image, palette,
colors_in_new_palette);
read_png(img);
if (strcmp(opts.infile, "rgb.png") == 0) {
palette[0].red = 0xFF;
palette[0].green = 0xEF;
palette[0].blue = 0xFF;
for (y = 0; y < img->height; y++) {
for (x = 0; x < img->width; x++) {
raw_image->data[y][x] =
old_to_new_palette[img->data[y][x]];
}
}
palette[1].red = 0xF7;
palette[1].green = 0xF7;
palette[1].blue = 0x8C;
free(old_to_new_palette);
} else {
set_raw_image_palette(raw_image, palette, colors_in_PLTE);
read_png(img);
palette[2].red = 0x94;
palette[2].green = 0x94;
palette[2].blue = 0xC6;
palette[3].red = 0x39;
palette[3].green = 0x39;
palette[3].blue = 0x84;
} else {
palette[0].red = 0xFF;
palette[0].green = 0xFF;
palette[0].blue = 0xFF;
palette[1].red = 0xA9;
palette[1].green = 0xA9;
palette[1].blue = 0xA9;
palette[2].red = 0x55;
palette[2].green = 0x55;
palette[2].blue = 0x55;
palette[3].red = 0x00;
palette[3].green = 0x00;
palette[3].blue = 0x00;
for (y = 0; y < img->height; y++) {
for (x = 0; x < img->width; x++)
raw_image->data[y][x] = img->data[y][x];
}
}
/*
* Also unfortunately, this sets it at 8 bit, and I can't find any
* option to reduce to 2 or 1 bit.
*/
#if PNG_LIBPNG_VER < 10402
png_set_dither(img->png, palette, colors, colors, NULL, 1);
#else
png_set_quantize(img->png, palette, colors, colors, NULL, 1);
#endif
return raw_image;
}
if (!has_palette) {
png_set_PLTE(img->png, img->info, palette, colors);
free(palette);
static struct RawIndexedImage *grayscale_png_to_raw(struct PNGImage *img)
{
if (img->depth < 8)
png_set_expand_gray_1_2_4_to_8(img->png);
png_set_gray_to_rgb(img->png);
return truecolor_png_to_raw(img);
}
static void rgba_png_palette(struct PNGImage *img,
png_color **palette_ptr_ptr, int *num_colors);
static struct RawIndexedImage
*processed_rgba_png_to_raw(const struct PNGImage *img,
const png_color *palette,
int colors_in_palette);
static struct RawIndexedImage *truecolor_png_to_raw(struct PNGImage *img)
{
struct RawIndexedImage *raw_image;
png_color *palette;
int colors_in_palette;
if (img->depth == 16) {
#if PNG_LIBPNG_VER >= 10504
png_set_scale_16(img->png);
#else
png_set_strip_16(img->png);
#endif
}
if (!(img->type & PNG_COLOR_MASK_ALPHA)) {
if (png_get_valid(img->png, img->info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(img->png);
else
png_set_add_alpha(img->png, 0xFF, PNG_FILLER_AFTER);
}
read_png(img);
rgba_png_palette(img, &palette, &colors_in_palette);
raw_image = processed_rgba_png_to_raw(img, palette, colors_in_palette);
free(palette);
return raw_image;
}
static void rgba_PLTE_palette(struct PNGImage *img,
png_color **palette_ptr_ptr, int *num_colors);
static void rgba_build_palette(struct PNGImage *img,
png_color **palette_ptr_ptr, int *num_colors);
static void rgba_png_palette(struct PNGImage *img,
png_color **palette_ptr_ptr, int *num_colors)
{
if (png_get_valid(img->png, img->info, PNG_INFO_PLTE))
return rgba_PLTE_palette(img, palette_ptr_ptr, num_colors);
else
return rgba_build_palette(img, palette_ptr_ptr, num_colors);
}
static void rgba_PLTE_palette(struct PNGImage *img,
png_color **palette_ptr_ptr, int *num_colors)
{
png_get_PLTE(img->png, img->info, palette_ptr_ptr, num_colors);
/*
* If other useless chunks exist (sRGB, bKGD, pHYs, gAMA, cHRM, iCCP,
* etc.) offer to remove?
* Lets us free the palette manually instead of leaving it to libpng,
* which lets us handle a PLTE and a built palette the same way.
*/
png_data_freer(img->png, img->info,
PNG_USER_WILL_FREE_DATA, PNG_FREE_PLTE);
}
static void update_built_palette(png_color *palette,
const png_color *pixel_color, png_byte alpha,
int *num_colors, bool *only_grayscale);
static int fit_grayscale_palette(png_color *palette, int *num_colors);
static void order_color_palette(png_color *palette, int num_colors);
static void rgba_build_palette(struct PNGImage *img,
png_color **palette_ptr_ptr, int *num_colors)
{
png_color *palette;
int y, value_index;
png_color cur_pixel_color;
png_byte cur_alpha;
bool only_grayscale = true;
/*
* By filling the palette up with black by default, if the image
* doesn't have enough colors, the palette gets padded with black.
*/
*palette_ptr_ptr = calloc(colors, sizeof(png_color));
palette = *palette_ptr_ptr;
*num_colors = 0;
for (y = 0; y < img->height; y++) {
value_index = 0;
while (value_index < img->width * 4) {
cur_pixel_color.red = img->data[y][value_index++];
cur_pixel_color.green = img->data[y][value_index++];
cur_pixel_color.blue = img->data[y][value_index++];
cur_alpha = img->data[y][value_index++];
update_built_palette(palette, &cur_pixel_color,
cur_alpha,
num_colors, &only_grayscale);
}
}
/* In order not to count 100% transparent images as grayscale. */
only_grayscale = *num_colors ? only_grayscale : false;
if (!only_grayscale || !fit_grayscale_palette(palette, num_colors))
order_color_palette(palette, *num_colors);
}
static void update_built_palette(png_color *palette,
const png_color *pixel_color, png_byte alpha,
int *num_colors, bool *only_grayscale)
{
bool color_exists;
png_color cur_palette_color;
int i;
/*
* Transparent pixels don't count toward the palette,
* as they'll be replaced with color #0 later.
*/
if (alpha == 0)
return;
if (*only_grayscale && !(pixel_color->red == pixel_color->green &&
pixel_color->red == pixel_color->blue)) {
*only_grayscale = false;
}
color_exists = false;
for (i = 0; i < *num_colors; i++) {
cur_palette_color = palette[i];
if (pixel_color->red == cur_palette_color.red &&
pixel_color->green == cur_palette_color.green &&
pixel_color->blue == cur_palette_color.blue) {
color_exists = true;
break;
}
}
if (!color_exists) {
if (*num_colors == colors) {
err(1, "Too many colors in input PNG file to fit into a %d-bit palette (max %d).",
depth, colors);
}
palette[*num_colors] = *pixel_color;
(*num_colors)++;
}
}
static int fit_grayscale_palette(png_color *palette, int *num_colors)
{
int interval = 256 / colors;
png_color *fitted_palette = malloc(sizeof(png_color) * colors);
bool *set_indices = calloc(colors, sizeof(bool));
int i, shade_index;
fitted_palette[0].red = 0xFF;
fitted_palette[0].green = 0xFF;
fitted_palette[0].blue = 0xFF;
fitted_palette[colors - 1].red = 0;
fitted_palette[colors - 1].green = 0;
fitted_palette[colors - 1].blue = 0;
if (colors == 4) {
fitted_palette[1].red = 0xA9;
fitted_palette[1].green = 0xA9;
fitted_palette[1].blue = 0xA9;
fitted_palette[2].red = 0x55;
fitted_palette[2].green = 0x55;
fitted_palette[2].blue = 0x55;
}
for (i = 0; i < *num_colors; i++) {
shade_index = colors - 1 - palette[i].red / interval;
if (set_indices[shade_index]) {
free(fitted_palette);
free(set_indices);
return false;
}
fitted_palette[shade_index] = palette[i];
set_indices[shade_index] = true;
}
for (i = 0; i < colors; i++)
palette[i] = fitted_palette[i];
*num_colors = colors;
free(fitted_palette);
free(set_indices);
return true;
}
/* A combined struct is needed to sort csolors in order of luminance. */
struct ColorWithLuminance {
png_color color;
int luminance;
};
static int compare_luminance(const void *a, const void *b)
{
struct ColorWithLuminance *x = (struct ColorWithLuminance *)a;
struct ColorWithLuminance *y = (struct ColorWithLuminance *)b;
return y->luminance - x->luminance;
}
static void order_color_palette(png_color *palette, int num_colors)
{
int i;
struct ColorWithLuminance *palette_with_luminance =
malloc(sizeof(struct ColorWithLuminance) * num_colors);
for (i = 0; i < num_colors; i++) {
/*
* Normally this would be done with floats, but since it's only
* used for comparison, we might as well use integer math.
*/
palette_with_luminance[i].color = palette[i];
palette_with_luminance[i].luminance = 2126 * palette[i].red +
7152 * palette[i].green +
722 * palette[i].blue;
}
qsort(palette_with_luminance, num_colors,
sizeof(struct ColorWithLuminance), compare_luminance);
for (i = 0; i < num_colors; i++)
palette[i] = palette_with_luminance[i].color;
free(palette_with_luminance);
}
static void put_raw_image_pixel(struct RawIndexedImage *raw_image,
const struct PNGImage *img,
int *value_index, int x, int y,
const png_color *palette,
int colors_in_palette);
static struct RawIndexedImage
*processed_rgba_png_to_raw(const struct PNGImage *img,
const png_color *palette,
int colors_in_palette)
{
struct RawIndexedImage *raw_image;
int x, y, value_index;
raw_image = create_raw_image(img->width, img->height, colors);
set_raw_image_palette(raw_image, palette, colors_in_palette);
for (y = 0; y < img->height; y++) {
x = raw_image->width - 1;
value_index = img->width * 4 - 1;
while (x >= 0) {
put_raw_image_pixel(raw_image, img,
&value_index, x, y,
palette, colors_in_palette);
x--;
}
}
return raw_image;
}
static uint8_t palette_index_of(const png_color *palette,
int num_colors, const png_color *color);
static void put_raw_image_pixel(struct RawIndexedImage *raw_image,
const struct PNGImage *img,
int *value_index, int x, int y,
const png_color *palette,
int colors_in_palette)
{
png_color pixel_color;
png_byte alpha;
alpha = img->data[y][*value_index];
if (alpha == 0) {
raw_image->data[y][x] = 0;
*value_index -= 4;
} else {
(*value_index)--;
pixel_color.blue = img->data[y][(*value_index)--];
pixel_color.green = img->data[y][(*value_index)--];
pixel_color.red = img->data[y][(*value_index)--];
raw_image->data[y][x] = palette_index_of(palette,
colors_in_palette,
&pixel_color);
}
}
static uint8_t palette_index_of(const png_color *palette,
int num_colors, const png_color *color)
{
uint8_t i;
for (i = 0; i < num_colors; i++) {
if (palette[i].red == color->red &&
palette[i].green == color->green &&
palette[i].blue == color->blue) {
return i;
}
}
errx(1, "The input PNG file contains colors that don't appear in its embedded palette.");
}
static void read_png(struct PNGImage *img)
{
int y;
png_read_update_info(img->png, img->info);
@@ -182,35 +586,78 @@ void input_png_file(const struct Options opts, struct PNGImage *img)
png_read_image(img->png, img->data);
png_read_end(img->png, img->info);
fclose(f);
}
void get_text(struct PNGImage *png)
static struct RawIndexedImage *create_raw_image(int width, int height,
int num_colors)
{
struct RawIndexedImage *raw_image;
int y;
raw_image = malloc(sizeof(struct RawIndexedImage));
raw_image->width = width;
raw_image->height = height;
raw_image->num_colors = num_colors;
raw_image->palette = malloc(sizeof(struct RGBColor) * num_colors);
raw_image->data = malloc(sizeof(uint8_t *) * height);
for (y = 0; y < height; y++)
raw_image->data[y] = malloc(sizeof(uint8_t) * width);
return raw_image;
}
static void set_raw_image_palette(struct RawIndexedImage *raw_image,
const png_color *palette, int num_colors)
{
int i;
if (num_colors > raw_image->num_colors) {
errx(1, "Too many colors in input PNG file's palette to fit into a %d-bit palette (%d in input palette, max %d).",
raw_image->num_colors >> 1,
num_colors, raw_image->num_colors);
}
for (i = 0; i < num_colors; i++) {
raw_image->palette[i].red = palette[i].red;
raw_image->palette[i].green = palette[i].green;
raw_image->palette[i].blue = palette[i].blue;
}
for (i = num_colors; i < raw_image->num_colors; i++) {
raw_image->palette[i].red = 0;
raw_image->palette[i].green = 0;
raw_image->palette[i].blue = 0;
}
}
static void get_text(const struct PNGImage *img,
struct ImageOptions *png_options)
{
png_text *text;
int i, numtxts, numremoved;
png_get_text(png->png, png->info, &text, &numtxts);
png_get_text(img->png, img->info, &text, &numtxts);
for (i = 0; i < numtxts; i++) {
if (strcmp(text[i].key, "h") == 0 && !*text[i].text) {
png->horizontal = true;
png_free_data(png->png, png->info, PNG_FREE_TEXT, i);
png_options->horizontal = true;
png_free_data(img->png, img->info, PNG_FREE_TEXT, i);
} else if (strcmp(text[i].key, "x") == 0) {
png->trim = strtoul(text[i].text, NULL, 0);
png_free_data(png->png, png->info, PNG_FREE_TEXT, i);
png_options->trim = strtoul(text[i].text, NULL, 0);
png_free_data(img->png, img->info, PNG_FREE_TEXT, i);
} else if (strcmp(text[i].key, "t") == 0) {
png->mapfile = text[i].text;
png_free_data(png->png, png->info, PNG_FREE_TEXT, i);
png_options->mapfile = text[i].text;
png_free_data(img->png, img->info, PNG_FREE_TEXT, i);
} else if (strcmp(text[i].key, "T") == 0 && !*text[i].text) {
png->mapout = true;
png_free_data(png->png, png->info, PNG_FREE_TEXT, i);
png_options->mapout = true;
png_free_data(img->png, img->info, PNG_FREE_TEXT, i);
} else if (strcmp(text[i].key, "p") == 0) {
png->palfile = text[i].text;
png_free_data(png->png, png->info, PNG_FREE_TEXT, i);
png_options->palfile = text[i].text;
png_free_data(img->png, img->info, PNG_FREE_TEXT, i);
} else if (strcmp(text[i].key, "P") == 0 && !*text[i].text) {
png->palout = true;
png_free_data(png->png, png->info, PNG_FREE_TEXT, i);
png_options->palout = true;
png_free_data(img->png, img->info, PNG_FREE_TEXT, i);
}
}
@@ -226,106 +673,64 @@ void get_text(struct PNGImage *png)
text[i].text = text[i + numremoved].text;
text[i].compression = text[i + numremoved].compression;
}
png_set_text(png->png, png->info, text, numtxts - numremoved);
png_set_text(img->png, img->info, text, numtxts - numremoved);
}
void set_text(const struct PNGImage *png)
static void set_text(const struct PNGImage *img,
const struct ImageOptions *png_options)
{
png_text *text;
char buffer[3];
text = malloc(sizeof(png_text));
if (png->horizontal) {
if (png_options->horizontal) {
text[0].key = "h";
text[0].text = "";
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
png_set_text(png->png, png->info, text, 1);
png_set_text(img->png, img->info, text, 1);
}
if (png->trim) {
if (png_options->trim) {
text[0].key = "x";
snprintf(buffer, 3, "%d", png->trim);
snprintf(buffer, 3, "%d", png_options->trim);
text[0].text = buffer;
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
png_set_text(png->png, png->info, text, 1);
png_set_text(img->png, img->info, text, 1);
}
if (*png->mapfile) {
if (*png_options->mapfile) {
text[0].key = "t";
text[0].text = "";
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
png_set_text(png->png, png->info, text, 1);
png_set_text(img->png, img->info, text, 1);
}
if (png->mapout) {
if (png_options->mapout) {
text[0].key = "T";
text[0].text = "";
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
png_set_text(png->png, png->info, text, 1);
png_set_text(img->png, img->info, text, 1);
}
if (*png->palfile) {
if (*png_options->palfile) {
text[0].key = "p";
text[0].text = "";
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
png_set_text(png->png, png->info, text, 1);
png_set_text(img->png, img->info, text, 1);
}
if (png->palout) {
if (png_options->palout) {
text[0].key = "P";
text[0].text = "";
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
png_set_text(png->png, png->info, text, 1);
png_set_text(img->png, img->info, text, 1);
}
free(text);
}
void output_png_file(const struct Options opts, const struct PNGImage *png)
{
FILE *f;
char *outfile;
png_struct *img;
/*
* TODO: Variable outfile is for debugging purposes. Eventually,
* opts.infile will be used directly.
*/
if (opts.debug) {
outfile = malloc(strlen(opts.infile) + 5);
strcpy(outfile, opts.infile);
strcat(outfile, ".out");
} else {
outfile = opts.infile;
}
f = fopen(outfile, "wb");
if (!f)
err(1, "Opening output png file '%s' failed", outfile);
img = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!img)
errx(1, "Creating png structure failed");
/* TODO: Better error handling here? */
if (setjmp(png_jmpbuf(img)))
exit(1);
png_init_io(img, f);
png_write_info(img, png->info);
png_write_image(img, png->data);
png_write_end(img, NULL);
fclose(f);
if (opts.debug)
free(outfile);
}
void free_png_data(const struct PNGImage *png)
static void free_png_data(const struct PNGImage *img)
{
int y;
for (y = 0; y < png->height; y++)
free(png->data[y]);
for (y = 0; y < img->height; y++)
free(img->data[y]);
free(png->data);
free(img->data);
}

View File

@@ -1,18 +1,11 @@
.\" Copyright © 2013 stag019 <stag019@gmail.com>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\" This file is part of RGBDS.
.\"
.\" THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" Copyright (c) 2013-2018, stag019 and RGBDS contributors.
.\"
.Dd April 17, 2017
.\" SPDX-License-Identifier: MIT
.\"
.Dd January 26, 2018
.Dt RGBGFX 1
.Os RGBDS Manual
.Sh NAME
@@ -31,7 +24,28 @@
The
.Nm
program converts PNG images into the Nintendo Game Boy's planar tile format.
The arguments are as follows:
The resulting colors and their palette indices are determined differently
depending on the input PNG file:
.Bl -dash -width Ds
.It
If the file has an embedded palette, that palette's color and order are used.
.It
If not, and the image only contains shades of gray, rgbgfx maps them to the
indices appropriate for each shade. Any undetermined indices are set to
respective default shades of gray. For example: if the bit depth is 2 and the
image contains light gray and black, they become the second and fourth colors -
and the first and third colors get set to default white and dark gray. If the
image has multiple shades that map to the same index, the palette is instead
determined as if the image had color.
.It
If the image has color (or the grayscale method failed), the colors are sorted
from lightest to darkest.
.El
The input image may not contain more colors than the selected bit depth
allows. Transparent pixels are set to palette index 0.
.Sh ARGUMENTS
.Bl -tag -width Ds
.It Fl D
Debug features are enabled.
@@ -40,24 +54,25 @@ Fix the input PNG file to be a correctly indexed image.
.It Fl F
Same as
.Fl f ,
but additionally, the input PNG file is fixed to have its parameters match the
command line's parameters.
but additionally, the supplied command line parameters are saved within the PNG
and will be loaded and automatically used next time.
.It Fl d Ar depth
The bitdepth of the output image (either 1 or 2).
By default, the bitdepth is 2 (two bits per pixel).
The bit depth of the output image (either 1 or 2).
By default, the bit depth is 2 (two bits per pixel).
.It Fl h
Lay out tiles horizontally rather than vertically.
.It Fl o Ar outfile
The name of the output file.
.It Fl p Ar palfile
Raw bytes (8 bytes for two bits per pixel, 4 bytes for one bit per pixel)
containing the RGB15 values in the little-endian byte order and then ordered
from lightest to darkest.
Output the image's palette in standard GBC palette format - bytes (8 bytes for
two bits per pixel, 4 bytes for one bit per pixel) containing the RGB15 values
in little-endian byte order. If the palette contains too few colors, the
remaining entries are set to black.
.It Fl P
Same as
.Fl p ,
but the pallete file output name is made by taking the input filename,
removing the file extension, and appending
but the palette file output name is made by taking the input PNG file's
filename, removing the file extension, and appending
.Pa .pal .
.It Fl t Ar mapfile
If any tiles are the same, don't place the repeat tiles in the output file, and
@@ -80,7 +95,7 @@ the PNG file don't match.
Trim the end of the output file by this many tiles.
.El
.Sh EXAMPLES
The following will take a PNG file with a bitdepth of 1, 2, or 8, and output
The following will take a PNG file with a bit depth of 1, 2, or 8, and output
planar 2bpp data:
.Pp
.D1 $ rgbgfx -o out.2bpp in.png

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

View File

@@ -1,17 +1,9 @@
/*
* Copyright (C) 2017 Antonio Nino Diaz <antonio_nd@outlook.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
%option noinput

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -5,7 +13,6 @@
#include <unistd.h>
#include "extern/err.h"
#include "extern/version.h"
#include "link/object.h"
#include "link/output.h"
@@ -16,6 +23,8 @@
#include "link/main.h"
#include "link/library.h"
#include "version.h"
enum eBlockType {
BLOCK_COMMENT,
BLOCK_OBJECTS,

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <errno.h>
#include <stdint.h>
#include <stdio.h>

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
/*
* Here we have the routines that read an objectfile
*/

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

View File

@@ -1,17 +1,9 @@
/*
* Copyright (C) 2017 Antonio Nino Diaz <antonio_nd@outlook.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
%{

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -49,7 +57,6 @@ static int32_t getsymvalue(int32_t symid)
errx(1, "%s: Unknown symbol type", __func__);
}
static int32_t getrealbankfrominternalbank(int32_t n)
{
if (BankIndexIsWRAM0(n) || BankIndexIsROM0(n) ||
@@ -65,8 +72,6 @@ static int32_t getrealbankfrominternalbank(int32_t n)
return n - BANK_INDEX_SRAM;
}
errx(1, "%s: Unknown bank %d", __func__, n);
return n;
}
@@ -262,6 +267,7 @@ void Patch(void)
pPatch = pSect->pPatches;
while (pPatch) {
int32_t t;
int32_t nPatchOrg;
nPC = pSect->nOrg + pPatch->nOffset;
t = calcrpn(pPatch);
@@ -301,6 +307,24 @@ void Patch(void)
pSect->pData[pPatch->nOffset + 3] =
(t >> 24) & 0xFF;
break;
case PATCH_BYTE_JR:
/* Calculate absolute address of the patch */
nPatchOrg = pSect->nOrg + pPatch->nOffset;
/* t contains the destination of the jump */
t = (int16_t)((t & 0xFFFF) - (nPatchOrg + 1));
if (t >= -128 && t <= 255) {
t &= 0xFF;
pSect->pData[pPatch->nOffset] =
(uint8_t)t;
} else {
errx(1,
"%s(%ld) : Value must be 8-bit",
pPatch->pzFilename,
pPatch->nLineNo);
}
break;
}
pPatch = pPatch->pNext;

View File

@@ -1,18 +1,11 @@
.\" Copyright © 2010 Anthony J. Bentley <anthony@anjbe.name>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\" This file is part of RGBDS.
.\"
.\" THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" Copyright (c) 2010-2018, Anthony J. Bentley and RGBDS contributors.
.\"
.Dd April 17, 2017
.\" SPDX-License-Identifier: MIT
.\"
.Dd January 26, 2018
.Dt RGBLINK 1
.Os RGBDS Manual
.Sh NAME
@@ -64,7 +57,7 @@ Write a symbol file to the given filename.
.It Fl O Ar overlayfile
The ROM image to overlay sections over.
When an overlay ROM is provided, all sections must be fixed.
This may be used to patch an existing binray.
This may be used to patch an existing binary.
.It Fl o Ar outfile
Write ROM image to the given filename.
.It Fl p Ar pad_value

View File

@@ -1,18 +1,11 @@
.\" Copyright (C) 2017 Antonio Nino Diaz <antonio_nd@outlook.com>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\" This file is part of RGBDS.
.\"
.\" THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
.\"
.Dd April 17, 2017
.\" SPDX-License-Identifier: MIT
.\"
.Dd January 27, 2018
.Dt RGBLINK 5
.Os RGBDS Manual
.Sh NAME
@@ -45,7 +38,7 @@ WRAMX 2
.Pp
Numbers can be in decimal or hexadecimal format (the prefix is
.Ql $ ) .
It is an error if any bank or command is found before setting a bank.
It is an error if any section name or command are found before setting a bank.
.Pp
Files can be included by using the
.Ar INCLUDE

View File

@@ -1,17 +1,9 @@
/*
* Copyright (C) 2017 Antonio Nino Diaz <antonio_nd@outlook.com>
* This file is part of RGBDS.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* SPDX-License-Identifier: MIT
*/
#include <stdint.h>
@@ -120,9 +112,9 @@ void script_SetCurrentSectionType(const char *type, uint32_t bank)
current_real_bank = bank;
return;
} else if (strcmp(type, "WRAM0") == 0) {
if (bank != 0) {
if (bank != 0)
errx(1, "Trying to assign a bank number to WRAM0.\n");
}
current_bank = BANK_INDEX_WRAM0;
current_real_bank = 0;
return;
@@ -134,7 +126,7 @@ void script_SetCurrentSectionType(const char *type, uint32_t bank)
BANK_COUNT_WRAMX);
}
current_bank = BANK_INDEX_WRAMX + bank - 1;
current_real_bank = bank - 1;
current_real_bank = bank;
return;
} else if (strcmp(type, "SRAM") == 0) {
if (bank >= BANK_COUNT_SRAM) {

View File

@@ -1,3 +1,11 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

View File

@@ -1,18 +1,11 @@
.\" Copyright (c) 2017-2018 Antonio Nino Diaz <antonio_nd@outlook.com>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\" This file is part of RGBDS.
.\"
.\" THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
.\"
.Dd January 7, 2018
.\" SPDX-License-Identifier: MIT
.\"
.Dd January 26, 2018
.Dt RGBDS 5
.Os RGBDS Manual
.Sh NAME
@@ -120,6 +113,7 @@ REPT NumberOfSections
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.

View File

@@ -1,18 +1,11 @@
.\" Copyright © 2010 Anthony J. Bentley <anthony@anjbe.name>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\" This file is part of RGBDS.
.\"
.\" THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" Copyright (c) 2010-2018, Anthony J. Bentley and RGBDS contributors.
.\"
.Dd April 17, 2017
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 7, 2018
.Dt RGBDS 7
.Os RGBDS Manual
.Sh NAME
@@ -21,9 +14,11 @@
.Sh EXAMPLES
To get a working ROM image from a single assembly source file:
.Pp
.D1 $ rgbasm \-o bar.o foo.asm
.D1 $ rgblink \-o baz.gb bar.o
.D1 $ rgbfix \-v \-p 0 baz.gb
.Bd -literal -offset indent
$ rgbasm \-o bar.o foo.asm
$ rgblink \-o baz.gb bar.o
$ rgbfix \-v \-p 0 baz.gb
.Ed
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgbfix 1 ,
@@ -48,4 +43,6 @@ implementation of rgbds.
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 .
.It
2018, codebase relicensed under the MIT license.
.El

26
src/version.c Normal file
View File

@@ -0,0 +1,26 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2017-2018, Antonio Nino Diaz and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/
#include <stdio.h>
#include <string.h>
#include "version.h"
const char *get_package_version_string(void)
{
static char s[50];
/* The following conditional should be simplified by the compiler. */
if (strlen(BUILD_VERSION_STRING) == 0) {
snprintf(s, sizeof(s), "v%d.%d.%d", PACKAGE_VERSION_MAJOR,
PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCH);
return s;
} else {
return BUILD_VERSION_STRING;
}
}

View File

@@ -0,0 +1,237 @@
SECTION "All instructions", ROM0
; 8-bit Arithmetic and Logic Instructions
alu_instruction_list : MACRO
\1 a,a
\1 a,b
\1 a,c
\1 a,d
\1 a,$DB
\1 a,e
\1 a,h
\1 a,[hl]
\1 a,l
ENDM
alu_instruction_list adc
alu_instruction_list add
alu_instruction_list and
alu_instruction_list cp
alu_instruction_list or
alu_instruction_list sbc
alu_instruction_list sub
alu_instruction_list xor
incdec_8bit_instruction_list : MACRO
\1 a
\1 b
\1 c
\1 d
\1 e
\1 h
\1 [hl]
\1 l
ENDM
incdec_8bit_instruction_list inc
incdec_8bit_instruction_list dec
; 16-bit Arithmetic Instructions
add hl,bc
add hl,de
add hl,hl
add hl,sp
inc bc
inc de
inc hl
inc sp
dec bc
dec de
dec hl
dec sp
; Bit Operations Instructions
bitop_u3_instruction_list : MACRO
NBIT SET 0
REPT 8
\1 NBIT,a
\1 NBIT,b
\1 NBIT,c
\1 NBIT,d
\1 NBIT,e
\1 NBIT,h
\1 NBIT,[hl]
\1 NBIT,l
NBIT SET NBIT + 1
ENDR
ENDM
bitop_u3_instruction_list bit
bitop_u3_instruction_list res
bitop_u3_instruction_list set
bitop_noarg_instruction_list : MACRO
\1 a
\1 b
\1 c
\1 d
\1 e
\1 h
\1 [hl]
\1 l
ENDM
bitop_noarg_instruction_list swap
; Bit Shift Instructions
rla
rlca
rra
rrca
bitop_noarg_instruction_list rl
bitop_noarg_instruction_list rlc
bitop_noarg_instruction_list rr
bitop_noarg_instruction_list rrc
bitop_noarg_instruction_list sla
bitop_noarg_instruction_list sra
bitop_noarg_instruction_list srl
; Load Instructions
ld_r8_x_instruction_list : MACRO
ld \1,a
ld \1,b
ld \1,c
ld \1,d
ld \1,$DB
ld \1,e
ld \1,h
ld \1,l
ENDM
ld_r8_x_instruction_list a
ld_r8_x_instruction_list b
ld_r8_x_instruction_list c
ld_r8_x_instruction_list d
ld_r8_x_instruction_list e
ld_r8_x_instruction_list h
ld_r8_x_instruction_list [hl]
ld_r8_x_instruction_list l
ld_x_r8_instruction_list : MACRO
ld a,\1
ld b,\1
ld c,\1
ld d,\1
ld e,\1
ld h,\1
ld l,\1
ENDM
ld_x_r8_instruction_list a
ld_x_r8_instruction_list b
ld_x_r8_instruction_list c
ld_x_r8_instruction_list d
ld_x_r8_instruction_list e
ld_x_r8_instruction_list h
ld_x_r8_instruction_list [hl]
ld_x_r8_instruction_list l
ld bc,$ABCD
ld de,$ABCD
ld hl,$ABCD
ld sp,$ABCD
ld [bc],a
ld [de],a
ld [hl],a
ld [$ABCD],a
ldh [$ff00+$DB],a
ld [$ff00+c],a
ld a,[bc]
ld a,[de]
ld a,[hl]
ld a,[$ABCD]
ldh a,[$ff00+$DB]
ld a,[$ff00+c]
ld [hl+],a
ld [hl-],a
ld a,[hl+]
ld a,[hl-]
; Jumps and Subroutines
call $ABCD
call z,$ABCD
call nz,$ABCD
call c,$ABCD
call nc,$ABCD
jp hl
jp $ABCD
jp z,$ABCD
jp nz,$ABCD
jp c,$ABCD
jp nc,$ABCD
jrlabel:
jr jrlabel
jr z,jrlabel
jr nz,jrlabel
jr c,jrlabel
jr nc,jrlabel
ret
ret z
ret nz
ret c
ret nc
reti
rst $00
rst $08
rst $10
rst $18
rst $20
rst $28
rst $30
rst $38
; Stack Operations Instructions
add sp,$DB
ld [$ABCD],sp
ld hl,sp+$DB
ld sp,hl
pop af
pop bc
pop de
pop hl
push af
push bc
push de
push hl
; Miscellaneous Instructions
ccf
cpl
daa
di
ei
halt
nop
scf
stop

Binary file not shown.

View File

@@ -55,4 +55,9 @@ $RGBLINK -o $gbtemp2 $otemp
diff $gbtemp $gbtemp2
rc=$(($? || $rc))
$RGBASM -o $otemp all-instructions.asm
$RGBLINK -o $gbtemp $otemp
diff all-instructions.out.bin $gbtemp
rc=$(($? || $rc))
exit $rc

View File

@@ -25,4 +25,7 @@ $RGBASM -o $otemp romx-tiny.asm
$RGBLINK -o $gbtemp $otemp > romx-tiny-no-t.out 2>&1
$RGBLINK -t -o $gbtemp $otemp > romx-tiny-t.out 2>&1
$RGBASM -o $otemp all-instructions.asm
$RGBLINK -o all-instructions.out.bin $otemp 2>&1
exit 0

34
test/run-tests.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# Return failure as soon as a command fails to execute
set -e
# Tests included with the repository
pushd asm
./test.sh
popd
pushd link
./test.sh
popd
# Test some significant external projects that use RGBDS
git clone https://github.com/pret/pokecrystal.git --depth=1
pushd pokecrystal
make -j
make compare
popd
git clone --recursive https://github.com/pret/pokered.git --depth=1
pushd pokered
make -j
make compare
popd
git clone https://github.com/AntonioND/ucity.git --depth=1
pushd ucity
make -j
popd