Compare commits

...

70 Commits

Author SHA1 Message Date
Anthony J. Bentley
6c10ca62ad Don't silently truncate banks greater than 255 to 8 bits. 2015-07-26 02:08:39 -06:00
Christophe Staïesse
49809f6caf Fix segfault in createpatch() when symbol is an inexistant local label or bank
Fixed as follows: if the symbol doesn't exist, don't add it to the relocation
table. The functions calling createpatch will nevertheless increment PC
correctly.

Test case:

SECTION "CODE", CODE
glob:
        jp .loc

; from test/asm/banknoexist.asm:
SECTION "sec", ROM0
        db BANK(noexist)

See also issue #68
2015-07-26 01:57:30 -06:00
Christophe Staïesse
81675bc4c7 Fix yacc conflict (asmfile/lastline/lines/line rules) 2015-07-26 01:50:56 -06:00
YamaArashi
37b615f070 Fix bug with macro args in symbol names
If a macro arg came in the middle of a symbol or at the end, e.g. "SYM\1", it would say that the symbol was not defined. This was because it wasn't looking up the macro arg's value correctly.
2015-07-25 21:20:44 -07:00
stag019
6438ae2591 Remove __progname; add progname set to argv[0] in each main(). 2015-03-09 13:57:04 -04:00
Anthony J. Bentley
33ae6d8ca3 Use long for file offsets. 2015-03-07 14:21:57 -07:00
stag019
ebc9a4b786 Merge include/link/types.h and include/asm/types.h into include/types.h 2015-03-07 16:04:07 -05:00
stag019
e195076793 Only block comments in headers 2015-03-07 15:50:09 -05:00
stag019
b14beeff10 Consistency in #includes 2015-03-07 15:49:17 -05:00
stag019
db54c2ebd6 Replace all ASMOTOR references with RGBDS. 2015-03-07 15:42:06 -05:00
Anthony J. Bentley
eadaa47770 Sync with upstream. 2015-03-03 23:15:05 -07:00
Anthony J. Bentley
b5e7855afd Remove reference to currently nonexistent gbz80(7) manual. 2015-02-26 00:37:45 -07:00
Anthony J. Bentley
ce7d1d5d49 Use real dates in the manpages. 2015-02-26 00:37:13 -07:00
Anthony J. Bentley
64a3929f4e “No Ns” is redundant. 2015-02-26 00:36:46 -07:00
Anthony J. Bentley
1c1a4e6ac9 Merge branch 'master' of https://github.com/Sanqui/rgbds 2015-02-26 00:36:14 -07:00
Anthony J. Bentley
cc3aa969b8 Merge branch 'cldefines' of https://github.com/stag019/rgbds 2015-02-26 00:25:32 -07:00
Anthony J. Bentley
7055301616 Don’t unnecessarily escape hyphens in manpages. 2015-02-25 02:17:54 -07:00
Anthony J. Bentley
bbf24916e6 Sync usage lines. 2015-02-25 02:16:41 -07:00
Anthony J. Bentley
261503c7c8 Fix the reallocarray header by providing a prototype. 2015-02-25 02:13:23 -07:00
stag019
b924f58bb0 Added -D to manpage 2015-02-24 18:31:13 -05:00
stag019
ac78c37f9d Add reallocarray to Makefile; clean up some things in main.c 2015-02-24 18:11:02 -05:00
Anthony J. Bentley
c8d9ae21e6 A header file this simple doesn’t satisfy modicum of creativity. 2015-02-24 16:02:21 -07:00
Anthony J. Bentley
5281704f62 These internal headers don’t need C++ boilerplate. 2015-02-24 16:01:53 -07:00
stag019
fd4327327c Command line definitions. 2015-02-23 21:23:51 -05:00
Anthony J. Bentley
d81d128a04 Don't specify strict warnings on MinGW. 2015-02-22 04:02:30 -07:00
Anthony J. Bentley
d067f31678 Point to the Github releases for Windows builds. 2015-02-22 04:00:06 -07:00
Anthony J. Bentley
d02294505c Avoid use of magic numbers.
From Antonio Niño Díaz.
2015-02-22 03:55:51 -07:00
Anthony J. Bentley
eb4bbb3e0b Update mapfile code to support new section types.
From Antonio Niño Díaz.
2015-02-22 03:52:28 -07:00
Anthony J. Bentley
2ab10a95e4 Fix a bug in handling WRAMX sections with/without hardcoded addresses.
From Antonio Niño Díaz.
2015-02-22 03:48:00 -07:00
Anthony J. Bentley
bc60b85785 Support BANK() correctly when given WRAMX/SRAM/VRAM labels.
(Mostly) from Antonio Niño Díaz.
2015-02-22 03:33:18 -07:00
Anthony J. Bentley
9d0203a4ee Delete commented-out code. 2015-02-22 03:31:22 -07:00
Anthony J. Bentley
a18b65de21 Update license for reallocarray. 2015-02-17 21:23:14 -07:00
Anthony J. Bentley
1c47ffcce8 Import reallocarray() for later use. 2015-02-14 00:14:39 -07:00
Sanqui
bbf60c7197 Fix _PI (define it for pass 2) 2015-02-11 00:45:42 +01:00
Anthony J. Bentley
60c3a7e2f3 Reformat code for better spacing, and provide a more detailed error. 2015-01-30 20:30:33 -07:00
Anthony J. Bentley
5702995978 extern: sync strlcpy and strlcat with upstream. 2015-01-28 23:36:08 -07:00
Anthony J. Bentley
483d94f88b rgbasm: Fixed a dumb typo; pointed out by stag019. 2015-01-27 05:42:51 -07:00
Anthony J. Bentley
9b4d16b0d8 Add another crashing regression test. 2015-01-27 05:02:57 -07:00
Anthony J. Bentley
a3e95f99d2 rgbasm: Fix a division by zero in section address specifiers. 2015-01-27 04:56:42 -07:00
Anthony J. Bentley
e3a31d7e59 Correct test output for divzero-section-bank. 2015-01-27 04:48:25 -07:00
Anthony J. Bentley
d9f5ce339a Add some basic regression tests.
Most cause crashes. Only macro-@ works correctly; the others need to
be fixed.
2015-01-27 04:33:38 -07:00
Anthony J. Bentley
361f1ac50b Work around a crash when '@' is interpreted as a macro name. 2015-01-22 21:12:57 -07:00
Anthony J. Bentley
4f8cf84ed4 rgbasm: improve (some) pathological spacing. 2015-01-22 21:09:10 -07:00
Anthony J. Bentley
c75b9d4d55 Makefile: don't expand variables in a non-POSIXish way. 2015-01-22 20:42:27 -07:00
Anthony J. Bentley
cd2af0204e rgbasm: Save some horizontal space in main.c. 2015-01-22 20:33:07 -07:00
yenatch
91241b44da rgbasm: bump MAXMACROARGS up to 256 from 9 2015-01-19 23:28:09 -08:00
Anthony J. Bentley
1d174f37da rgbasm: Convert oDontExpandStrings to bool. 2015-01-07 23:52:22 -07:00
Anthony J. Bentley
2777044f70 Delete some unused functions. 2015-01-07 23:39:00 -07:00
Anthony J. Bentley
e5e64b8cec rgbasm: trim ludicrously redundant comments. 2015-01-07 23:36:08 -07:00
Anthony J. Bentley
8534f3a148 Unify usage strings/functions across programs.
The funny spacing is to make it easier to keep to 80 characters/line.
2015-01-07 23:13:18 -07:00
Anthony J. Bentley
bdc6401eba rgbfix: deal with options and arguments in the right order. 2015-01-07 23:07:09 -07:00
Anthony J. Bentley
21d0b402d3 Don't unnecessarily initialize variables. 2015-01-07 22:59:06 -07:00
Anthony J. Bentley
a305649557 rgbasm: Print usage if no filename is given after flags. 2015-01-07 22:44:28 -07:00
Anthony J. Bentley
3b0e207036 Pass -Wimplicit (implicit + implicit-function-declaration) by default. 2015-01-07 18:43:16 -07:00
Anthony J. Bentley
83eddb4c4e Merge branch 'haltnop' of https://github.com/stag019/rgbds 2015-01-07 16:47:10 -07:00
Anthony J. Bentley
57997756b6 Merge branch 'symmapfix' of https://github.com/stag019/rgbds 2015-01-07 16:36:37 -07:00
stag019
ab66b28fdf yacc_pre is no longer needed, since all the files were merged into one. 2015-01-03 06:57:07 -05:00
stag019
116569f54d Fix for mapfiles and symfiles. Before, you couldn't define a mapfile unless you also defined a symfile. If you did, it would segfault. 2015-01-01 01:20:29 -05:00
stag019
2b839fec37 Use the options parameter provided for command line options. Specifically, for haltnop. 2014-12-31 13:29:24 -05:00
Anthony J. Bentley
513d451710 Tweak path for stdnoreturn.h header. 2014-12-31 03:21:46 -07:00
Anthony J. Bentley
9399ba36f9 Check for standards‐compliant platforms first in stdnoreturn.h. 2014-12-31 03:20:14 -07:00
Anthony J. Bentley
ef3a486845 Request POSIX 2008 for strdup(). 2014-12-31 03:18:01 -07:00
stag019
f0e5c5ccc8 Cross-compiler noreturn support. 2014-12-31 04:11:06 -05:00
stag019
9b4959cb75 Implement round, ceil, and floor math functions. 2014-12-17 01:30:19 -05:00
stag019
dca82e6d95 Fix DEF() automatically converting string EQUS. 2014-11-07 16:42:55 -05:00
stag019
871c5ed360 We aren't kidding ourselves anymore. This is a Gameboy assembler, not any sort of generic assembler. 2014-11-07 16:36:03 -05:00
Anthony J. Bentley
635014b74d On Clang, error on implicit function declaration by default. 2014-11-06 21:54:49 -07:00
Anthony J. Bentley
7ad634febd Don’t assign to self. 2014-11-06 21:42:40 -07:00
Anthony J. Bentley
1e1339467e Use POSIX 2001 as the base standard. 2014-11-06 21:39:36 -07:00
Anthony J. Bentley
9e24c26468 Specify _Noreturn in the err family prototypes. 2014-11-06 21:36:27 -07:00
72 changed files with 2418 additions and 2630 deletions

View File

@@ -21,5 +21,8 @@ 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/reallocarray.c is derived from the OpenBSD Project,
http://www.openbsd.org, and is released under the ISC license.
extern/strl.c is derived from the OpenBSD Project, http://www.openbsd.org,
and is released under the BSD license.

View File

@@ -1,6 +1,8 @@
.POSIX:
REALCFLAGS = ${CFLAGS} -Wall -Iinclude -Iinclude/asm/gameboy -g -std=c99
WARNFLAGS = -Wall -Werror=implicit
REALCFLAGS = ${CFLAGS} ${WARNFLAGS} -Iinclude -g \
-std=c99 -D_POSIX_C_SOURCE=200809L
# User-defined variables
PREFIX = /usr/local
@@ -8,13 +10,7 @@ BINPREFIX = ${PREFIX}/bin
MANPREFIX = ${PREFIX}/man
Q = @
yacc_pre := \
src/asm/yaccprt1.y\
src/asm/gameboy/yaccprt2.y\
src/asm/yaccprt3.y\
src/asm/gameboy/yaccprt4.y
rgbasm_obj := \
rgbasm_obj = \
src/asm/asmy.o \
src/asm/charmap.o \
src/asm/fstack.o \
@@ -25,12 +21,13 @@ rgbasm_obj := \
src/asm/output.o \
src/asm/rpn.o \
src/asm/symbol.o \
src/asm/gameboy/locallex.o \
src/asm/locallex.o \
src/extern/err.o \
src/extern/reallocarray.o \
src/extern/strlcpy.o \
src/extern/strlcat.o
rgblink_obj := \
rgblink_obj = \
src/link/assign.o \
src/link/library.o \
src/link/main.o \
@@ -41,7 +38,7 @@ rgblink_obj := \
src/link/symbol.o \
src/extern/err.o
rgbfix_obj := \
rgbfix_obj = \
src/fix/main.o \
src/extern/err.o
@@ -52,7 +49,7 @@ clean:
$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
$Qrm -rf src/asm/asmy.c src/asm/asmy.h
install: all
$Qmkdir -p ${BINPREFIX}
@@ -80,22 +77,17 @@ rgbfix: ${rgbfix_obj}
.c.o:
$Q${CC} ${REALCFLAGS} -c -o $@ $<
src/asm/gameboy/locallex.o src/asm/globlex.o src/asm/lexer.o: src/asm/asmy.h
src/asm/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}
$Qcat ${yacc_pre} > $@
# Below is a target for the project maintainer to easily create win32 exes.
# This is not for Windows users!
# If you're building on Windows with Cygwin or Mingw, just follow the Unix
# install instructions instead.
mingw:
$Qenv PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin \
make CC=gcc CFLAGS="-I/usr/local/mingw32/include \
-D__progname=\\\"\\\" \
-D_Noreturn='__attribute__((noreturn))' ${CFLAGS}"
make WARNFLAGS= CC=gcc CFLAGS="-I/usr/local/mingw32/include \
${CFLAGS}"
$Qmv rgbasm rgbasm.exe
$Qmv rgblink rgblink.exe
$Qmv rgbfix rgbfix.exe

2
README
View File

@@ -53,6 +53,6 @@ this variable. Defaults to @.
Installing RGBDS (Windows)
============================
Windows builds are available here: http://anthony.bentley.name/rgbds/
Windows builds are available here: https://github.com/bentley/rgbds/releases
Copy the .exe files to C:\Windows\ or similar.

View File

@@ -6,16 +6,17 @@
*
*/
#ifndef ASMOTOR_ASM_ASM_H
#define ASMOTOR_ASM_ASM_H
#ifndef RGBDS_ASM_ASM_H
#define RGBDS_ASM_ASM_H
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "asm/types.h"
#include "types.h"
#include "asm/symbol.h"
#include "localasm.h"
#include "asm/localasm.h"
extern SLONG nLineNo;
extern ULONG nTotalLines;
@@ -26,9 +27,9 @@ extern char tzCurrentFileName[_MAX_PATH + 1];
extern struct Section *pCurrentSection;
extern struct sSymbol *tHashedSymbols[HASHSIZE];
extern struct sSymbol *pPCSymbol;
extern UBYTE oDontExpandStrings;
extern bool oDontExpandStrings;
#define MAXMACROARGS 9
#define MAXMACROARGS 256
#define MAXINCPATHS 16
#endif /* // ASM_H */

View File

@@ -1,5 +1,5 @@
#ifndef ASMOTOR_ASM_CHARMAP_H
#define ASMOTOR_ASM_CHARMAP_H
#ifndef RGBDS_ASM_CHARMAP_H
#define RGBDS_ASM_CHARMAP_H
#define MAXCHARMAPS 512
#define CHARMAPLENGTH 8

View File

@@ -6,13 +6,13 @@
*
*/
#ifndef ASMOTOR_ASM_FSTACK_H
#define ASMOTOR_ASM_FSTACK_H
#ifndef RGBDS_ASM_FSTACK_H
#define RGBDS_ASM_FSTACK_H
#include <stdio.h>
#include "asm/asm.h"
#include "asm/types.h"
#include "types.h"
#include "asm/lexer.h"
struct sContext {

View File

@@ -1,9 +1,9 @@
#ifndef ASMOTOR_ASM_LEXER_H
#define ASMOTOR_ASM_LEXER_H
#ifndef RGBDS_ASM_LEXER_H
#define RGBDS_ASM_LEXER_H
#include <stdio.h>
#include "asm/types.h"
#include "types.h"
#define LEXHASHSIZE (1 << 11)
#define MAXSTRLEN 255

View File

@@ -1,5 +1,5 @@
#ifndef ASMOTOR_MAIN_H
#define ASMOTOR_MAIN_H
#ifndef RGBDS_MAIN_H
#define RGBDS_MAIN_H
#include <stdbool.h>
@@ -8,6 +8,7 @@ struct sOptions {
char binary[2];
SLONG fillchar;
bool verbose;
bool haltnop;
//-1 == random
};

View File

@@ -1,5 +1,5 @@
#ifndef ASMOTOR_ASM_LINK_H
#define ASMOTOR_ASM_LINK_H
#ifndef RGBDS_ASM_LINK_H
#define RGBDS_ASM_LINK_H
/* RGB0 .obj format:
*

View File

@@ -1,7 +1,7 @@
#ifndef ASMOTOR_ASM_MATH_H
#define ASMOTOR_ASM_MATH_H
#ifndef RGBDS_ASM_MATH_H
#define RGBDS_ASM_MATH_H
#include "asm/types.h"
#include "types.h"
void math_DefinePI(void);
void math_Print(SLONG i);
@@ -14,5 +14,8 @@ SLONG math_ATan(SLONG i);
SLONG math_ATan2(SLONG i, SLONG j);
SLONG math_Mul(SLONG i, SLONG j);
SLONG math_Div(SLONG i, SLONG j);
SLONG math_Round(SLONG i);
SLONG math_Ceil(SLONG i);
SLONG math_Floor(SLONG i);
#endif

View File

@@ -1,8 +1,8 @@
#ifndef ASMOTOR_ASM_OUTPUT_H
#define ASMOTOR_ASM_OUTPUT_H
#ifndef RGBDS_ASM_OUTPUT_H
#define RGBDS_ASM_OUTPUT_H
#include "asm/rpn.h"
#include "asm/types.h"
#include "types.h"
struct Section {
char *pzName;

View File

@@ -1,5 +1,5 @@
#ifndef ASMOTOR_ASM_RPN_H
#define ASMOTOR_ASM_RPN_H
#ifndef RGBDS_ASM_RPN_H
#define RGBDS_ASM_RPN_H
struct Expression {
SLONG nVal;

View File

@@ -1,7 +1,7 @@
#ifndef ASMOTOR_SYMBOL_H
#define ASMOTOR_SYMBOL_H
#ifndef RGBDS_SYMBOL_H
#define RGBDS_SYMBOL_H
#include "asm/types.h"
#include "types.h"
#define HASHSIZE (1 << 16)
#define MAXSYMLEN 256

View File

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

40
include/extern/err.h vendored
View File

@@ -1,26 +1,3 @@
/*
* 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
@@ -29,6 +6,7 @@
#else
#include <stdarg.h>
#include "extern/stdnoreturn.h"
#define warn rgbds_warn
#define vwarn rgbds_vwarn
@@ -40,23 +18,15 @@
#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
noreturn void err(int, const char *, ...);
noreturn void verr(int, const char *, va_list);
noreturn void errx(int, const char *, ...);
noreturn void verrx(int, const char *, va_list);
#endif

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

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

16
include/extern/stdnoreturn.h vendored Normal file
View File

@@ -0,0 +1,16 @@
#if __STDC_VERSION__ >= 201112L
/* C11 or newer */
#define noreturn _Noreturn
#elif __cplusplus >= 201103L
/* C++11 or newer */
#define noreturn [[noreturn]]
#elif __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ >= 5))
/* GCC 2.5 or newer */
#define noreturn __attribute__ ((noreturn))
#elif _MSC_VER >= 1310
/* MS Visual Studio 2003/.NET Framework 1.1 or newer */
#define noreturn _declspec( noreturn)
#else
/* unsupported, but no need to throw a fit */
#define noreturn
#endif

View File

@@ -1,7 +1,7 @@
#ifndef ASMOTOR_LINK_ASSIGN_H
#define ASMOTOR_LINK_ASSIGN_H
#ifndef RGBDS_LINK_ASSIGN_H
#define RGBDS_LINK_ASSIGN_H
#include "link/types.h"
#include "types.h"
enum eBankDefine {
BANK_ROM0 = 0,

View File

@@ -1,5 +1,5 @@
#ifndef ASMOTOR_LINK_LIBRARY_H
#define ASMOTOR_LINK_LIBRARY_H
#ifndef RGBDS_LINK_LIBRARY_H
#define RGBDS_LINK_LIBRARY_H
extern void AddNeededModules(void);

View File

@@ -1,7 +1,7 @@
#ifndef ASMOTOR_LINK_MAIN_H
#define ASMOTOR_LINK_MAIN_H
#ifndef RGBDS_LINK_MAIN_H
#define RGBDS_LINK_MAIN_H
#include "link/types.h"
#include "types.h"
extern SLONG fillchar;
extern char smartlinkstartsymbol[256];

View File

@@ -1,5 +1,5 @@
#ifndef ASMOTOR_LINK_MAPFILE_H
#define ASMOTOR_LINK_MAPFILE_H
#ifndef RGBDS_LINK_MAPFILE_H
#define RGBDS_LINK_MAPFILE_H
extern void SetMapfileName(char *name);
extern void SetSymfileName(char *name);

View File

@@ -1,11 +1,11 @@
#ifndef ASMOTOR_LINK_LINK_H
#define ASMOTOR_LINK_LINK_H
#ifndef RGBDS_LINK_LINK_H
#define RGBDS_LINK_LINK_H
#ifndef _MAX_PATH
#define _MAX_PATH 512
#endif
#include "link/types.h"
#include "types.h"
extern SLONG options;
#define OPT_SMALL 0x01

View File

@@ -1,5 +1,5 @@
#ifndef ASMOTOR_LINK_OBJECT_H
#define ASMOTOR_LINK_OBJECT_H
#ifndef RGBDS_LINK_OBJECT_H
#define RGBDS_LINK_OBJECT_H
extern void obj_Readfile(char *tzObjectfile);

View File

@@ -1,5 +1,5 @@
#ifndef ASMOTOR_LINK_OUTPUT_H
#define ASMOTOR_LINK_OUTPUT_H
#ifndef RGBDS_LINK_OUTPUT_H
#define RGBDS_LINK_OUTPUT_H
void out_Setname(char *tzOutputfile);
void Output(void);

View File

@@ -1,7 +1,7 @@
#ifndef ASMOTOR_LINK_PATCH_H
#define ASMOTOR_LINK_PATCH_H
#ifndef RGBDS_LINK_PATCH_H
#define RGBDS_LINK_PATCH_H
#include "link/types.h"
#include "types.h"
void Patch(void);
extern SLONG nPC;

View File

@@ -1,10 +1,10 @@
#ifndef ASMOTOR_LINK_SYMBOL_H
#define ASMOTOR_LINK_SYMBOL_H
#ifndef RGBDS_LINK_SYMBOL_H
#define RGBDS_LINK_SYMBOL_H
#include "link/types.h"
#include "types.h"
void sym_Init(void);
void sym_CreateSymbol(char *tzName, SLONG nValue, SBYTE nBank);
void sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank);
SLONG sym_GetValue(char *tzName);
SLONG sym_GetBank(char *tzName);

View File

@@ -1,5 +1,5 @@
#ifndef ASMOTOR_LINK_TYPES_H
#define ASMOTOR_LINK_TYPES_H
#ifndef RGBDS_TYPES_H
#define RGBDS_TYPES_H
#ifndef _MAX_PATH
#define _MAX_PATH 512

1
src/asm/.gitignore vendored
View File

@@ -1,3 +1,2 @@
asmy.c
asmy.h
asmy.y

1599
src/asm/asmy.y Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,5 @@
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* INCLUDES
*
* FileStack routines
*/
#include <errno.h>
@@ -13,7 +10,7 @@
#include "asm/symbol.h"
#include "asm/fstack.h"
#include "asm/types.h"
#include "types.h"
#include "asm/main.h"
#include "asm/lexer.h"
#include "extern/err.h"
@@ -23,13 +20,6 @@
#define PATH_MAX 256
#endif
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* VARIABLES
*
*/
struct sContext *pFileStack;
struct sSymbol *pCurrentMacro;
YY_BUFFER_STATE CurrentFlexHandle;
@@ -55,12 +45,8 @@ ULONG ulMacroReturnValue;
#define STAT_isREPTBlock 3
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Context push and pop
*
*/
void
pushcontext(void)
{
@@ -167,13 +153,10 @@ yywrap(void)
{
return (popcontext());
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Dump the context stack to stderr
*
*/
/*
* Dump the context stack to stderr
*/
void
fstk_Dump(void)
{
@@ -189,13 +172,10 @@ fstk_Dump(void)
fprintf(stderr, "%s(%ld)", tzCurrentFileName, nLineNo);
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Extra includepath stuff
*
*/
/*
* Extra includepath stuff
*/
void
fstk_AddIncludePath(char *s)
{
@@ -230,13 +210,10 @@ fstk_FindFile(char *fname)
errno = ENOENT;
return NULL;
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Set up an include file for parsing
*
*/
/*
* Set up an include file for parsing
*/
void
fstk_RunInclude(char *tzFileName)
{
@@ -262,13 +239,10 @@ fstk_RunInclude(char *tzFileName)
yyunput('\n');
nLineNo -= 1;
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Set up a macro for parsing
*
*/
/*
* Set up a macro for parsing
*/
ULONG
fstk_RunMacro(char *s)
{
@@ -281,6 +255,8 @@ fstk_RunMacro(char *s)
sym_UseNewMacroArgs();
nCurrentStatus = STAT_isMacro;
strcpy(tzCurrentFileName, s);
if (sym->pMacro == NULL)
return 0;
pCurrentMacro = sym;
CurrentFlexHandle =
yy_scan_bytes(pCurrentMacro->pMacro,
@@ -290,13 +266,10 @@ fstk_RunMacro(char *s)
} else
return (0);
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Set up a macroargument for parsing
*
*/
/*
* Set up a macroargument for parsing
*/
void
fstk_RunMacroArg(SLONG s)
{
@@ -316,13 +289,10 @@ fstk_RunMacroArg(SLONG s)
} else
fatalerror("No such macroargument");
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Set up a stringequate for parsing
*
*/
/*
* Set up a stringequate for parsing
*/
void
fstk_RunString(char *s)
{
@@ -338,13 +308,10 @@ fstk_RunString(char *s)
} else
yyerror("No such string symbol '%s'", s);
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Set up a repeat block for parsing
*
*/
/*
* Set up a repeat block for parsing
*/
void
fstk_RunRept(ULONG count)
{
@@ -362,13 +329,10 @@ fstk_RunRept(ULONG count)
yy_switch_to_buffer(CurrentFlexHandle);
}
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Initialize the filestack routines
*
*/
/*
* Initialize the filestack routines
*/
void
fstk_Init(char *s)
{

View File

@@ -1,41 +0,0 @@
%token T_SECT_WRAM0 T_SECT_VRAM T_SECT_ROMX T_SECT_ROM0 T_SECT_HRAM T_SECT_WRAMX T_SECT_SRAM
%token T_Z80_ADC T_Z80_ADD T_Z80_AND
%token T_Z80_BIT
%token T_Z80_CALL T_Z80_CCF T_Z80_CP T_Z80_CPL
%token T_Z80_DAA T_Z80_DEC T_Z80_DI
%token T_Z80_EI T_Z80_EX
%token T_Z80_HALT
%token T_Z80_INC
%token T_Z80_JP T_Z80_JR
%token T_Z80_LD
%token T_Z80_LDI
%token T_Z80_LDD
%token T_Z80_LDIO
%token T_Z80_NOP
%token T_Z80_OR
%token T_Z80_POP T_Z80_PUSH
%token T_Z80_RES T_Z80_RET T_Z80_RETI T_Z80_RST
%token T_Z80_RL T_Z80_RLA T_Z80_RLC T_Z80_RLCA
%token T_Z80_RR T_Z80_RRA T_Z80_RRC T_Z80_RRCA
%token T_Z80_SBC T_Z80_SCF T_Z80_STOP
%token T_Z80_SLA T_Z80_SRA T_Z80_SRL T_Z80_SUB T_Z80_SWAP
%token T_Z80_XOR
%token T_MODE_A T_MODE_B T_MODE_C T_MODE_C_IND T_MODE_D T_MODE_E T_MODE_H T_MODE_L
%token T_MODE_AF
%token T_MODE_BC T_MODE_BC_IND
%token T_MODE_DE T_MODE_DE_IND
%token T_MODE_SP T_MODE_SP_IND
%token T_MODE_HL T_MODE_HL_IND T_MODE_HL_INDDEC T_MODE_HL_INDINC
%token T_CC_NZ T_CC_Z T_CC_NC
%type <nConstValue> reg_r
%type <nConstValue> reg_ss
%type <nConstValue> reg_rr
%type <nConstValue> reg_tt
%type <nConstValue> ccode
%type <sVal> op_a_n
%type <nConstValue> op_a_r
%type <nConstValue> op_hl_ss
%type <sVal> op_mem_ind

View File

@@ -1,557 +0,0 @@
section:
T_POP_SECTION string ',' sectiontype
{
out_NewSection($2,$4);
}
| T_POP_SECTION string ',' sectiontype '[' const ']'
{
if( $6>=0 && $6<0x10000 )
out_NewAbsSection($2,$4,$6,-1);
else
yyerror("Address $%x not 16-bit", $6);
}
| T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']'
{
if( $4==SECT_ROMX ) {
if( $8>=1 && $8<=0x1ff )
out_NewAbsSection($2,$4,-1,$8);
else
yyerror("ROM bank value $%x out of range (1 to $1ff)", $8);
} else if ($4 == SECT_SRAM) {
if ($8 >= 0 && $8 <= 3) {
out_NewAbsSection($2, $4, -1, $8);
} else {
yyerror("SRAM bank value $%x out of range (0 to 3)", $8);
}
} else if ($4 == SECT_WRAMX) {
if ($8 >= 1 && $8 <= 7) {
out_NewAbsSection($2, $4, -1, $8);
} else {
yyerror("WRAMX bank value $%x out of range (1 to 7)", $8);
}
} else if ($4 == SECT_VRAM) {
if ($8 >= 0 && $8 <= 1) {
out_NewAbsSection($2, $4, -1, $8);
} else {
yyerror("VRAM bank value $%x out of range (0 to 1)", $8);
}
} else {
yyerror("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections");
}
}
| T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']'
{
if( $4==SECT_ROMX ) {
if( $6>=0 && $6<0x10000 ) {
if( $11>=1 && $11<=0x1ff )
out_NewAbsSection($2,$4,$6,$11);
else
yyerror("ROM bank value $%x out of range (1 to $1ff)", $11);
} else
yyerror("Address $%x not 16-bit", $6);
} else if ($4 == SECT_SRAM) {
if ($6 >= 0 && $6 < 0x10000) {
if ($11 >= 0 && $11 <= 3) {
out_NewAbsSection($2, $4, $6, $11);
} else {
yyerror("SRAM bank value $%x out of range (0 to 3)", $11);
}
} else {
yyerror("Address $%x not 16-bit", $6);
}
} else if ($4 == SECT_WRAMX) {
if ($6 >= 0 && $6 < 0x10000) {
if ($11 >= 1 && $11 <= 7) {
out_NewAbsSection($2, $4, $6, $11);
} else {
yyerror("WRAMX bank value $%x out of range (1 to 7)", $11);
}
} else {
yyerror("Address $%x not 16-bit", $6);
}
} else if ($4 == SECT_VRAM) {
if ($6 >= 0 && $6 < 0x10000) {
if ($11 >= 0 && $11 <= 1) {
out_NewAbsSection($2,$4,$6,$11);
} else {
yyerror("VRAM bank value $%x out of range (0 to 1)", $11);
}
} else {
yyerror("Address $%x not 16-bit", $6);
}
} else {
yyerror("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections");
}
}
;
sectiontype:
T_SECT_WRAM0 { $$=SECT_WRAM0; }
| T_SECT_VRAM { $$=SECT_VRAM; }
| T_SECT_ROMX { $$=SECT_ROMX; }
| T_SECT_ROM0 { $$=SECT_ROM0; }
| T_SECT_HRAM { $$=SECT_HRAM; }
| T_SECT_WRAMX { $$=SECT_WRAMX; }
| T_SECT_SRAM { $$=SECT_SRAM; }
;
cpu_command : z80_adc
| z80_add
| z80_and
| z80_bit
| z80_call
| z80_ccf
| z80_cp
| z80_cpl
| z80_daa
| z80_dec
| z80_di
| z80_ei
| z80_ex
| z80_halt
| z80_inc
| z80_jp
| z80_jr
| z80_ld
| z80_ldd
| z80_ldi
| z80_ldio
| z80_nop
| z80_or
| z80_pop
| z80_push
| z80_res
| z80_ret
| z80_reti
| z80_rl
| z80_rla
| z80_rlc
| z80_rlca
| z80_rr
| z80_rra
| z80_rrc
| z80_rrca
| z80_rst
| z80_sbc
| z80_scf
| z80_set
| z80_sla
| z80_sra
| z80_srl
| z80_stop
| z80_sub
| z80_swap
| z80_xor
;
z80_adc : T_Z80_ADC op_a_n { out_AbsByte(0xCE); out_RelByte(&$2); }
| T_Z80_ADC op_a_r { out_AbsByte(0x88|$2); }
;
z80_add : T_Z80_ADD op_a_n { out_AbsByte(0xC6); out_RelByte(&$2); }
| T_Z80_ADD op_a_r { out_AbsByte(0x80|$2); }
| T_Z80_ADD op_hl_ss { out_AbsByte(0x09|($2<<4)); }
| T_Z80_ADD T_MODE_SP comma const_8bit
{ out_AbsByte(0xE8); out_RelByte(&$4); }
;
z80_and : T_Z80_AND op_a_n { out_AbsByte(0xE6); out_RelByte(&$2); }
| T_Z80_AND op_a_r { out_AbsByte(0xA0|$2); }
;
z80_bit : T_Z80_BIT const_3bit comma reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x40|($2<<3)|$4); }
;
z80_call : T_Z80_CALL const_16bit
{ out_AbsByte(0xCD); out_RelWord(&$2); }
| T_Z80_CALL ccode comma const_16bit
{ out_AbsByte(0xC4|($2<<3)); out_RelWord(&$4); }
;
z80_ccf : T_Z80_CCF
{ out_AbsByte(0x3F); }
;
z80_cp : T_Z80_CP op_a_n { out_AbsByte(0xFE); out_RelByte(&$2); }
| T_Z80_CP op_a_r { out_AbsByte(0xB8|$2); }
;
z80_cpl : T_Z80_CPL { out_AbsByte(0x2F); }
;
z80_daa : T_Z80_DAA { out_AbsByte(0x27); }
;
z80_dec : T_Z80_DEC reg_r
{ out_AbsByte(0x05|($2<<3)); }
| T_Z80_DEC reg_ss
{ out_AbsByte(0x0B|($2<<4)); }
;
z80_di : T_Z80_DI
{ out_AbsByte(0xF3); }
;
z80_ei : T_Z80_EI
{ out_AbsByte(0xFB); }
;
z80_ex : T_Z80_EX T_MODE_HL comma T_MODE_SP_IND
{ out_AbsByte(0xE3); }
| T_Z80_EX T_MODE_SP_IND comma T_MODE_HL
{ out_AbsByte(0xE3); }
;
z80_halt: T_Z80_HALT
{
out_AbsByte(0x76);
if (haltnop) {
out_AbsByte(0x00);
}
}
;
z80_inc : T_Z80_INC reg_r
{ out_AbsByte(0x04|($2<<3)); }
| T_Z80_INC reg_ss
{ out_AbsByte(0x03|($2<<4)); }
;
z80_jp : T_Z80_JP const_16bit
{ out_AbsByte(0xC3); out_RelWord(&$2); }
| T_Z80_JP ccode comma const_16bit
{ out_AbsByte(0xC2|($2<<3)); out_RelWord(&$4); }
| T_Z80_JP T_MODE_HL_IND
{ out_AbsByte(0xE9); }
| T_Z80_JP T_MODE_HL
{ out_AbsByte(0xE9); }
;
z80_jr : T_Z80_JR const_PCrel
{ out_AbsByte(0x18); out_PCRelByte(&$2); }
| T_Z80_JR ccode comma const_PCrel
{ out_AbsByte(0x20|($2<<3)); out_PCRelByte(&$4); }
;
z80_ldi : T_Z80_LDI T_MODE_HL_IND comma T_MODE_A
{ out_AbsByte(0x02|(2<<4)); }
| T_Z80_LDI T_MODE_A comma T_MODE_HL
{ out_AbsByte(0x0A|(2<<4)); }
;
z80_ldd : T_Z80_LDD T_MODE_HL_IND comma T_MODE_A
{ out_AbsByte(0x02|(3<<4)); }
| T_Z80_LDD T_MODE_A comma T_MODE_HL
{ out_AbsByte(0x0A|(3<<4)); }
;
z80_ldio : T_Z80_LDIO T_MODE_A comma op_mem_ind
{
rpn_CheckHRAM(&$4,&$4);
if( (!rpn_isReloc(&$4))
&& ($4.nVal<0 || ($4.nVal>0xFF && $4.nVal<0xFF00) || $4.nVal>0xFFFF) )
{
yyerror("Source address $%x not in HRAM ($FF00 to $FFFE)", $4.nVal);
}
out_AbsByte(0xF0);
$4.nVal&=0xFF;
out_RelByte(&$4);
}
| T_Z80_LDIO op_mem_ind comma T_MODE_A
{
rpn_CheckHRAM(&$2,&$2);
if( (!rpn_isReloc(&$2))
&& ($2.nVal<0 || ($2.nVal>0xFF && $2.nVal<0xFF00) || $2.nVal>0xFFFF) )
{
yyerror("Destination address $%x not in HRAM ($FF00 to $FFFE)", $2.nVal);
}
out_AbsByte(0xE0);
$2.nVal&=0xFF;
out_RelByte(&$2);
}
;
z80_ld : z80_ld_mem
| z80_ld_cind
| z80_ld_rr
| z80_ld_ss
| z80_ld_hl
| z80_ld_sp
| z80_ld_r
| z80_ld_a
;
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); }
;
z80_ld_sp : T_Z80_LD T_MODE_SP comma T_MODE_HL
{ out_AbsByte(0xF9); }
| T_Z80_LD T_MODE_SP comma const_16bit
{ out_AbsByte(0x01|(REG_SP<<4)); out_RelWord(&$4); }
;
z80_ld_mem : T_Z80_LD op_mem_ind comma T_MODE_SP
{ out_AbsByte(0x08); out_RelWord(&$2); }
| T_Z80_LD op_mem_ind comma T_MODE_A
{
if( (!rpn_isReloc(&$2)) && $2.nVal>=0xFF00)
{
out_AbsByte(0xE0);
out_AbsByte($2.nVal&0xFF);
}
else
{
out_AbsByte(0xEA);
out_RelWord(&$2);
}
}
;
z80_ld_cind : T_Z80_LD T_MODE_C_IND comma T_MODE_A
{ out_AbsByte(0xE2); }
;
z80_ld_rr : T_Z80_LD reg_rr comma T_MODE_A
{ out_AbsByte(0x02|($2<<4)); }
;
z80_ld_r : T_Z80_LD reg_r comma const_8bit
{ out_AbsByte(0x06|($2<<3)); out_RelByte(&$4); }
| T_Z80_LD reg_r comma reg_r
{
if( ($2==REG_HL_IND) && ($4==REG_HL_IND) )
{
yyerror("LD [HL],[HL] not a valid instruction");
}
else
out_AbsByte(0x40|($2<<3)|$4);
}
;
z80_ld_a : T_Z80_LD reg_r comma T_MODE_C_IND
{
if( $2==REG_A )
out_AbsByte(0xF2);
else
{
yyerror("Destination operand must be A");
}
}
| T_Z80_LD reg_r comma reg_rr
{
if( $2==REG_A )
out_AbsByte(0x0A|($4<<4));
else
{
yyerror("Destination operand must be A");
}
}
| T_Z80_LD reg_r comma op_mem_ind
{
if( $2==REG_A )
{
if( (!rpn_isReloc(&$4)) && $4.nVal>=0xFF00 )
{
out_AbsByte(0xF0);
out_AbsByte($4.nVal&0xFF);
}
else
{
out_AbsByte(0xFA);
out_RelWord(&$4);
}
}
else
{
yyerror("Destination operand must be A");
}
}
;
z80_ld_ss : T_Z80_LD reg_ss comma const_16bit
{ out_AbsByte(0x01|($2<<4)); out_RelWord(&$4); }
;
z80_nop : T_Z80_NOP
{ out_AbsByte(0x00); }
;
z80_or : T_Z80_OR op_a_n
{ out_AbsByte(0xF6); out_RelByte(&$2); }
| T_Z80_OR op_a_r
{ out_AbsByte(0xB0|$2); }
;
z80_pop : T_Z80_POP reg_tt
{ out_AbsByte(0xC1|($2<<4)); }
;
z80_push : T_Z80_PUSH reg_tt
{ out_AbsByte(0xC5|($2<<4)); }
;
z80_res : T_Z80_RES const_3bit comma reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x80|($2<<3)|$4); }
;
z80_ret : T_Z80_RET
{ out_AbsByte(0xC9); }
| T_Z80_RET ccode
{ out_AbsByte(0xC0|($2<<3)); }
;
z80_reti : T_Z80_RETI
{ out_AbsByte(0xD9); }
;
z80_rl : T_Z80_RL reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x10|$2); }
;
z80_rla : T_Z80_RLA
{ out_AbsByte(0x17); }
;
z80_rlc : T_Z80_RLC reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x00|$2); }
;
z80_rlca : T_Z80_RLCA
{ out_AbsByte(0x07); }
;
z80_rr : T_Z80_RR reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x18|$2); }
;
z80_rra : T_Z80_RRA
{ out_AbsByte(0x1F); }
;
z80_rrc : T_Z80_RRC reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x08|$2); }
;
z80_rrca : T_Z80_RRCA
{ out_AbsByte(0x0F); }
;
z80_rst : T_Z80_RST const_8bit
{
if( rpn_isReloc(&$2) )
{
yyerror("Address for RST must be absolute");
}
else if( ($2.nVal&0x38)!=$2.nVal )
{
yyerror("Invalid address $%x for RST", $2.nVal);
}
else
out_AbsByte(0xC7|$2.nVal);
}
;
z80_sbc : T_Z80_SBC op_a_n { out_AbsByte(0xDE); out_RelByte(&$2); }
| T_Z80_SBC op_a_r { out_AbsByte(0x98|$2); }
;
z80_scf : T_Z80_SCF
{ out_AbsByte(0x37); }
;
z80_set : T_POP_SET const_3bit comma reg_r
{ out_AbsByte(0xCB); out_AbsByte(0xC0|($2<<3)|$4); }
;
z80_sla : T_Z80_SLA reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x20|$2); }
;
z80_sra : T_Z80_SRA reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x28|$2); }
;
z80_srl : T_Z80_SRL reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x38|$2); }
;
z80_stop : T_Z80_STOP
{ out_AbsByte(0x10); out_AbsByte(0x00); }
;
z80_sub : T_Z80_SUB op_a_n { out_AbsByte(0xD6); out_RelByte(&$2); }
| T_Z80_SUB op_a_r { out_AbsByte(0x90|$2); }
;
z80_swap : T_Z80_SWAP reg_r
{ out_AbsByte(0xCB); out_AbsByte(0x30|$2); }
;
z80_xor : T_Z80_XOR op_a_n { out_AbsByte(0xEE); out_RelByte(&$2); }
| T_Z80_XOR op_a_r { out_AbsByte(0xA8|$2); }
;
op_mem_ind : '[' const_16bit ']' { $$ = $2; }
;
op_hl_ss : reg_ss { $$ = $1; }
| T_MODE_HL comma reg_ss { $$ = $3; }
;
op_a_r : reg_r { $$ = $1; }
| T_MODE_A comma reg_r { $$ = $3; }
;
op_a_n : const_8bit { $$ = $1; }
| T_MODE_A comma const_8bit { $$ = $3; }
;
comma : ','
;
ccode : T_CC_NZ { $$ = CC_NZ; }
| T_CC_Z { $$ = CC_Z; }
| T_CC_NC { $$ = CC_NC; }
| T_MODE_C { $$ = CC_C; }
;
reg_r : T_MODE_B { $$ = REG_B; }
| T_MODE_C { $$ = REG_C; }
| T_MODE_D { $$ = REG_D; }
| T_MODE_E { $$ = REG_E; }
| T_MODE_H { $$ = REG_H; }
| T_MODE_L { $$ = REG_L; }
| T_MODE_HL_IND { $$ = REG_HL_IND; }
| T_MODE_A { $$ = REG_A; }
;
reg_tt : T_MODE_BC { $$ = REG_BC; }
| T_MODE_DE { $$ = REG_DE; }
| T_MODE_HL { $$ = REG_HL; }
| T_MODE_AF { $$ = REG_AF; }
;
reg_ss : T_MODE_BC { $$ = REG_BC; }
| T_MODE_DE { $$ = REG_DE; }
| T_MODE_HL { $$ = REG_HL; }
| T_MODE_SP { $$ = REG_SP; }
;
reg_rr : T_MODE_BC_IND { $$ = REG_BC_IND; }
| T_MODE_DE_IND { $$ = REG_DE_IND; }
| T_MODE_HL_INDINC { $$ = REG_HL_INDINC; }
| T_MODE_HL_INDDEC { $$ = REG_HL_INDDEC; }
;
%%

View File

@@ -7,12 +7,13 @@
#include "asmy.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
UBYTE oDontExpandStrings = 0;
bool oDontExpandStrings = false;
SLONG nGBGfxID = -1;
SLONG nBinaryID = -1;
@@ -160,7 +161,7 @@ ParseSymbol(char *src, ULONG size)
if (*src == '@')
marg = sym_FindMacroArg(-1);
else if (*src >= '0' && *src <= '9')
marg = sym_FindMacroArg(*src);
marg = sym_FindMacroArg(*src - '0');
else {
fatalerror("Malformed ID");
return (0);
@@ -184,7 +185,7 @@ ParseSymbol(char *src, ULONG size)
dest[copied] = 0;
if (oDontExpandStrings == 0 && sym_isString(dest)) {
if (!oDontExpandStrings && sym_isString(dest)) {
char *s;
yyskipbytes(size_backup);
@@ -225,7 +226,6 @@ PutUniqueArg(char *src, ULONG size)
{
char *s;
src = src;
yyskipbytes(size);
if ((s = sym_FindMacroArg(-1)) != NULL) {
yyunputstr(s);
@@ -268,6 +268,9 @@ struct sLexInitString staticstrings[] = {
{"bank", T_OP_BANK},
{"round", T_OP_ROUND},
{"ceil", T_OP_CEIL},
{"floor", T_OP_FLOOR},
{"div", T_OP_FDIV},
{"mul", T_OP_FMUL},
{"sin", T_OP_SIN},

View File

@@ -1,4 +1,3 @@
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -7,7 +6,7 @@
#include "asm/asm.h"
#include "asm/lexer.h"
#include "asm/types.h"
#include "types.h"
#include "asm/main.h"
#include "asm/rpn.h"
#include "asm/fstack.h"

View File

@@ -2,7 +2,7 @@
#include "asm/lexer.h"
#include "asm/rpn.h"
#include "../asmy.h"
#include "asmy.h"
struct sLexInitString localstrings[] = {
{"adc", T_Z80_ADC},

View File

@@ -1,14 +1,5 @@
/*
* RGBAsm - MAIN.C
*
* INCLUDES
*
*/
#define _XOPEN_SOURCE 500
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -20,18 +11,16 @@
#include "asm/output.h"
#include "asm/main.h"
#include "extern/err.h"
#include "extern/reallocarray.h"
int yyparse(void);
void setuplex(void);
/*
* RGBAsm - MAIN.C
*
* VARIABLES
*
*/
int cldefines_index;
int cldefines_size;
char **cldefines;
bool haltnop;
char *progname;
clock_t nStartClock, nEndClock;
SLONG nLineNo;
@@ -40,10 +29,7 @@ ULONG nTotalLines, nPass, nPC, nIFDepth, nErrors;
extern int yydebug;
/*
* RGBAsm - MAIN.C
*
* Option stack
*
*/
struct sOptions DefaultOptions;
@@ -194,13 +180,49 @@ opt_Pop(void)
} else
fatalerror("No entries in the option stack");
}
/*
* RGBAsm - MAIN.C
*
* Error handling
*
*/
void
opt_AddDefine(char *s)
{
char *value, *equals;
if(cldefines_index >= cldefines_size)
{
cldefines_size *= 2;
cldefines = reallocarray(cldefines, cldefines_size,
2 * sizeof(void *));
if(!cldefines)
{
fatalerror("No memory for command line defines");
}
}
equals = strchr(s, '=');
if(equals)
{
*equals = '\0';
value = equals + 1;
}
else
{
value = "1";
}
cldefines[cldefines_index++] = s;
cldefines[cldefines_index++] = value;
}
void
opt_ParseDefines()
{
int i;
for(i = 0; i < cldefines_index; i += 2)
{
sym_AddString(cldefines[i], cldefines[i + 1]);
}
}
/*
* Error handling
*/
void
verror(const char *fmt, va_list args)
{
@@ -230,26 +252,15 @@ fatalerror(const char *fmt, ...)
va_end(args);
exit(5);
}
/*
* RGBAsm - MAIN.C
*
* Help text
*
*/
void
PrintUsage(void)
static void
usage(void)
{
printf("Usage: rgbasm [-v] [-h] [-b chars] [-g chars] [-i path] [-o outfile] [-p pad_value]\n"
" file\n");
printf(
"Usage: rgbasm [-hv] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n"
" [-o outfile] [-p pad_value] file.asm\n");
exit(1);
}
/*
* RGBAsm - MAIN.C
*
* main
*
*/
int
main(int argc, char *argv[])
@@ -261,10 +272,18 @@ main(int argc, char *argv[])
char *tzMainfile;
haltnop = true;
cldefines_size = 32;
cldefines = reallocarray(cldefines, cldefines_size,
2 * sizeof(void *));
if(!cldefines)
{
fatalerror("No memory for command line defines");
}
if (argc == 1)
PrintUsage();
usage();
progname = argv[0];
/* yydebug=1; */
@@ -276,12 +295,13 @@ main(int argc, char *argv[])
DefaultOptions.binary[1] = '1';
DefaultOptions.fillchar = 0;
DefaultOptions.verbose = false;
DefaultOptions.haltnop = true;
opt_SetCurrentOptions(&DefaultOptions);
newopt = CurrentOptions;
while ((ch = getopt(argc, argv, "b:g:hi:o:p:v")) != -1) {
while ((ch = getopt(argc, argv, "b:D:g:hi:o:p:v")) != -1) {
switch (ch) {
case 'b':
if (strlen(optarg) == 2) {
@@ -292,6 +312,9 @@ main(int argc, char *argv[])
"option 'b'");
}
break;
case 'D':
opt_AddDefine(optarg);
break;
case 'g':
if (strlen(optarg) == 4) {
newopt.gbgfx[0] = optarg[1];
@@ -304,7 +327,7 @@ main(int argc, char *argv[])
}
break;
case 'h':
haltnop = false;
newopt.haltnop = false;
break;
case 'i':
fstk_AddIncludePath(optarg);
@@ -326,7 +349,7 @@ main(int argc, char *argv[])
newopt.verbose = true;
break;
default:
PrintUsage();
usage();
}
}
argc -= optind;
@@ -336,6 +359,9 @@ main(int argc, char *argv[])
DefaultOptions = CurrentOptions;
if (argc == 0)
usage();
tzMainfile = argv[argc - 1];
setuplex();
@@ -354,6 +380,8 @@ main(int argc, char *argv[])
nErrors = 0;
sym_PrepPass1();
fstk_Init(tzMainfile);
opt_ParseDefines();
if (CurrentOptions.verbose) {
printf("Pass 1...\n");
}
@@ -361,8 +389,14 @@ main(int argc, char *argv[])
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
if (yyparse() == 0 && nErrors == 0) {
if (nIFDepth == 0) {
if (yyparse() != 0 || nErrors != 0) {
errx(1, "Assembly aborted in pass 1 (%ld errors)!", nErrors);
}
if (nIFDepth != 0) {
errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth);
}
nTotalLines = 0;
nLineNo = 1;
nIFDepth = 0;
@@ -374,46 +408,30 @@ main(int argc, char *argv[])
fstk_Init(tzMainfile);
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
opt_ParseDefines();
if (CurrentOptions.verbose) {
printf("Pass 2...\n");
}
if (yyparse() == 0 && nErrors == 0) {
if (yyparse() != 0 || nErrors != 0) {
errx(1, "Assembly aborted in pass 2 (%ld errors)!", nErrors);
}
double timespent;
nEndClock = clock();
timespent =
((double) (nEndClock - nStartClock))
/ (double) CLOCKS_PER_SEC;
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);
printf("Success! %ld lines in %d.%02d seconds ", nTotalLines,
(int) timespent, ((int) (timespent * 100.0)) % 100);
if (timespent == 0)
printf
("(INFINITY lines/minute)\n");
printf("(INFINITY lines/minute)\n");
else
printf("(%d lines/minute)\n",
(int) (60 / timespent *
nTotalLines));
(int) (60 / timespent * nTotalLines));
}
out_WriteObject();
} else {
printf
("Assembly aborted in pass 2 (%ld errors)!\n",
nErrors);
//sym_PrintSymbolTable();
exit(5);
}
} else {
errx(1, "Unterminated IF construct (%ld levels)!",
nIFDepth);
}
} else {
errx(1, "Assembly aborted in pass 1 (%ld errors)!",
nErrors);
}
return 0;
}

View File

@@ -1,14 +1,11 @@
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* INCLUDES
*
* Fixedpoint math routines
*/
#include <math.h>
#include <stdio.h>
#include "asm/types.h"
#include "types.h"
#include "asm/mymath.h"
#include "asm/symbol.h"
@@ -19,24 +16,17 @@
#endif
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Define the _PI symbol
*
*/
void
math_DefinePI(void)
{
sym_AddEqu("_PI", double2fix(PI));
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Print a fixed point value
*
*/
/*
* Print a fixed point value
*/
void
math_Print(SLONG i)
{
@@ -47,112 +37,112 @@ math_Print(SLONG i)
printf("-%ld.%05ld", (-i) >> 16,
((SLONG) (fix2double(-i) * 100000 + 0.5)) % 100000);
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate sine
*
*/
/*
* Calculate sine
*/
SLONG
math_Sin(SLONG i)
{
return (double2fix(sin(fix2double(i) * 2 * PI / 65536)));
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate cosine
*
*/
/*
* Calculate cosine
*/
SLONG
math_Cos(SLONG i)
{
return (double2fix(cos(fix2double(i) * 2 * PI / 65536)));
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate tangent
*
*/
/*
* Calculate tangent
*/
SLONG
math_Tan(SLONG i)
{
return (double2fix(tan(fix2double(i) * 2 * PI / 65536)));
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate sine^-1
*
*/
/*
* Calculate arcsine
*/
SLONG
math_ASin(SLONG i)
{
return (double2fix(asin(fix2double(i)) / 2 / PI * 65536));
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate cosine^-1
*
*/
/*
* Calculate arccosine
*/
SLONG
math_ACos(SLONG i)
{
return (double2fix(acos(fix2double(i)) / 2 / PI * 65536));
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate tangent^-1
*
*/
/*
* Calculate arctangent
*/
SLONG
math_ATan(SLONG i)
{
return (double2fix(atan(fix2double(i)) / 2 / PI * 65536));
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate atan2
*
*/
/*
* Calculate atan2
*/
SLONG
math_ATan2(SLONG i, SLONG j)
{
return (double2fix
(atan2(fix2double(i), fix2double(j)) / 2 / PI * 65536));
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Multiplication
*
*/
/*
* Multiplication
*/
SLONG
math_Mul(SLONG i, SLONG j)
{
return (double2fix(fix2double(i) * fix2double(j)));
}
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Division
*
*/
/*
* Division
*/
SLONG
math_Div(SLONG i, SLONG j)
{
return (double2fix(fix2double(i) / fix2double(j)));
}
/*
* Round
*/
SLONG
math_Round(SLONG i)
{
return double2fix(round(fix2double(i)));
}
/*
* Ceil
*/
SLONG
math_Ceil(SLONG i)
{
return double2fix(ceil(fix2double(i)));
}
/*
* Floor
*/
SLONG
math_Floor(SLONG i)
{
return double2fix(floor(fix2double(i)));
}

View File

@@ -1,8 +1,5 @@
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* INCLUDES
*
* Outputs an objectfile
*/
#include <errno.h>
@@ -22,13 +19,6 @@
#define SECTIONCHUNK 0x4000
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Internal structures
*
*/
void out_SetCurrentSection(struct Section * pSect);
struct Patch {
@@ -52,12 +42,6 @@ struct SectionStackEntry {
struct Section *pSection;
struct SectionStackEntry *pNext;
};
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* VARIABLES
*
*/
struct PatchSymbol *tHashedPatchSymbols[HASHSIZE];
struct Section *pSectionList = NULL, *pCurrentSection = NULL;
@@ -67,12 +51,8 @@ char *tzObjectname;
struct SectionStackEntry *pSectionStack = NULL;
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Section stack routines
*
*/
void
out_PushSection(void)
{
@@ -99,13 +79,10 @@ out_PopSection(void)
} else
fatalerror("No entries in the section stack");
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Count the number of symbols used in this object
*
*/
/*
* Count the number of symbols used in this object
*/
ULONG
countsymbols(void)
{
@@ -121,13 +98,10 @@ countsymbols(void)
return (count);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Count the number of sections used in this object
*
*/
/*
* Count the number of sections used in this object
*/
ULONG
countsections(void)
{
@@ -143,13 +117,10 @@ countsections(void)
return (count);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Count the number of patches used in this object
*
*/
/*
* Count the number of patches used in this object
*/
ULONG
countpatches(struct Section * pSect)
{
@@ -164,13 +135,10 @@ countpatches(struct Section * pSect)
return (r);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Write a long to a file (little-endian)
*
*/
/*
* Write a long to a file (little-endian)
*/
void
fputlong(ULONG i, FILE * f)
{
@@ -179,13 +147,10 @@ fputlong(ULONG i, FILE * f)
fputc(i >> 16, f);
fputc(i >> 24, f);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Write a NULL-terminated string to a file
*
*/
/*
* Write a NULL-terminated string to a file
*/
void
fputstring(char *s, FILE * f)
{
@@ -193,13 +158,10 @@ fputstring(char *s, FILE * f)
fputc(*s++, f);
fputc(0, f);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Return a sections ID
*
*/
/*
* Return a section's ID
*/
ULONG
getsectid(struct Section * pSect)
{
@@ -218,13 +180,10 @@ getsectid(struct Section * pSect)
fatalerror("INTERNAL: Unknown section");
return ((ULONG) - 1);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Write a patch to a file
*
*/
/*
* Write a patch to a file
*/
void
writepatch(struct Patch * pPatch, FILE * f)
{
@@ -235,13 +194,10 @@ writepatch(struct Patch * pPatch, FILE * f)
fputlong(pPatch->nRPNSize, f);
fwrite(pPatch->pRPN, 1, pPatch->nRPNSize, f);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Write a section to a file
*
*/
/*
* Write a section to a file
*/
void
writesection(struct Section * pSect, FILE * f)
{
@@ -269,13 +225,10 @@ writesection(struct Section * pSect, FILE * f)
}
}
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Write a symbol to a file
*
*/
/*
* Write a symbol to a file
*/
void
writesymbol(struct sSymbol * pSym, FILE * f)
{
@@ -319,13 +272,10 @@ writesymbol(struct sSymbol * pSym, FILE * f)
fputlong(offset, f);
}
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Add a symbol to the object
*
*/
/*
* Add a symbol to the object
*/
ULONG
addsymbol(struct sSymbol * pSym)
{
@@ -355,13 +305,10 @@ addsymbol(struct sSymbol * pSym)
return pPSym->ID;
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Add all exported symbols to the object
*
*/
/*
* Add all exported symbols to the object
*/
void
addexports(void)
{
@@ -378,13 +325,10 @@ addexports(void)
}
}
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Allocate a new patchstructure and link it into the list
*
*/
/*
* Allocate a new patchstructure and link it into the list
*/
struct Patch *
allocpatch(void)
{
@@ -401,13 +345,10 @@ allocpatch(void)
return (pPatch);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Create a new patch (includes the rpn expr)
*
*/
/*
* Create a new patch (includes the rpn expr)
*/
void
createpatch(ULONG type, struct Expression * expr)
{
@@ -445,7 +386,10 @@ createpatch(ULONG type, struct Expression * expr)
rpnexpr[rpnptr++] = value >> 16;
rpnexpr[rpnptr++] = value >> 24;
} else {
symptr = addsymbol(sym_FindSymbol(tzSym));
struct sSymbol *sym;
if ((sym = sym_FindSymbol(tzSym)) == NULL)
break;
symptr = addsymbol(sym);
rpnexpr[rpnptr++] = RPN_SYM;
rpnexpr[rpnptr++] = symptr & 0xFF;
rpnexpr[rpnptr++] = symptr >> 8;
@@ -453,15 +397,19 @@ createpatch(ULONG type, struct Expression * expr)
rpnexpr[rpnptr++] = symptr >> 24;
}
break;
case RPN_BANK:
case RPN_BANK: {
struct sSymbol *sym;
symptr = 0;
while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0);
symptr = addsymbol(sym_FindSymbol(tzSym));
if ((sym = sym_FindSymbol(tzSym)) == NULL)
break;
symptr = addsymbol(sym);
rpnexpr[rpnptr++] = RPN_BANK;
rpnexpr[rpnptr++] = symptr & 0xFF;
rpnexpr[rpnptr++] = symptr >> 8;
rpnexpr[rpnptr++] = symptr >> 16;
rpnexpr[rpnptr++] = symptr >> 24;
}
break;
default:
rpnexpr[rpnptr++] = rpndata;
@@ -473,13 +421,10 @@ createpatch(ULONG type, struct Expression * expr)
pPatch->nRPNSize = rpnptr;
}
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* A quick check to see if we have an initialized section
*
*/
/*
* A quick check to see if we have an initialized section
*/
void
checksection(void)
{
@@ -488,14 +433,11 @@ checksection(void)
else
fatalerror("Code generation before SECTION directive");
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* A quick check to see if we have an initialized section that can contain
* this much initialized data
*
*/
void
checkcodesection(SLONG size)
{
@@ -505,32 +447,35 @@ checkcodesection(SLONG size)
errx(1, "Section '%s' cannot contain code or data (not a "
"ROM0 or ROMX)", pCurrentSection->pzName);
}
if (pCurrentSection->nPC + size <= MAXSECTIONSIZE) {
if (pCurrentSection->nPC + size > MAXSECTIONSIZE) {
/*
* N.B.: This check is not sufficient to ensure the section
* will fit, because there can be multiple sections of this
* type. The definitive check must be done at the linking
* stage.
*/
errx(1, "Section '%s' is too big (old size %d + %d > %d)",
pCurrentSection->pzName, pCurrentSection->nPC, size,
MAXSECTIONSIZE);
}
if (((pCurrentSection->nPC % SECTIONCHUNK) >
((pCurrentSection->nPC + size) % SECTIONCHUNK))
&& (pCurrentSection->nType == SECT_ROM0
|| pCurrentSection->nType == SECT_ROMX)) {
if ((pCurrentSection->tData =
(UBYTE *) realloc(pCurrentSection->tData,
((pCurrentSection->nPC +
size) / SECTIONCHUNK +
1) * SECTIONCHUNK)) != NULL) {
return;
} else
fatalerror
("Not enough memory to expand section");
((pCurrentSection->nPC + size) % SECTIONCHUNK)) &&
(pCurrentSection->nType == SECT_ROM0 ||
pCurrentSection->nType == SECT_ROMX)) {
pCurrentSection->tData = realloc(pCurrentSection->tData,
((pCurrentSection->nPC + size) / SECTIONCHUNK + 1) *
SECTIONCHUNK);
if (pCurrentSection->tData == NULL) {
err(1, "Could not expand section");
}
}
return;
} else
errx(1, "Section '%s' is too big", pCurrentSection->pzName);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Write an objectfile
*
*/
/*
* Write an objectfile
*/
void
out_WriteObject(void)
{
@@ -561,13 +506,10 @@ out_WriteObject(void)
fclose(f);
}
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Prepare for pass #2
*
*/
/*
* Prepare for pass #2
*/
void
out_PrepPass2(void)
{
@@ -581,13 +523,10 @@ out_PrepPass2(void)
pCurrentSection = NULL;
pSectionStack = NULL;
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Set the objectfilename
*
*/
/*
* Set the objectfilename
*/
void
out_SetFileName(char *s)
{
@@ -599,16 +538,12 @@ out_SetFileName(char *s)
pCurrentSection = NULL;
pPatchSymbols = NULL;
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Find a section by name and type. If it doesn't exist, create it
*
*/
/*
* Find a section by name and type. If it doesn't exist, create it
*/
struct Section *
out_FindSection(char *pzName, ULONG secttype, SLONG org,
SLONG bank)
out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
{
struct Section *pSect, **ppSect;
@@ -652,13 +587,10 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org,
return (NULL);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Set the current section
*
*/
/*
* Set the current section
*/
void
out_SetCurrentSection(struct Section * pSect)
{
@@ -668,37 +600,28 @@ out_SetCurrentSection(struct Section * pSect)
pPCSymbol->nValue = nPC;
pPCSymbol->pSection = pCurrentSection;
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Set the current section by name and type
*
*/
/*
* Set the current section by name and type
*/
void
out_NewSection(char *pzName, ULONG secttype)
{
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1));
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Set the current section by name and type
*
*/
/*
* Set the current section by name and type
*/
void
out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
{
out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank));
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output an absolute byte
*
*/
/*
* Output an absolute byte
*/
void
out_AbsByte(int b)
{
@@ -719,13 +642,10 @@ out_AbsByteGroup(char *s, int length)
while (length--)
out_AbsByte(*s++);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Skip this many bytes
*
*/
/*
* Skip this many bytes
*/
void
out_Skip(int skip)
{
@@ -741,13 +661,10 @@ out_Skip(int skip)
out_AbsByte(CurrentOptions.fillchar);
}
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a NULL terminated string (excluding the NULL-character)
*
*/
/*
* Output a NULL terminated string (excluding the NULL-character)
*/
void
out_String(char *s)
{
@@ -755,12 +672,10 @@ out_String(char *s)
while (*s)
out_AbsByte(*s++);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a relocatable byte. Checking will be done to see if it
* is an absolute value in disguise.
*
*/
void
@@ -780,13 +695,10 @@ out_RelByte(struct Expression * expr)
rpn_Reset(expr);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output an absolute word
*
*/
/*
* Output an absolute word
*/
void
out_AbsWord(int b)
{
@@ -800,14 +712,11 @@ out_AbsWord(int b)
nPC += 2;
pPCSymbol->nValue += 2;
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a relocatable word. Checking will be done to see if
* is an absolute value in disguise.
*
*/
/*
* Output a relocatable word. Checking will be done to see if
* it's an absolute value in disguise.
*/
void
out_RelWord(struct Expression * expr)
{
@@ -828,13 +737,10 @@ out_RelWord(struct Expression * expr)
out_AbsWord(expr->nVal);
rpn_Reset(expr);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output an absolute longword
*
*/
/*
* Output an absolute longword
*/
void
out_AbsLong(SLONG b)
{
@@ -849,14 +755,11 @@ out_AbsLong(SLONG b)
nPC += 4;
pPCSymbol->nValue += 4;
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a relocatable longword. Checking will be done to see if
* is an absolute value in disguise.
*
*/
void
out_RelLong(struct Expression * expr)
{
@@ -879,13 +782,10 @@ out_RelLong(struct Expression * expr)
out_AbsLong(expr->nVal);
rpn_Reset(expr);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a PC-relative byte
*
*/
/*
* Output a PC-relative byte
*/
void
out_PCRelByte(struct Expression * expr)
{
@@ -899,13 +799,10 @@ out_PCRelByte(struct Expression * expr)
out_AbsByte(b);
rpn_Reset(expr);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a binary file
*
*/
/*
* Output a binary file
*/
void
out_BinaryFile(char *s)
{

View File

@@ -1,4 +1,4 @@
.Dd $Mdocdate$
.Dd February 26, 2015
.Dt RGBASM 1
.Os RGBDS Manual
.Sh NAME
@@ -6,9 +6,9 @@
.Nd Game Boy assembler
.Sh SYNOPSIS
.Nm rgbasm
.Op Fl v
.Op Fl h
.Op Fl hv
.Op Fl b Ar chars
.Op Fl D Ar name Ns Op = Ns Ar value
.Op Fl g Ar chars
.Op Fl i Ar path
.Op Fl o Ar outfile
@@ -23,6 +23,12 @@ Its arguments are as follows:
.It Fl b Ar chars
Change the two characters used for binary constants.
The defaults are 01.
.It Fl D Ar name Ns Op = Ns Ar value
Add string symbol to the compiled source code. This is equivalent to
.Ar name
.Cm EQUS
.Qq Ar "value"
in code. If a value is not specified, a value of 1 is given.
.It Fl g Ar chars
Change the four characters used for binary constants.
The defaults are 0123.
@@ -50,7 +56,7 @@ Be verbose.
.Sh EXAMPLES
Assembling a basic source file is simple:
.Pp
.D1 $ rgbasm \-o bar.o foo.asm
.D1 $ rgbasm -o bar.o foo.asm
.Pp
The resulting object file is not yet a usable ROM image \(em it must first be
run through
@@ -58,10 +64,9 @@ run through
and
.Xr rgbfix 1 .
.Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbfix 1 ,
.Xr rgblink 1 ,
.Xr gbz80 7
.Xr rgbds 7
.Sh HISTORY
.Nm
was originally written by Carsten S\(/orensen as part of the ASMotor package,

View File

@@ -1,15 +1,12 @@
/*
* RGBAsm - RPN.C - Controls RPN expressions for objectfiles
*
* INCLUDES
*
* Controls RPN expressions for objectfiles
*/
#include <stdio.h>
#include <string.h>
#include "asm/mylink.h"
#include "asm/types.h"
#include "types.h"
#include "asm/symbol.h"
#include "asm/asm.h"
#include "asm/main.h"
@@ -29,49 +26,26 @@ mergetwoexpressions(struct Expression * expr, struct Expression * src1,
#define joinexpr() mergetwoexpressions(expr,src1,src2)
/*
* RGBAsm - RPN.C - Controls RPN expressions for objectfiles
*
* VARIABLES
*
*/
//UBYTE rpnexpr[2048];
//ULONG rpnptr = 0;
//ULONG rpnoutptr = 0;
//ULONG reloc = 0;
//ULONG pcrel = 0;
/*
* RGBAsm - RPN.C - Controls RPN expressions for objectfiles
*
* Add a byte to the RPN expression
*
*/
void
pushbyte(struct Expression * expr, int b)
{
expr->tRPN[expr->nRPNLength++] = b & 0xFF;
}
/*
* RGBAsm - RPN.C - Controls RPN expressions for objectfiles
*
* Reset the RPN module
*
*/
/*
* Reset the RPN module
*/
void
rpn_Reset(struct Expression * expr)
{
expr->nRPNLength = expr->nRPNOut = expr->isReloc = expr->isPCRel = 0;
}
/*
* RGBAsm - RPN.C - Controls RPN expressions for objectfiles
*
* Returns the next rpn byte in expression
*
*/
/*
* Returns the next rpn byte in expression
*/
UWORD
rpn_PopByte(struct Expression * expr)
{
@@ -80,37 +54,28 @@ rpn_PopByte(struct Expression * expr)
} else
return (expr->tRPN[expr->nRPNOut++]);
}
/*
* RGBAsm - RPN.C - Controls RPN expressions for objectfiles
*
* Determine if the current expression is relocatable
*
*/
/*
* Determine if the current expression is relocatable
*/
ULONG
rpn_isReloc(struct Expression * expr)
{
return (expr->isReloc);
}
/*
* RGBAsm - RPN.C - Controls RPN expressions for objectfiles
*
* Determine if the current expression can be pc-relative
*
*/
/*
* Determine if the current expression can be pc-relative
*/
ULONG
rpn_isPCRelative(struct Expression * expr)
{
return (expr->isPCRel);
}
/*
* RGBAsm - RPN.C - Controls RPN expressions for objectfiles
*
* Add symbols, constants and operators to expression
*
*/
/*
* Add symbols, constants and operators to expression
*/
void
rpn_Number(struct Expression * expr, ULONG i)
{
@@ -187,6 +152,7 @@ rpn_RangeCheck(struct Expression * expr, struct Expression * src, SLONG low,
return (expr->nVal >= low && expr->nVal <= high);
}
}
void
rpn_CheckHRAM(struct Expression * expr, struct Expression * src)
{

View File

@@ -1,11 +1,7 @@
/*
* RGBAsm - SYMBOL.C - Symboltable and macroargs stuff
*
* INCLUDES
*
* Symboltable and macroargs stuff
*/
#define _XOPEN_SOURCE 500
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -17,13 +13,6 @@
#include "asm/mymath.h"
#include "asm/output.h"
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* VARIABLES
*
*/
struct sSymbol *tHashedSymbols[HASHSIZE];
struct sSymbol *pScope = NULL;
struct sSymbol *pPCSymbol = NULL;
@@ -38,7 +27,6 @@ Callback_NARG(struct sSymbol * sym)
{
ULONG i = 0;
sym = sym;
while (currentmacroargs[i] && i < MAXMACROARGS)
i += 1;
@@ -46,12 +34,8 @@ Callback_NARG(struct sSymbol * sym)
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Get the nValue field of a symbol
*
*/
SLONG
getvaluefield(struct sSymbol * sym)
{
@@ -60,13 +44,10 @@ getvaluefield(struct sSymbol * sym)
} else
return (sym->nValue);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Calculate the hash value for a string
*
*/
/*
* Calculate the hash value for a string
*/
ULONG
calchash(char *s)
{
@@ -77,13 +58,10 @@ calchash(char *s)
return (hash % HASHSIZE);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Create a new symbol by name
*
*/
/*
* Create a new symbol by name
*/
struct sSymbol *
createsymbol(char *s)
{
@@ -112,12 +90,8 @@ createsymbol(char *s)
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find a symbol by name and scope
*
*/
struct sSymbol *
findsymbol(char *s, struct sSymbol * scope)
{
@@ -136,13 +110,10 @@ findsymbol(char *s, struct sSymbol * scope)
}
return (NULL);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find the pointer to a symbol by name and scope
*
*/
/*
* Find the pointer to a symbol by name and scope
*/
struct sSymbol **
findpsymbol(char *s, struct sSymbol * scope)
{
@@ -161,13 +132,10 @@ findpsymbol(char *s, struct sSymbol * scope)
}
return (NULL);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find a symbol by name and scope
*
*/
/*
* Find a symbol by name and scope
*/
struct sSymbol *
sym_FindSymbol(char *tzName)
{
@@ -180,13 +148,10 @@ sym_FindSymbol(char *tzName)
return (findsymbol(tzName, pscope));
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Purge a symbol
*
*/
/*
* Purge a symbol
*/
void
sym_Purge(char *tzName)
{
@@ -214,13 +179,10 @@ sym_Purge(char *tzName)
yyerror("'%s' not defined", tzName);
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Determine if a symbol has been defined
*
*/
/*
* Determine if a symbol has been defined
*/
ULONG
sym_isConstDefined(char *tzName)
{
@@ -262,13 +224,10 @@ sym_isDefined(char *tzName)
else
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Determine if the symbol is a constant
*
*/
/*
* Determine if the symbol is a constant
*/
ULONG
sym_isConstant(char *s)
{
@@ -285,13 +244,10 @@ sym_isConstant(char *s)
}
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Get a string equate's value
*
*/
/*
* Get a string equate's value
*/
char *
sym_GetStringValue(char *tzSym)
{
@@ -305,13 +261,10 @@ sym_GetStringValue(char *tzSym)
return (NULL);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Return a constant symbols value
*
*/
/*
* Return a constant symbols value
*/
ULONG
sym_GetConstantValue(char *s)
{
@@ -334,13 +287,10 @@ sym_GetConstantValue(char *s)
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Return a symbols value... "estimated" if not defined yet
*
*/
/*
* Return a symbols value... "estimated" if not defined yet
*/
ULONG
sym_GetValue(char *s)
{
@@ -376,13 +326,10 @@ sym_GetValue(char *s)
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Return a defined symbols value... aborts if not defined yet
*
*/
/*
* Return a defined symbols value... aborts if not defined yet
*/
ULONG
sym_GetDefinedValue(char *s)
{
@@ -408,13 +355,10 @@ sym_GetDefinedValue(char *s)
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Macro argument stuff
*
*/
/*
* Macro argument stuff
*/
void
sym_ShiftCurrentMacroArgs(void)
{
@@ -492,7 +436,7 @@ sym_AddNewMacroArg(char *s)
else
newmacroargs[i] = NULL;
} else
yyerror("A maximum of 9 arguments allowed");
yyerror("A maximum of %d arguments allowed", MAXMACROARGS);
}
void
@@ -512,25 +456,19 @@ sym_UseCurrentMacroArgs(void)
for (i = 1; i <= MAXMACROARGS; i += 1)
sym_AddNewMacroArg(sym_FindMacroArg(i));
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find a macro by name
*
*/
/*
* Find a macro by name
*/
struct sSymbol *
sym_FindMacro(char *s)
{
return (findsymbol(s, NULL));
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add an equated symbol
*
*/
/*
* Add an equated symbol
*/
void
sym_AddEqu(char *tzSym, SLONG value)
{
@@ -553,13 +491,10 @@ sym_AddEqu(char *tzSym, SLONG value)
}
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a string equated symbol
*
*/
/*
* Add a string equated symbol
*/
void
sym_AddString(char *tzSym, char *tzValue)
{
@@ -582,13 +517,10 @@ sym_AddString(char *tzSym, char *tzValue)
nsym->pScope = NULL;
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* check if symbol is a string equated symbol
*
*/
/*
* check if symbol is a string equated symbol
*/
ULONG
sym_isString(char *tzSym)
{
@@ -600,13 +532,10 @@ sym_isString(char *tzSym)
}
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Alter a SET symbols value
*
*/
/*
* Alter a SET symbols value
*/
void
sym_AddSet(char *tzSym, SLONG value)
{
@@ -622,13 +551,10 @@ sym_AddSet(char *tzSym, SLONG value)
nsym->pScope = NULL;
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a local (.name) relocatable symbol
*
*/
/*
* Add a local (.name) relocatable symbol
*/
void
sym_AddLocalReloc(char *tzSym)
{
@@ -656,13 +582,10 @@ sym_AddLocalReloc(char *tzSym)
fatalerror("Local label in main scope");
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a relocatable symbol
*
*/
/*
* Add a relocatable symbol
*/
void
sym_AddReloc(char *tzSym)
{
@@ -686,15 +609,11 @@ sym_AddReloc(char *tzSym)
}
}
pScope = findsymbol(tzSym, NULL);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Export a symbol
*
*/
/*
* Export a symbol
*/
void
sym_Export(char *tzSym)
{
@@ -718,13 +637,10 @@ sym_Export(char *tzSym)
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Import a symbol
*
*/
/*
* Import a symbol
*/
void
sym_Import(char *tzSym)
{
@@ -739,13 +655,10 @@ sym_Import(char *tzSym)
nsym->nType |= SYMF_IMPORT;
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Globalize a symbol (export if defined, import if not)
*
*/
/*
* Globalize a symbol (export if defined, import if not)
*/
void
sym_Global(char *tzSym)
{
@@ -767,13 +680,10 @@ sym_Global(char *tzSym)
}
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a macro definition
*
*/
/*
* Add a macro definition
*/
void
sym_AddMacro(char *tzSym)
{
@@ -798,25 +708,19 @@ sym_AddMacro(char *tzSym)
}
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Prepare for pass #1
*
*/
/*
* Prepare for pass #1
*/
void
sym_PrepPass1(void)
{
sym_Init();
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Prepare for pass #2
*
*/
/*
* Prepare for pass #2
*/
void
sym_PrepPass2(void)
{
@@ -847,14 +751,13 @@ sym_PrepPass2(void)
sym_AddEqu("_NARG", 0);
p_NARGSymbol = findsymbol("_NARG", NULL);
p_NARGSymbol->Callback = Callback_NARG;
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Initialise the symboltable
*
*/
math_DefinePI();
}
/*
* Initialize the symboltable
*/
void
sym_Init(void)
{
@@ -891,72 +794,3 @@ sym_Init(void)
math_DefinePI();
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* DEBUG: Print the symbol table
*
*/
void
sym_PrintSymbolTable(void)
{
ULONG i;
for (i = 0; i < HASHSIZE; i += 1) {
struct sSymbol *sym = tHashedSymbols[i];
if (sym != NULL)
printf("\nHashTable #%ld:\n", i);
while (sym != NULL) {
if (sym->nType & SYMF_LOCAL)
printf("LOCAL : '%s%s' - %08lX\n",
sym->pScope->tzName, sym->tzName,
getvaluefield(sym));
else if (sym->nType & (SYMF_MACRO | SYMF_STRING)) {
ULONG i = 0;
printf("MACRO : '%s'\n\"", sym->tzName);
while (i < sym->ulMacroSize) {
if (sym->pMacro[i] == '\n') {
printf("\n");
i += 1;
} else
printf("%c", sym->pMacro[i++]);
}
printf("\"\n");
} else if (sym->nType & SYMF_EXPORT)
printf("EXPORT: '%s' - %08lX\n", sym->tzName,
getvaluefield(sym));
else if (sym->nType & SYMF_IMPORT)
printf("IMPORT: '%s'\n", sym->tzName);
else if (sym->nType & SYMF_EQU)
printf("EQU : '%s' - %08lX\n", sym->tzName,
getvaluefield(sym));
else if (sym->nType & SYMF_SET)
printf("SET : '%s' - %08lX\n", sym->tzName,
getvaluefield(sym));
else
printf("SYMBOL: '%s' - %08lX\n", sym->tzName,
getvaluefield(sym));
sym = sym->pNext;
}
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* DEBUG: Dump the macroargs
*
*/
void
sym_DumpMacroArgs(void)
{
ULONG i;
for (i = 0; i < MAXMACROARGS; i += 1)
printf("CurrentArg%ld: %s\n", i + 1, currentmacroargs[i]);
}

View File

@@ -1,454 +0,0 @@
%{
#define _XOPEN_SOURCE 500
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "asm/symbol.h"
#include "asm/asm.h"
#include "asm/charmap.h"
#include "asm/output.h"
#include "asm/mylink.h"
#include "asm/fstack.h"
#include "asm/mymath.h"
#include "asm/rpn.h"
#include "asm/main.h"
#include "asm/lexer.h"
extern bool haltnop;
char *tzNewMacro;
ULONG ulNewMacroSize;
size_t symvaluetostring(char *dest, size_t maxLength, char *sym)
{
size_t length;
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 )
{
ULONG r=0;
while( *s )
{
r<<=8;
r|=(UBYTE)(*s++);
}
return( r );
}
ULONG str2int2( char *s, int length )
{
int i;
ULONG r=0;
i = (length - 4 < 0 ? 0 : length - 4);
while(i < length)
{
r<<=8;
r|=(UBYTE)(s[i]);
i++;
}
return( r );
}
ULONG isWhiteSpace( char s )
{
return( s==' ' || s=='\t' || s=='\0' || s=='\n' );
}
ULONG isRept( char *s )
{
return( (strncasecmp(s,"REPT",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}
ULONG isEndr( char *s )
{
return( (strncasecmp(s,"Endr",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}
void copyrept( void )
{
SLONG level=1, len, instring=0;
char *src=pCurrentBuffer->pBuffer;
while( *src && level )
{
if( instring==0 )
{
if( isRept(src) )
{
level+=1;
src+=4;
}
else if( isEndr(src) )
{
level-=1;
src+=4;
}
else
{
if( *src=='\"' )
instring=1;
src+=1;
}
}
else
{
if( *src=='\\' )
{
src+=2;
}
else if( *src=='\"' )
{
src+=1;
instring=0;
}
else
{
src+=1;
}
}
}
len=src-pCurrentBuffer->pBuffer-4;
src=pCurrentBuffer->pBuffer;
ulNewMacroSize=len;
if ((tzNewMacro = malloc(ulNewMacroSize + 1)) != NULL) {
ULONG i;
tzNewMacro[ulNewMacroSize]=0;
for( i=0; i<ulNewMacroSize; i+=1 )
{
if( (tzNewMacro[i]=src[i])=='\n' )
nLineNo+=1;
}
} else
fatalerror( "No mem for REPT block" );
yyskipbytes( ulNewMacroSize+4 );
}
ULONG isMacro( char *s )
{
return( (strncasecmp(s,"MACRO",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[5]) );
}
ULONG isEndm( char *s )
{
return( (strncasecmp(s,"Endm",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}
void copymacro( void )
{
SLONG level=1, len, instring=0;
char *src=pCurrentBuffer->pBuffer;
while( *src && level )
{
if( instring==0 )
{
if( isMacro(src) )
{
level+=1;
src+=4;
}
else if( isEndm(src) )
{
level-=1;
src+=4;
}
else
{
if( *src=='\"' )
instring=1;
src+=1;
}
}
else
{
if( *src=='\\' )
{
src+=2;
}
else if( *src=='\"' )
{
src+=1;
instring=0;
}
else
{
src+=1;
}
}
}
len=src-pCurrentBuffer->pBuffer-4;
src=pCurrentBuffer->pBuffer;
ulNewMacroSize=len;
if( (tzNewMacro=(char *)malloc(ulNewMacroSize+2))!=NULL )
{
ULONG i;
tzNewMacro[ulNewMacroSize]='\n';
tzNewMacro[ulNewMacroSize+1]=0;
for( i=0; i<ulNewMacroSize; i+=1 )
{
if( (tzNewMacro[i]=src[i])=='\n' )
nLineNo+=1;
}
}
else
fatalerror( "No mem for MACRO definition" );
yyskipbytes( ulNewMacroSize+4 );
}
ULONG isIf( char *s )
{
return( (strncasecmp(s,"If",2)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[2]) );
}
ULONG isElse( char *s )
{
return( (strncasecmp(s,"Else",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}
ULONG isEndc( char *s )
{
return( (strncasecmp(s,"Endc",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
}
void if_skip_to_else( void )
{
SLONG level=1, len, instring=0;
char *src=pCurrentBuffer->pBuffer;
while( *src && level )
{
if( *src=='\n' )
nLineNo+=1;
if( instring==0 )
{
if( isIf(src) )
{
level+=1;
src+=2;
}
else if( level==1 && isElse(src) )
{
level-=1;
src+=4;
}
else if( isEndc(src) )
{
level-=1;
if( level!=0 )
src+=4;
}
else
{
if( *src=='\"' )
instring=1;
src+=1;
}
}
else
{
if( *src=='\\' )
{
src+=2;
}
else if( *src=='\"' )
{
src+=1;
instring=0;
}
else
{
src+=1;
}
}
}
len=src-pCurrentBuffer->pBuffer;
yyskipbytes( len );
yyunput( '\n' );
nLineNo-=1;
}
void if_skip_to_endc( void )
{
SLONG level=1, len, instring=0;
char *src=pCurrentBuffer->pBuffer;
while( *src && level )
{
if( *src=='\n' )
nLineNo+=1;
if( instring==0 )
{
if( isIf(src) )
{
level+=1;
src+=2;
}
else if( isEndc(src) )
{
level-=1;
if( level!=0 )
src+=4;
}
else
{
if( *src=='\"' )
instring=1;
src+=1;
}
}
else
{
if( *src=='\\' )
{
src+=2;
}
else if( *src=='\"' )
{
src+=1;
instring=0;
}
else
{
src+=1;
}
}
}
len=src-pCurrentBuffer->pBuffer;
yyskipbytes( len );
yyunput( '\n' );
nLineNo-=1;
}
%}
%union
{
char tzSym[MAXSYMLEN + 1];
char tzString[MAXSTRLEN + 1];
struct Expression sVal;
SLONG nConstValue;
}
%type <sVal> relocconst
%type <nConstValue> const
%type <nConstValue> const_3bit
%type <sVal> const_8bit
%type <sVal> const_16bit
%type <sVal> const_PCrel
%type <nConstValue> sectiontype
%type <tzString> string
%token <nConstValue> T_NUMBER
%token <tzString> T_STRING
%left T_OP_LOGICNOT
%left T_OP_LOGICOR T_OP_LOGICAND T_OP_LOGICEQU
%left T_OP_LOGICGT T_OP_LOGICLT T_OP_LOGICGE T_OP_LOGICLE T_OP_LOGICNE
%left T_OP_ADD T_OP_SUB
%left T_OP_OR T_OP_XOR T_OP_AND
%left T_OP_SHL T_OP_SHR
%left T_OP_MUL T_OP_DIV T_OP_MOD
%left T_OP_NOT
%left T_OP_DEF
%left T_OP_BANK
%left T_OP_SIN
%left T_OP_COS
%left T_OP_TAN
%left T_OP_ASIN
%left T_OP_ACOS
%left T_OP_ATAN
%left T_OP_ATAN2
%left T_OP_FDIV
%left T_OP_FMUL
%left T_OP_STRCMP
%left T_OP_STRIN
%left T_OP_STRSUB
%left T_OP_STRLEN
%left T_OP_STRCAT
%left T_OP_STRUPR
%left T_OP_STRLWR
%left NEG /* negation--unary minus */
%token <tzSym> T_LABEL
%token <tzSym> T_ID
%token <tzSym> T_POP_EQU
%token <tzSym> T_POP_SET
%token <tzSym> T_POP_EQUS
%token T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_IF T_POP_ELSE T_POP_ENDC
%token T_POP_IMPORT T_POP_EXPORT T_POP_GLOBAL
%token T_POP_DB T_POP_DS T_POP_DW T_POP_DL
%token T_POP_SECTION
%token T_POP_RB
%token T_POP_RW
%token T_POP_RL
%token T_POP_MACRO
%token T_POP_ENDM
%token T_POP_RSRESET T_POP_RSSET
%token T_POP_INCBIN T_POP_REPT
%token T_POP_CHARMAP
%token T_POP_SHIFT
%token T_POP_ENDR
%token T_POP_FAIL
%token T_POP_WARN
%token T_POP_PURGE
%token T_POP_POPS
%token T_POP_PUSHS
%token T_POP_POPO
%token T_POP_PUSHO
%token T_POP_OPT

View File

@@ -1,552 +0,0 @@
%start asmfile
%%
asmfile : lines lastline
;
lastline : /* empty */
| line
{ nLineNo+=1; nTotalLines+=1; }
;
lines : /* empty */
| lines line '\n'
{ nLineNo+=1; nTotalLines+=1; }
;
line : /* empty */
| label
| label cpu_command
| label macro
| label simple_pseudoop
| pseudoop
;
label : /* empty */
| T_LABEL { if( $1[0]=='.' )
sym_AddLocalReloc($1);
else
sym_AddReloc($1);
}
| T_LABEL ':' { if( $1[0]=='.' )
sym_AddLocalReloc($1);
else
sym_AddReloc($1);
}
| T_LABEL ':' ':' { sym_AddReloc($1); sym_Export($1); }
;
macro : T_ID
{
yy_set_state( LEX_STATE_MACROARGS );
}
macroargs
{
yy_set_state( LEX_STATE_NORMAL );
if( !fstk_RunMacro($1) )
{
yyerror("Macro '%s' not defined", $1);
}
}
;
macroargs : /* empty */
| macroarg
| macroarg ',' macroargs
;
macroarg : T_STRING
{ sym_AddNewMacroArg( $1 ); }
;
pseudoop : equ
| set
| rb
| rw
| rl
| equs
| macrodef
;
simple_pseudoop : include
| printf
| printt
| printv
| if
| else
| endc
| import
| export
| global
| db
| dw
| dl
| ds
| section
| rsreset
| rsset
| incbin
| charmap
| rept
| shift
| fail
| warn
| purge
| pops
| pushs
| popo
| pusho
| opt
;
opt : T_POP_OPT
{
yy_set_state( LEX_STATE_MACROARGS );
}
opt_list
{
yy_set_state( LEX_STATE_NORMAL );
}
;
opt_list : opt_list_entry
| opt_list_entry ',' opt_list
;
opt_list_entry : T_STRING
{
opt_Parse($1);
}
;
popo : T_POP_POPO
{ opt_Pop(); }
;
pusho : T_POP_PUSHO
{ opt_Push(); }
;
pops : T_POP_POPS
{ out_PopSection(); }
;
pushs : T_POP_PUSHS
{ out_PushSection(); }
;
fail : T_POP_FAIL string
{ fatalerror("%s", $2); }
;
warn : T_POP_WARN string
{ yyerror("%s", $2); }
;
shift : T_POP_SHIFT
{ sym_ShiftCurrentMacroArgs(); }
;
rept : T_POP_REPT const
{
copyrept();
fstk_RunRept( $2 );
}
;
macrodef : T_LABEL ':' T_POP_MACRO
{
copymacro();
sym_AddMacro($1);
}
;
equs : T_LABEL T_POP_EQUS string
{ sym_AddString( $1, $3 ); }
;
rsset : T_POP_RSSET const
{ sym_AddSet( "_RS", $2 ); }
;
rsreset : T_POP_RSRESET
{ sym_AddSet( "_RS", 0 ); }
;
rl : T_LABEL T_POP_RL const
{
sym_AddEqu( $1, sym_GetConstantValue("_RS") );
sym_AddSet( "_RS", sym_GetConstantValue("_RS")+4*$3 );
}
;
rw : T_LABEL T_POP_RW const
{
sym_AddEqu( $1, sym_GetConstantValue("_RS") );
sym_AddSet( "_RS", sym_GetConstantValue("_RS")+2*$3 );
}
;
rb : T_LABEL T_POP_RB const
{
sym_AddEqu( $1, sym_GetConstantValue("_RS") );
sym_AddSet( "_RS", sym_GetConstantValue("_RS")+$3 );
}
;
ds : T_POP_DS const
{ out_Skip( $2 ); }
;
db : T_POP_DB constlist_8bit
;
dw : T_POP_DW constlist_16bit
;
dl : T_POP_DL constlist_32bit
;
purge : T_POP_PURGE
{
oDontExpandStrings=1;
}
purge_list
{
oDontExpandStrings=0;
}
;
purge_list : purge_list_entry
| purge_list_entry ',' purge_list
;
purge_list_entry : T_ID { sym_Purge($1); }
;
import : T_POP_IMPORT import_list
;
import_list : import_list_entry
| import_list_entry ',' import_list
;
import_list_entry : T_ID { sym_Import($1); }
;
export : T_POP_EXPORT export_list
;
export_list : export_list_entry
| export_list_entry ',' export_list
;
export_list_entry : T_ID { sym_Export($1); }
;
global : T_POP_GLOBAL global_list
;
global_list : global_list_entry
| global_list_entry ',' global_list
;
global_list_entry : T_ID { sym_Global($1); }
;
equ : T_LABEL T_POP_EQU const
{ sym_AddEqu( $1, $3 ); }
;
set : T_LABEL T_POP_SET const
{ sym_AddSet( $1, $3 ); }
;
include : T_POP_INCLUDE string
{
fstk_RunInclude($2);
}
;
incbin : T_POP_INCBIN string
{ out_BinaryFile( $2 ); }
| T_POP_INCBIN string ',' const ',' const
{
out_BinaryFileSlice( $2, $4, $6 );
}
;
charmap : T_POP_CHARMAP string ',' string
{
if(charmap_Add($2, $4[0] & 0xFF) == -1)
{
fprintf(stderr, "Error parsing charmap. Either you've added too many (%i), or the input character length is too long (%i)' : %s\n", MAXCHARMAPS, CHARMAPLENGTH, strerror(errno));
yyerror("Error parsing charmap.");
}
}
| T_POP_CHARMAP string ',' const
{
if(charmap_Add($2, $4 & 0xFF) == -1)
{
fprintf(stderr, "Error parsing charmap. Either you've added too many (%i), or the input character length is too long (%i)' : %s\n", MAXCHARMAPS, CHARMAPLENGTH, strerror(errno));
yyerror("Error parsing charmap.");
}
}
;
printt : T_POP_PRINTT string
{
if( nPass==1 )
printf( "%s", $2 );
}
;
printv : T_POP_PRINTV const
{
if( nPass==1 )
printf( "$%lX", $2 );
}
;
printf : T_POP_PRINTF const
{
if( nPass==1 )
math_Print( $2 );
}
;
if : T_POP_IF const
{
nIFDepth+=1;
if( !$2 )
{
if_skip_to_else(); /* will continue parsing just after ELSE or just at ENDC keyword */
}
}
else : T_POP_ELSE
{
if_skip_to_endc(); /* will continue parsing just at ENDC keyword */
}
;
endc : T_POP_ENDC
{
nIFDepth-=1;
}
;
const_3bit : const
{
if( ($1<0) || ($1>7) )
{
yyerror("Immediate value must be 3-bit");
}
else
$$=$1&0x7;
}
;
constlist_8bit : constlist_8bit_entry
| constlist_8bit_entry ',' constlist_8bit
;
constlist_8bit_entry : { out_Skip( 1 ); }
| const_8bit { out_RelByte( &$1 ); }
| string { char *s; int length; s = $1; length = charmap_Convert(&s); out_AbsByteGroup(s, length); free(s); }
;
constlist_16bit : constlist_16bit_entry
| constlist_16bit_entry ',' constlist_16bit
;
constlist_16bit_entry : { out_Skip( 2 ); }
| const_16bit { out_RelWord( &$1 ); }
;
constlist_32bit : constlist_32bit_entry
| constlist_32bit_entry ',' constlist_32bit
;
constlist_32bit_entry : { out_Skip( 4 ); }
| relocconst { out_RelLong( &$1 ); }
;
const_PCrel : relocconst
{
$$ = $1;
if( !rpn_isPCRelative(&$1) )
yyerror("Expression must be PC-relative");
}
;
const_8bit : relocconst
{
if( (!rpn_isReloc(&$1)) && (($1.nVal<-128) || ($1.nVal>255)) )
{
yyerror("Expression must be 8-bit");
}
$$=$1;
}
;
const_16bit : relocconst
{
if( (!rpn_isReloc(&$1)) && (($1.nVal<-32768) || ($1.nVal>65535)) )
{
yyerror("Expression must be 16-bit");
}
$$=$1;
}
;
relocconst : T_ID
{ rpn_Symbol(&$$,$1); $$.nVal = sym_GetValue($1); }
| T_NUMBER
{ rpn_Number(&$$,$1); $$.nVal = $1; }
| string
{ char *s; int length; ULONG r; s = $1; length = charmap_Convert(&s); r = str2int2(s, length); free(s); rpn_Number(&$$,r); $$.nVal=r; }
| T_OP_LOGICNOT relocconst %prec NEG
{ rpn_LOGNOT(&$$,&$2); }
| relocconst T_OP_LOGICOR relocconst
{ rpn_LOGOR(&$$,&$1,&$3); }
| relocconst T_OP_LOGICAND relocconst
{ rpn_LOGAND(&$$,&$1,&$3); }
| relocconst T_OP_LOGICEQU relocconst
{ rpn_LOGEQU(&$$,&$1,&$3); }
| relocconst T_OP_LOGICGT relocconst
{ rpn_LOGGT(&$$,&$1,&$3); }
| relocconst T_OP_LOGICLT relocconst
{ rpn_LOGLT(&$$,&$1,&$3); }
| relocconst T_OP_LOGICGE relocconst
{ rpn_LOGGE(&$$,&$1,&$3); }
| relocconst T_OP_LOGICLE relocconst
{ rpn_LOGLE(&$$,&$1,&$3); }
| relocconst T_OP_LOGICNE relocconst
{ rpn_LOGNE(&$$,&$1,&$3); }
| relocconst T_OP_ADD relocconst
{ rpn_ADD(&$$,&$1,&$3); }
| relocconst T_OP_SUB relocconst
{ rpn_SUB(&$$,&$1,&$3); }
| relocconst T_OP_XOR relocconst
{ rpn_XOR(&$$,&$1,&$3); }
| relocconst T_OP_OR relocconst
{ rpn_OR(&$$,&$1,&$3); }
| relocconst T_OP_AND relocconst
{ rpn_AND(&$$,&$1,&$3); }
| relocconst T_OP_SHL relocconst
{ rpn_SHL(&$$,&$1,&$3); }
| relocconst T_OP_SHR relocconst
{ rpn_SHR(&$$,&$1,&$3); }
| relocconst T_OP_MUL relocconst
{ rpn_MUL(&$$,&$1,&$3); }
| relocconst T_OP_DIV relocconst
{ rpn_DIV(&$$,&$1,&$3); }
| relocconst T_OP_MOD relocconst
{ rpn_MOD(&$$,&$1,&$3); }
| T_OP_ADD relocconst %prec NEG
{ $$ = $2; }
| T_OP_SUB relocconst %prec NEG
{ rpn_UNNEG(&$$,&$2); }
| T_OP_NOT relocconst %prec NEG
{ rpn_UNNOT(&$$,&$2); }
| T_OP_BANK '(' T_ID ')'
{ rpn_Bank(&$$,$3); $$.nVal = 0; }
| T_OP_DEF '(' T_ID ')'
{ rpn_Number(&$$,sym_isConstDefined($3)); }
| T_OP_FDIV '(' const ',' const ')' { rpn_Number(&$$,math_Div($3,$5)); }
| T_OP_FMUL '(' const ',' const ')' { rpn_Number(&$$,math_Mul($3,$5)); }
| T_OP_SIN '(' const ')' { rpn_Number(&$$,math_Sin($3)); }
| T_OP_COS '(' const ')' { rpn_Number(&$$,math_Cos($3)); }
| T_OP_TAN '(' const ')' { rpn_Number(&$$,math_Tan($3)); }
| T_OP_ASIN '(' const ')' { rpn_Number(&$$,math_ASin($3)); }
| T_OP_ACOS '(' const ')' { rpn_Number(&$$,math_ACos($3)); }
| T_OP_ATAN '(' const ')' { rpn_Number(&$$,math_ATan($3)); }
| T_OP_ATAN2 '(' const ',' const ')' { rpn_Number(&$$,math_ATan2($3,$5)); }
| T_OP_STRCMP '(' string ',' string ')' { rpn_Number(&$$,strcmp($3,$5)); }
| T_OP_STRIN '(' string ',' string ')'
{
char *p;
if( (p=strstr($3,$5))!=NULL )
{
rpn_Number(&$$,p-$3+1);
}
else
{
rpn_Number(&$$,0);
}
}
| T_OP_STRLEN '(' string ')' { rpn_Number(&$$,strlen($3)); }
| '(' relocconst ')'
{ $$ = $2; }
;
const : T_ID { $$ = sym_GetConstantValue($1); }
| T_NUMBER { $$ = $1; }
| string { $$ = str2int($1); }
| T_OP_LOGICNOT const %prec NEG { $$ = !$2; }
| const T_OP_LOGICOR const { $$ = $1 || $3; }
| const T_OP_LOGICAND const { $$ = $1 && $3; }
| const T_OP_LOGICEQU const { $$ = $1 == $3; }
| const T_OP_LOGICGT const { $$ = $1 > $3; }
| const T_OP_LOGICLT const { $$ = $1 < $3; }
| const T_OP_LOGICGE const { $$ = $1 >= $3; }
| const T_OP_LOGICLE const { $$ = $1 <= $3; }
| const T_OP_LOGICNE const { $$ = $1 != $3; }
| const T_OP_ADD const { $$ = $1 + $3; }
| const T_OP_SUB const { $$ = $1 - $3; }
| T_ID T_OP_SUB T_ID { $$ = sym_GetDefinedValue($1) - sym_GetDefinedValue($3); }
| const T_OP_XOR const { $$ = $1 ^ $3; }
| const T_OP_OR const { $$ = $1 | $3; }
| const T_OP_AND const { $$ = $1 & $3; }
| const T_OP_SHL const { $$ = $1 << $3; }
| const T_OP_SHR const { $$ = $1 >> $3; }
| const T_OP_MUL const { $$ = $1 * $3; }
| const T_OP_DIV const { $$ = $1 / $3; }
| const T_OP_MOD const { $$ = $1 % $3; }
| T_OP_ADD const %prec NEG { $$ = +$2; }
| T_OP_SUB const %prec NEG { $$ = -$2; }
| T_OP_NOT const %prec NEG { $$ = 0xFFFFFFFF^$2; }
| T_OP_FDIV '(' const ',' const ')' { $$ = math_Div($3,$5); }
| T_OP_FMUL '(' const ',' const ')' { $$ = math_Mul($3,$5); }
| T_OP_SIN '(' const ')' { $$ = math_Sin($3); }
| T_OP_COS '(' const ')' { $$ = math_Cos($3); }
| T_OP_TAN '(' const ')' { $$ = math_Tan($3); }
| T_OP_ASIN '(' const ')' { $$ = math_ASin($3); }
| T_OP_ACOS '(' const ')' { $$ = math_ACos($3); }
| T_OP_ATAN '(' const ')' { $$ = math_ATan($3); }
| T_OP_ATAN2 '(' const ',' const ')' { $$ = math_ATan2($3,$5); }
| T_OP_DEF '(' T_ID ')' { $$ = sym_isConstDefined($3); }
| T_OP_STRCMP '(' string ',' string ')' { $$ = strcmp( $3, $5 ); }
| T_OP_STRIN '(' string ',' string ')'
{
char *p;
if( (p=strstr($3,$5))!=NULL )
{
$$ = p-$3+1;
}
else
{
$$ = 0;
}
}
| T_OP_STRLEN '(' string ')' { $$ = strlen($3); }
| '(' const ')' { $$ = $2; }
;
string : T_STRING
{ strcpy($$,$1); }
| T_OP_STRSUB '(' string ',' const ',' const ')'
{ strncpy($$,$3+$5-1,$7); $$[$7]=0; }
| T_OP_STRCAT '(' string ',' string ')'
{ strcpy($$,$3); strcat($$,$5); }
| T_OP_STRUPR '(' string ')'
{ strcpy($$,$3); strupr($$); }
| T_OP_STRLWR '(' string ')'
{ strcpy($$,$3); strlwr($$); }
;

16
src/extern/err.c vendored
View File

@@ -26,13 +26,11 @@
#include <stdlib.h>
#include "extern/err.h"
#ifndef __MINGW32__
char *__progname;
#endif
extern char *progname;
void rgbds_vwarn(const char *fmt, va_list ap)
{
fprintf (stderr, "%s: ", __progname);
fprintf (stderr, "%s: ", progname);
if (fmt) {
vfprintf(stderr, fmt, ap);
fputs (": ", stderr);
@@ -42,18 +40,18 @@ void rgbds_vwarn(const char *fmt, va_list ap)
void rgbds_vwarnx(const char *fmt, va_list ap)
{
fprintf (stderr, "%s: ", __progname);
fprintf (stderr, "%s: ", progname);
if (fmt) vfprintf(stderr, fmt, ap);
putc('\n', stderr);
}
_Noreturn void rgbds_verr(int status, const char *fmt, va_list ap)
noreturn void rgbds_verr(int status, const char *fmt, va_list ap)
{
vwarn(fmt, ap);
exit(status);
}
_Noreturn void rgbds_verrx(int status, const char *fmt, va_list ap)
noreturn void rgbds_verrx(int status, const char *fmt, va_list ap)
{
vwarnx(fmt, ap);
exit(status);
@@ -75,7 +73,7 @@ void rgbds_warnx(const char *fmt, ...)
va_end(ap);
}
_Noreturn void rgbds_err(int status, const char *fmt, ...)
noreturn void rgbds_err(int status, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -83,7 +81,7 @@ _Noreturn void rgbds_err(int status, const char *fmt, ...)
va_end(ap);
}
_Noreturn void rgbds_errx(int status, const char *fmt, ...)
noreturn void rgbds_errx(int status, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);

38
src/extern/reallocarray.c vendored Normal file
View File

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

48
src/extern/strlcat.c vendored
View File

@@ -1,7 +1,7 @@
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
/* $OpenBSD: strlcat.c,v 1.14 2015/01/15 03:54:12 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -20,36 +20,36 @@
#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.
* Appends src to string dst of size dsize (unlike strncat, dsize is the
* full size of dst, not space left). At most dsize-1 characters
* will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
* Returns strlen(src) + MIN(dsize, strlen(initial dst)).
* If retval >= dsize, truncation occurred.
*/
size_t
rgbds_strlcat(char *dst, const char *src, size_t siz)
rgbds_strlcat(char *dst, const char *src, size_t dsize)
{
char *d = dst;
const char *s = src;
size_t n = siz;
const char *odst = dst;
const char *osrc = src;
size_t n = dsize;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
/* Find the end of dst and adjust bytes left but don't go past end. */
while (n-- != 0 && *dst != '\0')
dst++;
dlen = dst - odst;
n = dsize - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
if (n-- == 0)
return(dlen + strlen(src));
while (*src != '\0') {
if (n != 0) {
*dst++ = *src;
n--;
}
s++;
src++;
}
*d = '\0';
*dst = '\0';
return(dlen + (s - src)); /* count does not include NUL */
return(dlen + (src - osrc)); /* count does not include NUL */
}

37
src/extern/strlcpy.c vendored
View File

@@ -1,7 +1,7 @@
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
/* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -20,32 +20,31 @@
#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.
* Copy string src to buffer dst of size dsize. At most dsize-1
* chars will be copied. Always NUL terminates (unless dsize == 0).
* Returns strlen(src); if retval >= dsize, truncation occurred.
*/
size_t
rgbds_strlcpy(char *dst, const char *src, size_t siz)
rgbds_strlcpy(char *dst, const char *src, size_t dsize)
{
char *d = dst;
const char *s = src;
size_t n = siz;
const char *osrc = src;
size_t nleft = dsize;
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
/* Copy as many bytes as will fit. */
if (nleft != 0) {
while (--nleft != 0) {
if ((*dst++ = *src++) == '\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++)
/* Not enough room in dst, add NUL and traverse rest of src. */
if (nleft == 0) {
if (dsize != 0)
*dst = '\0'; /* NUL-terminate dst */
while (*src++)
;
}
return(s - src - 1); /* count does not include NUL */
return(src - osrc - 1); /* count does not include NUL */
}

View File

@@ -14,7 +14,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define _XOPEN_SOURCE 500
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -24,13 +23,15 @@
#include "extern/err.h"
char *progname;
static void
usage(void)
{
printf("usage: rgbfix [-Ccjsv] [-i game_id] [-k licensee_str] "
"[-l licensee_id]\n" " [-m mbc_type] [-n rom_version] "
"[-p pad_value] [-r ram_size]\n"
" [-t title_str] file.gb\n");
printf(
"usage: rgbfix [-Ccjsv] [-i game_id] [-k licensee_str] [-l licensee_id]\n"
" [-m mbc_type] [-n rom_version] [-p pad_value] [-r ram_size]\n"
" [-t title_str] file\n");
exit(1);
}
@@ -41,17 +42,6 @@ main(int argc, char *argv[])
int ch;
char *ep;
/*
* Open the ROM file
*/
if (argc < 2)
usage();
if ((rom = fopen(argv[argc - 1], "rb+")) == NULL) {
err(1, "Error opening file %s", argv[argc - 1]);
}
/*
* Parse command-line options
*/
@@ -71,15 +61,17 @@ main(int argc, char *argv[])
bool resize = false;
bool setversion = false;
char *title = NULL; /* game title in ASCII */
char *id = NULL; /* game ID in ASCII */
char *newlicensee = NULL; /* new licensee ID, two ASCII characters */
char *title; /* game title in ASCII */
char *id; /* game ID in ASCII */
char *newlicensee; /* new licensee ID, two ASCII characters */
int licensee = -1; /* old licensee ID */
int cartridge = -1; /* cartridge hardware ID */
int ramsize = -1; /* RAM size ID */
int version = -1; /* mask ROM version number */
int padvalue = -1; /* to pad the rom with if it changes size */
int licensee; /* old licensee ID */
int cartridge; /* cartridge hardware ID */
int ramsize; /* RAM size ID */
int version; /* mask ROM version number */
int padvalue; /* to pad the rom with if it changes size */
progname = argv[0];
while ((ch = getopt(argc, argv, "Cci:jk:l:m:n:p:sr:t:v")) != -1) {
switch (ch) {
@@ -198,6 +190,20 @@ main(int argc, char *argv[])
}
}
argc -= optind;
argv += optind;
if (argc == 0)
usage();
/*
* Open the ROM file
*/
if ((rom = fopen(argv[argc - 1], "rb+")) == NULL) {
err(1, "Error opening file %s", argv[argc - 1]);
}
/*
* Write changes to ROM
*/
@@ -351,7 +357,8 @@ main(int argc, char *argv[])
*/
/* We will pad the ROM to match the size given in the header. */
int romsize, newsize, headbyte;
long romsize, newsize;
int headbyte;
uint8_t *buf;
fseek(rom, 0, SEEK_END);
romsize = ftell(rom);

View File

@@ -1,4 +1,4 @@
.Dd $Mdocdate$
.Dd February 26, 2015
.Dt RGBFIX 1
.Os RGBDS Manual
.Sh NAME
@@ -41,7 +41,7 @@ flag are set,
takes precedence.
.It Fl i Ar game_id
Set the game ID string
.Pq Ad 0x13F No Ns \(en Ns Ad 0x142
.Pq Ad 0x13F Ns \(en Ns Ad 0x142
to a given string of exactly 4 characters.
If both this and the title are set, the game ID will overwrite the
overlapping portion of the title.
@@ -51,7 +51,7 @@ Set the non-Japanese region flag:
= 1.
.It Fl k Ar licensee_str
Set the new licensee string
.Pq Ad 0x144 No Ns \(en Ns Ad 0x145
.Pq Ad 0x144 Ns \(en Ns Ad 0x145
to a given string, truncated to at most two characters.
.It Fl l Ar licensee_id
Set the old licensee code,
@@ -84,7 +84,7 @@ Set the SGB flag:
= 3.
.It Fl t Ar title
Set the title string
.Pq Ad 0x134 No Ns \(en Ns Ad 0x143
.Pq Ad 0x134 Ns \(en Ns Ad 0x143
to a given string, truncated to at most 16 characters.
It is recommended to use 15 characters instead, to avoid clashing with the CGB
flag
@@ -93,11 +93,11 @@ If both this and the game ID are set, the game ID will overwrite the
overlapping portion of the title.
.It Fl v
Validate the header and fix checksums: the Nintendo character area
.Pq Ad 0x104 No Ns \(en Ns Ad 0x133 ,
.Pq Ad 0x104 Ns \(en Ns Ad 0x133 ,
the header checksum
.Pq Ad 0x14D ,
and the global checksum
.Pq Ad 0x14E No Ns \(en Ns Ad 0x14F .
.Pq Ad 0x14E Ns \(en Ns Ad 0x14F .
.El
.Sh EXAMPLES
Most values in the ROM header are only cosmetic.
@@ -109,7 +109,7 @@ It is a good idea to pad the image to a valid size as well
The following will make a plain, no-color Game Boy game without checking for
a valid size:
.Pp
.D1 $ rgbfix \-v foo.gb
.D1 $ rgbfix -v foo.gb
.Pp
The following will make a SGB-enabled, color-enabled game with a title of
.Dq foobar ,
@@ -119,19 +119,19 @@ The Game Boy itself does not use the title, but some emulators or ROM managers
might.
.Pc
.Pp
.D1 $ rgbfix \-vcs \-l 0x33 \-p 0 \-t foobar baz.gb
.D1 $ rgbfix -vcs -l 0x33 -p 0 -t foobar baz.gb
.Pp
The following will duplicate the header
.Pq sans global checksum
of the game
.Dq Survival Kids :
.Pp
.D1 $ rgbfix \-cjsv \-k A4 \-l 0x33 \-m 0x1B \-p 0xFF \-r 3 \-t SURVIVALKIDAVKE SurvivalKids.gbc
.D1 $ rgbfix -cjsv -k A4 -l 0x33 -m 0x1B -p 0xFF -r 3 -t SURVIVALKIDAVKE \
SurvivalKids.gbc
.Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbasm 1 ,
.Xr rgblink 1 ,
.Xr gbz80 7
.Xr rgbds 7
.Sh HISTORY
.Nm
was originally released by Carsten S\(/orensen as a standalone program called

View File

@@ -324,6 +324,7 @@ AssignSRAMSections(void)
if ((org = area_AllocSRAMAnyBank(pSection->nByteSize)) != -1) {
pSection->nOrg = org & 0xFFFF;
pSection->nBank = org >> 16;
pSection->nBank += BANK_SRAM;
pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank);
} else {
@@ -343,6 +344,7 @@ AssignWRAMSections(void)
if ((org = area_AllocWRAMAnyBank(pSection->nByteSize)) != -1) {
pSection->nOrg = org & 0xFFFF;
pSection->nBank = org >> 16;
pSection->nBank += BANK_WRAMX - 1;
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
} else {
@@ -557,8 +559,8 @@ AssignSections(void)
* bank are hardcoded.
*/
if (pSection->nBank >= 1
&& pSection->nBank <= 7) {
if (pSection->nBank >= 0
&& pSection->nBank <= 6) {
pSection->nBank +=
BANK_WRAMX;
if (area_AllocAbs

View File

@@ -3,7 +3,7 @@
#include <string.h>
#include "extern/err.h"
#include "link/types.h"
#include "types.h"
#include "link/mylink.h"
#include "link/main.h"

View File

@@ -1,4 +1,3 @@
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -25,6 +24,8 @@ SLONG options = 0;
SLONG fillchar = 0;
char smartlinkstartsymbol[256];
char *progname;
/*
* Print the usagescreen
*
@@ -33,9 +34,9 @@ char smartlinkstartsymbol[256];
static void
usage(void)
{
printf("usage: rgblink [-t] [-m mapfile] [-n symfile] [-o outfile]\n");
printf("\t [-s symbol] [-z pad_value] objectfile [...]\n");
printf(
"usage: rgblink [-t] [-m mapfile] [-n symfile] [-o outfile] [-p pad_value]\n"
" [-s symbol] file [...]\n");
exit(1);
}
@@ -53,7 +54,9 @@ main(int argc, char *argv[])
if (argc == 1)
usage();
while ((ch = getopt(argc, argv, "l:m:n:o:p:s:t")) != -1) {
progname = argv[0];
while ((ch = getopt(argc, argv, "m:n:o:p:s:t")) != -1) {
switch (ch) {
case 'm':
SetMapfileName(optarg);

View File

@@ -53,33 +53,49 @@ MapfileInitBank(SLONG bank)
{
if (mf) {
currentbank = bank;
if (bank == 0)
fprintf(mf, "Bank #0 (HOME):\n");
if (bank == BANK_ROM0)
fprintf(mf, "ROM Bank #0 (HOME):\n");
else if (bank < BANK_WRAM0)
fprintf(mf, "Bank #%ld:\n", bank);
fprintf(mf, "ROM Bank #%ld:\n", bank);
else if (bank == BANK_WRAM0)
fprintf(mf, "WRAM0:\n");
fprintf(mf, "WRAM Bank #0:\n");
else if (bank < BANK_VRAM)
fprintf(mf, "WRAM Bank #%ld:\n", bank - BANK_WRAMX + 1);
else if (bank == BANK_HRAM)
fprintf(mf, "HRAM:\n");
else if (bank == BANK_VRAM || bank == BANK_VRAM + 1)
fprintf(mf, "VRAM Bank #%ld:\n", bank - BANK_VRAM);
else if (bank < MAXBANKS)
fprintf(mf, "SRAM Bank #%ld:\n", bank - BANK_SRAM);
}
if (sf) {
sfbank = (bank >= 1 && bank <= 511) ? bank : 0;
if (bank < BANK_WRAM0)
sfbank = bank;
else if (bank == BANK_WRAM0)
sfbank = 0;
else if (bank < BANK_VRAM)
sfbank = bank - BANK_WRAMX + 1;
else if (bank == BANK_HRAM)
sfbank = 0;
else if (bank == BANK_VRAM || bank == BANK_VRAM + 1)
sfbank = bank - BANK_VRAM;
else if (bank < MAXBANKS)
sfbank = bank - BANK_SRAM;
else
sfbank = 0;
}
}
void
MapfileWriteSection(struct sSection * pSect)
{
if (!mf && !sf)
return;
SLONG i;
if (mf) {
fprintf(mf, " SECTION: $%04lX-$%04lX ($%04lX bytes)\n",
pSect->nOrg, pSect->nOrg + pSect->nByteSize - 1,
pSect->nByteSize);
}
for (i = 0; i < pSect->nNumberOfSymbols; i += 1) {
struct sSymbol *pSym;

View File

@@ -86,7 +86,7 @@ Output(void)
fclose(f);
}
for (i = 256; i < MAXBANKS; i += 1) {
for (i = BANK_WRAM0; i < MAXBANKS; i++) {
struct sSection *pSect;
MapfileInitBank(i);
pSect = pSections;

View File

@@ -3,6 +3,7 @@
#include <string.h>
#include "extern/err.h"
#include "link/assign.h"
#include "link/mylink.h"
#include "link/symbol.h"
#include "link/main.h"
@@ -53,18 +54,28 @@ getsymvalue(SLONG symid)
SLONG
getsymbank(SLONG symid)
{
SLONG nBank;
switch (pCurrentSection->tSymbols[symid]->Type) {
case SYM_IMPORT:
return (sym_GetBank(pCurrentSection->tSymbols[symid]->pzName));
nBank = sym_GetBank(pCurrentSection->tSymbols[symid]->pzName);
break;
case SYM_EXPORT:
case SYM_LOCAL:
return (pCurrentSection->tSymbols[symid]->pSection->nBank);
//return (pCurrentSection->nBank);
default:
nBank = pCurrentSection->tSymbols[symid]->pSection->nBank;
break;
}
default:
errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE");
}
if (nBank >= BANK_WRAMX && nBank <= (BANK_WRAMX+6))
return nBank - BANK_WRAMX + 1;
if (nBank >= BANK_VRAM && nBank <= (BANK_VRAM+1))
return nBank - BANK_VRAM;
if (nBank >= BANK_SRAM && nBank <= (BANK_SRAM+3))
return nBank - BANK_SRAM;
return nBank;
}
SLONG

View File

@@ -1,4 +1,4 @@
.Dd $Mdocdate$
.Dd February 26, 2015
.Dt RGBLINK 1
.Os RGBDS Manual
.Sh NAME
@@ -7,7 +7,6 @@
.Sh SYNOPSIS
.Nm rgblink
.Op Fl t
.Op Fl l Ar library
.Op Fl m Ar mapfile
.Op Fl n Ar symfile
.Op Fl o Ar outfile
@@ -51,7 +50,7 @@ section size from 16KiB to 32KiB.
All you need for a basic ROM is an object file, which can be made into a ROM
image like so:
.Pp
.D1 $ rgblink \-o bar.gb foo.o
.D1 $ rgblink -o bar.gb foo.o
.Pp
The resulting bar.gb will not have correct checksums
.Pq unless you put them in the assembly source .
@@ -59,12 +58,11 @@ You should use
.Xr rgbfix 1
to fix these so that the program will actually run in a Game Boy:
.Pp
.D1 $ rgbfix \-v bar.gb
.D1 $ rgbfix -v bar.gb
.Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbasm 1 ,
.Xr rgbfix 1 ,
.Xr gbz80 7
.Xr rgbds 7
.Sh HISTORY
.Nm
was originally written by Carsten S\(/orensen as part of the ASMotor package,

View File

@@ -5,7 +5,7 @@
#include "extern/err.h"
#include "link/main.h"
#include "link/patch.h"
#include "link/types.h"
#include "types.h"
#define HASHSIZE 73
@@ -76,7 +76,7 @@ sym_GetBank(char *tzName)
}
void
sym_CreateSymbol(char *tzName, SLONG nValue, SBYTE nBank)
sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank)
{
if (strcmp(tzName, "@") == 0)
return;

View File

@@ -0,0 +1,2 @@
SECTION "sec", ROM0
db BANK(noexist)

View File

@@ -0,0 +1,2 @@
ERROR: bank-noexist.asm(2) :
'noexist' not defined

View File

@@ -0,0 +1,2 @@
SECTION "sec", ROM0
ld a, 1/0

View File

@@ -0,0 +1,2 @@
ERROR: divzero-instr.asm(2) :
division by zero

View File

@@ -0,0 +1 @@
SECTION "sec", ROMX[$/0]

View File

@@ -0,0 +1,2 @@
ERROR: divzero-section-bank.asm(1) :
division by zero

1
test/asm/macro-@.asm Normal file
View File

@@ -0,0 +1 @@
foo @bar

2
test/asm/macro-@.out Normal file
View File

@@ -0,0 +1,2 @@
ERROR: macro-@.asm(1) -> @(-1) :
Macro '@' not defined

BIN
test/asm/null-in-macro.asm Normal file

Binary file not shown.

View File

6
test/asm/test.sh Normal file
View File

@@ -0,0 +1,6 @@
fname=$(mktemp)
for i in *.asm; do
../../rgbasm $i >$fname 2>&1
diff -u $fname ${i%.asm}.out
done

View File

@@ -0,0 +1,3 @@
SECTION "sec", ROM0
foo:
add sp, .

View File

@@ -0,0 +1,2 @@
ERROR: undefined-dot.asm(3) :
'.' not defined

View File

@@ -0,0 +1,36 @@
; this should generate a rom consisting of the following bytes:
; 01 02 03 04 05 06 07 00 01 02 03 00 01
section "x",rom0
db bank(w1),bank(w2),bank(w3),bank(w4),bank(w5),bank(w6),bank(w7)
db bank(s0),bank(s1),bank(s2),bank(s3)
db bank(v0),bank(v1)
section "wa",wramx,bank[1]
w1:
section "wb",wramx,bank[2]
w2:
section "wc",wramx,bank[3]
w3:
section "wd",wramx,bank[4]
w4:
section "we",wramx,bank[5]
w5:
section "wf",wramx,bank[6]
w6:
section "wg",wramx,bank[7]
w7:
section "sa",sram,bank[0]
s0:
section "sb",sram,bank[1]
s1:
section "sc",sram,bank[2]
s2:
section "sd",sram,bank[3]
s3:
section "v00",vram,bank[0]
v0:
section "v01",vram,bank[1]
v1: