aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2022-11-10 13:11:44 -0500
committerB. Watson <urchlay@slackware.uk>2022-11-10 13:11:44 -0500
commitfff4e5a818e6fe74c0d2e322a0feb447f9de722d (patch)
tree1631ad07ee4ac0bd194f14d719126e18f7e0c576
parentf14004fcd8c795bfab14d7c7f2fc9bba0ba2a217 (diff)
downloaddla-asm-fff4e5a818e6fe74c0d2e322a0feb447f9de722d.tar.gz
Report write errors in dla2csv, add disk and disktest make targets.
-rw-r--r--Makefile9
-rw-r--r--dla2csv.c142
2 files changed, 100 insertions, 51 deletions
diff --git a/Makefile b/Makefile
index 802a2bd..a1f119f 100644
--- a/Makefile
+++ b/Makefile
@@ -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 $@ $<
diff --git a/dla2csv.c b/dla2csv.c
index 734ec57..fea78d6 100644
--- a/dla2csv.c
+++ b/dla2csv.c
@@ -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;
}
}