From 60322f95cb27d13d35d2b142ebbfed5b3f570049 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sun, 23 Apr 2017 22:43:35 -0400 Subject: [PATCH 1/5] asoft_detoken: clean up whitespace, add command line args --- asoft_basic-utils/asoft_detoken.c | 147 ++++++++++++++++++------------ 1 file changed, 91 insertions(+), 56 deletions(-) diff --git a/asoft_basic-utils/asoft_detoken.c b/asoft_basic-utils/asoft_detoken.c index fcc4ec45..e5af3858 100644 --- a/asoft_basic-utils/asoft_detoken.c +++ b/asoft_basic-utils/asoft_detoken.c @@ -1,10 +1,14 @@ +/* asoft_detoken: detokenize an applesoft BASIC program */ +/* by Vince Weaver (vince@deater.net) */ + #include #include /* strlen() */ +#include /* getopt() */ #include "version.h" /* Starting at 0x80 */ char applesoft_tokens[][8]={ - + /* 80 */ "END","FOR","NEXT","DATA","INPUT","DEL","DIM","READ", /* 88 */ "GR","TEXT","PR #","IN #","CALL","PLOT","HLIN","VLIN", /* 90 */ "HGR2","HGR","HCOLOR=","HPLOT","DRAW","XDRAW","HTAB","HOME", @@ -24,61 +28,92 @@ char applesoft_tokens[][8]={ }; int main(int argc, char **argv) { - - int ch1,i; - int size1,size2; - int line1,line2; - int link1,link2,link; - int debug=0; - int offset=0x801; - - /* read size, first two bytes */ - size1=fgetc(stdin); - size2=fgetc(stdin); - - if (debug) fprintf(stderr,"File size: %x %x\n",size1,size2); - while(!feof(stdin)) { - - /* link points to the next line */ - /* assumes asoft program starts at address $801 */ - link1=fgetc(stdin); - link2=fgetc(stdin); - link=(link2<<8)|link1; - offset+=2; + int ch1,i; + int size1,size2; + int line1,line2; + int link1,link2,link; + int debug=0,print_link=0; + int offset=0x801; + int c; + FILE *fff; - /* link==0 indicates EOF */ - if (link==0) goto the_end; - - /* line number is little endian 16-bit value */ - line1=fgetc(stdin); - line2=fgetc(stdin); - if (feof(stdin)) goto the_end; - printf("%4d ",((line2)<<8)+line1); - offset+=2; - - /* repeat until EOL character (0) */ - while( (ch1=fgetc(stdin))!=0 ) { - offset++; - /* if > 0x80 it's a token */ - if (ch1>=0x80) { - fputc(' ',stdout); - for(i=0;i 0x80 it's a token */ + if (ch1>=0x80) { + fputc(' ',stdout); + for(i=0;i Date: Sun, 23 Apr 2017 22:53:20 -0400 Subject: [PATCH 2/5] tokenize_asoft: add command line parser --- asoft_basic-utils/tokenize_asoft.c | 50 +++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/asoft_basic-utils/tokenize_asoft.c b/asoft_basic-utils/tokenize_asoft.c index 9d92c6e0..d180280b 100644 --- a/asoft_basic-utils/tokenize_asoft.c +++ b/asoft_basic-utils/tokenize_asoft.c @@ -1,6 +1,10 @@ +/* tokenize_asoft: Tokenize an Applesoft BASIC program */ +/* by Vince Weaver */ + #include #include /* strlen() */ #include /* exit() */ +#include /* getopt() */ #include "version.h" @@ -9,13 +13,13 @@ /* Info from http://docs.info.apple.com/article.html?coll=ap&artnum=57 */ -/* In memory, applesoft file starts at address $801 */ -/* format is $00$00 */ -/* Where is: */ -/* 2 bytes (little endian) of LINK indicating addy of next line */ -/* 2 bytes (little endian) giving the line number */ -/* a series of bytes either ASCII or tokens (see below) */ -/* a $0 char indicating end of line */ +/* In memory, applesoft file starts at address $801 */ +/* format is $00$00 */ +/* Where is: */ +/* 2 bytes (little endian) of LINK indicating addy of next line */ +/* 2 bytes (little endian) giving the line number */ +/* a series of bytes either ASCII or tokens (see below) */ +/* a $0 char indicating end of line */ #define NUM_TOKENS 107 @@ -169,10 +173,36 @@ int main(int argc, char **argv) { int linenum=0,lastline=0,link_offset; int link_value=0x801; /* start of applesoft program */ int token; + int debug=0; + int c; + FILE *fff; + + /* Check command line arguments */ + while ((c = getopt (argc, argv,"d"))!=-1) { + switch (c) { + + case 'd': + debug=1; + break; + } + } + + /* No file specified, used stdin */ + if (optind==argc) { + fff=stdin; + } + else { + fff=fopen(argv[optind],"r"); + if (fff==NULL) { + fprintf(stderr,"Error, could not open %s\n",argv[optind]); + return -1; + } + if (debug) fprintf(stderr,"Opened file %s\n",argv[optind]); + } while(1) { /* get line from input file */ - line_ptr=fgets(input_line,BUFSIZ,stdin); + line_ptr=fgets(input_line,BUFSIZ,fff); line++; if (line_ptr==NULL) break; @@ -180,7 +210,7 @@ int main(int argc, char **argv) { if (line_ptr[0]=='\'') { if (!strncmp(line_ptr,"\'.if 0",6)) { while(1) { - line_ptr=fgets(input_line,BUFSIZ,stdin); + line_ptr=fgets(input_line,BUFSIZ,fff); line++; if (line_ptr==NULL) break; if (!strncmp(line_ptr,"\'.endif",7)) break; @@ -192,8 +222,6 @@ int main(int argc, char **argv) { /* VMW extension: use leading ' as a comment char */ if (line_ptr[0]=='\'') continue; - - /* skip empty lines */ if (line_ptr[0]=='\n') continue; From 3cfcf85a3a93de151f8b5aa8c6c059591b60624c Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sun, 23 Apr 2017 23:24:30 -0400 Subject: [PATCH 3/5] tokenize_asoft: add support for manually setting offset --- asoft_basic-utils/asoft_detoken.c | 2 +- asoft_basic-utils/tokenize_asoft.c | 51 ++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/asoft_basic-utils/asoft_detoken.c b/asoft_basic-utils/asoft_detoken.c index e5af3858..d5f02fd4 100644 --- a/asoft_basic-utils/asoft_detoken.c +++ b/asoft_basic-utils/asoft_detoken.c @@ -80,7 +80,7 @@ int main(int argc, char **argv) { link=(link2<<8)|link1; offset+=2; - if (print_link) printf("%04X:",link); + if (print_link) printf("*%04X",link); /* link==0 indicates EOF */ if (link==0) goto the_end; diff --git a/asoft_basic-utils/tokenize_asoft.c b/asoft_basic-utils/tokenize_asoft.c index d180280b..2f8d5dfe 100644 --- a/asoft_basic-utils/tokenize_asoft.c +++ b/asoft_basic-utils/tokenize_asoft.c @@ -8,6 +8,8 @@ #include "version.h" +static int debug=0; + /* TODO */ /* match lowercase tokens as well as upper case ones */ @@ -65,13 +67,37 @@ static void show_problem(char *line_ptr) { fprintf(stderr,"^\n"); } -static int getnum(void) { +static int get_line_num(int *linenum, int *custom_offset) { int num=0; + int offset=0; /* skip any whitespace */ while((*line_ptr<=' ') && (*line_ptr!=0)) line_ptr++; + /* Custom Offset */ + if (*line_ptr=='*') { + line_ptr++; + while(*line_ptr>' ') { + if ((*line_ptr>='0')&&(*line_ptr<='9')) { + offset*=16; + offset+=(*line_ptr)-'0'; + } else if ((*line_ptr>='A')&&(*line_ptr<='F')) { + offset*=16; + offset+=(*line_ptr)-'A'+10; + } + else { + fprintf(stderr,"Invalid offset line %d\n",line); + show_problem(line_ptr); + exit(-1); + } + line_ptr++; + } + + /* Skip whitespace */ + while((*line_ptr<=' ') && (*line_ptr!=0)) line_ptr++; + } + while (*line_ptr>' ') { if ((*line_ptr<'0')||(*line_ptr>'9')) { fprintf(stderr,"Invalid line number line %d\n",line); @@ -88,6 +114,13 @@ static int getnum(void) { exit(-1); } + if (linenum) *linenum=num; + if (custom_offset) { + *custom_offset=offset; + if (debug) fprintf(stderr,"CO=%x\n",offset); + + } + return num; } @@ -170,10 +203,9 @@ int main(int argc, char **argv) { int offset=2,i; - int linenum=0,lastline=0,link_offset; + int linenum=0,custom_offset=0,lastline=0,link_offset; int link_value=0x801; /* start of applesoft program */ int token; - int debug=0; int c; FILE *fff; @@ -225,7 +257,7 @@ int main(int argc, char **argv) { /* skip empty lines */ if (line_ptr[0]=='\n') continue; - linenum=getnum(); + get_line_num(&linenum,&custom_offset); if ((linenum>65535) || (linenum<0)) { fprintf(stderr,"Invalid line number %d\n",linenum); exit(-1); @@ -246,6 +278,7 @@ int main(int argc, char **argv) { while(1) { token=find_token(); output[offset]=token; + if (debug) fprintf(stderr,"%2X ",token); offset++; check_oflo(offset); if (!token) break; @@ -259,8 +292,14 @@ int main(int argc, char **argv) { /* point link value to next line */ check_oflo(offset+2); - output[link_offset]=LOW(link_value); - output[link_offset+1]=HIGH(link_value); + if (custom_offset) { + output[link_offset]=LOW(custom_offset); + output[link_offset+1]=HIGH(custom_offset); + } + else { + output[link_offset]=LOW(link_value); + output[link_offset+1]=HIGH(link_value); + } } /* set last link field to $00 $00 which indicates EOF */ check_oflo(offset+2); From 38994ef9a8e11f6d1d7f52ec03fb618568557843 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sun, 23 Apr 2017 23:46:18 -0400 Subject: [PATCH 4/5] asoft-detoken: don't print trailing space on REM this makes the output of detoken match input of token --- asoft_basic-utils/asoft_detoken.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/asoft_basic-utils/asoft_detoken.c b/asoft_basic-utils/asoft_detoken.c index d5f02fd4..fc96a77d 100644 --- a/asoft_basic-utils/asoft_detoken.c +++ b/asoft_basic-utils/asoft_detoken.c @@ -97,11 +97,13 @@ int main(int argc, char **argv) { offset++; /* if > 0x80 it's a token */ if (ch1>=0x80) { + /* Leading space */ fputc(' ',stdout); for(i=0;i Date: Mon, 24 Apr 2017 08:10:29 -0400 Subject: [PATCH 5/5] deceptive_listings: messing around with basic listings though it turns out that DOS re-interprets programs you load so manually messing with the line offsets is lost if you do it in advance --- deceptive_list/Makefile | 14 ++++++++++++++ deceptive_list/deceptive.dsk | Bin 0 -> 143360 bytes deceptive_list/hidden.bas | 11 +++++++++++ deceptive_list/hidden.basd | 21 +++++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 deceptive_list/Makefile create mode 100644 deceptive_list/deceptive.dsk create mode 100644 deceptive_list/hidden.bas create mode 100644 deceptive_list/hidden.basd diff --git a/deceptive_list/Makefile b/deceptive_list/Makefile new file mode 100644 index 00000000..5a92cce3 --- /dev/null +++ b/deceptive_list/Makefile @@ -0,0 +1,14 @@ +DOS33 = ../dos33fs-utils/dos33 +TXT2BAS = ../asoft_basic-utils/tokenize_asoft + +all: deceptive.dsk + +BACKWARD.BAS: backward.basd + $(TXT2BAS) < backward.basd > BACKWARD.BAS + +deceptive.dsk: BACKWARD.BAS + $(DOS33) -y deceptive.dsk SAVE A BACKWARD.BAS + +clean: + rm -f *~ *.BAS *.SHAPE sound_test.bas shape_test.bas *.lst + diff --git a/deceptive_list/deceptive.dsk b/deceptive_list/deceptive.dsk new file mode 100644 index 0000000000000000000000000000000000000000..40a9ab1f4e18dfed1717e7437ac07d6631f1b4a6 GIT binary patch literal 143360 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