Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.1KB

  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <termios.h>
  5. #include "emul.h"
  6. #include "forth-bin.h"
  7. #include "blkfs-bin.h"
  8. // in sync with glue.asm
  9. #define RAMSTART 0x900
  10. #define STDIO_PORT 0x00
  11. // This binary is also used for automated tests and those tests, when
  12. // failing, send a non-zero value to RET_PORT to indicate failure
  13. #define RET_PORT 0x01
  14. // Port for block reads. Write 2 bytes, MSB first, on that port and then
  15. // read 1024 bytes from the DATA port.
  16. #define BLK_PORT 0x03
  17. #define BLKDATA_PORT 0x04
  18. static int running;
  19. static FILE *fp;
  20. static FILE *blkfp;
  21. static int retcode = 0;
  22. static uint16_t blkid = 0;
  23. static uint8_t iord_stdio()
  24. {
  25. int c = getc(fp);
  26. if (c == EOF) {
  27. running = 0;
  28. }
  29. return (uint8_t)c;
  30. }
  31. static void iowr_stdio(uint8_t val)
  32. {
  33. if (val == 0x04) { // CTRL+D
  34. running = 0;
  35. } else {
  36. putchar(val);
  37. }
  38. }
  39. static void iowr_ret(uint8_t val)
  40. {
  41. retcode = val;
  42. }
  43. static void iowr_blk(uint8_t val)
  44. {
  45. blkid <<= 8;
  46. blkid |= val;
  47. if (blkfp != NULL) {
  48. fseek(blkfp, blkid*1024, SEEK_SET);
  49. }
  50. }
  51. static uint8_t iord_blkdata()
  52. {
  53. uint8_t res = 0;
  54. if (blkfp != NULL) {
  55. int c = getc(blkfp);
  56. if (c != EOF) {
  57. res = c;
  58. }
  59. }
  60. return res;
  61. }
  62. static void iowr_blkdata(uint8_t val)
  63. {
  64. if (blkfp != NULL) {
  65. putc(val, blkfp);
  66. }
  67. }
  68. int main(int argc, char *argv[])
  69. {
  70. bool tty = false;
  71. struct termios termInfo;
  72. if (argc == 2) {
  73. fp = fopen(argv[1], "r");
  74. if (fp == NULL) {
  75. fprintf(stderr, "Can't open %s\n", argv[1]);
  76. return 1;
  77. }
  78. } else if (argc == 1) {
  79. fp = stdin;
  80. tty = isatty(fileno(stdin));
  81. if (tty) {
  82. // Turn echo off: the shell takes care of its own echoing.
  83. if (tcgetattr(0, &termInfo) == -1) {
  84. printf("Can't setup terminal.\n");
  85. return 1;
  86. }
  87. termInfo.c_lflag &= ~ECHO;
  88. termInfo.c_lflag &= ~ICANON;
  89. tcsetattr(0, TCSAFLUSH, &termInfo);
  90. }
  91. } else {
  92. fprintf(stderr, "Usage: ./forth [filename]\n");
  93. return 1;
  94. }
  95. blkfp = fopen("blkfs", "r+");
  96. if (blkfp) {
  97. fprintf(stderr, "Using blkfs file\n");
  98. } else {
  99. blkfp = fmemopen((char*)BLKFS, sizeof(BLKFS), "r");
  100. fprintf(stderr, "Using in-memory read-only blkfs\n");
  101. }
  102. Machine *m = emul_init();
  103. m->ramstart = RAMSTART;
  104. m->iord[STDIO_PORT] = iord_stdio;
  105. m->iowr[STDIO_PORT] = iowr_stdio;
  106. m->iowr[RET_PORT] = iowr_ret;
  107. m->iowr[BLK_PORT] = iowr_blk;
  108. m->iord[BLKDATA_PORT] = iord_blkdata;
  109. m->iowr[BLKDATA_PORT] = iowr_blkdata;
  110. // initialize memory
  111. for (int i=0; i<sizeof(KERNEL); i++) {
  112. m->mem[i] = KERNEL[i];
  113. }
  114. // Run!
  115. running = 1;
  116. while (running && emul_step());
  117. if (tty) {
  118. printf("\nDone!\n");
  119. termInfo.c_lflag |= ECHO;
  120. termInfo.c_lflag |= ICANON;
  121. tcsetattr(0, TCSAFLUSH, &termInfo);
  122. emul_printdebug();
  123. }
  124. if (blkfp != NULL) {
  125. fclose(blkfp);
  126. }
  127. fclose(fp);
  128. return retcode;
  129. }