diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index d19b474fb..5cf6a856c 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -134,7 +134,7 @@ void AddLabel (unsigned Addr, const char* Name) } /* Create a new label */ - SymTab[Addr] = xstrdup (Name); + SymTab[Addr] = xstrdup (Name); } diff --git a/src/da65/config.c b/src/da65/config.c new file mode 100644 index 000000000..7d284d242 --- /dev/null +++ b/src/da65/config.c @@ -0,0 +1,241 @@ +/*****************************************************************************/ +/* */ +/* config.c */ +/* */ +/* Disassembler configuration file handling */ +/* */ +/* */ +/* */ +/* (C) 2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#if defined(_MSC_VER) +/* Microsoft compiler */ +# include +#else +/* Anyone else */ +# include +#endif + +/* common */ +#include "xmalloc.h" + +/* da65 */ +#include "global.h" +#include "scanner.h" +#include "config.h" + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static void GlobalSection (void) +/* Parse a global section */ +{ + static const IdentTok GlobalDefs[] = { + { "INPUTNAME", CFGTOK_INPUTNAME }, + { "OUTPUTNAME", CFGTOK_OUTPUTNAME }, + { "PAGELENGTH", CFGTOK_PAGELENGTH }, + }; + + /* Skip the token */ + CfgNextTok (); + + /* Expect the opening curly brace */ + CfgConsumeLCurly (); + + /* Look for section tokens */ + while (CfgTok != CFGTOK_RCURLY) { + + /* Convert to special token */ + CfgSpecialToken (GlobalDefs, ENTRY_COUNT (GlobalDefs), "Global directive"); + + /* Look at the token */ + switch (CfgTok) { + + case CFGTOK_INPUTNAME: + CfgNextTok (); + CfgAssureStr (); + if (InFile) { + CfgError ("Input file name already given"); + } + InFile = xstrdup (CfgSVal); + CfgNextTok (); + break; + + case CFGTOK_OUTPUTNAME: + CfgNextTok (); + CfgAssureStr (); + if (OutFile) { + CfgError ("Output file name already given"); + } + OutFile = xstrdup (CfgSVal); + CfgNextTok (); + break; + + case CFGTOK_PAGELENGTH: + CfgNextTok (); + CfgAssureInt (); + if (CfgIVal != -1) { + CfgRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN); + } + PageLength = CfgIVal; + CfgNextTok (); + break; + } + + /* Directive is followed by a semicolon */ + CfgConsumeSemi (); + + } + + /* Consume the closing brace */ + CfgConsumeRCurly (); +} + + + +static void RangeSection (void) +/* Parse a range section */ +{ + static const IdentTok RangeDefs[] = { + { "START", CFGTOK_START }, + { "END", CFGTOK_END }, + { "TYPE", CFGTOK_TYPE }, + }; + + /* Skip the token */ + CfgNextTok (); + + /* Expect the opening curly brace */ + CfgConsumeLCurly (); + + /* Look for section tokens */ + while (CfgTok != CFGTOK_RCURLY) { + + + } + + /* Consume the closing brace */ + CfgConsumeRCurly (); +} + + + +static void LabelSection (void) +/* Parse a label section */ +{ + static const IdentTok Globals[] = { + { "INPUTNAMEL", CFGTOK_INPUTNAME }, + { "OUTPUTNAME", CFGTOK_OUTPUTNAME }, + { "PAGELENGTH", CFGTOK_PAGELENGTH }, + }; + + /* Skip the token */ + CfgNextTok (); + + /* Expect the opening curly brace */ + CfgConsumeLCurly (); + + /* Look for section tokens */ + while (CfgTok != CFGTOK_RCURLY) { + + + } + + /* Consume the closing brace */ + CfgConsumeRCurly (); +} + + + +static void CfgParse (void) +/* Parse the config file */ +{ + static const IdentTok Globals[] = { + { "GLOBAL", CFGTOK_GLOBAL }, + { "RANGE", CFGTOK_RANGE }, + { "LABEL", CFGTOK_LABEL }, + }; + + while (CfgTok != CFGTOK_EOF) { + + /* Convert an identifier into a token */ + CfgSpecialToken (Globals, ENTRY_COUNT (Globals), "Config directive"); + + /* Check the token */ + switch (CfgTok) { + + case CFGTOK_GLOBAL: + GlobalSection (); + break; + + case CFGTOK_RANGE: + RangeSection (); + break; + + case CFGTOK_LABEL: + LabelSection (); + break; + + } + + /* Semicolon expected */ + CfgConsumeSemi (); + } +} + + + +void CfgRead (void) +/* Read the configuration if a configuration file exists */ +{ + /* Check if we have a config file given */ + if (!CfgAvail() || access (CfgGetName(), 0) != 0) { + /* No name given or file not found */ + return; + } + + /* Open the config file */ + CfgOpenInput (); + + /* Parse the config file */ + CfgParse (); + + /* Close the file */ + CfgCloseInput (); +} + + + + + + diff --git a/src/da65/config.h b/src/da65/config.h new file mode 100644 index 000000000..382279241 --- /dev/null +++ b/src/da65/config.h @@ -0,0 +1,56 @@ +/*****************************************************************************/ +/* */ +/* config.h */ +/* */ +/* Disassembler configuration file handling */ +/* */ +/* */ +/* */ +/* (C) 2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef CONFIG_H +#define CONFIG_H + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void CfgRead (void); +/* Read the configuration if a configuration file exists */ + + + +/* End of config.h */ +#endif + + + diff --git a/src/da65/cpu.h b/src/da65/cpu.h index 3d2210ec0..b945c6ba6 100644 --- a/src/da65/cpu.h +++ b/src/da65/cpu.h @@ -46,9 +46,10 @@ /* Supported CPUs */ typedef enum CPUType { - CPU_6502, - CPU_65C02, - CPU_65816 + CPU_6502 = 0x01, + CPU_65C02 = 0x02, + CPU_65816 = 0x04, + CPU_ALL = 0x07 } CPUType; /* Current CPU */ diff --git a/src/da65/global.c b/src/da65/global.c index 3e99ec8c3..c0ca7588e 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -48,11 +48,11 @@ const char* InFile = 0; /* Name of input file */ const char* OutFile = 0; /* Name of output file */ /* Default extensions */ -const char ObjExt[] = ".o"; /* Default object extension */ -const char ListExt[] = ".lst"; /* Default listing extension */ +const char OutExt[] = ".dis"; /* Output file extension */ +const char CfgExt[] = ".cfg"; /* Config file extension */ /* Flags and other command line stuff */ -unsigned char Verbose = 2; /* Verbosity of the output file */ +unsigned char Verbosity = 2; /* Verbosity of the output file */ /* Stuff needed by many routines */ unsigned Pass = 0; /* Disassembler pass */ diff --git a/src/da65/global.h b/src/da65/global.h index 0af03cdd3..e70295c2a 100644 --- a/src/da65/global.h +++ b/src/da65/global.h @@ -49,11 +49,11 @@ extern const char* InFile; /* Name of input file */ extern const char* OutFile; /* Name of output file */ /* Default extensions */ -extern const char ObjExt[]; /* Default object extension */ -extern const char ListExt[]; /* Default listing extension */ +extern const char OutExt[]; /* Output file extension */ +extern const char CfgExt[]; /* Config file extension */ /* Flags and other command line stuff */ -extern unsigned char Verbose; /* Verbosity of the output file */ +extern unsigned char Verbosity; /* Verbosity of the output file */ /* Stuff needed by many routines */ extern unsigned Pass; /* Disassembler pass */ diff --git a/src/da65/main.c b/src/da65/main.c index c343a6444..abcfd474a 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -48,10 +48,12 @@ /* da65 */ #include "attrtab.h" #include "code.h" +#include "config.h" #include "cpu.h" #include "global.h" #include "opctable.h" #include "output.h" +#include "scanner.h" @@ -151,7 +153,7 @@ static void OptPageLength (const char* Opt, const char* Arg) static void OptVerbose (const char* Opt, const char* Arg) /* Increase verbosity */ { - ++Verbose; + ++Verbosity; } @@ -172,9 +174,6 @@ static void OneOpcode (unsigned RemainingBytes) /* Get the current PC */ unsigned PC = GetPC (); - /* Get the attribute for the current address */ - unsigned char Style = GetStyle (PC); - /* Get the opcode from the current address */ unsigned char OPC = PeekCodeByte (); @@ -187,20 +186,42 @@ static void OneOpcode (unsigned RemainingBytes) DefLabel (Label); } - /* Check if we have enough bytes remaining for the code at this address. */ - if (D->Size > RemainingBytes) { - OneDataByte (); - return; + /* Check... + * - ...if we have enough bytes remaining for the code at this address. + * - ...if the current instruction is valid for the given CPU. + * - ...if there is no label somewhere between the instruction bytes. + * If any of these conditions is true, switch to data mode. + */ + if (GetStyle (PC) == atDefault) { + if (D->Size > RemainingBytes) { + MarkAddr (PC, atIllegal); + } else if ((D->CPU & CPU) != CPU) { + MarkAddr (PC, atIllegal); + } else { + unsigned I; + for (I = 1; I < D->Size; ++I) { + if (HaveLabel (PC+I)) { + MarkAddr (PC, atIllegal); + break; + } + } + } } - /* Also check if there are any labels that point into this instruction. - * If so, disassemble one byte as data. - */ - /* ### */ - /* Disassemble the line */ - GetCodeByte (); - D->Handler (D); + switch (GetStyle (PC)) { + + case atDefault: + case atCode: + GetCodeByte (); + D->Handler (D); + break; + + default: + OneDataByte (); + break; + + } } @@ -309,9 +330,17 @@ int main (int argc, char* argv []) AbEnd ("No input file"); } + /* Make the config file name from the input file if none was given */ + if (!CfgAvail ()) { + CfgSetName (MakeFilename (InFile, CfgExt)); + } + + /* Try to read the configuration file */ + CfgRead (); + /* Make the output file name from the input file name if none was given */ if (OutFile == 0) { - OutFile = MakeFilename (InFile, ".dis"); + OutFile = MakeFilename (InFile, OutExt); } /* Load the input file */ diff --git a/src/da65/make/gcc.mak b/src/da65/make/gcc.mak index d0502f70b..47af383ac 100644 --- a/src/da65/make/gcc.mak +++ b/src/da65/make/gcc.mak @@ -10,14 +10,16 @@ CC=gcc LDFLAGS= OBJS = attrtab.o \ - code.o \ - cpu.o \ - error.o \ - global.o \ + code.o \ + config.o \ + cpu.o \ + error.o \ + global.o \ handler.o \ - main.o \ + main.o \ opctable.o \ - output.o + output.o \ + scanner.o LIBS = $(COMMON)/common.a diff --git a/src/da65/opctable.c b/src/da65/opctable.c index da72b672a..fd9ee6c36 100644 --- a/src/da65/opctable.c +++ b/src/da65/opctable.c @@ -33,6 +33,8 @@ +/* da65 */ +#include "cpu.h" #include "handler.h" #include "opctable.h" @@ -49,1792 +51,1792 @@ const OpcDesc OpcTable[256] = { "brk", 2, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $01 */ "ora", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectXIndirect }, { /* $02 */ "cop", 2, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $03 */ "ora", 2, 0, - cpu65816, + CPU_65816, OH_StackRelative }, { /* $04 */ "tsb", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_Direct }, { /* $05 */ "ora", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $06 */ "asl", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $07 */ "ora", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLong }, { /* $08 */ "php", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $09 */ "ora", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $0a */ "asl", 1, 0, - cpuAll, + CPU_ALL, OH_Accumulator }, { /* $0b */ "phd", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $0c */ "tsb", 3, lfUseLabel, - cpu65816, + CPU_65816, OH_Absolute }, { /* $0d */ "ora", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $0e */ "asl", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $0f */ "ora", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $10 */ "bpl", 2, lfLabel, - cpuAll, + CPU_ALL, OH_Relative }, { /* $11 */ "ora", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectIndirectY }, { /* $12 */ "ora", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirect }, { /* $13 */ "ora", 2, 0, - cpu65816, + CPU_65816, OH_StackRelativeIndirectY }, { /* $14 */ "trb", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_Direct }, { /* $15 */ "ora", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $16 */ "asl", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $17 */ "ora", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLongY }, { /* $18 */ "clc", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $19 */ "ora", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteY }, { /* $1a */ "inc", 1, 0, - cpu65816, + CPU_65816, OH_Accumulator }, { /* $1b */ "tcs", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $1c */ "trb", 3, lfUseLabel, - cpu65816, + CPU_65816, OH_Absolute }, { /* $1d */ "ora", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $1e */ "asl", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $1f */ "ora", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLongX }, { /* $20 */ "jsr", 3, lfLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $21 */ "and", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectXIndirect }, { /* $22 */ "jsl", 3, lfLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $23 */ "and", 2, 0, - cpu65816, + CPU_65816, OH_StackRelative }, { /* $24 */ "bit", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $25 */ "and", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $26 */ "rol", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $27 */ "and", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLong }, { /* $28 */ "plp", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $29 */ "and", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $2a */ "rol", 1, 0, - cpuAll, + CPU_ALL, OH_Accumulator }, { /* $2b */ "pld", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $2c */ "bit", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $2d */ "and", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $2e */ "rol", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $2f */ "and", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $30 */ "bmi", 2, lfLabel, - cpuAll, + CPU_ALL, OH_Relative }, { /* $31 */ "and", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectIndirectY }, { /* $32 */ "and", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirect }, { /* $33 */ "and", 2, 0, - cpu65816, + CPU_65816, OH_StackRelativeIndirectY }, { /* $34 */ "bit", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectX }, { /* $35 */ "and", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $36 */ "rol", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $37 */ "and", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLongY }, { /* $38 */ "sec", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $39 */ "and", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteY }, { /* $3a */ "dec", 1, 0, - cpu65816, + CPU_65816, OH_Accumulator }, { /* $3b */ "tsc", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $3c */ "bit", 3, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteX }, { /* $3d */ "and", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $3e */ "rol", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $3f */ "and", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLongX }, { /* $40 */ "rti", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $41 */ "eor", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectXIndirect }, { /* $42 */ "wdm", 2, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $43 */ "eor", 2, 0, - cpu65816, + CPU_65816, OH_StackRelative }, { /* $44 */ "mvp", 3, 0, - cpu65816, + CPU_65816, OH_BlockMove }, { /* $45 */ "eor", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $46 */ "lsr", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $47 */ "eor", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLong }, { /* $48 */ "pha", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $49 */ "eor", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $4a */ "lsr", 1, 0, - cpuAll, + CPU_ALL, OH_Accumulator }, { /* $4b */ "phk", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $4c */ "jmp", 3, lfLabel, - cpuAll, + CPU_ALL, OH_JmpAbsolute }, { /* $4d */ "eor", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $4e */ "lsr", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $4f */ "eor", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $50 */ "bvc", 2, lfLabel, - cpuAll, + CPU_ALL, OH_Relative }, { /* $51 */ "eor", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectIndirectY }, { /* $52 */ "eor", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirect }, { /* $53 */ "eor", 2, 0, - cpu65816, + CPU_65816, OH_StackRelativeIndirectY }, { /* $54 */ "mvn", 3, 0, - cpu65816, + CPU_65816, OH_BlockMove }, { /* $55 */ "eor", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $56 */ "lsr", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $57 */ "eor", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLongY }, { /* $58 */ "cli", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $59 */ "eor", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteY }, { /* $5a */ "phy", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $5b */ "tcd", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $5c */ "jml", 4, lfLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $5d */ "eor", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $5e */ "lsr", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $5f */ "eor", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLongX }, { /* $60 */ "rts", 1, 0, - cpuAll, + CPU_ALL, OH_Rts }, { /* $61 */ "adc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectXIndirect }, { /* $62 */ "per", 3, lfLabel, - cpu65816, + CPU_65816, OH_RelativeLong }, { /* $63 */ "adc", 2, 0, - cpu65816, + CPU_65816, OH_StackRelative }, { /* $64 */ "stz", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_Direct }, { /* $65 */ "adc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $66 */ "ror", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $67 */ "adc", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLong }, { /* $68 */ "pla", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $69 */ "adc", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $6a */ "ror", 1, 0, - cpuAll, + CPU_ALL, OH_Accumulator }, { /* $6b */ "rtl", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $6c */ "jmp", 3, lfLabel, - cpuAll, + CPU_ALL, OH_AbsoluteIndirect }, { /* $6d */ "adc", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $6e */ "ror", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $6f */ "adc", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $70 */ "bvs", 2, lfLabel, - cpuAll, + CPU_ALL, OH_Relative }, { /* $71 */ "adc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectIndirectY }, { /* $72 */ "adc", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirect }, { /* $73 */ "adc", 2, 0, - cpu65816, + CPU_65816, OH_StackRelativeIndirectY }, { /* $74 */ "stz", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectX }, { /* $75 */ "adc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $76 */ "ror", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $77 */ "adc", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLongY }, { /* $78 */ "sei", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $79 */ "adc", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteY }, { /* $7a */ "ply", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $7b */ "tdc", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $7c */ "jmp", 3, lfLabel, - cpu65816, + CPU_65816, OH_AbsoluteXIndirect }, { /* $7d */ "adc", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $7e */ "ror", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $7f */ "adc", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLongX }, { /* $80 */ "bra", 2, lfLabel, - cpu65816, + CPU_65816, OH_Relative }, { /* $81 */ "sta", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectXIndirect }, { /* $82 */ "brl", 3, lfLabel, - cpu65816, + CPU_65816, OH_RelativeLong }, { /* $83 */ "sta", 2, 0, - cpu65816, + CPU_65816, OH_StackRelative }, { /* $84 */ "sty", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $85 */ "sta", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $86 */ "stx", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $87 */ "sta", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLong }, { /* $88 */ "dey", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $89 */ "bit", 2, 0, - cpu65816, + CPU_65816, OH_Immidiate }, { /* $8a */ "txa", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $8b */ "phb", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $8c */ "sty", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $8d */ "sta", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $8e */ "stx", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $8f */ "sta", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $90 */ "bcc", 2, lfLabel, - cpuAll, + CPU_ALL, OH_Relative }, { /* $91 */ "sta", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectIndirectY }, { /* $92 */ "sta", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirect }, { /* $93 */ "sta", 2, 0, - cpu65816, + CPU_65816, OH_StackRelativeIndirectY }, { /* $94 */ "sty", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $95 */ "sta", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $96 */ "stx", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectY }, { /* $97 */ "sta", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLongY }, { /* $98 */ "tya", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $99 */ "sta", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteY }, { /* $9a */ "txs", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $9b */ "txy", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $9c */ "stz", 3, lfUseLabel, - cpu65816, + CPU_65816, OH_Absolute }, { /* $9d */ "sta", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $9e */ "stz", 3, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteX }, { /* $9f */ "sta", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLongX }, { /* $a0 */ "ldy", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $a1 */ "lda", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectXIndirect }, { /* $a2 */ "ldx", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $a3 */ "lda", 2, 0, - cpu65816, + CPU_65816, OH_StackRelative }, { /* $a4 */ "ldy", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $a5 */ "lda", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $a6 */ "ldx", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $a7 */ "lda", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLong }, { /* $a8 */ "tay", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $a9 */ "lda", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $aa */ "tax", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $ab */ "plb", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $ac */ "ldy", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $ad */ "lda", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $ae */ "ldx", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $af */ "lda", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $b0 */ "bcs", 2, lfLabel, - cpuAll, + CPU_ALL, OH_Relative }, { /* $b1 */ "lda", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectIndirectY }, { /* $b2 */ "lda", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirect }, { /* $b3 */ "lda", 2, 0, - cpu65816, + CPU_65816, OH_StackRelativeIndirectY }, { /* $b4 */ "ldy", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $b5 */ "lda", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $b6 */ "ldx", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectY }, { /* $b7 */ "lda", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLongY }, { /* $b8 */ "clv", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $b9 */ "lda", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteY }, { /* $ba */ "tsx", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $bb */ "tyx", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $bc */ "ldy", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $bd */ "lda", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $be */ "ldx", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteY }, { /* $bf */ "lda", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLongX }, { /* $c0 */ "cpy", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $c1 */ "cmp", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectXIndirect }, { /* $c2 */ "rep", 2, 0, - cpu65816, + CPU_65816, OH_Immidiate }, { /* $c3 */ "cmp", 2, 0, - cpu65816, + CPU_65816, OH_StackRelative }, { /* $c4 */ "cpy", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $c5 */ "cmp", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $c6 */ "dec", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $c7 */ "cmp", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLong }, { /* $c8 */ "iny", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $c9 */ "cmp", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $ca */ "dex", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $cb */ "wai", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $cc */ "cpy", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $cd */ "cmp", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $ce */ "dec", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $cf */ "cmp", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $d0 */ "bne", 2, lfLabel, - cpuAll, + CPU_ALL, OH_Relative }, { /* $d1 */ "cmp", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectXIndirect }, { /* $d2 */ "cmp", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirect }, { /* $d3 */ "cmp", 2, 0, - cpu65816, + CPU_65816, OH_StackRelativeIndirectY }, { /* $d4 */ "pei", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_Direct }, { /* $d5 */ "cmp", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $d6 */ "dec", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $d7 */ "cmp", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLongY }, { /* $d8 */ "cld", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $d9 */ "cmp", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteY }, { /* $da */ "phx", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $db */ "stp", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $dc */ "jml", 3, lfLabel, - cpu65816, + CPU_65816, OH_AbsoluteIndirect }, { /* $dd */ "cmp", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $de */ "dec", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $df */ "cmp", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLongX }, { /* $e0 */ "cpx", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $e1 */ "sbc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectXIndirect }, { /* $e2 */ "sep", 2, 0, - cpu65816, + CPU_65816, OH_Immidiate }, { /* $e3 */ "sbc", 2, 0, - cpu65816, + CPU_65816, OH_StackRelative }, { /* $e4 */ "cpx", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $e5 */ "sbc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $e6 */ "inc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_Direct }, { /* $e7 */ "sbc", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLong }, { /* $e8 */ "inx", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $e9 */ "sbc", 2, 0, - cpuAll, + CPU_ALL, OH_Immidiate }, { /* $ea */ "nop", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $eb */ "xba", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $ec */ "cpx", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $ed */ "sbc", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $ee */ "inc", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_Absolute }, { /* $ef */ "sbc", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLong }, { /* $f0 */ "beq", 2, lfLabel, - cpuAll, + CPU_ALL, OH_Relative }, { /* $f1 */ "sbc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectIndirectY }, { /* $f2 */ "sbc", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirect }, { /* $f3 */ "sbc", 2, 0, - cpu65816, + CPU_65816, OH_StackRelativeIndirectY }, { /* $f4 */ "pea", 3, lfUseLabel, - cpu65816, + CPU_65816, OH_Absolute }, { /* $f5 */ "sbc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $f6 */ "inc", 2, lfUseLabel, - cpuAll, + CPU_ALL, OH_DirectX }, { /* $f7 */ "sbc", 2, lfUseLabel, - cpu65816, + CPU_65816, OH_DirectIndirectLongY }, { /* $f8 */ "sed", 1, 0, - cpuAll, + CPU_ALL, OH_Implicit }, { /* $f9 */ "sbc", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteY }, { /* $fa */ "plx", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $fb */ "xce", 1, 0, - cpu65816, + CPU_65816, OH_Implicit }, { /* $fc */ "jsr", 3, lfLabel, - cpu65816, + CPU_65816, OH_AbsoluteXIndirect }, { /* $fd */ "sbc", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $fe */ "inc", 3, lfUseLabel, - cpuAll, + CPU_ALL, OH_AbsoluteX }, { /* $ff */ "sbc", 4, lfUseLabel, - cpu65816, + CPU_65816, OH_AbsoluteLongX }, }; diff --git a/src/da65/opctable.h b/src/da65/opctable.h index 480fe8854..f89daa5cb 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -52,14 +52,6 @@ enum { lfLabel = lfUseLabel|lfGenLabel /* Generate and use a label */ }; -/* Constants for the CPU type */ -enum { - cpu6502 = 0x01, - cpu65C02 = 0x02, - cpu65816 = 0x04, - cpuAll = 0x07, -}; - /* Forward/typedef for struct OpcDesc */ typedef struct OpcDesc OpcDesc; diff --git a/src/da65/output.c b/src/da65/output.c index 2f4514e19..a655b605f 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -133,11 +133,13 @@ void DefLabel (const char* Name) void OneDataByte (void) /* Output a .byte line with the current code byte */ { + unsigned char B = GetCodeByte (); + if (Pass > 1) { Indent (MIndent); Output (".byte"); Indent (AIndent); - Output ("$%02X", GetCodeByte()); + Output ("$%02X", B); LineFeed (); } } @@ -153,3 +155,4 @@ void SeparatorLine (void) + diff --git a/src/da65/scanner.c b/src/da65/scanner.c new file mode 100644 index 000000000..8a03b0c7f --- /dev/null +++ b/src/da65/scanner.c @@ -0,0 +1,528 @@ +/*****************************************************************************/ +/* */ +/* scanner.c */ +/* */ +/* Configuration file scanner for the da65 disassembler */ +/* */ +/* */ +/* */ +/* (C) 2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include +#include +#include +#include +#include + +/* common */ +#include "xsprintf.h" + +/* ld65 */ +#include "global.h" +#include "error.h" +#include "scanner.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Current token and attributes */ +unsigned CfgTok; +char CfgSVal [CFG_MAX_IDENT_LEN+1]; +unsigned long CfgIVal; + +/* Error location */ +unsigned CfgErrorLine; +unsigned CfgErrorCol; + +/* Input sources for the configuration */ +static const char* CfgFile = 0; +static const char* CfgBuf = 0; + +/* Other input stuff */ +static int C = ' '; +static unsigned InputLine = 1; +static unsigned InputCol = 0; +static FILE* InputFile = 0; + + + +/*****************************************************************************/ +/* Error handling */ +/*****************************************************************************/ + + + +void CfgWarning (const char* Format, ...) +/* Print a warning message adding file name and line number of the config file */ +{ + char Buf [512]; + va_list ap; + + va_start (ap, Format); + xvsprintf (Buf, sizeof (Buf), Format, ap); + va_end (ap); + + Warning ("%s(%u): %s", CfgFile, CfgErrorLine, Buf); +} + + + +void CfgError (const char* Format, ...) +/* Print an error message adding file name and line number of the config file */ +{ + char Buf [512]; + va_list ap; + + va_start (ap, Format); + xvsprintf (Buf, sizeof (Buf), Format, ap); + va_end (ap); + + Error ("%s(%u): %s", CfgFile, CfgErrorLine, Buf); +} + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static void NextChar (void) +/* Read the next character from the input file */ +{ + if (CfgBuf) { + /* Read from buffer */ + C = (unsigned char)(*CfgBuf); + if (C == 0) { + C = EOF; + } else { + ++CfgBuf; + } + } else { + /* Read from the file */ + C = getc (InputFile); + } + + /* Count columns */ + if (C != EOF) { + ++InputCol; + } + + /* Count lines */ + if (C == '\n') { + ++InputLine; + InputCol = 0; + } +} + + + +static unsigned DigitVal (int C) +/* Return the value for a numeric digit */ +{ + if (isdigit (C)) { + return C - '0'; + } else { + return toupper (C) - 'A' + 10; + } +} + + + +void CfgNextTok (void) +/* Read the next token from the input stream */ +{ + unsigned I; + + +Again: + /* Skip whitespace */ + while (isspace (C)) { + NextChar (); + } + + /* Remember the current position */ + CfgErrorLine = InputLine; + CfgErrorCol = InputCol; + + /* Identifier? */ + if (C == '_' || isalpha (C)) { + + /* Read the identifier */ + I = 0; + while (C == '_' || isalnum (C)) { + if (I < CFG_MAX_IDENT_LEN) { + CfgSVal [I++] = C; + } + NextChar (); + } + CfgSVal [I] = '\0'; + CfgTok = CFGTOK_IDENT; + return; + } + + /* Hex number? */ + if (C == '$') { + NextChar (); + if (!isxdigit (C)) { + CfgError ("Hex digit expected"); + } + CfgIVal = 0; + while (isxdigit (C)) { + CfgIVal = CfgIVal * 16 + DigitVal (C); + NextChar (); + } + CfgTok = CFGTOK_INTCON; + return; + } + + /* Decimal number? */ + if (isdigit (C)) { + CfgIVal = 0; + while (isdigit (C)) { + CfgIVal = CfgIVal * 10 + DigitVal (C); + NextChar (); + } + CfgTok = CFGTOK_INTCON; + return; + } + + /* Other characters */ + switch (C) { + + case '{': + NextChar (); + CfgTok = CFGTOK_LCURLY; + break; + + case '}': + NextChar (); + CfgTok = CFGTOK_RCURLY; + break; + + case ';': + NextChar (); + CfgTok = CFGTOK_SEMI; + break; + + case '.': + NextChar (); + CfgTok = CFGTOK_DOT; + break; + + case ',': + NextChar (); + CfgTok = CFGTOK_COMMA; + break; + + case '=': + NextChar (); + CfgTok = CFGTOK_EQ; + break; + + case ':': + NextChar (); + CfgTok = CFGTOK_COLON; + break; + + case '\"': + NextChar (); + I = 0; + while (C != '\"') { + if (C == EOF || C == '\n') { + CfgError ("Unterminated string"); + } + if (I < CFG_MAX_IDENT_LEN) { + CfgSVal [I++] = C; + } + NextChar (); + } + NextChar (); + CfgSVal [I] = '\0'; + CfgTok = CFGTOK_STRCON; + break; + + case '#': + /* Comment */ + while (C != '\n' && C != EOF) { + NextChar (); + } + if (C != EOF) { + goto Again; + } + CfgTok = CFGTOK_EOF; + break; + + case EOF: + CfgTok = CFGTOK_EOF; + break; + + default: + CfgError ("Invalid character `%c'", C); + + } +} + + + +void CfgConsume (unsigned T, const char* Msg) +/* Skip a token, print an error message if not found */ +{ + if (CfgTok != T) { + CfgError (Msg); + } + CfgNextTok (); +} + + + +void CfgConsumeLCurly (void) +/* Consume a left curly brace */ +{ + CfgConsume (CFGTOK_LCURLY, "`{' expected"); +} + + + +void CfgConsumeRCurly (void) +/* Consume a right curly brace */ +{ + CfgConsume (CFGTOK_RCURLY, "`}' expected"); +} + + + +void CfgConsumeSemi (void) +/* Consume a semicolon */ +{ + CfgConsume (CFGTOK_SEMI, "`;' expected"); +} + + + +void CfgConsumeColon (void) +/* Consume a colon */ +{ + CfgConsume (CFGTOK_COLON, "`:' expected"); +} + + + +void CfgOptionalComma (void) +/* Consume a comma if there is one */ +{ + if (CfgTok == CFGTOK_COMMA) { + CfgNextTok (); + } +} + + + +void CfgOptionalAssign (void) +/* Consume an equal sign if there is one */ +{ + if (CfgTok == CFGTOK_EQ) { + CfgNextTok (); + } +} + + + +void CfgAssureInt (void) +/* Make sure the next token is an integer */ +{ + if (CfgTok != CFGTOK_INTCON) { + CfgError ("Integer constant expected"); + } +} + + + +void CfgAssureStr (void) +/* Make sure the next token is a string constant */ +{ + if (CfgTok != CFGTOK_STRCON) { + CfgError ("String constant expected"); + } +} + + + +void CfgAssureIdent (void) +/* Make sure the next token is an identifier */ +{ + if (CfgTok != CFGTOK_IDENT) { + CfgError ("Identifier expected"); + } +} + + + +void CfgRangeCheck (unsigned long Lo, unsigned long Hi) +/* Check the range of CfgIVal */ +{ + if (CfgIVal < Lo || CfgIVal > Hi) { + CfgError ("Range error"); + } +} + + + +void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) +/* Map an identifier to one of the special tokens in the table */ +{ + unsigned I; + + /* We need an identifier */ + if (CfgTok == CFGTOK_IDENT) { + + /* Make it upper case */ + I = 0; + while (CfgSVal [I]) { + CfgSVal [I] = toupper (CfgSVal [I]); + ++I; + } + + /* Linear search */ + for (I = 0; I < Size; ++I) { + if (strcmp (CfgSVal, Table [I].Ident) == 0) { + CfgTok = Table [I].Tok; + return; + } + } + + } + + /* Not found or no identifier */ + CfgError ("%s expected", Name); +} + + + +void CfgBoolToken (void) +/* Map an identifier or integer to a boolean token */ +{ + static const IdentTok Booleans [] = { + { "YES", CFGTOK_TRUE }, + { "NO", CFGTOK_FALSE }, + { "TRUE", CFGTOK_TRUE }, + { "FALSE", CFGTOK_FALSE }, + }; + + /* If we have an identifier, map it to a boolean token */ + if (CfgTok == CFGTOK_IDENT) { + CfgSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean"); + } else { + /* We expected an integer here */ + if (CfgTok != CFGTOK_INTCON) { + CfgError ("Boolean value expected"); + } + CfgTok = (CfgIVal == 0)? CFGTOK_FALSE : CFGTOK_TRUE; + } +} + + + +void CfgSetName (const char* Name) +/* Set a name for a config file */ +{ + CfgFile = Name; +} + + + +const char* CfgGetName (void) +/* Get the name of the config file */ +{ + return CfgFile? CfgFile : ""; +} + + + +void CfgSetBuf (const char* Buf) +/* Set a memory buffer for the config */ +{ + CfgBuf = Buf; +} + + + +int CfgAvail (void) +/* Return true if we have a configuration available */ +{ + return CfgFile != 0 || CfgBuf != 0; +} + + + +void CfgOpenInput (void) +/* Open the input file if we have one */ +{ + /* If we have a config name given, open the file, otherwise we will read + * from a buffer. + */ + if (!CfgBuf) { + + /* Open the file */ + InputFile = fopen (CfgFile, "r"); + if (InputFile == 0) { + Error ("Cannot open `%s': %s", CfgFile, strerror (errno)); + } + + } + + /* Initialize variables */ + C = ' '; + InputLine = 1; + InputCol = 0; + + /* Start the ball rolling ... */ + CfgNextTok (); +} + + + +void CfgCloseInput (void) +/* Close the input file if we have one */ +{ + /* Close the input file if we had one */ + if (InputFile) { + (void) fclose (InputFile); + InputFile = 0; + } +} + + + + diff --git a/src/da65/scanner.h b/src/da65/scanner.h new file mode 100644 index 000000000..4b980db96 --- /dev/null +++ b/src/da65/scanner.h @@ -0,0 +1,186 @@ +/*****************************************************************************/ +/* */ +/* scanner.h */ +/* */ +/* Configuration file scanner for the da65 disassembler */ +/* */ +/* */ +/* */ +/* (C) 2000 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef SCANNER_H +#define SCANNER_H + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Config file tokens */ +typedef enum token_t { + CFGTOK_NONE, + CFGTOK_INTCON, + CFGTOK_STRCON, + CFGTOK_IDENT, + CFGTOK_LCURLY, + CFGTOK_RCURLY, + CFGTOK_SEMI, + CFGTOK_COMMA, + CFGTOK_EQ, + CFGTOK_COLON, + CFGTOK_DOT, + CFGTOK_EOF, + + /* Special tokens */ + CFGTOK_GLOBAL, + CFGTOK_RANGE, + CFGTOK_LABEL, + + /* Global section */ + CFGTOK_INPUTNAME, + CFGTOK_OUTPUTNAME, + CFGTOK_PAGELENGTH, + + /* Range section */ + CFGTOK_START, + CFGTOK_END, + CFGTOK_TYPE, + + /* Label section */ + + + /* */ + CFGTOK_TRUE, + CFGTOK_FALSE +} token_t; + + +/* Mapping table entry, special identifier --> token */ +typedef struct IdentTok_ IdentTok; +struct IdentTok_ { + const char* Ident; /* Identifier */ + token_t Tok; /* Token for identifier */ +}; +#define ENTRY_COUNT(s) (sizeof (s) / sizeof (s [0])) + + + +/* Current token and attributes */ +#define CFG_MAX_IDENT_LEN 255 +extern unsigned CfgTok; +extern char CfgSVal [CFG_MAX_IDENT_LEN+1]; +extern unsigned long CfgIVal; + +/* Error location */ +extern unsigned CfgErrorLine; +extern unsigned CfgErrorCol; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void CfgWarning (const char* Format, ...); +/* Print a warning message adding file name and line number of the config file */ + +void CfgError (const char* Format, ...); +/* Print an error message adding file name and line number of the config file */ + +void CfgNextTok (void); +/* Read the next token from the input stream */ + +void CfgConsume (unsigned T, const char* Msg); +/* Skip a token, print an error message if not found */ + +void CfgConsumeLCurly (void); +/* Consume a left curly brace */ + +void CfgConsumeRCurly (void); +/* Consume a right curly brace */ + +void CfgConsumeSemi (void); +/* Consume a semicolon */ + +void CfgConsumeColon (void); +/* Consume a colon */ + +void CfgOptionalComma (void); +/* Consume a comma if there is one */ + +void CfgOptionalAssign (void); +/* Consume an equal sign if there is one */ + +void CfgAssureInt (void); +/* Make sure the next token is an integer */ + +void CfgAssureStr (void); +/* Make sure the next token is a string constant */ + +void CfgAssureIdent (void); +/* Make sure the next token is an identifier */ + +void CfgRangeCheck (unsigned long Lo, unsigned long Hi); +/* Check the range of CfgIVal */ + +void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name); +/* Map an identifier to one of the special tokens in the table */ + +void CfgBoolToken (void); +/* Map an identifier or integer to a boolean token */ + +void CfgSetName (const char* Name); +/* Set a name for a config file */ + +const char* CfgGetName (void); +/* Get the name of the config file */ + +void CfgSetBuf (const char* Buf); +/* Set a memory buffer for the config */ + +int CfgAvail (void); +/* Return true if we have a configuration available */ + +void CfgOpenInput (void); +/* Open the input file if we have one */ + +void CfgCloseInput (void); +/* Close the input file if we have one */ + + + +/* End of scanner.h */ +#endif + + +