From 5504c796ee82311bb4ce4be49729bf3987332c71 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 3 May 2020 08:53:17 -0400 Subject: [PATCH] tools: add blkup With this tool, we can send content to a TRS-80 directly to floppy. This paves the way to writing ourselves a set of disks containing the blkfs! --- tools/.gitignore | 1 + tools/blkup.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/common.c | 20 +++++++++++++---- 3 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 tools/blkup.c diff --git a/tools/.gitignore b/tools/.gitignore index 901df7b..f8ae9ea 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -10,3 +10,4 @@ /exec /blkpack /blkunpack +/blkup diff --git a/tools/blkup.c b/tools/blkup.c new file mode 100644 index 0000000..25dffb5 --- /dev/null +++ b/tools/blkup.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include + +#include "common.h" + +/* Push specified file to specified device blk device, starting from blkno + * and upwards. + */ + +int main(int argc, char **argv) +{ + if (argc != 4) { + fprintf(stderr, "Usage: ./blkup device blkno fname\n"); + return 1; + } + unsigned int blkno = strtol(argv[2], NULL, 10); + FILE *fp = fopen(argv[3], "r"); + if (!fp) { + fprintf(stderr, "Can't open %s.\n", argv[3]); + return 1; + } + int fd = open(argv[1], O_RDWR|O_NOCTTY|O_SYNC); + if (fd < 0) { + fprintf(stderr, "Could not open %s\n", argv[1]); + return 1; + } + set_interface_attribs(fd, 0, 0); + set_blocking(fd, 1); + char s[0x40]; + char buf[1024] = {0}; + sendcmdp(fd, ": _ 1024 0 DO KEY DUP .x I BLK( + C! LOOP ;"); + + int returncode = 0; + while (fread(buf, 1, 1024, fp)) { + sendcmd(fd, "_"); + for (int i=0; i<1024; i++) { + putchar('.'); + fflush(stdout); + write(fd, &buf[i], 1); + usleep(1000); // let it breathe + mread(fd, s, 2); // read hex pair + s[2] = 0; // null terminate + unsigned char c = strtol(s, NULL, 16); + if (c != buf[i]) { + // mismatch! + fprintf(stderr, "Mismatch at bno %d (%d) %d != %d.\n", blkno, i, buf[i], c); + // we don't exit now because we need to "consume" our whole program. + returncode = 1; + } + usleep(1000); // let it breathe + } + readprompt(fd); + if (returncode) break; + memset(buf, 0, 1024); + sprintf(s, "%d BLK> ! BLK!", blkno); + sendcmdp(fd, s); + blkno++; + } + sendcmdp(fd, "FORGET _"); + printf("Done!\n"); + fclose(fp); + return returncode; +} + diff --git a/tools/common.c b/tools/common.c index 0de4532..e029df0 100644 --- a/tools/common.c +++ b/tools/common.c @@ -16,10 +16,22 @@ void mread(int fd, char *s, int count) } } +void mexpect(int fd, char ec) +{ + char c; + mread(fd, &c, 1); + if (c != ec) { + fprintf(stderr, "Expected %d but got %d\n", ec, c); + } +} + void readprompt(int fd) { - char junk[3]; - mread(fd, junk, 3); // " ok" prompt + mexpect(fd, ' '); + mexpect(fd, 'o'); + mexpect(fd, 'k'); + mexpect(fd, '\r'); + mexpect(fd, '\n'); } void sendcmd(int fd, char *cmd) @@ -34,14 +46,14 @@ void sendcmd(int fd, char *cmd) usleep(1000); } write(fd, "\r", 1); - mread(fd, junk, 2); // sends back \r\n + mexpect(fd, '\r'); + mexpect(fd, '\n'); usleep(1000); } // Send a cmd and also read the " ok" prompt void sendcmdp(int fd, char *cmd) { - char junk[2]; sendcmd(fd, cmd); readprompt(fd); }