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, extern/err.c is derived from the Musl C library, http://www.musl-libc.org,
and is released under the MIT license. 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, extern/strl.c is derived from the OpenBSD Project, http://www.openbsd.org,
and is released under the BSD license. and is released under the BSD license.

View File

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

2
README
View File

@@ -53,6 +53,6 @@ this variable. Defaults to @.
Installing RGBDS (Windows) 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. Copy the .exe files to C:\Windows\ or similar.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
#ifndef ASMOTOR_ASM_MATH_H #ifndef RGBDS_ASM_MATH_H
#define ASMOTOR_ASM_MATH_H #define RGBDS_ASM_MATH_H
#include "asm/types.h" #include "types.h"
void math_DefinePI(void); void math_DefinePI(void);
void math_Print(SLONG i); void math_Print(SLONG i);
@@ -14,5 +14,8 @@ SLONG math_ATan(SLONG i);
SLONG math_ATan2(SLONG i, SLONG j); SLONG math_ATan2(SLONG i, SLONG j);
SLONG math_Mul(SLONG i, SLONG j); SLONG math_Mul(SLONG i, SLONG j);
SLONG math_Div(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 #endif

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
#ifndef ASMOTOR_SYMBOL_H #ifndef RGBDS_SYMBOL_H
#define ASMOTOR_SYMBOL_H #define RGBDS_SYMBOL_H
#include "asm/types.h" #include "types.h"
#define HASHSIZE (1 << 16) #define HASHSIZE (1 << 16)
#define MAXSYMLEN 256 #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 #ifndef EXTERN_ERR_H
#define EXTERN_ERR_H #define EXTERN_ERR_H
@@ -29,6 +6,7 @@
#else #else
#include <stdarg.h> #include <stdarg.h>
#include "extern/stdnoreturn.h"
#define warn rgbds_warn #define warn rgbds_warn
#define vwarn rgbds_vwarn #define vwarn rgbds_vwarn
@@ -40,23 +18,15 @@
#define errx rgbds_errx #define errx rgbds_errx
#define verrx rgbds_verrx #define verrx rgbds_verrx
#ifdef __cplusplus
extern "C" {
#endif
void warn(const char *, ...); void warn(const char *, ...);
void vwarn(const char *, va_list); void vwarn(const char *, va_list);
void warnx(const char *, ...); void warnx(const char *, ...);
void vwarnx(const char *, va_list); void vwarnx(const char *, va_list);
void err(int, const char *, ...); noreturn void err(int, const char *, ...);
void verr(int, const char *, va_list); noreturn void verr(int, const char *, va_list);
void errx(int, const char *, ...); noreturn void errx(int, const char *, ...);
void verrx(int, const char *, va_list); noreturn void verrx(int, const char *, va_list);
#ifdef __cplusplus
}
#endif
#endif #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 #ifndef RGBDS_LINK_ASSIGN_H
#define ASMOTOR_LINK_ASSIGN_H #define RGBDS_LINK_ASSIGN_H
#include "link/types.h" #include "types.h"
enum eBankDefine { enum eBankDefine {
BANK_ROM0 = 0, BANK_ROM0 = 0,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,10 +1,10 @@
#ifndef ASMOTOR_LINK_SYMBOL_H #ifndef RGBDS_LINK_SYMBOL_H
#define ASMOTOR_LINK_SYMBOL_H #define RGBDS_LINK_SYMBOL_H
#include "link/types.h" #include "types.h"
void sym_Init(void); 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_GetValue(char *tzName);
SLONG sym_GetBank(char *tzName); SLONG sym_GetBank(char *tzName);

View File

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

1
src/asm/.gitignore vendored
View File

@@ -1,3 +1,2 @@
asmy.c asmy.c
asmy.h 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) * FileStack routines
*
* INCLUDES
*
*/ */
#include <errno.h> #include <errno.h>
@@ -13,7 +10,7 @@
#include "asm/symbol.h" #include "asm/symbol.h"
#include "asm/fstack.h" #include "asm/fstack.h"
#include "asm/types.h" #include "types.h"
#include "asm/main.h" #include "asm/main.h"
#include "asm/lexer.h" #include "asm/lexer.h"
#include "extern/err.h" #include "extern/err.h"
@@ -23,13 +20,6 @@
#define PATH_MAX 256 #define PATH_MAX 256
#endif #endif
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* VARIABLES
*
*/
struct sContext *pFileStack; struct sContext *pFileStack;
struct sSymbol *pCurrentMacro; struct sSymbol *pCurrentMacro;
YY_BUFFER_STATE CurrentFlexHandle; YY_BUFFER_STATE CurrentFlexHandle;
@@ -55,12 +45,8 @@ ULONG ulMacroReturnValue;
#define STAT_isREPTBlock 3 #define STAT_isREPTBlock 3
/* /*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Context push and pop * Context push and pop
*
*/ */
void void
pushcontext(void) pushcontext(void)
{ {
@@ -167,13 +153,10 @@ yywrap(void)
{ {
return (popcontext()); return (popcontext());
} }
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Dump the context stack to stderr
*
*/
/*
* Dump the context stack to stderr
*/
void void
fstk_Dump(void) fstk_Dump(void)
{ {
@@ -189,13 +172,10 @@ fstk_Dump(void)
fprintf(stderr, "%s(%ld)", tzCurrentFileName, nLineNo); fprintf(stderr, "%s(%ld)", tzCurrentFileName, nLineNo);
} }
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Extra includepath stuff
*
*/
/*
* Extra includepath stuff
*/
void void
fstk_AddIncludePath(char *s) fstk_AddIncludePath(char *s)
{ {
@@ -230,13 +210,10 @@ fstk_FindFile(char *fname)
errno = ENOENT; errno = ENOENT;
return NULL; return NULL;
} }
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Set up an include file for parsing
*
*/
/*
* Set up an include file for parsing
*/
void void
fstk_RunInclude(char *tzFileName) fstk_RunInclude(char *tzFileName)
{ {
@@ -262,13 +239,10 @@ fstk_RunInclude(char *tzFileName)
yyunput('\n'); yyunput('\n');
nLineNo -= 1; nLineNo -= 1;
} }
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Set up a macro for parsing
*
*/
/*
* Set up a macro for parsing
*/
ULONG ULONG
fstk_RunMacro(char *s) fstk_RunMacro(char *s)
{ {
@@ -281,6 +255,8 @@ fstk_RunMacro(char *s)
sym_UseNewMacroArgs(); sym_UseNewMacroArgs();
nCurrentStatus = STAT_isMacro; nCurrentStatus = STAT_isMacro;
strcpy(tzCurrentFileName, s); strcpy(tzCurrentFileName, s);
if (sym->pMacro == NULL)
return 0;
pCurrentMacro = sym; pCurrentMacro = sym;
CurrentFlexHandle = CurrentFlexHandle =
yy_scan_bytes(pCurrentMacro->pMacro, yy_scan_bytes(pCurrentMacro->pMacro,
@@ -290,13 +266,10 @@ fstk_RunMacro(char *s)
} else } else
return (0); return (0);
} }
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Set up a macroargument for parsing
*
*/
/*
* Set up a macroargument for parsing
*/
void void
fstk_RunMacroArg(SLONG s) fstk_RunMacroArg(SLONG s)
{ {
@@ -316,13 +289,10 @@ fstk_RunMacroArg(SLONG s)
} else } else
fatalerror("No such macroargument"); fatalerror("No such macroargument");
} }
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Set up a stringequate for parsing
*
*/
/*
* Set up a stringequate for parsing
*/
void void
fstk_RunString(char *s) fstk_RunString(char *s)
{ {
@@ -338,13 +308,10 @@ fstk_RunString(char *s)
} else } else
yyerror("No such string symbol '%s'", s); 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 void
fstk_RunRept(ULONG count) fstk_RunRept(ULONG count)
{ {
@@ -362,13 +329,10 @@ fstk_RunRept(ULONG count)
yy_switch_to_buffer(CurrentFlexHandle); yy_switch_to_buffer(CurrentFlexHandle);
} }
} }
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
* Initialize the filestack routines
*
*/
/*
* Initialize the filestack routines
*/
void void
fstk_Init(char *s) 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 "asmy.h"
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
UBYTE oDontExpandStrings = 0; bool oDontExpandStrings = false;
SLONG nGBGfxID = -1; SLONG nGBGfxID = -1;
SLONG nBinaryID = -1; SLONG nBinaryID = -1;
@@ -160,7 +161,7 @@ ParseSymbol(char *src, ULONG size)
if (*src == '@') if (*src == '@')
marg = sym_FindMacroArg(-1); marg = sym_FindMacroArg(-1);
else if (*src >= '0' && *src <= '9') else if (*src >= '0' && *src <= '9')
marg = sym_FindMacroArg(*src); marg = sym_FindMacroArg(*src - '0');
else { else {
fatalerror("Malformed ID"); fatalerror("Malformed ID");
return (0); return (0);
@@ -184,7 +185,7 @@ ParseSymbol(char *src, ULONG size)
dest[copied] = 0; dest[copied] = 0;
if (oDontExpandStrings == 0 && sym_isString(dest)) { if (!oDontExpandStrings && sym_isString(dest)) {
char *s; char *s;
yyskipbytes(size_backup); yyskipbytes(size_backup);
@@ -225,7 +226,6 @@ PutUniqueArg(char *src, ULONG size)
{ {
char *s; char *s;
src = src;
yyskipbytes(size); yyskipbytes(size);
if ((s = sym_FindMacroArg(-1)) != NULL) { if ((s = sym_FindMacroArg(-1)) != NULL) {
yyunputstr(s); yyunputstr(s);
@@ -268,6 +268,9 @@ struct sLexInitString staticstrings[] = {
{"bank", T_OP_BANK}, {"bank", T_OP_BANK},
{"round", T_OP_ROUND},
{"ceil", T_OP_CEIL},
{"floor", T_OP_FLOOR},
{"div", T_OP_FDIV}, {"div", T_OP_FDIV},
{"mul", T_OP_FMUL}, {"mul", T_OP_FMUL},
{"sin", T_OP_SIN}, {"sin", T_OP_SIN},

View File

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

View File

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

View File

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

View File

@@ -1,14 +1,11 @@
/* /*
* RGBAsm - MATH.C (Fixedpoint math routines) * Fixedpoint math routines
*
* INCLUDES
*
*/ */
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include "asm/types.h" #include "types.h"
#include "asm/mymath.h" #include "asm/mymath.h"
#include "asm/symbol.h" #include "asm/symbol.h"
@@ -19,24 +16,17 @@
#endif #endif
/* /*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Define the _PI symbol * Define the _PI symbol
*
*/ */
void void
math_DefinePI(void) math_DefinePI(void)
{ {
sym_AddEqu("_PI", double2fix(PI)); sym_AddEqu("_PI", double2fix(PI));
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Print a fixed point value
*
*/
/*
* Print a fixed point value
*/
void void
math_Print(SLONG i) math_Print(SLONG i)
{ {
@@ -47,112 +37,112 @@ math_Print(SLONG i)
printf("-%ld.%05ld", (-i) >> 16, printf("-%ld.%05ld", (-i) >> 16,
((SLONG) (fix2double(-i) * 100000 + 0.5)) % 100000); ((SLONG) (fix2double(-i) * 100000 + 0.5)) % 100000);
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate sine
*
*/
/*
* Calculate sine
*/
SLONG SLONG
math_Sin(SLONG i) math_Sin(SLONG i)
{ {
return (double2fix(sin(fix2double(i) * 2 * PI / 65536))); return (double2fix(sin(fix2double(i) * 2 * PI / 65536)));
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate cosine
*
*/
/*
* Calculate cosine
*/
SLONG SLONG
math_Cos(SLONG i) math_Cos(SLONG i)
{ {
return (double2fix(cos(fix2double(i) * 2 * PI / 65536))); return (double2fix(cos(fix2double(i) * 2 * PI / 65536)));
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate tangent
*
*/
/*
* Calculate tangent
*/
SLONG SLONG
math_Tan(SLONG i) math_Tan(SLONG i)
{ {
return (double2fix(tan(fix2double(i) * 2 * PI / 65536))); return (double2fix(tan(fix2double(i) * 2 * PI / 65536)));
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate sine^-1
*
*/
/*
* Calculate arcsine
*/
SLONG SLONG
math_ASin(SLONG i) math_ASin(SLONG i)
{ {
return (double2fix(asin(fix2double(i)) / 2 / PI * 65536)); return (double2fix(asin(fix2double(i)) / 2 / PI * 65536));
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate cosine^-1
*
*/
/*
* Calculate arccosine
*/
SLONG SLONG
math_ACos(SLONG i) math_ACos(SLONG i)
{ {
return (double2fix(acos(fix2double(i)) / 2 / PI * 65536)); return (double2fix(acos(fix2double(i)) / 2 / PI * 65536));
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate tangent^-1
*
*/
/*
* Calculate arctangent
*/
SLONG SLONG
math_ATan(SLONG i) math_ATan(SLONG i)
{ {
return (double2fix(atan(fix2double(i)) / 2 / PI * 65536)); return (double2fix(atan(fix2double(i)) / 2 / PI * 65536));
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Calculate atan2
*
*/
/*
* Calculate atan2
*/
SLONG SLONG
math_ATan2(SLONG i, SLONG j) math_ATan2(SLONG i, SLONG j)
{ {
return (double2fix return (double2fix
(atan2(fix2double(i), fix2double(j)) / 2 / PI * 65536)); (atan2(fix2double(i), fix2double(j)) / 2 / PI * 65536));
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Multiplication
*
*/
/*
* Multiplication
*/
SLONG SLONG
math_Mul(SLONG i, SLONG j) math_Mul(SLONG i, SLONG j)
{ {
return (double2fix(fix2double(i) * fix2double(j))); return (double2fix(fix2double(i) * fix2double(j)));
} }
/*
* RGBAsm - MATH.C (Fixedpoint math routines)
*
* Division
*
*/
/*
* Division
*/
SLONG SLONG
math_Div(SLONG i, SLONG j) math_Div(SLONG i, SLONG j)
{ {
return (double2fix(fix2double(i) / fix2double(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 * Outputs an objectfile
*
* INCLUDES
*
*/ */
#include <errno.h> #include <errno.h>
@@ -22,13 +19,6 @@
#define SECTIONCHUNK 0x4000 #define SECTIONCHUNK 0x4000
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Internal structures
*
*/
void out_SetCurrentSection(struct Section * pSect); void out_SetCurrentSection(struct Section * pSect);
struct Patch { struct Patch {
@@ -52,12 +42,6 @@ struct SectionStackEntry {
struct Section *pSection; struct Section *pSection;
struct SectionStackEntry *pNext; struct SectionStackEntry *pNext;
}; };
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* VARIABLES
*
*/
struct PatchSymbol *tHashedPatchSymbols[HASHSIZE]; struct PatchSymbol *tHashedPatchSymbols[HASHSIZE];
struct Section *pSectionList = NULL, *pCurrentSection = NULL; struct Section *pSectionList = NULL, *pCurrentSection = NULL;
@@ -67,12 +51,8 @@ char *tzObjectname;
struct SectionStackEntry *pSectionStack = NULL; struct SectionStackEntry *pSectionStack = NULL;
/* /*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Section stack routines * Section stack routines
*
*/ */
void void
out_PushSection(void) out_PushSection(void)
{ {
@@ -99,13 +79,10 @@ out_PopSection(void)
} else } else
fatalerror("No entries in the section stack"); 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 ULONG
countsymbols(void) countsymbols(void)
{ {
@@ -121,13 +98,10 @@ countsymbols(void)
return (count); 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 ULONG
countsections(void) countsections(void)
{ {
@@ -143,13 +117,10 @@ countsections(void)
return (count); 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 ULONG
countpatches(struct Section * pSect) countpatches(struct Section * pSect)
{ {
@@ -164,13 +135,10 @@ countpatches(struct Section * pSect)
return (r); 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 void
fputlong(ULONG i, FILE * f) fputlong(ULONG i, FILE * f)
{ {
@@ -179,13 +147,10 @@ fputlong(ULONG i, FILE * f)
fputc(i >> 16, f); fputc(i >> 16, f);
fputc(i >> 24, 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 void
fputstring(char *s, FILE * f) fputstring(char *s, FILE * f)
{ {
@@ -193,13 +158,10 @@ fputstring(char *s, FILE * f)
fputc(*s++, f); fputc(*s++, f);
fputc(0, f); fputc(0, f);
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Return a sections ID
*
*/
/*
* Return a section's ID
*/
ULONG ULONG
getsectid(struct Section * pSect) getsectid(struct Section * pSect)
{ {
@@ -218,13 +180,10 @@ getsectid(struct Section * pSect)
fatalerror("INTERNAL: Unknown section"); fatalerror("INTERNAL: Unknown section");
return ((ULONG) - 1); return ((ULONG) - 1);
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Write a patch to a file
*
*/
/*
* Write a patch to a file
*/
void void
writepatch(struct Patch * pPatch, FILE * f) writepatch(struct Patch * pPatch, FILE * f)
{ {
@@ -235,13 +194,10 @@ writepatch(struct Patch * pPatch, FILE * f)
fputlong(pPatch->nRPNSize, f); fputlong(pPatch->nRPNSize, f);
fwrite(pPatch->pRPN, 1, 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 void
writesection(struct Section * pSect, FILE * f) 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 void
writesymbol(struct sSymbol * pSym, FILE * f) writesymbol(struct sSymbol * pSym, FILE * f)
{ {
@@ -319,13 +272,10 @@ writesymbol(struct sSymbol * pSym, FILE * f)
fputlong(offset, f); fputlong(offset, f);
} }
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Add a symbol to the object
*
*/
/*
* Add a symbol to the object
*/
ULONG ULONG
addsymbol(struct sSymbol * pSym) addsymbol(struct sSymbol * pSym)
{ {
@@ -355,13 +305,10 @@ addsymbol(struct sSymbol * pSym)
return pPSym->ID; return pPSym->ID;
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Add all exported symbols to the object
*
*/
/*
* Add all exported symbols to the object
*/
void void
addexports(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 * struct Patch *
allocpatch(void) allocpatch(void)
{ {
@@ -401,13 +345,10 @@ allocpatch(void)
return (pPatch); 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 void
createpatch(ULONG type, struct Expression * expr) createpatch(ULONG type, struct Expression * expr)
{ {
@@ -445,7 +386,10 @@ createpatch(ULONG type, struct Expression * expr)
rpnexpr[rpnptr++] = value >> 16; rpnexpr[rpnptr++] = value >> 16;
rpnexpr[rpnptr++] = value >> 24; rpnexpr[rpnptr++] = value >> 24;
} else { } 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++] = RPN_SYM;
rpnexpr[rpnptr++] = symptr & 0xFF; rpnexpr[rpnptr++] = symptr & 0xFF;
rpnexpr[rpnptr++] = symptr >> 8; rpnexpr[rpnptr++] = symptr >> 8;
@@ -453,15 +397,19 @@ createpatch(ULONG type, struct Expression * expr)
rpnexpr[rpnptr++] = symptr >> 24; rpnexpr[rpnptr++] = symptr >> 24;
} }
break; break;
case RPN_BANK: case RPN_BANK: {
struct sSymbol *sym;
symptr = 0; symptr = 0;
while ((tzSym[symptr++] = rpn_PopByte(expr)) != 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++] = RPN_BANK;
rpnexpr[rpnptr++] = symptr & 0xFF; rpnexpr[rpnptr++] = symptr & 0xFF;
rpnexpr[rpnptr++] = symptr >> 8; rpnexpr[rpnptr++] = symptr >> 8;
rpnexpr[rpnptr++] = symptr >> 16; rpnexpr[rpnptr++] = symptr >> 16;
rpnexpr[rpnptr++] = symptr >> 24; rpnexpr[rpnptr++] = symptr >> 24;
}
break; break;
default: default:
rpnexpr[rpnptr++] = rpndata; rpnexpr[rpnptr++] = rpndata;
@@ -473,13 +421,10 @@ createpatch(ULONG type, struct Expression * expr)
pPatch->nRPNSize = rpnptr; 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 void
checksection(void) checksection(void)
{ {
@@ -488,14 +433,11 @@ checksection(void)
else else
fatalerror("Code generation before SECTION directive"); 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 * A quick check to see if we have an initialized section that can contain
* this much initialized data * this much initialized data
*
*/ */
void void
checkcodesection(SLONG size) checkcodesection(SLONG size)
{ {
@@ -505,32 +447,35 @@ checkcodesection(SLONG size)
errx(1, "Section '%s' cannot contain code or data (not a " errx(1, "Section '%s' cannot contain code or data (not a "
"ROM0 or ROMX)", pCurrentSection->pzName); "ROM0 or ROMX)", pCurrentSection->pzName);
} }
if (pCurrentSection->nPC + size <= MAXSECTIONSIZE) { if (pCurrentSection->nPC + size > MAXSECTIONSIZE) {
if (((pCurrentSection->nPC % SECTIONCHUNK) > /*
((pCurrentSection->nPC + size) % SECTIONCHUNK)) * N.B.: This check is not sufficient to ensure the section
&& (pCurrentSection->nType == SECT_ROM0 * will fit, because there can be multiple sections of this
|| pCurrentSection->nType == SECT_ROMX)) { * type. The definitive check must be done at the linking
if ((pCurrentSection->tData = * stage.
(UBYTE *) realloc(pCurrentSection->tData, */
((pCurrentSection->nPC + errx(1, "Section '%s' is too big (old size %d + %d > %d)",
size) / SECTIONCHUNK + pCurrentSection->pzName, pCurrentSection->nPC, size,
1) * SECTIONCHUNK)) != NULL) { MAXSECTIONSIZE);
return; }
} else if (((pCurrentSection->nPC % SECTIONCHUNK) >
fatalerror ((pCurrentSection->nPC + size) % SECTIONCHUNK)) &&
("Not enough memory to expand section"); (pCurrentSection->nType == SECT_ROM0 ||
} pCurrentSection->nType == SECT_ROMX)) {
return; pCurrentSection->tData = realloc(pCurrentSection->tData,
} else ((pCurrentSection->nPC + size) / SECTIONCHUNK + 1) *
errx(1, "Section '%s' is too big", pCurrentSection->pzName); SECTIONCHUNK);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Write an objectfile
*
*/
if (pCurrentSection->tData == NULL) {
err(1, "Could not expand section");
}
}
return;
}
/*
* Write an objectfile
*/
void void
out_WriteObject(void) out_WriteObject(void)
{ {
@@ -561,13 +506,10 @@ out_WriteObject(void)
fclose(f); fclose(f);
} }
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Prepare for pass #2
*
*/
/*
* Prepare for pass #2
*/
void void
out_PrepPass2(void) out_PrepPass2(void)
{ {
@@ -581,13 +523,10 @@ out_PrepPass2(void)
pCurrentSection = NULL; pCurrentSection = NULL;
pSectionStack = NULL; pSectionStack = NULL;
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Set the objectfilename
*
*/
/*
* Set the objectfilename
*/
void void
out_SetFileName(char *s) out_SetFileName(char *s)
{ {
@@ -599,16 +538,12 @@ out_SetFileName(char *s)
pCurrentSection = NULL; pCurrentSection = NULL;
pPatchSymbols = 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 * struct Section *
out_FindSection(char *pzName, ULONG secttype, SLONG org, out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
SLONG bank)
{ {
struct Section *pSect, **ppSect; struct Section *pSect, **ppSect;
@@ -652,13 +587,10 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org,
return (NULL); return (NULL);
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Set the current section
*
*/
/*
* Set the current section
*/
void void
out_SetCurrentSection(struct Section * pSect) out_SetCurrentSection(struct Section * pSect)
{ {
@@ -668,37 +600,28 @@ out_SetCurrentSection(struct Section * pSect)
pPCSymbol->nValue = nPC; pPCSymbol->nValue = nPC;
pPCSymbol->pSection = pCurrentSection; 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 void
out_NewSection(char *pzName, ULONG secttype) out_NewSection(char *pzName, ULONG secttype)
{ {
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1)); 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 void
out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank) out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
{ {
out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank)); out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank));
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output an absolute byte
*
*/
/*
* Output an absolute byte
*/
void void
out_AbsByte(int b) out_AbsByte(int b)
{ {
@@ -719,13 +642,10 @@ out_AbsByteGroup(char *s, int length)
while (length--) while (length--)
out_AbsByte(*s++); out_AbsByte(*s++);
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Skip this many bytes
*
*/
/*
* Skip this many bytes
*/
void void
out_Skip(int skip) out_Skip(int skip)
{ {
@@ -741,13 +661,10 @@ out_Skip(int skip)
out_AbsByte(CurrentOptions.fillchar); 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 void
out_String(char *s) out_String(char *s)
{ {
@@ -755,12 +672,10 @@ out_String(char *s)
while (*s) while (*s)
out_AbsByte(*s++); out_AbsByte(*s++);
} }
/* /*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a relocatable byte. Checking will be done to see if it * Output a relocatable byte. Checking will be done to see if it
* is an absolute value in disguise. * is an absolute value in disguise.
*
*/ */
void void
@@ -780,13 +695,10 @@ out_RelByte(struct Expression * expr)
rpn_Reset(expr); rpn_Reset(expr);
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output an absolute word
*
*/
/*
* Output an absolute word
*/
void void
out_AbsWord(int b) out_AbsWord(int b)
{ {
@@ -800,14 +712,11 @@ out_AbsWord(int b)
nPC += 2; nPC += 2;
pPCSymbol->nValue += 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 void
out_RelWord(struct Expression * expr) out_RelWord(struct Expression * expr)
{ {
@@ -828,13 +737,10 @@ out_RelWord(struct Expression * expr)
out_AbsWord(expr->nVal); out_AbsWord(expr->nVal);
rpn_Reset(expr); rpn_Reset(expr);
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output an absolute longword
*
*/
/*
* Output an absolute longword
*/
void void
out_AbsLong(SLONG b) out_AbsLong(SLONG b)
{ {
@@ -849,14 +755,11 @@ out_AbsLong(SLONG b)
nPC += 4; nPC += 4;
pPCSymbol->nValue += 4; pPCSymbol->nValue += 4;
} }
/* /*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a relocatable longword. Checking will be done to see if * Output a relocatable longword. Checking will be done to see if
* is an absolute value in disguise. * is an absolute value in disguise.
*
*/ */
void void
out_RelLong(struct Expression * expr) out_RelLong(struct Expression * expr)
{ {
@@ -879,13 +782,10 @@ out_RelLong(struct Expression * expr)
out_AbsLong(expr->nVal); out_AbsLong(expr->nVal);
rpn_Reset(expr); rpn_Reset(expr);
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a PC-relative byte
*
*/
/*
* Output a PC-relative byte
*/
void void
out_PCRelByte(struct Expression * expr) out_PCRelByte(struct Expression * expr)
{ {
@@ -899,13 +799,10 @@ out_PCRelByte(struct Expression * expr)
out_AbsByte(b); out_AbsByte(b);
rpn_Reset(expr); rpn_Reset(expr);
} }
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
*
* Output a binary file
*
*/
/*
* Output a binary file
*/
void void
out_BinaryFile(char *s) out_BinaryFile(char *s)
{ {

View File

@@ -1,4 +1,4 @@
.Dd $Mdocdate$ .Dd February 26, 2015
.Dt RGBASM 1 .Dt RGBASM 1
.Os RGBDS Manual .Os RGBDS Manual
.Sh NAME .Sh NAME
@@ -6,9 +6,9 @@
.Nd Game Boy assembler .Nd Game Boy assembler
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm rgbasm .Nm rgbasm
.Op Fl v .Op Fl hv
.Op Fl h
.Op Fl b Ar chars .Op Fl b Ar chars
.Op Fl D Ar name Ns Op = Ns Ar value
.Op Fl g Ar chars .Op Fl g Ar chars
.Op Fl i Ar path .Op Fl i Ar path
.Op Fl o Ar outfile .Op Fl o Ar outfile
@@ -23,6 +23,12 @@ Its arguments are as follows:
.It Fl b Ar chars .It Fl b Ar chars
Change the two characters used for binary constants. Change the two characters used for binary constants.
The defaults are 01. 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 .It Fl g Ar chars
Change the four characters used for binary constants. Change the four characters used for binary constants.
The defaults are 0123. The defaults are 0123.
@@ -50,7 +56,7 @@ Be verbose.
.Sh EXAMPLES .Sh EXAMPLES
Assembling a basic source file is simple: Assembling a basic source file is simple:
.Pp .Pp
.D1 $ rgbasm \-o bar.o foo.asm .D1 $ rgbasm -o bar.o foo.asm
.Pp .Pp
The resulting object file is not yet a usable ROM image \(em it must first be The resulting object file is not yet a usable ROM image \(em it must first be
run through run through
@@ -58,10 +64,9 @@ run through
and and
.Xr rgbfix 1 . .Xr rgbfix 1 .
.Sh SEE ALSO .Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbfix 1 , .Xr rgbfix 1 ,
.Xr rgblink 1 , .Xr rgblink 1 ,
.Xr gbz80 7 .Xr rgbds 7
.Sh HISTORY .Sh HISTORY
.Nm .Nm
was originally written by Carsten S\(/orensen as part of the ASMotor package, 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 * Controls RPN expressions for objectfiles
*
* INCLUDES
*
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "asm/mylink.h" #include "asm/mylink.h"
#include "asm/types.h" #include "types.h"
#include "asm/symbol.h" #include "asm/symbol.h"
#include "asm/asm.h" #include "asm/asm.h"
#include "asm/main.h" #include "asm/main.h"
@@ -29,49 +26,26 @@ mergetwoexpressions(struct Expression * expr, struct Expression * src1,
#define joinexpr() mergetwoexpressions(expr,src1,src2) #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 * Add a byte to the RPN expression
*
*/ */
void void
pushbyte(struct Expression * expr, int b) pushbyte(struct Expression * expr, int b)
{ {
expr->tRPN[expr->nRPNLength++] = b & 0xFF; expr->tRPN[expr->nRPNLength++] = b & 0xFF;
} }
/*
* RGBAsm - RPN.C - Controls RPN expressions for objectfiles
*
* Reset the RPN module
*
*/
/*
* Reset the RPN module
*/
void void
rpn_Reset(struct Expression * expr) rpn_Reset(struct Expression * expr)
{ {
expr->nRPNLength = expr->nRPNOut = expr->isReloc = expr->isPCRel = 0; 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 UWORD
rpn_PopByte(struct Expression * expr) rpn_PopByte(struct Expression * expr)
{ {
@@ -80,37 +54,28 @@ rpn_PopByte(struct Expression * expr)
} else } else
return (expr->tRPN[expr->nRPNOut++]); 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 ULONG
rpn_isReloc(struct Expression * expr) rpn_isReloc(struct Expression * expr)
{ {
return (expr->isReloc); 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 ULONG
rpn_isPCRelative(struct Expression * expr) rpn_isPCRelative(struct Expression * expr)
{ {
return (expr->isPCRel); 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 void
rpn_Number(struct Expression * expr, ULONG i) 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); return (expr->nVal >= low && expr->nVal <= high);
} }
} }
void void
rpn_CheckHRAM(struct Expression * expr, struct Expression * src) rpn_CheckHRAM(struct Expression * expr, struct Expression * src)
{ {

View File

@@ -1,11 +1,7 @@
/* /*
* RGBAsm - SYMBOL.C - Symboltable and macroargs stuff * Symboltable and macroargs stuff
*
* INCLUDES
*
*/ */
#define _XOPEN_SOURCE 500
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -17,13 +13,6 @@
#include "asm/mymath.h" #include "asm/mymath.h"
#include "asm/output.h" #include "asm/output.h"
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* VARIABLES
*
*/
struct sSymbol *tHashedSymbols[HASHSIZE]; struct sSymbol *tHashedSymbols[HASHSIZE];
struct sSymbol *pScope = NULL; struct sSymbol *pScope = NULL;
struct sSymbol *pPCSymbol = NULL; struct sSymbol *pPCSymbol = NULL;
@@ -38,7 +27,6 @@ Callback_NARG(struct sSymbol * sym)
{ {
ULONG i = 0; ULONG i = 0;
sym = sym;
while (currentmacroargs[i] && i < MAXMACROARGS) while (currentmacroargs[i] && i < MAXMACROARGS)
i += 1; i += 1;
@@ -46,12 +34,8 @@ Callback_NARG(struct sSymbol * sym)
} }
/* /*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Get the nValue field of a symbol * Get the nValue field of a symbol
*
*/ */
SLONG SLONG
getvaluefield(struct sSymbol * sym) getvaluefield(struct sSymbol * sym)
{ {
@@ -60,13 +44,10 @@ getvaluefield(struct sSymbol * sym)
} else } else
return (sym->nValue); return (sym->nValue);
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Calculate the hash value for a string
*
*/
/*
* Calculate the hash value for a string
*/
ULONG ULONG
calchash(char *s) calchash(char *s)
{ {
@@ -77,13 +58,10 @@ calchash(char *s)
return (hash % HASHSIZE); return (hash % HASHSIZE);
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Create a new symbol by name
*
*/
/*
* Create a new symbol by name
*/
struct sSymbol * struct sSymbol *
createsymbol(char *s) createsymbol(char *s)
{ {
@@ -112,12 +90,8 @@ createsymbol(char *s)
} }
} }
/* /*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find a symbol by name and scope * Find a symbol by name and scope
*
*/ */
struct sSymbol * struct sSymbol *
findsymbol(char *s, struct sSymbol * scope) findsymbol(char *s, struct sSymbol * scope)
{ {
@@ -136,13 +110,10 @@ findsymbol(char *s, struct sSymbol * scope)
} }
return (NULL); 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 ** struct sSymbol **
findpsymbol(char *s, struct sSymbol * scope) findpsymbol(char *s, struct sSymbol * scope)
{ {
@@ -161,13 +132,10 @@ findpsymbol(char *s, struct sSymbol * scope)
} }
return (NULL); return (NULL);
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find a symbol by name and scope
*
*/
/*
* Find a symbol by name and scope
*/
struct sSymbol * struct sSymbol *
sym_FindSymbol(char *tzName) sym_FindSymbol(char *tzName)
{ {
@@ -180,13 +148,10 @@ sym_FindSymbol(char *tzName)
return (findsymbol(tzName, pscope)); return (findsymbol(tzName, pscope));
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Purge a symbol
*
*/
/*
* Purge a symbol
*/
void void
sym_Purge(char *tzName) sym_Purge(char *tzName)
{ {
@@ -214,13 +179,10 @@ sym_Purge(char *tzName)
yyerror("'%s' not defined", 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 ULONG
sym_isConstDefined(char *tzName) sym_isConstDefined(char *tzName)
{ {
@@ -262,13 +224,10 @@ sym_isDefined(char *tzName)
else else
return (0); return (0);
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Determine if the symbol is a constant
*
*/
/*
* Determine if the symbol is a constant
*/
ULONG ULONG
sym_isConstant(char *s) sym_isConstant(char *s)
{ {
@@ -285,13 +244,10 @@ sym_isConstant(char *s)
} }
return (0); return (0);
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Get a string equate's value
*
*/
/*
* Get a string equate's value
*/
char * char *
sym_GetStringValue(char *tzSym) sym_GetStringValue(char *tzSym)
{ {
@@ -305,13 +261,10 @@ sym_GetStringValue(char *tzSym)
return (NULL); return (NULL);
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Return a constant symbols value
*
*/
/*
* Return a constant symbols value
*/
ULONG ULONG
sym_GetConstantValue(char *s) sym_GetConstantValue(char *s)
{ {
@@ -334,13 +287,10 @@ sym_GetConstantValue(char *s)
return (0); 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 ULONG
sym_GetValue(char *s) sym_GetValue(char *s)
{ {
@@ -376,13 +326,10 @@ sym_GetValue(char *s)
return (0); 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 ULONG
sym_GetDefinedValue(char *s) sym_GetDefinedValue(char *s)
{ {
@@ -408,13 +355,10 @@ sym_GetDefinedValue(char *s)
return (0); return (0);
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Macro argument stuff
*
*/
/*
* Macro argument stuff
*/
void void
sym_ShiftCurrentMacroArgs(void) sym_ShiftCurrentMacroArgs(void)
{ {
@@ -492,7 +436,7 @@ sym_AddNewMacroArg(char *s)
else else
newmacroargs[i] = NULL; newmacroargs[i] = NULL;
} else } else
yyerror("A maximum of 9 arguments allowed"); yyerror("A maximum of %d arguments allowed", MAXMACROARGS);
} }
void void
@@ -512,25 +456,19 @@ sym_UseCurrentMacroArgs(void)
for (i = 1; i <= MAXMACROARGS; i += 1) for (i = 1; i <= MAXMACROARGS; i += 1)
sym_AddNewMacroArg(sym_FindMacroArg(i)); sym_AddNewMacroArg(sym_FindMacroArg(i));
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find a macro by name
*
*/
/*
* Find a macro by name
*/
struct sSymbol * struct sSymbol *
sym_FindMacro(char *s) sym_FindMacro(char *s)
{ {
return (findsymbol(s, NULL)); return (findsymbol(s, NULL));
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add an equated symbol
*
*/
/*
* Add an equated symbol
*/
void void
sym_AddEqu(char *tzSym, SLONG value) 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 void
sym_AddString(char *tzSym, char *tzValue) sym_AddString(char *tzSym, char *tzValue)
{ {
@@ -582,13 +517,10 @@ sym_AddString(char *tzSym, char *tzValue)
nsym->pScope = NULL; 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 ULONG
sym_isString(char *tzSym) sym_isString(char *tzSym)
{ {
@@ -600,13 +532,10 @@ sym_isString(char *tzSym)
} }
return (0); return (0);
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Alter a SET symbols value
*
*/
/*
* Alter a SET symbols value
*/
void void
sym_AddSet(char *tzSym, SLONG value) sym_AddSet(char *tzSym, SLONG value)
{ {
@@ -622,13 +551,10 @@ sym_AddSet(char *tzSym, SLONG value)
nsym->pScope = NULL; nsym->pScope = NULL;
} }
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a local (.name) relocatable symbol
*
*/
/*
* Add a local (.name) relocatable symbol
*/
void void
sym_AddLocalReloc(char *tzSym) sym_AddLocalReloc(char *tzSym)
{ {
@@ -656,13 +582,10 @@ sym_AddLocalReloc(char *tzSym)
fatalerror("Local label in main scope"); fatalerror("Local label in main scope");
} }
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a relocatable symbol
*
*/
/*
* Add a relocatable symbol
*/
void void
sym_AddReloc(char *tzSym) sym_AddReloc(char *tzSym)
{ {
@@ -686,15 +609,11 @@ sym_AddReloc(char *tzSym)
} }
} }
pScope = findsymbol(tzSym, NULL); pScope = findsymbol(tzSym, NULL);
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Export a symbol
*
*/
/*
* Export a symbol
*/
void void
sym_Export(char *tzSym) sym_Export(char *tzSym)
{ {
@@ -718,13 +637,10 @@ sym_Export(char *tzSym)
} }
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Import a symbol
*
*/
/*
* Import a symbol
*/
void void
sym_Import(char *tzSym) sym_Import(char *tzSym)
{ {
@@ -739,13 +655,10 @@ sym_Import(char *tzSym)
nsym->nType |= SYMF_IMPORT; 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 void
sym_Global(char *tzSym) 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 void
sym_AddMacro(char *tzSym) 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 void
sym_PrepPass1(void) sym_PrepPass1(void)
{ {
sym_Init(); sym_Init();
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Prepare for pass #2
*
*/
/*
* Prepare for pass #2
*/
void void
sym_PrepPass2(void) sym_PrepPass2(void)
{ {
@@ -847,14 +751,13 @@ sym_PrepPass2(void)
sym_AddEqu("_NARG", 0); sym_AddEqu("_NARG", 0);
p_NARGSymbol = findsymbol("_NARG", NULL); p_NARGSymbol = findsymbol("_NARG", NULL);
p_NARGSymbol->Callback = Callback_NARG; p_NARGSymbol->Callback = Callback_NARG;
math_DefinePI();
} }
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Initialise the symboltable
*
*/
/*
* Initialize the symboltable
*/
void void
sym_Init(void) sym_Init(void)
{ {
@@ -891,72 +794,3 @@ sym_Init(void)
math_DefinePI(); 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 <stdlib.h>
#include "extern/err.h" #include "extern/err.h"
#ifndef __MINGW32__ extern char *progname;
char *__progname;
#endif
void rgbds_vwarn(const char *fmt, va_list ap) void rgbds_vwarn(const char *fmt, va_list ap)
{ {
fprintf (stderr, "%s: ", __progname); fprintf (stderr, "%s: ", progname);
if (fmt) { if (fmt) {
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fputs (": ", stderr); fputs (": ", stderr);
@@ -42,18 +40,18 @@ void rgbds_vwarn(const char *fmt, va_list ap)
void rgbds_vwarnx(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); if (fmt) vfprintf(stderr, fmt, ap);
putc('\n', stderr); 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); vwarn(fmt, ap);
exit(status); 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); vwarnx(fmt, ap);
exit(status); exit(status);
@@ -75,7 +73,7 @@ void rgbds_warnx(const char *fmt, ...)
va_end(ap); 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_list ap;
va_start(ap, fmt); va_start(ap, fmt);
@@ -83,7 +81,7 @@ _Noreturn void rgbds_err(int status, const char *fmt, ...)
va_end(ap); 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_list ap;
va_start(ap, fmt); 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 * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -20,36 +20,36 @@
#include <string.h> #include <string.h>
/* /*
* Appends src to string dst of size siz (unlike strncat, siz is the * Appends src to string dst of size dsize (unlike strncat, dsize is the
* full size of dst, not space left). At most siz-1 characters * full size of dst, not space left). At most dsize-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)). * will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)). * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
* If retval >= siz, truncation occurred. * If retval >= dsize, truncation occurred.
*/ */
size_t 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 *odst = dst;
const char *s = src; const char *osrc = src;
size_t n = siz; size_t n = dsize;
size_t dlen; size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */ /* Find the end of dst and adjust bytes left but don't go past end. */
while (n-- != 0 && *d != '\0') while (n-- != 0 && *dst != '\0')
d++; dst++;
dlen = d - dst; dlen = dst - odst;
n = siz - dlen; n = dsize - dlen;
if (n == 0) if (n-- == 0)
return(dlen + strlen(s)); return(dlen + strlen(src));
while (*s != '\0') { while (*src != '\0') {
if (n != 1) { if (n != 0) {
*d++ = *s; *dst++ = *src;
n--; 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 * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -20,32 +20,31 @@
#include <string.h> #include <string.h>
/* /*
* Copy src to string dst of size siz. At most siz-1 characters * Copy string src to buffer dst of size dsize. At most dsize-1
* will be copied. Always NUL terminates (unless siz == 0). * chars will be copied. Always NUL terminates (unless dsize == 0).
* Returns strlen(src); if retval >= siz, truncation occurred. * Returns strlen(src); if retval >= dsize, truncation occurred.
*/ */
size_t 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 *osrc = src;
const char *s = src; size_t nleft = dsize;
size_t n = siz;
/* Copy as many bytes as will fit */ /* Copy as many bytes as will fit. */
if (n != 0) { if (nleft != 0) {
while (--n != 0) { while (--nleft != 0) {
if ((*d++ = *s++) == '\0') if ((*dst++ = *src++) == '\0')
break; break;
} }
} }
/* Not enough room in dst, add NUL and traverse rest of src */ /* Not enough room in dst, add NUL and traverse rest of src. */
if (n == 0) { if (nleft == 0) {
if (siz != 0) if (dsize != 0)
*d = '\0'; /* NUL-terminate dst */ *dst = '\0'; /* NUL-terminate dst */
while (*s++) 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. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#define _XOPEN_SOURCE 500
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@@ -24,13 +23,15 @@
#include "extern/err.h" #include "extern/err.h"
char *progname;
static void static void
usage(void) usage(void)
{ {
printf("usage: rgbfix [-Ccjsv] [-i game_id] [-k licensee_str] " printf(
"[-l licensee_id]\n" " [-m mbc_type] [-n rom_version] " "usage: rgbfix [-Ccjsv] [-i game_id] [-k licensee_str] [-l licensee_id]\n"
"[-p pad_value] [-r ram_size]\n" " [-m mbc_type] [-n rom_version] [-p pad_value] [-r ram_size]\n"
" [-t title_str] file.gb\n"); " [-t title_str] file\n");
exit(1); exit(1);
} }
@@ -41,17 +42,6 @@ main(int argc, char *argv[])
int ch; int ch;
char *ep; 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 * Parse command-line options
*/ */
@@ -71,15 +61,17 @@ main(int argc, char *argv[])
bool resize = false; bool resize = false;
bool setversion = false; bool setversion = false;
char *title = NULL; /* game title in ASCII */ char *title; /* game title in ASCII */
char *id = NULL; /* game ID in ASCII */ char *id; /* game ID in ASCII */
char *newlicensee = NULL; /* new licensee ID, two ASCII characters */ char *newlicensee; /* new licensee ID, two ASCII characters */
int licensee = -1; /* old licensee ID */ int licensee; /* old licensee ID */
int cartridge = -1; /* cartridge hardware ID */ int cartridge; /* cartridge hardware ID */
int ramsize = -1; /* RAM size ID */ int ramsize; /* RAM size ID */
int version = -1; /* mask ROM version number */ int version; /* mask ROM version number */
int padvalue = -1; /* to pad the rom with if it changes size */ 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) { while ((ch = getopt(argc, argv, "Cci:jk:l:m:n:p:sr:t:v")) != -1) {
switch (ch) { 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 * 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. */ /* 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; uint8_t *buf;
fseek(rom, 0, SEEK_END); fseek(rom, 0, SEEK_END);
romsize = ftell(rom); romsize = ftell(rom);

View File

@@ -1,4 +1,4 @@
.Dd $Mdocdate$ .Dd February 26, 2015
.Dt RGBFIX 1 .Dt RGBFIX 1
.Os RGBDS Manual .Os RGBDS Manual
.Sh NAME .Sh NAME
@@ -41,7 +41,7 @@ flag are set,
takes precedence. takes precedence.
.It Fl i Ar game_id .It Fl i Ar game_id
Set the game ID string 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. to a given string of exactly 4 characters.
If both this and the title are set, the game ID will overwrite the If both this and the title are set, the game ID will overwrite the
overlapping portion of the title. overlapping portion of the title.
@@ -51,7 +51,7 @@ Set the non-Japanese region flag:
= 1. = 1.
.It Fl k Ar licensee_str .It Fl k Ar licensee_str
Set the new licensee string 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. to a given string, truncated to at most two characters.
.It Fl l Ar licensee_id .It Fl l Ar licensee_id
Set the old licensee code, Set the old licensee code,
@@ -84,7 +84,7 @@ Set the SGB flag:
= 3. = 3.
.It Fl t Ar title .It Fl t Ar title
Set the title string 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. to a given string, truncated to at most 16 characters.
It is recommended to use 15 characters instead, to avoid clashing with the CGB It is recommended to use 15 characters instead, to avoid clashing with the CGB
flag 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. overlapping portion of the title.
.It Fl v .It Fl v
Validate the header and fix checksums: the Nintendo character area 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 the header checksum
.Pq Ad 0x14D , .Pq Ad 0x14D ,
and the global checksum and the global checksum
.Pq Ad 0x14E No Ns \(en Ns Ad 0x14F . .Pq Ad 0x14E Ns \(en Ns Ad 0x14F .
.El .El
.Sh EXAMPLES .Sh EXAMPLES
Most values in the ROM header are only cosmetic. 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 The following will make a plain, no-color Game Boy game without checking for
a valid size: a valid size:
.Pp .Pp
.D1 $ rgbfix \-v foo.gb .D1 $ rgbfix -v foo.gb
.Pp .Pp
The following will make a SGB-enabled, color-enabled game with a title of The following will make a SGB-enabled, color-enabled game with a title of
.Dq foobar , .Dq foobar ,
@@ -119,19 +119,19 @@ The Game Boy itself does not use the title, but some emulators or ROM managers
might. might.
.Pc .Pc
.Pp .Pp
.D1 $ rgbfix \-vcs \-l 0x33 \-p 0 \-t foobar baz.gb .D1 $ rgbfix -vcs -l 0x33 -p 0 -t foobar baz.gb
.Pp .Pp
The following will duplicate the header The following will duplicate the header
.Pq sans global checksum .Pq sans global checksum
of the game of the game
.Dq Survival Kids : .Dq Survival Kids :
.Pp .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 .Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbasm 1 , .Xr rgbasm 1 ,
.Xr rgblink 1 , .Xr rgblink 1 ,
.Xr gbz80 7 .Xr rgbds 7
.Sh HISTORY .Sh HISTORY
.Nm .Nm
was originally released by Carsten S\(/orensen as a standalone program called 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) { if ((org = area_AllocSRAMAnyBank(pSection->nByteSize)) != -1) {
pSection->nOrg = org & 0xFFFF; pSection->nOrg = org & 0xFFFF;
pSection->nBank = org >> 16; pSection->nBank = org >> 16;
pSection->nBank += BANK_SRAM;
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank); DOMAXSBANK(pSection->nBank);
} else { } else {
@@ -343,6 +344,7 @@ AssignWRAMSections(void)
if ((org = area_AllocWRAMAnyBank(pSection->nByteSize)) != -1) { if ((org = area_AllocWRAMAnyBank(pSection->nByteSize)) != -1) {
pSection->nOrg = org & 0xFFFF; pSection->nOrg = org & 0xFFFF;
pSection->nBank = org >> 16; pSection->nBank = org >> 16;
pSection->nBank += BANK_WRAMX - 1;
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank); DOMAXWBANK(pSection->nBank);
} else { } else {
@@ -557,8 +559,8 @@ AssignSections(void)
* bank are hardcoded. * bank are hardcoded.
*/ */
if (pSection->nBank >= 1 if (pSection->nBank >= 0
&& pSection->nBank <= 7) { && pSection->nBank <= 6) {
pSection->nBank += pSection->nBank +=
BANK_WRAMX; BANK_WRAMX;
if (area_AllocAbs if (area_AllocAbs

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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