mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Conflicts: include/lib/types.h src/asm/symbol.c
This commit is contained in:
10
LICENSE
10
LICENSE
@@ -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.
|
||||
|
||||
106
Makefile
106
Makefile
@@ -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
|
||||
@@ -13,7 +15,6 @@ yacc_pre := \
|
||||
src/asm/gameboy/yaccprt4.y
|
||||
|
||||
rgbasm_obj := \
|
||||
src/asm/alloca.o \
|
||||
src/asm/asmy.o \
|
||||
src/asm/charmap.o \
|
||||
src/asm/fstack.o \
|
||||
@@ -24,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 \
|
||||
@@ -38,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.
|
||||
@@ -100,19 +92,23 @@ 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=\\\"\\\" ${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
1
README
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
47
doc/lib.htm
47
doc/lib.htm
@@ -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>
|
||||
@@ -17,8 +17,6 @@
|
||||
|
||||
#include "localasm.h"
|
||||
|
||||
#include "asmotor.h"
|
||||
|
||||
extern SLONG nLineNo;
|
||||
extern ULONG nTotalLines;
|
||||
extern ULONG nPC;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
#include "asm/types.h"
|
||||
|
||||
#define LEXHASHSIZE 512
|
||||
#define LEXHASHSIZE (1 << 11)
|
||||
#define MAXSTRLEN 255
|
||||
|
||||
struct sLexInitString {
|
||||
char *tzName;
|
||||
@@ -18,7 +19,9 @@ struct sLexFloat {
|
||||
};
|
||||
|
||||
struct yy_buffer_state {
|
||||
char *pBufferStart;
|
||||
char *pBufferRealStart; // actual starting address
|
||||
char *pBufferStart; // address where the data is initially written
|
||||
// after the "safety margin"
|
||||
char *pBuffer;
|
||||
ULONG nBufferSize;
|
||||
ULONG oAtLineStart;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "asm/types.h"
|
||||
|
||||
#define HASHSIZE 73
|
||||
#define HASHSIZE (1 << 16)
|
||||
#define MAXSYMLEN 256
|
||||
|
||||
struct sSymbol {
|
||||
@@ -35,6 +35,7 @@ struct sSymbol {
|
||||
#define SYMF_CONST 0x200 /* symbol has a constant value, will
|
||||
* not be changed during linking */
|
||||
|
||||
ULONG calchash(char *s);
|
||||
void sym_PrepPass1(void);
|
||||
void sym_PrepPass2(void);
|
||||
void sym_AddLocalReloc(char *tzSym);
|
||||
|
||||
@@ -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
63
include/extern/err.h
vendored
Normal 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
13
include/extern/strl.h
vendored
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef ASMOTOR_LIB_TYPES_H
|
||||
#define ASMOTOR_LIB_TYPES_H
|
||||
|
||||
#ifndef _MAX_PATH
|
||||
#define _MAX_PATH 512
|
||||
#endif
|
||||
|
||||
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
|
||||
@@ -2,6 +2,5 @@
|
||||
#define ASMOTOR_LINK_OBJECT_H
|
||||
|
||||
extern void obj_Readfile(char *tzObjectfile);
|
||||
extern void lib_Readfile(char *tzLibfile);
|
||||
|
||||
#endif
|
||||
|
||||
466
src/asm/alloca.c
466
src/asm/alloca.c
@@ -1,466 +0,0 @@
|
||||
/* alloca.c -- allocate automatically reclaimed memory
|
||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
This implementation of the PWB library alloca function,
|
||||
which is used to allocate space off the run-time stack so
|
||||
that it is automatically reclaimed upon procedure exit,
|
||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||
|
||||
There are some preprocessor constants that can
|
||||
be defined when compiling for your specific system, for
|
||||
improved efficiency; however, the defaults should be okay.
|
||||
|
||||
The general concept of this implementation is to keep
|
||||
track of all alloca-allocated blocks, and reclaim any
|
||||
that are found to be deeper in the stack than the current
|
||||
invocation. This heuristic does not reclaim storage as
|
||||
soon as it becomes invalid, but it will do so eventually.
|
||||
|
||||
As a special case, alloca(0) reclaims storage without
|
||||
allocating any. It is a good idea to use alloca(0) in
|
||||
your main control loop, etc. to force garbage collection. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#include "blockinput.h"
|
||||
#endif
|
||||
|
||||
/* If compiling with GCC 2, this file's not needed. */
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
|
||||
/* If someone has defined alloca as a macro,
|
||||
there must be some other way alloca is supposed to work. */
|
||||
#ifndef alloca
|
||||
|
||||
#ifdef emacs
|
||||
#ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
-- this is for usg, in which emacs must undefine static
|
||||
in order to make unexec workable
|
||||
*/
|
||||
#ifndef STACK_DIRECTION
|
||||
you lose-- must know STACK_DIRECTION at compile - time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
/* If your stack is a linked list of frames, you have to
|
||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
long i00afunc();
|
||||
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||
#else
|
||||
#define ADDRESS_FUNCTION(arg) &(arg)
|
||||
#endif
|
||||
#if __STDC__
|
||||
typedef void *pointer;
|
||||
#else
|
||||
typedef char *pointer;
|
||||
#endif
|
||||
|
||||
#define NULL 0
|
||||
|
||||
/* Different portions of Emacs need to call different versions of
|
||||
malloc. The Emacs executable needs alloca to call xmalloc, because
|
||||
ordinary malloc isn't protected from input signals. On the other
|
||||
hand, the utilities in lib-src need alloca to call malloc; some of
|
||||
them are very simple, and don't have an xmalloc routine.
|
||||
|
||||
Non-Emacs programs expect this to call use xmalloc.
|
||||
|
||||
Callers below should use malloc. */
|
||||
|
||||
/* Carsten Sorensen 09/09/97
|
||||
* Commented out the following, I want malloc!
|
||||
#ifndef emacs
|
||||
#define malloc xmalloc
|
||||
#endif
|
||||
extern pointer malloc ();
|
||||
And added the following line:
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
deduced at run-time.
|
||||
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
|
||||
#ifndef STACK_DIRECTION
|
||||
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
#endif
|
||||
|
||||
#if STACK_DIRECTION != 0
|
||||
|
||||
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||
|
||||
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
#define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction()
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once
|
||||
* known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL) { /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION(dummy);
|
||||
|
||||
find_stack_direction(); /* Recurse once. */
|
||||
} else {
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION(dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
}
|
||||
#endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/* An "alloca header" is used to:
|
||||
(a) chain together all alloca'ed blocks;
|
||||
(b) keep track of stack depth.
|
||||
|
||||
It is very important that sizeof(header) agree with malloc
|
||||
alignment chunk size. The following default should work okay. */
|
||||
|
||||
#ifndef ALIGN_SIZE
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
|
||||
typedef union hdr {
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct {
|
||||
union hdr *next;/* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
|
||||
/* Return a pointer to at least SIZE bytes of storage,
|
||||
which will be automatically reclaimed upon exit from
|
||||
the procedure that called alloca. Originally, this space
|
||||
was supposed to be taken from the current stack frame of the
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32. */
|
||||
|
||||
pointer
|
||||
alloca(size)
|
||||
unsigned size;
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION(probe);
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction();
|
||||
#endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca'd storage that was allocated
|
||||
* from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
#ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
#endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth)) {
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free((pointer) hp); /* Collect garbage. */
|
||||
|
||||
hp = np; /* -> next header. */
|
||||
} else
|
||||
break; /* Rest are not deeper. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
#ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = malloc(sizeof(header) + size);
|
||||
/* Address of header. */
|
||||
|
||||
((header *) new)->h.next = last_alloca_header;
|
||||
((header *) new)->h.deep = depth;
|
||||
|
||||
last_alloca_header = (header *) new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (pointer) ((char *) new + sizeof(header));
|
||||
}
|
||||
}
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef CRAY_STACK
|
||||
#define CRAY_STACK
|
||||
#ifndef CRAY2
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header {
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
/* The stack segment linkage control information occurs at
|
||||
the high-address end of a stack segment. (The stack
|
||||
grows from low addresses to high addresses.) The initial
|
||||
part of the stack segment linkage control information is
|
||||
0200 (octal) words. This provides for register storage
|
||||
for the routine which overflows the stack. */
|
||||
|
||||
struct stack_segment_linkage {
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
* segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
* microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
};
|
||||
#else /* CRAY2 */
|
||||
/* The following structure defines the vector of words
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat {
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would be
|
||||
* required to satisfy the maximum stack
|
||||
* demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This number is
|
||||
* actually corrupted by STKSTAT to include
|
||||
* the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
/* The following structure describes the data structure which trails
|
||||
any stack segment. I think that the description in 'asdef' is
|
||||
out of date. I only describe the parts that I am sure about. */
|
||||
|
||||
struct stk_trailer {
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include this
|
||||
* trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
* segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
};
|
||||
#endif /* CRAY2 */
|
||||
#endif /* not CRAY_STACK */
|
||||
|
||||
#ifdef CRAY2
|
||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||
I doubt that "lint" will like this much. */
|
||||
|
||||
static long
|
||||
i00afunc(long *address)
|
||||
{
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
|
||||
/* We want to iterate through all of the segments. The first step is
|
||||
* to get the stack status structure. We could do this more quickly
|
||||
* and more directly, perhaps, by referencing the $LM00 common block,
|
||||
* but I know that this works. */
|
||||
|
||||
STKSTAT(&status);
|
||||
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size - 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is a fatal
|
||||
* error if "trailer" is null. */
|
||||
|
||||
if (trailer == 0)
|
||||
abort();
|
||||
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
|
||||
while (trailer != 0) {
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes of
|
||||
* all predecessor segments. */
|
||||
|
||||
result = address - block;
|
||||
|
||||
if (trailer == 0) {
|
||||
return result;
|
||||
}
|
||||
do {
|
||||
if (trailer->this_size <= 0)
|
||||
abort();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
|
||||
/* We are done. Note that if you present a bogus address (one not in
|
||||
* any segment), you will get a different number back, formed from
|
||||
* subtracting the address of the first block. This is probably not
|
||||
* what you want. */
|
||||
|
||||
return (result);
|
||||
}
|
||||
#else /* not CRAY2 */
|
||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||
Determine the number of the cell within the stack,
|
||||
given the address of the cell. The purpose of this
|
||||
routine is to linearize, in some sense, stack addresses
|
||||
for alloca. */
|
||||
|
||||
static long
|
||||
i00afunc(long address)
|
||||
{
|
||||
long stkl = 0;
|
||||
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
|
||||
struct stack_segment_linkage *ssptr;
|
||||
|
||||
/* Register B67 contains the address of the end of the current stack
|
||||
* segment. If you (as a subprogram) store your registers on the
|
||||
* stack and find that you are past the contents of B67, you have
|
||||
* overflowed the segment.
|
||||
*
|
||||
* B67 also points to the stack segment linkage control area, which is
|
||||
* what we are really interested in. */
|
||||
|
||||
stkl = CRAY_STACKSEG_END();
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
|
||||
/* If one subtracts 'size' from the end of the segment, one has the
|
||||
* address of the first word of the segment.
|
||||
*
|
||||
* If this is not the first segment, 'pseg' will be nonzero. */
|
||||
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
|
||||
this_segment = stkl - size;
|
||||
|
||||
/* It is possible that calling this routine itself caused a stack
|
||||
* overflow. Discard stack segments which do not contain the target
|
||||
* address. */
|
||||
|
||||
while (!(this_segment <= address && address <= stkl)) {
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf(stderr, "%011o %011o %011o\n", this_segment, address,
|
||||
stkl);
|
||||
#endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
|
||||
result = address - this_segment;
|
||||
|
||||
/* If you subtract pseg from the current end of the stack, you get the
|
||||
* address of the previous stack segment's end. This seems a little
|
||||
* convoluted to me, but I'll bet you save a cycle somewhere. */
|
||||
|
||||
while (pseg != 0) {
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf(stderr, "%011o %011o\n", pseg, size);
|
||||
#endif
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
#endif /* not CRAY2 */
|
||||
#endif /* CRAY */
|
||||
|
||||
#endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
||||
108
src/asm/fstack.c
108
src/asm/fstack.c
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -290,6 +290,8 @@ z80_ld : z80_ld_mem
|
||||
|
||||
z80_ld_hl : T_Z80_LD T_MODE_HL comma '[' T_MODE_SP const_8bit ']'
|
||||
{ out_AbsByte(0xF8); out_RelByte(&$6); }
|
||||
| T_Z80_LD T_MODE_HL comma T_MODE_SP const_8bit
|
||||
{ out_AbsByte(0xF8); out_RelByte(&$5); }
|
||||
| T_Z80_LD T_MODE_HL comma const_16bit
|
||||
{ out_AbsByte(0x01|(REG_HL<<4)); out_RelWord(&$4); }
|
||||
;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -388,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, '@', '@');
|
||||
|
||||
968
src/asm/lexer.c
968
src/asm/lexer.c
File diff suppressed because it is too large
Load Diff
153
src/asm/main.c
153
src/asm/main.c
@@ -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;
|
||||
}
|
||||
|
||||
167
src/asm/output.c
167
src/asm/output.c
@@ -18,6 +18,7 @@
|
||||
#include "asm/main.h"
|
||||
#include "asm/rpn.h"
|
||||
#include "asm/fstack.h"
|
||||
#include "extern/err.h"
|
||||
|
||||
#define SECTIONCHUNK 0x4000
|
||||
|
||||
@@ -44,6 +45,7 @@ struct PatchSymbol {
|
||||
ULONG ID;
|
||||
struct sSymbol *pSymbol;
|
||||
struct PatchSymbol *pNext;
|
||||
struct PatchSymbol *pBucketNext; // next symbol in hash table bucket
|
||||
};
|
||||
|
||||
struct SectionStackEntry {
|
||||
@@ -57,9 +59,11 @@ struct SectionStackEntry {
|
||||
*
|
||||
*/
|
||||
|
||||
struct PatchSymbol *tHashedPatchSymbols[HASHSIZE];
|
||||
struct Section *pSectionList = NULL, *pCurrentSection = NULL;
|
||||
struct PatchSymbol *pPatchSymbols = NULL;
|
||||
char tzObjectname[_MAX_PATH];
|
||||
struct PatchSymbol **ppPatchSymbolsTail = &pPatchSymbols;
|
||||
char *tzObjectname;
|
||||
struct SectionStackEntry *pSectionStack = NULL;
|
||||
|
||||
/*
|
||||
@@ -74,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;
|
||||
@@ -328,30 +330,30 @@ ULONG
|
||||
addsymbol(struct sSymbol * pSym)
|
||||
{
|
||||
struct PatchSymbol *pPSym, **ppPSym;
|
||||
ULONG ID = 0;
|
||||
static ULONG nextID = 0;
|
||||
ULONG hash;
|
||||
|
||||
pPSym = pPatchSymbols;
|
||||
ppPSym = &(pPatchSymbols);
|
||||
hash = calchash(pSym->tzName);
|
||||
ppPSym = &(tHashedPatchSymbols[hash]);
|
||||
|
||||
while (pPSym) {
|
||||
if (pSym == pPSym->pSymbol)
|
||||
return (pPSym->ID);
|
||||
ppPSym = &(pPSym->pNext);
|
||||
pPSym = pPSym->pNext;
|
||||
ID += 1;
|
||||
while ((*ppPSym) != NULL) {
|
||||
if (pSym == (*ppPSym)->pSymbol)
|
||||
return (*ppPSym)->ID;
|
||||
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;
|
||||
pPSym->ID = ID;
|
||||
return (ID);
|
||||
pPSym->ID = nextID++;
|
||||
} else
|
||||
fatalerror("No memory for patchsymbol");
|
||||
|
||||
return ((ULONG) - 1);
|
||||
*ppPatchSymbolsTail = pPSym;
|
||||
ppPatchSymbolsTail = &(pPSym->pNext);
|
||||
|
||||
return pPSym->ID;
|
||||
}
|
||||
/*
|
||||
* RGBAsm - OUTPUT.C - Outputs an objectfile
|
||||
@@ -386,24 +388,17 @@ addexports(void)
|
||||
struct Patch *
|
||||
allocpatch(void)
|
||||
{
|
||||
struct Patch *pPatch, **ppPatch;
|
||||
struct Patch *pPatch;
|
||||
|
||||
pPatch = pCurrentSection->pPatches;
|
||||
ppPatch = &(pCurrentSection->pPatches);
|
||||
|
||||
while (pPatch) {
|
||||
ppPatch = &(pPatch->pNext);
|
||||
pPatch = pPatch->pNext;
|
||||
}
|
||||
|
||||
if ((*ppPatch = pPatch =
|
||||
(struct Patch *) malloc(sizeof(struct Patch))) != NULL) {
|
||||
pPatch->pNext = NULL;
|
||||
if ((pPatch = malloc(sizeof(struct Patch))) != NULL) {
|
||||
pPatch->pNext = pCurrentSection->pPatches;
|
||||
pPatch->nRPNSize = 0;
|
||||
pPatch->pRPN = NULL;
|
||||
} else
|
||||
fatalerror("No memory for patch");
|
||||
|
||||
pCurrentSection->pPatches = pPatch;
|
||||
|
||||
return (pPatch);
|
||||
}
|
||||
/*
|
||||
@@ -473,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;
|
||||
}
|
||||
@@ -505,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
|
||||
@@ -524,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
|
||||
@@ -594,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);
|
||||
}
|
||||
@@ -632,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;
|
||||
@@ -647,8 +641,7 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org,
|
||||
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");
|
||||
@@ -918,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
|
||||
@@ -955,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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@@ -27,7 +28,6 @@ struct sSymbol *tHashedSymbols[HASHSIZE];
|
||||
struct sSymbol *pScope = NULL;
|
||||
struct sSymbol *pPCSymbol = NULL;
|
||||
struct sSymbol *p_NARGSymbol = NULL;
|
||||
struct sSymbol *p__LINE__Symbol = NULL;
|
||||
char *currentmacroargs[MAXMACROARGS + 1];
|
||||
char *newmacroargs[MAXMACROARGS + 1];
|
||||
char SavedTIME[256];
|
||||
@@ -45,12 +45,6 @@ Callback_NARG(struct sSymbol * sym)
|
||||
return (i);
|
||||
}
|
||||
|
||||
SLONG
|
||||
Callback__LINE__(struct sSymbol * sym)
|
||||
{
|
||||
sym = sym;
|
||||
return (nLineNo);
|
||||
}
|
||||
/*
|
||||
* RGBAsm - SYMBOL.C - Symboltable stuff
|
||||
*
|
||||
@@ -76,10 +70,10 @@ getvaluefield(struct sSymbol * sym)
|
||||
ULONG
|
||||
calchash(char *s)
|
||||
{
|
||||
ULONG hash = 0;
|
||||
ULONG hash = 5381;
|
||||
|
||||
while (*s != 0)
|
||||
hash += (*s++);
|
||||
hash = (hash * 33) ^ (*s++);
|
||||
|
||||
return (hash % HASHSIZE);
|
||||
}
|
||||
@@ -102,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;
|
||||
@@ -440,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]);
|
||||
}
|
||||
|
||||
@@ -578,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");
|
||||
@@ -849,6 +843,10 @@ sym_PrepPass2(void)
|
||||
sym_AddString("__TIME__", SavedTIME);
|
||||
sym_AddString("__DATE__", SavedDATE);
|
||||
sym_AddSet("_RS", 0);
|
||||
|
||||
sym_AddEqu("_NARG", 0);
|
||||
p_NARGSymbol = findsymbol("_NARG", NULL);
|
||||
p_NARGSymbol->Callback = Callback_NARG;
|
||||
}
|
||||
/*
|
||||
* RGBAsm - SYMBOL.C - Symboltable stuff
|
||||
@@ -876,11 +874,7 @@ sym_Init(void)
|
||||
sym_AddEqu("_NARG", 0);
|
||||
p_NARGSymbol = findsymbol("_NARG", NULL);
|
||||
p_NARGSymbol->Callback = Callback_NARG;
|
||||
sym_AddEqu("__LINE__", 0);
|
||||
p__LINE__Symbol = findsymbol("__LINE__", NULL);
|
||||
p__LINE__Symbol->Callback = Callback__LINE__;
|
||||
|
||||
sym_AddEqu("__ASM__", (SLONG) (atof(ASM_VERSION) * 65536));
|
||||
sym_AddSet("_RS", 0);
|
||||
|
||||
if (time(&tod) != -1) {
|
||||
|
||||
@@ -24,14 +24,38 @@ extern bool haltnop;
|
||||
char *tzNewMacro;
|
||||
ULONG ulNewMacroSize;
|
||||
|
||||
ULONG symvaluetostring( char *dest, char *sym )
|
||||
size_t symvaluetostring(char *dest, size_t maxLength, char *sym)
|
||||
{
|
||||
if( sym_isString(sym) )
|
||||
strcpy( dest, sym_GetStringValue(sym) );
|
||||
else
|
||||
sprintf( dest, "$%lX", sym_GetConstantValue(sym) );
|
||||
size_t length;
|
||||
|
||||
return( strlen(dest) );
|
||||
if (sym_isString(sym)) {
|
||||
char *src = sym_GetStringValue(sym);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; src[i] != 0; i++) {
|
||||
if (i >= maxLength) {
|
||||
fatalerror("Symbol value too long to fit buffer");
|
||||
}
|
||||
dest[i] = src[i];
|
||||
}
|
||||
|
||||
length = i;
|
||||
} else {
|
||||
ULONG value = sym_GetConstantValue(sym);
|
||||
int fullLength = snprintf(dest, maxLength + 1, "$%lX", value);
|
||||
|
||||
if (fullLength < 0) {
|
||||
fatalerror("snprintf encoding error");
|
||||
} else {
|
||||
length = (size_t)fullLength;
|
||||
|
||||
if (length > maxLength) {
|
||||
fatalerror("Symbol value too long to fit buffer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
ULONG str2int( char *s )
|
||||
@@ -124,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;
|
||||
@@ -134,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 );
|
||||
@@ -353,8 +375,8 @@ void if_skip_to_endc( void )
|
||||
|
||||
%union
|
||||
{
|
||||
char tzSym[MAXSYMLEN+1];
|
||||
char tzString[256];
|
||||
char tzSym[MAXSYMLEN + 1];
|
||||
char tzString[MAXSTRLEN + 1];
|
||||
struct Expression sVal;
|
||||
SLONG nConstValue;
|
||||
}
|
||||
|
||||
@@ -266,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);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
92
src/extern/err.c
vendored
Normal file
92
src/extern/err.c
vendored
Normal 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);
|
||||
}
|
||||
|
||||
void rgbds_verr(int status, const char *fmt, va_list ap)
|
||||
{
|
||||
vwarn(fmt, ap);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void rgbds_err(int status, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verr(status, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
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
55
src/extern/strlcat.c
vendored
Normal 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
51
src/extern/strlcpy.c
vendored
Normal 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 */
|
||||
}
|
||||
@@ -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);
|
||||
@@ -380,6 +352,7 @@ main(int argc, char *argv[])
|
||||
|
||||
/* We will pad the ROM to match the size given in the header. */
|
||||
int romsize, newsize, headbyte;
|
||||
uint8_t *buf;
|
||||
fseek(rom, 0, SEEK_END);
|
||||
romsize = ftell(rom);
|
||||
newsize = 0x8000;
|
||||
@@ -390,14 +363,17 @@ main(int argc, char *argv[])
|
||||
headbyte++;
|
||||
}
|
||||
|
||||
while (newsize != ftell(rom)) /* ROM needs resizing */
|
||||
fputc(padvalue, rom);
|
||||
|
||||
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);
|
||||
fwrite(buf, 1, newsize - romsize, rom);
|
||||
|
||||
fseek(rom, 0x148, SEEK_SET);
|
||||
fputc(headbyte, rom);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
if (setramsize) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
120
src/lib/main.c
120
src/lib/main.c
@@ -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);
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
#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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user