Mirror of CollapseOS
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

128 行
3.1KB

  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <curses.h>
  5. #include "cpu.h"
  6. #define WCOLS 80
  7. #define WLINES 25
  8. #define SEC_PER_TRK 0x24
  9. #define HEADCNT 2
  10. extern uint8_t byteregtable[8];
  11. extern union _bytewordregs_ regs;
  12. extern uint16_t segregs[4];
  13. extern INTHOOK INTHOOKS[0x100];
  14. static FILE *fp;
  15. WINDOW *bw, *dw, *w;
  16. static void int10() {
  17. uint8_t cmd = regs.byteregs[regah];
  18. uint8_t al = regs.byteregs[regal];
  19. uint16_t dx = regs.wordregs[regdx];
  20. switch (cmd) {
  21. case 0x02: // at-xy
  22. wmove(w, dx>>8, dx&0xff);
  23. break;
  24. case 0x0e: // emit
  25. if (al >= 0x20 || al == '\n') {
  26. wechochar(w, al);
  27. } else if (al == 0x08) {
  28. int y, x; getyx(w, y, x);
  29. wmove(w, y, x-1);
  30. }
  31. break;
  32. }
  33. }
  34. static void int13() {
  35. uint8_t cmd = regs.byteregs[regah];
  36. uint8_t al = regs.byteregs[regal];
  37. uint8_t cl = regs.byteregs[regcl];
  38. uint8_t ch = regs.byteregs[regch];
  39. uint8_t dh = regs.byteregs[regdh];
  40. uint16_t bx = regs.wordregs[regbx];
  41. switch (cmd) {
  42. case 0x02: // read disk sector(s)
  43. case 0x03: // write disk sector(s)
  44. // CL = sector number (1-based), AL = sector count
  45. // DH = head number, CH = track number
  46. // ES:BX = dest addr
  47. fseek(fp, (((ch*HEADCNT*SEC_PER_TRK)+(dh*SEC_PER_TRK))+cl-1)*512, SEEK_SET);
  48. for (int i=0; i<(al*512); i++) {
  49. if (cmd == 0x03) { // write
  50. fputc(getmem8(segregs[reges], bx+i), fp);
  51. } else { // read
  52. putmem8(segregs[reges], bx+i, fgetc(fp));
  53. }
  54. }
  55. break;
  56. case 0x08: // poll sectors per track / per head
  57. // we just report a lot of them
  58. regs.wordregs[regcx] = SEC_PER_TRK;
  59. regs.byteregs[regdh] = HEADCNT-1;
  60. break;
  61. }
  62. }
  63. static void int16() {
  64. int c;
  65. // debug_panel();
  66. c = wgetch(w);
  67. regs.byteregs[regal] = c;
  68. }
  69. static void usage()
  70. {
  71. fprintf(stderr, "Usage: ./pcat /path/to/fd\n");
  72. }
  73. int main(int argc, char *argv[])
  74. {
  75. if (argc < 2) {
  76. usage();
  77. return 1;
  78. }
  79. INTHOOKS[0x10] = int10;
  80. INTHOOKS[0x13] = int13;
  81. INTHOOKS[0x16] = int16;
  82. reset86(0x7c00);
  83. // initialize memory
  84. fp = fopen(argv[1], "r");
  85. if (!fp) {
  86. fprintf(stderr, "Can't open %s\n", argv[1]);
  87. return 1;
  88. }
  89. // read MBR into RAM
  90. for (int i=0; i<512; i++) {
  91. int c = getc(fp);
  92. if (c != EOF) {
  93. write86(0x7c00+i, c);
  94. }
  95. }
  96. uint16_t magic = readw86(0x7dfe);
  97. if (magic != 0xaa55) {
  98. fprintf(stderr, "Invalid MBR magic %x\n", magic);
  99. return 1;
  100. }
  101. initscr(); cbreak(); noecho(); nl(); clear();
  102. // border window
  103. bw = newwin(WLINES+2, WCOLS+2, 0, 0);
  104. wborder(bw, 0, 0, 0, 0, 0, 0, 0, 0);
  105. wrefresh(bw);
  106. // debug panel
  107. dw = newwin(1, 30, LINES-1, COLS-30);
  108. w = newwin(WLINES, WCOLS, 1, 1);
  109. scrollok(w, 1);
  110. while (exec86(100)) {
  111. //debug_panel();
  112. }
  113. nocbreak(); echo(); delwin(w); delwin(bw); delwin(dw); endwin();
  114. printf("\nDone!\n");
  115. //emul_printdebug();
  116. fclose(fp);
  117. return 0;
  118. }