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.

135 lines
3.4KB

  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 24
  9. #define RAMSTART 0
  10. #define BINSTART 0x3000
  11. WINDOW *bw, *dw, *w;
  12. static FILE *blkfp = NULL;
  13. void debug_panel()
  14. {
  15. char buf[30];
  16. emul_debugstr(buf);
  17. mvwaddnstr(dw, 0, 0, buf, 30);
  18. wrefresh(dw);
  19. }
  20. static void pchookfunc(Machine *m)
  21. {
  22. byte val;
  23. switch (m->cpu.R1.br.A) {
  24. case 0x01: // @KEY
  25. debug_panel();
  26. m->cpu.R1.br.A = wgetch(w);
  27. break;
  28. case 0x02: // @DSP
  29. val = m->cpu.R1.br.C;
  30. if (val == '\r') {
  31. val = '\n';
  32. }
  33. if (val >= 0x20 || val == '\n') {
  34. wechochar(w, val);
  35. } else if (val == 0x08) {
  36. int y, x; getyx(w, y, x);
  37. wmove(w, y, x-1);
  38. }
  39. break;
  40. case 0x0f: // @VDCTL
  41. wmove(w, m->cpu.R1.br.H, m->cpu.R1.br.L);
  42. break;
  43. case 0x16: // @EXIT
  44. m->cpu.halted = true;
  45. break;
  46. case 0x28: // @DCSTAT
  47. // set Z to indicate floppy presence
  48. if (blkfp != NULL) {
  49. m->cpu.R1.br.F |= F_Z;
  50. } else {
  51. m->cpu.R1.br.F &= ~F_Z;
  52. }
  53. break;
  54. // 0x100b per sector. 10 sector per cylinder, 40 cylinders per floppy.
  55. // TODO: support swapping floppies. only 1 floppy for now.
  56. case 0x31: // @RDSEC
  57. case 0x35: // @WRSEC
  58. if (blkfp != NULL) {
  59. fseek(
  60. blkfp, /* D = cylinder, E = sector */
  61. ((m->cpu.R1.br.D * 10) + m->cpu.R1.br.E) * 0x100,
  62. SEEK_SET);
  63. if (m->cpu.R1.br.A == 0x31) { // @RDSEC
  64. fread(&m->mem[m->cpu.R1.wr.HL], 0x100, 1, blkfp);
  65. } else {
  66. fwrite(&m->mem[m->cpu.R1.wr.HL], 0x100, 1, blkfp);
  67. }
  68. m->cpu.R1.br.F |= F_Z;
  69. }
  70. break;
  71. default:
  72. fprintf(stderr, "Unhandled RST28: %x\n", m->cpu.R1.br.A);
  73. }
  74. }
  75. static void usage()
  76. {
  77. fprintf(stderr, "Usage: ./trs80 [-f floppies.img] /path/to/rom\n");
  78. }
  79. int main(int argc, char *argv[])
  80. {
  81. if (argc < 2) {
  82. usage();
  83. return 1;
  84. }
  85. int ch;
  86. while ((ch = getopt(argc, argv, "f:")) != -1) {
  87. switch (ch) {
  88. case 'f':
  89. fprintf(stderr, "Setting up floppies image with %s\n", optarg);
  90. blkfp = fopen(optarg, "r+");
  91. if (blkfp == NULL) {
  92. fprintf(stderr, "Can't open file\n");
  93. return 1;
  94. }
  95. break;
  96. }
  97. }
  98. if (optind != argc-1) {
  99. usage();
  100. return 1;
  101. }
  102. Machine *m = emul_init(argv[optind], BINSTART);
  103. if (m == NULL) return 1;
  104. m->ramstart = RAMSTART;
  105. m->pchookfunc = pchookfunc;
  106. m->pchooks_cnt = 1;
  107. m->pchooks[0] = 0x28; // RST 28
  108. // Place a RET at 0x28 so that it properly returns after pchookfunc().
  109. m->mem[0x28] = 0xc9; // RET
  110. m->cpu.PC = BINSTART;
  111. initscr(); cbreak(); noecho(); nl(); clear();
  112. // border window
  113. bw = newwin(WLINES+2, WCOLS+2, 0, 0);
  114. wborder(bw, 0, 0, 0, 0, 0, 0, 0, 0);
  115. wrefresh(bw);
  116. // debug panel
  117. dw = newwin(1, 30, LINES-1, COLS-30);
  118. w = newwin(WLINES, WCOLS, 1, 1);
  119. scrollok(w, 1);
  120. while (emul_steps(1000)) {
  121. debug_panel();
  122. }
  123. nocbreak(); echo(); delwin(w); delwin(bw); delwin(dw); endwin();
  124. printf("\nDone!\n");
  125. emul_printdebug();
  126. printf("PC: %x\n", m->cpu.PC);
  127. return 0;
  128. }