Mirror of CollapseOS
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

80 行
2.0KB

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <stdint.h>
  6. #include "common.h"
  7. /* Push specified file to specified device running Forth and verify
  8. * that the sent contents is correct.
  9. */
  10. int main(int argc, char **argv)
  11. {
  12. if (argc != 4) {
  13. fprintf(stderr, "Usage: ./upload device memptr fname\n");
  14. return 1;
  15. }
  16. unsigned int memptr = strtol(argv[2], NULL, 16);
  17. FILE *fp = fopen(argv[3], "r");
  18. if (!fp) {
  19. fprintf(stderr, "Can't open %s.\n", argv[3]);
  20. return 1;
  21. }
  22. fseek(fp, 0, SEEK_END);
  23. unsigned int bytecount = ftell(fp);
  24. fprintf(stderr, "memptr: 0x%04x bytecount: 0x%04x.\n", memptr, bytecount);
  25. if (!bytecount) {
  26. // Nothing to read
  27. fclose(fp);
  28. return 0;
  29. }
  30. if (memptr+bytecount > 0xffff) {
  31. fprintf(stderr, "memptr+bytecount out of range.\n");
  32. fclose(fp);
  33. return 1;
  34. }
  35. rewind(fp);
  36. int fd = ttyopen(argv[1]);
  37. if (fd < 0) {
  38. fprintf(stderr, "Could not open %s\n", argv[1]);
  39. return 1;
  40. }
  41. uint16_t checksum = 0;
  42. char s[0x40];
  43. // Write all received bytes, keeping a checksum, then print that checksum
  44. sprintf(s,
  45. ": _ 0 %d %d DO KEY DUP I C! + LOOP .X ; _",
  46. memptr+bytecount, memptr);
  47. sendcmd(fd, s);
  48. int returncode = 0;
  49. while (fread(s, 1, 1, fp)) {
  50. putc('.', stderr);
  51. fflush(stderr);
  52. unsigned char c = s[0];
  53. checksum += c;
  54. write(fd, &c, 1);
  55. usleep(1000); // let it breathe
  56. }
  57. fprintf(stderr, "\nBytes sent, checksum...\n");
  58. mread(fd, s, 4); // read hex string
  59. s[4] = 0; // null terminate
  60. uint16_t checksum2 = strtol(s, NULL, 16);
  61. if (checksum == checksum2) {
  62. fprintf(stderr, "OK\n");
  63. } else {
  64. fprintf(stderr, "Mismatch! Expected %04x and got %04x.\n", checksum, checksum2);
  65. returncode = 1;
  66. }
  67. readprompt(fd);
  68. sendcmdp(fd, "FORGET _");
  69. fclose(fp);
  70. if (fd > 0) {
  71. close(fd);
  72. }
  73. return returncode;
  74. }