static int load_and_run_DOS_program(char *command, char *cmdline, int quit) { BMEM(pa4) = (struct param4a *)lowmem_alloc(sizeof(struct param4a)); if (!BMEM(pa4)) return -1; BMEM(allocated) = 1; BMEM(quit) = quit; BMEM(cmd) = com_strdup(command); if (!BMEM(cmd)) { com_errno = 8; return -1; } BMEM(cmdl) = lowmem_alloc(256); if (!BMEM(cmdl)) { com_strfree(BMEM(cmd)); com_errno = 8; return -1; } if (!cmdline) cmdline = ""; snprintf(BMEM(cmdl), 256, "%c %s\r", (char)(strlen(cmdline)+1), cmdline); /* prepare param block */ BMEM(pa4)->envframe = 0; // ctcb->envir_frame; BMEM(pa4)->cmdline = MK_FARt(DOSEMU_LMHEAP_SEG, DOSEMU_LMHEAP_OFFS_OF(BMEM(cmdl))); BMEM(pa4)->fcb1 = MK_FARt(COM_PSP_SEG, offsetof(struct PSP, FCB1)); BMEM(pa4)->fcb2 = MK_FARt(COM_PSP_SEG, offsetof(struct PSP, FCB2)); SREG(es) = DOSEMU_LMHEAP_SEG; LWORD(ebx) = DOSEMU_LMHEAP_OFFS_OF(BMEM(pa4)); /* path of programm to load */ SREG(ds) = DOSEMU_LMHEAP_SEG; LWORD(edx) = DOSEMU_LMHEAP_OFFS_OF(BMEM(cmd)); fake_call_to(BIOSSEG, GET_RETCODE_HELPER); LWORD(eax) = 0x4b00; real_run_int(0x21); return 0; }
int mscdex(void) { unsigned char *buf = MK_FP32(_ES, _BX); unsigned long dev; unsigned seg, strat, intr; int error; int i; char devname[] = "MSCD0001"; if (numDrives == 0) return 0; switch (_AL) { case 0x00: /* install check */ _BX = numDrives; if (_BX > 0) { int firstdrive = INT_MAX; for (i = 0; i < 4; i++) { if (cd_drives[i] != -1 && cd_drives[i] < firstdrive) firstdrive = cd_drives[i]; } _CX = firstdrive; } break; case 0x01: /* driver info */ for (i = 0; i < 4; i++) { if (cd_drives[i] != -1) { /* subunit: always 0 for cdrom.sys */ WRITE_BYTE(buf, 0x00); devname[7] = i + '1'; WRITE_DWORD(buf + 1, is_dos_device(devname)); buf += 5; } }; break; case 0x02: /* copyright file name */ case 0x03: /* abstract file name */ case 0x04: /* documentation file name */ { char readbuf[CD_FRAMESIZE]; if (ReadVTOC(_CX, 0x00, readbuf) == 0) { MEMCPY_2DOS(buf, readbuf + 702 + (_AL - 2) * 37, 37); WRITE_BYTE(buf + 37, 0); NOCARRY; } else { _AX = MSCDEX_ERROR_UNKNOWN_DRIVE; CARRY; } break; } case 0x05: /* read vtoc */ NOCARRY; error = ReadVTOC(_CX, _DX, buf); if (error) { _AL = error; CARRY; }; break; case 0x08: /* read sectors */ NOCARRY; error = ReadSectors(_CX, (_SI << 16) + _DI, _DX, buf); if (error) { _AL = error; CARRY; }; break; case 0x09: /* write sectors - not supported */ _AL = MSCDEX_ERROR_DRIVE_NOT_READY; CARRY; break; case 0x0B: /* CD-ROM drive check */ _AX = 0; for (i = 0; i < 4; i++) if (_CX == cd_drives[i]) { _AX = 1; break; } _BX = 0xadad; break; case 0x0C: _BX = (MSCDEX_VERSION_HIGH << 8) + MSCDEX_VERSION_LOW; break; case 0x0D: /* get drives */ for (i = 0; i < 4; i++) if (cd_drives[i] != -1) WRITE_BYTE(buf++, cd_drives[i]); break; case 0x0F: /* Get directory entry */ CARRY; _AX = GetDirectoryEntry(_CL, _CH & 1, buf, SEGOFF2LINEAR(_SI, _DI)); if (_AX == 0 || _AX == 1) NOCARRY; break; case 0x10: { int driver = GetDriver(_CX); if (driver >= 4) break; devname[7] = driver + '1'; dev = is_dos_device(devname); seg = dev >> 16; dev = SEGOFF2LINEAR(seg, dev & 0xffff); strat = READ_WORD(dev + 6); intr = READ_WORD(dev + 8); fake_call_to(seg, intr); fake_call_to(seg, strat); break; } default: C_printf("unknown mscdex\n"); return 0; } return 1; }
static void do_exit(void *arg) { fake_call_to(BIOSSEG, ROM_BIOS_EXIT); }