mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-04-02 13:32:49 +00:00
added "!outfilestart" and "!outfilelimit". made "--from-to" to use end+1 instead of end.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@335 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
f52430f620
commit
444c7e858f
17
src/acme.c
17
src/acme.c
@ -130,7 +130,7 @@ static void show_help_and_exit(void)
|
||||
" --" OPTION_LABELDUMP " (old name for --" OPTION_SYMBOLLIST ")\n"
|
||||
" --" OPTION_VICELABELS " FILE set file name for label dump in VICE format\n"
|
||||
" --" OPTION_SETPC " VALUE set program counter\n"
|
||||
" --" OPTION_FROM_TO " VALUE VALUE set start and end of output file\n"
|
||||
" --" OPTION_FROM_TO " VALUE VALUE set start and end+1 of output file\n"
|
||||
" --" OPTION_CPU " CPU set target processor\n"
|
||||
" --" OPTION_INITMEM " VALUE define 'empty' memory\n"
|
||||
" --" OPTION_MAXERRORS " NUMBER set number of errors before exiting\n"
|
||||
@ -533,7 +533,7 @@ static const char *long_option(const char *string)
|
||||
config.initial_pc = string_to_nonneg_number(cliargs_safe_get_next("program counter"));
|
||||
else if (strcmp(string, OPTION_FROM_TO) == 0) {
|
||||
config.outfile_start = string_to_nonneg_number(cliargs_safe_get_next("start address of output file"));
|
||||
config.outfile_end = string_to_nonneg_number(cliargs_safe_get_next("end address of output file"));
|
||||
config.outfile_limit = string_to_nonneg_number(cliargs_safe_get_next("end+1 of output file"));
|
||||
} else if (strcmp(string, OPTION_CPU) == 0)
|
||||
set_starting_cpu(cliargs_get_next()); // NULL is ok (handled like unknown)
|
||||
else if (strcmp(string, OPTION_INITMEM) == 0)
|
||||
@ -553,7 +553,7 @@ static const char *long_option(const char *string)
|
||||
else if (strcmp(string, OPTION_IGNORE_ZEROES) == 0)
|
||||
config.honor_leading_zeroes = FALSE;
|
||||
else if (strcmp(string, OPTION_STRICT_SEGMENTS) == 0)
|
||||
config.segment_warning_is_error = TRUE;
|
||||
config.debuglevel_segmentprobs = DEBUGLEVEL_ERROR;
|
||||
else if (strcmp(string, OPTION_STRICT) == 0)
|
||||
config.all_warnings_are_errors = TRUE;
|
||||
else if (strcmp(string, OPTION_DIALECT) == 0)
|
||||
@ -668,12 +668,15 @@ int main(int argc, const char *argv[])
|
||||
fprintf(stderr, "%sStart address of output file exceeds outbuffer size.\n", cliargs_error);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((config.outfile_end != NO_VALUE_GIVEN) && (config.outfile_end >= config.outbuf_size)) {
|
||||
fprintf(stderr, "%sEnd address of output file exceeds outbuffer size.\n", cliargs_error);
|
||||
// "limit" is end+1 and therefore we need ">" instead of ">=":
|
||||
if ((config.outfile_limit != NO_VALUE_GIVEN) && (config.outfile_limit > config.outbuf_size)) {
|
||||
fprintf(stderr, "%sEnd+1 of output file exceeds outbuffer size.\n", cliargs_error);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (config.outfile_start > config.outfile_end) {
|
||||
fprintf(stderr, "%sStart address of output file exceeds end address.\n", cliargs_error);
|
||||
if ((config.outfile_start != NO_VALUE_GIVEN)
|
||||
&& (config.outfile_limit != NO_VALUE_GIVEN)
|
||||
&& (config.outfile_start >= config.outfile_limit)) {
|
||||
fprintf(stderr, "%sStart address of output file exceeds end+1.\n", cliargs_error);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ void config_default(struct config *conf)
|
||||
conf->format_color = FALSE; // enabled by --color
|
||||
conf->msg_stream = stderr; // set to stdout by --use-stdout
|
||||
conf->honor_leading_zeroes = TRUE; // disabled by --ignore-zeroes
|
||||
conf->segment_warning_is_error = FALSE; // enabled by --strict-segments TODO - toggle default?
|
||||
conf->debuglevel_segmentprobs = DEBUGLEVEL_WARNING; // changed to ERROR by --strict-segments TODO - toggle default?
|
||||
conf->all_warnings_are_errors = FALSE; // enabled by --strict
|
||||
conf->test_new_features = FALSE; // enabled by --test
|
||||
conf->wanted_version = VER_CURRENT; // changed by --dialect
|
||||
@ -126,7 +126,7 @@ void config_default(struct config *conf)
|
||||
conf->mem_init_value = MEMINIT_USE_DEFAULT; // set by --initmem
|
||||
conf->initial_pc = NO_VALUE_GIVEN; // set by --setpc
|
||||
conf->outfile_start = NO_VALUE_GIVEN; // set by --from-to
|
||||
conf->outfile_end = NO_VALUE_GIVEN; // set by --from-to
|
||||
conf->outfile_limit = NO_VALUE_GIVEN; // end+1, set by --from-to
|
||||
}
|
||||
|
||||
// memory allocation stuff
|
||||
|
22
src/global.h
22
src/global.h
@ -60,6 +60,15 @@ enum version {
|
||||
// ignore leading zeroes?
|
||||
VER_FUTURE // far future
|
||||
};
|
||||
enum debuglevel {
|
||||
DEBUGLEVEL_SERIOUS = -3, // ACME stops right away
|
||||
DEBUGLEVEL_ERROR = -2, // something is wrong
|
||||
DEBUGLEVEL_WARNING = -1, // something looks wrong
|
||||
DEBUGLEVEL_INFO = 0, // info msg ("173 bytes left in code area!")
|
||||
DEBUGLEVEL_DEBUG = 1 // debug msg
|
||||
// debug messages with higher levels are suppressed,
|
||||
// can be changed using "--debuglevel" cli switch.
|
||||
};
|
||||
// configuration
|
||||
struct config {
|
||||
char pseudoop_prefix; // '!' or '.'
|
||||
@ -72,7 +81,7 @@ struct config {
|
||||
boolean format_color; // enabled by --color
|
||||
FILE *msg_stream; // defaults to stderr, changed to stdout by --use-stdout
|
||||
boolean honor_leading_zeroes; // TRUE, disabled by --ignore-zeroes
|
||||
boolean segment_warning_is_error; // FALSE, enabled by --strict-segments
|
||||
enum debuglevel debuglevel_segmentprobs; // WARNING, changed to ERROR by --strict-segments
|
||||
boolean all_warnings_are_errors; // FALSE, enabled by --strict
|
||||
boolean test_new_features; // FALSE, enabled by --test
|
||||
enum version wanted_version; // set by --dialect (and --test --test)
|
||||
@ -83,7 +92,7 @@ struct config {
|
||||
#define NO_VALUE_GIVEN (-1) // default value for these fields if cli switch not used:
|
||||
signed long initial_pc; // set by --setpc
|
||||
signed long outfile_start; // set by --from-to
|
||||
signed long outfile_end; // set by --from-to
|
||||
signed long outfile_limit; // end+1, set by --from-to
|
||||
};
|
||||
extern struct config config;
|
||||
|
||||
@ -163,15 +172,6 @@ extern void parse_until_eob_or_eof(void);
|
||||
// Don't forget to call EnsureEOL() afterwards.
|
||||
extern int parse_optional_block(void);
|
||||
|
||||
enum debuglevel {
|
||||
DEBUGLEVEL_SERIOUS = -3, // ACME stops right away
|
||||
DEBUGLEVEL_ERROR = -2, // something is wrong
|
||||
DEBUGLEVEL_WARNING = -1, // something looks wrong
|
||||
DEBUGLEVEL_INFO = 0, // info msg ("173 bytes left in code area!")
|
||||
DEBUGLEVEL_DEBUG = 1 // debug msg
|
||||
// debug messages with higher levels are suppressed,
|
||||
// can be changed using "--debuglevel" cli switch.
|
||||
};
|
||||
// generate a debug/info/warning/error message
|
||||
void throw_message(enum debuglevel level, const char msg[]);
|
||||
|
||||
|
63
src/output.c
63
src/output.c
@ -42,7 +42,7 @@ struct output {
|
||||
intval_t write_idx; // index of next write
|
||||
intval_t lowest_written; // smallest address used
|
||||
intval_t highest_written; // largest address used
|
||||
boolean initvalue_set;
|
||||
boolean initvalue_set; // default byte value for buffer has been set
|
||||
struct {
|
||||
intval_t start; // start of current segment (or NO_SEGMENT_START)
|
||||
intval_t max; // highest address segment may use
|
||||
@ -123,11 +123,7 @@ static void border_crossed(int current_offset)
|
||||
Throw_serious_error("Produced too much code.");
|
||||
// TODO - get rid of FIRST_PASS condition, because user can suppress these warnings if they want
|
||||
if (FIRST_PASS) {
|
||||
// TODO: make warn/err an arg for a general "Throw" function
|
||||
if (config.segment_warning_is_error)
|
||||
Throw_error("Segment reached another one, overwriting it.");
|
||||
else
|
||||
Throw_warning("Segment reached another one, overwriting it.");
|
||||
throw_message(config.debuglevel_segmentprobs, "Segment reached another one, overwriting it.");
|
||||
find_segment_max(current_offset + 1); // find new (next) limit
|
||||
}
|
||||
}
|
||||
@ -233,6 +229,32 @@ int output_setdefault(char content)
|
||||
return 0; // ok
|
||||
}
|
||||
|
||||
// remember current outbuf index as start/limit of output file
|
||||
static boolean force_file_start = FALSE;
|
||||
static intval_t forced_start_idx;
|
||||
void outbuf_set_outfile_start(void)
|
||||
{
|
||||
// check whether ptr undefined
|
||||
if (output_byte == no_output) {
|
||||
Throw_error(exception_pc_undefined);
|
||||
} else {
|
||||
force_file_start = TRUE;
|
||||
forced_start_idx = out->write_idx;
|
||||
}
|
||||
}
|
||||
static boolean force_file_limit = FALSE;
|
||||
static intval_t forced_limit_idx;
|
||||
void outbuf_set_outfile_limit(void)
|
||||
{
|
||||
// check whether ptr undefined
|
||||
if (output_byte == no_output) {
|
||||
Throw_error(exception_pc_undefined);
|
||||
} else {
|
||||
force_file_limit = TRUE;
|
||||
forced_limit_idx = out->write_idx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// try to set output format held in DynaBuf. Returns zero on success.
|
||||
int outputfile_set_format(void)
|
||||
@ -298,29 +320,35 @@ void output_createbuffer(void)
|
||||
void output_save_file(FILE *fd)
|
||||
{
|
||||
intval_t start,
|
||||
end,
|
||||
limit, // end+1
|
||||
amount;
|
||||
|
||||
start = out->lowest_written;
|
||||
end = out->highest_written;
|
||||
// if cli args were given, they override the actual values:
|
||||
limit = out->highest_written + 1;
|
||||
// if pseudo opcodes were used, they override the actual values:
|
||||
if (force_file_start)
|
||||
start = forced_start_idx;
|
||||
if (force_file_limit)
|
||||
limit = forced_limit_idx;
|
||||
// if cli args were given, they override even harder:
|
||||
if (config.outfile_start != NO_VALUE_GIVEN)
|
||||
start = config.outfile_start;
|
||||
if (config.outfile_end != NO_VALUE_GIVEN)
|
||||
end = config.outfile_end;
|
||||
if (config.outfile_limit != NO_VALUE_GIVEN)
|
||||
limit = config.outfile_limit;
|
||||
|
||||
if (end < start) {
|
||||
if (limit <= start) {
|
||||
// nothing written
|
||||
start = 0; // I could try to use some segment start, but what for?
|
||||
amount = 0;
|
||||
// FIXME - how about not writing anything in this case?
|
||||
// a CBM file would consist of a bogus load address and nothing else!
|
||||
} else {
|
||||
amount = end - start + 1;
|
||||
amount = limit - start;
|
||||
}
|
||||
if (config.process_verbosity)
|
||||
printf("Saving %ld (0x%lx) bytes (0x%lx - 0x%lx exclusive).\n",
|
||||
if (config.process_verbosity) {
|
||||
printf("Saving %ld (0x%04lx) bytes (0x%04lx - 0x%04lx exclusive).\n",
|
||||
amount, amount, start, start + amount);
|
||||
}
|
||||
// output file header according to file format
|
||||
// FIXME - add checks and error messages for "start is above $ffff"!)
|
||||
switch (output_format) {
|
||||
@ -386,10 +414,7 @@ static void check_segment(intval_t new_pc)
|
||||
while (test_segment->start <= new_pc) {
|
||||
if ((test_segment->start + test_segment->length) > new_pc) {
|
||||
// TODO - include overlap size in error message!
|
||||
if (config.segment_warning_is_error)
|
||||
Throw_error("Segment starts inside another one, overwriting it.");
|
||||
else
|
||||
Throw_warning("Segment starts inside another one, overwriting it.");
|
||||
throw_message(config.debuglevel_segmentprobs, "Segment starts inside another one, overwriting it.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,6 @@ extern struct vcpu CPU_state; // current CPU state FIXME - restrict visibility t
|
||||
// Prototypes
|
||||
|
||||
// clear segment list and disable output
|
||||
//TODO - does this belong to outbuf stuff?
|
||||
extern void output_passinit(void);
|
||||
|
||||
|
||||
@ -58,6 +57,9 @@ extern void (*output_byte)(intval_t);
|
||||
// returns zero if ok, nonzero if already set
|
||||
extern int output_setdefault(char content);
|
||||
|
||||
// remember current outbuf index as start/limit of output file
|
||||
extern void outbuf_set_outfile_start(void);
|
||||
extern void outbuf_set_outfile_limit(void);
|
||||
|
||||
// outfile stuff:
|
||||
|
||||
|
@ -1372,6 +1372,35 @@ static enum eos po_serious(void)
|
||||
return throw_src_string(DEBUGLEVEL_SERIOUS, "!serious: ");
|
||||
}
|
||||
|
||||
// use current outbuf index as "first byte of output file"
|
||||
static enum eos po_outfilestart(void)
|
||||
{
|
||||
static int last_pass_number = -1;
|
||||
|
||||
if ((config.outfile_start != NO_VALUE_GIVEN)
|
||||
|| (last_pass_number == pass.number)) {
|
||||
Throw_first_pass_warning("Start of output file already chosen.");
|
||||
} else {
|
||||
last_pass_number = pass.number;
|
||||
outbuf_set_outfile_start();
|
||||
}
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
// use current outbuf index as "end+1 of output file"
|
||||
static enum eos po_outfilelimit(void)
|
||||
{
|
||||
static int last_pass_number = -1;
|
||||
|
||||
if ((config.outfile_limit != NO_VALUE_GIVEN)
|
||||
|| (last_pass_number == pass.number)) {
|
||||
Throw_first_pass_warning("End of output file already chosen.");
|
||||
} else {
|
||||
last_pass_number = pass.number;
|
||||
outbuf_set_outfile_limit();
|
||||
}
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
|
||||
|
||||
// end of source file ("!endoffile" or "!eof")
|
||||
static enum eos po_endoffile(void)
|
||||
@ -1455,8 +1484,8 @@ static struct ronode pseudo_opcode_tree[] = {
|
||||
PREDEFNODE("warn", po_warn),
|
||||
PREDEFNODE("error", po_error),
|
||||
PREDEFNODE("serious", po_serious),
|
||||
// PREDEFNODE("filestart", po_),
|
||||
// PREDEFNODE("filestop", po_),
|
||||
PREDEFNODE("outfilestart", po_outfilestart),
|
||||
PREDEFNODE("outfilelimit", po_outfilelimit),
|
||||
PREDEFNODE("eof", po_endoffile),
|
||||
PREDEF_END("endoffile", po_endoffile),
|
||||
// ^^^^ this marks the last element
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#define RELEASE "0.97" // update before release FIXME
|
||||
#define CODENAME "Zem" // update before release
|
||||
#define CHANGE_DATE "11 Feb" // update before release FIXME
|
||||
#define CHANGE_DATE "12 Feb" // update before release FIXME
|
||||
#define CHANGE_YEAR "2024" // update before release
|
||||
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
|
||||
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
|
||||
|
Loading…
x
Reference in New Issue
Block a user