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
20 static int verbose = 1;
21 static char C_dev[] = "C:";
23 static struct __iocb *findfreeiocb(void)
27 for (i = 0; i < 8; i++) {
28 if (OS.iocb[i].handler == 0xff)
34 int main(int argc, char **argv)
39 unsigned char *buffer;
40 size_t filen, buflen = 32768l + 1;
42 struct __iocb *iocb = findfreeiocb();
45 /* if DOS will automatically clear the screen after the program exits, wait for a keypress... */
46 if (doesclrscrafterexit())
47 atexit((void (*)(void))cgetc);
50 fprintf(stderr, "couldn't find a free iocb\n");
53 iocb_num = (iocb - OS.iocb) * 16;
55 printf("using iocb index $%02X ($%04X)\n", iocb_num, iocb);
58 printf("\nfilename: ");
59 x = fgets(buf, 19, stdin);
62 printf("empty filename, exiting...\n");
65 if (*x && *(x + strlen(x) - 1) == '\n')
66 *(x + strlen(x) - 1) = 0;
67 if (! strlen(x)) { /* empty filename */
68 printf("empty filename, exiting...\n");
78 buffer = malloc(buflen);
80 buflen = _heapmaxavail(); /* get as much as we can */
81 buffer = malloc(buflen);
83 fprintf(stderr, "cannot alloc %ld bytes -- aborting...\n", (long)buflen);
88 printf("buffer size: %ld bytes\n", (long)buflen);
91 file = fopen(filename, "rb");
94 fprintf(stderr, "cannot open '%s': %s\n", filename, strerror(errno));
98 /* read file -- file length must be < 32K */
100 printf("reading input file...\n");
101 filen = fread(buffer, 1, buflen, file);
103 fprintf(stderr, "read error\n");
109 if (filen > 32767l) {
110 fprintf(stderr, "file is too large (must be < 32768)\n");
113 if (filen == buflen) { /* we have a buffer < 32768 and the file fits into it (and is most probably larger) */
114 fprintf(stderr, "not enough memory\n");
118 printf("file size: %ld bytes\n", (long)filen);
120 /* close input file */
125 printf("opening cassette...\n");
126 iocb->buffer = C_dev;
127 iocb->aux1 = 8; /* open for output */
128 iocb->aux2 = 128; /* short breaks and no stop between data blocks */
129 iocb->command = IOCB_OPEN;
131 regs.pc = 0xe456; /* CIOV */
135 fprintf(stderr, "CIO call to open cassette returned %d\n", regs.y);
142 printf("writing to cassette...\n");
143 iocb->buffer = buffer;
144 iocb->buflen = filen;
145 iocb->command = IOCB_PUTCHR;
147 regs.pc = 0xe456; /* CIOV */
151 fprintf(stderr, "CIO call to write file returned %d\n", regs.y);
154 iocb->command = IOCB_CLOSE;
156 regs.pc = 0xe456; /* CIOV */
166 iocb->command = IOCB_CLOSE;
168 regs.pc = 0xe456; /* CIOV */
172 fprintf(stderr, "CIO call to close cassette returned %d\n", regs.y);