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