tools: add exec and convert ./upload to Forth

This commit is contained in:
Virgil Dupras 2020-04-13 10:25:27 -04:00
parent 1e0b40a876
commit 509972b08c
6 changed files with 136 additions and 10 deletions

1
tools/.gitignore vendored
View File

@ -7,3 +7,4 @@
/slatest
/stripfc
/bin2c
/exec

View File

@ -7,9 +7,10 @@ PINGPONG_TGT = pingpong
SLATEST_TGT = slatest
STRIPFC_TGT = stripfc
BIN2C_TGT = bin2c
EXEC_TGT = exec
TARGETS = $(MEMDUMP_TGT) $(BLKDUMP_TGT) $(UPLOAD_TGT) $(FONTCOMPILE_TGT) \
$(TTYSAFE_TGT) $(PINGPONG_TGT) $(SLATEST_TGT) $(STRIPFC_TGT) \
$(BIN2C_TGT)
$(BIN2C_TGT) $(EXEC_TGT)
OBJS = common.o
all: $(TARGETS)
@ -27,6 +28,7 @@ $(PINGPONG_TGT): $(PINGPONG_TGT).c
$(SLATEST_TGT): $(SLATEST_TGT).c
$(STRIPFC_TGT): $(STRIPFC_TGT).c
$(BIN2C_TGT): $(BIN2C_TGT).c
$(EXEC_TGT): $(EXEC_TGT).c
$(TARGETS): $(OBJS)
$(CC) $(CFLAGS) $@.c $(OBJS) -o $@

View File

@ -1,5 +1,18 @@
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
void mread(int fd, char *s, int count)
{
while (count) {
while (read(fd, s, 1) == 0);
s++;
count--;
}
}
void sendcmd(int fd, char *cmd)
{
@ -12,8 +25,8 @@ void sendcmd(int fd, char *cmd)
// it breathe, it can choke.
usleep(1000);
}
write(fd, "\n", 1);
read(fd, &junk, 2); // sends back \r\n
write(fd, "\r", 1);
mread(fd, junk, 2); // sends back \r\n
usleep(1000);
}
@ -22,5 +35,66 @@ void sendcmdp(int fd, char *cmd)
{
char junk[2];
sendcmd(fd, cmd);
read(fd, &junk, 2);
mread(fd, junk, 2);
}
// from https://stackoverflow.com/a/6947758
// discussion from https://stackoverflow.com/a/26006680 is interesting,
// but we don't want POSIX compliance.
int set_interface_attribs(int fd, int speed, int parity)
{
struct termios tty;
if (tcgetattr (fd, &tty) != 0) {
fprintf(stderr, "error %d from tcgetattr", errno);
return -1;
}
if (speed) {
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
}
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0) {
fprintf(stderr, "error %d from tcsetattr", errno);
return -1;
}
return 0;
}
void set_blocking(int fd, int should_block)
{
struct termios tty;
memset(&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0) {
fprintf(stderr, "error %d from tggetattr", errno);
return;
}
tty.c_cc[VMIN] = should_block ? 1 : 0;
tty.c_cc[VTIME] = 1; // 0.1 seconds read timeout
if (tcsetattr (fd, TCSANOW, &tty) != 0) {
fprintf(stderr, "error %d setting term attributes", errno);
}
}

View File

@ -1,3 +1,6 @@
void sendcmd(int fd, char *cmd);
void sendcmdp(int fd, char *cmd);
void mread(int fd, char *s, int count);
int set_interface_attribs(int fd, int speed, int parity);
void set_blocking(int fd, int should_block);

38
tools/exec.c Normal file
View File

@ -0,0 +1,38 @@
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include "common.h"
/* Execute code from stdin on the target machine.
*/
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: ./exec device\n");
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, 0);
int c = getchar();
while (c != EOF) {
if (c == '\n') c = '\r';
write(fd, &c, 1);
while (read(fd, &c, 1) == 1) {
putchar(c);
fflush(stdout);
}
c = getchar();
}
printf("Done!\n");
return 0;
}

View File

@ -5,7 +5,7 @@
#include "common.h"
/* Push specified file to specified device running the BASIC shell and verify
/* Push specified file to specified device running Forth and verify
* that the sent contents is correct.
*/
@ -35,11 +35,17 @@ int main(int argc, char **argv)
return 1;
}
rewind(fp);
int fd = open(argv[1], O_RDWR|O_NOCTTY);
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];
sprintf(s, "m=0x%04x", memptr);
sendcmdp(fd, s);
sprintf(s, "while m<0x%04x getc:puth a:poke m a:m=m+1", memptr+bytecount);
sprintf(s,
": _ 0x%04x 0x%04x DO KEY DUP .x I C! LOOP ; _",
memptr+bytecount, memptr);
sendcmd(fd, s);
int returncode = 0;
@ -49,7 +55,7 @@ int main(int argc, char **argv)
unsigned char c = s[0];
write(fd, &c, 1);
usleep(1000); // let it breathe
read(fd, s, 2); // read hex pair
mread(fd, s, 2); // read hex pair
s[2] = 0; // null terminate
unsigned char c2 = strtol(s, NULL, 16);
if (c != c2) {
@ -60,6 +66,8 @@ int main(int argc, char **argv)
returncode = 1;
}
}
mread(fd, s, 2); // "> " prompt
sendcmdp(fd, "FORGET _");
printf("Done!\n");
fclose(fp);
return returncode;