mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-11-21 11:32:23 +00:00
added another test file and did a bit of cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@371 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
5a504b4ff3
commit
15aa8b3a3c
@ -542,14 +542,14 @@ void throw_redef_error(struct location *old_def, const char msg[])
|
||||
|
||||
// process error that might vanish if symbols change:
|
||||
// if current pass is an "error output" pass, actually throw error.
|
||||
// otherwise just set a flag to let mainloop know this pass wasn't successful.
|
||||
// otherwise just increment counter to let mainloop know this pass wasn't successful.
|
||||
void throw_symbol_error(const char *msg)
|
||||
{
|
||||
// atm we just mimic the old behaviour. in future, do something like this:
|
||||
//if (pass.is_error_pass)
|
||||
Throw_error(msg);
|
||||
//else
|
||||
//pass.has_symbol_errors = TRUE;
|
||||
//++pass.symbol_errors;
|
||||
}
|
||||
|
||||
|
||||
|
@ -211,7 +211,7 @@ extern void throw_redef_error(struct location *old_def, const char msg[]);
|
||||
|
||||
// process error that might vanish if symbols change:
|
||||
// if current pass is an "error output" pass, actually throw error.
|
||||
// otherwise just set a flag to let mainloop know this pass wasn't successful.
|
||||
// otherwise just increment counter to let mainloop know this pass wasn't successful.
|
||||
extern void throw_symbol_error(const char *msg);
|
||||
|
||||
// output a serious error (assembly stops, for example if outbuffer overruns).
|
||||
|
33
src/mnemo.c
33
src/mnemo.c
@ -650,23 +650,20 @@ static bits get_addr_mode(struct number *result)
|
||||
|
||||
// Helper function for calc_arg_size()
|
||||
// Only call with "size_bit = NUMBER_FORCES_16" or "size_bit = NUMBER_FORCES_24"
|
||||
static bits check_oversize(bits size_bit, struct number *argument)
|
||||
static void check_oversize(bits size_bit, struct number *argument)
|
||||
{
|
||||
// only check if value is *defined*
|
||||
if (argument->ntype == NUMTYPE_UNDEFINED)
|
||||
return size_bit; // pass on result
|
||||
|
||||
// value is defined, so check
|
||||
if (size_bit == NUMBER_FORCES_16) {
|
||||
// check 16-bit argument for high byte zero
|
||||
if ((argument->val.intval <= 255) && (argument->val.intval >= -128))
|
||||
Throw_warning(exception_oversized_addrmode);
|
||||
} else {
|
||||
// check 24-bit argument for bank byte zero
|
||||
if ((argument->val.intval <= 65535) && (argument->val.intval >= -32768))
|
||||
Throw_warning(exception_oversized_addrmode);
|
||||
if (argument->ntype != NUMTYPE_UNDEFINED) {
|
||||
// value is defined, so check
|
||||
if (size_bit == NUMBER_FORCES_16) {
|
||||
// check 16-bit argument for high byte zero
|
||||
if ((argument->val.intval <= 255) && (argument->val.intval >= -128))
|
||||
Throw_warning(exception_oversized_addrmode);
|
||||
} else {
|
||||
// check 24-bit argument for bank byte zero
|
||||
if ((argument->val.intval <= 65535) && (argument->val.intval >= -32768))
|
||||
Throw_warning(exception_oversized_addrmode);
|
||||
}
|
||||
}
|
||||
return size_bit; // pass on result
|
||||
}
|
||||
|
||||
// Utility function for comparing force bits, argument value, argument size,
|
||||
@ -733,13 +730,15 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
|
||||
// if there is a 16-bit addressing, use that
|
||||
// call helper function for "oversized addr mode" warning
|
||||
if (NUMBER_FORCES_16 & addressing_modes) {
|
||||
return check_oversize(NUMBER_FORCES_16, argument);
|
||||
check_oversize(NUMBER_FORCES_16, argument);
|
||||
return NUMBER_FORCES_16;
|
||||
}
|
||||
|
||||
// if there is a 24-bit addressing, use that
|
||||
// call helper function for "oversized addr mode" warning
|
||||
if (NUMBER_FORCES_24 & addressing_modes) {
|
||||
return check_oversize(NUMBER_FORCES_24, argument);
|
||||
check_oversize(NUMBER_FORCES_24, argument);
|
||||
return NUMBER_FORCES_24;
|
||||
}
|
||||
|
||||
// otherwise, use 8-bit-addressing, which will raise an
|
||||
|
31
src/output.c
31
src/output.c
@ -33,7 +33,6 @@ 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; // 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
|
||||
@ -184,28 +183,20 @@ static void fill_completely(char value)
|
||||
}
|
||||
|
||||
|
||||
// define default value for empty memory ("!initmem" pseudo opcode)
|
||||
// returns zero if ok, nonzero if already set
|
||||
int output_setdefault(char content)
|
||||
// default value for empty memory has changed (called by "!initmem" pseudo opcode)
|
||||
void output_newdefault(void)
|
||||
{
|
||||
// if MemInit flag is already set, complain
|
||||
if (out->initvalue_set) {
|
||||
Throw_warning("Memory already initialised.");
|
||||
return 1; // failed
|
||||
}
|
||||
// set MemInit flag
|
||||
out->initvalue_set = TRUE;
|
||||
// init memory
|
||||
fill_completely(content);
|
||||
fill_completely(config.mem_init_value);
|
||||
// enforce another pass
|
||||
if (pass.undefined_count == 0)
|
||||
pass.undefined_count = 1;
|
||||
//if (pass.needvalue_count == 0) FIXME - use? instead or additionally?
|
||||
// pass.needvalue_count = 1;
|
||||
// FIXME - enforcing another pass is not needed if there hasn't been any
|
||||
// enforcing another pass is not needed if there hasn't been any
|
||||
// output yet. But that's tricky to detect without too much overhead.
|
||||
// The old solution was to add &&(out->lowest_written < out->highest_written+1) to "if" above
|
||||
return 0; // ok
|
||||
// in future, just allocate and init outbuf at the start of the "last" pass!
|
||||
}
|
||||
|
||||
// remember current outbuf index as start/limit of output file
|
||||
@ -238,18 +229,14 @@ void outbuf_set_outfile_limit(void)
|
||||
// init output struct
|
||||
void output_createbuffer(void)
|
||||
{
|
||||
char fill_value = 0; // default value for output buffer
|
||||
|
||||
out->buffer = safe_malloc(config.outbuf_size);
|
||||
// FIXME - in future, do both of these only at start of "last" pass:
|
||||
// fill memory with initial value
|
||||
if (config.mem_init_value == NO_VALUE_GIVEN) {
|
||||
out->initvalue_set = FALSE; // "!initmem" can be used
|
||||
fill_completely(0); // default value
|
||||
} else {
|
||||
out->initvalue_set = TRUE; // "!initmem" generates a warning
|
||||
fill_value = 0xff & config.mem_init_value;
|
||||
fill_completely(config.mem_init_value & 0xff);
|
||||
}
|
||||
// FIXME - move both of these to passinit(), needed in future:
|
||||
// init output buffer (fill memory with initial value)
|
||||
fill_completely(fill_value);
|
||||
// init ring list of segments
|
||||
out->segment.list_head.next = &out->segment.list_head;
|
||||
out->segment.list_head.prev = &out->segment.list_head;
|
||||
|
@ -34,9 +34,8 @@ extern void output_skip(int size);
|
||||
// FIXME - replace by output_sequence(char *src, size_t size)
|
||||
extern void (*output_byte)(intval_t);
|
||||
|
||||
// define default value for empty memory ("!initmem" pseudo opcode)
|
||||
// returns zero if ok, nonzero if already set
|
||||
extern int output_setdefault(char content);
|
||||
// default value for empty memory has changed (called by "!initmem" pseudo opcode)
|
||||
extern void output_newdefault(void);
|
||||
|
||||
// remember current outbuf index as start/limit of output file
|
||||
extern void outbuf_set_outfile_start(void);
|
||||
|
@ -55,15 +55,25 @@ static enum eos po_initmem(void)
|
||||
if (pass.number != 1)
|
||||
return SKIP_REMAINDER;
|
||||
|
||||
// get value
|
||||
// the "--initmem" cli arg and earlier calls have priority
|
||||
if (config.mem_init_value != NO_VALUE_GIVEN) {
|
||||
Throw_warning("Memory already initialised.");
|
||||
return SKIP_REMAINDER;
|
||||
}
|
||||
|
||||
// read value
|
||||
// (allowing undefined values in future versions does not make sense,
|
||||
// because all "configuration pseudo opcodes" should be skipped after
|
||||
// first pass)
|
||||
ALU_defined_int(&intresult);
|
||||
if ((intresult.val.intval > 255) || (intresult.val.intval < -128))
|
||||
Throw_error(exception_number_out_of_8b_range);
|
||||
// TODO - move "Memory already initialised." logic from output.c
|
||||
// to this place.
|
||||
// TODO - increment pass.changed_count to enforce another pass.
|
||||
if (output_setdefault(intresult.val.intval & 0xff))
|
||||
return SKIP_REMAINDER;
|
||||
|
||||
// remember value
|
||||
config.mem_init_value = intresult.val.intval & 0xff;
|
||||
|
||||
// fill outbuffer and enforce another pass
|
||||
output_newdefault(); // FIXME - remove when outbuffer gets initialized only right before "last" pass!
|
||||
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#define RELEASE "0.97" // update before release FIXME
|
||||
#define CODENAME "Zem" // update before release
|
||||
#define CHANGE_DATE "13 Mar" // update before release FIXME
|
||||
#define CHANGE_DATE "14 Mar" // 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
|
||||
|
3
testing/errors/macroparamtwice1.a
Normal file
3
testing/errors/macroparamtwice1.a
Normal file
@ -0,0 +1,3 @@
|
||||
!macro dummy ~@x, ~@x {
|
||||
}
|
||||
+dummy ~y, ~z ; -> "Macro parameter twice."
|
Loading…
Reference in New Issue
Block a user