|
- #include <stdint.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <curses.h>
- #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;
- }
|