Mercurial > hg > index.cgi
changeset 406:4411a6123716
Add "basic" output format
Add "basic" output format. This outputs the code in the form of a Basic
program that installs the assembled output. If an execution address is
provided to the END pseudo operation, it will transfer control there using
the Basic EXEC command.
Thanks to Tim Lindner <tlindner@macmess.org> for the original patch. I used
it mostly as is except for a couple of minor fixes for coding style and
removing a variable declaration from inside a for() statement for
portability reasons.
author | William Astle <lost@l-w.ca> |
---|---|
date | Thu, 03 Mar 2016 21:04:39 -0700 |
parents | 4c8925f97eb5 |
children | c501b3ce39c8 |
files | lwasm/lwasm.h lwasm/main.c lwasm/output.c lwasm/pseudo.c |
diffstat | 4 files changed, 107 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/lwasm/lwasm.h Thu Mar 03 20:52:15 2016 -0700 +++ b/lwasm/lwasm.h Thu Mar 03 21:04:39 2016 -0700 @@ -54,6 +54,7 @@ enum lwasm_output_e { OUTPUT_DECB = 0, // DECB multirecord format + OUTPUT_BASIC, // Color BASIC program OUTPUT_RAW, // raw sequence of bytes OUTPUT_OBJ, // proprietary object file format OUTPUT_RAWREL, // raw bytes where ORG causes a SEEK in the file
--- a/lwasm/main.c Thu Mar 03 20:52:15 2016 -0700 +++ b/lwasm/main.c Thu Mar 03 21:04:39 2016 -0700 @@ -44,7 +44,7 @@ { { "output", 'o', "FILE", 0, "Output to FILE"}, { "debug", 'd', "LEVEL", lw_cmdline_opt_optional, "Set debug mode"}, - { "format", 'f', "TYPE", 0, "Select output format: decb, raw, obj, os9"}, + { "format", 'f', "TYPE", 0, "Select output format: decb, basic, raw, obj, os9"}, { "list", 'l', "FILE", lw_cmdline_opt_optional, "Generate list [to FILE]"}, { "symbols", 's', 0, lw_cmdline_opt_optional, "Generate symbol list in listing, no effect without --list"}, { "symbols-nolocals", 0x103, 0, lw_cmdline_opt_optional, "Same as --symbols but with local labels ignored"}, @@ -175,6 +175,8 @@ case 'f': if (!strcasecmp(arg, "decb")) as -> output_format = OUTPUT_DECB; + else if (strcasecmp(arg, "basic")) + as -> output_format = OUTPUT_BASIC; else if (!strcasecmp(arg, "raw")) as -> output_format = OUTPUT_RAW; else if (!strcasecmp(arg, "rawrel"))
--- a/lwasm/output.c Thu Mar 03 20:52:15 2016 -0700 +++ b/lwasm/output.c Thu Mar 03 21:04:39 2016 -0700 @@ -35,6 +35,7 @@ void write_code_raw(asmstate_t *as, FILE *of); void write_code_decb(asmstate_t *as, FILE *of); +void write_code_BASIC(asmstate_t *as, FILE *of); void write_code_rawrel(asmstate_t *as, FILE *of); void write_code_obj(asmstate_t *as, FILE *of); void write_code_os9(asmstate_t *as, FILE *of); @@ -73,6 +74,10 @@ case OUTPUT_DECB: write_code_decb(as, of); break; + + case OUTPUT_BASIC: + write_code_BASIC(as, of); + break; case OUTPUT_RAWREL: write_code_rawrel(as, of); @@ -108,6 +113,103 @@ fclose(of); } +int write_code_BASIC_fprintf(FILE *of, int linelength, int *linenumber, int value) +{ + if (linelength > 247) + { + fprintf(of, "\n"); + linelength = fprintf(of, "%d DATA ", *linenumber); + *linenumber += 10; + } + else + { + linelength += fprintf(of, ","); + } + linelength += fprintf(of, "%d", value); + + return linelength; +} + +void write_code_BASIC(asmstate_t *as, FILE *of) +{ + line_t *cl; + line_t *startblock = as -> line_head; + line_t *endblock; + int linenumber, linelength, startaddress, lastaddress, address; + int outidx; + + fprintf(of, "10 READ A,B\n"); + fprintf(of, "20 IF A=-1 THEN 70\n"); + fprintf(of, "30 FOR C = A TO B\n"); + fprintf(of, "40 READ D:POKE C,D\n"); + fprintf(of, "50 NEXT C\n"); + fprintf(of, "60 GOTO 10\n"); + + if (as -> execaddr == 0) + { + fprintf(of, "70 END"); + } + else + { + fprintf(of, "70 EXEC %d", as -> execaddr); + } + + linenumber = 80; + linelength = 255; + + while(startblock) + { + startaddress = -1; + endblock = NULL; + + for (cl = startblock; cl; cl = cl -> next) + { + if (cl -> outputl < 0) + continue; + + address = lw_expr_intval(cl -> addr); + + if (startaddress == -1) + { + startaddress = address; + lastaddress = address + cl -> outputl - 1; + } + else + { + if (lastaddress != address - 1) + { + endblock = cl; + break; + } + + lastaddress += cl -> outputl; + } + } + + linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, startaddress); + linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, lastaddress); + + for (cl = startblock; cl != endblock; cl = cl -> next) + { + if (cl -> outputl < 0) + continue; + + for (outidx=0; outidx<cl -> outputl; outidx++) + { + linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, cl -> output[outidx]); + } + } + + startblock = cl; + } + + linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, -1); + linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, -1); + + fprintf(of, "\n"); +} + + /* rawrel output treats an ORG directive as an offset from the start of the file. Undefined results will occur if an ORG directive moves the output