2016-12-28 20:32:00 +00:00
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
2020-04-14 00:28:31 +00:00
// Copyright (C) 1998-2020 Marco Baye
2012-02-27 21:14:46 +00:00
// Have a look at "acme.c" for further info
//
// Global stuff - things that are needed by several modules
2014-11-22 01:36:02 +00:00
// 19 Nov 2014 Merged Johann Klasek's report listing generator patch
2014-11-23 23:40:01 +00:00
// 23 Nov 2014 Merged Martin Piper's "--msvc" error output patch
2012-02-27 21:14:46 +00:00
# ifndef global_H
# define global_H
# include <stdio.h>
# include <stdlib.h>
2014-11-22 01:36:02 +00:00
# include <string.h>
2012-02-27 21:14:46 +00:00
# include "config.h"
2013-06-26 23:01:00 +00:00
# define LOCAL_PREFIX '.' // FIXME - this is not yet used consistently!
2017-10-29 23:29:07 +00:00
# define CHEAP_PREFIX '@' // prefix character for cheap locals
2012-02-27 21:14:46 +00:00
// Constants
# define SF_FOUND_BLANK (1u << 0) // statement had space or tab
# define SF_IMPLIED_LABEL (1u << 1) // statement had implied label def
extern const char s_and [ ] ;
extern const char s_asl [ ] ;
extern const char s_asr [ ] ;
2014-11-23 23:40:01 +00:00
extern const char s_bra [ ] ;
2012-02-27 21:14:46 +00:00
extern const char s_brl [ ] ;
extern const char s_cbm [ ] ;
extern const char s_eor [ ] ;
extern const char s_error [ ] ;
extern const char s_lsr [ ] ;
extern const char s_scrxor [ ] ;
2014-12-04 11:26:42 +00:00
extern char s_untitled [ ] ;
extern const char s_Zone [ ] ;
# define s_zone (s_subzone + 3) // Yes, I know I'm sick
extern const char s_subzone [ ] ;
2014-12-16 08:21:44 +00:00
extern const char s_pet [ ] ;
extern const char s_raw [ ] ;
extern const char s_scr [ ] ;
2014-12-04 11:26:42 +00:00
// error messages during assembly
2012-02-27 21:14:46 +00:00
extern const char exception_cannot_open_input_file [ ] ;
extern const char exception_missing_string [ ] ;
2017-10-21 19:59:56 +00:00
extern const char exception_negative_size [ ] ;
2012-02-27 21:14:46 +00:00
extern const char exception_no_left_brace [ ] ;
extern const char exception_no_memory_left [ ] ;
extern const char exception_no_right_brace [ ] ;
//extern const char exception_not_yet[];
extern const char exception_number_out_of_range [ ] ;
extern const char exception_pc_undefined [ ] ;
extern const char exception_syntax [ ] ;
2020-05-02 21:59:20 +00:00
extern const char exception_value_not_defined [ ] ;
2014-12-04 11:26:42 +00:00
// byte flags table
2020-04-28 11:18:22 +00:00
extern const char global_byte_flags [ ] ;
# define BYTE_STARTS_KEYWORD(b) (global_byte_flags[(unsigned char) b] & (1u << 7)) // byte is allowed at start of keyword (a-z, A-Z, _, everything>127)
# define BYTE_CONTINUES_KEYWORD(b) (global_byte_flags[(unsigned char) b] & (1u << 6)) // byte is allowed in a keyword (as above, plus digits)
//#define BYTE_TO_LOWER_CASE(b) bit 5 means: "byte is upper case, and can be converted to lower case by ORing this bit" - but this is not used at the moment!
# define BYTE_IS_SYNTAX_CHAR(b) (global_byte_flags[(unsigned char) b] & (1u << 4)) // special character for input syntax
# define BYTE_FOLLOWS_ANON(b) (global_byte_flags[(unsigned char) b] & (1u << 3)) // preceding '-' are backward label
2014-06-02 00:47:46 +00:00
// bits 2, 1 and 0 are currently unused
2012-02-27 21:14:46 +00:00
2017-10-29 23:29:07 +00:00
// TODO - put in runtime struct:
2012-02-27 21:14:46 +00:00
extern char GotByte ; // Last byte read (processed)
2017-10-29 23:29:07 +00:00
// configuration
struct config {
char pseudoop_prefix ; // '!' or '.'
int process_verbosity ; // level of additional output
2020-05-01 21:01:23 +00:00
boolean warn_on_indented_labels ; // warn if indented label is encountered
boolean warn_on_type_mismatch ; // use type-checking system
2017-10-29 23:29:07 +00:00
signed long max_errors ; // errors before giving up
2020-05-01 21:01:23 +00:00
boolean format_msvc ; // enabled by --msvc
boolean format_color ; // enabled by --color
2020-04-14 00:28:31 +00:00
FILE * msg_stream ; // defaults to stderr, changed to stdout by --use-stdout
2020-05-01 21:01:23 +00:00
boolean honor_leading_zeroes ; // TRUE, disabled by --ignore-zeroes
boolean segment_warning_is_error ; // FALSE, enabled by --strict-segments
boolean test_new_features ; // FALSE, enabled by --test
2020-05-27 17:32:48 +00:00
int wanted_version ;
# define VER_0_93 9300 // v0.93
# define VER_RIGHTASSOCIATIVEPOWEROF 9406 // v0.94.6 made "power of" operator right-associative
# define VER_NEWFORSYNTAX 9412 // v0.94.12 introduced the new "!for" syntax
# define VER_BACKSLASHESCAPING 10000 // not yet: backslash escaping
# define VER_FUTURE 32767
2017-10-29 23:29:07 +00:00
} ;
extern struct config config ;
2012-02-27 21:14:46 +00:00
2020-05-02 10:40:10 +00:00
struct pass {
int number ; // counts up from zero
int undefined_count ; // counts undefined expression results (if this stops decreasing, next pass must list them as errors)
//int needvalue_count; // counts undefined expression results actually needed for output (when this hits zero, we're done) FIXME - use
int error_count ;
2020-05-02 14:58:17 +00:00
boolean complain_about_undefined ; // will be FALSE until error pass is needed
2020-05-02 10:40:10 +00:00
} ;
extern struct pass pass ;
# define FIRST_PASS (pass.number == 0)
2014-11-22 01:36:02 +00:00
// report stuff
# define REPORT_ASCBUFSIZE 1024
# define REPORT_BINBUFSIZE 9 // eight are shown, then "..."
struct report {
FILE * fd ; // report file descriptor (NULL => no report)
struct input * last_input ;
size_t asc_used ;
size_t bin_used ;
int bin_address ; // address at start of bin_buf[]
char asc_buf [ REPORT_ASCBUFSIZE ] ; // source bytes
char bin_buf [ REPORT_BINBUFSIZE ] ; // output bytes
} ;
2017-10-16 17:01:44 +00:00
extern struct report * report ; // TODO - put in "part" struct
2014-11-22 01:36:02 +00:00
2012-02-27 21:14:46 +00:00
// Macros for skipping a single space character
# define SKIPSPACE() \
do { \
if ( GotByte = = ' ' ) \
GetByte ( ) ; \
} while ( 0 )
# define NEXTANDSKIPSPACE() \
do { \
if ( GetByte ( ) = = ' ' ) \
GetByte ( ) ; \
} while ( 0 )
// Prototypes
2017-10-29 23:29:07 +00:00
// set configuration to default values
extern void config_default ( struct config * conf ) ;
2014-12-04 11:26:42 +00:00
// allocate memory and die if not available
2012-02-27 21:14:46 +00:00
extern void * safe_malloc ( size_t ) ;
// Parse block, beginning with next byte.
// End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards
// Has to be re-entrant.
extern void Parse_until_eob_or_eof ( void ) ;
// Skip space. If GotByte is CHAR_SOB ('{'), parse block and return TRUE.
// Otherwise (if there is no block), return FALSE.
// Don't forget to call EnsureEOL() afterwards.
extern int Parse_optional_block ( void ) ;
2016-10-08 12:19:12 +00:00
// error/warning counter so macro calls can find out whether to show a call stack
extern int Throw_get_counter ( void ) ;
2012-02-27 21:14:46 +00:00
// Output a warning.
// This means the produced code looks as expected. But there has been a
// situation that should be reported to the user, for example ACME may have
// assembled a 16-bit parameter with an 8-bit value.
extern void Throw_warning ( const char * ) ;
// Output a warning if in first pass. See above.
extern void Throw_first_pass_warning ( const char * ) ;
// Output an error.
// This means something went wrong in a way that implies that the output
// almost for sure won't look like expected, for example when there was a
// syntax error. The assembler will try to go on with the assembly though, so
// the user gets to know about more than one of his typos at a time.
extern void Throw_error ( const char * ) ;
// Output a serious error, stopping assembly.
// Serious errors are those that make it impossible to go on with the
// assembly. Example: "!fill" without a parameter - the program counter cannot
// be set correctly in this case, so proceeding would be of no use at all.
extern void Throw_serious_error ( const char * ) ;
2014-12-04 11:26:42 +00:00
// handle bugs
2012-02-27 21:14:46 +00:00
extern void Bug_found ( const char * , int ) ;
# endif