aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2020-09-05 20:23:30 -0700
committerH. Peter Anvin <hpa@zytor.com>2020-09-05 20:23:30 -0700
commit50e064734f5945577cb456e56c711c7999ae9e24 (patch)
tree456dcaeed82c0db6d95b917bb4409d0022aa9a6e
parent0e7e996bd315cfa4c9ca036a278f15211361cda5 (diff)
downloadabcdisk-50e064734f5945577cb456e56c711c7999ae9e24.tar.gz
abcdisk-50e064734f5945577cb456e56c711c7999ae9e24.tar.xz
abcdisk-50e064734f5945577cb456e56c711c7999ae9e24.zip
bin2abc: add support for .bas file output
-rw-r--r--Makefile.in2
-rw-r--r--bas.c64
-rw-r--r--bin2abc.c24
-rw-r--r--bin2abc.h5
4 files changed, 91 insertions, 4 deletions
diff --git a/Makefile.in b/Makefile.in
index b54926b..b547280 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -81,7 +81,7 @@ bac80.$(O): asmsrc/bac80.h asmsrc/bac80r.h
bac800.$(O): asmsrc/bac800.h asmsrc/bac800d.h
-bin2abc$(X): bin2abc.$(O) ihex.$(O) abs.$(O) relocs.$(O) \
+bin2abc$(X): bin2abc.$(O) ihex.$(O) abs.$(O) bas.$(O) relocs.$(O) \
bac80.$(O) bac800.$(O) mangle.$(O) $(ASMO)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
diff --git a/bas.c b/bas.c
new file mode 100644
index 0000000..abe62c4
--- /dev/null
+++ b/bas.c
@@ -0,0 +1,64 @@
+#include "compiler.h"
+#include "bin2abc.h"
+
+#define MAXLINE 79
+
+int writebas(FILE * out, uint8_t * data, const bool * isset,
+ int origin, int entrypoint, int firstline,
+ bool subroutine, const char *chain)
+{
+ int nextaddr = 0;
+ int addr;
+ char buf[MAXLINE+1];
+ int buf_len = 0;
+
+ if (have_relocs)
+ apply_relocs(data, origin);
+
+ for (addr = 0; addr < MAX_ADDR; addr++) {
+ if (isset[addr]) {
+ if (buf_len) {
+ if (addr != nextaddr || buf_len > MAXLINE-5) {
+ buf[buf_len++] = '\n';
+ fwrite(buf, 1, buf_len, out);
+ buf_len = 0;
+ }
+ }
+
+ if (!buf_len) {
+ buf_len = snprintf(buf, sizeof buf, "%d POKE %d%%",
+ firstline++, addr);
+ }
+
+ buf_len += snprintf(buf + buf_len, sizeof buf - buf_len,
+ ",%d%%", data[addr]);
+ nextaddr = addr + 1;
+ }
+ }
+
+ if (buf_len) {
+ buf[buf_len++] = '\n';
+ fwrite(buf, 1, buf_len, out);
+ }
+
+ if (subroutine) {
+ fprintf(out, "%d RETURN\n", firstline++);
+ } else {
+ if (entrypoint >= 0)
+ fprintf(out, "%d Z%%=CALL(%d%%)\n", firstline++, entrypoint);
+
+ if (chain[0] == ':') {
+ fprintf(out, "%d END\n", firstline++);
+ } else if (!chain[0]) {
+ /* Make it work on both ABC80 and 800 */
+ fprintf(out, "%d ON ERROR GOTO %d\n", firstline, firstline+2);
+ fprintf(out, "%d CHAIN \"NUL:\"\n", firstline+1);
+ fprintf(out, "%d CHAIN \"\"\n", firstline+2);
+ firstline += 3;
+ } else {
+ fprintf(out, "%d CHAIN \"%s\"\n", firstline++, chain);
+ }
+ }
+
+ return 0;
+}
diff --git a/bin2abc.c b/bin2abc.c
index e1fd668..c1f71f9 100644
--- a/bin2abc.c
+++ b/bin2abc.c
@@ -2,7 +2,7 @@
* bin2abc.c
*
* Convert a binary file either in binary or ith format to an ABC80/800
- * .bac or .abs file.
+ * .bac, .abs, or .bas (POKE) file.
*/
#include "abcdisk.h"
@@ -224,6 +224,9 @@ static no_return help(void)
"Options:\n"
" -1, --bac80 generate a .bac file for ABC80\n"
" -2, --bac800 generate a .bac file for ABC800\n"
+ " -t, --bas generate a .bas file\n"
+ " --firstline # first line number in .bas file\n"
+ " --subroutine .bas file ends in RETURN\n"
" -a, --abs generate an .abs file\n"
" -o, --output ... send output to a file instead of stdout\n"
" -r, --reloc ... read a relocation file (.reloc from z80asm)\n"
@@ -247,7 +250,8 @@ static no_return help(void)
enum output {
OUT_BAC80,
OUT_BAC800,
- OUT_ABS
+ OUT_ABS,
+ OUT_BAS
};
int main(int argc, char *argv[])
@@ -262,6 +266,8 @@ int main(int argc, char *argv[])
const char *chain = no_chain;
bool patch_mode = false;
FILE *out;
+ int firstline = 1;
+ bool subroutine=false;
int firstaddr, i;
int lastaddr = 0;
int err = 0;
@@ -284,6 +290,8 @@ int main(int argc, char *argv[])
output = OUT_BAC800;
} else if (!strcmp(optstr, "abs")) {
output = OUT_ABS;
+ } else if (!strcmp(optstr, "bas")) {
+ output = OUT_BAS;
} else if (!strcmp(optstr, "reloc")) {
read_reloc_file(LONG_ARG());
} else if (!strcmp(optstr, "ihex") ||
@@ -319,6 +327,10 @@ int main(int argc, char *argv[])
entrypt = intarg(LONG_ARG());
} else if (!strcmp(optstr, "bss") || !strcmp(optstr, "zero")) {
bss += intarg(LONG_ARG());
+ } else if (!strcmp(optstr, "firstline")) {
+ firstline = intarg(LONG_ARG());
+ } else if (!strcmp(optstr, "subroutine")) {
+ subroutine = true;
} else if (!strcmp(optstr, "version")) {
printf("abcdisk %s\n", VERSION);
exit(0);
@@ -342,6 +354,9 @@ int main(int argc, char *argv[])
case 'a':
output = OUT_ABS;
break;
+ case 't':
+ output = OUT_BAS;
+ break;
case 'i':
ihex = true;
break;
@@ -466,6 +481,11 @@ int main(int argc, char *argv[])
case OUT_ABS:
err = writeabs(out, data, isset, firstaddr, entrypt);
break;
+
+ case OUT_BAS:
+ err = writebas(out, data, isset, firstaddr, entrypt, firstline,
+ subroutine, chain);
+ break;
}
err |= close_file(out);
diff --git a/bin2abc.h b/bin2abc.h
index f15df1e..2a5d634 100644
--- a/bin2abc.h
+++ b/bin2abc.h
@@ -45,12 +45,15 @@ void apply_relocs(uint8_t *data, uint16_t origin);
#define CHAIN_LEN 16
-int writeabs(FILE * out, uint8_t * data, const bool * isset,
+int writeabs(FILE *out, uint8_t *data, const bool *isset,
int origin, int entrypoint);
int writebac80(FILE * out, const uint8_t * data, int len, int origin,
int entrypoint, bool driver, const char *chain);
int writebac800(FILE * out, const uint8_t * data, int len, int origin,
int entrypoint, bool driver, const char *chain);
+int writebas(FILE * out, uint8_t * data, const bool * isset,
+ int origin, int entrypoint, int firstline,
+ bool subroutine, const char *chain);
extern const char *program_name;