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 int main(int argc, char **argv)
40 unsigned char *buffer;
41 size_t filen, buflen = 32768l + 1;
43 struct __iocb *iocb = findfreeiocb();
47 fprintf(stderr, "couldn't find a free iocb\n");
48 if (! _is_cmdline_dos())
52 iocb_num = (iocb - &IOCB) * 16;
54 printf("using iocb index $%02X ($%04X)\n", iocb_num, iocb);
57 printf("\nfilename: ");
58 x = fgets(buf, 19, stdin);
61 printf("empty filename, exiting...\n");
62 if (! _is_cmdline_dos())
66 if (*x && *(x + strlen(x) - 1) == '\n')
67 *(x + strlen(x) - 1) = 0;
68 if (! strlen(x)) { /* empty filename */
69 printf("empty filename, exiting...\n");
70 if (! _is_cmdline_dos())
81 buffer = malloc(buflen);
83 buflen = _heapmaxavail(); /* get as much as we can */
84 buffer = malloc(buflen);
86 fprintf(stderr, "cannot alloc %ld bytes -- aborting...\n", (long)buflen);
87 if (! _is_cmdline_dos())
93 printf("buffer size: %ld bytes\n", (long)buflen);
96 file = fopen(filename, "rb");
99 fprintf(stderr, "cannot open '%s': %s\n", filename, strerror(errno));
100 if (! _is_cmdline_dos())
105 /* read file -- file length must be < 32K */
107 printf("reading input file...\n");
108 filen = fread(buffer, 1, buflen, file);
110 fprintf(stderr, "read error\n");
114 if (! _is_cmdline_dos())
118 if (filen > 32767l) {
119 fprintf(stderr, "file is too large (must be < 32768)\n");
122 if (filen == buflen) { /* we have a buffer < 32768 and the file fits into it (and is most probably larger) */
123 fprintf(stderr, "not enough memory\n");
127 printf("file size: %ld bytes\n", (long)filen);
129 /* close input file */
134 printf("opening cassette...\n");
135 iocb->buffer = C_dev;
136 iocb->aux1 = 8; /* open for output */
137 iocb->aux2 = 128; /* short breaks and no stop between data blocks */
138 iocb->command = IOCB_OPEN;
140 regs.pc = 0xe456; /* CIOV */
144 fprintf(stderr, "CIO call to open cassette returned %d\n", regs.y);
146 if (! _is_cmdline_dos())
153 printf("writing to cassette...\n");
154 iocb->buffer = buffer;
155 iocb->buflen = filen;
156 iocb->command = IOCB_PUTCHR;
158 regs.pc = 0xe456; /* CIOV */
162 fprintf(stderr, "CIO call to write file returned %d\n", regs.y);
165 iocb->command = IOCB_CLOSE;
167 regs.pc = 0xe456; /* CIOV */
170 if (! _is_cmdline_dos())
179 iocb->command = IOCB_CLOSE;
181 regs.pc = 0xe456; /* CIOV */
185 fprintf(stderr, "CIO call to close cassette returned %d\n", regs.y);
186 if (! _is_cmdline_dos())
193 if (! _is_cmdline_dos())