Compare commits

..

45 Commits

Author SHA1 Message Date
Anthony J. Bentley
c1213f536b Merge branch 'master' of https://github.com/stag019/rgbds 2014-11-04 17:36:45 -07:00
Anthony J. Bentley
82de716454 Mark error functions as _Noreturn. 2014-11-04 17:30:00 -07:00
stag019
a64d725a8d The actual way the macro bug should have been fixed. 2014-11-04 18:09:22 -05:00
stag019
80e2129f22 Merge https://github.com/bentley/rgbds
Conflicts:
	include/lib/types.h
	src/asm/symbol.c
2014-11-02 01:00:20 -05:00
stag019
af70f03933 A few more small changes to charmap.c. 2014-10-31 19:01:21 -04:00
stag019
004bc2e50e Fix a few charmap bugs maybe? 2014-10-31 10:48:54 -04:00
Christophe Staïesse
25efb00769 fix a bug in the lexer involving double quote escaping and semicolons
The bug showed up when a semicolon was located anywhere after \".

These three test cases are syntaxically correct but didn't compile:

1)
SECTION "HOME", HOME
	db "\";"

2)
SECTION "HOME", HOME
	db "\""
	nop
	;

3)
SECTION "HOME", HOME
	db "\"" ;

The problem was located in yy_create_buffer(). Basicaly, this function loads an
entire source file, uniformizes EOL terminators and filters out comments without
touching literal strings.

However, bounds of literal strings were wrongly guessed because \" was
interpreted as two characters (and so the double quote was not escaped).

In test 1, the string terminates early and so ;" is filtered out as it was a
comment and so the assembler complains of an unterminated string.
In test 2 and 3, the string is in fact interpreted as two strings, the second
one terminates at EOF in these cases and so comments are not filtered out and
that makes the assembler complains.

A special case must be taken into account:

4)
SECTION "HOME", HOME
	db "\\" ;

So we need to ignore \\ as well.

Note that there is still a problem left: in yy_create_buffer() a string may
span multiple lines but not in the lexer. However in this case I think the lexer
would quit at the first newline so there should be nothing to worry about.
2014-10-10 16:50:11 +02:00
Anthony J. Bentley
c6c7b99fad PATH_MAX is not exactly portable. Hack around it for now. 2014-10-10 03:48:52 -06:00
Anthony J. Bentley
e28d8384fb Merge branch 'fix-makefile' of https://github.com/chastai/rgbds 2014-10-06 02:01:21 -06:00
Anthony J. Bentley
27a350eaab Merge branch 'fix-uniquearg-segfault' of https://github.com/chastai/rgbds 2014-10-06 01:55:19 -06:00
Anthony J. Bentley
cd8d895c1b Style. 2014-10-06 01:54:03 -06:00
Christophe Staïesse
4577a01c68 Fix out of bounds array access on invalid macro arg references
A reference to an invalid macro argument (\ not followed by a digit
between 1 and 9) will cause an access outside of the bounds of the
currentmacroargs array in sym_FindMacroArg().

Macro arg references are processed in two places:

In CopyMacroArg(): called when scanning tokens between "", {} and
arguments of a macro call. The only problem here is that it accepts \0
as valid and so calls sym_FindMacroArg with a invalid value.

In PutMacroArg(): called by the lexer automata when it encounters a
token matching \\[0-9]? (in other cases than above). So not only it
accepts \0 but also \ alone.
  Memo: In setuplex(), a rule is defined with a regex composed of up to
    three ranges of chars and takes the form:
      [FirstRange]
      or [FirstRange][SecondRange]?
      or [FirstRange]([SecondRange][Range]*)?
    On scanning, when several rules match, the first longuest one is
    choosen.

Regression test:
1)
SECTION "HOME", HOME
	db "\0"

2)
SECTION "HOME", HOME
	db \A

3)
SECTION "HOME", HOME
	db \
2014-10-05 18:15:37 +02:00
Christophe Staïesse
6758387668 Add assertion to symFindMacroArg() to debug oob array access 2014-10-05 18:13:07 +02:00
Christophe Staïesse
424702b272 Fix bug: rgbasm segfault when \@ is used outside a macro
The problem occurs when \@ is accessed outside the definition of a
macro and is not between "" or {}, or when it is used in an argument of
a macro call, i.e. when the access is processed by PutUniqueArg().

PutUniqueArg(), puts back the string value of \@ to the lexer's buffer
(to substitute \@ by the unique label string).
When \@ is not defined, sym_FindMacroArg(-1) returns NULL, which
yyunputstr() doesn't expect and crashes.

Solution:
Generate an error when \@ is not defined.

Regression test:

SECTION "HOME", HOME
        ld a,\@

Will segfault.
On the fixed version, it will return an error as \@ is not available.
2014-10-05 13:32:18 +02:00
Christophe Staïesse
191f98a008 Fix incorrect dependencies in Makefile 2014-10-05 11:37:11 +02:00
Anthony J. Bentley
00de7674af Now that install dirs are created, this error is unlikely to occur. 2014-10-03 15:17:49 -06:00
Anthony J. Bentley
32fa032a62 Makefile: Create install directories if they don’t exist. 2014-10-03 15:14:40 -06:00
Anthony J. Bentley
73e44cb803 Fix dependencies for Yacc files. Improve Makefile POSIX compliance.
Parallel building issue pointed out by murphm8 and chastai.
2014-09-26 15:27:52 -06:00
Anthony J. Bentley
3e4350afa4 Don't cast calls to malloc(). 2014-09-26 00:39:29 -06:00
Anthony J. Bentley
0d07caba60 Remove inconsistent version numbering. 2014-09-25 20:56:15 -06:00
Anthony J. Bentley
3992ce2502 Separate errors that shouldn't have been combined in the first place. 2014-09-25 20:40:25 -06:00
Anthony J. Bentley
215d6f0c5b Revert 97d431d1f4ad404e282e3781bd195be3f053734d; it breaks things. 2014-09-24 03:40:50 -06:00
Anthony J. Bentley
f3394f46b4 Fix MinGW target. 2014-09-24 03:17:33 -06:00
Anthony J. Bentley
e3df758897 Update license. 2014-09-24 03:07:43 -06:00
Anthony J. Bentley
d7319ecd00 Remove rgblib.
I have never used it and it's probably been broken for years.
2014-09-24 03:03:42 -06:00
Anthony J. Bentley
d661b3a532 Now that we replace missing libc functions, switch back to err(). 2014-09-24 02:50:39 -06:00
Anthony J. Bentley
c0be5ddbb2 Remove dead stores. 2014-09-24 01:19:05 -06:00
Anthony J. Bentley
97d431d1f4 rgbasm: Avoid unnecessary filename copying. 2014-09-24 00:52:00 -06:00
Anthony J. Bentley
a849e1107e Improve POSIX compliance in the Makefile.
Set .POSIX and don't use the += operator.
2014-09-24 00:38:19 -06:00
Anthony J. Bentley
a41bdff88f Wrap Makefile to 80 characters. 2014-09-24 00:28:14 -06:00
Anthony J. Bentley
cb383e6b1a Unclutter Makefile: use $Q instead of ${Q}. 2014-09-24 00:26:46 -06:00
Anthony J. Bentley
45b6872e2a rgbasm: Fix TOCTOU and reduce buffering. 2014-09-24 00:23:40 -06:00
Anthony J. Bentley
056109652d rgbasm: Don't allocate an unnecessary buffer. 2014-09-23 22:22:39 -06:00
Anthony J. Bentley
284600ef1f rgblink: Don't allocate unnecessary buffer. Delete unused flag. 2014-09-23 22:17:43 -06:00
stag019
af506985e5 Added license to charmap.c 2014-02-03 20:46:52 -05:00
stag019
240d2a7f14 Merge https://github.com/bentley/rgbds 2014-01-29 00:18:10 -05:00
stag019
34656f9e5d Fix a bug where the first charmap entry wasn't added correctly. 2013-12-28 00:35:05 -05:00
stag019
c61c112218 Remove GNU-specific <getopt.h>. getopt() is defined in <unistd.h> in POSIX, which adding #define _XOPEN_SOURCE 500 causes GCC to include. 2013-12-23 14:57:06 -05:00
stag019
55974bc743 Only define _MAX_PATH is it isn't already defined. 2013-12-23 14:52:37 -05:00
stag019
94005513a4 Comment out unused variable dest. 2013-12-23 14:50:37 -05:00
stag019
36edec6231 Add out_BinaryFileSlice() definition to output.h. 2013-12-23 14:47:37 -05:00
stag019
7d176245d8 Remove all implicit definitions of compiler provided functions.
<strings.h> cause strncasecmp to be define.
2013-12-23 14:40:53 -05:00
stag019
c65d58c589 Move local includes below system includes. 2013-12-23 14:37:56 -05:00
stag019
1f9fd0f060 This fixes an error with using long label names in macros. If the label name you're using is longer than the string length of the literal macro text, a syntax error would occur. This fix makes sure it at least allocates enough bytes for the largest allowed label name. 2013-12-22 20:56:31 -05:00
stag019
1218da79a9 Character maps. 2013-12-22 20:55:14 -05:00
47 changed files with 979 additions and 1153 deletions

10
LICENSE
View File

@@ -1,5 +1,5 @@
rgbasm, rgblink, and rgblib are derived from Justin Lloyd's RGBDS, which
is released under the following license:
rgbasm and rgblink are derived from Justin Lloyd's RGBDS, which is
released under the following license:
DO WHATEVER PUBLIC LICENSE*
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@@ -17,3 +17,9 @@ is released under the following license:
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.
extern/err.c is derived from the Musl C library, http://www.musl-libc.org,
and is released under the MIT license.
extern/strl.c is derived from the OpenBSD Project, http://www.openbsd.org,
and is released under the BSD license.

107
Makefile
View File

@@ -1,4 +1,6 @@
CFLAGS += -Wall -Iinclude -Iinclude/asm/gameboy -g -std=c99
.POSIX:
REALCFLAGS = ${CFLAGS} -Wall -Iinclude -Iinclude/asm/gameboy -g -std=c99
# User-defined variables
PREFIX = /usr/local
@@ -14,6 +16,7 @@ yacc_pre := \
rgbasm_obj := \
src/asm/asmy.o \
src/asm/charmap.o \
src/asm/fstack.o \
src/asm/globlex.o \
src/asm/lexer.o \
@@ -22,11 +25,10 @@ rgbasm_obj := \
src/asm/output.o \
src/asm/rpn.o \
src/asm/symbol.o \
src/asm/gameboy/locallex.o
rgblib_obj := \
src/lib/library.o \
src/lib/main.o
src/asm/gameboy/locallex.o \
src/extern/err.o \
src/extern/strlcpy.o \
src/extern/strlcat.o
rgblink_obj := \
src/link/assign.o \
@@ -36,61 +38,53 @@ rgblink_obj := \
src/link/object.o \
src/link/output.o \
src/link/patch.o \
src/link/symbol.o
src/link/symbol.o \
src/extern/err.o
rgbfix_obj := \
src/fix/main.o
src/fix/main.o \
src/extern/err.o
all: rgbasm rgblib rgblink rgbfix
all: rgbasm rgblink rgbfix
clean:
${Q}rm -rf rgbds.html
${Q}rm -rf rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.html
${Q}rm -rf rgblib rgblib.exe ${rgblib_obj} rgblib.html
${Q}rm -rf rgblink rgblink.exe ${rgblink_obj} rgblink.html
${Q}rm -rf rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.html
${Q}rm -rf src/asm/asmy.c src/asm/asmy.h src/asm/asmy.y
$Qrm -rf rgbds.html
$Qrm -rf rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.html
$Qrm -rf rgblink rgblink.exe ${rgblink_obj} rgblink.html
$Qrm -rf rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.html
$Qrm -rf src/asm/asmy.c src/asm/asmy.h src/asm/asmy.y
install: all
${Q}install -s -m 555 rgbasm ${BINPREFIX}/rgbasm
${Q}install -s -m 555 rgbfix ${BINPREFIX}/rgbfix
${Q}install -s -m 555 rgblink ${BINPREFIX}/rgblink
${Q}install -s -m 555 rgblib ${BINPREFIX}/rgblib
${Q}install -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7 || \
(echo Installing manpages to ${MANPREFIX} failed. >&2 && \
echo Check where your manpages are installed and set the \
proper directory >&2 && \
echo with, e.g., make install MANPREFIX=/usr/share/man \
>&2 ; false)
${Q}install -m 444 src/asm/rgbasm.1 \
${MANPREFIX}/man1/rgbasm.1
${Q}install -m 444 src/fix/rgbfix.1 \
${MANPREFIX}/man1/rgbfix.1
${Q}install -m 444 src/link/rgblink.1 \
${MANPREFIX}/man1/rgblink.1
${Q}install -m 444 src/lib/rgblib.1 \
${MANPREFIX}/man1/rgblib.1
$Qmkdir -p ${BINPREFIX}
$Qinstall -s -m 555 rgbasm ${BINPREFIX}/rgbasm
$Qinstall -s -m 555 rgbfix ${BINPREFIX}/rgbfix
$Qinstall -s -m 555 rgblink ${BINPREFIX}/rgblink
$Qmkdir -p ${MANPREFIX}/man1 ${MANPREFIX}/man7
$Qinstall -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7
$Qinstall -m 444 src/asm/rgbasm.1 ${MANPREFIX}/man1/rgbasm.1
$Qinstall -m 444 src/fix/rgbfix.1 ${MANPREFIX}/man1/rgbfix.1
$Qinstall -m 444 src/link/rgblink.1 ${MANPREFIX}/man1/rgblink.1
rgbasm: ${rgbasm_obj}
${Q}${CC} ${CFLAGS} -o $@ ${rgbasm_obj} -lm
rgblib: ${rgblib_obj}
${Q}${CC} ${CFLAGS} -o $@ ${rgblib_obj}
$Q${CC} ${REALCFLAGS} -o $@ ${rgbasm_obj} -lm
rgblink: ${rgblink_obj}
${Q}${CC} ${CFLAGS} -o $@ ${rgblink_obj}
$Q${CC} ${REALCFLAGS} -o $@ ${rgblink_obj}
rgbfix: ${rgbfix_obj}
${Q}${CC} ${CFLAGS} -o $@ ${rgbfix_obj}
$Q${CC} ${REALCFLAGS} -o $@ ${rgbfix_obj}
.y.c:
$Q${YACC} -d ${YFLAGS} -o $@ $<
.c.o:
${Q}${CC} ${CFLAGS} -c -o $@ $<
$Q${CC} ${REALCFLAGS} -c -o $@ $<
src/asm/asmy.c: src/asm/asmy.y
${Q}${YACC} -d -o $@ $<
src/asm/gameboy/locallex.o src/asm/globlex.o src/asm/lexer.o: src/asm/asmy.h
src/asm/asmy.h: src/asm/asmy.c
src/asm/asmy.y: ${yacc_pre}
${Q}cat ${yacc_pre} > $@
$Qcat ${yacc_pre} > $@
# Below is a target for the project maintainer to easily create win32 exes.
@@ -98,19 +92,24 @@ src/asm/asmy.y: ${yacc_pre}
# If you're building on Windows with Cygwin or Mingw, just follow the Unix
# install instructions instead.
mingw:
${Q}env PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin make CC=gcc CFLAGS="-I/usr/local/mingw32/include ${CFLAGS}"
${Q}mv rgbasm rgbasm.exe
${Q}mv rgblib rgblib.exe
${Q}mv rgblink rgblink.exe
${Q}mv rgbfix rgbfix.exe
$Qenv PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin \
make CC=gcc CFLAGS="-I/usr/local/mingw32/include \
-D__progname=\\\"\\\" \
-D_Noreturn='__attribute__((noreturn))' ${CFLAGS}"
$Qmv rgbasm rgbasm.exe
$Qmv rgblink rgblink.exe
$Qmv rgbfix rgbfix.exe
# Below is a target for the project maintainer to easily create web manuals.
# It relies on mandoc: http://mdocml.bsd.lv
MANDOC = -Thtml -Oman=/rgbds/manual/%N/ -Ostyle=/rgbds/manual/manual.css -Ios=General
MANDOC = -Thtml -Ios=General -Oman=/rgbds/manual/%N/ \
-Ostyle=/rgbds/manual/manual.css
wwwman:
${Q}mandoc ${MANDOC} src/rgbds.7 | sed s/OpenBSD/General/ > rgbds.html
${Q}mandoc ${MANDOC} src/asm/rgbasm.1 | sed s/OpenBSD/General/ > rgbasm.html
${Q}mandoc ${MANDOC} src/fix/rgbfix.1 | sed s/OpenBSD/General/ > rgbfix.html
${Q}mandoc ${MANDOC} src/lib/rgblib.1 | sed s/OpenBSD/General/ > rgblib.html
${Q}mandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > rgblink.html
$Qmandoc ${MANDOC} src/rgbds.7 | sed s/OpenBSD/General/ > rgbds.html
$Qmandoc ${MANDOC} src/asm/rgbasm.1 | sed s/OpenBSD/General/ > \
rgbasm.html
$Qmandoc ${MANDOC} src/fix/rgbfix.1 | sed s/OpenBSD/General/ > \
rgbfix.html
$Qmandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > \
rgblink.html

1
README
View File

@@ -7,7 +7,6 @@ for the Game Boy and Game Boy Color. It consists of:
- rgbasm (assembler)
- rgblink (linker)
- rgblib (library manager)
- rgbfix (checksum/header fixer)
rgbds-linux is a fork of the original RGBDS which aims to make the programs

View File

@@ -12,7 +12,6 @@
<li><a href="geninfo.htm">ASMotor General Information</a>
<li><a href="asm.htm">xASM Documentation</a>
<li><a href="link.htm">xLink Documentation</a>
<li><a href="lib.htm">xLib Documentation</a>
<li><a href="fix.htm">RGBFix Documentation</a>
<li><a href="rgb0.htm">The RGB0-2 ObjectFileFormat</a>
</ul>

View File

@@ -1,47 +0,0 @@
<!DOCTYPE HTML PUBliC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>xLib</title>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<h1>xLib Documentation</h1>
<h2>Table of Contents</h2>
<ul>
<li><a href="#history"> History</A>
<li><a href="#usage"> Usage</A>
<li><a href="#commands"> The commands</A>
</ul>
<hr>
<h2 id="history">History</h2>
<table>
<caption>The history of xLib</caption>
<thead>
<tr>
<th scope="col">Version</th>
<th scope="col">Dated</th>
<th scope="col">Release notes</th>
</tr>
</thead>
<tr>
<td>1.0</td>
<td>21 Sep. 1997</td>
<td>First release</td>
</tr>
</table>
<h2 id="usage">Usage</h2>
<pre> xlib library command [module1 module2 ... modulen]</pre>
<h2 id="commands">The Commands</h2>
<p>The <b>command</b> specified after <b>library</b> on the <a href="#Usage">commandline</a> tells xLib what to do.
<p>The following commands are available:
<ul>
<li>a — Adds (or replaces if already present) the modules to the library
<li>d — Deletes the modules specified from the library
<li>l — Lists the library contents
<li>x — Extracts the modules from the library
</ul>
<hr>
<p>Last updated 21 September 1997 by <a href="mailto:surfsmurf@matilde.demon.co.uk">Carsten Sorensen</a></p>
</body>
</html>

View File

@@ -17,8 +17,6 @@
#include "localasm.h"
#include "asmotor.h"
extern SLONG nLineNo;
extern ULONG nTotalLines;
extern ULONG nPC;

18
include/asm/charmap.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef ASMOTOR_ASM_CHARMAP_H
#define ASMOTOR_ASM_CHARMAP_H
#define MAXCHARMAPS 512
#define CHARMAPLENGTH 8
struct Charmap {
int count;
char input[MAXCHARMAPS][CHARMAPLENGTH + 1];
char output[MAXCHARMAPS];
};
int readUTF8Char(char *destination, char *source);
void charmap_Sort();
int charmap_Add(char *input, UBYTE output);
int charmap_Convert(char **input);
#endif

View File

@@ -9,6 +9,8 @@
#ifndef ASMOTOR_ASM_FSTACK_H
#define ASMOTOR_ASM_FSTACK_H
#include <stdio.h>
#include "asm/asm.h"
#include "asm/types.h"
#include "asm/lexer.h"
@@ -27,14 +29,17 @@ struct sContext {
ULONG nREPTBlockSize;
};
extern ULONG fstk_RunInclude(char *s);
void
fstk_RunInclude(char *);
extern void fstk_RunMacroArg(SLONG s);
extern ULONG fstk_Init(char *s);
void
fstk_Init(char *);
extern void fstk_Dump(void);
extern void fstk_AddIncludePath(char *s);
extern ULONG fstk_RunMacro(char *s);
extern void fstk_RunRept(ULONG count);
extern void fstk_FindFile(char *s);
FILE *
fstk_FindFile(char *);
extern int yywrap(void);

View File

@@ -12,6 +12,7 @@ struct Section {
ULONG nBank;
struct Section *pNext;
struct Patch *pPatches;
struct Charmap *charmap;
UBYTE *tData;
};
@@ -20,12 +21,14 @@ void out_SetFileName(char *s);
void out_NewSection(char *pzName, ULONG secttype);
void out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank);
void out_AbsByte(int b);
void out_AbsByteGroup(char *s, int length);
void out_RelByte(struct Expression * expr);
void out_RelWord(struct Expression * expr);
void out_PCRelByte(struct Expression * expr);
void out_WriteObject(void);
void out_Skip(int skip);
void out_BinaryFile(char *s);
void out_BinaryFileSlice(char *s, SLONG start_pos, SLONG length);
void out_String(char *s);
void out_AbsLong(SLONG b);
void out_RelLong(struct Expression * expr);

View File

@@ -1,7 +1,9 @@
#ifndef ASMOTOR_ASM_TYPES_H
#define ASMOTOR_ASM_TYPES_H
#ifndef _MAX_PATH
#define _MAX_PATH 512
#endif
typedef unsigned char UBYTE;
typedef signed char SBYTE;

View File

@@ -1,21 +0,0 @@
/* asmotor.h
*
* Contains defines for every program in the ASMotor package
*
* Copyright 1997 Carsten Sorensen
*
*/
#ifndef ASMOTOR_ASMOTOR_H
#define ASMOTOR_ASMOTOR_H
#define ASMOTOR
#define ASMOTOR_VERSION "1.10-linux"
#define ASM_VERSION "1.08c"
#define LINK_VERSION "1.06c"
#define RGBFIX_VERSION "1.02"
#define LIB_VERSION "1.00"
#endif

63
include/extern/err.h vendored Normal file
View File

@@ -0,0 +1,63 @@
/*
* Copyright © 2005-2013 Rich Felker, et al.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef EXTERN_ERR_H
#define EXTERN_ERR_H
#ifdef ERR_IN_LIBC
#include <err.h>
#else
#include <stdarg.h>
#define warn rgbds_warn
#define vwarn rgbds_vwarn
#define warnx rgbds_warnx
#define vwarnx rgbds_vwarnx
#define err rgbds_err
#define verr rgbds_verr
#define errx rgbds_errx
#define verrx rgbds_verrx
#ifdef __cplusplus
extern "C" {
#endif
void warn(const char *, ...);
void vwarn(const char *, va_list);
void warnx(const char *, ...);
void vwarnx(const char *, va_list);
void err(int, const char *, ...);
void verr(int, const char *, va_list);
void errx(int, const char *, ...);
void verrx(int, const char *, va_list);
#ifdef __cplusplus
}
#endif
#endif
#endif

13
include/extern/strl.h vendored Normal file
View File

@@ -0,0 +1,13 @@
#ifndef STRL_H
#define STRL_H
#ifdef STRL_IN_LIBC
#include <string.h>
#else
#define strlcpy rgbds_strlcpy
#define strlcat rgbds_strlcat
size_t strlcpy(char *, const char *, size_t);
size_t strlcat(char *, const char *, size_t);
#endif
#endif

View File

@@ -1,13 +0,0 @@
#ifndef ASMOTOR_LIB_LIBRARY_H
#define ASMOTOR_LIB_LIBRARY_H
#include "lib/libwrap.h"
extern sLibrary *lib_Read(char *filename);
extern BBOOL lib_Write(sLibrary * lib, char *filename);
extern sLibrary *lib_AddReplace(sLibrary * lib, char *filename);
extern void lib_Free(sLibrary * lib);
extern sLibrary *lib_DeleteModule(sLibrary * lib, char *filename);
extern sLibrary *lib_Find(sLibrary * lib, char *filename);
#endif

View File

@@ -1,19 +0,0 @@
#ifndef ASMOTOR_LIB_LIBWRAP_H
#define ASMOTOR_LIB_LIBWRAP_H
#include "lib/types.h"
#define MAXNAMELENGTH 256
struct LibraryWrapper {
char tName[MAXNAMELENGTH];
UWORD uwTime;
UWORD uwDate;
SLONG nByteLength;
UBYTE *pData;
struct LibraryWrapper *pNext;
};
typedef struct LibraryWrapper sLibrary;
#endif

View File

@@ -1,14 +0,0 @@
#ifndef ASMOTOR_LIB_TYPES_H
#define ASMOTOR_LIB_TYPES_H
#define _MAX_PATH 512
typedef unsigned char UBYTE;
typedef signed char SBYTE;
typedef unsigned short UWORD;
typedef signed short SWORD;
typedef unsigned long ULONG;
typedef signed long SLONG;
typedef signed char BBOOL;
#endif

View File

@@ -1,7 +1,9 @@
#ifndef ASMOTOR_LINK_LINK_H
#define ASMOTOR_LINK_LINK_H
#ifndef _MAX_PATH
#define _MAX_PATH 512
#endif
#include "link/types.h"

View File

@@ -2,6 +2,5 @@
#define ASMOTOR_LINK_OBJECT_H
extern void obj_Readfile(char *tzObjectfile);
extern void lib_Readfile(char *tzLibfile);
#endif

View File

@@ -1,7 +1,9 @@
#ifndef ASMOTOR_LINK_TYPES_H
#define ASMOTOR_LINK_TYPES_H
#ifndef _MAX_PATH
#define _MAX_PATH 512
#endif
typedef unsigned char UBYTE;
typedef signed char SBYTE;

204
src/asm/charmap.c Normal file
View File

@@ -0,0 +1,204 @@
/*
* 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>
#include "asm/asm.h"
#include "asm/charmap.h"
#include "asm/main.h"
#include "asm/output.h"
struct Charmap globalCharmap = {0};
extern struct Section *pCurrentSection;
int
readUTF8Char(char *destination, char *source)
{
int size;
UBYTE first;
first = source[0];
if(first >= 0xFC)
{
size = 6;
}
else if(first >= 0xF8)
{
size = 5;
}
else if(first >= 0xF0)
{
size = 4;
}
else if(first >= 0xE0)
{
size = 3;
}
else if(first >= 0xC0)
{
size = 2;
}
else if(first != '\0')
{
size = 1;
}
else
{
size = 0;
}
strncpy(destination, source, size);
destination[size] = 0;
return size;
}
int
charmap_Add(char *input, UBYTE output)
{
int i, input_length;
char temp1i[CHARMAPLENGTH + 1], temp2i[CHARMAPLENGTH + 1], temp1o = 0, temp2o = 0;
struct Charmap *charmap;
if(pCurrentSection)
{
if(pCurrentSection -> charmap)
{
charmap = pCurrentSection -> charmap;
}
else
{
if((charmap = (struct Charmap *) calloc(1, sizeof(struct Charmap))) == NULL)
{
fatalerror("Not enough memory for charmap");
}
pCurrentSection -> charmap = charmap;
}
}
else
{
charmap = &globalCharmap;
}
if(nPass == 2)
{
return charmap -> count;
}
if(charmap -> count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH)
{
return -1;
}
input_length = strlen(input);
if(input_length > 1)
{
i = 0;
while(i < charmap -> count + 1)
{
if(input_length > strlen(charmap -> input[i]))
{
memcpy(temp1i, charmap -> input[i], CHARMAPLENGTH + 1);
memcpy(charmap -> input[i], input, input_length);
temp1o = charmap -> output[i];
charmap -> output[i] = output;
i++;
break;
}
i++;
}
while(i < charmap -> count + 1)
{
memcpy(temp2i, charmap -> input[i], CHARMAPLENGTH + 1);
memcpy(charmap -> input[i], temp1i, CHARMAPLENGTH + 1);
memcpy(temp1i, temp2i, CHARMAPLENGTH + 1);
temp2o = charmap -> output[i];
charmap -> output[i] = temp1o;
temp1o = temp2o;
i++;
}
memcpy(charmap -> input[charmap -> count + 1], temp1i, CHARMAPLENGTH + 1);
charmap -> output[charmap -> count + 1] = temp1o;
}
else
{
memcpy(charmap -> input[charmap -> count], input, input_length);
charmap -> output[charmap -> count] = output;
}
return ++charmap -> count;
}
int
charmap_Convert(char **input)
{
struct Charmap *charmap;
char outchar[CHARMAPLENGTH + 1];
char *buffer;
int i, j, length;
if(pCurrentSection && pCurrentSection -> charmap)
{
charmap = pCurrentSection -> charmap;
}
else
{
charmap = &globalCharmap;
}
if((buffer = (char *) malloc(strlen(*input))) == NULL)
{
fatalerror("Not enough memory for buffer");
}
length = 0;
while(**input)
{
j = 0;
for(i = 0; i < charmap -> count; i++)
{
j = strlen(charmap -> input[i]);
if(memcmp(*input, charmap -> input[i], j) == 0)
{
outchar[0] = charmap -> output[i];
outchar[1] = 0;
break;
}
j = 0;
}
if(!j)
{
j = readUTF8Char(outchar, *input);
}
if(!outchar[0])
{
buffer[length++] = 0;
}
else
{
for(i = 0; outchar[i]; i++)
{
buffer[length++] = outchar[i];
}
}
*input += j;
}
*input = buffer;
return length;
}

View File

@@ -5,6 +5,8 @@
*
*/
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -14,6 +16,12 @@
#include "asm/types.h"
#include "asm/main.h"
#include "asm/lexer.h"
#include "extern/err.h"
#include "extern/strl.h"
#ifndef PATH_MAX
#define PATH_MAX 256
#endif
/*
* RGBAsm - FSTACK.C (FileStack routines)
@@ -62,8 +70,7 @@ pushcontext(void)
while (*ppFileStack)
ppFileStack = &((*ppFileStack)->pNext);
if ((*ppFileStack =
(struct sContext *) malloc(sizeof(struct sContext))) != NULL) {
if ((*ppFileStack = malloc(sizeof(struct sContext))) != NULL) {
(*ppFileStack)->FlexHandle = CurrentFlexHandle;
(*ppFileStack)->pNext = NULL;
strcpy((char *) (*ppFileStack)->tzFileName,
@@ -195,28 +202,33 @@ fstk_AddIncludePath(char *s)
strcpy(IncludePaths[NextIncPath++], s);
}
void
fstk_FindFile(char *s)
FILE *
fstk_FindFile(char *fname)
{
char t[_MAX_PATH + 1];
SLONG i = -1;
char path[PATH_MAX];
int i;
FILE *f;
strcpy(t, s);
if ((f = fopen(fname, "rb")) != NULL || errno != ENOENT) {
return f;
}
while (i < NextIncPath) {
FILE *f;
if ((f = fopen(t, "rb")) != NULL) {
fclose(f);
strcpy(s, t);
return;
for (i = 0; i < NextIncPath; ++i) {
if (strlcpy(path, IncludePaths[i], sizeof path) >=
sizeof path) {
continue;
}
i += 1;
if (i < NextIncPath) {
strcpy(t, IncludePaths[i]);
strcat(t, s);
if (strlcat(path, fname, sizeof path) >= sizeof path) {
continue;
}
if ((f = fopen(path, "rb")) != NULL || errno != ENOENT) {
return f;
}
}
errno = ENOENT;
return NULL;
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
@@ -225,33 +237,30 @@ fstk_FindFile(char *s)
*
*/
ULONG
void
fstk_RunInclude(char *tzFileName)
{
FILE *f;
//printf("INCLUDE: %s\n", s);
f = fstk_FindFile(tzFileName);
fstk_FindFile(tzFileName);
//printf("INCLUDING: %s\n", tzFileName);
if (f == NULL) {
err(1, "Unable to open included file '%s'",
tzFileName);
}
if ((f = fopen(tzFileName, "r")) != NULL) {
pushcontext();
nLineNo = 1;
nCurrentStatus = STAT_isInclude;
strcpy(tzCurrentFileName, tzFileName);
pCurrentFile = f;
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle);
pushcontext();
nLineNo = 1;
nCurrentStatus = STAT_isInclude;
strcpy(tzCurrentFileName, tzFileName);
pCurrentFile = f;
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle);
//Dirty hack to give the INCLUDE directive a linefeed
//Dirty hack to give the INCLUDE directive a linefeed
yyunput('\n');
nLineNo -= 1;
return (1);
} else
return (0);
yyunput('\n');
nLineNo -= 1;
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
@@ -275,7 +284,7 @@ fstk_RunMacro(char *s)
pCurrentMacro = sym;
CurrentFlexHandle =
yy_scan_bytes(pCurrentMacro->pMacro,
pCurrentMacro->ulMacroSize);
strlen(pCurrentMacro->pMacro));
yy_switch_to_buffer(CurrentFlexHandle);
return (1);
} else
@@ -360,7 +369,7 @@ fstk_RunRept(ULONG count)
*
*/
ULONG
void
fstk_Init(char *s)
{
char tzFileName[_MAX_PATH + 1];
@@ -368,17 +377,16 @@ fstk_Init(char *s)
sym_AddString("__FILE__", s);
strcpy(tzFileName, s);
fstk_FindFile(tzFileName);
pFileStack = NULL;
if ((pCurrentFile = fopen(tzFileName, "r")) != NULL) {
nMacroCount = 0;
nCurrentStatus = STAT_isInclude;
strcpy(tzCurrentFileName, tzFileName);
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle);
nLineNo = 1;
return (1);
} else
return (0);
pCurrentFile = fopen(tzFileName, "rb");
if (pCurrentFile == NULL) {
err(1, "Unable to open file '%s'", tzFileName);
}
nMacroCount = 0;
nCurrentStatus = STAT_isInclude;
strcpy(tzCurrentFileName, tzFileName);
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle);
nLineNo = 1;
}

View File

@@ -109,7 +109,7 @@ ascii2bin(char *s)
ULONG
ParseFixedPoint(char *s, ULONG size)
{
char dest[256];
//char dest[256];
ULONG i = 0, dot = 0;
while (size && dot != 2) {
@@ -117,13 +117,13 @@ ParseFixedPoint(char *s, ULONG size)
dot += 1;
if (dot < 2) {
dest[i] = s[i];
//dest[i] = s[i];
size -= 1;
i += 1;
}
}
dest[i] = 0;
//dest[i] = 0;
yyunputbytes(size);
@@ -208,10 +208,14 @@ PutMacroArg(char *src, ULONG size)
char *s;
yyskipbytes(size);
if ((s = sym_FindMacroArg(src[1] - '0')) != NULL) {
yyunputstr(s);
if ((size == 2 && src[1] >= '1' && src[1] <= '9')) {
if ((s = sym_FindMacroArg(src[1] - '0')) != NULL) {
yyunputstr(s);
} else {
yyerror("Macro argument not defined");
}
} else {
yyerror("Macro argument not defined");
yyerror("Invalid macro argument");
}
return (0);
}
@@ -219,9 +223,15 @@ PutMacroArg(char *src, ULONG size)
ULONG
PutUniqueArg(char *src, ULONG size)
{
char *s;
src = src;
yyskipbytes(size);
yyunputstr(sym_FindMacroArg(-1));
if ((s = sym_FindMacroArg(-1)) != NULL) {
yyunputstr(s);
} else {
yyerror("Macro unique label string not defined");
}
return (0);
}
@@ -298,6 +308,7 @@ struct sLexInitString staticstrings[] = {
{"rsset", T_POP_RSSET},
{"incbin", T_POP_INCBIN},
{"charmap", T_POP_CHARMAP},
{"fail", T_POP_FAIL},
{"warn", T_POP_WARN},
@@ -387,7 +398,7 @@ setuplex(void)
id = lex_FloatAlloc(&tMacroArgToken);
lex_FloatAddFirstRange(id, '\\', '\\');
lex_FloatAddSecondRange(id, '0', '9');
lex_FloatAddSecondRange(id, '1', '9');
id = lex_FloatAlloc(&tMacroUniqueToken);
lex_FloatAddFirstRange(id, '\\', '\\');
lex_FloatAddSecondRange(id, '@', '@');

View File

@@ -1,17 +1,20 @@
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include "asm/asm.h"
#include "asm/lexer.h"
#include "asm/types.h"
#include "asm/main.h"
#include "asm/rpn.h"
#include "asm/fstack.h"
#include "extern/err.h"
#include "asmy.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct sLexString {
char *tzName;
ULONG nToken;
@@ -115,11 +118,9 @@ yy_scan_bytes(char *mem, ULONG size)
{
YY_BUFFER_STATE pBuffer;
if ((pBuffer =
(YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) !=
NULL) {
if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) {
if ((pBuffer->pBufferRealStart =
(char *) malloc(size + 1 + SAFETYMARGIN)) != NULL) {
malloc(size + 1 + SAFETYMARGIN)) != NULL) {
pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN;
pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN;
memcpy(pBuffer->pBuffer, mem, size);
@@ -138,8 +139,7 @@ yy_create_buffer(FILE * f)
{
YY_BUFFER_STATE pBuffer;
if ((pBuffer =
(YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) != NULL) {
if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) {
ULONG size;
fseek(f, 0, SEEK_END);
@@ -147,7 +147,7 @@ yy_create_buffer(FILE * f)
fseek(f, 0, SEEK_SET);
if ((pBuffer->pBufferRealStart =
(char *) malloc(size + 2 + SAFETYMARGIN)) != NULL) {
malloc(size + 2 + SAFETYMARGIN)) != NULL) {
char *mem;
ULONG instring = 0;
@@ -166,7 +166,10 @@ yy_create_buffer(FILE * f)
if (*mem == '\"')
instring = 1 - instring;
if (instring) {
if (mem[0] == '\\' &&
(mem[1] == '\"' || mem[1] == '\\')) {
mem += 2;
} else if (instring) {
mem += 1;
} else {
if ((mem[0] == 10 && mem[1] == 13)
@@ -213,9 +216,8 @@ void
lex_CheckCharacterRange(UWORD start, UWORD end)
{
if (start > end || start < 1 || end > 127) {
fprintf(stderr, "Invalid character range (start: %u, end: %u)\n",
errx(1, "Invalid character range (start: %u, end: %u)",
start, end);
exit(1);
}
}
@@ -344,11 +346,7 @@ lex_AddStrings(struct sLexInitString * lex)
while (*ppHash)
ppHash = &((*ppHash)->pNext);
//printf("%s has hashvalue %d\n", lex->tzName, hash);
if (((*ppHash) =
(struct sLexString *) malloc(sizeof(struct sLexString))) !=
NULL) {
if (((*ppHash) = malloc(sizeof(struct sLexString))) != NULL) {
if (((*ppHash)->tzName =
(char *) strdup(lex->tzName)) != NULL) {
(*ppHash)->nNameLength = strlen(lex->tzName);
@@ -444,7 +442,6 @@ CopyMacroArg(char *dest, size_t maxLength, char c)
int argNum;
switch (c) {
case '0':
case '1':
case '2':
case '3':

View File

@@ -5,8 +5,8 @@
*
*/
#define _XOPEN_SOURCE 500
#include <math.h>
#include <getopt.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
@@ -19,6 +19,7 @@
#include "asm/fstack.h"
#include "asm/output.h"
#include "asm/main.h"
#include "extern/err.h"
int yyparse(void);
void setuplex(void);
@@ -133,9 +134,8 @@ opt_Parse(char *s)
newopt.gbgfx[2] = s[3];
newopt.gbgfx[3] = s[4];
} else {
fprintf(stderr, "Must specify exactly 4 characters "
"for option 'g'\n");
exit(1);
errx(1, "Must specify exactly 4 characters for "
"option 'g'");
}
break;
case 'b':
@@ -143,9 +143,8 @@ opt_Parse(char *s)
newopt.binary[0] = s[1];
newopt.binary[1] = s[2];
} else {
fprintf(stderr, "Must specify exactly 2 characters "
"for option 'b'\n");
exit(1);
errx(1, "Must specify exactly 2 characters for option "
"'b'");
}
break;
case 'z':
@@ -154,12 +153,10 @@ opt_Parse(char *s)
result = sscanf(&s[1], "%lx", &newopt.fillchar);
if (!((result == EOF) || (result == 1))) {
fprintf(stderr,
"Invalid argument for option 'z'\n");
exit(1);
errx(1, "Invalid argument for option 'z'");
}
} else {
fprintf(stderr, "Invalid argument for option 'z'\n");
errx(1, "Invalid argument for option 'z'");
exit(1);
}
break;
@@ -176,9 +173,7 @@ opt_Push(void)
{
struct sOptionStackEntry *pOpt;
if ((pOpt =
(struct sOptionStackEntry *)
malloc(sizeof(struct sOptionStackEntry))) != NULL) {
if ((pOpt = malloc(sizeof(struct sOptionStackEntry))) != NULL) {
pOpt->Options = CurrentOptions;
pOpt->pNext = pOptionStack;
pOptionStack = pOpt;
@@ -245,8 +240,6 @@ fatalerror(const char *fmt, ...)
void
PrintUsage(void)
{
printf("RGBAsm v" ASM_VERSION " (part of ASMotor " ASMOTOR_VERSION
")\n\n");
printf("Usage: rgbasm [-v] [-h] [-b chars] [-g chars] [-i path] [-o outfile] [-p pad_value]\n"
" file\n");
exit(1);
@@ -295,9 +288,8 @@ main(int argc, char *argv[])
newopt.binary[0] = optarg[1];
newopt.binary[1] = optarg[2];
} else {
fprintf(stderr, "Must specify exactly "
"2 characters for option 'b'\n");
exit(1);
errx(1, "Must specify exactly 2 characters for "
"option 'b'");
}
break;
case 'g':
@@ -307,9 +299,8 @@ main(int argc, char *argv[])
newopt.gbgfx[2] = optarg[3];
newopt.gbgfx[3] = optarg[4];
} else {
fprintf(stderr, "Must specify exactly "
"4 characters for option 'g'\n");
exit(1);
errx(1, "Must specify exactly 4 characters for "
"option 'g'");
}
break;
case 'h':
@@ -324,14 +315,11 @@ main(int argc, char *argv[])
case 'p':
newopt.fillchar = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
fprintf(stderr,
"Invalid argument for option 'p'\n");
exit(1);
errx(1, "Invalid argument for option 'p'");
}
if (newopt.fillchar < 0 || newopt.fillchar > 0xFF) {
fprintf(stderr, "Argument for option 'p' "
"must be between 0 and 0xFF\n");
exit(1);
errx(1, "Argument for option 'p' must be "
"between 0 and 0xFF");
}
break;
case 'v':
@@ -348,7 +336,6 @@ main(int argc, char *argv[])
DefaultOptions = CurrentOptions;
/* tzMainfile=argv[argn++]; argc-=1; */
tzMainfile = argv[argc - 1];
setuplex();
@@ -366,75 +353,67 @@ main(int argc, char *argv[])
nPass = 1;
nErrors = 0;
sym_PrepPass1();
if (fstk_Init(tzMainfile)) {
if (CurrentOptions.verbose) {
printf("Pass 1...\n");
}
fstk_Init(tzMainfile);
if (CurrentOptions.verbose) {
printf("Pass 1...\n");
}
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
if (yyparse() == 0 && nErrors == 0) {
if (nIFDepth == 0) {
nTotalLines = 0;
nLineNo = 1;
nIFDepth = 0;
nPC = 0;
nPass = 2;
nErrors = 0;
sym_PrepPass2();
out_PrepPass2();
fstk_Init(tzMainfile);
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
if (yyparse() == 0 && nErrors == 0) {
if (nIFDepth == 0) {
nTotalLines = 0;
nLineNo = 1;
nIFDepth = 0;
nPC = 0;
nPass = 2;
nErrors = 0;
sym_PrepPass2();
out_PrepPass2();
fstk_Init(tzMainfile);
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
if (CurrentOptions.verbose) {
printf("Pass 2...\n");
}
if (yyparse() == 0 && nErrors == 0) {
double timespent;
nEndClock = clock();
timespent =
((double) (nEndClock - nStartClock))
/ (double) CLOCKS_PER_SEC;
if (CurrentOptions.verbose) {
printf("Pass 2...\n");
}
if (yyparse() == 0 && nErrors == 0) {
double timespent;
nEndClock = clock();
timespent =
((double) (nEndClock - nStartClock))
/ (double) CLOCKS_PER_SEC;
if (CurrentOptions.verbose) {
printf
("Success! %ld lines in %d.%02d seconds ",
nTotalLines, (int) timespent,
((int) (timespent * 100.0)) % 100);
if (timespent == 0)
printf
("(INFINITY lines/minute)\n");
else
printf("(%d lines/minute)\n",
(int) (60 / timespent *
nTotalLines));
}
out_WriteObject();
} else {
printf
("Assembly aborted in pass 2 (%ld errors)!\n",
nErrors);
//sym_PrintSymbolTable();
exit(5);
("Success! %ld lines in %d.%02d seconds ",
nTotalLines, (int) timespent,
((int) (timespent * 100.0)) % 100);
if (timespent == 0)
printf
("(INFINITY lines/minute)\n");
else
printf("(%d lines/minute)\n",
(int) (60 / timespent *
nTotalLines));
}
out_WriteObject();
} else {
fprintf(stderr,
"Unterminated IF construct (%ld levels)!\n",
nIFDepth);
exit(1);
printf
("Assembly aborted in pass 2 (%ld errors)!\n",
nErrors);
//sym_PrintSymbolTable();
exit(5);
}
} else {
fprintf(stderr,
"Assembly aborted in pass 1 (%ld errors)!\n",
nErrors);
exit(1);
errx(1, "Unterminated IF construct (%ld levels)!",
nIFDepth);
}
} else {
printf("File '%s' not found\n", tzMainfile);
exit(5);
errx(1, "Assembly aborted in pass 1 (%ld errors)!",
nErrors);
}
return (0);
return 0;
}

View File

@@ -11,12 +11,14 @@
#include <string.h>
#include "asm/asm.h"
#include "asm/charmap.h"
#include "asm/output.h"
#include "asm/symbol.h"
#include "asm/mylink.h"
#include "asm/main.h"
#include "asm/rpn.h"
#include "asm/fstack.h"
#include "extern/err.h"
#define SECTIONCHUNK 0x4000
@@ -61,7 +63,7 @@ struct PatchSymbol *tHashedPatchSymbols[HASHSIZE];
struct Section *pSectionList = NULL, *pCurrentSection = NULL;
struct PatchSymbol *pPatchSymbols = NULL;
struct PatchSymbol **ppPatchSymbolsTail = &pPatchSymbols;
char tzObjectname[_MAX_PATH];
char *tzObjectname;
struct SectionStackEntry *pSectionStack = NULL;
/*
@@ -76,9 +78,7 @@ out_PushSection(void)
{
struct SectionStackEntry *pSect;
if ((pSect =
(struct SectionStackEntry *)
malloc(sizeof(struct SectionStackEntry))) != NULL) {
if ((pSect = malloc(sizeof(struct SectionStackEntry))) != NULL) {
pSect->pSection = pCurrentSection;
pSect->pNext = pSectionStack;
pSectionStack = pSect;
@@ -342,9 +342,7 @@ addsymbol(struct sSymbol * pSym)
ppPSym = &((*ppPSym)->pBucketNext);
}
if ((*ppPSym = pPSym =
(struct PatchSymbol *) malloc(sizeof(struct PatchSymbol))) !=
NULL) {
if ((*ppPSym = pPSym = malloc(sizeof(struct PatchSymbol))) != NULL) {
pPSym->pNext = NULL;
pPSym->pBucketNext = NULL;
pPSym->pSymbol = pSym;
@@ -392,8 +390,7 @@ allocpatch(void)
{
struct Patch *pPatch;
if ((pPatch =
(struct Patch *) malloc(sizeof(struct Patch))) != NULL) {
if ((pPatch = malloc(sizeof(struct Patch))) != NULL) {
pPatch->pNext = pCurrentSection->pPatches;
pPatch->nRPNSize = 0;
pPatch->pRPN = NULL;
@@ -471,7 +468,7 @@ createpatch(ULONG type, struct Expression * expr)
break;
}
}
if ((pPatch->pRPN = (UBYTE *) malloc(rpnptr)) != NULL) {
if ((pPatch->pRPN = malloc(rpnptr)) != NULL) {
memcpy(pPatch->pRPN, rpnexpr, rpnptr);
pPatch->nRPNSize = rpnptr;
}
@@ -503,9 +500,12 @@ void
checkcodesection(SLONG size)
{
checksection();
if ((pCurrentSection->nType == SECT_ROM0
|| pCurrentSection->nType == SECT_ROMX)
&& (pCurrentSection->nPC + size <= MAXSECTIONSIZE)) {
if (pCurrentSection->nType != SECT_ROM0 &&
pCurrentSection->nType != SECT_ROMX) {
errx(1, "Section '%s' cannot contain code or data (not a "
"ROM0 or ROMX)", pCurrentSection->pzName);
}
if (pCurrentSection->nPC + size <= MAXSECTIONSIZE) {
if (((pCurrentSection->nPC % SECTIONCHUNK) >
((pCurrentSection->nPC + size) % SECTIONCHUNK))
&& (pCurrentSection->nType == SECT_ROM0
@@ -522,8 +522,7 @@ checkcodesection(SLONG size)
}
return;
} else
fatalerror
("Section can't contain initialized data or section limit exceeded");
errx(1, "Section '%s' is too big", pCurrentSection->pzName);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
@@ -592,7 +591,7 @@ out_PrepPass2(void)
void
out_SetFileName(char *s)
{
strcpy(tzObjectname, s);
tzObjectname = s;
if (CurrentOptions.verbose) {
printf("Output filename %s\n", s);
}
@@ -630,11 +629,8 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org,
pSect = pSect->pNext;
}
if ((*ppSect =
(pSect =
(struct Section *) malloc(sizeof(struct Section)))) != NULL) {
if ((pSect->pzName =
(char *) malloc(strlen(pzName) + 1)) != NULL) {
if ((*ppSect = (pSect = malloc(sizeof(struct Section)))) != NULL) {
if ((pSect->pzName = malloc(strlen(pzName) + 1)) != NULL) {
strcpy(pSect->pzName, pzName);
pSect->nType = secttype;
pSect->nPC = 0;
@@ -642,10 +638,10 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org,
pSect->nBank = bank;
pSect->pNext = NULL;
pSect->pPatches = NULL;
pSect->charmap = NULL;
pPatchSymbols = NULL;
if ((pSect->tData =
(UBYTE *) malloc(SECTIONCHUNK)) != NULL) {
if ((pSect->tData = malloc(SECTIONCHUNK)) != NULL) {
return (pSect);
} else
fatalerror("Not enough memory for section");
@@ -715,6 +711,14 @@ out_AbsByte(int b)
nPC += 1;
pPCSymbol->nValue += 1;
}
void
out_AbsByteGroup(char *s, int length)
{
checkcodesection(length);
while (length--)
out_AbsByte(*s++);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
@@ -907,30 +911,30 @@ out_BinaryFile(char *s)
{
FILE *f;
fstk_FindFile(s);
f = fstk_FindFile(s);
if (f == NULL) {
err(1, "Unable to open incbin file '%s'", s);
}
if ((f = fopen(s, "rb")) != NULL) {
SLONG fsize;
SLONG fsize;
fseek(f, 0, SEEK_END);
fsize = ftell(f);
fseek(f, 0, SEEK_SET);
fseek(f, 0, SEEK_END);
fsize = ftell(f);
fseek(f, 0, SEEK_SET);
checkcodesection(fsize);
checkcodesection(fsize);
if (nPass == 2) {
SLONG dest = nPC;
SLONG todo = fsize;
if (nPass == 2) {
SLONG dest = nPC;
SLONG todo = fsize;
while (todo--)
pCurrentSection->tData[dest++] = fgetc(f);
}
pCurrentSection->nPC += fsize;
nPC += fsize;
pPCSymbol->nValue += fsize;
fclose(f);
} else
fatalerror("Could not open file '%s': %s", s, strerror(errno));
while (todo--)
pCurrentSection->tData[dest++] = fgetc(f);
}
pCurrentSection->nPC += fsize;
nPC += fsize;
pPCSymbol->nValue += fsize;
fclose(f);
}
void
@@ -944,36 +948,36 @@ out_BinaryFileSlice(char *s, SLONG start_pos, SLONG length)
if (length < 0)
fatalerror("Number of bytes to read must be greater than zero");
fstk_FindFile(s);
f = fstk_FindFile(s);
if (f == NULL) {
err(1, "Unable to open included file '%s'", s);
}
if ((f = fopen(s, "rb")) != NULL) {
SLONG fsize;
SLONG fsize;
fseek(f, 0, SEEK_END);
fsize = ftell(f);
fseek(f, 0, SEEK_END);
fsize = ftell(f);
if (start_pos >= fsize)
fatalerror("Specified start position is greater than length of file");
if (start_pos >= fsize)
fatalerror("Specified start position is greater than length of file");
if ((start_pos + length) > fsize)
fatalerror("Specified range in INCBIN is out of bounds");
if ((start_pos + length) > fsize)
fatalerror("Specified range in INCBIN is out of bounds");
fseek(f, start_pos, SEEK_SET);
fseek(f, start_pos, SEEK_SET);
checkcodesection(length);
checkcodesection(length);
if (nPass == 2) {
SLONG dest = nPC;
SLONG todo = length;
if (nPass == 2) {
SLONG dest = nPC;
SLONG todo = length;
while (todo--)
pCurrentSection->tData[dest++] = fgetc(f);
}
pCurrentSection->nPC += length;
nPC += length;
pPCSymbol->nValue += length;
while (todo--)
pCurrentSection->tData[dest++] = fgetc(f);
}
pCurrentSection->nPC += length;
nPC += length;
pPCSymbol->nValue += length;
fclose(f);
} else
fatalerror("Could not open file '%s': %s", s, strerror(errno));
fclose(f);
}

View File

@@ -60,7 +60,6 @@ and
.Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbfix 1 ,
.Xr rgblib 1 ,
.Xr rgblink 1 ,
.Xr gbz80 7
.Sh HISTORY

View File

@@ -5,6 +5,8 @@
*
*/
#define _XOPEN_SOURCE 500
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
@@ -94,8 +96,7 @@ createsymbol(char *s)
while ((*ppsym) != NULL)
ppsym = &((*ppsym)->pNext);
if (((*ppsym) =
(struct sSymbol *) malloc(sizeof(struct sSymbol))) != NULL) {
if (((*ppsym) = malloc(sizeof(struct sSymbol))) != NULL) {
strcpy((*ppsym)->tzName, s);
(*ppsym)->nValue = 0;
(*ppsym)->nType = 0;
@@ -432,6 +433,8 @@ sym_FindMacroArg(SLONG i)
if (i == -1)
i = MAXMACROARGS + 1;
assert(i-1 >= 0 &&
i-1 < sizeof currentmacroargs / sizeof *currentmacroargs);
return (currentmacroargs[i - 1]);
}
@@ -570,8 +573,7 @@ sym_AddString(char *tzSym, char *tzValue)
nsym = createsymbol(tzSym);
if (nsym) {
if ((nsym->pMacro =
(char *) malloc(strlen(tzValue) + 1)) != NULL)
if ((nsym->pMacro = malloc(strlen(tzValue) + 1)) != NULL)
strcpy(nsym->pMacro, tzValue);
else
fatalerror("No memory for stringequate");
@@ -873,7 +875,6 @@ sym_Init(void)
p_NARGSymbol = findsymbol("_NARG", NULL);
p_NARGSymbol->Callback = Callback_NARG;
sym_AddEqu("__ASM__", (SLONG) (atof(ASM_VERSION) * 65536));
sym_AddSet("_RS", 0);
if (time(&tod) != -1) {

View File

@@ -1,13 +1,16 @@
%{
#define _XOPEN_SOURCE 500
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "asm/symbol.h"
#include "asm/asm.h"
#include "asm/charmap.h"
#include "asm/output.h"
#include "asm/mylink.h"
#include "asm/fstack.h"
@@ -66,6 +69,21 @@ ULONG str2int( char *s )
return( r );
}
ULONG str2int2( char *s, int length )
{
int i;
ULONG r=0;
i = (length - 4 < 0 ? 0 : length - 4);
while(i < length)
{
r<<=8;
r|=(UBYTE)(s[i]);
i++;
}
return( r );
}
ULONG isWhiteSpace( char s )
{
return( s==' ' || s=='\t' || s=='\0' || s=='\n' );
@@ -130,8 +148,7 @@ void copyrept( void )
src=pCurrentBuffer->pBuffer;
ulNewMacroSize=len;
if( (tzNewMacro=(char *)malloc(ulNewMacroSize+1))!=NULL )
{
if ((tzNewMacro = malloc(ulNewMacroSize + 1)) != NULL) {
ULONG i;
tzNewMacro[ulNewMacroSize]=0;
@@ -140,8 +157,7 @@ void copyrept( void )
if( (tzNewMacro[i]=src[i])=='\n' )
nLineNo+=1;
}
}
else
} else
fatalerror( "No mem for REPT block" );
yyskipbytes( ulNewMacroSize+4 );
@@ -425,6 +441,7 @@ void if_skip_to_endc( void )
%token T_POP_ENDM
%token T_POP_RSRESET T_POP_RSSET
%token T_POP_INCBIN T_POP_REPT
%token T_POP_CHARMAP
%token T_POP_SHIFT
%token T_POP_ENDR
%token T_POP_FAIL

View File

@@ -88,6 +88,7 @@ simple_pseudoop : include
| rsreset
| rsset
| incbin
| charmap
| rept
| shift
| fail
@@ -265,10 +266,7 @@ set : T_LABEL T_POP_SET const
include : T_POP_INCLUDE string
{
if( !fstk_RunInclude($2) )
{
yyerror("Could not open file '%s' : %s\n", $2, strerror(errno));
}
fstk_RunInclude($2);
}
;
@@ -280,6 +278,24 @@ incbin : T_POP_INCBIN string
}
;
charmap : T_POP_CHARMAP string ',' string
{
if(charmap_Add($2, $4[0] & 0xFF) == -1)
{
fprintf(stderr, "Error parsing charmap. Either you've added too many (%i), or the input character length is too long (%i)' : %s\n", MAXCHARMAPS, CHARMAPLENGTH, strerror(errno));
yyerror("Error parsing charmap.");
}
}
| T_POP_CHARMAP string ',' const
{
if(charmap_Add($2, $4 & 0xFF) == -1)
{
fprintf(stderr, "Error parsing charmap. Either you've added too many (%i), or the input character length is too long (%i)' : %s\n", MAXCHARMAPS, CHARMAPLENGTH, strerror(errno));
yyerror("Error parsing charmap.");
}
}
;
printt : T_POP_PRINTT string
{
if( nPass==1 )
@@ -339,7 +355,7 @@ constlist_8bit : constlist_8bit_entry
constlist_8bit_entry : { out_Skip( 1 ); }
| const_8bit { out_RelByte( &$1 ); }
| string { out_String( $1 ); }
| string { char *s; int length; s = $1; length = charmap_Convert(&s); out_AbsByteGroup(s, length); free(s); }
;
constlist_16bit : constlist_16bit_entry
@@ -394,7 +410,7 @@ relocconst : T_ID
| T_NUMBER
{ rpn_Number(&$$,$1); $$.nVal = $1; }
| string
{ ULONG r; r=str2int($1); rpn_Number(&$$,r); $$.nVal=r; }
{ char *s; int length; ULONG r; s = $1; length = charmap_Convert(&s); r = str2int2(s, length); free(s); rpn_Number(&$$,r); $$.nVal=r; }
| T_OP_LOGICNOT relocconst %prec NEG
{ rpn_LOGNOT(&$$,&$2); }
| relocconst T_OP_LOGICOR relocconst

92
src/extern/err.c vendored Normal file
View File

@@ -0,0 +1,92 @@
/*
* Copyright © 2005-2013 Rich Felker, et al.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include "extern/err.h"
#ifndef __MINGW32__
char *__progname;
#endif
void rgbds_vwarn(const char *fmt, va_list ap)
{
fprintf (stderr, "%s: ", __progname);
if (fmt) {
vfprintf(stderr, fmt, ap);
fputs (": ", stderr);
}
perror(0);
}
void rgbds_vwarnx(const char *fmt, va_list ap)
{
fprintf (stderr, "%s: ", __progname);
if (fmt) vfprintf(stderr, fmt, ap);
putc('\n', stderr);
}
_Noreturn void rgbds_verr(int status, const char *fmt, va_list ap)
{
vwarn(fmt, ap);
exit(status);
}
_Noreturn void rgbds_verrx(int status, const char *fmt, va_list ap)
{
vwarnx(fmt, ap);
exit(status);
}
void rgbds_warn(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vwarn(fmt, ap);
va_end(ap);
}
void rgbds_warnx(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vwarnx(fmt, ap);
va_end(ap);
}
_Noreturn void rgbds_err(int status, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
verr(status, fmt, ap);
va_end(ap);
}
_Noreturn void rgbds_errx(int status, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
verrx(status, fmt, ap);
va_end(ap);
}

55
src/extern/strlcat.c vendored Normal file
View File

@@ -0,0 +1,55 @@
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
/*
* Copyright (c) 1998 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 <sys/types.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
rgbds_strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}

51
src/extern/strlcpy.c vendored Normal file
View File

@@ -0,0 +1,51 @@
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
/*
* Copyright (c) 1998 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 <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
rgbds_strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}

View File

@@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <getopt.h>
#define _XOPEN_SOURCE 500
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -22,6 +22,8 @@
#include <string.h>
#include <unistd.h>
#include "extern/err.h"
static void
usage(void)
{
@@ -47,9 +49,7 @@ main(int argc, char *argv[])
usage();
if ((rom = fopen(argv[argc - 1], "rb+")) == NULL) {
fprintf(stderr, "Error opening file %s: \n", argv[argc - 1]);
perror(NULL);
exit(1);
err(1, "Error opening file %s", argv[argc - 1]);
}
/*
@@ -93,9 +93,8 @@ main(int argc, char *argv[])
setid = true;
if (strlen(optarg) != 4) {
fprintf(stderr, "Game ID %s must be exactly 4 "
"characters\n", optarg);
exit(1);
errx(1, "Game ID %s must be exactly 4 "
"characters", optarg);
}
id = optarg;
@@ -107,10 +106,8 @@ main(int argc, char *argv[])
setnewlicensee = true;
if (strlen(optarg) != 2) {
fprintf(stderr,
"New licensee code %s is not the correct "
"length of 2 characters\n", optarg);
exit(1);
errx(1, "New licensee code %s is not the "
"correct length of 2 characters", optarg);
}
newlicensee = optarg;
@@ -120,15 +117,11 @@ main(int argc, char *argv[])
licensee = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
fprintf(stderr,
"Invalid argument for option 'l'\n");
exit(1);
errx(1, "Invalid argument for option 'l'");
}
if (licensee < 0 || licensee > 0xFF) {
fprintf(stderr,
"Argument for option 'l' must be "
"between 0 and 255\n");
exit(1);
errx(1, "Argument for option 'l' must be "
"between 0 and 255");
}
break;
case 'm':
@@ -136,15 +129,11 @@ main(int argc, char *argv[])
cartridge = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
fprintf(stderr,
"Invalid argument for option 'm'\n");
exit(1);
errx(1, "Invalid argument for option 'm'");
}
if (cartridge < 0 || cartridge > 0xFF) {
fprintf(stderr,
"Argument for option 'm' must be "
"between 0 and 255\n");
exit(1);
errx(1, "Argument for option 'm' must be "
"between 0 and 255");
}
break;
case 'n':
@@ -152,15 +141,11 @@ main(int argc, char *argv[])
version = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
fprintf(stderr,
"Invalid argument for option 'n'\n");
exit(1);
errx(1, "Invalid argument for option 'n'");
}
if (version < 0 || version > 0xFF) {
fprintf(stderr,
"Argument for option 'n' must be "
"between 0 and 255\n");
exit(1);
errx(1, "Argument for option 'n' must be "
"between 0 and 255");
}
break;
case 'p':
@@ -168,15 +153,11 @@ main(int argc, char *argv[])
padvalue = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
fprintf(stderr,
"Invalid argument for option 'p'\n");
exit(1);
errx(1, "Invalid argument for option 'p'");
}
if (padvalue < 0 || padvalue > 0xFF) {
fprintf(stderr,
"Argument for option 'p' must be "
"between 0 and 255\n");
exit(1);
errx(1, "Argument for option 'p' must be "
"between 0 and 255");
}
break;
case 'r':
@@ -184,14 +165,11 @@ main(int argc, char *argv[])
ramsize = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
fprintf(stderr,
"Invalid argument for option 'r'\n");
errx(1, "Invalid argument for option 'r'");
}
if (ramsize < 0 || ramsize > 0xFF) {
fprintf(stderr,
"Argument for option 'r' must be "
"between 0 and 255\n");
exit(1);
errx(1, "Argument for option 'r' must be "
"between 0 and 255");
}
break;
case 's':
@@ -201,15 +179,13 @@ main(int argc, char *argv[])
settitle = true;
if (strlen(optarg) > 16) {
fprintf(stderr, "Title %s is greater than the "
"maximum of 16 characters\n", optarg);
exit(1);
errx(1, "Title %s is greater than the "
"maximum of 16 characters", optarg);
}
if (strlen(optarg) == 16)
fprintf(stderr,
"Title %s is 16 chars, it is best "
"to keep it to 15 or fewer\n", optarg);
warnx("Title %s is 16 chars, it is best to "
"keep it to 15 or fewer", optarg);
title = optarg;
break;
@@ -221,8 +197,6 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
/*
* Write changes to ROM
@@ -315,8 +289,7 @@ main(int argc, char *argv[])
byte |= 1 << 6;
if (byte & 0x3F)
fprintf(stderr,
"Color flag conflicts with game title\n");
warnx("Color flag conflicts with game title");
fseek(rom, 0x143, SEEK_SET);
fputc(byte, rom);
@@ -353,9 +326,8 @@ main(int argc, char *argv[])
*/
if (!setlicensee)
fprintf(stderr,
"You should probably set both '-s' and "
"'-l 0x33'\n");
warnx("You should probably set both '-s' and "
"'-l 0x33'");
fseek(rom, 0x146, SEEK_SET);
fputc(3, rom);
@@ -392,7 +364,7 @@ main(int argc, char *argv[])
}
if (newsize > 0x800000) /* ROM is bigger than 8MiB */
fprintf(stderr, "ROM size is bigger than 8MiB\n");
warnx("ROM size is bigger than 8MiB");
buf = malloc(newsize - romsize);
memset(buf, padvalue, newsize - romsize);

View File

@@ -130,7 +130,6 @@ of the game
.Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbasm 1 ,
.Xr rgblib 1 ,
.Xr rgblink 1 ,
.Xr gbz80 7
.Sh HISTORY

View File

@@ -1,306 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lib/types.h"
#include "lib/libwrap.h"
SLONG
file_Length(FILE * f)
{
ULONG r, p;
p = ftell(f);
fseek(f, 0, SEEK_END);
r = ftell(f);
fseek(f, p, SEEK_SET);
return (r);
}
SLONG
file_ReadASCIIz(char *b, FILE * f)
{
SLONG r = 0;
while ((*b++ = fgetc(f)) != 0)
r += 1;
return (r + 1);
}
void
file_WriteASCIIz(char *b, FILE * f)
{
while (*b)
fputc(*b++, f);
fputc(0, f);
}
UWORD
file_ReadWord(FILE * f)
{
UWORD r;
r = fgetc(f);
r |= fgetc(f) << 8;
return (r);
}
void
file_WriteWord(UWORD w, FILE * f)
{
fputc(w, f);
fputc(w >> 8, f);
}
ULONG
file_ReadLong(FILE * f)
{
ULONG r;
r = fgetc(f);
r |= fgetc(f) << 8;
r |= fgetc(f) << 16;
r |= fgetc(f) << 24;
return (r);
}
void
file_WriteLong(UWORD w, FILE * f)
{
fputc(w, f);
fputc(w >> 8, f);
fputc(w >> 16, f);
fputc(w >> 24, f);
}
sLibrary *
lib_ReadLib0(FILE * f, SLONG size)
{
if (size) {
sLibrary *l = NULL, *first = NULL;
while (size > 0) {
if (l == NULL) {
l = malloc(sizeof *l);
if (!l) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
first = l;
} else {
l->pNext = malloc(sizeof *l->pNext);
if (!l->pNext) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
l = l->pNext;
}
size -= file_ReadASCIIz(l->tName, f);
l->uwTime = file_ReadWord(f);
size -= 2;
l->uwDate = file_ReadWord(f);
size -= 2;
l->nByteLength = file_ReadLong(f);
size -= 4;
if ((l->pData = malloc(l->nByteLength))) {
fread(l->pData, sizeof(UBYTE), l->nByteLength,
f);
size -= l->nByteLength;
} else {
fprintf(stderr, "Out of memory\n");
exit(1);
}
l->pNext = NULL;
}
return (first);
}
return (NULL);
}
sLibrary *
lib_Read(char *filename)
{
FILE *f;
if ((f = fopen(filename, "rb"))) {
SLONG size;
char ID[5];
size = file_Length(f);
if (size == 0) {
fclose(f);
return (NULL);
}
fread(ID, sizeof(char), 4, f);
ID[4] = 0;
size -= 4;
if (strcmp(ID, "XLB0") == 0) {
sLibrary *r;
r = lib_ReadLib0(f, size);
fclose(f);
printf("Library '%s' opened\n", filename);
return (r);
} else {
fclose(f);
fprintf(stderr, "Not a valid xLib library\n");
exit(1);
}
} else {
printf
("Library '%s' not found, it will be created if necessary\n",
filename);
return (NULL);
}
}
BBOOL
lib_Write(sLibrary * lib, char *filename)
{
FILE *f;
if ((f = fopen(filename, "wb"))) {
fwrite("XLB0", sizeof(char), 4, f);
while (lib) {
file_WriteASCIIz(lib->tName, f);
file_WriteWord(lib->uwTime, f);
file_WriteWord(lib->uwDate, f);
file_WriteLong(lib->nByteLength, f);
fwrite(lib->pData, sizeof(UBYTE), lib->nByteLength, f);
lib = lib->pNext;
}
fclose(f);
printf("Library '%s' closed\n", filename);
return (1);
}
return (0);
}
sLibrary *
lib_Find(sLibrary * lib, char *filename)
{
if (strlen(filename) >= MAXNAMELENGTH) {
fprintf(stderr, "Module name too long: %s\n", filename);
exit(1);
}
while (lib) {
if (strcmp(lib->tName, filename) == 0)
break;
lib = lib->pNext;
}
return (lib);
}
sLibrary *
lib_AddReplace(sLibrary * lib, char *filename)
{
FILE *f;
if ((f = fopen(filename, "rb"))) {
sLibrary *module;
if (strlen(filename) >= MAXNAMELENGTH) {
fprintf(stderr, "Module name too long: %s\n",
filename);
exit(1);
}
if ((module = lib_Find(lib, filename)) == NULL) {
module = malloc(sizeof *module);
if (!module) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
module->pNext = lib;
lib = module;
} else {
/* Module already exists */
free(module->pData);
}
module->nByteLength = file_Length(f);
strcpy(module->tName, filename);
module->pData = malloc(module->nByteLength);
if (!module->pData) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
fread(module->pData, sizeof(UBYTE), module->nByteLength, f);
printf("Added module '%s'\n", filename);
fclose(f);
}
return (lib);
}
sLibrary *
lib_DeleteModule(sLibrary * lib, char *filename)
{
sLibrary **pp, **first;
BBOOL found = 0;
pp = &lib;
first = pp;
if (strlen(filename) >= MAXNAMELENGTH) {
fprintf(stderr, "Module name too long: %s\n", filename);
exit(1);
}
while ((*pp) && (!found)) {
if (strcmp((*pp)->tName, filename) == 0) {
sLibrary *t;
t = *pp;
if (t->pData)
free(t->pData);
*pp = t->pNext;
free(t);
found = 1;
}
pp = &((*pp)->pNext);
}
if (!found) {
fprintf(stderr, "Module not found\n");
exit(1);
} else
printf("Module '%s' deleted from library\n", filename);
return (*first);
}
void
lib_Free(sLibrary * lib)
{
while (lib) {
sLibrary *l;
if (lib->pData)
free(lib->pData);
l = lib;
lib = lib->pNext;
free(l);
}
}

View File

@@ -1,120 +0,0 @@
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "asmotor.h"
#include "lib/types.h"
#include "lib/library.h"
/*
* Print the usagescreen
*
*/
static void
usage(void)
{
printf("RGBLib v" LIB_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n");
printf("usage: rgblib file [add | delete | extract | list] [module ...]\n");
exit(1);
}
/*
* The main routine
*
*/
int
main(int argc, char *argv[])
{
SLONG argn = 0;
char *libname;
argc -= 1;
argn += 1;
if (argc >= 2) {
sLibrary *lib;
lib = lib_Read(libname = argv[argn++]);
argc -= 1;
if (strcmp(argv[argn], "add") == 0) {
argn += 1;
argc -= 1;
while (argc) {
lib = lib_AddReplace(lib, argv[argn++]);
argc -= 1;
}
lib_Write(lib, libname);
lib_Free(lib);
} else if (strcmp(argv[argn], "delete") == 0) {
argn += 1;
argc -= 1;
while (argc) {
lib =
lib_DeleteModule(lib, argv[argn++]);
argc -= 1;
}
lib_Write(lib, libname);
lib_Free(lib);
} else if (strcmp(argv[argn], "extract") == 0) {
argn += 1;
argc -= 1;
while (argc) {
sLibrary *l;
l = lib_Find(lib, argv[argn]);
if (l) {
FILE *f;
if ((f = fopen(argv[argn], "wb"))) {
fwrite(l->pData,
sizeof(UBYTE),
l->nByteLength,
f);
fclose(f);
printf
("Extracted module '%s'\n",
argv[argn]);
} else {
fprintf(stderr,
"Unable to write module '%s': ", argv[argn]);
perror(NULL);
exit(1);
}
} else {
fprintf(stderr, "Module not found\n");
exit(1);
}
argn += 1;
argc -= 1;
}
lib_Free(lib);
} else if (strcmp(argv[argn], "list") == 0) {
argn += 1;
argc -= 1;
sLibrary *l;
l = lib;
while (l) {
printf("%10ld %s\n",
l->nByteLength,
l->tName);
l = l->pNext;
}
} else
usage();
} else
usage();
return (0);
}

View File

@@ -1,36 +0,0 @@
.Dd $Mdocdate$
.Dt RGBLIB 1
.Os RGBDS Manual
.Sh NAME
.Nm rgblib
.Nd Game Boy library manager
.Sh SYNOPSIS
.Nm rgblib
.Ar library
.Op add | delete | extract | list
.Ar module ...
.Sh DESCRIPTION
The
.Nm
program manages libraries for use with
.Xr rgblink 1 .
.Bl -tag -width Ds
.It add
Add the given modules to the library.
.It delete
Delete the given modules from the library.
.It extract
Extract the given modules from the library.
.It list
List all the modules in the library.
.El
.Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbasm 1 ,
.Xr rgbfix 1 ,
.Xr rgblink 1 ,
.Xr gbz80 7
.Sh HISTORY
.Nm
was originally released by Carsten S\(/orensen as part of the ASMotor package,
and was later packaged in RGBDS by Justin Lloyd.

View File

@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "extern/err.h"
#include "link/mylink.h"
#include "link/main.h"
#include "link/symbol.h"
@@ -63,7 +64,6 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
struct sFreeArea *pNewArea;
if ((pNewArea =
(struct sFreeArea *)
malloc(sizeof(struct sFreeArea)))
!= NULL) {
*pNewArea = *pArea;
@@ -77,9 +77,7 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
return (org);
} else {
fprintf(stderr,
"Out of memory!\n");
exit(1);
err(1, NULL);
}
}
}
@@ -310,9 +308,7 @@ AssignVRAMSections(void)
pSection->oAssigned = 1;
DOMAXVBANK(pSection->nBank);
} else {
fprintf(stderr,
"Unable to place VRAM section anywhere\n");
exit(1);
errx(1, "Unable to place VRAM section anywhere");
}
}
}
@@ -331,9 +327,7 @@ AssignSRAMSections(void)
pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank);
} else {
fprintf(stderr,
"Unable to place SRAM section anywhere\n");
exit(1);
errx(1, "Unable to place SRAM section anywhere");
}
}
}
@@ -352,9 +346,7 @@ AssignWRAMSections(void)
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
} else {
fprintf(stderr,
"Unable to place WRAMX section anywhere\n");
exit(1);
errx(1, "Unable to place WRAMX section anywhere");
}
}
}
@@ -373,9 +365,7 @@ AssignCodeSections(void)
pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank);
} else {
fprintf(stderr,
"Unable to place ROMX section anywhere\n");
exit(1);
errx(1, "Unable to place ROMX section anywhere");
}
}
}
@@ -397,8 +387,7 @@ AssignSections(void)
BankFree[i] = malloc(sizeof *BankFree[i]);
if (!BankFree[i]) {
fprintf(stderr, "Out of memory!\n");
exit(1);
err(1, NULL);
}
if (i == 0) {
@@ -472,10 +461,9 @@ AssignSections(void)
if (area_AllocAbs
(&BankFree[BANK_WRAM0], pSection->nOrg,
pSection->nByteSize) != pSection->nOrg) {
fprintf(stderr,
"Unable to load fixed WRAM0 section "
"at $%lX\n", pSection->nOrg);
exit(1);
errx(1,
"Unable to load fixed WRAM0 "
"section at $%lX", pSection->nOrg);
}
pSection->oAssigned = 1;
pSection->nBank = BANK_WRAM0;
@@ -484,10 +472,8 @@ AssignSections(void)
if (area_AllocAbs
(&BankFree[BANK_HRAM], pSection->nOrg,
pSection->nByteSize) != pSection->nOrg) {
fprintf(stderr, "Unable to load fixed "
"HRAM section at $%lX\n",
pSection->nOrg);
exit(1);
errx(1, "Unable to load fixed HRAM "
"section at $%lX", pSection->nOrg);
}
pSection->oAssigned = 1;
pSection->nBank = BANK_HRAM;
@@ -530,17 +516,15 @@ AssignSections(void)
pSection->nOrg,
pSection->nByteSize)
!= pSection->nOrg) {
fprintf(stderr,
"Unable to load fixed SRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
exit(1);
errx(1,
"Unable to load fixed SRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXVBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
fprintf(stderr,
"Unable to load fixed SRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
exit(1);
errx(1,
"Unable to load fixed SRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
}
@@ -583,17 +567,15 @@ AssignSections(void)
pSection->nOrg,
pSection->nByteSize)
!= pSection->nOrg) {
fprintf(stderr,
"Unable to load fixed WRAMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
exit(1);
errx(1,
"Unable to load fixed WRAMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXWBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
fprintf(stderr,
"Unable to load fixed WRAMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
exit(1);
errx(1,
"Unable to load fixed WRAMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
}
@@ -636,17 +618,15 @@ AssignSections(void)
pSection->nOrg,
pSection->nByteSize)
!= pSection->nOrg) {
fprintf(stderr,
"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
exit(1);
errx(1,
"Unable to load fixed VRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXVBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
fprintf(stderr,
"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
exit(1);
errx(1,
"Unable to load fixed VRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
}
@@ -655,10 +635,8 @@ AssignSections(void)
if (area_AllocAbs
(&BankFree[BANK_ROM0], pSection->nOrg,
pSection->nByteSize) != pSection->nOrg) {
fprintf(stderr, "Unable to load fixed "
"ROM0 section at $%lX\n",
pSection->nOrg);
exit(1);
errx(1, "Unable to load fixed ROM0 "
"section at $%lX", pSection->nOrg);
}
pSection->oAssigned = 1;
pSection->nBank = BANK_ROM0;
@@ -703,15 +681,15 @@ AssignSections(void)
pSection->
nByteSize) !=
pSection->nOrg) {
fprintf(stderr, "Unable to load fixed ROMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
exit(1);
errx(1,
"Unable to load fixed ROMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
fprintf(stderr, "Unable to load fixed ROMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
exit(1);
errx(1,
"Unable to load fixed ROMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
@@ -737,14 +715,13 @@ AssignSections(void)
if ((pSection->nOrg =
area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) {
fprintf(stderr, "Unable to load fixed ROMX section into bank $%02lX\n", pSection->nBank);
exit(1);
errx(1,
"Unable to load fixed ROMX section into bank $%02lX", pSection->nBank);
}
pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank);
} else {
fprintf(stderr, "Unable to load fixed ROMX section into bank $%02lX\n", pSection->nBank);
exit(1);
errx(1, "Unable to load fixed ROMX section into bank $%02lX", pSection->nBank);
}
} else if (pSection->oAssigned == 0
&& pSection->Type == SECT_SRAM
@@ -755,14 +732,12 @@ AssignSections(void)
if ((pSection->nOrg =
area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) {
fprintf(stderr, "Unable to load fixed SRAM section into bank $%02lX\n", pSection->nBank);
exit(1);
errx(1, "Unable to load fixed SRAM section into bank $%02lX", pSection->nBank);
}
pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank);
} else {
fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank);
exit(1);
errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank);
}
} else if (pSection->oAssigned == 0
&& pSection->Type == SECT_VRAM
@@ -773,14 +748,12 @@ AssignSections(void)
if ((pSection->nOrg =
area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) {
fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank);
exit(1);
errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank);
}
pSection->oAssigned = 1;
DOMAXVBANK(pSection->nBank);
} else {
fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank);
exit(1);
errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank);
}
} else if (pSection->oAssigned == 0
&& pSection->Type == SECT_WRAMX
@@ -791,14 +764,12 @@ AssignSections(void)
if ((pSection->nOrg =
area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) {
fprintf(stderr, "Unable to load fixed WRAMX section into bank $%02lX\n", pSection->nBank - BANK_WRAMX);
exit(1);
errx(1, "Unable to load fixed WRAMX section into bank $%02lX", pSection->nBank - BANK_WRAMX);
}
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
} else {
fprintf(stderr, "Unable to load fixed WRAMX section into bank $%02lX\n", pSection->nBank - BANK_WRAMX);
exit(1);
errx(1, "Unable to load fixed WRAMX section into bank $%02lX", pSection->nBank - BANK_WRAMX);
}
}
pSection = pSection->pNext;
@@ -820,8 +791,7 @@ AssignSections(void)
area_AllocAbsROMXAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
fprintf(stderr, "Unable to load fixed ROMX section at $%lX into any bank\n", pSection->nOrg);
exit(1);
errx(1, "Unable to load fixed ROMX section at $%lX into any bank", pSection->nOrg);
}
pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank);
@@ -834,8 +804,7 @@ AssignSections(void)
area_AllocAbsVRAMAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
fprintf(stderr, "Unable to load fixed VRAM section at $%lX into any bank\n", pSection->nOrg);
exit(1);
errx(1, "Unable to load fixed VRAM section at $%lX into any bank", pSection->nOrg);
}
pSection->oAssigned = 1;
DOMAXVBANK(pSection->nBank);
@@ -848,8 +817,7 @@ AssignSections(void)
area_AllocAbsSRAMAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
fprintf(stderr, "Unable to load fixed SRAM section at $%lX into any bank\n", pSection->nOrg);
exit(1);
errx(1, "Unable to load fixed SRAM section at $%lX into any bank", pSection->nOrg);
}
pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank);
@@ -862,8 +830,7 @@ AssignSections(void)
area_AllocAbsWRAMAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
fprintf(stderr, "Unable to load fixed WRAMX section at $%lX into any bank\n", pSection->nOrg);
exit(1);
errx(1, "Unable to load fixed WRAMX section at $%lX into any bank", pSection->nOrg);
}
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
@@ -885,8 +852,7 @@ AssignSections(void)
if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_WRAM0],
pSection->nByteSize)) == -1) {
fprintf(stderr, "WRAM0 section too large\n");
exit(1);
errx(1, "WRAM0 section too large");
}
pSection->nBank = BANK_WRAM0;
pSection->oAssigned = 1;
@@ -895,8 +861,7 @@ AssignSections(void)
if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_HRAM],
pSection->nByteSize)) == -1) {
fprintf(stderr, "HRAM section too large\n");
exit(1);
errx(1, "HRAM section too large");
}
pSection->nBank = BANK_HRAM;
pSection->oAssigned = 1;
@@ -911,8 +876,7 @@ AssignSections(void)
if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_ROM0],
pSection->nByteSize)) == -1) {
fprintf(stderr, "ROM0 section too large\n");
exit(1);
errx(1, "ROM0 section too large");
}
pSection->nBank = BANK_ROM0;
pSection->oAssigned = 1;
@@ -920,8 +884,7 @@ AssignSections(void)
case SECT_ROMX:
break;
default:
fprintf(stderr, "(INTERNAL) Unknown section type!\n");
exit(1);
errx(1, "(INTERNAL) Unknown section type!");
break;
}
}

View File

@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include "extern/err.h"
#include "link/types.h"
#include "link/mylink.h"
#include "link/main.h"
@@ -91,9 +92,8 @@ AddNeededModules(void)
}
if (options & OPT_SMART_C_LINK) {
if (!addmodulecontaining(smartlinkstartsymbol)) {
fprintf(stderr, "Can't find start symbol '%s'\n",
errx(1, "Can't find start symbol '%s'",
smartlinkstartsymbol);
exit(1);
} else
printf("Smart linking with symbol '%s'\n",
smartlinkstartsymbol);

View File

@@ -1,11 +1,10 @@
#include <getopt.h>
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "asmotor.h"
#include "extern/err.h"
#include "link/object.h"
#include "link/output.h"
#include "link/assign.h"
@@ -34,9 +33,7 @@ char smartlinkstartsymbol[256];
static void
usage(void)
{
printf("RGBLink v" LINK_VERSION " (part of ASMotor " ASMOTOR_VERSION
")\n\n");
printf("usage: rgblink [-t] [-l library] [-m mapfile] [-n symfile] [-o outfile]\n");
printf("usage: rgblink [-t] [-m mapfile] [-n symfile] [-o outfile]\n");
printf("\t [-s symbol] [-z pad_value] objectfile [...]\n");
exit(1);
@@ -58,9 +55,6 @@ main(int argc, char *argv[])
while ((ch = getopt(argc, argv, "l:m:n:o:p:s:t")) != -1) {
switch (ch) {
case 'l':
lib_Readfile(optarg);
break;
case 'm':
SetMapfileName(optarg);
break;
@@ -73,8 +67,7 @@ main(int argc, char *argv[])
case 'p':
fillchar = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
fprintf(stderr, "Invalid argument for option 'p'\n");
exit(1);
errx(1, "Invalid argument for option 'p'");
}
if (fillchar < 0 || fillchar > 0xFF) {
fprintf(stderr, "Argument for option 'p' must be between 0 and 0xFF");

View File

@@ -3,8 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include "asmotor.h"
#include "extern/err.h"
#include "link/main.h"
#include "link/mylink.h"
#include "link/assign.h"
@@ -20,9 +19,7 @@ SetMapfileName(char *name)
mf = fopen(name, "w");
if (mf == NULL) {
fprintf(stderr, "Cannot open mapfile '%s': ", name);
perror(NULL);
exit(1);
err(1, "Cannot open mapfile '%s'", name);
}
}
@@ -32,11 +29,10 @@ SetSymfileName(char *name)
sf = fopen(name, "w");
if (sf == NULL) {
fprintf(stderr, "Cannot open symfile '%s'\n", name);
exit(1);
err(1, "Cannot open symfile '%s'", name);
}
fprintf(sf, ";File generated by xLink v" LINK_VERSION "\n\n");
fprintf(sf, ";File generated by rgblink\n\n");
}
void

View File

@@ -8,6 +8,7 @@
#include <stdlib.h>
#include <string.h>
#include "extern/err.h"
#include "link/mylink.h"
#include "link/main.h"
@@ -80,8 +81,7 @@ AllocSection(void)
*ppSections = malloc(sizeof **ppSections);
if (!*ppSections) {
fprintf(stderr, "Out of memory!\n");
exit(1);
err(1, NULL);
}
(*ppSections)->tSymbols = tSymbols;
(*ppSections)->pNext = NULL;
@@ -102,15 +102,13 @@ obj_ReadSymbol(FILE * f)
pSym = malloc(sizeof *pSym);
if (!pSym) {
fprintf(stderr, "Out of memory!\n");
exit(1);
err(1, NULL);
}
readasciiz(s, f);
pSym->pzName = malloc(strlen(s) + 1);
if (!pSym->pzName) {
fprintf(stderr, "Out of memory!\n");
exit(1);
err(1, NULL);
}
strcpy(pSym->pzName, s);
@@ -150,7 +148,7 @@ obj_ReadRGB0Section(FILE * f)
if (pSection->nByteSize) {
pSection->pData = malloc(pSection->nByteSize);
if (!pSection->pData) {
fprintf(stderr, "Out of memory!\n");
err(1, NULL);
}
SLONG nNumberOfPatches;
@@ -169,7 +167,7 @@ obj_ReadRGB0Section(FILE * f)
while (nNumberOfPatches--) {
pPatch = malloc(sizeof *pPatch);
if (!pPatch) {
fprintf(stderr, "Out of memory!\n");
err(1, NULL);
}
*ppPatch = pPatch;
@@ -177,7 +175,7 @@ obj_ReadRGB0Section(FILE * f)
pPatch->pzFilename = malloc(strlen(s) + 1);
if (!pPatch->pzFilename) {
fprintf(stderr, "Out of memory!\n");
err(1, NULL);
}
strcpy(pPatch->pzFilename, s);
@@ -193,8 +191,7 @@ obj_ReadRGB0Section(FILE * f)
if ((pPatch->nRPNSize = readlong(f)) > 0) {
pPatch->pRPN = malloc(pPatch->nRPNSize);
if (!pPatch->pRPN) {
fprintf(stderr, "Out of memory!\n");
exit(1);
err(1, NULL);
}
fread(pPatch->pRPN, sizeof(UBYTE),
@@ -228,8 +225,7 @@ obj_ReadRGB0(FILE * pObjfile)
if (nNumberOfSymbols) {
tSymbols = malloc(nNumberOfSymbols * sizeof(struct sSymbol *));
if (!tSymbols) {
fprintf(stderr, "Out of memory!\n");
exit(1);
err(1, NULL);
}
for (i = 0; i < nNumberOfSymbols; i += 1)
@@ -305,8 +301,7 @@ obj_ReadRGB1Section(FILE * f)
if (pSection->nByteSize) {
pSection->pData = malloc(pSection->nByteSize);
if (!pSection->pData) {
fprintf(stderr, "Out of memory!\n");
exit(1);
err(1, NULL);
}
SLONG nNumberOfPatches;
@@ -325,14 +320,14 @@ obj_ReadRGB1Section(FILE * f)
while (nNumberOfPatches--) {
pPatch = malloc(sizeof *pPatch);
if (!pPatch) {
fprintf(stderr, "Out of memory!\n");
err(1, NULL);
}
*ppPatch = pPatch;
readasciiz(s, f);
pPatch->pzFilename = malloc(strlen(s) + 1);
if (!pPatch->pzFilename) {
fprintf(stderr, "Out of memory!\n");
err(1, NULL);
}
strcpy(pPatch->pzFilename, s);
@@ -342,7 +337,7 @@ obj_ReadRGB1Section(FILE * f)
if ((pPatch->nRPNSize = readlong(f)) > 0) {
pPatch->pRPN = malloc(pPatch->nRPNSize);
if (!pPatch->pRPN) {
fprintf(stderr, "Out of memory!\n");
err(1, NULL);
}
fread(pPatch->pRPN, sizeof(UBYTE),
@@ -376,7 +371,7 @@ obj_ReadRGB1(FILE * pObjfile)
if (nNumberOfSymbols) {
tSymbols = malloc(nNumberOfSymbols * sizeof *tSymbols);
if (!tSymbols) {
fprintf(stderr, "Out of memory!\n");
err(1, NULL);
}
for (i = 0; i < nNumberOfSymbols; i += 1)
@@ -440,14 +435,10 @@ obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile)
obj_ReadRGB1(pObjfile);
break;
default:
fprintf(stderr, "'%s' is an unsupported version",
tzObjectfile);
exit(1);
break;
errx(1, "'%s' is an unsupported version", tzObjectfile);
}
} else {
fprintf(stderr, "'%s' is not a valid object\n", tzObjectfile);
exit(1);
errx(1, "'%s' is not a valid object", tzObjectfile);
}
}
@@ -463,10 +454,7 @@ obj_Readfile(char *tzObjectfile)
pObjfile = fopen(tzObjectfile, "rb");
if (pObjfile == NULL) {
fprintf(stderr, "Unable to open object '%s': ",
tzObjectfile);
perror(NULL);
exit(1);
err(1, "Unable to open object '%s'", tzObjectfile);
}
obj_ReadOpenFile(pObjfile, tzObjectfile);
fclose(pObjfile);
@@ -506,34 +494,3 @@ lib_ReadXLB0(FILE * f)
obj_ReadOpenFile(f, name);
}
}
void
lib_Readfile(char *tzLibfile)
{
FILE *pObjfile;
oReadLib = 1;
pObjfile = fopen(tzLibfile, "rb");
if (pObjfile == NULL) {
fprintf(stderr, "Unable to open object '%s': ", tzLibfile);
perror(NULL);
exit(1);
}
if (!pObjfile) {
fprintf(stderr, "Unable to open '%s'\n", tzLibfile);
exit(1);
}
char tzHeader[5];
fread(tzHeader, sizeof(char), 4, pObjfile);
tzHeader[4] = 0;
if (strcmp(tzHeader, "XLB0") == 0)
lib_ReadXLB0(pObjfile);
else {
fprintf(stderr, "'%s' is an invalid library\n",
tzLibfile);
exit(1);
}
fclose(pObjfile);
}

View File

@@ -7,8 +7,7 @@
#include "link/main.h"
#include "link/assign.h"
char tzOutname[_MAX_PATH];
BBOOL oOutput = 0;
char *tzOutname;
void
writehome(FILE * f)
@@ -71,8 +70,7 @@ writebank(FILE * f, SLONG bank)
void
out_Setname(char *tzOutputfile)
{
strcpy(tzOutname, tzOutputfile);
oOutput = 1;
tzOutname = tzOutputfile;
}
void

View File

@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include "extern/err.h"
#include "link/mylink.h"
#include "link/symbol.h"
#include "link/main.h"
@@ -46,8 +47,7 @@ getsymvalue(SLONG symid)
default:
break;
}
fprintf(stderr, "*INTERNAL* UNKNOWN SYMBOL TYPE\n");
exit(1);
errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE");
}
SLONG
@@ -64,8 +64,7 @@ getsymbank(SLONG symid)
default:
break;
}
fprintf(stderr, "*INTERNAL* UNKNOWN SYMBOL TYPE\n");
exit(1);
errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE");
}
SLONG
@@ -159,20 +158,18 @@ calcrpn(struct sPatch * pPatch)
t = rpnpop();
rpnpush(t & 0xFF);
if (t < 0 || (t > 0xFF && t < 0xFF00) || t > 0xFFFF) {
fprintf(stderr,
"%s(%ld) : Value must be in the HRAM area\n",
errx(1,
"%s(%ld) : Value must be in the HRAM area",
pPatch->pzFilename, pPatch->nLineNo);
exit(1);
}
break;
case RPN_PCEZP:
t = rpnpop();
rpnpush(t & 0xFF);
if (t < 0x2000 || t > 0x20FF) {
fprintf(stderr,
"%s(%ld) : Value must be in the ZP area\n",
errx(1,
"%s(%ld) : Value must be in the ZP area",
pPatch->pzFilename, pPatch->nLineNo);
exit(1);
}
break;
case RPN_CONST:
@@ -217,11 +214,10 @@ calcrpn(struct sPatch * pPatch)
high |= (*rpn++) << 24;
t = rpnpop();
if (t < low || t > high) {
fprintf(stderr,
"%s(%ld) : Value must be in the range [%ld;%ld]\n",
errx(1,
"%s(%ld) : Value must be in the range [%ld;%ld]",
pPatch->pzFilename,
pPatch->nLineNo, low, high);
exit(1);
}
rpnpush(t);
size -= 8;
@@ -255,11 +251,10 @@ Patch(void)
pSect->pData[pPatch->nOffset] =
(UBYTE) t;
} else {
fprintf(stderr,
"%s(%ld) : Value must be 8-bit\n",
errx(1,
"%s(%ld) : Value must be 8-bit",
pPatch->pzFilename,
pPatch->nLineNo);
exit(1);
}
break;
case PATCH_WORD_L:
@@ -280,11 +275,10 @@ Patch(void)
1] = t & 0xFF;
}
} else {
fprintf(stderr,
"%s(%ld) : Value must be 16-bit\n",
errx(1,
"%s(%ld) : Value must be 16-bit",
pPatch->pzFilename,
pPatch->nLineNo);
exit(1);
}
break;
case PATCH_LONG_L:

View File

@@ -29,12 +29,6 @@ option to override this.
.Pp
The arguments are as follows:
.Bl -tag -width Ds
.It Fl l Ar library
Include a referenced library module created with
.Xr rgblib 1 .
Note that specified libraries will be included only if needed\(emthat is, if
a SECTION from a library is referenced by an object file.
Only the relevant SECTION will be included, rather than the entire module.
.It Fl m Ar mapfile
Write a mapfile to the given filename.
.It Fl n Ar symfile
@@ -70,7 +64,6 @@ to fix these so that the program will actually run in a Game Boy:
.Xr rgbds 7 ,
.Xr rgbasm 1 ,
.Xr rgbfix 1 ,
.Xr rgblib 1 ,
.Xr gbz80 7
.Sh HISTORY
.Nm

View File

@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include "extern/err.h"
#include "link/main.h"
#include "link/patch.h"
#include "link/types.h"
@@ -53,8 +54,7 @@ sym_GetValue(char *tzName)
}
}
fprintf(stderr, "Unknown symbol '%s'\n", tzName);
exit(1);
errx(1, "Unknown symbol '%s'", tzName);
}
}
@@ -72,8 +72,7 @@ sym_GetBank(char *tzName)
}
}
fprintf(stderr, "Unknown symbol '%s'\n", tzName);
exit(1);
errx(1, "Unknown symbol '%s'", tzName);
}
void
@@ -93,10 +92,7 @@ sym_CreateSymbol(char *tzName, SLONG nValue, SBYTE nBank)
if (nBank == -1)
return;
fprintf(stderr,
"Symbol '%s' defined more than once\n",
tzName);
exit(1);
errx(1, "Symbol '%s' defined more than once", tzName);
}
}

View File

@@ -13,7 +13,6 @@ To get a working ROM image from a single assembly source file:
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgbfix 1 ,
.Xr rgblib 1 ,
.Xr rgblink 1 ,
.Xr gbz80 7
.Sh HISTORY