7907687abf
By uploading a BASIC loop and then run it, we can reduce the serial communication to pure content which greatly reduces the overhead and make the process much much faster.
78 lines
2.1 KiB
C
78 lines
2.1 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
|
|
#include "common.h"
|
|
|
|
/* Push specified file to specified device **running the BASIC shell** and verify
|
|
* that the sent contents is correct.
|
|
*
|
|
* Note: running this will clear the current BASIC listing on the other side.
|
|
*/
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
if (argc != 4) {
|
|
fprintf(stderr, "Usage: ./upload device memptr fname\n");
|
|
return 1;
|
|
}
|
|
unsigned int memptr = strtol(argv[2], NULL, 16);
|
|
FILE *fp = fopen(argv[3], "r");
|
|
if (!fp) {
|
|
fprintf(stderr, "Can't open %s.\n", argv[3]);
|
|
return 1;
|
|
}
|
|
fseek(fp, 0, SEEK_END);
|
|
unsigned int bytecount = ftell(fp);
|
|
fprintf(stderr, "memptr: 0x%04x bytecount: 0x%04x.\n", memptr, bytecount);
|
|
if (!bytecount) {
|
|
// Nothing to read
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
if (memptr+bytecount > 0xffff) {
|
|
fprintf(stderr, "memptr+bytecount out of range.\n");
|
|
fclose(fp);
|
|
return 1;
|
|
}
|
|
rewind(fp);
|
|
int fd = open(argv[1], O_RDWR|O_NOCTTY);
|
|
char s[0x20];
|
|
sprintf(s, "m=0x%04x", memptr);
|
|
sendcmdp(fd, s);
|
|
|
|
// Send program
|
|
sendcmdp(fd, "clear");
|
|
sendcmdp(fd, "1 getc");
|
|
sendcmdp(fd, "2 puth a");
|
|
sendcmdp(fd, "3 poke m a");
|
|
sendcmdp(fd, "4 m=m+1");
|
|
sprintf(s, "5 if m<0x%04x goto 1", memptr+bytecount);
|
|
sendcmdp(fd, s);
|
|
|
|
sendcmd(fd, "run");
|
|
int returncode = 0;
|
|
while (fread(s, 1, 1, fp)) {
|
|
putchar('.');
|
|
fflush(stdout);
|
|
unsigned char c = s[0];
|
|
write(fd, &c, 1);
|
|
usleep(1000); // let it breathe
|
|
read(fd, s, 2); // read hex pair
|
|
s[2] = 0; // null terminate
|
|
unsigned char c2 = strtol(s, NULL, 16);
|
|
if (c != c2) {
|
|
// mismatch!
|
|
unsigned int pos = ftell(fp);
|
|
fprintf(stderr, "Mismatch at byte %d! %d != %d.\n", pos, c, c2);
|
|
// we don't exit now because we need to "consume" our whole program.
|
|
returncode = 1;
|
|
}
|
|
}
|
|
printf("Done!\n");
|
|
fclose(fp);
|
|
return returncode;
|
|
}
|
|
|