1
0
mirror of https://github.com/uffejakobsen/acme.git synced 2025-04-14 14:37:10 +00:00

Release 0.95.2: Changed "save labels" to "symbol list" in a lot of code, error messages and docs.

Added "!symbollist" alias for "!sl" pseudo opcode.
Change in undocumented ("illegal") opcodes: ANC  now generates 0x0b instead of 0x2b (both opcodes do the same thing).
Added experimental support for generating a report listing. Thanks to Johann Klasek for writing this extension patch.


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@40 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2014-11-22 01:36:02 +00:00
parent 2a30237ac4
commit af1bd69455
23 changed files with 269 additions and 96 deletions

@ -3,6 +3,7 @@
# new in version 4: added !warn, !error, !serious
# new in version 5: changed mnemo colors
# new in version 6: added !ifndef, !addr
# new in version 7: added !symbollist
# define colors
#
@ -133,6 +134,7 @@
"!zn" pseudo
"!zone" pseudo
"!sl" pseudo
"!symbollist" pseudo
"!src" pseudo
"!source" pseudo
"!bin" pseudo

@ -89,7 +89,7 @@ WAI
!to
!source !src
!binary !bin
!sl
!symbollist !sl
!zone !zn
!if
!ifdef

@ -73,12 +73,8 @@ Parameters: ANDVALUE: Any formula the value parser accepts, but it
FILLVALUE: Any formula the value parser accepts. If it
is omitted, a default value is used (currently 234,
that's the 6502 CPU's NOP command).
Examples: ; eliminate the 6502's JMP($xxff)-Bug:
!align 1, 0 ; wait for even address
Label !word Pointer
; align code to page border for speed increase
!align 255, 0
Examples: !align 255, 0 ; align to page (256 bytes)
!align 63, 0 ; align to C64 sprite block (64 bytes)
----------------------------------------------------------------------
@ -282,14 +278,15 @@ Examples: .backgroundcolor = 0 ; some local symbol
.backgroundcolor = 3 ; => "Symbol already defined."
Call: !sl FILENAME
Purpose: Save all the global symbols to the given file after
the assembly is finished. This table could be loaded
during another assembly session using the "!source"
pseudo opcode.
Call: !symbollist FILENAME
Purpose: Write a symbol list to the given file after assembly
is finished. The list will contain all global symbols.
This table could be loaded during another assembly
session using the "!source" pseudo opcode.
Parameters: FILENAME: A file name given in "..." quoting.
Examples: !sl "Symbols.a" ; produce symbol dump after assembly
!sl "global" ; produce symbol dump after assembly
Aliases: "!sl"
Examples: !sl "Symbols.a" ; produce symbol list after assembly
!sl "global" ; produce symbol list after assembly
----------------------------------------------------------------------

@ -12,6 +12,19 @@ platform used. There should be another help file in this archive
outlining the platform specific changes.
----------------------------------------------------------------------
Section: New in release 0.95.2
----------------------------------------------------------------------
Changed "save labels" to "symbol list" in a lot of code, error
messages and docs.
Added "!symbollist" alias for "!sl" pseudo opcode.
Change in undocumented ("illegal") opcodes: ANC #8 now generates 0x0b
instead of 0x2b (both opcodes do the same thing).
Added experimental support for generating a report listing. Thanks to
Johann Klasek for writing this extension patch.
----------------------------------------------------------------------
Section: New in release 0.95.1
----------------------------------------------------------------------

@ -71,10 +71,6 @@ Found new "!for" syntax.
When using the "-Wno-old-for" switch to disable the warning about
the older syntax, the new syntax will trigger this warning.
Label dump file already chosen.
The "!sl" command was given more than once (or in addition to the
"--labeldump" command line option). Only use it once.
Label name not in leftmost column.
A label definition has blanks before the label name.
Imagine this source code:
@ -118,6 +114,10 @@ Segment starts inside another one, overwriting it.
Future versions of ACME might throw an error instead of a warning
in this case.
Symbol list file name already chosen.
The "!sl" command was given more than once (or in addition to the
"--symbollist" command line option). Only use it once.
Used "!to" without file format indicator. Defaulting to "cbm".
Now that "!to" can be given a file format keyword (either "plain"
or "cbm"), using "cbm" as default seems inappropriate. It still
@ -362,7 +362,7 @@ Value not yet defined.
Section: Errors on closedown
----------------------------------------------------------------------
Cannot open label dump file "FILENAME".
Cannot open symbol list file "FILENAME".
Cannot open output file "FILENAME".
Make sure the name doesn't contain wildcard characters and you
have write access to the directory.

@ -27,27 +27,31 @@ In release 0.89, more were added; and in 0.94.8, another one (lxa):
| addressing mode |
Mnemo | implied #8 8 8,x 16 16,x | performs:
------+-------------------------------------+------------------------
anc | -- 2b -- -- -- -- | A = A & arg, then C=N
anc | -- 0b* -- -- -- -- | A = A & arg, then C=N
asr | -- 4b -- -- -- -- | A = A & arg, then lsr
arr | -- 6b -- -- -- -- | A = A & arg, then ror
sbx | -- cb -- -- -- -- | X = (A & X) - arg
dop | 80* 80 04 14 -- -- | skips next byte
top | 0c* -- -- -- 0c 1c | skips next two bytes
dop | 80** 80 04 14 -- -- | skips next byte
top | 0c** -- -- -- 0c 1c | skips next two bytes
jam | 02 -- -- -- -- -- | crash (wait for reset)
lxa | -- ab** -- -- -- -- | A/X = (A | ??) & arg
lxa | -- ab*** -- -- -- -- | A/X = (A | ??) & arg
Example:
!cpu 6510 ; activate additional mnemonics...
lax (some_zp_label,x) ; ...and use them. No, this
dcp (other_zp_label),y ; example does not make sense.
*) Note that "dop" and "top" can be used with implied addressing, but
*) Up until ACME version 0.95.1, anc#8 generated opcode 0x2b. Since
ACME version 0.95.2, anc#8 generates opcode 0x0b. Both opcodes work
the same way.
**) Note that "dop" and "top" can be used with implied addressing, but
the generated opcodes are those for immediate and 16-bit absolute
addressing, respectively. Using dop/top with x-indexed addressing
might have its uses when timing is critical (crossing a page border
adds a penalty cycle).
**) This opcode is said to first perform an ORA with an arbitrary(!)
***) This opcode is said to first perform an ORA with an arbitrary(!)
value, then do an AND with the given argument, then do a TAX.
This means it is unstable and therefore useless - unless the given
argument is zero, in which case it reliably clears both A and X.
@ -70,10 +74,10 @@ Just for the sake of completeness: Here are all the remaining opcodes
Opcode| Description
------+--------------------------------------------------------------
0b | same as 2b anc #8
12 | same as 02 and others jam CRASH
1a | same as (*legal*) ea nop
22 | same as 02 and others jam CRASH
2b | same as 0b anc #8
32 | same as 02 and others jam CRASH
34 | same as 14 and others dop 8,x
3a | same as (*legal*) ea nop

@ -143,7 +143,7 @@ found in the file "AllPOs.txt". Here's just a short overview:
!byte !word !24 !32 !fill !align
...for directly placing values into the output file.
!zone !sl
!zone !symbollist
...for defining the scope of local symbols and saving global symbols.
!convtab !pet !raw !scr !scrxor !text
@ -187,14 +187,16 @@ Available options are:
This is more or less useless, because the help is also shown
if ACME is run without any arguments at all.
-f, --format FORMAT select output format ("plain", "cbm" or "apple")
-o, --outfile FILE select output file
Output filename and format can also be given using the "!to"
-f, --format FORMAT set output file format ("plain", "cbm" or "apple")
-o, --outfile FILE set output file name
Output file name and format can also be given using the "!to"
pseudo opcode. If the format is not specified, "!to" defaults
to "cbm", while the command line option defaults to "plain".
-l, --labeldump FILE select label dump file
This can also be given using the "!sl" pseudo opcode.
-l, --symbollist FILE set symbol list file name
This can also be given using the "!symbollist"/"!sl" pseudo
opcode. The switch was called "--labeldump" in older versions,
that name still works, too.
--setpc NUMBER set program counter
This can also be given in the source code using "* = NUMBER".

@ -1,4 +1,4 @@
;ACME 0.95
;ACME 0.95.1
; Konstanten:
FALSE = 0 ; Das Programm verläßt sich an etlichen Stellen
@ -76,15 +76,15 @@
texttop = $1210 ; Basic-Ende+1
maxmem0 = $1212 ; Ende Bank 0
basic = $12fd ; Basic-IRQ
kernel_copyfont = $c027 ; Systemroutine, kopiert Font in VDC-RAM
kernel_cls = $c142 ; Systemroutine, löscht Screen
kernel_switchmode = $cd2e ; Systemroutine, switcht aktiven Monitor
e_copyfont = $c027 ; Systemroutine, kopiert Font in VDC-RAM
e_cls = $c142 ; Systemroutine, löscht Screen
e_switchmode = $cd2e ; Systemroutine, switcht aktiven Monitor
takt = $d030 ; 2 MHz ; register (**mark**)
vdc = $d600 ; VDC
reg = $d601
conreg = $ff00 ; MMU-CR
nmiend = $ff33 ; NMI-Ende
primm = $ff7d ; Kernel
primm = $ff7d ; Kernal
open = $ffc0
close = $ffc3
chkin = $ffc6

@ -512,12 +512,12 @@ init ldx repeatedtry ; first start ?
stx addr($11e7)
lda mode ; which mode ?
bmi + ; if 40 then
jsr kernel_switchmode ; switch mode
jsr e_switchmode ; switch mode
+ lda #111 ; DIN on
sta D8502
lda #%..##..##
sta R8502
jsr kernel_copyfont
jsr e_copyfont
lda #47 ; DIN off
sta D8502
lda #<addfont1_start ; adjust font...
@ -744,7 +744,7 @@ gonot rts ; fixme - could save a byte here
F_goout jsr willblost ; changes saved ?
beq gonot
F_gosys +bank15
jsr kernel_cls ; CLS
jsr e_cls ; CLS
lda #0 ; '0' for
sta locks ; 'CBM-Shift' on
sta addr($0ac5) ; 'ASC/DIN' on

@ -1,4 +1,4 @@
CFLAGS = -O3 -Wall
CFLAGS = -O3 -Wall -Wstrict-prototypes
LIBS = -lm
CC = gcc
RM = rm

@ -1,4 +1,4 @@
CFLAGS = -Wall -s
CFLAGS = -Wall -s -Wstrict-prototypes
LIBS = -lm
CC = gcc
RM = rm

@ -2,7 +2,7 @@
# makefile for MingW
#
CFLAGS = -O3 -Wall
CFLAGS = -O3 -Wall -Wstrict-prototypes
LIBS = -lm
CC = gcc
RM = rm

@ -1,4 +1,4 @@
CFLAGS = -O3 -mthrowback -mlibscl -Wall
CFLAGS = -O3 -mthrowback -mlibscl -Wall -Wstrict-prototypes
LIBS = -lm
CC = gcc
RM = rm

@ -15,9 +15,9 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define RELEASE "0.95.1" // update before release (FIXME)
#define RELEASE "0.95.2" // update before release (FIXME)
#define CODENAME "Fenchurch" // update before release
#define CHANGE_DATE "7 Jun" // update before release
#define CHANGE_DATE "22 Nov" // update before release
#define CHANGE_YEAR "2014" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
@ -49,12 +49,15 @@ static const char FILE_WRITETEXT[] = "w";
static const char FILE_WRITEBINARY[] = "wb";
// names for error messages
static const char name_outfile[] = "output filename";
static const char name_dumpfile[] = "label dump filename";
static const char arg_symbollist[] = "symbol list filename";
static const char arg_reportfile[] = "report filename";
// long options
#define OPTION_HELP "help"
#define OPTION_FORMAT "format"
#define OPTION_OUTFILE "outfile"
#define OPTION_LABELDUMP "labeldump"
#define OPTION_LABELDUMP "labeldump" // old
#define OPTION_SYMBOLLIST "symbollist" // new
#define OPTION_REPORT "report"
#define OPTION_SETPC "setpc"
#define OPTION_CPU "cpu"
#define OPTION_INITMEM "initmem"
@ -75,8 +78,9 @@ static int toplevel_src_count = 0;
static signed long start_address = ILLEGAL_START_ADDRESS;
static signed long fill_value = MEMINIT_USE_DEFAULT;
static const struct cpu_type *default_cpu = NULL;
const char *symboldump_filename = NULL;
const char *symbollist_filename = NULL;
const char *output_filename = NULL;
const char *report_filename = NULL;
// maximum recursion depth for macro calls and "!source"
signed long macro_recursions_left = MAX_NESTING;
signed long source_recursions_left = MAX_NESTING;
@ -115,11 +119,13 @@ static void show_help_and_exit(void)
"\n"
"Options:\n"
" -h, --" OPTION_HELP " show this help and exit\n"
" -f, --" OPTION_FORMAT " FORMAT select output format\n"
" -o, --" OPTION_OUTFILE " FILE select output file\n"
" -l, --" OPTION_LABELDUMP " FILE select label dump file\n"
" -f, --" OPTION_FORMAT " FORMAT set output file format\n"
" -o, --" OPTION_OUTFILE " FILE set output file name\n"
" -r, --" OPTION_REPORT " FILE set report file name\n"
" -l, --" OPTION_SYMBOLLIST " FILE set symbol list file name\n"
" --" OPTION_LABELDUMP " (old name for --" OPTION_SYMBOLLIST ")\n"
" --" OPTION_SETPC " NUMBER set program counter\n"
" --" OPTION_CPU " CPU select target processor\n"
" --" OPTION_CPU " CPU set target processor\n"
" --" OPTION_INITMEM " NUMBER define 'empty' memory\n"
" --" OPTION_MAXERRORS " NUMBER set number of errors before exiting\n"
" --" OPTION_MAXDEPTH " NUMBER set recursion depth for macro calls and !src\n"
@ -139,22 +145,49 @@ PLATFORM_OPTION_HELP
}
// initialise report struct
static void report_init(struct report *report)
{
report->fd = NULL;
report->asc_used = 0;
report->bin_used = 0;
report->last_input = NULL;
}
// open report file
static int report_open(struct report *report, const char *filename)
{
report->fd = fopen(filename, FILE_WRITETEXT);
if (report->fd == NULL) {
fprintf(stderr, "Error: Cannot open report file \"%s\".\n", filename);
return 1;
}
return 0; // success
}
// close report file
static void report_close(struct report *report)
{
if (report->fd) {
fclose(report->fd);
report->fd = NULL;
}
}
// error handling
// tidy up before exiting by saving symbol dump
// tidy up before exiting by saving symbol list and close other output files
int ACME_finalize(int exit_code)
{
FILE *fd;
if (symboldump_filename) {
fd = fopen(symboldump_filename, FILE_WRITETEXT);
report_close(report);
if (symbollist_filename) {
fd = fopen(symbollist_filename, FILE_WRITETEXT);
if (fd) {
symbols_dump_all(fd);
symbols_list(fd);
fclose(fd);
} else {
fprintf(stderr,
"Error: Cannot open label dump file \"%s\".\n",
symboldump_filename);
fprintf(stderr, "Error: Cannot open symbol list file \"%s\".\n", symbollist_filename);
exit_code = EXIT_FAILURE;
}
}
@ -221,9 +254,12 @@ static int perform_pass(void)
// do passes until done (or errors occured). Return whether output is ready.
static int do_actual_work(void)
{
int undefined_prev, // "NeedValue" errors of previous pass
undefined_curr; // "NeedValue" errors of current pass
struct report my_report;
int undefined_prev, // "NeedValue" errors of previous pass
undefined_curr; // "NeedValue" errors of current pass
report = &my_report; // let global pointer point to something
report_init(report); // we must init struct before doing passes
if (Process_verbosity > 1)
puts("First pass.");
pass_count = 0;
@ -233,20 +269,33 @@ static int do_actual_work(void)
// As long as the number of "NeedValue" errors is decreasing but
// non-zero, keep doing passes.
while (undefined_curr && (undefined_curr < undefined_prev)) {
pass_count++;
++pass_count;
undefined_prev = undefined_curr;
if (Process_verbosity > 1)
puts("Further pass.");
undefined_curr = perform_pass();
}
// If still errors (unsolvable by doing further passes),
// perform additional pass to find and show them
if (undefined_curr == 0)
// any errors left?
if (undefined_curr == 0) {
// if listing report is wanted and there were no errors,
// do another pass to generate listing report
if (report_filename) {
if (Process_verbosity > 1)
puts("Extra pass to generate listing report.");
if (report_open(report, report_filename) == 0) {
++pass_count;
perform_pass();
report_close(report);
}
}
return 1;
}
// There are still errors (unsolvable by doing further passes),
// so perform additional pass to find and show them.
if (Process_verbosity > 1)
puts("Further pass needed to find error.");
puts("Extra pass needed to find error.");
ALU_throw_errors(); // activate error output (CAUTION - one-way!)
pass_count++;
++pass_count;
perform_pass(); // perform pass, but now show "value undefined"
return 0;
}
@ -372,8 +421,12 @@ static const char *long_option(const char *string)
set_output_format();
else if (strcmp(string, OPTION_OUTFILE) == 0)
output_filename = cliargs_safe_get_next(name_outfile);
else if (strcmp(string, OPTION_LABELDUMP) == 0)
symboldump_filename = cliargs_safe_get_next(name_dumpfile);
else if (strcmp(string, OPTION_LABELDUMP) == 0) // old
symbollist_filename = cliargs_safe_get_next(arg_symbollist);
else if (strcmp(string, OPTION_SYMBOLLIST) == 0) // new
symbollist_filename = cliargs_safe_get_next(arg_symbollist);
else if (strcmp(string, OPTION_REPORT) == 0)
report_filename = cliargs_safe_get_next(arg_reportfile);
else if (strcmp(string, OPTION_SETPC) == 0)
set_starting_pc();
else if (strcmp(string, OPTION_CPU) == 0)
@ -383,8 +436,7 @@ static const char *long_option(const char *string)
else if (strcmp(string, OPTION_MAXERRORS) == 0)
max_errors = string_to_number(cliargs_safe_get_next("maximum error count"));
else if (strcmp(string, OPTION_MAXDEPTH) == 0)
macro_recursions_left = (source_recursions_left =
string_to_number(cliargs_safe_get_next("recursion depth")));
macro_recursions_left = (source_recursions_left = string_to_number(cliargs_safe_get_next("recursion depth")));
// else if (strcmp(string, "strictsyntax") == 0)
// strict_syntax = TRUE;
else if (strcmp(string, OPTION_USE_STDOUT) == 0)
@ -392,7 +444,8 @@ static const char *long_option(const char *string)
PLATFORM_LONGOPTION_CODE
else if (strcmp(string, OPTION_VERSION) == 0)
show_version(TRUE);
else return string;
else
return string;
return NULL;
}
@ -413,8 +466,11 @@ static char short_option(const char *argument)
case 'o': // "-o" selects output filename
output_filename = cliargs_safe_get_next(name_outfile);
break;
case 'l': // "-l" selects symbol dump filename
symboldump_filename = cliargs_safe_get_next(name_dumpfile);
case 'l': // "-l" selects symbol list filename
symbollist_filename = cliargs_safe_get_next(arg_symbollist);
break;
case 'r': // "-r" selects report filename
report_filename = cliargs_safe_get_next(arg_reportfile);
break;
case 'v': // "-v" changes verbosity
Process_verbosity++;
@ -473,8 +529,7 @@ int main(int argc, const char *argv[])
// handle command line arguments
cliargs_handle_options(short_option, long_option);
// generate list of files to process
cliargs_get_rest(&toplevel_src_count, &toplevel_sources,
"No top level sources given");
cliargs_get_rest(&toplevel_src_count, &toplevel_sources, "No top level sources given");
// Init modules (most of them will just build keyword trees)
ALU_init();
Basics_init();

@ -11,8 +11,9 @@
// Variables
extern const char *symboldump_filename;
extern const char *symbollist_filename;
extern const char *output_filename;
extern const char *report_filename;
// maximum recursion depth for macro calls and "!source"
extern signed long macro_recursions_left;
extern signed long source_recursions_left;

@ -908,7 +908,7 @@ static void perform_ranged_fp(double (*fn)(double))
// convert right-hand value from fp to int
static void right_fp_to_int()
static void right_fp_to_int(void)
{
RIGHT_INTVAL = RIGHT_FPVAL;
RIGHT_FLAGS &= ~MVALUE_IS_FP;

@ -6,6 +6,7 @@
// 4 Oct 2006 Fixed a typo in a comment
// 22 Nov 2007 Added warn_on_indented_labels
// 2 Jun 2014 Added warn_on_old_for and warn_on_type_mismatch
// 19 Nov 2014 Merged Johann Klasek's report listing generator patch
#include <stdio.h>
#include "platform.h"
#include "acme.h"
@ -107,6 +108,7 @@ int pass_undefined_count; // "NeedValue" type errors
int pass_real_errors; // Errors yet
signed long max_errors = MAXERRORS; // errors before giving up
FILE *msg_stream = NULL; // set to stdout by --use-stdout
struct report *report = NULL;
// memory allocation stuff

@ -3,12 +3,14 @@
// Have a look at "acme.c" for further info
//
// Global stuff - things that are needed by several modules
// 19 Nov 2014 Merged Johann Klasek's report listing generator patch
#ifndef global_H
#define global_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#define PSEUDO_OPCODE_PREFIX '!' // FIXME - this is not yet used consistently!
@ -73,6 +75,20 @@ extern int pass_real_errors; // Errors yet
extern signed long max_errors; // errors before giving up
extern FILE *msg_stream; // set to stdout by --errors_to_stdout
// 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
};
extern struct report *report;
// Macros for skipping a single space character
#define SKIPSPACE() \
do { \

@ -3,6 +3,7 @@
// Have a look at "acme.c" for further info
//
// Input stuff
// 19 Nov 2014 Merged Johann Klasek's report listing generator patch
#include "config.h"
#include "alu.h"
#include "dynabuf.h"
@ -75,6 +76,61 @@ void Input_new_file(const char *filename, FILE *fd)
Input_now->src.fd = fd;
}
// remember source code character for report generator
#define IF_WANTED_REPORT_SRCCHAR(c) do { if (report->fd) report_srcchar(c); } while(0)
static void report_srcchar(char new_char)
{
static char prev_char = '\0';
int ii;
char hex_address[5];
char hexdump[2 * REPORT_BINBUFSIZE + 2]; // +2 for '.' and terminator
// if input has changed, insert explanation
if (Input_now != report->last_input) {
fprintf(report->fd, "\n; ******** Source: %s\n", Input_now->original_filename);
report->last_input = Input_now;
report->asc_used = 0; // clear buffer
prev_char = '\0';
}
if ((prev_char == '\n' || prev_char == '\r')) {
// this check makes empty lines screw up line numbers:
// && new_char != '\n') {
// line start after line break detected and EOS processed,
// build report line:
// show line number...
fprintf(report->fd, "%6d ", Input_now->line_number - 1);
// prepare outbytes' start address
if (report->bin_used)
snprintf(hex_address, 5, "%04x", report->bin_address);
else
hex_address[0] = '\0';
// prepare outbytes
hexdump[0] = '\0';
for (ii = 0; ii < report->bin_used; ++ii)
sprintf(hexdump + 2 * ii, "%02x", (unsigned int) (unsigned char) (report->bin_buf[ii]));
// if binary buffer is full, overwrite last byte with "..."
if (report->bin_used == REPORT_BINBUFSIZE)
sprintf(hexdump + 2 * (REPORT_BINBUFSIZE - 1), "...");
// show address and bytes
fprintf(report->fd, "%-4s %-19s", hex_address, hexdump);
// at this point the output should be a multiple of 8 characters
// so far to preserve tabs of the source...
if (report->asc_used == REPORT_ASCBUFSIZE)
--report->asc_used;
report->asc_buf[report->asc_used] = '\0';
fprintf(report->fd, "%s\n", report->asc_buf); // show source line
report->asc_used = 0; // reset buffers
report->bin_used = 0;
}
if (new_char != '\n' && new_char != '\r') { // detect line break
if (report->asc_used < REPORT_ASCBUFSIZE)
report->asc_buf[report->asc_used++] = new_char;
}
prev_char = new_char;
}
// Deliver source code from current file (!) in shortened high-level format
static char get_processed_from_file(void)
{
@ -85,6 +141,7 @@ static char get_processed_from_file(void)
case INPUTSTATE_NORMAL:
// fetch a fresh byte from the current source file
from_file = getc(Input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
// now process it
/*FALLTHROUGH*/
case INPUTSTATE_AGAIN:
@ -147,9 +204,10 @@ static char get_processed_from_file(void)
}
case INPUTSTATE_SKIPBLANKS:
// read until non-blank, then deliver that
do
do {
from_file = getc(Input_now->src.fd);
while ((from_file == CHAR_TAB) || (from_file == ' '));
IF_WANTED_REPORT_SRCCHAR(from_file);
} while ((from_file == CHAR_TAB) || (from_file == ' '));
// re-process last byte
Input_now->state = INPUTSTATE_AGAIN;
break;
@ -165,6 +223,7 @@ static char get_processed_from_file(void)
case INPUTSTATE_SKIPLF:
from_file = getc(Input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
// if LF, ignore it and fetch another byte
// otherwise, process current byte
if (from_file == CHAR_LF)
@ -174,9 +233,10 @@ static char get_processed_from_file(void)
break;
case INPUTSTATE_COMMENT:
// read until end-of-line or end-of-file
do
do {
from_file = getc(Input_now->src.fd);
while ((from_file != EOF) && (from_file != CHAR_CR) && (from_file != CHAR_LF));
IF_WANTED_REPORT_SRCCHAR(from_file);
} while ((from_file != EOF) && (from_file != CHAR_CR) && (from_file != CHAR_LF));
// re-process last byte
Input_now->state = INPUTSTATE_AGAIN;
break;
@ -236,6 +296,7 @@ char GetQuotedByte(void)
} else {
// fetch a fresh byte from the current source file
from_file = getc(Input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
switch (from_file) {
case EOF:
// remember to send an end-of-file

@ -114,7 +114,7 @@ enum { IDX_BIT,IDX_ASL,IDX_ROL,IDX_LSR,IDX_ROR,IDX_STY,IDX_STX,IDX_L
SCS misc_abs[] = { 0x2c24, 0x0e06, 0x2e26, 0x4e46, 0x6e66, 0x8c84, 0x8e86, 0xaca4, 0xaea6, 0xccc4, 0xece4, 0xcec6, 0xeee6, 0x0c04, 0x1c14, 0x2c24, 0xcec6, 0xeee6, 0x9c64, 0x02, 0, 0, 0xf400, 0, 0, 0, 0, 0x04, 0x0c00, 0, 0}; // $ff $ffff
SCS misc_xabs[] = { 0, 0x1e16, 0x3e36, 0x5e56, 0x7e76, 0x94, 0, 0xbcb4, 0, 0, 0, 0xded6, 0xfef6, 0, 0, 0x3c34, 0xded6, 0xfef6, 0x9e74, 0, 0, 0, 0, 0, 0, 0, 0, 0x14, 0x1c00, 0, 0}; // $ff,x $ffff,x
SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0, 0x96, 0, 0xbeb6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff,y $ffff,y
SCB misc_imm[] = { 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0, 0, 0, 0x89, 0, 0, 0, 0, 0xc2, 0xe2, 0, 0x2b, 0x4b, 0x6b, 0xcb, 0x80, 0, 0, 0xab}; // #$ff
SCB misc_imm[] = { 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0, 0, 0, 0x89, 0, 0, 0, 0, 0xc2, 0xe2, 0, 0x0b, 0x4b, 0x6b, 0xcb, 0x80, 0, 0, 0xab}; // #$ff
SCB misc_impl[] = { 0, 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0x1a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0c, 0x02, 0}; // implied/accu
// Code tables for group GROUP_ALLJUMPS:

@ -6,6 +6,7 @@
// 24 Nov 2007 Added possibility to suppress segment overlap warnings
// 25 Sep 2011 Fixed bug in !to (colons in filename could be interpreted as EOS)
// 5 Mar 2014 Fixed bug where setting *>0xffff resulted in hangups.
// 19 Nov 2014 Merged Johann Klasek's report listing generator patch
#include <stdlib.h>
//#include <stdio.h>
#include <string.h> // for memset()
@ -89,6 +90,16 @@ static struct node_t segment_modifiers[] = {
};
// report binary output
static void report_binary(char value)
{
if (report->bin_used == 0)
report->bin_address = out->write_idx; // remember address at start of line
if (report->bin_used < REPORT_BINBUFSIZE)
report->bin_buf[report->bin_used++] = value;
}
// set up new out->segment.max value according to the given address.
// just find the next segment start and subtract 1.
static void find_segment_max(intval_t new_pc)
@ -138,6 +149,8 @@ static void real_output(intval_t byte)
if (out->write_idx > out->highest_written)
out->highest_written = out->write_idx;
// write byte and advance ptrs
if (report->fd)
report_binary(byte & 0xff); // file for reporting, taking also CPU_2add
out->buffer[out->write_idx++] = byte & 0xff;
CPU_state.add_to_pc++;
}
@ -154,6 +167,8 @@ static void no_output(intval_t byte)
// call this if really calling Output_byte would be a waste of time
// FIXME - check all users of this, because future changes
// ("several-projects-at-once") may be incompatible with this!
void Output_fake(int size)
{
if (size < 1)
@ -584,6 +599,10 @@ when encountering "* = VALUE":
Problem: always check for "undefined"; there are some problematic combinations.
I need a way to return the size of a generated code block even if PC undefined.
Maybe like this:
* = new_address [, invisible] [, overlay] [, &size_symbol_ref {]
...code...
[} ; at end of block, size is written to size symbol given above!]
*/

@ -36,8 +36,8 @@ static void dump_one_symbol(struct node_ra_t *node, FILE *fd)
// output name
if (warn_on_type_mismatch
&& symbol->result.addr_refs == 1)
fprintf(fd, "!addr\t");
fprintf(fd, "%s", node->id_string);
fprintf(fd, "!addr");
fprintf(fd, "\t%s", node->id_string);
switch (symbol->result.flags & MVALUE_FORCEBITS) {
case MVALUE_FORCE16:
fprintf(fd, "+2\t= ");
@ -169,7 +169,7 @@ static enum eos PO_set(void) // Now GotByte = illegal char
}
// Select dump file
// set file name for symbol list
static enum eos PO_sl(void)
{
// bugfix: first read filename, *then* check for first pass.
@ -186,14 +186,14 @@ static enum eos PO_sl(void)
if (pass_count)
return SKIP_REMAINDER;
// if symbol dump file already chosen, complain and exit
if (symboldump_filename) {
Throw_warning("Label dump file already chosen.");
// if symbol list file name already set, complain and exit
if (symbollist_filename) {
Throw_warning("Symbol list file name already chosen.");
return SKIP_REMAINDER;
}
// get malloc'd copy of filename
symboldump_filename = DynaBuf_get_copy(GlobalDynaBuf);
symbollist_filename = DynaBuf_get_copy(GlobalDynaBuf);
// ensure there's no garbage at end of line
return ENSURE_EOS;
}
@ -201,8 +201,9 @@ static enum eos PO_sl(void)
// predefined stuff
static struct node_t pseudo_opcodes[] = {
PREDEFNODE("set", PO_set),
PREDEFLAST(s_sl, PO_sl),
PREDEFNODE("set", PO_set),
PREDEFNODE("symbollist", PO_sl),
PREDEFLAST(s_sl, PO_sl),
// ^^^^ this marks the last element
};
@ -268,10 +269,10 @@ void symbol_define(intval_t value)
// dump global symbols to file
void symbols_dump_all(FILE *fd)
void symbols_list(FILE *fd)
{
Tree_dump_forest(symbols_forest, ZONE_GLOBAL, dump_one_symbol, fd);
PLATFORM_SETFILETYPE_TEXT(symboldump_filename);
PLATFORM_SETFILETYPE_TEXT(symbollist_filename);
}

@ -41,7 +41,7 @@ extern struct symbol *symbol_find(zone_t, int flags);
// name must be held in GlobalDynaBuf.
extern void symbol_define(intval_t value);
// dump global symbols to file
extern void symbols_dump_all(FILE *fd);
extern void symbols_list(FILE *fd);
// fix name of anonymous forward label (held in GlobalDynaBuf, NOT TERMINATED!)
// so it references the *next* anonymous forward label definition.
extern void symbol_fix_forward_anon_name(int increment);