aboutsummaryrefslogtreecommitdiff
path: root/src/io.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-11-13 05:39:38 -0500
committerB. Watson <urchlay@slackware.uk>2025-11-13 05:39:38 -0500
commite2da2bffe58a76c091d3496bd3ca2d2f18ea2eb6 (patch)
tree5195b221457842d781fadcb94331c93058046744 /src/io.c
downloadunalf-e2da2bffe58a76c091d3496bd3ca2d2f18ea2eb6.tar.gz
initial commit
Diffstat (limited to 'src/io.c')
-rw-r--r--src/io.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/io.c b/src/io.c
new file mode 100644
index 0000000..9b8e40e
--- /dev/null
+++ b/src/io.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <f65.h>
+#include "unalf.h"
+#include "addrs.h"
+
+static int headers_read = 0;
+
+static void die_arc(void) {
+ fprintf(stderr, "%s: this is an ARC file, not ALF\n", self);
+ exit(1);
+}
+
+static void die_not_alf(void) {
+ fprintf(stderr, "%s: not an ALF file\n", self);
+ exit(1);
+}
+
+static void eof_junk(void) {
+ fprintf(stderr, "%s: junk at EOF (ignoring)\n", self);
+}
+
+/* return 1 if a header is read, 0 if not */
+int read_alf_header(void) {
+ u8 h1, h2;
+ int bytes;
+
+ bytes = fread(mem + alf_header, 1, 29, in_file);
+
+ if(!bytes) {
+ if(headers_read)
+ return 0;
+ else
+ die_not_alf();
+ } else if(bytes < 29) {
+ if(headers_read) {
+ eof_junk();
+ return 0;
+ } else {
+ die_not_alf();
+ }
+ }
+
+ h1 = mem[alf_header];
+ h2 = mem[alf_hdr_sig];
+
+ if(h1 == 0x1a) {
+ if(h2 < 0x0f) die_arc();
+ if(h2 == 0x0f) {
+ headers_read++;
+ return 1; /* signature matches */
+ }
+ }
+
+ if(headers_read)
+ eof_junk();
+ else
+ die_not_alf();
+
+ return 0;
+}
+
+/* read buf_len_l/h bytes into buf_adr_l/h, then store the number
+ of bytes actually read in buf_len_l/h. TODO: what about EOF? */
+void readblock(void) {
+ int bytes, len, bufadr;
+ u8 *buf;
+
+ bufadr = dpeek(buf_adr_l);
+ buf = mem + bufadr;
+ len = dpeek(buf_len_l);
+
+ // fprintf(stderr, "readblock, bufadr = $%04x, len = $%04x\n", bufadr, len);
+
+ bytes = fread(buf, 1, len, in_file);
+ dpoke(buf_len_l, bytes);
+}
+
+/* mirror of readblock() */
+void writeblock(void) {
+ int bytes, len, bufadr;
+ u8 *buf;
+
+ bufadr = dpeek(buf_adr_l);
+ buf = mem + bufadr;
+ len = dpeek(buf_len_l);
+
+ // fprintf(stderr, "writeblock, bufadr = $%04x, len = $%04x\n", bufadr, len);
+
+ bytes = fwrite(buf, 1, len, out_file);
+ dpoke(buf_len_l, bytes);
+}