Mirror of CollapseOS
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

164 lines
3.7KB

  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <curses.h>
  5. #include <termios.h>
  6. #include "emul.h"
  7. #define WCOLS 80
  8. #define WLINES 32
  9. // in sync with glue.asm
  10. #define RAMSTART 0x900
  11. #define STDIO_PORT 0x00
  12. // This binary is also used for automated tests and those tests, when
  13. // failing, send a non-zero value to RET_PORT to indicate failure
  14. #define RET_PORT 0x01
  15. // Port for block reads. Each read or write has to be done in 5 IO writes:
  16. // 1 - r/w. 1 for read, 2 for write.
  17. // 2 - blkid MSB
  18. // 3 - blkid LSB
  19. // 4 - dest addr MSB
  20. // 5 - dest addr LSB
  21. #define BLK_PORT 0x03
  22. #define SETX_PORT 0x05
  23. #define SETY_PORT 0x06
  24. static Machine *m;
  25. static FILE *fp;
  26. static int retcode = 0;
  27. WINDOW *bw, *dw, *w;
  28. static uint64_t blkop = 0; // 5 bytes
  29. static FILE *blkfp;
  30. void debug_panel()
  31. {
  32. char buf[30];
  33. emul_debugstr(buf);
  34. mvwaddnstr(dw, 0, 0, buf, 30);
  35. wrefresh(dw);
  36. }
  37. static uint8_t iord_stdio()
  38. {
  39. int c;
  40. if (fp != NULL) {
  41. c = getc(fp);
  42. } else {
  43. debug_panel();
  44. c = wgetch(w);
  45. }
  46. if (c == EOF) {
  47. c = 4; // ASCII EOT
  48. }
  49. return (uint8_t)c;
  50. }
  51. static void iowr_stdio(uint8_t val)
  52. {
  53. if (fp != NULL) {
  54. putchar(val);
  55. } else {
  56. if (val >= 0x20 || val == '\n') {
  57. wechochar(w, val);
  58. } else if (val == 0x08) {
  59. int y, x; getyx(w, y, x);
  60. wmove(w, y, x-1);
  61. }
  62. }
  63. }
  64. static void iowr_blk(uint8_t val)
  65. {
  66. blkop <<= 8;
  67. blkop |= val;
  68. uint8_t rw = blkop >> 32;
  69. if (rw) {
  70. uint16_t blkid = (blkop >> 16);
  71. uint16_t dest = blkop & 0xffff;
  72. blkop = 0;
  73. fseek(blkfp, blkid*1024, SEEK_SET);
  74. if (rw==2) { // write
  75. fwrite(&m->mem[dest], 1024, 1, blkfp);
  76. } else { // read
  77. fread(&m->mem[dest], 1024, 1, blkfp);
  78. }
  79. }
  80. }
  81. static void iowr_ret(uint8_t val)
  82. {
  83. retcode = val;
  84. }
  85. static void iowr_setx(uint8_t val)
  86. {
  87. int y, x; getyx(w, y, x);
  88. wmove(w, y, val);
  89. }
  90. static void iowr_sety(uint8_t val)
  91. {
  92. int y, x; getyx(w, y, x);
  93. wmove(w, val, x);
  94. }
  95. int main(int argc, char *argv[])
  96. {
  97. fprintf(stderr, "Using blkfs %s\n", BLKFS_PATH);
  98. blkfp = fopen(BLKFS_PATH, "r+");
  99. if (!blkfp) {
  100. fprintf(stderr, "Can't open\n");
  101. return 1;
  102. }
  103. fseek(blkfp, 0, SEEK_END);
  104. if (ftell(blkfp) < 100 * 1024) {
  105. fclose(blkfp);
  106. fprintf(stderr, "emul/blkfs too small, something's wrong, aborting.\n");
  107. return 1;
  108. }
  109. fseek(blkfp, 0, SEEK_SET);
  110. m = emul_init(FBIN_PATH, 0);
  111. if (m == NULL) {
  112. return 1;
  113. }
  114. m->ramstart = RAMSTART;
  115. m->iord[STDIO_PORT] = iord_stdio;
  116. m->iowr[STDIO_PORT] = iowr_stdio;
  117. m->iowr[RET_PORT] = iowr_ret;
  118. m->iowr[BLK_PORT] = iowr_blk;
  119. m->iowr[SETX_PORT] = iowr_setx;
  120. m->iowr[SETY_PORT] = iowr_sety;
  121. w = NULL;
  122. if (argc == 2) {
  123. fp = fopen(argv[1], "r");
  124. if (fp == NULL) {
  125. fprintf(stderr, "Can't open %s\n", argv[1]);
  126. return 1;
  127. }
  128. while (emul_step());
  129. fclose(fp);
  130. } else if (argc == 1) {
  131. fp = NULL;
  132. initscr(); cbreak(); noecho(); nl(); clear();
  133. // border window
  134. bw = newwin(WLINES+2, WCOLS+2, 0, 0);
  135. wborder(bw, 0, 0, 0, 0, 0, 0, 0, 0);
  136. wrefresh(bw);
  137. // debug panel
  138. dw = newwin(1, 30, LINES-1, COLS-30);
  139. w = newwin(WLINES, WCOLS, 1, 1);
  140. scrollok(w, 1);
  141. while (emul_steps(1000)) {
  142. debug_panel();
  143. }
  144. nocbreak(); echo(); delwin(w); delwin(bw); delwin(dw); endwin();
  145. printf("\nDone!\n");
  146. emul_printdebug();
  147. } else {
  148. fprintf(stderr, "Usage: ./forth [filename]\n");
  149. retcode = 1;
  150. }
  151. fclose(blkfp);
  152. return retcode;
  153. }