From f5f7603a55d4fbe9cda585f3464ace490627a6ed Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Mon, 3 Jun 2024 18:23:28 -0400 Subject: protbas: split off protection functions from unprotbas. --- bas.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 8 deletions(-) (limited to 'bas.c') diff --git a/bas.c b/bas.c index 64c4f3f..230032c 100644 --- a/bas.c +++ b/bas.c @@ -27,24 +27,50 @@ const char *self; unsigned char program[BUFSIZE]; FILE *input_file; FILE *output_file; +char *output_filename = NULL; void die(const char *msg) { fprintf(stderr, "%s: %s\n", self, msg); exit(1); } +void parse_general_args(int argc, char **argv, void (*helpfunc)()) { + if(argc < 2) { + (*helpfunc)(); + exit(1); + } + + if(strcmp(argv[1], "--help") == 0) { + (*helpfunc)(); + exit(0); + } + + if(strcmp(argv[1], "--version") == 0) { + printf("%s %s\n", self, VERSION); + exit(0); + } +} + /* read entire file into memory */ -int readfile(void) { - int got = fread(program, 1, BUFSIZE - 1, input_file); - if(verbose) fprintf(stderr, "Read %d bytes.\n", got); +void readfile(void) { + filelen = fread(program, 1, BUFSIZE - 1, input_file); + if(verbose) fprintf(stderr, "Read %d bytes.\n", filelen); if(!feof(input_file)) fprintf(stderr, "Warning: file is >64KB, way too big for a BASIC program.\n"); - else if(got > MAX_PROG_SIZE) - fprintf(stderr, "Warning: file is %d bytes, suspiciously large for a BASIC program.\n", got); + else if(filelen > MAX_PROG_SIZE) + fprintf(stderr, "Warning: file is %d bytes, suspiciously large for a BASIC program.\n", filelen); fclose(input_file); - if(got < MIN_PROG_SIZE) + if(filelen < MIN_PROG_SIZE) die("File too short to be a BASIC program (truncated?)\n"); - return got; +} + +int writefile(void) { + int outbytes; + + outbytes = fwrite(program, 1, filelen, output_file); + fclose(output_file); + if(verbose) fprintf(stderr, "Wrote %d bytes.\n", outbytes); + return outbytes; } /* get a 16-bit value from the file, in 6502 LSB/MSB order. */ @@ -76,6 +102,8 @@ void parse_header(void) { vvstart = vvtp - TBL_OFFSET; code_end = starp - TBL_OFFSET; + if(lomem) die("This doesn't look like an Atari BASIC program (no $0000 signature)."); + if(filelen < code_end) { fprintf(stderr, "Warning: file is truncated: %d bytes, should be %d.\n", filelen, code_end); } @@ -111,9 +139,9 @@ void move_code(int offset) { stmtab += offset; stmcur += offset; starp += offset; + filelen += offset; update_header(); parse_header(); - filelen += offset; } void adjust_vntable_size(int oldsize, int newsize) { @@ -127,6 +155,53 @@ void adjust_vntable_size(int oldsize, int newsize) { } } +/* return true if the variable name table is OK */ +int vntable_ok(void) { + int vp, bad; + + if(vntp == vntd) { + if(verbose) fprintf(stderr, "No variables.\n"); + return 1; + } + + /* first pass: bad = 1 if all the bytes in the table have the same + value, no matter what it is. */ + vp = vnstart + 1; + bad = 1; + while(vp < vvstart - 1) { + if(program[vp] != program[vnstart]) { + bad = 0; + break; + } + vp++; + } + if(bad) return 0; + + /* 2nd pass: bad = 1 if there's any invalid character in the table. */ + vp = vnstart; + while(vp < vvstart) { + unsigned char c = program[vp]; + + /* treat a null byte as end-of-table, ignore any junk between it and VNTP. */ + if(c == 0) break; + + vp++; + + /* inverse $ or ( is OK */ + if(c == 0xa4 || c == 0xa8) continue; + + /* numbers and letters are allowed, inverse or normal. */ + c &= 0x7f; + if(c >= 0x30 && c <= 0x39) continue; + if(c >= 0x41 && c <= 0x5a) continue; + + bad++; + break; + } + + return !bad; +} + void invalid_args(const char *arg) { fprintf(stderr, "%s: Invalid argument '%s'.\n\n", self, arg); exit(1); -- cgit v1.2.3