Makefile/tools: add chkmdv
authorAlan Cox <alan@linux.intel.com>
Sun, 12 Apr 2015 21:50:25 +0000 (22:50 +0100)
committerAlan Cox <alan@linux.intel.com>
Sun, 12 Apr 2015 21:50:25 +0000 (22:50 +0100)
Handy for checking Microdrive write logic

Kernel/Makefile
Kernel/tools/chkmdv.c [new file with mode: 0644]

index f0c7c19..dc8954e 100644 (file)
@@ -16,12 +16,12 @@ TARGET_LIST = platform-nc100 platform-micropack platform-pcw8256 platform-socz80
 #export TARGET = px4plus
 #export TARGET = socz80
 #export TARGET = tgl6502
-export TARGET = trs80
+#export TARGET = trs80
 #export TARGET = ubee
 #export TARGET = z80pack
 #export TARGET = z80pack-lite
 #export TARGET = zeta-v2
-#export TARGET = zx128
+export TARGET = zx128
 
 export VERSION = "0.1"
 export SUBVERSION = "ac1"
@@ -137,7 +137,7 @@ font4x6.c: tools/make4x6
        tools/make4x6 >font4x6.c
 
 clean:
-       rm -f $(OBJS) $(JUNK) fuzix.cdb fuzix.com fuzix.tmp platform fuzix.bin fuzix.map fuzix.noi fuzix.ihx common.ihx common.bin relocs.dat core *~ include/*~ version.c tools/make4x6 tools/analysemap tools/memhogs tools/binman tools/bihx tools/bintomdv tools/decbdragon hogs.txt hogs.txt.old tools/*~
+       rm -f $(OBJS) $(JUNK) fuzix.cdb fuzix.com fuzix.tmp platform fuzix.bin fuzix.map fuzix.noi fuzix.ihx common.ihx common.bin relocs.dat core *~ include/*~ version.c tools/make4x6 tools/analysemap tools/memhogs tools/binman tools/bihx tools/bintomdv tools/chkmdv tools/decbdragon hogs.txt hogs.txt.old tools/*~
        +make -C platform-$(TARGET) clean
        +make -C cpm-loader clean
        +make -C tools/bankld clean
diff --git a/Kernel/tools/chkmdv.c b/Kernel/tools/chkmdv.c
new file mode 100644 (file)
index 0000000..7fd8af0
--- /dev/null
@@ -0,0 +1,118 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/errno.h>
+
+static int mdv_sec;
+
+static void SectorError(const char *p, ...)
+{
+  va_list v;
+
+  fprintf(stderr, "Block %d: ", mdv_sec);
+  va_start(v, p);
+  vfprintf(stderr, p, v);
+  va_end(v);
+}
+
+  
+static uint8_t mdv_csum(uint8_t *data, int len)
+{
+  uint32_t sum = 0;
+  while(len--) {
+    sum += *data++;
+  }
+  return sum % 0xFF;
+}
+
+static void mdv_check_header(uint8_t *buf, uint8_t sec)
+{
+  if (buf[0] != 1)
+    SectorError("Bad header type: %d", buf[0]);
+  if (buf[1] != sec)
+    SectorError("Bad header block number: %d", buf[1]);
+  if (memcmp(buf + 4, "FUZIX     ", 10))
+    SectorError("Bad header magic");
+  if (buf[14] != mdv_csum(buf, 14))
+    SectorError("Bad header checksum %02x %02x\n", buf[14],
+      mdv_csum(buf,14));
+}
+
+static void mdv_check_bufhdr(uint8_t *buf, uint8_t rec)
+{
+  if (buf[0] != 0)
+    SectorError("Bad block type %d\n", buf[0]);
+  if (buf[1] != rec)
+    SectorError("Bad block header block number: %d", buf[1]);
+  if (buf[2] != 0)
+    SectorError("Bad block header zero byte 2: %d", buf[2]);
+  if (buf[3] != 2)
+    SectorError("Bad block header length byte: %d", buf[3]);
+  if (memcmp(buf+4, "FUZIX     ", 10))
+    SectorError("Bad block header magic");
+  if (buf[14] != mdv_csum(buf, 14))
+    SectorError("Bad block header checksum %02x %02x\n", buf[14],
+      mdv_csum(buf,14));
+  if (buf[527] != mdv_csum(buf+15, 512))
+    SectorError("Bad block data checksum %02x %02x\n", buf[527],
+      mdv_csum(buf+15, 512));
+}
+
+static void mdv_check_sectormap(uint8_t *buf)
+{
+  ; /* TODO */
+}
+
+static void mdv_read(FILE *fp, char *buf, int len)
+{
+  if (fread(buf, len, 1, fp) != 1) {
+    if (errno)
+      perror("fread");
+    else
+      fprintf(stderr, "Unexpected EOF\n");
+  }
+}
+
+static void mdv_check_tape(FILE *fp)
+{
+  uint8_t buf[528];
+  uint8_t *bits;
+  int block = 1;
+  
+
+  while (block < 254) {  
+    mdv_sec = block;
+    mdv_read(fp, buf, 15);
+    mdv_check_header(buf, block);
+    mdv_read(fp, buf, 528);
+    if (block == 1 || block == 128)
+      mdv_check_sectormap(buf);
+    else
+      mdv_check_bufhdr(buf, block);
+    block++;
+  }
+}
+
+void main(int argc, char *argv[])
+{
+  FILE *fp;
+  FILE *fsp = NULL;
+  uint8_t zero = 0;
+
+  if (argc != 2) {
+    fprintf(stderr, "%s: microdrive.mdr\n", argv[0]);
+    exit(1);
+  }
+
+  fp = fopen(argv[1], "r");
+  if (fp == NULL) {
+    perror(argv[1]);
+    exit(1);
+  }
+  mdv_check_tape(fp);
+  fclose(fp);
+  exit(0);
+}