diff options
author | B. Watson <urchlay@slackware.uk> | 2022-11-10 13:11:44 -0500 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2022-11-10 13:11:44 -0500 |
commit | fff4e5a818e6fe74c0d2e322a0feb447f9de722d (patch) | |
tree | 1631ad07ee4ac0bd194f14d719126e18f7e0c576 | |
parent | f14004fcd8c795bfab14d7c7f2fc9bba0ba2a217 (diff) | |
download | dla-asm-fff4e5a818e6fe74c0d2e322a0feb447f9de722d.tar.gz |
Report write errors in dla2csv, add disk and disktest make targets.
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | dla2csv.c | 142 |
2 files changed, 100 insertions, 51 deletions
@@ -24,6 +24,12 @@ dla2csv: dla2csv.c $(CC) $(CFLAGS) -o dla2csv dla2csv.c \ || echo "Couldn't build host dla2csv; continuing without it" +disk: drive1.atr + +drive1.atr: all + axe -w dla.xex drive1.atr + axe -w dla2csv.xex drive1.atr + clean: rm -f dla.xex dla2csv dla2csv.xex dla.list dla.labels *.o @@ -33,6 +39,9 @@ distclean: clean test: all atari800 dla.xex +disktest: disk + atari800 drive1.atr + %.xex: %.s $(CL65) $(CL65FLAGS) -t none -o $@ $< @@ -5,6 +5,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <errno.h> #define HEIGHT 170 #define WIDTH 256 @@ -14,6 +15,8 @@ ...it has to be a *constant*. */ #define INBUF_SIZE 5440 +#define STRINGBUF_SIZE 256 + /* cc65 doesn't "localize" \b to the Atari backspace character, so: */ #ifdef __ATARI__ #define BS '\x7e' @@ -22,11 +25,9 @@ #endif char inbuf[INBUF_SIZE]; - +char stringbuf[STRINGBUF_SIZE]; FILE *inf, *outf; -char stringbuf[256]; - /* don't use "\n" or "\r\n" on the right hand side, use explicit hex codes, to avoid cc65 tampering with them. */ char *eoltypes[][2] = { @@ -37,9 +38,14 @@ char *eoltypes[][2] = { }; /* read a string from stdin (E: on the Atari). - exit on EOF (or Break key on the Atari). */ + exit on EOF (or Break key on the Atari). + on DOS 2.0S, we end up back at the DUP menu... but + SpartaDOS 3.2d locks up with a black screen. so don't + suggest using this... + */ void readstring(void) { - if(fgets(stringbuf, 256, stdin) == NULL) + memset(stringbuf, 0, STRINGBUF_SIZE); + if(fgets(stringbuf, STRINGBUF_SIZE - 1, stdin) == NULL) exit(1); } @@ -58,7 +64,7 @@ FILE *prompt_filename(const char *name, const char *mode) { #ifdef __ATARI__ /* if there's no device spec (D: or D1: etc), prepend D: */ if(!strchr(stringbuf, ':')) { - memmove(stringbuf+2, stringbuf, strlen(stringbuf)); + memmove(stringbuf+2, stringbuf, strlen(stringbuf) + 1); stringbuf[0] = 'D'; stringbuf[1] = ':'; } @@ -69,6 +75,29 @@ FILE *prompt_filename(const char *name, const char *mode) { return f; } +int prompt_yn(char *prompt, int default_y) { + char *yn = "y/N"; + if(default_y) yn = "Y/n"; + + printf("%s[%s]? ", prompt, yn); + fflush(stdout); + readstring(); + + switch(stringbuf[0]) { + case 'y': + case 'Y': + return 1; + break; + case 'n': + case 'N': + return 0; + break; + default: + break; + } + return default_y; +} + /* prompt for and read EOL type, retry if needed. will not return until a valid number was entered. */ char *prompt_eol(void) { @@ -104,7 +133,7 @@ void backspace3(void) { int main(int argc, char **argv) { char *inp, *eol; - int i, bytes = 0, x, y, xmask, warn; + int i, bytes = 0, x, y, xmask, err; #ifdef __ATARI__ /* cc65's startup code turns off caps lock. turn it back on, @@ -118,13 +147,8 @@ int main(int argc, char **argv) { printf("DLA to CSV converter.\n\n"); -#ifdef __ATARI__ - /* Atari users aren't used to typing an EOF to exit */ - printf("Note: Press Ctrl-3 or Break at any\nprompt to exit this program.\n"); -#endif - while(1) { - warn = 0; + err = 0; /* in case of short read on 2nd or later conversion: */ memset(inbuf, 0, INBUF_SIZE); @@ -143,10 +167,10 @@ int main(int argc, char **argv) { /* warn if the file size is wrong... */ if(bytes < INBUF_SIZE) { printf("Warning: File too short!\n"); - warn = 1; + err = 1; } else if(fgetc(inf) != EOF) { printf("Warning: File too long!\n"); - warn = 1; + err = 1; } else { printf("File size is OK.\n"); } @@ -156,59 +180,75 @@ int main(int argc, char **argv) { for(i = 0; i < 32; i++) { if(inbuf[i]) { printf("Warning: File doesn't look like a DLA!\n"); - warn = 1; + err = 1; break; } } /* if anything looks wrong, we shouldn't proceed... but the user is boss, so give him the choice to shoot himself in the foot. */ - if(warn) { - printf("Try to convert anyway[y/N]? "); - fflush(stdout); - readstring(); - if(stringbuf[0] != 'y' && stringbuf[0] != 'Y') + if(err) { + if(!prompt_yn("Try to convert anyway", 0)) continue; } eol = prompt_eol(); - outf = prompt_filename("Output CSV", "wb"); - - printf("\nConverting... "); - fflush(stdout); + /* convert in a loop. in case of write error, this allows retry + without re-reading the input file. */ + i = err = 0; + while(!i) { + outf = prompt_filename("Output CSV", "wb"); - /* CSV file header row (column names) */ - fprintf(outf, "x,y%s", eol); - - /* write output file one line at a time */ - inp = inbuf; - xmask = 0x80; - bytes = 0; - for(y = 0; y < HEIGHT; y++) { - backspace3(); - printf("%02d%%", y * 100 / HEIGHT); /* percentage */ + printf("\nConverting... "); fflush(stdout); - for(x = 0; x < WIDTH; x++) { - if(*inp & xmask) { - fprintf(outf, "%d,%d%s", x, y, eol); - bytes++; - } - xmask >>= 1; - if(!xmask) { - xmask = 0x80; - inp++; + + /* CSV file header row (column names) */ + fprintf(outf, "x,y%s", eol); + + /* write output file one line at a time */ + inp = inbuf; + xmask = 0x80; + bytes = 0; + for(y = 0; y < HEIGHT; y++) { + backspace3(); + printf("%02d%%", y * 100 / HEIGHT); /* percentage */ + fflush(stdout); + for(x = 0; x < WIDTH; x++) { + if(*inp & xmask) { + if(fprintf(outf, "%d,%d%s", x, y, eol) < 0) { + #ifdef __ATARI__ + /* dirty hack alert: cc65 gives us the + wrong error here, when the disk fills up. */ + if(errno == EBADF) errno = ENOSPC; + #endif + printf("errno is %d\n", errno); + perror(stringbuf); + err = 1; + break; + } + bytes++; + } + xmask >>= 1; + if(!xmask) { + xmask = 0x80; + inp++; + } } + if(err) break; + } + fclose(outf); + if(err) { + if(!prompt_yn("Conversion failed, try again", 1)) + i = 1; + } else { + i = 1; + backspace3(); + printf("100%%\n%d particles.\n", bytes); } } - fclose(outf); - backspace3(); - printf("100%%\n%d particles.\n", bytes); - printf("\nConvert another file[Y/n]? "); - fflush(stdout); - readstring(); - if(stringbuf[0] == 'n' || stringbuf[0] == 'N') + if(!prompt_yn("\nConvert another file", 1)) return 0; } } |