aboutsummaryrefslogtreecommitdiff
path: root/listbas.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-06-25 04:09:46 -0400
committerB. Watson <urchlay@slackware.uk>2024-06-25 04:09:46 -0400
commitfba189882a394e9d85975ad5ad43ea688f8481c8 (patch)
tree4dce5ea8511ee1af921377206bb97b3e23880c71 /listbas.c
parentaa2c841fd291ba062881534936b7d89674b5f52d (diff)
downloadbw-atari8-tools-fba189882a394e9d85975ad5ad43ea688f8481c8.tar.gz
listbas: added (list basic programs, very barebones for now).
Diffstat (limited to 'listbas.c')
-rw-r--r--listbas.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/listbas.c b/listbas.c
new file mode 100644
index 0000000..6469009
--- /dev/null
+++ b/listbas.c
@@ -0,0 +1,171 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <math.h>
+
+#include "bas.h"
+#include "bcdfp.h"
+#include "tokens.h"
+
+int immediate = 0;
+
+void print_help(void) {
+ printf("Usage: %s [-v] [-i] <inputfile>\n", self);
+}
+
+void parse_args(int argc, char **argv) {
+ int opt;
+
+ while( (opt = getopt(argc, argv, "vi")) != -1) {
+ switch(opt) {
+ case 'v': verbose = 1; break;
+ case 'i': immediate = 1; break;
+ default:
+ print_help();
+ exit(1);
+ }
+ }
+
+ if(optind >= argc)
+ die("No input file given (use - for stdin).");
+ else
+ open_input(argv[optind]);
+}
+
+double bcd2double(const unsigned char *num) {
+ double result = 0, sign;
+ int exp, i;
+
+ exp = *num;
+ if(!exp) {
+ return 0.0;
+ }
+
+ sign = (exp & 0x80 ? -1.0 : 1.0);
+ exp &= 0x7f;
+ exp -= 0x40;
+
+ for(i = 1; i < 6; i++) {
+ result *= 100.0;
+ result += bcd2int(num[i]);
+ }
+
+ result *= pow(100, exp - 4);
+ result *= sign;
+
+ return result;
+}
+
+void print_number(unsigned int pos) {
+ printf("%G", bcd2double(program + pos));
+}
+
+void print_string(unsigned int pos, unsigned int len) {
+ putchar('"');
+ while(len--) putchar(program[pos++]);
+ putchar('"');
+}
+
+CALLBACK(print_lineno) {
+ printf("%d ", lineno);
+}
+
+CALLBACK(print_cmd) {
+ int bad;
+ const char *name;
+
+ if(tok == CMD_ILET) return;
+
+ if(tok > last_command) {
+ bad = 1;
+ } else if( (name = commands[tok]) ) {
+ bad = 0;
+ } else {
+ bad = 1;
+ }
+
+ if(bad)
+ printf("(bad cmd token $%02x)", tok);
+ else
+ printf("%s ", name);
+}
+
+CALLBACK(print_op) {
+ int bad;
+ const char *name;
+
+ switch(tok) {
+ case OP_NUMCONST:
+ print_number(pos + 1);
+ return;
+ case OP_STRCONST:
+ print_string(pos + 2, program[pos + 1]);
+ return;
+ case OP_EOL:
+ return;
+ default: break;
+ }
+
+
+ if(tok > last_operator) {
+ bad = 1;
+ } else if( (name = operators[tok]) ) {
+ bad = 0;
+ } else {
+ bad = 1;
+ }
+
+ if(bad)
+ printf("(bad op token $%02x)", tok);
+ else
+ printf("%s", name);
+}
+
+CALLBACK(print_varname) {
+ int i, count;
+ unsigned char c;
+
+ tok &= 0x7f;
+ for(i = vnstart, count = 0; count < tok; i++) {
+ if(program[i] & 0x80) count++;
+ }
+ while(1) {
+ c = program[i++];
+ putchar(c & 0x7f);
+ if(c & 0x80) break;
+ }
+}
+
+CALLBACK(print_text) {
+ while(program[pos] != 0x9b) putchar(program[pos++]);
+}
+
+CALLBACK(print_newline) {
+ putchar('\n');
+}
+
+void list(void) {
+ on_start_line = print_lineno;
+ on_cmd_token = print_cmd;
+ on_exp_token = print_op;
+ on_var_token = print_varname;
+ on_end_line = print_newline;
+ on_text = print_text;
+ walk_code(0, 32767 + immediate);
+}
+
+int main(int argc, char **argv) {
+ set_self(*argv);
+ parse_general_args(argc, argv, print_help);
+ parse_args(argc, argv);
+
+ readfile();
+ parse_header();
+
+ list();
+
+ return 0;
+}