#include #include #include #include #include "cpu.h" #define WCOLS 80 #define WLINES 25 #define SEC_PER_TRK 0x24 #define HEADCNT 2 extern uint8_t byteregtable[8]; extern union _bytewordregs_ regs; extern uint16_t segregs[4]; extern INTHOOK INTHOOKS[0x100]; static FILE *fp; WINDOW *bw, *dw, *w; static void int10() { uint8_t cmd = regs.byteregs[regah]; uint8_t al = regs.byteregs[regal]; uint16_t dx = regs.wordregs[regdx]; switch (cmd) { case 0x02: // at-xy wmove(w, dx>>8, dx&0xff); break; case 0x0e: // emit if (al >= 0x20 || al == '\n') { wechochar(w, al); } else if (al == 0x08) { int y, x; getyx(w, y, x); wmove(w, y, x-1); } break; } } static void int13() { uint8_t cmd = regs.byteregs[regah]; uint8_t al = regs.byteregs[regal]; uint8_t cl = regs.byteregs[regcl]; uint8_t ch = regs.byteregs[regch]; uint8_t dh = regs.byteregs[regdh]; uint16_t bx = regs.wordregs[regbx]; switch (cmd) { case 0x02: // read disk sector(s) case 0x03: // write disk sector(s) // CL = sector number (1-based), AL = sector count // DH = head number, CH = track number // ES:BX = dest addr fseek(fp, (((ch*HEADCNT*SEC_PER_TRK)+(dh*SEC_PER_TRK))+cl-1)*512, SEEK_SET); for (int i=0; i<(al*512); i++) { if (cmd == 0x03) { // write fputc(getmem8(segregs[reges], bx+i), fp); } else { // read putmem8(segregs[reges], bx+i, fgetc(fp)); } } break; case 0x08: // poll sectors per track / per head // we just report a lot of them regs.wordregs[regcx] = SEC_PER_TRK; regs.byteregs[regdh] = HEADCNT-1; break; } } static void int16() { int c; // debug_panel(); c = wgetch(w); regs.byteregs[regal] = c; } static void usage() { fprintf(stderr, "Usage: ./pcat /path/to/fd\n"); } int main(int argc, char *argv[]) { if (argc < 2) { usage(); return 1; } INTHOOKS[0x10] = int10; INTHOOKS[0x13] = int13; INTHOOKS[0x16] = int16; reset86(0x7c00); // initialize memory fp = fopen(argv[1], "r"); if (!fp) { fprintf(stderr, "Can't open %s\n", argv[1]); return 1; } // read MBR into RAM for (int i=0; i<512; i++) { int c = getc(fp); if (c != EOF) { write86(0x7c00+i, c); } } uint16_t magic = readw86(0x7dfe); if (magic != 0xaa55) { fprintf(stderr, "Invalid MBR magic %x\n", magic); return 1; } initscr(); cbreak(); noecho(); nl(); clear(); // border window bw = newwin(WLINES+2, WCOLS+2, 0, 0); wborder(bw, 0, 0, 0, 0, 0, 0, 0, 0); wrefresh(bw); // debug panel dw = newwin(1, 30, LINES-1, COLS-30); w = newwin(WLINES, WCOLS, 1, 1); scrollok(w, 1); while (exec86(100)) { //debug_panel(); } nocbreak(); echo(); delwin(w); delwin(bw); delwin(dw); endwin(); printf("\nDone!\n"); //emul_printdebug(); fclose(fp); return 0; }