1 /* w2cas.c -- write file to cassette
3 ** This program writes a boot file (typically linked with
4 ** 'atari-cassette.cfg') to the cassette.
5 ** Only files < 32K are supported, since the loading of
6 ** larger files requires a special loader inside the program.
8 ** Christian Groessler, chris@groessler.org, 2014
19 static int verbose = 1;
20 static char C_dev[] = "C:";
22 static struct __iocb *findfreeiocb(void)
24 struct __iocb *iocb = &IOCB; /* first IOCB (#0) */
27 for (i = 0; i < 8; i++) {
28 if (iocb->handler == 0xff)
35 static void exitfn(void)
37 /* if DOS will automatically clear the screen, after the program exits, wait for a keypress... */
38 if (doesclrscrafterexit())
42 int main(int argc, char **argv)
47 unsigned char *buffer;
48 size_t filen, buflen = 32768l + 1;
50 struct __iocb *iocb = findfreeiocb();
56 fprintf(stderr, "couldn't find a free iocb\n");
59 iocb_num = (iocb - &IOCB) * 16;
61 printf("using iocb index $%02X ($%04X)\n", iocb_num, iocb);
64 printf("\nfilename: ");
65 x = fgets(buf, 19, stdin);
68 printf("empty filename, exiting...\n");
71 if (*x && *(x + strlen(x) - 1) == '\n')
72 *(x + strlen(x) - 1) = 0;
73 if (! strlen(x)) { /* empty filename */
74 printf("empty filename, exiting...\n");
84 buffer = malloc(buflen);
86 buflen = _heapmaxavail(); /* get as much as we can */
87 buffer = malloc(buflen);
89 fprintf(stderr, "cannot alloc %ld bytes -- aborting...\n", (long)buflen);
94 printf("buffer size: %ld bytes\n", (long)buflen);
97 file = fopen(filename, "rb");
100 fprintf(stderr, "cannot open '%s': %s\n", filename, strerror(errno));
104 /* read file -- file length must be < 32K */
106 printf("reading input file...\n");
107 filen = fread(buffer, 1, buflen, file);
109 fprintf(stderr, "read error\n");
115 if (filen > 32767l) {
116 fprintf(stderr, "file is too large (must be < 32768)\n");
119 if (filen == buflen) { /* we have a buffer < 32768 and the file fits into it (and is most probably larger) */
120 fprintf(stderr, "not enough memory\n");
124 printf("file size: %ld bytes\n", (long)filen);
126 /* close input file */
131 printf("opening cassette...\n");
132 iocb->buffer = C_dev;
133 iocb->aux1 = 8; /* open for output */
134 iocb->aux2 = 128; /* short breaks and no stop between data blocks */
135 iocb->command = IOCB_OPEN;
137 regs.pc = 0xe456; /* CIOV */
141 fprintf(stderr, "CIO call to open cassette returned %d\n", regs.y);
148 printf("writing to cassette...\n");
149 iocb->buffer = buffer;
150 iocb->buflen = filen;
151 iocb->command = IOCB_PUTCHR;
153 regs.pc = 0xe456; /* CIOV */
157 fprintf(stderr, "CIO call to write file returned %d\n", regs.y);
160 iocb->command = IOCB_CLOSE;
162 regs.pc = 0xe456; /* CIOV */
172 iocb->command = IOCB_CLOSE;
174 regs.pc = 0xe456; /* CIOV */
178 fprintf(stderr, "CIO call to close cassette returned %d\n", regs.y);