aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dla.atrbin92176 -> 92176 bytes
-rw-r--r--dla2csv.c295
-rw-r--r--dla2csv.xexbin10790 -> 10909 bytes
3 files changed, 129 insertions, 166 deletions
diff --git a/dla.atr b/dla.atr
index 1af905c..7266dca 100644
--- a/dla.atr
+++ b/dla.atr
Binary files differ
diff --git a/dla2csv.c b/dla2csv.c
index d8341a8..98d1173 100644
--- a/dla2csv.c
+++ b/dla2csv.c
@@ -33,13 +33,37 @@ void print_id(void) {
printf("DLA to CSV converter v" VERSION ".\n");
}
+char inbuf[INBUF_SIZE];
+char stringbuf[STRINGBUF_SIZE];
+FILE *inf, *outf;
+
+/* We can't use string literal syntax, cc65 "helpfully" turns "\x0a"
+ into an Atari 0x9b EOL character. Numeric constants are left alone. */
+char a8eol[] = { 0x9b, 0x00, 0x00 };
+char uxeol[] = { 0x0a, 0x00, 0x00 };
+char mseol[] = { 0x0d, 0x0a, 0x00 };
+char *eoltypes[][2] = {
+ { "Atari ($9B)", a8eol },
+ { "Unix (\\n)", uxeol },
+ { "MS (\\r\\n)", mseol },
+ { NULL, NULL }
+};
+
+char *eol; /* gets assigned one of the eoltypes */
+
+/* using a table of masks instead of calculating them saves maybe 2s
+ on the Atari. */
+unsigned char masks[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+
#ifdef __ATARI__
/* Uncomment this to see elapsed time in convert() */
#define PROFILE
-/* cc65 doesn't "localize" \b to the Atari backspace character, so: */
+/* cc65 doesn't "localize" \b to the Atari backspace character, like it
+ does for \n. If we needed it:
#define BS CH_DEL
+*/
/* I like these colors. Also they match dla.xex. */
#define TEXT_COLOR 0x0e
@@ -129,15 +153,20 @@ void print_id(void) {
printf("\n");
}
- /* Show disk directory, in a 3-column layout.
- drive is an ASCII digit, e.g. 0x31 is drive 1. */
- void show_dir(char drive) {
+ /* if the user enters a single digit, show directory of that drive.
+ in a 3-column layout. this is a no-op on non-Atari.
+ returns true if the user asked for a directory, false if not.
+ */
+ char show_dir(void) {
static char dirspec[16];
DIR *dir;
struct dirent *ent;
- char device = 'D';
+ char device = 'D', drive = stringbuf[0];
unsigned char column = 0;
+ if(!isdigit(drive))
+ return 0;
+
if(drive == '0') {
drive++;
device = 'H';
@@ -148,9 +177,10 @@ void print_id(void) {
if(!(dir = opendir(dirspec))) {
dirspec[2] = '\0';
PERROR(dirspec);
- return;
+ return 1;
}
+ errno = 0;
while((ent = readdir(dir))) {
printf("%-13s", ent->d_name);
if(++column == 3) {
@@ -158,9 +188,11 @@ void print_id(void) {
putchar('\n');
}
}
+ if(errno) PERROR(dirspec);
closedir(dir);
if(column) putchar('\n');
+ return 1;
}
void atari_exit(int status) {
@@ -180,47 +212,104 @@ void print_id(void) {
cc65's runtime, do not pass Go, do not collect $200). This seems to
work reliably, but I hesistate to document "Press Ctrl-3 to exit"...
- ...and it turns out that on SpartaDOS X, even this doesn't prevent
- the atari from locking up if the user presses ^3. Sigh.
+ ...and it turns out that on SpartaDOS X and other command-line DOSes,
+ the display list doesn't get fixed: jmp (DOSVEC) just gives you the
+ prompt, which expects the screen to still be usable... Sigh. Treat it
+ as the Reset key instead.
*/
- #define exit_eof_stdin() (*(OS.dosvec))()
+ void exit_eof_stdin(void) {
+ if(_is_cmdline_dos())
+ __asm__("jmp $e474"); /* cc65 doesn't define WARMSV for C */
+ else
+ (*(OS.dosvec))();
+ }
+
+ void backspace2(void) {
+ OS.colcrs -= 2;
+ }
+
+ void print_converting(void) {
+ printf("Press Ctrl-C to abort conversion.\n");
+ OS.crsinh = 1;
+ printf("\nConverting... %%");
+ putchar(0xa0);
+ backspace2();
+ }
+ #define enable_cursor() OS.crsinh = 0
+
+ char user_abort(void) {
+ return OS.ch == (KEY_C | KEY_CTRL);
+ }
+
+ void clear_keystroke(void) {
+ OS.ch = KEY_NONE;
+ }
+
+ #define REGISTER register
+
+ /* using utoa() rather than fprintf() saves ~12 sec on the Atari. */
+ void writepoint(unsigned char x, unsigned char y) {
+ static char ubuf[10];
+ static char fbuf[16];
+
+ utoa(x, fbuf, 10);
+ strcat(fbuf, ",");
+ strcat(fbuf, utoa(y, ubuf, 10));
+ strcat(fbuf, eol);
+ fputs(fbuf, outf);
+ }
+
+ /* if user entered a filename with no device spec (D: or D1: etc),
+ prepend D1:. this is a no-op on non-Atari. */
+ void fix_filename(void) {
+ if(!strchr(stringbuf, ':')) {
+ memmove(stringbuf+3, stringbuf, strlen(stringbuf) + 1);
+ stringbuf[0] = 'D';
+ stringbuf[1] = '1';
+ stringbuf[2] = ':';
+ }
+ }
+
+ #ifdef PROFILE
+ #define start_profile_clock() OS.rtclok[0] = OS.rtclok[1] = OS.rtclok[2] = 0
+ #define print_profile_clock() \
+ printf("\nElapsed time: %ds\n", ((OS.rtclok[1] << 8) | OS.rtclok[2]) / 60)
+ #else
+ #define start_profile_clock()
+ #define print_profile_clock()
+ #endif
#else
/* non-Atari is assumed to be POSIX (and not something like
Commodore or Apple II). */
#define BS '\b'
+ void backspace2(void) {
+ putchar(BS);
+ putchar(BS);
+ }
#define PERROR(x) perror(x)
#define print_banner() print_id()
#define noop()
#define enable_break() noop()
#define disable_break() noop()
+ #define enable_cursor() noop()
#define init_console() noop()
+ #define clear_keystroke() noop()
+ #define start_profile_clock() noop()
+ #define print_profile_clock() noop()
+ #define fix_filename() noop()
+ #define user_abort() 0
+ #define show_dir() 0
#define EXIT(x) exit(1)
#define exit_eof_stdin() exit(1)
+ #define print_converting() printf("\nConverting... %%")
+ #define REGISTER
+ /* since utoa() only exists on cc65, can't use it on non-Atari. */
+ void writepoint(unsigned char x, unsigned char y) {
+ fprintf(outf, "%d,%d%s", x, y, eol);
+ }
#endif
-char inbuf[INBUF_SIZE];
-char stringbuf[STRINGBUF_SIZE];
-FILE *inf, *outf;
-
-/* We can't use string literal syntax, cc65 "helpfully" turns "\x0a"
- into an Atari 0x9b EOL character. Numeric constants are left alone. */
-char a8eol[] = { 0x9b, 0x00, 0x00 };
-char uxeol[] = { 0x0a, 0x00, 0x00 };
-char mseol[] = { 0x0d, 0x0a, 0x00 };
-char *eoltypes[][2] = {
- { "Atari ($9B)", a8eol },
- { "Unix (\\n)", uxeol },
- { "MS (\\r\\n)", mseol },
- { NULL, NULL }
-};
-
-char *eol; /* gets assigned one of the eoltypes */
-
-/* using a table of masks instead of calculating them saves maybe 2s
- on the Atari. */
-unsigned char masks[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
-
/* Read a string from stdin (E: on the Atari).
Exit if we get EOF on stdin (e.g. ^D on Linux, ^3 on Atari).
See exit_eof_stdin() comments above.
@@ -273,22 +362,9 @@ FILE *prompt_filename(const char *name, const char *mode) {
continue;
}
-#ifdef __ATARI__
- /* if the user enters a single digit, show directory of that drive. */
- if(isdigit(stringbuf[0])) {
- show_dir(stringbuf[0]);
- continue;
- }
-
- /* if user entered a filename with no device spec (D: or D1: etc),
- prepend D: */
- if(!strchr(stringbuf, ':')) {
- memmove(stringbuf+2, stringbuf, strlen(stringbuf) + 1);
- stringbuf[0] = 'D';
- stringbuf[1] = ':';
- }
-#endif
+ if(show_dir()) continue;
+ fix_filename();
enable_break();
f = fopen(stringbuf, mode);
disable_break();
@@ -327,17 +403,6 @@ char *prompt_eol(void) {
return eoltypes[i][1];
}
-#ifdef __ATARI__
-void backspace2(void) {
- OS.colcrs -= 2;
-}
-#else
-void backspace2(void) {
- putchar(BS);
- putchar(BS);
-}
-#endif
-
/* check_dla() returns 1 if all is well, 0 if there's a problem. */
int check_dla(int bytes) {
int i, ok = 1;
@@ -386,82 +451,6 @@ int read_file(void) {
return bytes;
}
-#if 0
-/* convert() returns the number of particles on success, 0 on failure. */
-int convert(char *eol) {
- div_t d;
- unsigned int particles;
-#ifdef __ATARI__
- register
-#endif
- unsigned int i;
- unsigned char j, x, pct = 0;
-
- outf = prompt_filename("Output CSV", "wb");
-#ifdef __ATARI__
- printf("Press Ctrl-C to abort conversion.\n");
-#endif
- printf("\nConverting... ");
- fprintf(outf, "x,y%s", eol);
-
- for(i = 0; i < INBUF_SIZE; ++i) {
- if(i % 38 == 0) {
- backspace3();
- printf("%02d%%", pct++);
- fflush(stdout);
- }
- if(inbuf[i]) {
- d = div(i, 22);
- x = d.rem * 8;
- for(j = 0; j < 8; ++x, ++j) {
- if(inbuf[i] & masks[j]) {
- if(fprintf(outf, "%d,%d%s", x, d.quot, eol) < 0) {
- putchar('\n');
- PERROR(stringbuf);
- fclose(outf);
- remove(stringbuf);
- return 0;
- }
- particles++;
- }
- }
- }
- }
-
- fclose(outf);
-
-
- return particles;
-}
-#endif
-
-#ifdef __ATARI__
-/* using utoa() rather than fprintf() saves ~12 sec on the Atari. */
-void writepoint(unsigned char x, unsigned char y) {
- static char ubuf[10];
- static char fbuf[16];
-
- utoa(x, fbuf, 10);
- strcat(fbuf, ",");
- strcat(fbuf, utoa(y, ubuf, 10));
- strcat(fbuf, eol);
- fputs(fbuf, outf);
- /*
- utoa(x, buf, 10);
- fputs(buf, outf);
- fputc(',', outf);
- utoa(y, buf, 10);
- fputs(buf, outf);
- fputs(eol, outf);
- */
-}
-#else
-/* since utoa() only exists on cc65, can't use it on non-Atari. */
-void writepoint(unsigned char x, unsigned char y) {
- fprintf(outf, "%d,%d%s", x, y, eol);
-}
-#endif
-
/* currently, on the 800 with atariserver, convert() takes:
5s for a DLA with no points (a file of zeroes).
16s for a DLA with 1000 points.
@@ -469,23 +458,12 @@ void writepoint(unsigned char x, unsigned char y) {
*/
int convert(void) {
unsigned char x, y, j, pixx;
-#ifdef __ATARI__
- register
-#endif
- char *inp = inbuf;
+ REGISTER char *inp = inbuf;
int particles = 0;
outf = prompt_filename("Output CSV", "wb");
-#ifdef __ATARI__
- printf("Press Ctrl-C to abort conversion.\n");
- OS.crsinh = 1;
-#endif
- printf("\nConverting... %%");
-#ifdef __ATARI__
- putchar(0xa0);
- backspace2();
-#endif
+ print_converting();
/* CSV file header row (column names) */
fprintf(outf, "x,y%s", eol);
@@ -494,16 +472,13 @@ int convert(void) {
/* loop over all the pixels, by row, then column. this
loop is rather slow. */
for(y = 0; y < HEIGHT; ++y) {
-#ifdef __ATARI__
- /* check for ^C */
- if(OS.ch == (KEY_C | KEY_CTRL)) {
+ if(user_abort()) {
printf("\nUser abort!\n");
fclose(outf);
remove(stringbuf);
- OS.ch = KEY_NONE;
+ clear_keystroke();
return 0;
}
-#endif
backspace2();
printf("%02d", y * 100 / HEIGHT); /* percentage */
fflush(stdout);
@@ -528,9 +503,7 @@ int convert(void) {
}
fclose(outf);
-#ifdef __ATARI__
- OS.crsinh = 0;
-#endif
+ enable_cursor();
return particles;
}
@@ -560,12 +533,7 @@ int main(int argc, char **argv) {
without re-reading the input file. */
done = 0;
while(!done) {
-
-#ifdef __ATARI__
- #ifdef PROFILE
- OS.rtclok[0] = OS.rtclok[1] = OS.rtclok[2] = 0;
- #endif
-#endif
+ start_profile_clock();
result = convert();
@@ -573,18 +541,13 @@ int main(int argc, char **argv) {
done = 1;
backspace2();
printf("100%%\n%d particles.\n", result);
+ print_profile_clock();
} else {
if(!prompt_yn("Conversion failed, try again", 1))
done = 1;
}
}
-#ifdef __ATARI__
- #ifdef PROFILE
- printf("\nElapsed time: %ds\n", ((OS.rtclok[1] << 8) | OS.rtclok[2]) / 60);
- #endif
-#endif
-
if(!prompt_yn("\nConvert another file", 1))
break;
}
diff --git a/dla2csv.xex b/dla2csv.xex
index 41b117c..fe0eb4e 100644
--- a/dla2csv.xex
+++ b/dla2csv.xex
Binary files differ