INCLUDES = -include code16.h -I.
LDFLAGS = -T com16.ld
-SRCS = main.c serial.c ymsend.c
+SRCS = main.c serial.c ymsend.c srecsend.c
OBJS = crt0.o $(patsubst %.c,%.o,$(notdir $(SRCS)))
LIBOBJS = conio.o memcpy.o memset.o skipatou.o strtoul.o \
argv.o printf.o __divdi3.o __udivmoddi4.o
--- /dev/null
+#ifndef FILE_H
+#define FILE_H
+
+#include "mystuff.h"
+
+struct serial_if {
+ int port;
+ void *pvt;
+ void (*read) (struct serial_if *, void *, size_t);
+ void (*write) (struct serial_if *, const void *, size_t);
+};
+
+struct file_info {
+ const char *name;
+ size_t base;
+ size_t size;
+ void *pvt;
+};
+
+
+int serial_init(struct serial_if *sif);
+void serial_read(struct serial_if *sif, void *data, size_t n);
+void serial_write(struct serial_if *sif, const void *data, size_t n);
+
+#endif /* FILE_H */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <stdbool.h>
#include "mystuff.h"
#include "ymsend.h"
+#include "srecsend.h"
#include "io.h"
const char *program = "memdump";
.write = serial_write,
};
struct file_info finfo;
- const char serial_banner[] = "Now begin Ymodem download...\r\n";
+ const char ymodem_banner[] = "Now begin Ymodem download...\r\n";
+ bool srec = false;
+
+ if (argv[1][0] == '-') {
+ srec = argv[1][1] == 's';
+ argc--;
+ argv++;
+ }
if (argc < 4)
- die("usage: memdump port prefix start,len...");
+ die("usage: memdump [-s] port prefix start,len...");
finfo.pvt = (void *)0x400;
get_bytes(bios_ports, 8, &finfo, 0); /* Get BIOS serial ports */
prefix = argv[2];
- puts("Printing prefix...\n");
- sif.write(&sif, serial_banner, sizeof serial_banner - 1);
+ if (!srec) {
+ puts("Printing prefix...\n");
+ sif.write(&sif, ymodem_banner, sizeof ymodem_banner - 1);
+ }
for (i = 3; i < argc; i++) {
uint32_t start, len;
puts(filename);
puts("...\n");
- send_ymodem(&sif, &finfo, get_bytes);
+ if (srec)
+ send_srec(&sif, &finfo, get_bytes);
+ else
+ send_ymodem(&sif, &finfo, get_bytes);
}
- puts("Sending closing signature...\n");
- end_ymodem(&sif);
+ if (!srec) {
+ puts("Sending closing signature...\n");
+ end_ymodem(&sif);
+ }
return 0;
}
+#include <stdbool.h>
+#include <stdio.h>
+
#include "mystuff.h"
-#include "ymsend.h"
+#include "file.h"
#include "io.h"
enum {
--- /dev/null
+/*
+ * SREC send routine.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "srecsend.h"
+
+static void make_srec(struct serial_if *sif, char type, size_t addr,
+ const void *data, size_t len)
+{
+ char buf[80]; /* More than the largest possible size */
+ char *p;
+ const uint8_t *dp = data;
+ size_t alen = (type == '0') ? 4 : 8;
+ uint8_t csum;
+
+ p = buf;
+ *p++ = 'S';
+ *p++ = type;
+ if (type == '0')
+ p += sprintf(p, "%04zX", addr);
+ else
+ p += sprintf(p, "%08zX", addr);
+
+ csum = (len+alen+1) + addr + (addr >> 8) + (addr >> 16) + (addr >> 24);
+ while (len) {
+ p += sprintf(p, "%02X", *dp);
+ csum += *dp;
+ dp++;
+ }
+ csum = 0xff - csum;
+ p += sprintf(p, "%02X\r\n", csum);
+
+ sif->write(sif, buf, p-buf);
+}
+
+void send_srec(struct serial_if *sif, struct file_info *fileinfo,
+ void (*gen_data) (void *, size_t, struct file_info *, size_t))
+{
+ uint8_t blk_buf[1024];
+ const uint8_t *np;
+ size_t addr, len, bytes, chunk, offset, pos;
+ int blk;
+
+ len = fileinfo->size;
+
+ make_srec(sif, '0', 0, NULL, 0);
+
+ blk = 0;
+ pos = 0;
+ addr = fileinfo->base;
+ while (len) {
+ gen_data(blk_buf, sizeof blk_buf, fileinfo, pos);
+ pos += sizeof blk_buf;
+ bytes = sizeof blk_buf;
+ if (bytes > len)
+ bytes = len;
+ len -= bytes;
+
+ printf("Sending block %d...\r", blk);
+
+ np = blk_buf;
+ while (bytes) {
+ chunk = bytes > 64 ? 64 : bytes;
+
+ make_srec(sif, '3', addr, np, chunk);
+
+ bytes -= chunk;
+ offset += chunk;
+ np += chunk;
+ addr += chunk;
+ }
+ blk++;
+ }
+
+ printf("\nSending EOT...\n");
+ make_srec(sif, '7', fileinfo->base, NULL, 0);
+ printf("Done.\n");
+}
--- /dev/null
+#ifndef SRECSEND_H
+#define SRECSEND_H
+
+#include "mystuff.h"
+#include "file.h"
+
+void send_srec(struct serial_if *, struct file_info *,
+ void (*)(void *, size_t, struct file_info *, size_t));
+
+#endif /* SRECSEND_H */
--- /dev/null
+/*
+ *
+ * stdbool.h
+ */
+
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+#ifndef __cplusplus
+
+#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
+# if !defined(__GNUC__) ||(__GNUC__ < 3)
+typedef char _Bool; /* For C compilers without _Bool */
+# endif
+#endif
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+#else
+
+/* C++ */
+#define bool bool
+#define true true
+#define false false
+
+#endif
+
+#define __bool_true_false_are_defined 1
+
+#endif /* _STDBOOL_H */
#define YMSEND_H
#include "mystuff.h"
-
-struct serial_if {
- int port;
- void *pvt;
- void (*read) (struct serial_if *, void *, size_t);
- void (*write) (struct serial_if *, const void *, size_t);
-};
-
-struct file_info {
- const char *name;
- size_t size;
- void *pvt;
-};
+#include "file.h"
void send_ymodem(struct serial_if *, struct file_info *,
void (*)(void *, size_t, struct file_info *, size_t));
void end_ymodem(struct serial_if *);
-int serial_init(struct serial_if *sif);
-void serial_read(struct serial_if *sif, void *data, size_t n);
-void serial_write(struct serial_if *sif, const void *data, size_t n);
-
#endif /* YMSEND_H */