mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Cleanup code of rgbasm
Follow Linux kernel coding style. Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
/* asm.h
|
||||
/*
|
||||
* asm.h
|
||||
*
|
||||
* Contains some assembler-wide defines and externs
|
||||
*
|
||||
* Copyright 1997 Carsten Sorensen
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RGBDS_ASM_ASM_H
|
||||
@@ -36,4 +36,4 @@ extern struct sSymbol *tHashedSymbols[HASHSIZE];
|
||||
extern struct sSymbol *pPCSymbol;
|
||||
extern bool oDontExpandStrings;
|
||||
|
||||
#endif /* // ASM_H */
|
||||
#endif /* RGBDS_ASM_ASM_H */
|
||||
|
||||
@@ -13,8 +13,7 @@ struct Charmap {
|
||||
};
|
||||
|
||||
int32_t readUTF8Char(char *destination, char *source);
|
||||
void charmap_Sort();
|
||||
int32_t charmap_Add(char *input, uint8_t output);
|
||||
int32_t charmap_Convert(char **input);
|
||||
|
||||
#endif
|
||||
#endif /* RGBDS_ASM_CHARMAP_H */
|
||||
|
||||
@@ -31,16 +31,16 @@ struct sContext {
|
||||
uint32_t nREPTBlockSize;
|
||||
};
|
||||
|
||||
void fstk_RunInclude(char *);
|
||||
extern void fstk_RunMacroArg(int32_t s);
|
||||
void fstk_Init(char *);
|
||||
extern void fstk_Dump(void);
|
||||
extern void fstk_AddIncludePath(char *s);
|
||||
extern uint32_t fstk_RunMacro(char *s);
|
||||
extern void fstk_RunRept(uint32_t count);
|
||||
FILE * fstk_FindFile(char *);
|
||||
void fstk_RunInclude(char *tzFileName);
|
||||
void fstk_RunMacroArg(int32_t s);
|
||||
void fstk_Init(char *s);
|
||||
void fstk_Dump(void);
|
||||
void fstk_AddIncludePath(char *s);
|
||||
uint32_t fstk_RunMacro(char *s);
|
||||
void fstk_RunRept(uint32_t count);
|
||||
FILE *fstk_FindFile(char *fname);
|
||||
int32_t fstk_GetLine(void);
|
||||
|
||||
extern int yywrap(void);
|
||||
|
||||
#endif
|
||||
#endif /* RGBDS_ASM_FSTACK_H */
|
||||
|
||||
@@ -13,14 +13,15 @@ struct sLexInitString {
|
||||
};
|
||||
|
||||
struct sLexFloat {
|
||||
uint32_t(*Callback) (char *s, uint32_t size);
|
||||
uint32_t (*Callback)(char *s, uint32_t size);
|
||||
uint32_t nToken;
|
||||
};
|
||||
|
||||
struct yy_buffer_state {
|
||||
char *pBufferRealStart; // actual starting address
|
||||
char *pBufferStart; // address where the data is initially written
|
||||
// after the "safety margin"
|
||||
/* Actual starting address */
|
||||
char *pBufferRealStart;
|
||||
/* Address where the data is initially written after a safety margin */
|
||||
char *pBufferStart;
|
||||
char *pBuffer;
|
||||
uint32_t nBufferSize;
|
||||
uint32_t oAtLineStart;
|
||||
@@ -30,35 +31,36 @@ enum eLexerState {
|
||||
LEX_STATE_NORMAL,
|
||||
LEX_STATE_MACROARGS
|
||||
};
|
||||
|
||||
#define INITIAL 0
|
||||
#define macroarg 3
|
||||
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
|
||||
extern void yy_set_state(enum eLexerState i);
|
||||
extern YY_BUFFER_STATE yy_create_buffer(FILE * f);
|
||||
extern YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size);
|
||||
extern void yy_delete_buffer(YY_BUFFER_STATE);
|
||||
extern void yy_switch_to_buffer(YY_BUFFER_STATE);
|
||||
extern uint32_t lex_FloatAlloc(struct sLexFloat * tok);
|
||||
extern void lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
extern void lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
extern void lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
extern void lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
extern void lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
extern void lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
extern void lex_Init(void);
|
||||
extern void lex_AddStrings(struct sLexInitString * lex);
|
||||
extern void lex_SetBuffer(char *buffer, uint32_t len);
|
||||
extern uint32_t yylex(void);
|
||||
extern void yyunput(char c);
|
||||
extern void yyunputstr(char *s);
|
||||
extern void yyskipbytes(uint32_t count);
|
||||
extern void yyunputbytes(uint32_t count);
|
||||
void yy_set_state(enum eLexerState i);
|
||||
YY_BUFFER_STATE yy_create_buffer(FILE *f);
|
||||
YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size);
|
||||
void yy_delete_buffer(YY_BUFFER_STATE buf);
|
||||
void yy_switch_to_buffer(YY_BUFFER_STATE buf);
|
||||
uint32_t lex_FloatAlloc(const struct sLexFloat *tok);
|
||||
void lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
void lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
void lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
void lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
void lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
void lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end);
|
||||
void lex_Init(void);
|
||||
void lex_AddStrings(const struct sLexInitString *lex);
|
||||
void lex_SetBuffer(char *buffer, uint32_t len);
|
||||
uint32_t yylex(void);
|
||||
void yyunput(char c);
|
||||
void yyunputstr(char *s);
|
||||
void yyskipbytes(uint32_t count);
|
||||
void yyunputbytes(uint32_t count);
|
||||
|
||||
extern YY_BUFFER_STATE pCurrentBuffer;
|
||||
|
||||
extern void upperstring(char *s);
|
||||
extern void lowerstring(char *s);
|
||||
void upperstring(char *s);
|
||||
void lowerstring(char *s);
|
||||
|
||||
#endif
|
||||
#endif /* RGBDS_ASM_LEXER_H */
|
||||
|
||||
@@ -1,83 +1,86 @@
|
||||
/* GB Z80 instruction groups
|
||||
|
||||
n3 = 3-bit
|
||||
n = 8-bit
|
||||
nn = 16-bit
|
||||
|
||||
* ADC A,n : 0xCE
|
||||
* ADC A,r : 0x88|r
|
||||
* ADD A,n : 0xC6
|
||||
* ADD A,r : 0x80|r
|
||||
* ADD HL,ss : 0x09|(ss<<4)
|
||||
* ADD SP,n : 0xE8
|
||||
* AND A,n : 0xE6
|
||||
* AND A,r : 0xA0|r
|
||||
* BIT n3,r : 0xCB 0x40|(n3<<3)|r
|
||||
* CALL cc,nn : 0xC4|(cc<<3)
|
||||
* CALL nn : 0xCD
|
||||
* CCF : 0x3F
|
||||
* CP A,n : 0xFE
|
||||
* CP A,r : 0xB8|r
|
||||
* CPL : 0x2F
|
||||
* DAA : 0x27
|
||||
* DEC r : 0x05|(r<<3)
|
||||
* DEC ss : 0x0B|(ss<<4)
|
||||
* DI : 0xF3
|
||||
* EI : 0xFB
|
||||
* HALT : 0x76
|
||||
* INC r : 0x04|(r<<3)
|
||||
* INC ss : 0x03|(ss<<4)
|
||||
* JP HL : 0xE9
|
||||
* JP cc,nn : 0xC2|(cc<<3)
|
||||
* JP nn : 0xC3|(cc<<3)
|
||||
* JR n : 0x18
|
||||
* JR cc,n : 0x20|(cc<<3)
|
||||
* LD (nn),SP : 0x08
|
||||
* LD ($FF00+C),A : 0xE2
|
||||
* LD ($FF00+n),A : 0xE0
|
||||
* LD (nn),A : 0xEA
|
||||
* LD (rr),A : 0x02|(rr<<4) // HL+ and HL- included
|
||||
* LD A,($FF00+C) : 0xF2
|
||||
* LD A,($FF00+n) : 0xF0
|
||||
* LD A,(nn) : 0xFA
|
||||
* LD A,(rr) : 0x0A|(rr<<4) // HL+ and HL- included
|
||||
* LD HL,SP+n : 0xF8
|
||||
* LD SP,HL : 0xF9
|
||||
* LD r,n : 0x06|(r<<3)
|
||||
* LD r,r' : 0x40|(r<<3)|r' // NOTE: LD (HL),(HL) not allowed
|
||||
* LD ss,nn : 0x01|(ss<<4)
|
||||
* NOP : 0x00
|
||||
* OR A,n : 0xF6
|
||||
* OR A,r : 0xB0|r
|
||||
* POP tt : 0xC1|(tt<<4)
|
||||
* PUSH tt : 0xC5|(tt<<4)
|
||||
* RES n3,r : 0xCB 0x80|(n3<<3)|r
|
||||
* RET : 0xC9
|
||||
* RET cc : 0xC0|(cc<<3)
|
||||
* RETI : 0xD9
|
||||
* RL r : 0xCB 0x10|r
|
||||
* RLA : 0x17
|
||||
* RLC r : 0xCB 0x00|r
|
||||
* RLCA : 0x07
|
||||
* RR r : 0xCB 0x18|r
|
||||
* RRA : 0x1F
|
||||
* RRC r : 0xCB 0x08|r
|
||||
* RRCA : 0x0F
|
||||
* RST n : 0xC7|n
|
||||
* SBC A,n : 0xDE
|
||||
* SBC A,r : 0x98|r
|
||||
* SCF : 0x37
|
||||
* SET n3,r : 0xCB 0xC0|(n8<<3)|r
|
||||
* SLA r : 0xCB 0x20|r
|
||||
* SRA r : 0xCB 0x28|r
|
||||
* SRL r : 0xCB 0x38|r
|
||||
* STOP : 0x10 0x00
|
||||
* SUB A,n : 0xD6
|
||||
* SUB A,r : 0x90|r
|
||||
* SWAP r : 0xCB 0x30|r
|
||||
* XOR A,n : 0xEE
|
||||
* XOR A,r : 0xA8|r
|
||||
#ifndef RGBDS_ASM_LOCALASM_H
|
||||
#define RGBDS_ASM_LOCALASM_H
|
||||
|
||||
/*
|
||||
* GB Z80 instruction groups
|
||||
*
|
||||
* n3 = 3-bit
|
||||
* n = 8-bit
|
||||
* nn = 16-bit
|
||||
*
|
||||
* ADC A,n : 0xCE
|
||||
* ADC A,r : 0x88|r
|
||||
* ADD A,n : 0xC6
|
||||
* ADD A,r : 0x80|r
|
||||
* ADD HL,ss : 0x09|(ss<<4)
|
||||
* ADD SP,n : 0xE8
|
||||
* AND A,n : 0xE6
|
||||
* AND A,r : 0xA0|r
|
||||
* BIT n3,r : 0xCB 0x40|(n3<<3)|r
|
||||
* CALL cc,nn : 0xC4|(cc<<3)
|
||||
* CALL nn : 0xCD
|
||||
* CCF : 0x3F
|
||||
* CP A,n : 0xFE
|
||||
* CP A,r : 0xB8|r
|
||||
* CPL : 0x2F
|
||||
* DAA : 0x27
|
||||
* DEC r : 0x05|(r<<3)
|
||||
* DEC ss : 0x0B|(ss<<4)
|
||||
* DI : 0xF3
|
||||
* EI : 0xFB
|
||||
* HALT : 0x76
|
||||
* INC r : 0x04|(r<<3)
|
||||
* INC ss : 0x03|(ss<<4)
|
||||
* JP HL : 0xE9
|
||||
* JP cc,nn : 0xC2|(cc<<3)
|
||||
* JP nn : 0xC3|(cc<<3)
|
||||
* JR n : 0x18
|
||||
* JR cc,n : 0x20|(cc<<3)
|
||||
* LD (nn),SP : 0x08
|
||||
* LD ($FF00+C),A : 0xE2
|
||||
* LD ($FF00+n),A : 0xE0
|
||||
* LD (nn),A : 0xEA
|
||||
* LD (rr),A : 0x02|(rr<<4) // HL+ and HL- included
|
||||
* LD A,($FF00+C) : 0xF2
|
||||
* LD A,($FF00+n) : 0xF0
|
||||
* LD A,(nn) : 0xFA
|
||||
* LD A,(rr) : 0x0A|(rr<<4) // HL+ and HL- included
|
||||
* LD HL,SP+n : 0xF8
|
||||
* LD SP,HL : 0xF9
|
||||
* LD r,n : 0x06|(r<<3)
|
||||
* LD r,r' : 0x40|(r<<3)|r' // NOTE: LD (HL),(HL) not allowed
|
||||
* LD ss,nn : 0x01|(ss<<4)
|
||||
* NOP : 0x00
|
||||
* OR A,n : 0xF6
|
||||
* OR A,r : 0xB0|r
|
||||
* POP tt : 0xC1|(tt<<4)
|
||||
* PUSH tt : 0xC5|(tt<<4)
|
||||
* RES n3,r : 0xCB 0x80|(n3<<3)|r
|
||||
* RET : 0xC9
|
||||
* RET cc : 0xC0|(cc<<3)
|
||||
* RETI : 0xD9
|
||||
* RL r : 0xCB 0x10|r
|
||||
* RLA : 0x17
|
||||
* RLC r : 0xCB 0x00|r
|
||||
* RLCA : 0x07
|
||||
* RR r : 0xCB 0x18|r
|
||||
* RRA : 0x1F
|
||||
* RRC r : 0xCB 0x08|r
|
||||
* RRCA : 0x0F
|
||||
* RST n : 0xC7|n
|
||||
* SBC A,n : 0xDE
|
||||
* SBC A,r : 0x98|r
|
||||
* SCF : 0x37
|
||||
* SET n3,r : 0xCB 0xC0|(n8<<3)|r
|
||||
* SLA r : 0xCB 0x20|r
|
||||
* SRA r : 0xCB 0x28|r
|
||||
* SRL r : 0xCB 0x38|r
|
||||
* STOP : 0x10 0x00
|
||||
* SUB A,n : 0xD6
|
||||
* SUB A,r : 0x90|r
|
||||
* SWAP r : 0xCB 0x30|r
|
||||
* XOR A,n : 0xEE
|
||||
* XOR A,r : 0xA8|r
|
||||
*/
|
||||
|
||||
#define NAME_DB "db"
|
||||
@@ -87,7 +90,6 @@
|
||||
#define NAME_RW "rw"
|
||||
|
||||
/* "r" defs */
|
||||
|
||||
enum {
|
||||
REG_B = 0,
|
||||
REG_C,
|
||||
@@ -98,36 +100,30 @@ enum {
|
||||
REG_HL_IND,
|
||||
REG_A
|
||||
};
|
||||
/* "rr" defs */
|
||||
|
||||
/* "rr" defs */
|
||||
enum {
|
||||
REG_BC_IND = 0,
|
||||
REG_DE_IND,
|
||||
REG_HL_INDINC,
|
||||
REG_HL_INDDEC,
|
||||
};
|
||||
/* "ss" defs */
|
||||
|
||||
/* "ss" defs (SP) and "tt" defs (AF) */
|
||||
enum {
|
||||
REG_BC = 0,
|
||||
REG_DE,
|
||||
REG_HL,
|
||||
REG_SP
|
||||
REG_DE = 1,
|
||||
REG_HL = 2,
|
||||
REG_SP = 3,
|
||||
REG_AF = 3
|
||||
};
|
||||
/* "tt" defs */
|
||||
|
||||
/*
|
||||
#define REG_BC 0
|
||||
#define REG_DE 1
|
||||
#define REG_HL 2
|
||||
*/
|
||||
#define REG_AF 3
|
||||
|
||||
/* "cc" defs */
|
||||
|
||||
enum {
|
||||
CC_NZ = 0,
|
||||
CC_Z,
|
||||
CC_NC,
|
||||
CC_C
|
||||
};
|
||||
|
||||
#endif /* RGBDS_ASM_LOCALASM_H */
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef RGBDS_MAIN_H
|
||||
#define RGBDS_MAIN_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "extern/stdnoreturn.h"
|
||||
|
||||
struct sOptions {
|
||||
@@ -12,8 +13,7 @@ struct sOptions {
|
||||
bool verbose;
|
||||
bool haltnop;
|
||||
bool exportall;
|
||||
bool warnings; /* true to enable warnings, false to disable them. */
|
||||
//-1 == random
|
||||
bool warnings; /* True to enable warnings, false to disable them. */
|
||||
};
|
||||
|
||||
extern char *tzNewMacro;
|
||||
@@ -23,9 +23,10 @@ extern int32_t nBinaryID;
|
||||
|
||||
extern struct sOptions DefaultOptions;
|
||||
extern struct sOptions CurrentOptions;
|
||||
extern void opt_Push(void);
|
||||
extern void opt_Pop(void);
|
||||
extern void opt_Parse(char *s);
|
||||
|
||||
void opt_Push(void);
|
||||
void opt_Pop(void);
|
||||
void opt_Parse(char *s);
|
||||
|
||||
/*
|
||||
* Used for errors that compromise the whole assembly process by affecting the
|
||||
@@ -35,6 +36,7 @@ extern void opt_Parse(char *s);
|
||||
* when it fails to allocate memory).
|
||||
*/
|
||||
noreturn void fatalerror(const char *fmt, ...);
|
||||
|
||||
/*
|
||||
* Used for errors that make it impossible to assemble correctly, but don't
|
||||
* affect the following code. The code will fail to assemble but the user will
|
||||
@@ -42,6 +44,7 @@ noreturn void fatalerror(const char *fmt, ...);
|
||||
* once.
|
||||
*/
|
||||
void yyerror(const char *fmt, ...);
|
||||
|
||||
/*
|
||||
* Used to warn the user about problems that don't prevent the generation of
|
||||
* valid code.
|
||||
@@ -55,4 +58,4 @@ void warning(const char *fmt, ...);
|
||||
#endif
|
||||
#define YYLMAX 65536
|
||||
|
||||
#endif
|
||||
#endif /* RGBDS_MAIN_H */
|
||||
|
||||
@@ -58,4 +58,5 @@ enum {
|
||||
PATCH_WORD_L,
|
||||
PATCH_LONG_L
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* RGBDS_ASM_LINK_H */
|
||||
|
||||
@@ -18,4 +18,4 @@ int32_t math_Round(int32_t i);
|
||||
int32_t math_Ceil(int32_t i);
|
||||
int32_t math_Floor(int32_t i);
|
||||
|
||||
#endif
|
||||
#endif /* RGBDS_ASM_MATH_H */
|
||||
|
||||
@@ -21,21 +21,23 @@ struct Section {
|
||||
void out_PrepPass2(void);
|
||||
void out_SetFileName(char *s);
|
||||
void out_NewSection(char *pzName, uint32_t secttype);
|
||||
void out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank);
|
||||
void out_NewAlignedSection(char *pzName, uint32_t secttype, int32_t alignment, int32_t bank);
|
||||
void out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org,
|
||||
int32_t bank);
|
||||
void out_NewAlignedSection(char *pzName, uint32_t secttype, int32_t alignment,
|
||||
int32_t bank);
|
||||
void out_AbsByte(int32_t b);
|
||||
void out_AbsByteGroup(char *s, int32_t length);
|
||||
void out_RelByte(struct Expression * expr);
|
||||
void out_RelWord(struct Expression * expr);
|
||||
void out_PCRelByte(struct Expression * expr);
|
||||
void out_RelByte(struct Expression *expr);
|
||||
void out_RelWord(struct Expression *expr);
|
||||
void out_PCRelByte(struct Expression *expr);
|
||||
void out_WriteObject(void);
|
||||
void out_Skip(int32_t skip);
|
||||
void out_BinaryFile(char *s);
|
||||
void out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length);
|
||||
void out_String(char *s);
|
||||
void out_AbsLong(int32_t b);
|
||||
void out_RelLong(struct Expression * expr);
|
||||
void out_RelLong(struct Expression *expr);
|
||||
void out_PushSection(void);
|
||||
void out_PopSection(void);
|
||||
|
||||
#endif
|
||||
#endif /* RGBDS_ASM_OUTPUT_H */
|
||||
|
||||
@@ -12,36 +12,54 @@ struct Expression {
|
||||
uint32_t isPCRel;
|
||||
};
|
||||
|
||||
uint32_t rpn_isReloc(struct Expression * expr);
|
||||
uint32_t rpn_isPCRelative(struct Expression * expr);
|
||||
void rpn_Symbol(struct Expression * expr, char *tzSym);
|
||||
void rpn_Number(struct Expression * expr, uint32_t i);
|
||||
void rpn_LOGNOT(struct Expression * expr, struct Expression * src1);
|
||||
void rpn_LOGOR(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_LOGAND(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_LOGEQU(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_LOGGT(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_LOGLT(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_LOGGE(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_LOGLE(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_LOGNE(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_ADD(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_SUB(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_XOR(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_OR(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_AND(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_SHL(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_SHR(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_MUL(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_DIV(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_MOD(struct Expression * expr, struct Expression * src1, struct Expression * src2);
|
||||
void rpn_HIGH(struct Expression * expr, struct Expression * src);
|
||||
void rpn_LOW(struct Expression * expr, struct Expression * src);
|
||||
void rpn_UNNEG(struct Expression * expr, struct Expression * src);
|
||||
void rpn_UNNOT(struct Expression * expr, struct Expression * src);
|
||||
uint16_t rpn_PopByte(struct Expression * expr);
|
||||
void rpn_Bank(struct Expression * expr, char *tzSym);
|
||||
void rpn_Reset(struct Expression * expr);
|
||||
void rpn_CheckHRAM(struct Expression * expr, struct Expression * src1);
|
||||
uint32_t rpn_isReloc(const struct Expression *expr);
|
||||
uint32_t rpn_isPCRelative(const struct Expression *expr);
|
||||
void rpn_Symbol(struct Expression *expr, char *tzSym);
|
||||
void rpn_Number(struct Expression *expr, uint32_t i);
|
||||
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
|
||||
void rpn_LOGOR(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_LOGAND(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_LOGEQU(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_LOGGT(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_LOGLT(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_LOGGE(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_LOGLE(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_LOGNE(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_ADD(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_SUB(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_XOR(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_OR(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_AND(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_SHL(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_SHR(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_MUL(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_DIV(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_MOD(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
void rpn_HIGH(struct Expression *expr, const struct Expression *src);
|
||||
void rpn_LOW(struct Expression *expr, const struct Expression *src);
|
||||
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
|
||||
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
|
||||
uint16_t rpn_PopByte(struct Expression *expr);
|
||||
void rpn_Bank(struct Expression *expr, char *tzSym);
|
||||
void rpn_Reset(struct Expression *expr);
|
||||
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
|
||||
|
||||
#endif
|
||||
#endif /* RGBDS_ASM_RPN_H */
|
||||
|
||||
@@ -17,27 +17,31 @@ struct sSymbol {
|
||||
struct Section *pSection;
|
||||
uint32_t ulMacroSize;
|
||||
char *pMacro;
|
||||
int32_t(*Callback) (struct sSymbol *);
|
||||
int32_t (*Callback)(struct sSymbol *);
|
||||
char tzFileName[_MAX_PATH + 1]; /* File where the symbol was defined. */
|
||||
uint32_t nFileLine; /* Line where the symbol was defined. */
|
||||
};
|
||||
#define SYMF_RELOC 0x001 /* symbol will be reloc'ed during
|
||||
* linking, it's absolute value is
|
||||
* unknown */
|
||||
#define SYMF_EQU 0x002 /* symbol is defined using EQU, will
|
||||
* not be changed during linking */
|
||||
#define SYMF_SET 0x004 /* symbol is (re)defined using SET,
|
||||
* will not be changed during linking */
|
||||
#define SYMF_EXPORT 0x008 /* symbol should be exported */
|
||||
#define SYMF_IMPORT 0x010 /* symbol is imported, it's value is
|
||||
* unknown */
|
||||
#define SYMF_LOCAL 0x020 /* symbol is a local symbol */
|
||||
#define SYMF_DEFINED 0x040 /* symbol has been defined, not only
|
||||
* referenced */
|
||||
#define SYMF_MACRO 0x080 /* symbol is a macro */
|
||||
#define SYMF_STRING 0x100 /* symbol is a stringsymbol */
|
||||
#define SYMF_CONST 0x200 /* symbol has a constant value, will
|
||||
* not be changed during linking */
|
||||
|
||||
/* Symbol will be relocated during linking, it's absolute value is unknown */
|
||||
#define SYMF_RELOC 0x001
|
||||
/* Symbol is defined using EQU, will not be changed during linking */
|
||||
#define SYMF_EQU 0x002
|
||||
/* Symbol is (re)defined using SET, will not be changed during linking */
|
||||
#define SYMF_SET 0x004
|
||||
/* Symbol should be exported */
|
||||
#define SYMF_EXPORT 0x008
|
||||
/* Symbol is imported, it's value is unknown */
|
||||
#define SYMF_IMPORT 0x010
|
||||
/* Symbol is a local symbol */
|
||||
#define SYMF_LOCAL 0x020
|
||||
/* Symbol has been defined, not only referenced */
|
||||
#define SYMF_DEFINED 0x040
|
||||
/* Symbol is a macro */
|
||||
#define SYMF_MACRO 0x080
|
||||
/* Symbol is a stringsymbol */
|
||||
#define SYMF_STRING 0x100
|
||||
/* Symbol has a constant value, will not be changed during linking */
|
||||
#define SYMF_CONST 0x200
|
||||
|
||||
uint32_t calchash(char *s);
|
||||
void sym_SetExportAll(uint8_t set);
|
||||
@@ -76,4 +80,4 @@ void sym_Purge(char *tzName);
|
||||
uint32_t sym_isConstDefined(char *tzName);
|
||||
int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2);
|
||||
|
||||
#endif
|
||||
#endif /* RGBDS_SYMBOL_H */
|
||||
|
||||
1489
src/asm/asmy.y
1489
src/asm/asmy.y
File diff suppressed because it is too large
Load Diff
@@ -24,31 +24,45 @@
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint8_t utf8d[] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
|
||||
0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
|
||||
0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
|
||||
0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
|
||||
1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
|
||||
1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
|
||||
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00..0f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10..1f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20..2f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30..3f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40..4f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50..5f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60..6f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70..7f */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80..8f */
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* 90..9f */
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* a0..af */
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* b0..bf */
|
||||
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* c0..cf */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* d0..df */
|
||||
0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, /* e0..e7 */
|
||||
0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, /* e8..ef */
|
||||
0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, /* f0..f7 */
|
||||
0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, /* f8..ff */
|
||||
0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, /* s0.. */
|
||||
0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, /* ..s0 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* s1 */
|
||||
1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, /* s1 */
|
||||
1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, /* s3 */
|
||||
1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, /* s4 */
|
||||
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, /* s5 */
|
||||
1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, /* s6 */
|
||||
1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, /* s7 */
|
||||
1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* s8 */
|
||||
};
|
||||
|
||||
uint32_t
|
||||
decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
|
||||
uint32_t decode(uint32_t *state, uint32_t *codep, uint32_t byte)
|
||||
{
|
||||
uint32_t type = utf8d[byte];
|
||||
|
||||
*codep = (*state != 0) ?
|
||||
(byte & 0x3fu) | (*codep << 6) :
|
||||
(0xff >> type) & (byte);
|
||||
|
||||
*state = utf8d[256 + *state*16 + type];
|
||||
*state = utf8d[256 + *state * 16 + type];
|
||||
return *state;
|
||||
}
|
||||
|
||||
@@ -79,19 +93,15 @@ decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
|
||||
|
||||
struct Charmap globalCharmap = {0};
|
||||
|
||||
extern struct Section *pCurrentSection;
|
||||
|
||||
int32_t
|
||||
readUTF8Char(char *dest, char *src)
|
||||
int32_t readUTF8Char(char *dest, char *src)
|
||||
{
|
||||
uint32_t state;
|
||||
uint32_t codep;
|
||||
int32_t i;
|
||||
|
||||
for (i = 0, state = 0;; i++) {
|
||||
if (decode(&state, &codep, (uint8_t)src[i]) == 1) {
|
||||
if (decode(&state, &codep, (uint8_t)src[i]) == 1)
|
||||
fatalerror("invalid UTF-8 character");
|
||||
}
|
||||
|
||||
dest[i] = src[i];
|
||||
|
||||
@@ -104,13 +114,12 @@ readUTF8Char(char *dest, char *src)
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
charmap_Add(char *input, uint8_t output)
|
||||
int32_t charmap_Add(char *input, uint8_t output)
|
||||
{
|
||||
int32_t i;
|
||||
size_t input_length;
|
||||
char temp1i[CHARMAPLENGTH + 1], temp2i[CHARMAPLENGTH + 1], temp1o = 0,
|
||||
temp2o = 0;
|
||||
char temp1i[CHARMAPLENGTH + 1], temp2i[CHARMAPLENGTH + 1];
|
||||
char temp1o = 0, temp2o = 0;
|
||||
|
||||
struct Charmap *charmap;
|
||||
|
||||
@@ -118,23 +127,21 @@ charmap_Add(char *input, uint8_t output)
|
||||
if (pCurrentSection->charmap) {
|
||||
charmap = pCurrentSection->charmap;
|
||||
} else {
|
||||
if ((charmap = calloc(1, sizeof(struct Charmap))) ==
|
||||
NULL) {
|
||||
charmap = calloc(1, sizeof(struct Charmap));
|
||||
if (charmap == NULL)
|
||||
fatalerror("Not enough memory for charmap");
|
||||
}
|
||||
|
||||
pCurrentSection->charmap = charmap;
|
||||
}
|
||||
} else {
|
||||
charmap = &globalCharmap;
|
||||
}
|
||||
|
||||
if (nPass == 2) {
|
||||
if (nPass == 2)
|
||||
return charmap->count;
|
||||
}
|
||||
|
||||
if (charmap->count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH) {
|
||||
if (charmap->count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH)
|
||||
return -1;
|
||||
}
|
||||
|
||||
input_length = strlen(input);
|
||||
if (input_length > 1) {
|
||||
@@ -170,8 +177,7 @@ charmap_Add(char *input, uint8_t output)
|
||||
return ++charmap->count;
|
||||
}
|
||||
|
||||
int32_t
|
||||
charmap_Convert(char **input)
|
||||
int32_t charmap_Convert(char **input)
|
||||
{
|
||||
struct Charmap *charmap;
|
||||
|
||||
@@ -179,15 +185,14 @@ charmap_Convert(char **input)
|
||||
char *buffer;
|
||||
int32_t i, j, length;
|
||||
|
||||
if (pCurrentSection && pCurrentSection->charmap) {
|
||||
if (pCurrentSection && pCurrentSection->charmap)
|
||||
charmap = pCurrentSection->charmap;
|
||||
} else {
|
||||
else
|
||||
charmap = &globalCharmap;
|
||||
}
|
||||
|
||||
if ((buffer = malloc(strlen(*input))) == NULL) {
|
||||
buffer = malloc(strlen(*input));
|
||||
if (buffer == NULL)
|
||||
fatalerror("Not enough memory for buffer");
|
||||
}
|
||||
|
||||
length = 0;
|
||||
while (**input) {
|
||||
@@ -201,16 +206,16 @@ charmap_Convert(char **input)
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
if (!j) {
|
||||
|
||||
if (!j)
|
||||
j = readUTF8Char(outchar, *input);
|
||||
}
|
||||
|
||||
if (!outchar[0]) {
|
||||
buffer[length++] = 0;
|
||||
} else {
|
||||
for (i = 0; outchar[i]; i++) {
|
||||
for (i = 0; outchar[i]; i++)
|
||||
buffer[length++] = outchar[i];
|
||||
}
|
||||
}
|
||||
*input += j;
|
||||
}
|
||||
*input = buffer;
|
||||
|
||||
198
src/asm/fstack.c
198
src/asm/fstack.c
@@ -19,19 +19,19 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct sContext *pFileStack;
|
||||
struct sSymbol *pCurrentMacro;
|
||||
YY_BUFFER_STATE CurrentFlexHandle;
|
||||
FILE *pCurrentFile;
|
||||
uint32_t nCurrentStatus;
|
||||
static struct sContext *pFileStack;
|
||||
static struct sSymbol *pCurrentMacro;
|
||||
static YY_BUFFER_STATE CurrentFlexHandle;
|
||||
static FILE *pCurrentFile;
|
||||
static uint32_t nCurrentStatus;
|
||||
char tzCurrentFileName[_MAX_PATH + 1];
|
||||
char IncludePaths[MAXINCPATHS][_MAX_PATH + 1];
|
||||
int32_t NextIncPath = 0;
|
||||
uint32_t nMacroCount;
|
||||
static char IncludePaths[MAXINCPATHS][_MAX_PATH + 1];
|
||||
static int32_t NextIncPath;
|
||||
static uint32_t nMacroCount;
|
||||
|
||||
char *pCurrentREPTBlock;
|
||||
uint32_t nCurrentREPTBlockSize;
|
||||
uint32_t nCurrentREPTBlockCount;
|
||||
static char *pCurrentREPTBlock;
|
||||
static uint32_t nCurrentREPTBlockSize;
|
||||
static uint32_t nCurrentREPTBlockCount;
|
||||
|
||||
uint32_t ulMacroReturnValue;
|
||||
|
||||
@@ -49,8 +49,7 @@ extern FILE *dependfile;
|
||||
/*
|
||||
* Context push and pop
|
||||
*/
|
||||
void
|
||||
pushcontext(void)
|
||||
static void pushcontext(void)
|
||||
{
|
||||
struct sContext **ppFileStack;
|
||||
|
||||
@@ -58,12 +57,16 @@ pushcontext(void)
|
||||
while (*ppFileStack)
|
||||
ppFileStack = &((*ppFileStack)->pNext);
|
||||
|
||||
if ((*ppFileStack = malloc(sizeof(struct sContext))) != NULL) {
|
||||
*ppFileStack = malloc(sizeof(struct sContext));
|
||||
|
||||
if (*ppFileStack == NULL)
|
||||
fatalerror("No memory for context");
|
||||
|
||||
(*ppFileStack)->FlexHandle = CurrentFlexHandle;
|
||||
(*ppFileStack)->pNext = NULL;
|
||||
strcpy((char *) (*ppFileStack)->tzFileName,
|
||||
(char *) tzCurrentFileName);
|
||||
strcpy((char *)(*ppFileStack)->tzFileName, (char *)tzCurrentFileName);
|
||||
(*ppFileStack)->nLine = nLineNo;
|
||||
|
||||
switch ((*ppFileStack)->nStatus = nCurrentStatus) {
|
||||
case STAT_isMacroArg:
|
||||
case STAT_isMacro:
|
||||
@@ -77,17 +80,14 @@ pushcontext(void)
|
||||
sym_SaveCurrentMacroArgs((*ppFileStack)->tzMacroArgs);
|
||||
(*ppFileStack)->pREPTBlock = pCurrentREPTBlock;
|
||||
(*ppFileStack)->nREPTBlockSize = nCurrentREPTBlockSize;
|
||||
(*ppFileStack)->nREPTBlockCount =
|
||||
nCurrentREPTBlockCount;
|
||||
(*ppFileStack)->nREPTBlockCount = nCurrentREPTBlockCount;
|
||||
break;
|
||||
}
|
||||
|
||||
nLineNo = 0;
|
||||
} else
|
||||
fatalerror("No memory for context");
|
||||
}
|
||||
|
||||
static int32_t
|
||||
popcontext(void)
|
||||
static int32_t popcontext(void)
|
||||
{
|
||||
struct sContext *pLastFile, **ppLastFile;
|
||||
|
||||
@@ -101,10 +101,14 @@ popcontext(void)
|
||||
sym_UseCurrentMacroArgs();
|
||||
sym_SetMacroArgID(nMacroCount++);
|
||||
sym_UseNewMacroArgs();
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ((pLastFile = pFileStack) != NULL) {
|
||||
|
||||
pLastFile = pFileStack;
|
||||
if (pLastFile == NULL)
|
||||
return 1;
|
||||
|
||||
ppLastFile = &pFileStack;
|
||||
while (pLastFile->pNext) {
|
||||
ppLastFile = &(pLastFile->pNext);
|
||||
@@ -113,18 +117,21 @@ popcontext(void)
|
||||
|
||||
yy_delete_buffer(CurrentFlexHandle);
|
||||
nLineNo = pLastFile->nLine;
|
||||
|
||||
if (nCurrentStatus == STAT_isInclude)
|
||||
fclose(pCurrentFile);
|
||||
|
||||
if (nCurrentStatus == STAT_isMacro) {
|
||||
sym_FreeCurrentMacroArgs();
|
||||
nLineNo += 1;
|
||||
}
|
||||
|
||||
if (nCurrentStatus == STAT_isREPTBlock)
|
||||
nLineNo += 1;
|
||||
|
||||
CurrentFlexHandle = pLastFile->FlexHandle;
|
||||
strcpy((char *) tzCurrentFileName,
|
||||
(char *) pLastFile->tzFileName);
|
||||
strcpy((char *)tzCurrentFileName, (char *)pLastFile->tzFileName);
|
||||
|
||||
switch (nCurrentStatus = pLastFile->nStatus) {
|
||||
case STAT_isMacroArg:
|
||||
case STAT_isMacro:
|
||||
@@ -145,13 +152,10 @@ popcontext(void)
|
||||
free(*ppLastFile);
|
||||
*ppLastFile = NULL;
|
||||
yy_switch_to_buffer(CurrentFlexHandle);
|
||||
return (0);
|
||||
} else
|
||||
return (1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
fstk_GetLine(void)
|
||||
int32_t fstk_GetLine(void)
|
||||
{
|
||||
struct sContext *pLastFile, **ppLastFile;
|
||||
|
||||
@@ -167,7 +171,9 @@ fstk_GetLine(void)
|
||||
break; /* Peek top file of the stack */
|
||||
}
|
||||
|
||||
if ((pLastFile = pFileStack) != NULL) {
|
||||
pLastFile = pFileStack;
|
||||
|
||||
if (pLastFile != NULL) {
|
||||
ppLastFile = &pFileStack;
|
||||
while (pLastFile->pNext) {
|
||||
ppLastFile = &(pLastFile->pNext);
|
||||
@@ -176,24 +182,24 @@ fstk_GetLine(void)
|
||||
return pLastFile->nLine;
|
||||
}
|
||||
|
||||
/* This is only reached if the lexer is in REPT or MACRO mode but there
|
||||
* are no saved contexts with the origin of said REPT or MACRO. */
|
||||
fatalerror("fstk_GetLine: Internal error.");
|
||||
/*
|
||||
* This is only reached if the lexer is in REPT or MACRO mode but there
|
||||
* are no saved contexts with the origin of said REPT or MACRO.
|
||||
*/
|
||||
fatalerror("%s: Internal error.", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
yywrap(void)
|
||||
int yywrap(void)
|
||||
{
|
||||
return (popcontext());
|
||||
return popcontext();
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump the context stack to stderr
|
||||
*/
|
||||
void
|
||||
fstk_Dump(void)
|
||||
void fstk_Dump(void)
|
||||
{
|
||||
struct sContext *pLastFile;
|
||||
const struct sContext *pLastFile;
|
||||
|
||||
pLastFile = pFileStack;
|
||||
|
||||
@@ -209,46 +215,44 @@ fstk_Dump(void)
|
||||
/*
|
||||
* Extra includepath stuff
|
||||
*/
|
||||
void
|
||||
fstk_AddIncludePath(char *s)
|
||||
void fstk_AddIncludePath(char *s)
|
||||
{
|
||||
if (NextIncPath == MAXINCPATHS) {
|
||||
if (NextIncPath == MAXINCPATHS)
|
||||
fatalerror("Too many include directories passed from command line");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strlcpy(IncludePaths[NextIncPath++], s, _MAX_PATH) >= _MAX_PATH) {
|
||||
fatalerror("Include path too long '%s'",s);
|
||||
return;
|
||||
}
|
||||
if (strlcpy(IncludePaths[NextIncPath++], s, _MAX_PATH) >= _MAX_PATH)
|
||||
fatalerror("Include path too long '%s'", s);
|
||||
}
|
||||
|
||||
FILE *
|
||||
fstk_FindFile(char *fname)
|
||||
FILE *fstk_FindFile(char *fname)
|
||||
{
|
||||
char path[_MAX_PATH];
|
||||
int32_t i;
|
||||
FILE *f;
|
||||
|
||||
if ((f = fopen(fname, "rb")) != NULL || errno != ENOENT) {
|
||||
if (dependfile) {
|
||||
f = fopen(fname, "rb");
|
||||
|
||||
if (f != NULL || errno != ENOENT) {
|
||||
if (dependfile)
|
||||
fprintf(dependfile, "%s: %s\n", tzObjectname, fname);
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
for (i = 0; i < NextIncPath; ++i) {
|
||||
if (strlcpy(path, IncludePaths[i], sizeof path) >=
|
||||
sizeof path) {
|
||||
if (strlcpy(path, IncludePaths[i], sizeof(path))
|
||||
>= sizeof(path))
|
||||
continue;
|
||||
}
|
||||
if (strlcat(path, fname, sizeof path) >= sizeof path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((f = fopen(path, "rb")) != NULL || errno != ENOENT) {
|
||||
if (strlcat(path, fname, sizeof(path)) >= sizeof(path))
|
||||
continue;
|
||||
|
||||
f = fopen(path, "rb");
|
||||
|
||||
if (f != NULL || errno != ENOENT) {
|
||||
if (dependfile) {
|
||||
fprintf(dependfile, "%s: %s\n", tzObjectname, path);
|
||||
fprintf(dependfile, "%s: %s\n", tzObjectname,
|
||||
path);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
@@ -261,17 +265,12 @@ fstk_FindFile(char *fname)
|
||||
/*
|
||||
* Set up an include file for parsing
|
||||
*/
|
||||
void
|
||||
fstk_RunInclude(char *tzFileName)
|
||||
void fstk_RunInclude(char *tzFileName)
|
||||
{
|
||||
FILE *f;
|
||||
FILE *f = fstk_FindFile(tzFileName);
|
||||
|
||||
f = fstk_FindFile(tzFileName);
|
||||
|
||||
if (f == NULL) {
|
||||
err(1, "Unable to open included file '%s'",
|
||||
tzFileName);
|
||||
}
|
||||
if (f == NULL)
|
||||
err(1, "Unable to open included file '%s'", tzFileName);
|
||||
|
||||
pushcontext();
|
||||
nLineNo = 1;
|
||||
@@ -281,7 +280,7 @@ fstk_RunInclude(char *tzFileName)
|
||||
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
|
||||
yy_switch_to_buffer(CurrentFlexHandle);
|
||||
|
||||
//Dirty hack to give the INCLUDE directive a linefeed
|
||||
/* Dirty hack to give the INCLUDE directive a linefeed */
|
||||
|
||||
yyunput('\n');
|
||||
nLineNo -= 1;
|
||||
@@ -290,35 +289,35 @@ fstk_RunInclude(char *tzFileName)
|
||||
/*
|
||||
* Set up a macro for parsing
|
||||
*/
|
||||
uint32_t
|
||||
fstk_RunMacro(char *s)
|
||||
uint32_t fstk_RunMacro(char *s)
|
||||
{
|
||||
struct sSymbol *sym;
|
||||
struct sSymbol *sym = sym_FindMacro(s);
|
||||
|
||||
if (sym == NULL)
|
||||
return 0;
|
||||
|
||||
if ((sym = sym_FindMacro(s)) != NULL) {
|
||||
pushcontext();
|
||||
sym_SetMacroArgID(nMacroCount++);
|
||||
nLineNo = -1;
|
||||
sym_UseNewMacroArgs();
|
||||
nCurrentStatus = STAT_isMacro;
|
||||
strcpy(tzCurrentFileName, s);
|
||||
|
||||
if (sym->pMacro == NULL)
|
||||
return 0;
|
||||
|
||||
pCurrentMacro = sym;
|
||||
CurrentFlexHandle =
|
||||
yy_scan_bytes(pCurrentMacro->pMacro,
|
||||
CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->pMacro,
|
||||
strlen(pCurrentMacro->pMacro));
|
||||
yy_switch_to_buffer(CurrentFlexHandle);
|
||||
return (1);
|
||||
} else
|
||||
return (0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a macroargument for parsing
|
||||
*/
|
||||
void
|
||||
fstk_RunMacroArg(int32_t s)
|
||||
void fstk_RunMacroArg(int32_t s)
|
||||
{
|
||||
char *sym;
|
||||
|
||||
@@ -327,40 +326,41 @@ fstk_RunMacroArg(int32_t s)
|
||||
else
|
||||
s -= '0';
|
||||
|
||||
if ((sym = sym_FindMacroArg(s)) != NULL) {
|
||||
sym = sym_FindMacroArg(s);
|
||||
|
||||
if (sym == NULL)
|
||||
fatalerror("No such macroargument");
|
||||
|
||||
pushcontext();
|
||||
nCurrentStatus = STAT_isMacroArg;
|
||||
sprintf(tzCurrentFileName, "%c", (uint8_t) s);
|
||||
sprintf(tzCurrentFileName, "%c", (uint8_t)s);
|
||||
CurrentFlexHandle = yy_scan_bytes(sym, strlen(sym));
|
||||
yy_switch_to_buffer(CurrentFlexHandle);
|
||||
} else
|
||||
fatalerror("No such macroargument");
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a stringequate for parsing
|
||||
*/
|
||||
void
|
||||
fstk_RunString(char *s)
|
||||
void fstk_RunString(char *s)
|
||||
{
|
||||
struct sSymbol *pSym;
|
||||
const struct sSymbol *pSym = sym_FindSymbol(s);
|
||||
|
||||
if ((pSym = sym_FindSymbol(s)) != NULL) {
|
||||
if (pSym != NULL) {
|
||||
pushcontext();
|
||||
nCurrentStatus = STAT_isMacroArg;
|
||||
strcpy(tzCurrentFileName, s);
|
||||
CurrentFlexHandle =
|
||||
yy_scan_bytes(pSym->pMacro, strlen(pSym->pMacro));
|
||||
yy_switch_to_buffer(CurrentFlexHandle);
|
||||
} else
|
||||
} else {
|
||||
yyerror("No such string symbol '%s'", s);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a repeat block for parsing
|
||||
*/
|
||||
void
|
||||
fstk_RunRept(uint32_t count)
|
||||
void fstk_RunRept(uint32_t count)
|
||||
{
|
||||
if (count) {
|
||||
pushcontext();
|
||||
@@ -380,21 +380,19 @@ fstk_RunRept(uint32_t count)
|
||||
/*
|
||||
* Initialize the filestack routines
|
||||
*/
|
||||
void
|
||||
fstk_Init(char *s)
|
||||
void fstk_Init(char *s)
|
||||
{
|
||||
char tzFileName[_MAX_PATH + 1];
|
||||
|
||||
char tzSymFileName[_MAX_PATH + 1 + 2];
|
||||
|
||||
snprintf(tzSymFileName, sizeof(tzSymFileName), "\"%s\"", s);
|
||||
sym_AddString("__FILE__", tzSymFileName);
|
||||
|
||||
strcpy(tzFileName, s);
|
||||
pFileStack = NULL;
|
||||
pCurrentFile = fopen(tzFileName, "rb");
|
||||
if (pCurrentFile == NULL) {
|
||||
if (pCurrentFile == NULL)
|
||||
err(1, "Unable to open file '%s'", tzFileName);
|
||||
}
|
||||
|
||||
nMacroCount = 0;
|
||||
nCurrentStatus = STAT_isInclude;
|
||||
|
||||
@@ -14,40 +14,35 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
bool oDontExpandStrings = false;
|
||||
bool oDontExpandStrings;
|
||||
int32_t nGBGfxID = -1;
|
||||
int32_t nBinaryID = -1;
|
||||
|
||||
int32_t
|
||||
gbgfx2bin(char ch)
|
||||
static int32_t gbgfx2bin(char ch)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i <= 3; i += 1) {
|
||||
if (CurrentOptions.gbgfx[i] == ch) {
|
||||
return (i);
|
||||
}
|
||||
if (CurrentOptions.gbgfx[i] == ch)
|
||||
return i;
|
||||
}
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
binary2bin(char ch)
|
||||
static int32_t binary2bin(char ch)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i <= 1; i += 1) {
|
||||
if (CurrentOptions.binary[i] == ch) {
|
||||
return (i);
|
||||
}
|
||||
if (CurrentOptions.binary[i] == ch)
|
||||
return i;
|
||||
}
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
char2bin(char ch)
|
||||
static int32_t char2bin(char ch)
|
||||
{
|
||||
if (ch >= 'a' && ch <= 'f')
|
||||
return (ch - 'a' + 10);
|
||||
@@ -58,13 +53,12 @@ char2bin(char ch)
|
||||
if (ch >= '0' && ch <= '9')
|
||||
return (ch - '0');
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int32_t(*x2bin) (char ch);
|
||||
|
||||
int32_t
|
||||
ascii2bin(char *s)
|
||||
static int32_t ascii2bin(char *s)
|
||||
{
|
||||
int32_t radix = 10;
|
||||
int32_t result = 0;
|
||||
@@ -105,11 +99,10 @@ ascii2bin(char *s)
|
||||
result = result * radix + convertfunc(*s++);
|
||||
}
|
||||
|
||||
return (result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ParseFixedPoint(char *s, uint32_t size)
|
||||
uint32_t ParseFixedPoint(char *s, uint32_t size)
|
||||
{
|
||||
uint32_t i = 0, dot = 0;
|
||||
|
||||
@@ -125,13 +118,12 @@ ParseFixedPoint(char *s, uint32_t size)
|
||||
|
||||
yyunputbytes(size);
|
||||
|
||||
yylval.nConstValue = (int32_t) (atof(s) * 65536);
|
||||
yylval.nConstValue = (int32_t)(atof(s) * 65536);
|
||||
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ParseNumber(char *s, uint32_t size)
|
||||
uint32_t ParseNumber(char *s, uint32_t size)
|
||||
{
|
||||
char dest[256];
|
||||
|
||||
@@ -139,11 +131,10 @@ ParseNumber(char *s, uint32_t size)
|
||||
dest[size] = 0;
|
||||
yylval.nConstValue = ascii2bin(dest);
|
||||
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ParseSymbol(char *src, uint32_t size)
|
||||
uint32_t ParseSymbol(char *src, uint32_t size)
|
||||
{
|
||||
char dest[MAXSYMLEN + 1];
|
||||
int32_t copied = 0, size_backup = size;
|
||||
@@ -155,13 +146,13 @@ ParseSymbol(char *src, uint32_t size)
|
||||
src += 1;
|
||||
size -= 1;
|
||||
|
||||
if (*src == '@')
|
||||
if (*src == '@') {
|
||||
marg = sym_FindMacroArg(-1);
|
||||
else if (*src >= '0' && *src <= '9')
|
||||
} else if (*src >= '0' && *src <= '9') {
|
||||
marg = sym_FindMacroArg(*src - '0');
|
||||
else {
|
||||
} else {
|
||||
fatalerror("Malformed ID");
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
src += 1;
|
||||
@@ -189,47 +180,48 @@ ParseSymbol(char *src, uint32_t size)
|
||||
yyunputstr(s = sym_GetStringValue(dest));
|
||||
|
||||
while (*s) {
|
||||
if (*s++ == '\n') {
|
||||
if (*s++ == '\n')
|
||||
nLineNo -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return (0);
|
||||
} else {
|
||||
|
||||
strcpy(yylval.tzString, dest);
|
||||
return (1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PutMacroArg(char *src, uint32_t size)
|
||||
uint32_t PutMacroArg(char *src, uint32_t size)
|
||||
{
|
||||
char *s;
|
||||
|
||||
yyskipbytes(size);
|
||||
if ((size == 2 && src[1] >= '1' && src[1] <= '9')) {
|
||||
if ((s = sym_FindMacroArg(src[1] - '0')) != NULL) {
|
||||
s = sym_FindMacroArg(src[1] - '0');
|
||||
|
||||
if (s != NULL)
|
||||
yyunputstr(s);
|
||||
} else {
|
||||
else
|
||||
yyerror("Macro argument not defined");
|
||||
}
|
||||
} else {
|
||||
yyerror("Invalid macro argument");
|
||||
}
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PutUniqueArg(char *src, uint32_t size)
|
||||
uint32_t PutUniqueArg(char *src, uint32_t size)
|
||||
{
|
||||
char *s;
|
||||
|
||||
yyskipbytes(size);
|
||||
if ((s = sym_FindMacroArg(-1)) != NULL) {
|
||||
|
||||
s = sym_FindMacroArg(-1);
|
||||
|
||||
if (s != NULL)
|
||||
yyunputstr(s);
|
||||
} else {
|
||||
else
|
||||
yyerror("Macro unique label string not defined");
|
||||
}
|
||||
return (0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum {
|
||||
@@ -237,9 +229,9 @@ enum {
|
||||
T_LEX_MACROUNIQUE
|
||||
};
|
||||
|
||||
extern struct sLexInitString localstrings[];
|
||||
extern const struct sLexInitString localstrings[];
|
||||
|
||||
struct sLexInitString staticstrings[] = {
|
||||
const struct sLexInitString staticstrings[] = {
|
||||
{"||", T_OP_LOGICOR},
|
||||
{"&&", T_OP_LOGICAND},
|
||||
{"==", T_OP_LOGICEQU},
|
||||
@@ -367,27 +359,27 @@ struct sLexInitString staticstrings[] = {
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
struct sLexFloat tNumberToken = {
|
||||
const struct sLexFloat tNumberToken = {
|
||||
ParseNumber,
|
||||
T_NUMBER
|
||||
};
|
||||
|
||||
struct sLexFloat tFixedPointToken = {
|
||||
const struct sLexFloat tFixedPointToken = {
|
||||
ParseFixedPoint,
|
||||
T_NUMBER
|
||||
};
|
||||
|
||||
struct sLexFloat tIDToken = {
|
||||
const struct sLexFloat tIDToken = {
|
||||
ParseSymbol,
|
||||
T_ID
|
||||
};
|
||||
|
||||
struct sLexFloat tMacroArgToken = {
|
||||
const struct sLexFloat tMacroArgToken = {
|
||||
PutMacroArg,
|
||||
T_LEX_MACROARG
|
||||
};
|
||||
|
||||
struct sLexFloat tMacroUniqueToken = {
|
||||
const struct sLexFloat tMacroUniqueToken = {
|
||||
PutUniqueArg,
|
||||
T_LEX_MACROUNIQUE
|
||||
};
|
||||
@@ -419,7 +411,8 @@ setuplex(void)
|
||||
|
||||
//Binary constants
|
||||
|
||||
nBinaryID = id = lex_FloatAlloc(&tNumberToken);
|
||||
id = lex_FloatAlloc(&tNumberToken);
|
||||
nBinaryID = id;
|
||||
lex_FloatAddFirstRange(id, '%', '%');
|
||||
lex_FloatAddSecondRange(id, CurrentOptions.binary[0],
|
||||
CurrentOptions.binary[0]);
|
||||
@@ -439,7 +432,8 @@ setuplex(void)
|
||||
|
||||
//Gameboy gfx constants
|
||||
|
||||
nGBGfxID = id = lex_FloatAlloc(&tNumberToken);
|
||||
id = lex_FloatAlloc(&tNumberToken);
|
||||
nGBGfxID = id;
|
||||
lex_FloatAddFirstRange(id, '`', '`');
|
||||
lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[0],
|
||||
CurrentOptions.gbgfx[0]);
|
||||
@@ -516,5 +510,4 @@ setuplex(void)
|
||||
lex_FloatAddSecondRange(id, '0', '9');
|
||||
lex_FloatAddRange(id, '.', '.');
|
||||
lex_FloatAddRange(id, '0', '9');
|
||||
|
||||
}
|
||||
|
||||
281
src/asm/lexer.c
281
src/asm/lexer.c
@@ -21,6 +21,7 @@ struct sLexString {
|
||||
uint32_t nNameLength;
|
||||
struct sLexString *pNext;
|
||||
};
|
||||
|
||||
#define pLexBufferRealStart (pCurrentBuffer->pBufferRealStart)
|
||||
#define pLexBuffer (pCurrentBuffer->pBuffer)
|
||||
#define AtLineStart (pCurrentBuffer->oAtLineStart)
|
||||
@@ -40,8 +41,7 @@ uint32_t tFloatingChars[256];
|
||||
uint32_t nFloating;
|
||||
enum eLexerState lexerstate = LEX_STATE_NORMAL;
|
||||
|
||||
void
|
||||
upperstring(char *s)
|
||||
void upperstring(char *s)
|
||||
{
|
||||
while (*s) {
|
||||
*s = toupper(*s);
|
||||
@@ -49,8 +49,7 @@ upperstring(char *s)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lowerstring(char *s)
|
||||
void lowerstring(char *s)
|
||||
{
|
||||
while (*s) {
|
||||
*s = tolower(*s);
|
||||
@@ -58,20 +57,17 @@ lowerstring(char *s)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
yyskipbytes(uint32_t count)
|
||||
void yyskipbytes(uint32_t count)
|
||||
{
|
||||
pLexBuffer += count;
|
||||
}
|
||||
|
||||
void
|
||||
yyunputbytes(uint32_t count)
|
||||
void yyunputbytes(uint32_t count)
|
||||
{
|
||||
pLexBuffer -= count;
|
||||
}
|
||||
|
||||
void
|
||||
yyunput(char c)
|
||||
void yyunput(char c)
|
||||
{
|
||||
if (pLexBuffer <= pLexBufferRealStart)
|
||||
fatalerror("Buffer safety margin exceeded");
|
||||
@@ -79,8 +75,7 @@ yyunput(char c)
|
||||
*(--pLexBuffer) = c;
|
||||
}
|
||||
|
||||
void
|
||||
yyunputstr(char *s)
|
||||
void yyunputstr(char *s)
|
||||
{
|
||||
int32_t i, len;
|
||||
|
||||
@@ -93,62 +88,61 @@ yyunputstr(char *s)
|
||||
*(--pLexBuffer) = s[i];
|
||||
}
|
||||
|
||||
void
|
||||
yy_switch_to_buffer(YY_BUFFER_STATE buf)
|
||||
void yy_switch_to_buffer(YY_BUFFER_STATE buf)
|
||||
{
|
||||
pCurrentBuffer = buf;
|
||||
}
|
||||
|
||||
void
|
||||
yy_set_state(enum eLexerState i)
|
||||
void yy_set_state(enum eLexerState i)
|
||||
{
|
||||
lexerstate = i;
|
||||
}
|
||||
|
||||
void
|
||||
yy_delete_buffer(YY_BUFFER_STATE buf)
|
||||
void yy_delete_buffer(YY_BUFFER_STATE buf)
|
||||
{
|
||||
free(buf->pBufferStart - SAFETYMARGIN);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
YY_BUFFER_STATE
|
||||
yy_scan_bytes(char *mem, uint32_t size)
|
||||
YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size)
|
||||
{
|
||||
YY_BUFFER_STATE pBuffer;
|
||||
YY_BUFFER_STATE pBuffer = malloc(sizeof(struct yy_buffer_state));
|
||||
|
||||
if (pBuffer == NULL)
|
||||
fatalerror("%s: Out of memory!", __func__);
|
||||
|
||||
pBuffer->pBufferRealStart = malloc(size + 1 + SAFETYMARGIN);
|
||||
|
||||
if (pBuffer->pBufferRealStart == NULL)
|
||||
fatalerror("%s: Out of memory for buffer!", __func__);
|
||||
|
||||
if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) {
|
||||
if ((pBuffer->pBufferRealStart =
|
||||
malloc(size + 1 + SAFETYMARGIN)) != NULL) {
|
||||
pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN;
|
||||
pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN;
|
||||
memcpy(pBuffer->pBuffer, mem, size);
|
||||
pBuffer->nBufferSize = size;
|
||||
pBuffer->oAtLineStart = 1;
|
||||
pBuffer->pBuffer[size] = 0;
|
||||
return (pBuffer);
|
||||
}
|
||||
}
|
||||
fatalerror("Out of memory!");
|
||||
return (NULL);
|
||||
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
YY_BUFFER_STATE
|
||||
yy_create_buffer(FILE * f)
|
||||
YY_BUFFER_STATE yy_create_buffer(FILE *f)
|
||||
{
|
||||
YY_BUFFER_STATE pBuffer;
|
||||
YY_BUFFER_STATE pBuffer = malloc(sizeof(struct yy_buffer_state));
|
||||
|
||||
if (pBuffer == NULL)
|
||||
fatalerror("%s: Out of memory!", __func__);
|
||||
|
||||
if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) {
|
||||
uint32_t size;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
if ((pBuffer->pBufferRealStart =
|
||||
malloc(size + 2 + SAFETYMARGIN)) != NULL) {
|
||||
char *mem;
|
||||
uint32_t instring = 0;
|
||||
pBuffer->pBufferRealStart = malloc(size + 2 + SAFETYMARGIN);
|
||||
|
||||
if (pBuffer->pBufferRealStart == NULL)
|
||||
fatalerror("%s: Out of memory for buffer!", __func__);
|
||||
|
||||
pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN;
|
||||
pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN;
|
||||
@@ -159,14 +153,14 @@ yy_create_buffer(FILE * f)
|
||||
pBuffer->pBuffer[size + 1] = 0;
|
||||
pBuffer->nBufferSize = size + 1;
|
||||
|
||||
mem = pBuffer->pBuffer;
|
||||
char *mem = pBuffer->pBuffer;
|
||||
uint32_t instring = 0;
|
||||
|
||||
while (*mem) {
|
||||
if (*mem == '\"')
|
||||
instring = 1 - instring;
|
||||
|
||||
if (mem[0] == '\\' &&
|
||||
(mem[1] == '\"' || mem[1] == '\\')) {
|
||||
if ((mem[0] == '\\') && (mem[1] == '\"' || mem[1] == '\\')) {
|
||||
mem += 2;
|
||||
} else if (instring) {
|
||||
mem += 1;
|
||||
@@ -186,21 +180,17 @@ yy_create_buffer(FILE * f)
|
||||
} else if (*mem == ';') {
|
||||
while (!(*mem == '\n' || *mem == '\0'))
|
||||
*mem++ = ' ';
|
||||
} else
|
||||
} else {
|
||||
mem += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pBuffer->oAtLineStart = 1;
|
||||
return (pBuffer);
|
||||
}
|
||||
}
|
||||
fatalerror("Out of memory!");
|
||||
return (NULL);
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
lex_FloatAlloc(struct sLexFloat *token)
|
||||
uint32_t lex_FloatAlloc(const struct sLexFloat *token)
|
||||
{
|
||||
tLexFloat[nFloating] = *token;
|
||||
|
||||
@@ -211,8 +201,7 @@ lex_FloatAlloc(struct sLexFloat *token)
|
||||
* Make sure that only non-zero ASCII characters are used. Also, check if the
|
||||
* start is greater than the end of the range.
|
||||
*/
|
||||
void
|
||||
lex_CheckCharacterRange(uint16_t start, uint16_t end)
|
||||
void lex_CheckCharacterRange(uint16_t start, uint16_t end)
|
||||
{
|
||||
if (start > end || start < 1 || end > 127) {
|
||||
errx(1, "Invalid character range (start: %u, end: %u)",
|
||||
@@ -220,8 +209,7 @@ lex_CheckCharacterRange(uint16_t start, uint16_t end)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
void lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
{
|
||||
lex_CheckCharacterRange(start, end);
|
||||
|
||||
@@ -231,8 +219,7 @@ lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
void lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
{
|
||||
lex_CheckCharacterRange(start, end);
|
||||
|
||||
@@ -242,8 +229,7 @@ lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
void lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
{
|
||||
lex_CheckCharacterRange(start, end);
|
||||
|
||||
@@ -253,8 +239,7 @@ lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
void lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
{
|
||||
lex_CheckCharacterRange(start, end);
|
||||
|
||||
@@ -264,8 +249,7 @@ lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
void lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
{
|
||||
lex_CheckCharacterRange(start, end);
|
||||
|
||||
@@ -275,8 +259,7 @@ lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
void lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
{
|
||||
lex_CheckCharacterRange(start, end);
|
||||
|
||||
@@ -286,12 +269,10 @@ lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end)
|
||||
}
|
||||
}
|
||||
|
||||
struct sLexFloat *
|
||||
lexgetfloat(uint32_t nFloatMask)
|
||||
static struct sLexFloat *lexgetfloat(uint32_t nFloatMask)
|
||||
{
|
||||
if (nFloatMask == 0) {
|
||||
fatalerror("Internal error in lexgetfloat");
|
||||
}
|
||||
if (nFloatMask == 0)
|
||||
fatalerror("Internal error in %s", __func__);
|
||||
|
||||
int32_t i = 0;
|
||||
|
||||
@@ -300,29 +281,25 @@ lexgetfloat(uint32_t nFloatMask)
|
||||
i++;
|
||||
}
|
||||
|
||||
return (&tLexFloat[i]);
|
||||
return &tLexFloat[i];
|
||||
}
|
||||
|
||||
uint32_t
|
||||
lexcalchash(char *s)
|
||||
static uint32_t lexcalchash(char *s)
|
||||
{
|
||||
uint32_t hash = 0;
|
||||
|
||||
while (*s) {
|
||||
while (*s)
|
||||
hash = (hash * 283) ^ toupper(*s++);
|
||||
}
|
||||
|
||||
return (hash % LEXHASHSIZE);
|
||||
return hash % LEXHASHSIZE;
|
||||
}
|
||||
|
||||
void
|
||||
lex_Init(void)
|
||||
void lex_Init(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < LEXHASHSIZE; i++) {
|
||||
for (i = 0; i < LEXHASHSIZE; i++)
|
||||
tLexHash[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
tFloatingFirstChar[i] = 0;
|
||||
@@ -334,8 +311,7 @@ lex_Init(void)
|
||||
nFloating = 0;
|
||||
}
|
||||
|
||||
void
|
||||
lex_AddStrings(struct sLexInitString * lex)
|
||||
void lex_AddStrings(const struct sLexInitString *lex)
|
||||
{
|
||||
while (lex->tzName) {
|
||||
struct sLexString **ppHash;
|
||||
@@ -345,9 +321,14 @@ lex_AddStrings(struct sLexInitString * lex)
|
||||
while (*ppHash)
|
||||
ppHash = &((*ppHash)->pNext);
|
||||
|
||||
if (((*ppHash) = malloc(sizeof(struct sLexString))) != NULL) {
|
||||
if (((*ppHash)->tzName =
|
||||
(char *) strdup(lex->tzName)) != NULL) {
|
||||
*ppHash = malloc(sizeof(struct sLexString));
|
||||
if (*ppHash == NULL)
|
||||
fatalerror("Out of memory!");
|
||||
|
||||
(*ppHash)->tzName = (char *)strdup(lex->tzName);
|
||||
if ((*ppHash)->tzName == NULL)
|
||||
fatalerror("Out of memory!");
|
||||
|
||||
(*ppHash)->nNameLength = strlen(lex->tzName);
|
||||
(*ppHash)->nToken = lex->nToken;
|
||||
(*ppHash)->pNext = NULL;
|
||||
@@ -357,11 +338,6 @@ lex_AddStrings(struct sLexInitString * lex)
|
||||
if ((*ppHash)->nNameLength > nLexMaxLength)
|
||||
nLexMaxLength = (*ppHash)->nNameLength;
|
||||
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
|
||||
lex += 1;
|
||||
}
|
||||
}
|
||||
@@ -376,11 +352,12 @@ lex_AddStrings(struct sLexInitString * lex)
|
||||
* The token types with the longest match from the current position in the
|
||||
* buffer will have their bits set in the float mask.
|
||||
*/
|
||||
void
|
||||
yylex_GetFloatMaskAndFloatLen(uint32_t *pnFloatMask, uint32_t *pnFloatLen)
|
||||
void yylex_GetFloatMaskAndFloatLen(uint32_t *pnFloatMask, uint32_t *pnFloatLen)
|
||||
{
|
||||
// Note that '\0' should always have a bit mask of 0 in the "floating"
|
||||
// tables, so it doesn't need to be checked for separately.
|
||||
/*
|
||||
* Note that '\0' should always have a bit mask of 0 in the "floating"
|
||||
* tables, so it doesn't need to be checked for separately.
|
||||
*/
|
||||
|
||||
char *s = pLexBuffer;
|
||||
uint32_t nOldFloatMask = 0;
|
||||
@@ -405,8 +382,7 @@ yylex_GetFloatMaskAndFloatLen(uint32_t *pnFloatMask, uint32_t *pnFloatLen)
|
||||
/*
|
||||
* Gets the longest keyword/operator from the current position in the buffer.
|
||||
*/
|
||||
struct sLexString *
|
||||
yylex_GetLongestFixed()
|
||||
struct sLexString *yylex_GetLongestFixed()
|
||||
{
|
||||
struct sLexString *pLongestFixed = NULL;
|
||||
char *s = pLexBuffer;
|
||||
@@ -433,8 +409,7 @@ yylex_GetLongestFixed()
|
||||
return pLongestFixed;
|
||||
}
|
||||
|
||||
size_t
|
||||
CopyMacroArg(char *dest, size_t maxLength, char c)
|
||||
size_t CopyMacroArg(char *dest, size_t maxLength, char c)
|
||||
{
|
||||
size_t i;
|
||||
char *s;
|
||||
@@ -459,35 +434,33 @@ CopyMacroArg(char *dest, size_t maxLength, char c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((s = sym_FindMacroArg(argNum)) == NULL)
|
||||
s = sym_FindMacroArg(argNum);
|
||||
|
||||
if (s == NULL)
|
||||
fatalerror("Macro argument not defined");
|
||||
|
||||
for (i = 0; s[i] != 0; i++) {
|
||||
if (i >= maxLength) {
|
||||
if (i >= maxLength)
|
||||
fatalerror("Macro argument too long to fit buffer");
|
||||
}
|
||||
|
||||
dest[i] = s[i];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline void
|
||||
yylex_StringWriteChar(char *s, size_t index, char c)
|
||||
static inline void yylex_StringWriteChar(char *s, size_t index, char c)
|
||||
{
|
||||
if (index >= MAXSTRLEN) {
|
||||
if (index >= MAXSTRLEN)
|
||||
fatalerror("String too long");
|
||||
}
|
||||
|
||||
s[index] = c;
|
||||
}
|
||||
|
||||
static inline void
|
||||
yylex_SymbolWriteChar(char *s, size_t index, char c)
|
||||
static inline void yylex_SymbolWriteChar(char *s, size_t index, char c)
|
||||
{
|
||||
if (index >= MAXSYMLEN) {
|
||||
if (index >= MAXSYMLEN)
|
||||
fatalerror("Symbol too long");
|
||||
}
|
||||
|
||||
s[index] = c;
|
||||
}
|
||||
@@ -498,14 +471,15 @@ yylex_SymbolWriteChar(char *s, size_t index, char c)
|
||||
*/
|
||||
void yylex_TrimEnd(char *s, size_t index)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t i = (int32_t)index - 1;
|
||||
|
||||
for (i = (int32_t)index - 1; i >= 0 && (s[i] == ' ' || s[i] == '\t'); i--)
|
||||
while ((i >= 0) && (s[i] == ' ' || s[i] == '\t')) {
|
||||
s[i] = 0;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
yylex_ReadBracketedSymbol(char *dest, size_t index)
|
||||
size_t yylex_ReadBracketedSymbol(char *dest, size_t index)
|
||||
{
|
||||
char sym[MAXSYMLEN + 1];
|
||||
char ch;
|
||||
@@ -524,13 +498,15 @@ yylex_ReadBracketedSymbol(char *dest, size_t index)
|
||||
i += length;
|
||||
else
|
||||
fatalerror("Illegal character escape '%c'", ch);
|
||||
} else
|
||||
} else {
|
||||
yylex_SymbolWriteChar(sym, i++, ch);
|
||||
}
|
||||
}
|
||||
|
||||
yylex_SymbolWriteChar(sym, i, 0);
|
||||
|
||||
maxLength = MAXSTRLEN - index; // it's assumed we're writing to a T_STRING
|
||||
/* It's assumed we're writing to a T_STRING */
|
||||
maxLength = MAXSTRLEN - index;
|
||||
length = symvaluetostring(&dest[index], maxLength, sym);
|
||||
|
||||
if (*pLexBuffer == '}')
|
||||
@@ -541,8 +517,7 @@ yylex_ReadBracketedSymbol(char *dest, size_t index)
|
||||
return length;
|
||||
}
|
||||
|
||||
void
|
||||
yylex_ReadQuotedString()
|
||||
static void yylex_ReadQuotedString(void)
|
||||
{
|
||||
size_t index = 0;
|
||||
size_t length, maxLength;
|
||||
@@ -577,19 +552,22 @@ yylex_ReadQuotedString()
|
||||
break;
|
||||
default:
|
||||
maxLength = MAXSTRLEN - index;
|
||||
length = CopyMacroArg(&yylval.tzString[index], maxLength, ch);
|
||||
length = CopyMacroArg(&yylval.tzString[index],
|
||||
maxLength, ch);
|
||||
|
||||
if (length != 0)
|
||||
index += length;
|
||||
else
|
||||
fatalerror("Illegal character escape '%c'", ch);
|
||||
fatalerror("Illegal character escape '%c'",
|
||||
ch);
|
||||
|
||||
ch = 0;
|
||||
break;
|
||||
}
|
||||
} else if (ch == '{') {
|
||||
// Get bracketed symbol within string.
|
||||
index += yylex_ReadBracketedSymbol(yylval.tzString, index);
|
||||
index += yylex_ReadBracketedSymbol(yylval.tzString,
|
||||
index);
|
||||
ch = 0;
|
||||
}
|
||||
|
||||
@@ -605,8 +583,7 @@ yylex_ReadQuotedString()
|
||||
fatalerror("Unterminated string");
|
||||
}
|
||||
|
||||
uint32_t
|
||||
yylex_NORMAL()
|
||||
static uint32_t yylex_NORMAL(void)
|
||||
{
|
||||
struct sLexString *pLongestFixed = NULL;
|
||||
uint32_t nFloatMask, nFloatLen;
|
||||
@@ -629,15 +606,20 @@ scanagain:
|
||||
}
|
||||
}
|
||||
|
||||
// Try to match an identifier, macro argument (e.g. \1),
|
||||
// or numeric literal.
|
||||
/*
|
||||
* Try to match an identifier, macro argument (e.g. \1),
|
||||
* or numeric literal.
|
||||
*/
|
||||
yylex_GetFloatMaskAndFloatLen(&nFloatMask, &nFloatLen);
|
||||
|
||||
// Try to match a keyword or operator.
|
||||
/* Try to match a keyword or operator. */
|
||||
pLongestFixed = yylex_GetLongestFixed();
|
||||
|
||||
if (nFloatLen == 0 && pLongestFixed == NULL) {
|
||||
// No keyword, identifier, operator, or numerical literal matches.
|
||||
/*
|
||||
* No keyword, identifier, operator, or numerical literal
|
||||
* matches.
|
||||
*/
|
||||
|
||||
if (*pLexBuffer == '"') {
|
||||
pLexBuffer++;
|
||||
@@ -647,52 +629,55 @@ scanagain:
|
||||
pLexBuffer++;
|
||||
yylex_ReadBracketedSymbol(yylval.tzString, 0);
|
||||
return T_STRING;
|
||||
} else {
|
||||
// It's not a keyword, operator, identifier, macro argument,
|
||||
// numeric literal, string, or bracketed symbol, so just return
|
||||
// the ASCII character.
|
||||
}
|
||||
|
||||
/*
|
||||
* It's not a keyword, operator, identifier, macro argument,
|
||||
* numeric literal, string, or bracketed symbol, so just return
|
||||
* the ASCII character.
|
||||
*/
|
||||
if (*pLexBuffer == '\n')
|
||||
AtLineStart = 1;
|
||||
|
||||
return *pLexBuffer++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pLongestFixed == NULL || nFloatLen > pLongestFixed->nNameLength) {
|
||||
// Longest match was an identifier, macro argument, or numeric literal.
|
||||
/*
|
||||
* Longest match was an identifier, macro argument, or numeric
|
||||
* literal.
|
||||
*/
|
||||
struct sLexFloat *token = lexgetfloat(nFloatMask);
|
||||
|
||||
if (token->Callback) {
|
||||
int32_t done = token->Callback(pLexBuffer, nFloatLen);
|
||||
|
||||
if (!done)
|
||||
goto scanagain;
|
||||
}
|
||||
|
||||
pLexBuffer += nFloatLen;
|
||||
|
||||
if (token->nToken == T_ID && linestart) {
|
||||
if (token->nToken == T_ID && linestart)
|
||||
return T_LABEL;
|
||||
} else {
|
||||
else
|
||||
return token->nToken;
|
||||
}
|
||||
}
|
||||
|
||||
// Longest match was a keyword or operator.
|
||||
/* Longest match was a keyword or operator. */
|
||||
pLexBuffer += pLongestFixed->nNameLength;
|
||||
return pLongestFixed->nToken;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
yylex_MACROARGS()
|
||||
static uint32_t yylex_MACROARGS(void)
|
||||
{
|
||||
size_t index = 0;
|
||||
size_t length, maxLength;
|
||||
|
||||
while (*pLexBuffer == ' ' || *pLexBuffer == '\t') {
|
||||
while ((*pLexBuffer == ' ') || (*pLexBuffer == '\t'))
|
||||
pLexBuffer++;
|
||||
}
|
||||
|
||||
while (*pLexBuffer != ',' && (*pLexBuffer != '\n')) {
|
||||
while ((*pLexBuffer != ',') && (*pLexBuffer != '\n')) {
|
||||
char ch = *pLexBuffer++;
|
||||
|
||||
if (ch == '\\') {
|
||||
@@ -719,18 +704,21 @@ yylex_MACROARGS()
|
||||
break;
|
||||
default:
|
||||
maxLength = MAXSTRLEN - index;
|
||||
length = CopyMacroArg(&yylval.tzString[index], maxLength, ch);
|
||||
length = CopyMacroArg(&yylval.tzString[index],
|
||||
maxLength, ch);
|
||||
|
||||
if (length != 0)
|
||||
index += length;
|
||||
else
|
||||
fatalerror("Illegal character escape '%c'", ch);
|
||||
fatalerror("Illegal character escape '%c'",
|
||||
ch);
|
||||
|
||||
ch = 0;
|
||||
break;
|
||||
}
|
||||
} else if (ch == '{') {
|
||||
index += yylex_ReadBracketedSymbol(yylval.tzString, index);
|
||||
index += yylex_ReadBracketedSymbol(yylval.tzString,
|
||||
index);
|
||||
ch = 0;
|
||||
}
|
||||
if (ch)
|
||||
@@ -740,7 +728,7 @@ yylex_MACROARGS()
|
||||
if (index) {
|
||||
yylex_StringWriteChar(yylval.tzString, index, 0);
|
||||
|
||||
// trim trailing white space at the end of the line
|
||||
/* trim trailing white space at the end of the line */
|
||||
if (*pLexBuffer == '\n')
|
||||
yylex_TrimEnd(yylval.tzString, index);
|
||||
|
||||
@@ -754,12 +742,10 @@ yylex_MACROARGS()
|
||||
return ',';
|
||||
}
|
||||
|
||||
fatalerror("Internal error in yylex_MACROARGS");
|
||||
return 0;
|
||||
fatalerror("Internal error in %s", __func__);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
yylex(void)
|
||||
uint32_t yylex(void)
|
||||
{
|
||||
switch (lexerstate) {
|
||||
case LEX_STATE_NORMAL:
|
||||
@@ -768,6 +754,5 @@ yylex(void)
|
||||
return yylex_MACROARGS();
|
||||
}
|
||||
|
||||
fatalerror("Internal error in yylex");
|
||||
return 0;
|
||||
fatalerror("Internal error in %s", __func__);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "asmy.h"
|
||||
|
||||
struct sLexInitString localstrings[] = {
|
||||
const struct sLexInitString localstrings[] = {
|
||||
{"adc", T_Z80_ADC},
|
||||
{"add", T_Z80_ADD},
|
||||
{"and", T_Z80_AND},
|
||||
|
||||
151
src/asm/main.c
151
src/asm/main.c
@@ -11,6 +11,7 @@
|
||||
#include "asm/fstack.h"
|
||||
#include "asm/output.h"
|
||||
#include "asm/main.h"
|
||||
|
||||
#include "extern/err.h"
|
||||
#include "extern/reallocarray.h"
|
||||
#include "extern/version.h"
|
||||
@@ -28,7 +29,7 @@ uint32_t nTotalLines, nPass, nPC, nIFDepth, nUnionDepth, nErrors;
|
||||
bool skipElif;
|
||||
uint32_t unionStart[128], unionSize[128];
|
||||
|
||||
extern int yydebug;
|
||||
/* extern int yydebug; */
|
||||
|
||||
FILE *dependfile;
|
||||
extern char *tzObjectname;
|
||||
@@ -45,10 +46,9 @@ struct sOptionStackEntry {
|
||||
struct sOptionStackEntry *pNext;
|
||||
};
|
||||
|
||||
struct sOptionStackEntry *pOptionStack = NULL;
|
||||
struct sOptionStackEntry *pOptionStack;
|
||||
|
||||
void
|
||||
opt_SetCurrentOptions(struct sOptions * pOpt)
|
||||
void opt_SetCurrentOptions(struct sOptions *pOpt)
|
||||
{
|
||||
if (nGBGfxID != -1) {
|
||||
lex_FloatDeleteRange(nGBGfxID, CurrentOptions.gbgfx[0],
|
||||
@@ -110,8 +110,7 @@ opt_SetCurrentOptions(struct sOptions * pOpt)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
opt_Parse(char *s)
|
||||
void opt_Parse(char *s)
|
||||
{
|
||||
struct sOptions newopt;
|
||||
|
||||
@@ -125,8 +124,7 @@ opt_Parse(char *s)
|
||||
newopt.gbgfx[2] = s[3];
|
||||
newopt.gbgfx[3] = s[4];
|
||||
} else {
|
||||
errx(1, "Must specify exactly 4 characters for "
|
||||
"option 'g'");
|
||||
errx(1, "Must specify exactly 4 characters for option 'g'");
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
@@ -134,8 +132,7 @@ opt_Parse(char *s)
|
||||
newopt.binary[0] = s[1];
|
||||
newopt.binary[1] = s[2];
|
||||
} else {
|
||||
errx(1, "Must specify exactly 2 characters for option "
|
||||
"'b'");
|
||||
errx(1, "Must specify exactly 2 characters for option 'b'");
|
||||
}
|
||||
break;
|
||||
case 'z':
|
||||
@@ -143,12 +140,10 @@ opt_Parse(char *s)
|
||||
int32_t result;
|
||||
|
||||
result = sscanf(&s[1], "%x", &newopt.fillchar);
|
||||
if (!((result == EOF) || (result == 1))) {
|
||||
if (!((result == EOF) || (result == 1)))
|
||||
errx(1, "Invalid argument for option 'z'");
|
||||
}
|
||||
} else {
|
||||
errx(1, "Invalid argument for option 'z'");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -159,77 +154,67 @@ opt_Parse(char *s)
|
||||
opt_SetCurrentOptions(&newopt);
|
||||
}
|
||||
|
||||
void
|
||||
opt_Push(void)
|
||||
void opt_Push(void)
|
||||
{
|
||||
struct sOptionStackEntry *pOpt;
|
||||
|
||||
if ((pOpt = malloc(sizeof(struct sOptionStackEntry))) != NULL) {
|
||||
pOpt = malloc(sizeof(struct sOptionStackEntry));
|
||||
|
||||
if (pOpt == NULL)
|
||||
fatalerror("No memory for option stack");
|
||||
|
||||
pOpt->Options = CurrentOptions;
|
||||
pOpt->pNext = pOptionStack;
|
||||
pOptionStack = pOpt;
|
||||
} else
|
||||
fatalerror("No memory for option stack");
|
||||
}
|
||||
|
||||
void
|
||||
opt_Pop(void)
|
||||
void opt_Pop(void)
|
||||
{
|
||||
if (pOptionStack) {
|
||||
if (pOptionStack == NULL)
|
||||
fatalerror("No entries in the option stack");
|
||||
|
||||
struct sOptionStackEntry *pOpt;
|
||||
|
||||
pOpt = pOptionStack;
|
||||
opt_SetCurrentOptions(&(pOpt->Options));
|
||||
pOptionStack = pOpt->pNext;
|
||||
free(pOpt);
|
||||
} else
|
||||
fatalerror("No entries in the option stack");
|
||||
}
|
||||
|
||||
void
|
||||
opt_AddDefine(char *s)
|
||||
void opt_AddDefine(char *s)
|
||||
{
|
||||
char *value, *equals;
|
||||
if(cldefines_index >= cldefines_size)
|
||||
{
|
||||
|
||||
if (cldefines_index >= cldefines_size) {
|
||||
cldefines_size *= 2;
|
||||
cldefines = reallocarray(cldefines, cldefines_size,
|
||||
2 * sizeof(void *));
|
||||
if(!cldefines)
|
||||
{
|
||||
if (!cldefines)
|
||||
fatalerror("No memory for command line defines");
|
||||
}
|
||||
}
|
||||
equals = strchr(s, '=');
|
||||
if(equals)
|
||||
{
|
||||
if (equals) {
|
||||
*equals = '\0';
|
||||
value = equals + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
value = "1";
|
||||
}
|
||||
cldefines[cldefines_index++] = s;
|
||||
cldefines[cldefines_index++] = value;
|
||||
}
|
||||
|
||||
void
|
||||
opt_ParseDefines()
|
||||
static void opt_ParseDefines(void)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for(i = 0; i < cldefines_index; i += 2)
|
||||
{
|
||||
for (i = 0; i < cldefines_index; i += 2)
|
||||
sym_AddString(cldefines[i], cldefines[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Error handling
|
||||
*/
|
||||
void
|
||||
verror(const char *fmt, va_list args)
|
||||
void verror(const char *fmt, va_list args)
|
||||
{
|
||||
fprintf(stderr, "ERROR: ");
|
||||
fstk_Dump();
|
||||
@@ -239,32 +224,33 @@ verror(const char *fmt, va_list args)
|
||||
nErrors += 1;
|
||||
}
|
||||
|
||||
void
|
||||
yyerror(const char *fmt, ...)
|
||||
void yyerror(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
verror(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
fatalerror(const char *fmt, ...)
|
||||
void fatalerror(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
verror(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
exit(5);
|
||||
}
|
||||
|
||||
void
|
||||
warning(const char *fmt, ...)
|
||||
void warning(const char *fmt, ...)
|
||||
{
|
||||
if (!CurrentOptions.warnings)
|
||||
return;
|
||||
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
|
||||
fprintf(stderr, "warning: ");
|
||||
@@ -276,17 +262,15 @@ warning(const char *fmt, ...)
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
static void print_usage(void)
|
||||
{
|
||||
printf(
|
||||
"Usage: rgbasm [-EhVvw] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n"
|
||||
"usage: rgbasm [-EhVvw] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n"
|
||||
" [-M dependfile] [-o outfile] [-p pad_value] file.asm\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ch;
|
||||
char *ep;
|
||||
@@ -298,15 +282,12 @@ main(int argc, char *argv[])
|
||||
dependfile = NULL;
|
||||
|
||||
cldefines_size = 32;
|
||||
cldefines = reallocarray(cldefines, cldefines_size,
|
||||
2 * sizeof(void *));
|
||||
if(!cldefines)
|
||||
{
|
||||
cldefines = reallocarray(cldefines, cldefines_size, 2 * sizeof(void *));
|
||||
if (!cldefines)
|
||||
fatalerror("No memory for command line defines");
|
||||
}
|
||||
|
||||
if (argc == 1)
|
||||
usage();
|
||||
print_usage();
|
||||
|
||||
/* yydebug=1; */
|
||||
|
||||
@@ -333,8 +314,7 @@ main(int argc, char *argv[])
|
||||
newopt.binary[0] = optarg[1];
|
||||
newopt.binary[1] = optarg[2];
|
||||
} else {
|
||||
errx(1, "Must specify exactly 2 characters for "
|
||||
"option 'b'");
|
||||
errx(1, "Must specify exactly 2 characters for option 'b'");
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
@@ -350,8 +330,7 @@ main(int argc, char *argv[])
|
||||
newopt.gbgfx[2] = optarg[3];
|
||||
newopt.gbgfx[3] = optarg[4];
|
||||
} else {
|
||||
errx(1, "Must specify exactly 4 characters for "
|
||||
"option 'g'");
|
||||
errx(1, "Must specify exactly 4 characters for option 'g'");
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
@@ -361,22 +340,23 @@ main(int argc, char *argv[])
|
||||
fstk_AddIncludePath(optarg);
|
||||
break;
|
||||
case 'M':
|
||||
if ((dependfile = fopen(optarg, "w")) == NULL) {
|
||||
dependfile = fopen(optarg, "w");
|
||||
if (dependfile == NULL)
|
||||
err(1, "Could not open dependfile %s", optarg);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'o':
|
||||
out_SetFileName(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
newopt.fillchar = strtoul(optarg, &ep, 0);
|
||||
if (optarg[0] == '\0' || *ep != '\0') {
|
||||
|
||||
if (optarg[0] == '\0' || *ep != '\0')
|
||||
errx(1, "Invalid argument for option 'p'");
|
||||
}
|
||||
if (newopt.fillchar < 0 || newopt.fillchar > 0xFF) {
|
||||
errx(1, "Argument for option 'p' must be "
|
||||
"between 0 and 0xFF");
|
||||
}
|
||||
|
||||
if (newopt.fillchar < 0 || newopt.fillchar > 0xFF)
|
||||
errx(1, "Argument for option 'p' must be between 0 and 0xFF");
|
||||
|
||||
break;
|
||||
case 'V':
|
||||
printf("rgbasm %s\n", get_package_version_string());
|
||||
@@ -388,7 +368,7 @@ main(int argc, char *argv[])
|
||||
newopt.warnings = false;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
print_usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
@@ -400,15 +380,14 @@ main(int argc, char *argv[])
|
||||
DefaultOptions = CurrentOptions;
|
||||
|
||||
if (argc == 0)
|
||||
usage();
|
||||
print_usage();
|
||||
|
||||
tzMainfile = argv[argc - 1];
|
||||
|
||||
setuplex();
|
||||
|
||||
if (CurrentOptions.verbose) {
|
||||
if (CurrentOptions.verbose)
|
||||
printf("Assembling %s\n", tzMainfile);
|
||||
}
|
||||
|
||||
if (dependfile) {
|
||||
if (!tzObjectname)
|
||||
@@ -432,23 +411,21 @@ main(int argc, char *argv[])
|
||||
fstk_Init(tzMainfile);
|
||||
opt_ParseDefines();
|
||||
|
||||
if (CurrentOptions.verbose) {
|
||||
if (CurrentOptions.verbose)
|
||||
printf("Pass 1...\n");
|
||||
}
|
||||
|
||||
yy_set_state(LEX_STATE_NORMAL);
|
||||
opt_SetCurrentOptions(&DefaultOptions);
|
||||
|
||||
if (yyparse() != 0 || nErrors != 0) {
|
||||
if (yyparse() != 0 || nErrors != 0)
|
||||
errx(1, "Assembly aborted in pass 1 (%ld errors)!", nErrors);
|
||||
}
|
||||
|
||||
if (nIFDepth != 0) {
|
||||
if (nIFDepth != 0)
|
||||
errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth);
|
||||
}
|
||||
|
||||
if (nUnionDepth != 0) {
|
||||
errx(1, "Unterminated UNION construct (%ld levels)!", nUnionDepth);
|
||||
errx(1, "Unterminated UNION construct (%ld levels)!",
|
||||
nUnionDepth);
|
||||
}
|
||||
|
||||
nTotalLines = 0;
|
||||
@@ -466,13 +443,11 @@ main(int argc, char *argv[])
|
||||
opt_SetCurrentOptions(&DefaultOptions);
|
||||
opt_ParseDefines();
|
||||
|
||||
if (CurrentOptions.verbose) {
|
||||
if (CurrentOptions.verbose)
|
||||
printf("Pass 2...\n");
|
||||
}
|
||||
|
||||
if (yyparse() != 0 || nErrors != 0) {
|
||||
if (yyparse() != 0 || nErrors != 0)
|
||||
errx(1, "Assembly aborted in pass 2 (%ld errors)!", nErrors);
|
||||
}
|
||||
|
||||
double timespent;
|
||||
|
||||
@@ -481,12 +456,12 @@ main(int argc, char *argv[])
|
||||
/ (double)CLOCKS_PER_SEC;
|
||||
if (CurrentOptions.verbose) {
|
||||
printf("Success! %u lines in %d.%02d seconds ", nTotalLines,
|
||||
(int) timespent, ((int) (timespent * 100.0)) % 100);
|
||||
(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));
|
||||
(int)(60 / timespent * nTotalLines));
|
||||
}
|
||||
out_WriteObject();
|
||||
return 0;
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include "asm/mymath.h"
|
||||
#include "asm/symbol.h"
|
||||
|
||||
#define fix2double(i) ((double)(i/65536.0))
|
||||
#define double2fix(d) ((int32_t)(d*65536.0))
|
||||
#define fx2double(i) ((double)((i) / 65536.0))
|
||||
#define double2fx(d) ((int32_t)((d) * 65536.0))
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
@@ -19,131 +19,116 @@
|
||||
/*
|
||||
* Define the _PI symbol
|
||||
*/
|
||||
void
|
||||
math_DefinePI(void)
|
||||
void math_DefinePI(void)
|
||||
{
|
||||
sym_AddEqu("_PI", double2fix(M_PI));
|
||||
sym_AddEqu("_PI", double2fx(M_PI));
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a fixed point value
|
||||
*/
|
||||
void
|
||||
math_Print(int32_t i)
|
||||
void math_Print(int32_t i)
|
||||
{
|
||||
if (i >= 0)
|
||||
printf("%d.%05d", i >> 16,
|
||||
((int32_t) (fix2double(i) * 100000 + 0.5)) % 100000);
|
||||
((int32_t)(fx2double(i) * 100000 + 0.5)) % 100000);
|
||||
else
|
||||
printf("-%d.%05d", (-i) >> 16,
|
||||
((int32_t) (fix2double(-i) * 100000 + 0.5)) % 100000);
|
||||
((int32_t)(fx2double(-i) * 100000 + 0.5)) % 100000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate sine
|
||||
*/
|
||||
int32_t
|
||||
math_Sin(int32_t i)
|
||||
int32_t math_Sin(int32_t i)
|
||||
{
|
||||
return (double2fix(sin(fix2double(i) * 2 * M_PI / 65536)));
|
||||
return double2fx(sin(fx2double(i) * 2 * M_PI / 65536));
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate cosine
|
||||
*/
|
||||
int32_t
|
||||
math_Cos(int32_t i)
|
||||
int32_t math_Cos(int32_t i)
|
||||
{
|
||||
return (double2fix(cos(fix2double(i) * 2 * M_PI / 65536)));
|
||||
return double2fx(cos(fx2double(i) * 2 * M_PI / 65536));
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate tangent
|
||||
*/
|
||||
int32_t
|
||||
math_Tan(int32_t i)
|
||||
int32_t math_Tan(int32_t i)
|
||||
{
|
||||
return (double2fix(tan(fix2double(i) * 2 * M_PI / 65536)));
|
||||
return double2fx(tan(fx2double(i) * 2 * M_PI / 65536));
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate arcsine
|
||||
*/
|
||||
int32_t
|
||||
math_ASin(int32_t i)
|
||||
int32_t math_ASin(int32_t i)
|
||||
{
|
||||
return (double2fix(asin(fix2double(i)) / 2 / M_PI * 65536));
|
||||
return double2fx(asin(fx2double(i)) / 2 / M_PI * 65536);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate arccosine
|
||||
*/
|
||||
int32_t
|
||||
math_ACos(int32_t i)
|
||||
int32_t math_ACos(int32_t i)
|
||||
{
|
||||
return (double2fix(acos(fix2double(i)) / 2 / M_PI * 65536));
|
||||
return double2fx(acos(fx2double(i)) / 2 / M_PI * 65536);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate arctangent
|
||||
*/
|
||||
int32_t
|
||||
math_ATan(int32_t i)
|
||||
int32_t math_ATan(int32_t i)
|
||||
{
|
||||
return (double2fix(atan(fix2double(i)) / 2 / M_PI * 65536));
|
||||
return double2fx(atan(fx2double(i)) / 2 / M_PI * 65536);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate atan2
|
||||
*/
|
||||
int32_t
|
||||
math_ATan2(int32_t i, int32_t j)
|
||||
int32_t math_ATan2(int32_t i, int32_t j)
|
||||
{
|
||||
return (double2fix
|
||||
(atan2(fix2double(i), fix2double(j)) / 2 / M_PI * 65536));
|
||||
return double2fx(atan2(fx2double(i), fx2double(j)) / 2 / M_PI * 65536);
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication
|
||||
*/
|
||||
int32_t
|
||||
math_Mul(int32_t i, int32_t j)
|
||||
int32_t math_Mul(int32_t i, int32_t j)
|
||||
{
|
||||
return (double2fix(fix2double(i) * fix2double(j)));
|
||||
return double2fx(fx2double(i) * fx2double(j));
|
||||
}
|
||||
|
||||
/*
|
||||
* Division
|
||||
*/
|
||||
int32_t
|
||||
math_Div(int32_t i, int32_t j)
|
||||
int32_t math_Div(int32_t i, int32_t j)
|
||||
{
|
||||
return (double2fix(fix2double(i) / fix2double(j)));
|
||||
return double2fx(fx2double(i) / fx2double(j));
|
||||
}
|
||||
|
||||
/*
|
||||
* Round
|
||||
*/
|
||||
int32_t
|
||||
math_Round(int32_t i)
|
||||
int32_t math_Round(int32_t i)
|
||||
{
|
||||
return double2fix(round(fix2double(i)));
|
||||
return double2fx(round(fx2double(i)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Ceil
|
||||
*/
|
||||
int32_t
|
||||
math_Ceil(int32_t i)
|
||||
int32_t math_Ceil(int32_t i)
|
||||
{
|
||||
return double2fix(ceil(fix2double(i)));
|
||||
return double2fx(ceil(fx2double(i)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Floor
|
||||
*/
|
||||
int32_t
|
||||
math_Floor(int32_t i)
|
||||
int32_t math_Floor(int32_t i)
|
||||
{
|
||||
return double2fix(floor(fix2double(i)));
|
||||
return double2fx(floor(fx2double(i)));
|
||||
}
|
||||
|
||||
333
src/asm/output.c
333
src/asm/output.c
@@ -10,16 +10,18 @@
|
||||
|
||||
#include "asm/asm.h"
|
||||
#include "asm/charmap.h"
|
||||
#include "asm/output.h"
|
||||
#include "asm/symbol.h"
|
||||
#include "asm/mylink.h"
|
||||
#include "asm/main.h"
|
||||
#include "asm/rpn.h"
|
||||
#include "asm/fstack.h"
|
||||
#include "asm/main.h"
|
||||
#include "asm/mylink.h"
|
||||
#include "asm/output.h"
|
||||
#include "asm/rpn.h"
|
||||
#include "asm/symbol.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "extern/err.h"
|
||||
|
||||
void out_SetCurrentSection(struct Section * pSect);
|
||||
void out_SetCurrentSection(struct Section *pSect);
|
||||
|
||||
struct Patch {
|
||||
char tzFilename[_MAX_PATH + 1];
|
||||
@@ -35,7 +37,7 @@ struct PatchSymbol {
|
||||
uint32_t ID;
|
||||
struct sSymbol *pSymbol;
|
||||
struct PatchSymbol *pNext;
|
||||
struct PatchSymbol *pBucketNext; // next symbol in hash table bucket
|
||||
struct PatchSymbol *pBucketNext; /* next symbol in hash table bucket */
|
||||
};
|
||||
|
||||
struct SectionStackEntry {
|
||||
@@ -44,56 +46,62 @@ struct SectionStackEntry {
|
||||
};
|
||||
|
||||
struct PatchSymbol *tHashedPatchSymbols[HASHSIZE];
|
||||
struct Section *pSectionList = NULL, *pCurrentSection = NULL;
|
||||
struct PatchSymbol *pPatchSymbols = NULL;
|
||||
struct Section *pSectionList, *pCurrentSection;
|
||||
struct PatchSymbol *pPatchSymbols;
|
||||
struct PatchSymbol **ppPatchSymbolsTail = &pPatchSymbols;
|
||||
char *tzObjectname;
|
||||
struct SectionStackEntry *pSectionStack = NULL;
|
||||
struct SectionStackEntry *pSectionStack;
|
||||
|
||||
/*
|
||||
* Section stack routines
|
||||
*/
|
||||
void
|
||||
out_PushSection(void)
|
||||
void out_PushSection(void)
|
||||
{
|
||||
struct SectionStackEntry *pSect;
|
||||
|
||||
if ((pSect = malloc(sizeof(struct SectionStackEntry))) != NULL) {
|
||||
pSect = malloc(sizeof(struct SectionStackEntry));
|
||||
if (pSect == NULL)
|
||||
fatalerror("No memory for section stack");
|
||||
|
||||
pSect->pSection = pCurrentSection;
|
||||
pSect->pNext = pSectionStack;
|
||||
pSectionStack = pSect;
|
||||
} else
|
||||
fatalerror("No memory for section stack");
|
||||
}
|
||||
|
||||
void
|
||||
out_PopSection(void)
|
||||
void out_PopSection(void)
|
||||
{
|
||||
if (pSectionStack) {
|
||||
if (pSectionStack == NULL)
|
||||
fatalerror("No entries in the section stack");
|
||||
|
||||
struct SectionStackEntry *pSect;
|
||||
|
||||
pSect = pSectionStack;
|
||||
out_SetCurrentSection(pSect->pSection);
|
||||
pSectionStack = pSect->pNext;
|
||||
free(pSect);
|
||||
} else
|
||||
fatalerror("No entries in the section stack");
|
||||
}
|
||||
|
||||
uint32_t
|
||||
getmaxsectionsize(uint32_t secttype, char * sectname)
|
||||
static uint32_t getmaxsectionsize(uint32_t secttype, char *sectname)
|
||||
{
|
||||
switch (secttype)
|
||||
{
|
||||
case SECT_ROM0: return 0x8000; /* If ROMX sections not used. */
|
||||
case SECT_ROMX: return 0x4000;
|
||||
case SECT_VRAM: return 0x2000;
|
||||
case SECT_SRAM: return 0x2000;
|
||||
case SECT_WRAM0: return 0x2000; /* If WRAMX sections not used. */
|
||||
case SECT_WRAMX: return 0x1000;
|
||||
case SECT_OAM: return 0xA0;
|
||||
case SECT_HRAM: return 0x7F;
|
||||
default: break;
|
||||
switch (secttype) {
|
||||
case SECT_ROM0:
|
||||
return 0x8000; /* If ROMX sections not used */
|
||||
case SECT_ROMX:
|
||||
return 0x4000;
|
||||
case SECT_VRAM:
|
||||
return 0x2000;
|
||||
case SECT_SRAM:
|
||||
return 0x2000;
|
||||
case SECT_WRAM0:
|
||||
return 0x2000; /* If WRAMX sections not used */
|
||||
case SECT_WRAMX:
|
||||
return 0x1000;
|
||||
case SECT_OAM:
|
||||
return 0xA0;
|
||||
case SECT_HRAM:
|
||||
return 0x7F;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
errx(1, "Section \"%s\" has an invalid section type.", sectname);
|
||||
}
|
||||
@@ -101,8 +109,7 @@ getmaxsectionsize(uint32_t secttype, char * sectname)
|
||||
/*
|
||||
* Count the number of symbols used in this object
|
||||
*/
|
||||
uint32_t
|
||||
countsymbols(void)
|
||||
static uint32_t countsymbols(void)
|
||||
{
|
||||
struct PatchSymbol *pSym;
|
||||
uint32_t count = 0;
|
||||
@@ -120,8 +127,7 @@ countsymbols(void)
|
||||
/*
|
||||
* Count the number of sections used in this object
|
||||
*/
|
||||
uint32_t
|
||||
countsections(void)
|
||||
static uint32_t countsections(void)
|
||||
{
|
||||
struct Section *pSect;
|
||||
uint32_t count = 0;
|
||||
@@ -139,8 +145,7 @@ countsections(void)
|
||||
/*
|
||||
* Count the number of patches used in this object
|
||||
*/
|
||||
uint32_t
|
||||
countpatches(struct Section * pSect)
|
||||
static uint32_t countpatches(struct Section *pSect)
|
||||
{
|
||||
struct Patch *pPatch;
|
||||
uint32_t r = 0;
|
||||
@@ -157,8 +162,7 @@ countpatches(struct Section * pSect)
|
||||
/*
|
||||
* Write a long to a file (little-endian)
|
||||
*/
|
||||
void
|
||||
fputlong(uint32_t i, FILE * f)
|
||||
static void fputlong(uint32_t i, FILE *f)
|
||||
{
|
||||
fputc(i, f);
|
||||
fputc(i >> 8, f);
|
||||
@@ -169,8 +173,7 @@ fputlong(uint32_t i, FILE * f)
|
||||
/*
|
||||
* Write a NULL-terminated string to a file
|
||||
*/
|
||||
void
|
||||
fputstring(char *s, FILE * f)
|
||||
static void fputstring(char *s, FILE *f)
|
||||
{
|
||||
while (*s)
|
||||
fputc(*s++, f);
|
||||
@@ -180,8 +183,7 @@ fputstring(char *s, FILE * f)
|
||||
/*
|
||||
* Return a section's ID
|
||||
*/
|
||||
uint32_t
|
||||
getsectid(struct Section * pSect)
|
||||
static uint32_t getsectid(struct Section *pSect)
|
||||
{
|
||||
struct Section *sec;
|
||||
uint32_t ID = 0;
|
||||
@@ -190,20 +192,19 @@ getsectid(struct Section * pSect)
|
||||
|
||||
while (sec) {
|
||||
if (sec == pSect)
|
||||
return (ID);
|
||||
return ID;
|
||||
ID += 1;
|
||||
sec = sec->pNext;
|
||||
}
|
||||
|
||||
fatalerror("INTERNAL: Unknown section");
|
||||
return ((uint32_t) - 1);
|
||||
return (uint32_t)(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a patch to a file
|
||||
*/
|
||||
void
|
||||
writepatch(struct Patch * pPatch, FILE * f)
|
||||
static void writepatch(struct Patch *pPatch, FILE *f)
|
||||
{
|
||||
fputstring(pPatch->tzFilename, f);
|
||||
fputlong(pPatch->nLine, f);
|
||||
@@ -216,8 +217,7 @@ writepatch(struct Patch * pPatch, FILE * f)
|
||||
/*
|
||||
* Write a section to a file
|
||||
*/
|
||||
void
|
||||
writesection(struct Section * pSect, FILE * f)
|
||||
static void writesection(struct Section *pSect, FILE *f)
|
||||
{
|
||||
fputstring(pSect->pzName, f);
|
||||
|
||||
@@ -229,8 +229,7 @@ writesection(struct Section * pSect, FILE * f)
|
||||
fputlong(pSect->nBank, f);
|
||||
fputlong(pSect->nAlign, f);
|
||||
|
||||
if ((pSect->nType == SECT_ROM0)
|
||||
|| (pSect->nType == SECT_ROMX)) {
|
||||
if ((pSect->nType == SECT_ROM0) || (pSect->nType == SECT_ROMX)) {
|
||||
struct Patch *pPatch;
|
||||
|
||||
fwrite(pSect->tData, 1, pSect->nPC, f);
|
||||
@@ -247,8 +246,7 @@ writesection(struct Section * pSect, FILE * f)
|
||||
/*
|
||||
* Write a symbol to a file
|
||||
*/
|
||||
void
|
||||
writesymbol(struct sSymbol * pSym, FILE * f)
|
||||
static void writesymbol(struct sSymbol *pSym, FILE *f)
|
||||
{
|
||||
char symname[MAXSYMLEN * 2 + 1];
|
||||
uint32_t type;
|
||||
@@ -295,11 +293,11 @@ writesymbol(struct sSymbol * pSym, FILE * f)
|
||||
/*
|
||||
* Add a symbol to the object
|
||||
*/
|
||||
uint32_t
|
||||
addsymbol(struct sSymbol * pSym)
|
||||
static uint32_t nextID;
|
||||
|
||||
static uint32_t addsymbol(struct sSymbol *pSym)
|
||||
{
|
||||
struct PatchSymbol *pPSym, **ppPSym;
|
||||
static uint32_t nextID = 0;
|
||||
uint32_t hash;
|
||||
|
||||
hash = calchash(pSym->tzName);
|
||||
@@ -311,13 +309,16 @@ addsymbol(struct sSymbol * pSym)
|
||||
ppPSym = &((*ppPSym)->pBucketNext);
|
||||
}
|
||||
|
||||
if ((*ppPSym = pPSym = malloc(sizeof(struct PatchSymbol))) != NULL) {
|
||||
pPSym = malloc(sizeof(struct PatchSymbol));
|
||||
*ppPSym = pPSym;
|
||||
|
||||
if (pPSym == NULL)
|
||||
fatalerror("No memory for patchsymbol");
|
||||
|
||||
pPSym->pNext = NULL;
|
||||
pPSym->pBucketNext = NULL;
|
||||
pPSym->pSymbol = pSym;
|
||||
pPSym->ID = nextID++;
|
||||
} else
|
||||
fatalerror("No memory for patchsymbol");
|
||||
|
||||
*ppPatchSymbolsTail = pPSym;
|
||||
ppPatchSymbolsTail = &(pPSym->pNext);
|
||||
@@ -328,8 +329,7 @@ addsymbol(struct sSymbol * pSym)
|
||||
/*
|
||||
* Add all exported symbols to the object
|
||||
*/
|
||||
void
|
||||
addexports(void)
|
||||
static void addexports(void)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
@@ -348,28 +348,27 @@ addexports(void)
|
||||
/*
|
||||
* Allocate a new patchstructure and link it into the list
|
||||
*/
|
||||
struct Patch *
|
||||
allocpatch(void)
|
||||
struct Patch *allocpatch(void)
|
||||
{
|
||||
struct Patch *pPatch;
|
||||
|
||||
if ((pPatch = malloc(sizeof(struct Patch))) != NULL) {
|
||||
pPatch = malloc(sizeof(struct Patch));
|
||||
|
||||
if (pPatch == NULL)
|
||||
fatalerror("No memory for patch");
|
||||
|
||||
pPatch->pNext = pCurrentSection->pPatches;
|
||||
pPatch->nRPNSize = 0;
|
||||
pPatch->pRPN = NULL;
|
||||
} else
|
||||
fatalerror("No memory for patch");
|
||||
|
||||
pCurrentSection->pPatches = pPatch;
|
||||
|
||||
return (pPatch);
|
||||
return pPatch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new patch (includes the rpn expr)
|
||||
*/
|
||||
void
|
||||
createpatch(uint32_t type, struct Expression * expr)
|
||||
void createpatch(uint32_t type, struct Expression *expr)
|
||||
{
|
||||
struct Patch *pPatch;
|
||||
uint16_t rpndata;
|
||||
@@ -394,7 +393,9 @@ createpatch(uint32_t type, struct Expression * expr)
|
||||
break;
|
||||
case RPN_SYM:
|
||||
symptr = 0;
|
||||
while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0);
|
||||
while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0)
|
||||
;
|
||||
|
||||
if (sym_isConstant(tzSym)) {
|
||||
uint32_t value;
|
||||
|
||||
@@ -405,9 +406,11 @@ createpatch(uint32_t type, struct Expression * expr)
|
||||
rpnexpr[rpnptr++] = value >> 16;
|
||||
rpnexpr[rpnptr++] = value >> 24;
|
||||
} else {
|
||||
struct sSymbol *sym;
|
||||
if ((sym = sym_FindSymbol(tzSym)) == NULL)
|
||||
struct sSymbol *sym = sym_FindSymbol(tzSym);
|
||||
|
||||
if (sym == NULL)
|
||||
break;
|
||||
|
||||
symptr = addsymbol(sym);
|
||||
rpnexpr[rpnptr++] = RPN_SYM;
|
||||
rpnexpr[rpnptr++] = symptr & 0xFF;
|
||||
@@ -416,26 +419,34 @@ createpatch(uint32_t type, struct Expression * expr)
|
||||
rpnexpr[rpnptr++] = symptr >> 24;
|
||||
}
|
||||
break;
|
||||
case RPN_BANK: {
|
||||
case RPN_BANK:
|
||||
{
|
||||
struct sSymbol *sym;
|
||||
|
||||
symptr = 0;
|
||||
while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0);
|
||||
if ((sym = sym_FindSymbol(tzSym)) == NULL)
|
||||
while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0)
|
||||
;
|
||||
|
||||
sym = sym_FindSymbol(tzSym);
|
||||
if (sym == NULL)
|
||||
break;
|
||||
|
||||
symptr = addsymbol(sym);
|
||||
rpnexpr[rpnptr++] = RPN_BANK;
|
||||
rpnexpr[rpnptr++] = symptr & 0xFF;
|
||||
rpnexpr[rpnptr++] = symptr >> 8;
|
||||
rpnexpr[rpnptr++] = symptr >> 16;
|
||||
rpnexpr[rpnptr++] = symptr >> 24;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rpnexpr[rpnptr++] = rpndata;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((pPatch->pRPN = malloc(rpnptr)) != NULL) {
|
||||
|
||||
pPatch->pRPN = malloc(rpnptr);
|
||||
if (pPatch->pRPN != NULL) {
|
||||
memcpy(pPatch->pRPN, rpnexpr, rpnptr);
|
||||
pPatch->nRPNSize = rpnptr;
|
||||
}
|
||||
@@ -444,12 +455,9 @@ createpatch(uint32_t type, struct Expression * expr)
|
||||
/*
|
||||
* A quick check to see if we have an initialized section
|
||||
*/
|
||||
void
|
||||
checksection(void)
|
||||
static void checksection(void)
|
||||
{
|
||||
if (pCurrentSection)
|
||||
return;
|
||||
else
|
||||
if (pCurrentSection == NULL)
|
||||
fatalerror("Code generation before SECTION directive");
|
||||
}
|
||||
|
||||
@@ -457,8 +465,7 @@ checksection(void)
|
||||
* A quick check to see if we have an initialized section that can contain
|
||||
* this much initialized data
|
||||
*/
|
||||
void
|
||||
checkcodesection(void)
|
||||
static void checkcodesection(void)
|
||||
{
|
||||
checksection();
|
||||
if (pCurrentSection->nType != SECT_ROM0 &&
|
||||
@@ -473,8 +480,7 @@ checkcodesection(void)
|
||||
/*
|
||||
* Check if the section has grown too much.
|
||||
*/
|
||||
void
|
||||
checksectionoverflow(uint32_t delta_size)
|
||||
static void checksectionoverflow(uint32_t delta_size)
|
||||
{
|
||||
uint32_t maxsize = getmaxsectionsize(pCurrentSection->nType,
|
||||
pCurrentSection->pzName);
|
||||
@@ -495,14 +501,14 @@ checksectionoverflow(uint32_t delta_size)
|
||||
/*
|
||||
* Write an objectfile
|
||||
*/
|
||||
void
|
||||
out_WriteObject(void)
|
||||
void out_WriteObject(void)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
addexports();
|
||||
|
||||
if ((f = fopen(tzObjectname, "wb")) != NULL) {
|
||||
f = fopen(tzObjectname, "wb");
|
||||
if (f != NULL) {
|
||||
struct PatchSymbol *pSym;
|
||||
struct Section *pSect;
|
||||
|
||||
@@ -531,8 +537,7 @@ out_WriteObject(void)
|
||||
/*
|
||||
* Prepare for pass #2
|
||||
*/
|
||||
void
|
||||
out_PrepPass2(void)
|
||||
void out_PrepPass2(void)
|
||||
{
|
||||
struct Section *pSect;
|
||||
|
||||
@@ -548,13 +553,12 @@ out_PrepPass2(void)
|
||||
/*
|
||||
* Set the objectfilename
|
||||
*/
|
||||
void
|
||||
out_SetFileName(char *s)
|
||||
void out_SetFileName(char *s)
|
||||
{
|
||||
tzObjectname = s;
|
||||
if (CurrentOptions.verbose) {
|
||||
if (CurrentOptions.verbose)
|
||||
printf("Output filename %s\n", s);
|
||||
}
|
||||
|
||||
pSectionList = NULL;
|
||||
pCurrentSection = NULL;
|
||||
pPatchSymbols = NULL;
|
||||
@@ -563,8 +567,8 @@ out_SetFileName(char *s)
|
||||
/*
|
||||
* Find a section by name and type. If it doesn't exist, create it
|
||||
*/
|
||||
struct Section *
|
||||
out_FindSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank, int32_t alignment)
|
||||
struct Section *out_FindSection(char *pzName, uint32_t secttype, int32_t org,
|
||||
int32_t bank, int32_t alignment)
|
||||
{
|
||||
struct Section *pSect, **ppSect;
|
||||
|
||||
@@ -574,20 +578,27 @@ out_FindSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank, int3
|
||||
while (pSect) {
|
||||
if (strcmp(pzName, pSect->pzName) == 0) {
|
||||
if (secttype == pSect->nType
|
||||
&& ((uint32_t) org) == pSect->nOrg
|
||||
&& ((uint32_t) bank) == pSect->nBank
|
||||
&& ((uint32_t) alignment == pSect->nAlign)) {
|
||||
return (pSect);
|
||||
} else
|
||||
fatalerror
|
||||
("Section already exists but with a different type");
|
||||
&& ((uint32_t)org) == pSect->nOrg
|
||||
&& ((uint32_t)bank) == pSect->nBank
|
||||
&& ((uint32_t)alignment == pSect->nAlign)) {
|
||||
return pSect;
|
||||
}
|
||||
|
||||
fatalerror("Section already exists but with a different type");
|
||||
}
|
||||
ppSect = &(pSect->pNext);
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
|
||||
if ((*ppSect = (pSect = malloc(sizeof(struct Section)))) != NULL) {
|
||||
if ((pSect->pzName = malloc(strlen(pzName) + 1)) != NULL) {
|
||||
pSect = malloc(sizeof(struct Section));
|
||||
*ppSect = pSect;
|
||||
if (pSect == NULL)
|
||||
fatalerror("Not enough memory for section");
|
||||
|
||||
pSect->pzName = malloc(strlen(pzName) + 1);
|
||||
if (pSect->pzName == NULL)
|
||||
fatalerror("Not enough memory for sectionname");
|
||||
|
||||
strcpy(pSect->pzName, pzName);
|
||||
pSect->nType = secttype;
|
||||
pSect->nPC = 0;
|
||||
@@ -599,32 +610,28 @@ out_FindSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank, int3
|
||||
pSect->charmap = NULL;
|
||||
pPatchSymbols = NULL;
|
||||
|
||||
pSect->tData = NULL;
|
||||
/* It is only needed to allocate memory for ROM sections. */
|
||||
if (secttype == SECT_ROM0 || secttype == SECT_ROMX) {
|
||||
/* It is only needed to allocate memory for ROM
|
||||
* sections. */
|
||||
uint32_t sectsize = getmaxsectionsize(secttype, pzName);
|
||||
if ((pSect->tData = malloc(sectsize)) == NULL)
|
||||
fatalerror("Not enough memory for section");
|
||||
}
|
||||
return (pSect);
|
||||
} else
|
||||
fatalerror("Not enough memory for sectionname");
|
||||
} else
|
||||
fatalerror("Not enough memory for section");
|
||||
uint32_t sectsize;
|
||||
|
||||
return (NULL);
|
||||
sectsize = getmaxsectionsize(secttype, pzName);
|
||||
pSect->tData = malloc(sectsize);
|
||||
if (pSect->tData == NULL)
|
||||
fatalerror("Not enough memory for section");
|
||||
} else {
|
||||
pSect->tData = NULL;
|
||||
}
|
||||
|
||||
return (pSect);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the current section
|
||||
*/
|
||||
void
|
||||
out_SetCurrentSection(struct Section * pSect)
|
||||
void out_SetCurrentSection(struct Section *pSect)
|
||||
{
|
||||
if (nUnionDepth > 0) {
|
||||
if (nUnionDepth > 0)
|
||||
fatalerror("Cannot change the section within a UNION");
|
||||
}
|
||||
|
||||
pCurrentSection = pSect;
|
||||
nPC = pSect->nPC;
|
||||
@@ -636,8 +643,7 @@ out_SetCurrentSection(struct Section * pSect)
|
||||
/*
|
||||
* Set the current section by name and type
|
||||
*/
|
||||
void
|
||||
out_NewSection(char *pzName, uint32_t secttype)
|
||||
void out_NewSection(char *pzName, uint32_t secttype)
|
||||
{
|
||||
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1, 1));
|
||||
}
|
||||
@@ -645,8 +651,8 @@ out_NewSection(char *pzName, uint32_t secttype)
|
||||
/*
|
||||
* Set the current section by name and type
|
||||
*/
|
||||
void
|
||||
out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank)
|
||||
void out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org,
|
||||
int32_t bank)
|
||||
{
|
||||
out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank, 1));
|
||||
}
|
||||
@@ -654,20 +660,20 @@ out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank)
|
||||
/*
|
||||
* Set the current section by name and type, using a given byte alignment
|
||||
*/
|
||||
void
|
||||
out_NewAlignedSection(char *pzName, uint32_t secttype, int32_t alignment, int32_t bank)
|
||||
void out_NewAlignedSection(char *pzName, uint32_t secttype, int32_t alignment,
|
||||
int32_t bank)
|
||||
{
|
||||
if (alignment < 0 || alignment > 16) {
|
||||
if (alignment < 0 || alignment > 16)
|
||||
yyerror("Alignment must be between 0-16 bits.");
|
||||
}
|
||||
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank, 1 << alignment));
|
||||
|
||||
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank,
|
||||
1 << alignment));
|
||||
}
|
||||
|
||||
/*
|
||||
* Output an absolute byte (bypassing ROM/union checks)
|
||||
*/
|
||||
void
|
||||
out_AbsByteBypassCheck(int32_t b)
|
||||
void out_AbsByteBypassCheck(int32_t b)
|
||||
{
|
||||
checksectionoverflow(1);
|
||||
b &= 0xFF;
|
||||
@@ -682,15 +688,13 @@ out_AbsByteBypassCheck(int32_t b)
|
||||
/*
|
||||
* Output an absolute byte
|
||||
*/
|
||||
void
|
||||
out_AbsByte(int32_t b)
|
||||
void out_AbsByte(int32_t b)
|
||||
{
|
||||
checkcodesection();
|
||||
out_AbsByteBypassCheck(b);
|
||||
}
|
||||
|
||||
void
|
||||
out_AbsByteGroup(char *s, int32_t length)
|
||||
void out_AbsByteGroup(char *s, int32_t length)
|
||||
{
|
||||
checkcodesection();
|
||||
checksectionoverflow(length);
|
||||
@@ -701,8 +705,7 @@ out_AbsByteGroup(char *s, int32_t length)
|
||||
/*
|
||||
* Skip this many bytes
|
||||
*/
|
||||
void
|
||||
out_Skip(int32_t skip)
|
||||
void out_Skip(int32_t skip)
|
||||
{
|
||||
checksection();
|
||||
checksectionoverflow(skip);
|
||||
@@ -724,8 +727,7 @@ out_Skip(int32_t skip)
|
||||
/*
|
||||
* Output a NULL terminated string (excluding the NULL-character)
|
||||
*/
|
||||
void
|
||||
out_String(char *s)
|
||||
void out_String(char *s)
|
||||
{
|
||||
checkcodesection();
|
||||
checksectionoverflow(strlen(s));
|
||||
@@ -737,9 +739,7 @@ out_String(char *s)
|
||||
* Output a relocatable byte. Checking will be done to see if it
|
||||
* is an absolute value in disguise.
|
||||
*/
|
||||
|
||||
void
|
||||
out_RelByte(struct Expression * expr)
|
||||
void out_RelByte(struct Expression *expr)
|
||||
{
|
||||
checkcodesection();
|
||||
checksectionoverflow(1);
|
||||
@@ -751,17 +751,16 @@ out_RelByte(struct Expression * expr)
|
||||
pCurrentSection->nPC += 1;
|
||||
nPC += 1;
|
||||
pPCSymbol->nValue += 1;
|
||||
} else
|
||||
} else {
|
||||
out_AbsByte(expr->nVal);
|
||||
|
||||
}
|
||||
rpn_Reset(expr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output an absolute word
|
||||
*/
|
||||
void
|
||||
out_AbsWord(int32_t b)
|
||||
void out_AbsWord(int32_t b)
|
||||
{
|
||||
checkcodesection();
|
||||
checksectionoverflow(2);
|
||||
@@ -779,8 +778,7 @@ out_AbsWord(int32_t b)
|
||||
* Output a relocatable word. Checking will be done to see if
|
||||
* it's an absolute value in disguise.
|
||||
*/
|
||||
void
|
||||
out_RelWord(struct Expression * expr)
|
||||
void out_RelWord(struct Expression *expr)
|
||||
{
|
||||
uint32_t b;
|
||||
|
||||
@@ -796,16 +794,16 @@ out_RelWord(struct Expression * expr)
|
||||
pCurrentSection->nPC += 2;
|
||||
nPC += 2;
|
||||
pPCSymbol->nValue += 2;
|
||||
} else
|
||||
} else {
|
||||
out_AbsWord(expr->nVal);
|
||||
}
|
||||
rpn_Reset(expr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output an absolute longword
|
||||
*/
|
||||
void
|
||||
out_AbsLong(int32_t b)
|
||||
void out_AbsLong(int32_t b)
|
||||
{
|
||||
checkcodesection();
|
||||
checksectionoverflow(sizeof(int32_t));
|
||||
@@ -824,8 +822,7 @@ out_AbsLong(int32_t b)
|
||||
* Output a relocatable longword. Checking will be done to see if
|
||||
* is an absolute value in disguise.
|
||||
*/
|
||||
void
|
||||
out_RelLong(struct Expression * expr)
|
||||
void out_RelLong(struct Expression *expr)
|
||||
{
|
||||
int32_t b;
|
||||
|
||||
@@ -843,16 +840,16 @@ out_RelLong(struct Expression * expr)
|
||||
pCurrentSection->nPC += 4;
|
||||
nPC += 4;
|
||||
pPCSymbol->nValue += 4;
|
||||
} else
|
||||
} else {
|
||||
out_AbsLong(expr->nVal);
|
||||
}
|
||||
rpn_Reset(expr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output a PC-relative byte
|
||||
*/
|
||||
void
|
||||
out_PCRelByte(struct Expression * expr)
|
||||
void out_PCRelByte(struct Expression *expr)
|
||||
{
|
||||
int32_t b = expr->nVal;
|
||||
|
||||
@@ -869,15 +866,13 @@ out_PCRelByte(struct Expression * expr)
|
||||
/*
|
||||
* Output a binary file
|
||||
*/
|
||||
void
|
||||
out_BinaryFile(char *s)
|
||||
void out_BinaryFile(char *s)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fstk_FindFile(s);
|
||||
if (f == NULL) {
|
||||
if (f == NULL)
|
||||
err(1, "Unable to open incbin file '%s'", s);
|
||||
}
|
||||
|
||||
int32_t fsize;
|
||||
|
||||
@@ -901,8 +896,7 @@ out_BinaryFile(char *s)
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void
|
||||
out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length)
|
||||
void out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
@@ -913,9 +907,8 @@ out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length)
|
||||
fatalerror("Number of bytes to read must be greater than zero");
|
||||
|
||||
f = fstk_FindFile(s);
|
||||
if (f == NULL) {
|
||||
if (f == NULL)
|
||||
err(1, "Unable to open included file '%s'", s);
|
||||
}
|
||||
|
||||
int32_t fsize;
|
||||
|
||||
|
||||
178
src/asm/rpn.c
178
src/asm/rpn.c
@@ -12,9 +12,8 @@
|
||||
#include "asm/rpn.h"
|
||||
#include "asm/symbol.h"
|
||||
|
||||
void
|
||||
mergetwoexpressions(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void mergetwoexpressions(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
*expr = *src1;
|
||||
memcpy(&(expr->tRPN[expr->nRPNLength]), src2->tRPN, src2->nRPNLength);
|
||||
@@ -23,13 +22,13 @@ mergetwoexpressions(struct Expression * expr, struct Expression * src1,
|
||||
expr->isReloc |= src2->isReloc;
|
||||
expr->isPCRel |= src2->isPCRel;
|
||||
}
|
||||
#define joinexpr() mergetwoexpressions(expr,src1,src2)
|
||||
|
||||
#define joinexpr() mergetwoexpressions(expr, src1, src2)
|
||||
|
||||
/*
|
||||
* Add a byte to the RPN expression
|
||||
*/
|
||||
void
|
||||
pushbyte(struct Expression * expr, int b)
|
||||
void pushbyte(struct Expression *expr, int b)
|
||||
{
|
||||
expr->tRPN[expr->nRPNLength++] = b & 0xFF;
|
||||
}
|
||||
@@ -37,47 +36,45 @@ pushbyte(struct Expression * expr, int b)
|
||||
/*
|
||||
* Reset the RPN module
|
||||
*/
|
||||
void
|
||||
rpn_Reset(struct Expression * expr)
|
||||
void rpn_Reset(struct Expression *expr)
|
||||
{
|
||||
expr->nRPNLength = expr->nRPNOut = expr->isReloc = expr->isPCRel = 0;
|
||||
expr->nRPNLength = 0;
|
||||
expr->nRPNOut = 0;
|
||||
expr->isReloc = 0;
|
||||
expr->isPCRel = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the next rpn byte in expression
|
||||
*/
|
||||
uint16_t
|
||||
rpn_PopByte(struct Expression * expr)
|
||||
uint16_t rpn_PopByte(struct Expression *expr)
|
||||
{
|
||||
if (expr->nRPNOut == expr->nRPNLength) {
|
||||
return (0xDEAD);
|
||||
} else
|
||||
return (expr->tRPN[expr->nRPNOut++]);
|
||||
if (expr->nRPNOut == expr->nRPNLength)
|
||||
return 0xDEAD;
|
||||
|
||||
return expr->tRPN[expr->nRPNOut++];
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if the current expression is relocatable
|
||||
*/
|
||||
uint32_t
|
||||
rpn_isReloc(struct Expression * expr)
|
||||
uint32_t rpn_isReloc(const struct Expression *expr)
|
||||
{
|
||||
return (expr->isReloc);
|
||||
return expr->isReloc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if the current expression can be pc-relative
|
||||
*/
|
||||
uint32_t
|
||||
rpn_isPCRelative(struct Expression * expr)
|
||||
uint32_t rpn_isPCRelative(const struct Expression *expr)
|
||||
{
|
||||
return (expr->isPCRel);
|
||||
return expr->isPCRel;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add symbols, constants and operators to expression
|
||||
*/
|
||||
void
|
||||
rpn_Number(struct Expression * expr, uint32_t i)
|
||||
void rpn_Number(struct Expression *expr, uint32_t i)
|
||||
{
|
||||
rpn_Reset(expr);
|
||||
pushbyte(expr, RPN_CONST);
|
||||
@@ -88,11 +85,10 @@ rpn_Number(struct Expression * expr, uint32_t i)
|
||||
expr->nVal = i;
|
||||
}
|
||||
|
||||
void
|
||||
rpn_Symbol(struct Expression * expr, char *tzSym)
|
||||
void rpn_Symbol(struct Expression *expr, char *tzSym)
|
||||
{
|
||||
if (!sym_isConstant(tzSym)) {
|
||||
struct sSymbol *psym;
|
||||
const struct sSymbol *psym;
|
||||
|
||||
rpn_Reset(expr);
|
||||
|
||||
@@ -106,17 +102,20 @@ rpn_Symbol(struct Expression * expr, char *tzSym)
|
||||
while (*tzSym)
|
||||
pushbyte(expr, *tzSym++);
|
||||
pushbyte(expr, 0);
|
||||
} else
|
||||
} else {
|
||||
rpn_Number(expr, sym_GetConstantValue(tzSym));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rpn_Bank(struct Expression * expr, char *tzSym)
|
||||
void rpn_Bank(struct Expression *expr, char *tzSym)
|
||||
{
|
||||
if (!sym_isConstant(tzSym)) {
|
||||
rpn_Reset(expr);
|
||||
|
||||
/* Check that the symbol exists by evaluating and discarding the value. */
|
||||
/*
|
||||
* Check that the symbol exists by evaluating and discarding the
|
||||
* value.
|
||||
*/
|
||||
sym_GetValue(tzSym);
|
||||
|
||||
expr->isReloc = 1;
|
||||
@@ -124,44 +123,40 @@ rpn_Bank(struct Expression * expr, char *tzSym)
|
||||
while (*tzSym)
|
||||
pushbyte(expr, *tzSym++);
|
||||
pushbyte(expr, 0);
|
||||
} else
|
||||
} else {
|
||||
yyerror("BANK argument must be a relocatable identifier");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rpn_CheckHRAM(struct Expression * expr, struct Expression * src)
|
||||
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
|
||||
{
|
||||
*expr = *src;
|
||||
pushbyte(expr, RPN_HRAM);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOGNOT(struct Expression * expr, struct Expression * src)
|
||||
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src)
|
||||
{
|
||||
*expr = *src;
|
||||
pushbyte(expr, RPN_LOGUNNOT);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOGOR(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_LOGOR(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal || src2->nVal);
|
||||
pushbyte(expr, RPN_LOGOR);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOGAND(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_LOGAND(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal && src2->nVal);
|
||||
pushbyte(expr, RPN_LOGAND);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_HIGH(struct Expression * expr, struct Expression * src)
|
||||
void rpn_HIGH(struct Expression *expr, const struct Expression *src)
|
||||
{
|
||||
*expr = *src;
|
||||
|
||||
@@ -184,8 +179,7 @@ rpn_HIGH(struct Expression * expr, struct Expression * src)
|
||||
pushbyte(expr, RPN_AND);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOW(struct Expression * expr, struct Expression * src)
|
||||
void rpn_LOW(struct Expression *expr, const struct Expression *src)
|
||||
{
|
||||
*expr = *src;
|
||||
|
||||
@@ -200,166 +194,148 @@ rpn_LOW(struct Expression * expr, struct Expression * src)
|
||||
pushbyte(expr, RPN_AND);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOGEQU(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_LOGEQU(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal == src2->nVal);
|
||||
pushbyte(expr, RPN_LOGEQ);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOGGT(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_LOGGT(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal > src2->nVal);
|
||||
pushbyte(expr, RPN_LOGGT);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOGLT(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_LOGLT(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal < src2->nVal);
|
||||
pushbyte(expr, RPN_LOGLT);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOGGE(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_LOGGE(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal >= src2->nVal);
|
||||
pushbyte(expr, RPN_LOGGE);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOGLE(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_LOGLE(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal <= src2->nVal);
|
||||
pushbyte(expr, RPN_LOGLE);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_LOGNE(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_LOGNE(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal != src2->nVal);
|
||||
pushbyte(expr, RPN_LOGNE);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_ADD(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_ADD(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal + src2->nVal);
|
||||
pushbyte(expr, RPN_ADD);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_SUB(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_SUB(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal - src2->nVal);
|
||||
pushbyte(expr, RPN_SUB);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_XOR(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_XOR(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal ^ src2->nVal);
|
||||
pushbyte(expr, RPN_XOR);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_OR(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_OR(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal | src2->nVal);
|
||||
pushbyte(expr, RPN_OR);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_AND(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_AND(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal & src2->nVal);
|
||||
pushbyte(expr, RPN_AND);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_SHL(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_SHL(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal << src2->nVal);
|
||||
pushbyte(expr, RPN_SHL);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_SHR(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_SHR(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal >> src2->nVal);
|
||||
pushbyte(expr, RPN_SHR);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_MUL(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_MUL(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
expr->nVal = (expr->nVal * src2->nVal);
|
||||
pushbyte(expr, RPN_MUL);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_DIV(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_DIV(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
if (src2->nVal == 0) {
|
||||
if (src2->nVal == 0)
|
||||
fatalerror("division by zero");
|
||||
}
|
||||
|
||||
expr->nVal = (expr->nVal / src2->nVal);
|
||||
pushbyte(expr, RPN_DIV);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_MOD(struct Expression * expr, struct Expression * src1,
|
||||
struct Expression * src2)
|
||||
void rpn_MOD(struct Expression *expr, const struct Expression *src1,
|
||||
const struct Expression *src2)
|
||||
{
|
||||
joinexpr();
|
||||
if (src2->nVal == 0) {
|
||||
if (src2->nVal == 0)
|
||||
fatalerror("division by zero");
|
||||
}
|
||||
|
||||
expr->nVal = (expr->nVal % src2->nVal);
|
||||
pushbyte(expr, RPN_MOD);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_UNNEG(struct Expression * expr, struct Expression * src)
|
||||
void rpn_UNNEG(struct Expression *expr, const struct Expression *src)
|
||||
{
|
||||
*expr = *src;
|
||||
expr->nVal = -expr->nVal;
|
||||
pushbyte(expr, RPN_UNSUB);
|
||||
}
|
||||
|
||||
void
|
||||
rpn_UNNOT(struct Expression * expr, struct Expression * src)
|
||||
void rpn_UNNOT(struct Expression *expr, const struct Expression *src)
|
||||
{
|
||||
*expr = *src;
|
||||
expr->nVal = ~expr->nVal;
|
||||
|
||||
532
src/asm/symbol.c
532
src/asm/symbol.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user