/* * DANG_BEGIN_FUNCTION map_custom_bios * * description: * Setup the dosemu amazing custom BIOS, quietly overwriting anything * was copied there before. Do not overwrite graphic fonts! * * DANG_END_FUNCTION */ static inline void map_custom_bios(void) { unsigned int ptr; u_long n; n = (u_long)bios_f000_endpart1 - (u_long)bios_f000; ptr = SEGOFF2LINEAR(BIOSSEG, 0); MEMCPY_2DOS(ptr, bios_f000, n); n = (u_long)bios_f000_end - (u_long)bios_f000_part2; ptr = SEGOFF2LINEAR(BIOSSEG, ((u_long)bios_f000_part2 - (u_long)bios_f000)); MEMCPY_2DOS(ptr, bios_f000_part2, n); /* Initialize the lowmem heap that resides in a custom bios */ lowmem_heap_init(); }
static int pass_to_int2f(Bit16u *ssp) { struct vm86_regs saved_regs = REGS; /* first save the regs */ /* expected stack layout pointed to by ssp: * * word 0 return IP (from near call) * word 1 dosemu_generic mode * word 2 AX for INT2f * word 3 DOS far ptr to dosc_iregs */ const struct dosc_iregs *r = (void *)SEGOFF2LINEAR(ssp[4], ssp[3]); int ret; if (running_DosC && running_DosC <= 1937) { d_printf("Redirector: INT2f, AX=%04x unsupported by DosC build %d\n", running_DosC, r->ax); return 1; } dosc_iregs_to_vm86regs(r); if (ssp[2] == 0x111e) { /* expected stack layout pointed to by ssp: * word 5 orig AX to be placed on stack */ /* NOTE: SS:SP are _not_ changed, we jus adjust SP to point to * word 5 on the stack (original AX) */ _SP += 5*2; } ret = mfs_redirector(); REGS = saved_regs; /* we restore all regs, as we return to DosC' C-code */ return ret; }
static void rmcb_handler(struct sigcontext *scp, const struct RealModeCallStructure *rmreg, int is_32, void *arg) { switch (RM_LO(ax)) { case 0: /* read */ { unsigned int offs = E_RMREG(edi); unsigned int size = E_RMREG(ecx); unsigned int dos_ptr = SEGOFF2LINEAR(RMREG(ds), RMLWORD(dx)); D_printf("MSDOS: read %x %x\n", offs, size); /* need to use copy function that takes VGA mem into account */ if (offs + size <= io_buffer_size) memcpy_2unix(io_buffer + offs, dos_ptr, size); else error("MSDOS: bad read (%x %x %x)\n", offs, size, io_buffer_size); break; } case 1: /* write */ { unsigned int offs = E_RMREG(edi); unsigned int size = E_RMREG(ecx); unsigned int dos_ptr = SEGOFF2LINEAR(RMREG(ds), RMLWORD(dx)); D_printf("MSDOS: write %x %x\n", offs, size); /* need to use copy function that takes VGA mem into account */ if (offs + size <= io_buffer_size) memcpy_2dos(dos_ptr, io_buffer + offs, size); else error("MSDOS: bad write (%x %x %x)\n", offs, size, io_buffer_size); break; } case 2: /* error */ io_error = 1; io_error_code = RMLWORD(cx); D_printf("MSDOS: set I/O error %x\n", io_error_code); break; default: error("MSDOS: unknown rmcb 0x%x\n", RM_LO(ax)); break; } }
static void do_retf(struct RealModeCallStructure *rmreg, int rmask) { unsigned int ssp, sp; ssp = SEGOFF2LINEAR(READ_RMREG(ss, rmask), 0); sp = READ_RMREG(sp, rmask); RMREG(ip) = popw(ssp, sp); RMREG(cs) = popw(ssp, sp); RMREG(sp) += 4; }
static void do_call(int cs, int ip, struct RealModeCallStructure *rmreg, int rmask) { unsigned int ssp, sp; ssp = SEGOFF2LINEAR(READ_RMREG(ss, rmask), 0); sp = READ_RMREG(sp, rmask); g_printf("fake_call() CS:IP %04x:%04x\n", cs, ip); pushw(ssp, sp, cs); pushw(ssp, sp, ip); RMREG(sp) -= 4; }
static int umb_find(int segbase) { int i; unsigned int addr = SEGOFF2LINEAR(segbase, 0); for (i = 0; i < UMBS; i++) { if (umbs[i].in_use && ((addr >= umbs[i].addr) && (addr < (umbs[i].addr + umbs[i].size)))) { return (i); } } return (UMB_NULL); }
void cdrom_helper(unsigned char *req_buf, unsigned char *transfer_buf, unsigned int dos_transfer_buf) { unsigned int Sector_plus_150,Sector; struct cdrom_msf cdrom_msf; struct cdrom_subchnl cdrom_subchnl; struct cdrom_tochdr cdrom_tochdr; struct cdrom_tocentry cdrom_tocentry; struct cdrom_volctrl cdrom_volctrl; int n, err; cdrom_subchnl.cdsc_format = CDROM_MSF; IndexCd=(int)((HI(ax) & 0xC0)>>6); HI(ax) = HI(ax) & 0x3F; if ((cdu33a) && (cdrom_fd < 0)) { cdrom_fd = open (path_cdrom, O_RDONLY | O_NONBLOCK); if (cdrom_fd < 0) { switch (HI(ax)) { case 0x09: /* media changed request */ LO(bx) = 1; /* media changed */ LO(ax) = 0; return; case 0x0A: /* device status request */ LWORD(ebx) = audio_status.status | 0x800; /* no disc */ LO(ax) = 0; return; } LO(ax) = 1; /* for other requests return with error */ return ; } } switch (HI(ax)) { case 0x01: /* NOTE: you can't see XA data disks if bit 10 of status * is cleared, MSCDEX will test it and skip XA entries! * Actually the entries skipped must have this pattern: * xxxx1xxx xxxxxxxx 0x58 0x41 * and the mscdex 2.25 code is: * test word ptr [bx+1Eh],400h * jz [check for XA] * [return 0 = valid entry] * [check for XA] * ... * cmp word ptr es:[bx+6],4158h 'XA' * jne [return 0] * mov ax,es:[bx+4] * and ax,8 * [return ax] */ audio_status.status = 0x00000710; /* see function 0x0A below */ audio_status.paused_bit = 0; audio_status.media_changed = 0; audio_status.volume0 = 0xFF; audio_status.volume1 = 0xFF; audio_status.volume2 = 0; audio_status.volume3 = 0; audio_status.outchan0 = 0; audio_status.outchan1 = 1; audio_status.outchan2 = 2; audio_status.outchan3 = 3; cdrom_fd = open (path_cdrom, O_RDONLY | O_NONBLOCK); err = errno; if (cdrom_fd < 0) { C_printf("CDROM: cdrom open (%s) failed: %s\n", path_cdrom, strerror(err)); LO(ax) = 0; if ((err == EIO) || (err==ENOMEDIUM)) { /* drive which cannot be opened if no disc is inserted! */ cdu33a = 1; if (! eject_allowed) LO(ax) = 1; /* no disk in drive */ } else LO(ax) = 1; /* no cdrom drive installed */ if (! eject_allowed) LO(ax) = 1; /* no disk in drive */ } else { LO(ax) = 0; if (! eject_allowed) { if (ioctl (cdrom_fd, CDROMREADTOCHDR, &cdrom_tochdr)) if (ioctl (cdrom_fd, CDROMREADTOCHDR, &cdrom_tochdr)) LO(ax) = 1; } } break; case 0x02: /* read long */ if (eject_allowed && ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl) && errno != ENOTTY) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disc in drive */ LO(ax) = 1; break; } else { /* disc in drive */ } } if (req_buf == NULL && transfer_buf == NULL) { req_buf = SEG_ADR((unsigned char *), es, di); dos_transfer_buf = SEGOFF2LINEAR(REG(ds), LWORD(esi)); } if (*CALC_PTR(req_buf,MSCD_READ_ADRESSING,u_char) == 1) { cdrom_msf.cdmsf_min0 = *CALC_PTR(req_buf,MSCD_READ_STARTSECTOR+2,u_char); cdrom_msf.cdmsf_sec0 = *CALC_PTR(req_buf,MSCD_READ_STARTSECTOR+1,u_char); cdrom_msf.cdmsf_frame0 = *CALC_PTR(req_buf,MSCD_READ_STARTSECTOR+0,u_char); Sector = cdrom_msf.cdmsf_min0*60*75+cdrom_msf.cdmsf_sec0*75 +cdrom_msf.cdmsf_frame0-150; } else { Sector = *CALC_PTR(req_buf,MSCD_READ_STARTSECTOR,u_long); } C_printf("CDROM: reading sector %#x (fmt %d)\n", Sector, *CALC_PTR(req_buf,MSCD_READ_ADRESSING,u_char)); if ((off_t) -1 == lseek (cdrom_fd, Sector*CD_FRAMESIZE, SEEK_SET)) { HI(ax) = (errno == EINVAL ? 0x08 : 0x0F); C_printf("CDROM: lseek failed: %s\n", strerror(errno)); LO(ax) = 1; } else { n = *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE; if (transfer_buf == NULL) { n = dos_read (cdrom_fd, dos_transfer_buf, n); } else { n = unix_read (cdrom_fd, transfer_buf, n); } if ( n < 0 ) { /* cd must be in drive, reset drive and try again */ cdrom_reset(); if ((off_t) -1 == lseek (cdrom_fd, Sector*CD_FRAMESIZE, SEEK_SET)) { HI(ax) = (errno == EINVAL ? 0x08 : 0x0F); C_printf("CDROM: lseek failed: %s\n", strerror(errno)); LO(ax) = 1; } else { n = *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE; if (transfer_buf == NULL) n = dos_read (cdrom_fd, dos_transfer_buf, n); else n = unix_read (cdrom_fd, transfer_buf, n); if ( n < 0) { HI(ax) = (errno == EFAULT ? 0x0A : 0x0F); C_printf("CDROM: sector read (to %p, len %#x) failed: %s\n", transfer_buf, *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE, strerror(errno)); LO(ax) = 1; } else LO(ax) = 0; } } if (n != *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE) { C_printf("CDROM: sector read len %#x got %#x\n", *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE, n); LO(ax) = 1; HI(ax) = 0x0F; } else { #ifdef CDROM_DEBUG dump_cd_sect(transfer_buf); #endif LO(ax) = 0; } } break; case 0x03: /* seek */ req_buf = SEG_ADR((unsigned char *), es, di); if ((off_t)-1 == lseek (cdrom_fd, *CALC_PTR(req_buf,MSCD_SEEK_STARTSECTOR,u_long)*CD_FRAMESIZE, SEEK_SET)) { C_printf("CDROM: lseek failed: %s\n", strerror(errno)); LO(ax) = 1; } break; case 0x04: /* play */ req_buf = SEG_ADR((unsigned char *), es, di); if (*CALC_PTR(req_buf,MSCD_PLAY_ADRESSING,u_char) == 1) { cdrom_msf.cdmsf_min0 = *CALC_PTR(req_buf,MSCD_PLAY_STARTSECTOR+2,u_char); cdrom_msf.cdmsf_sec0 = *CALC_PTR(req_buf,MSCD_PLAY_STARTSECTOR+1,u_char); cdrom_msf.cdmsf_frame0 = *CALC_PTR(req_buf,MSCD_PLAY_STARTSECTOR+0,u_char); Sector_plus_150 = cdrom_msf.cdmsf_min0*60*75+cdrom_msf.cdmsf_sec0*75 +cdrom_msf.cdmsf_frame0; audio_status.last_StartSector = Sector_plus_150; } else { Sector_plus_150 = *CALC_PTR(req_buf,MSCD_PLAY_STARTSECTOR,u_long) + 150; cdrom_msf.cdmsf_min0 = (Sector_plus_150 / (60*75)); cdrom_msf.cdmsf_sec0 = (Sector_plus_150 % (60*75)) / 75; cdrom_msf.cdmsf_frame0 = (Sector_plus_150 % (60*75)) % 75; audio_status.last_StartSector = Sector_plus_150; } Sector_plus_150 += *CALC_PTR(req_buf,MSCD_PLAY_NUMSECTORS,u_long); cdrom_msf.cdmsf_min1 = (Sector_plus_150 / (60*75)); cdrom_msf.cdmsf_sec1 = (Sector_plus_150 % (60*75)) / 75; cdrom_msf.cdmsf_frame1 = (Sector_plus_150 % (60*75)) % 75; audio_status.last_EndSector = Sector_plus_150; audio_status.paused_bit = 0; if (ioctl (cdrom_fd, CDROMPLAYMSF, &cdrom_msf)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMPLAYMSF, &cdrom_msf)) { /* no disk in drive */ LO(ax) = 1; break; } } LO(ax) = 0; break; case 0x05: /* pause (stop) audio */ LO(ax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl) == 0) { if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) { audio_status.last_StartSector = cdrom_subchnl.cdsc_absaddr.msf.minute*60*75 +cdrom_subchnl.cdsc_absaddr.msf.second*75 +cdrom_subchnl.cdsc_absaddr.msf.frame; ioctl (cdrom_fd, CDROMPAUSE, NULL); audio_status.paused_bit = 1; } else { audio_status.last_StartSector = 0; audio_status.last_EndSector = 0; audio_status.paused_bit = 0; } } else { audio_status.last_StartSector = 0; audio_status.last_EndSector = 0; audio_status.paused_bit = 0; audio_status.media_changed = 1; } break; case 0x06: /* resume audio */ LO(ax) = 0; if (audio_status.paused_bit) { if (ioctl (cdrom_fd, CDROMRESUME, NULL) == 0) { audio_status.paused_bit = 0; HI(ax) = 1; } } else LO(ax) = 1; break; case 0x07: /* location of head */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); if (*CALC_PTR(req_buf,MSCD_LOCH_ADRESSING,u_char) == 0) { *CALC_PTR(req_buf,MSCD_LOCH_LOCATION,u_long) = cdrom_subchnl.cdsc_absaddr.msf.minute*60*75 +cdrom_subchnl.cdsc_absaddr.msf.second*75 +cdrom_subchnl.cdsc_absaddr.msf.frame-150; } else {/* red book adressing */ *CALC_PTR(req_buf,MSCD_LOCH_LOCATION+3,u_char) = 0; *CALC_PTR(req_buf,MSCD_LOCH_LOCATION+2,u_char) = cdrom_subchnl.cdsc_absaddr.msf.minute; *CALC_PTR(req_buf,MSCD_LOCH_LOCATION+1,u_char) = cdrom_subchnl.cdsc_absaddr.msf.second; *CALC_PTR(req_buf,MSCD_LOCH_LOCATION+0,u_char) = cdrom_subchnl.cdsc_absaddr.msf.frame; } break; case 0x08: /* return sectorsize */ LO(ax) = 0; LWORD(ebx) = CD_FRAMESIZE; break; case 0x09: /* media changed */ /* this function will be called from MSCDEX before each new disk access ! */ HI(ax) = 0; LO(ax) = 0; LO(bx) = 0; C_printf("CDROM: media changed? %#x\n", audio_status.media_changed); errno = 0; if (eject_allowed) { if ((audio_status.media_changed) || ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { if (errno == EIO) cdrom_reset(); audio_status.media_changed = 0; LO(bx) = 1; /* media has been changed */ C_printf("CDROM: media changed? yes\n"); ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl); if (! ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) cdrom_reset(); /* disc in drive */ } else /* media has not changed, check audio status */ if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; /* audio playing in progress */ } break; case 0x0A: /* device status */ HI(ax) = 0; LO(ax) = 0; if (eject_allowed) { if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LWORD(ebx) = audio_status.status | 0x800; C_printf("CDROM: subch failed: %s\n", strerror(errno)); break; } else cdrom_reset(); } } /* disk in drive */ LWORD(ebx) = audio_status.status; if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; break; case 0x0B: /* drive reset */ LO(ax) = 0; break; case 0x0C: /* lock/unlock door */ cdrom_reset(); if (LO(bx) == 1) audio_status.status &= 0xFFFFFFFD; else audio_status.status |= 0x2; LO(ax) = 0; break; case 0x0D: /* eject */ LO(ax) = 0; if ((eject_allowed) && (audio_status.status & 0x02)) /* drive unlocked ? */ { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMEJECT)) { LO(ax) = errno; } } break; case 0x0E: /* close tray */ LO(ax) = 0; if ((eject_allowed) && (audio_status.status & 0x02)) /* drive unlocked ? */ { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMCLOSETRAY)) { LO(ax) = errno; } } break; case 0x0F: /* audio channel control */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); cdrom_volctrl.channel0 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME0, u_char); cdrom_volctrl.channel1 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME1, u_char); cdrom_volctrl.channel2 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME2, u_char); cdrom_volctrl.channel3 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME3, u_char); audio_status.volume0 = cdrom_volctrl.channel0; audio_status.volume1 = cdrom_volctrl.channel1; audio_status.volume2 = cdrom_volctrl.channel2; audio_status.volume3 = cdrom_volctrl.channel3; audio_status.outchan0 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME0-1, u_char); audio_status.outchan1 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME1-1, u_char); audio_status.outchan2 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME2-1, u_char); audio_status.outchan3 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME3-1, u_char); ioctl (cdrom_fd, CDROMVOLCTRL, &cdrom_volctrl); break; case 0x10: /* audio disk info */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMREADTOCHDR, &cdrom_tochdr)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMREADTOCHDR, &cdrom_tochdr)) { /* no disk in drive */ LO(ax) = 1; break; } } req_buf = SEG_ADR((unsigned char *), ds, si); *CALC_PTR(req_buf,MSCD_DISKINFO_LTN,u_char) = cdrom_tochdr.cdth_trk0; *CALC_PTR(req_buf,MSCD_DISKINFO_HTN,u_char) = cdrom_tochdr.cdth_trk1; cdrom_tocentry.cdte_track = CDROM_LEADOUT; cdrom_tocentry.cdte_format = CDROM_MSF; if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { C_printf ("Fatal cdrom error(audio disk info); read toc header succeeded but following read entry didn't\n"); LO(ax) = 1; break; } #ifdef __linux__ *CALC_PTR(req_buf,MSCD_DISKINFO_LEADOUT+3,u_char) = 0; *CALC_PTR(req_buf,MSCD_DISKINFO_LEADOUT+2,u_char) = cdrom_tocentry.cdte_addr.msf.minute; *CALC_PTR(req_buf,MSCD_DISKINFO_LEADOUT+1,u_char) = cdrom_tocentry.cdte_addr.msf.second; *CALC_PTR(req_buf,MSCD_DISKINFO_LEADOUT+0,u_char) = cdrom_tocentry.cdte_addr.msf.frame; #endif break; case 0x11: /* track info */ req_buf = SEG_ADR((unsigned char *), ds, si); cdrom_tocentry.cdte_track = *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKNUM,u_char); cdrom_tocentry.cdte_format = CDROM_MSF; C_printf("CDROM: track info, track %d\n", cdrom_tocentry.cdte_track); if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { /* XXX MSCDEX reads beyond the end of existing tracks. Sigh. */ if (errno != EINVAL) audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { if (errno == EIO) { audio_status.media_changed = 1; /* no disk in drive */ } LO(ax) = 1; break; } } #ifdef __linux__ *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKPOS+3,u_char) = 0; *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKPOS+2,u_char) = cdrom_tocentry.cdte_addr.msf.minute; *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKPOS+1,u_char) = cdrom_tocentry.cdte_addr.msf.second; *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKPOS+0,u_char) = cdrom_tocentry.cdte_addr.msf.frame; #endif *CALC_PTR(req_buf,MSCD_TRACKINFO_CTRL,u_char) = cdrom_tocentry.cdte_ctrl << 4 | 0x20; LO(ax) = 0; break; case 0x12: /* volume size */ cdrom_tocentry.cdte_track = CDROM_LEADOUT; cdrom_tocentry.cdte_format = CDROM_MSF; if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { /* no disk in drive */ LO(ax) = 1; break; } } req_buf = SEG_ADR((unsigned char *), ds, si); #ifdef __linux__ *CALC_PTR(req_buf,MSCD_GETVOLUMESIZE_SIZE,int) = cdrom_tocentry.cdte_addr.msf.minute*60*75 +cdrom_tocentry.cdte_addr.msf.second*60 +cdrom_tocentry.cdte_addr.msf.frame; #endif LO(ax) = 0; break; case 0x13: /* q channel */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); *CALC_PTR(req_buf,MSCD_QCHAN_CTRL,u_char) = (cdrom_subchnl.cdsc_adr << 4) + (cdrom_subchnl.cdsc_ctrl); *CALC_PTR(req_buf,MSCD_QCHAN_TNO,u_char) = cdrom_subchnl.cdsc_trk; *CALC_PTR(req_buf,MSCD_QCHAN_IND,u_char) = cdrom_subchnl.cdsc_ind; #ifdef __linux__ *CALC_PTR(req_buf,MSCD_QCHAN_MIN,u_char) = cdrom_subchnl.cdsc_reladdr.msf.minute; *CALC_PTR(req_buf,MSCD_QCHAN_SEC,u_char) = cdrom_subchnl.cdsc_reladdr.msf.second; *CALC_PTR(req_buf,MSCD_QCHAN_FRM,u_char) = cdrom_subchnl.cdsc_reladdr.msf.frame; #endif *CALC_PTR(req_buf,MSCD_QCHAN_ZERO,u_char) = 0; *CALC_PTR(req_buf,MSCD_QCHAN_AMIN,u_char) = cdrom_subchnl.cdsc_absaddr.msf.minute; *CALC_PTR(req_buf,MSCD_QCHAN_ASEC,u_char) = cdrom_subchnl.cdsc_absaddr.msf.second; *CALC_PTR(req_buf,MSCD_QCHAN_AFRM,u_char) = cdrom_subchnl.cdsc_absaddr.msf.frame; break; case 0x14: /* audio status */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); *CALC_PTR(req_buf,MSCD_AUDSTAT_PAUSED,u_short)= audio_status.paused_bit; *CALC_PTR(req_buf,MSCD_AUDSTAT_START ,u_long) = audio_status.last_StartSector; *CALC_PTR(req_buf,MSCD_AUDSTAT_END ,u_long) = audio_status.last_EndSector; break; case 0x15: /* get audio channel information */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME0,u_char) = audio_status.volume0; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME1,u_char) = audio_status.volume1; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME2,u_char) = audio_status.volume2; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME3,u_char) = audio_status.volume3; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME0-1,u_char) = audio_status.outchan0; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME1-1,u_char) = audio_status.outchan1; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME2-1,u_char) = audio_status.outchan2; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME3-1,u_char) = audio_status.outchan3; break; default: C_printf ("CDROM: unknown request %#x!\n",HI(ax)); }
unsigned int mhp_debug(enum dosdebug_event code, unsigned int parm1, unsigned int parm2) { int rtncd = 0; #if 0 return rtncd; #endif mhpdbgc.currcode = code; mhp_bpclr(); switch (DBG_TYPE(mhpdbgc.currcode)) { case DBG_INIT: mhp_init(); break; case DBG_BOOT: mhp_boot(); break; case DBG_INTx: if (!mhpdbg.active) break; if (test_bit(DBG_ARG(mhpdbgc.currcode), mhpdbg.intxxtab)) { if ((mhpdbgc.bpload==1) && (DBG_ARG(mhpdbgc.currcode) == 0x21) && (LWORD(eax) == 0x4b00) ) { /* mhpdbgc.bpload_bp=((long)SREG(cs) << 4) +LWORD(eip); */ mhpdbgc.bpload_bp = SEGOFF2LINEAR(SREG(cs), LWORD(eip)); if (mhp_setbp(mhpdbgc.bpload_bp)) { mhp_printf("bpload: intercepting EXEC\n", SREG(cs), REG(eip)); /* mhp_cmd("r"); mhp_cmd("d ss:sp 30h"); */ mhpdbgc.bpload++; mhpdbgc.bpload_par=MK_FP32(BIOSSEG,(long)DBGload_parblock-(long)bios_f000); MEMCPY_2UNIX(mhpdbgc.bpload_par, SEGOFF2LINEAR(SREG(es), LWORD(ebx)), 14); MEMCPY_2UNIX(mhpdbgc.bpload_cmdline, PAR4b_addr(commandline_ptr), 128); MEMCPY_2UNIX(mhpdbgc.bpload_cmd, SEGOFF2LINEAR(SREG(ds), LWORD(edx)), 128); SREG(es)=BIOSSEG; LWORD(ebx)=(void *)mhpdbgc.bpload_par - MK_FP32(BIOSSEG, 0); LWORD(eax)=0x4b01; /* load, but don't execute */ } else { mhp_printf("bpload: ??? #1\n"); mhp_cmd("r"); mhpdbgc.bpload_bp=0; mhpdbgc.bpload=0; } if (!--mhpdbgc.int21_count) { volatile register int i=0x21; /* beware, set_bit-macro has wrong constraints */ clear_bit(i, mhpdbg.intxxtab); if (test_bit(i, mhpdbgc.intxxalt)) { clear_bit(i, mhpdbgc.intxxalt); reset_revectored(i, &vm86s.int_revectored); } } } else { if ((DBG_ARG(mhpdbgc.currcode) != 0x21) || !mhpdbgc.bpload ) { mhpdbgc.stopped = 1; if (parm1) LWORD(eip) -= 2; mhpdbgc.int_handled = 0; mhp_poll(); if (mhpdbgc.int_handled) rtncd = 1; else if (parm1) LWORD(eip) += 2; } } } break; case DBG_INTxDPMI: if (!mhpdbg.active) break; mhpdbgc.stopped = 1; #if WITH_DPMI dpmi_mhp_intxxtab[DBG_ARG(mhpdbgc.currcode) & 0xff] &= ~2; #endif break; case DBG_TRAP: if (!mhpdbg.active) break; if (DBG_ARG(mhpdbgc.currcode) == 1) { /* single step */ switch (mhpdbgc.trapcmd) { case 2: /* t command -- step until IP changes */ if (mhpdbgc.trapip == mhp_getcsip_value()) break; /* no break */ case 1: /* ti command */ mhpdbgc.trapcmd = 0; rtncd = 1; mhpdbgc.stopped = 1; break; } if (traceloop && mhp_bpchk(mhp_getcsip_value())) { traceloop = 0; loopbuf[0] = '\0'; } } if (DBG_ARG(mhpdbgc.currcode) == 3) { /* int3 (0xCC) */ int ok=0; unsigned int csip=mhp_getcsip_value() - 1; if (mhpdbgc.bpload_bp == csip ) { /* mhp_cmd("r"); */ mhp_clearbp(mhpdbgc.bpload_bp); mhp_modify_eip(-1); if (mhpdbgc.bpload == 2) { mhp_printf("bpload: INT3 caught\n"); SREG(cs)=BIOSSEG; LWORD(eip)=(long)DBGload-(long)bios_f000; mhpdbgc.trapcmd = 1; mhpdbgc.bpload = 0; } } else { if ((ok=mhp_bpchk( csip))) { mhp_modify_eip(-1); } else { if ((ok=test_bit(3, mhpdbg.intxxtab))) { /* software programmed INT3 */ mhp_modify_eip(-1); mhp_cmd("r"); mhp_modify_eip(+1); } } } if (ok) { mhpdbgc.trapcmd = 0; rtncd = 1; mhpdbgc.stopped = 1; } } break; case DBG_PRE_VM86: mhp_pre_vm86(); break; case DBG_POLL: mhp_poll(); break; case DBG_GPF: if (!mhpdbg.active) break; mhpdbgc.stopped = 1; mhp_poll(); break; default: break; } if (mhpdbg.active) mhp_bpset(); return rtncd; }
int ipx_int7a(void) { u_short port; /* port here means DOS IPX socket */ u_short newPort; u_char *AddrPtr; far_t ECBPtr; unsigned long network; int hops, ticks; n_printf("IPX: request number 0x%x\n", LWORD(ebx)); switch (LWORD(ebx)) { case IPX_OPEN_SOCKET: if (LO(ax) != 0xff) n_printf("IPX: OpenSocket: longevity flag (%#x) not supported\n", LO(ax)); port = LWORD(edx); newPort = 0; LO(ax) = IPXOpenSocket(port, &newPort); if (LO(ax) == RCODE_SUCCESS) LWORD(edx) = newPort; break; case IPX_CLOSE_SOCKET: port = LWORD(edx); LO(ax) = IPXCloseSocket(port); break; case IPX_GET_LOCAL_TARGET: /* do nothing here because routing is handled by IPX */ /* normally this would return an ImmediateAddress, but */ /* the ECB ImmediateAddress is never used, so just return */ network = READ_DWORD(SEGOFF2LINEAR(REG(es), LWORD(esi))); n_printf("IPX: GetLocalTarget for network %08lx\n", network ); if( network==0 || memcmp(&network, MyAddress, 4) == 0 ) { n_printf("IPX: returning GLT success for local address\n"); LO(ax) = RCODE_SUCCESS; LWORD(ecx) = 1; } else { if( IPXGetLocalTarget( network, &hops, &ticks )==0 ) { LO(ax) = RCODE_SUCCESS; LWORD(ecx) = ticks; } else { n_printf("IPX: GetLocalTarget failed.\n"); LO(ax) = RCODE_CANNOT_FIND_ROUTE; } } break; case IPX_FAST_SEND: n_printf("IPX: fast send\n"); /* just fall through to regular send */ case IPX_SEND_PACKET: { int ret; ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: send packet ECB at %p\n", ECBp); /* What the hell is the async send? Do it synchroniously! */ ret = IPXSendPacket(ECBPtr); if ((ret == RCODE_SUCCESS) && FARt_PTR(ECBp->ESRAddress)) ipx_esr_call(ECBPtr, ESR_CALLOUT_IPX); LO(ax) = ret; break; } case IPX_LISTEN_FOR_PACKET: ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: listen for packet, ECB at %x:%x\n", ECBPtr.segment, ECBPtr.offset); /* put this packet on the queue of listens for this socket */ LO(ax) = IPXListenForPacket(ECBPtr); break; case IPX_SCHEDULE_IPX_EVENT: ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: schedule IPX event for ECB at %x:%x\n", ECBPtr.segment, ECBPtr.offset); /* put this packet on the queue of AES events for this socket */ LO(ax) = IPXScheduleEvent(ECBPtr, IU_ECB_IPX_WAITING, LWORD(eax)); break; case IPX_CANCEL_EVENT: ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: cancel event for ECB at %p\n", ECBp); LO(ax) = IPXCancelEvent(ECBPtr); break; case IPX_SCHEDULE_AES_EVENT: ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: schedule AES event ECB at %p\n", FARt_PTR(ECBPtr)); /* put this packet on the queue of AES events for this socket */ LO(ax) = IPXScheduleEvent(ECBPtr, IU_ECB_AES_WAITING, LWORD(eax)); break; case IPX_GET_INTERVAL_MARKER: /* Note that timerticks is actually an unsigned long in BIOS */ /* this works because of intel lo-hi architecture */ LWORD(eax) = READ_WORD(BIOS_TICK_ADDR); n_printf("IPX: get interval marker %d\n", LWORD(eax)); /* n_printf("IPX: doing extra relinquish control\n"); */ IPXRelinquishControl(); break; case IPX_GET_INTERNETWORK_ADDRESS: n_printf("IPX: get internetwork address\n"); AddrPtr = SEG_ADR((u_char *), es, si); memcpy(AddrPtr, MyAddress, 10); break; case IPX_RELINQUISH_CONTROL: n_printf("IPX: relinquish control\n"); IPXRelinquishControl(); break; case IPX_DISCONNECT: n_printf("IPX: disconnect\n"); break; case IPX_SHELL_HOOK: n_printf("IPX: shell hook\n"); break; case IPX_GET_MAX_PACKET_SIZE: n_printf("IPX: get max packet size\n"); /* return max data size in AX, and suggested retries in CL */ /* DANG_FIXTHIS - return a real max packet size here */ LWORD(eax) = 1024; /* must be a power of 2 */ LO(cx) = 20; break; case IPX_GET_MEDIA_DATA_SIZE: n_printf("IPX: get max packet size\n"); /* return max data size in AX, and suggested retries in CL */ /* DANG_FIXTHIS - return a real max media size here */ LWORD(eax) = 1480; LO(cx) = 20; break; case IPX_CLEAR_SOCKET: n_printf("IPX: clear socket\n"); break; default: n_printf("IPX: Unimplemented function.\n"); break; } return 1; }
void do_vesa_int() { int err_code = VBE_ERROR_GENERAL_FAIL; #if 0 v_printf( "VBE: function 0x%02x, bx = 0x%04x cx = 0x%04x, dx = 0x%04x, es = 0x%04x, di = 0x%04x\n", (unsigned) _AL, (unsigned) _BX, (unsigned) _CX, (unsigned) _DX, (unsigned) _ES, (unsigned) _DI ); #endif switch(_AL) { case 0x00: /* return VBE controller info */ err_code = vbe_info(SEGOFF2LINEAR(_ES, _DI)); break; case 0x01: /* return VBE mode info */ err_code = vbe_mode_info(_CX, SEGOFF2LINEAR(_ES, _DI)); break; case 0x02: /* set VBE mode */ err_code = vbe_set_mode(_BX); break; case 0x03: /* get current VBE mode */ err_code = vbe_get_mode(); break; case 0x04: /* save/restore state */ err_code = vbe_save_restore(_DL, _CX, SEGOFF2LINEAR(_ES, _BX)); break; case 0x05: /* display window control (aka set/get bank) */ err_code = vbe_display_window(_BH, _BL, _DL /* must be _DX !!!*/); break; case 0x06: /* set/get logical scan line length */ err_code = vbe_scan_length(_BL, _CX); break; case 0x07: /* set/get display start */ err_code = vbe_display_start(_BL, _CX, _DX); break; case 0x08: /* set/get DAC palette format */ err_code = vbe_dac_format(_BL, _BH); break; case 0x09: /* set/get palette data */ err_code = vbe_palette_data(_BL, _CX, _DX, SEGOFF2LINEAR(_ES, _DI)); break; case 0x0a: /* return VBE PM interface */ err_code = vbe_pm_interface(_BL); break; case 0x10: /* set/get display power state */ err_code = vbe_power_state(_BL, _BH); break; default: err_code = VBE_ERROR_UNSUP; #ifdef DEBUG_VBE v_printf( "VBE: unsupported function 0x%02x, retval = %d, bx = 0x%04x cx = 0x%04x, dx = 0x%04x, es = 0x%04x, di = 0x%04x\n", (unsigned) _AL, err_code, (unsigned) _BX, (unsigned) _CX, (unsigned) _DX, (unsigned) _ES, (unsigned) _DI ); #endif } if(err_code >= 0) { _AL = 0x4f; _AH = (unsigned char) err_code; } }
void vbe_pre_init(void) { int i; vga_mode_info *vmi = NULL; unsigned int dos_vga_bios = SEGOFF2LINEAR(0xc000,0x0000); int bios_ptr = (char *) vgaemu_bios_end - (char *) vgaemu_bios_start; static struct { char modes[3]; char reserved1[4]; char scanlines; char character_blocks; char max_active_blocks; short support_flags; short reserved2; char save_function_flags; char reserved3; } vgaemu_bios_functionality_table = { .modes = {0xff,0xe0,0x0f}, /* Modes 0-7, 0dh-0fh, 10h-13h supported */ .scanlines = 7, /* scanlines 200,350,400 supported */ .character_blocks = 2, /* This all corresponds to a real BIOS */ .max_active_blocks = 8, /* See Ralf Brown's interrupt list */ .support_flags = 0xeff, /* INT 10h, AH=1b for documentation */ .save_function_flags=0x3f }; MEMSET_DOS(dos_vga_bios, 0, VBE_BIOS_MAXPAGES << 12); /* one page */ MEMCPY_2DOS(dos_vga_bios, vgaemu_bios_start, bios_ptr); vgaemu_bios.prod_name = (char *) vgaemu_bios_prod_name - (char *) vgaemu_bios_start; if (Video->setmode) { i = (char *) vgaemu_bios_pm_interface_end - (char *) vgaemu_bios_pm_interface; if(i + bios_ptr > (VBE_BIOS_MAXPAGES << 12) - 8) { error("VBE: vbe_init: protected mode interface to large, disabling\n"); vgaemu_bios.vbe_pm_interface_len = vgaemu_bios.vbe_pm_interface = 0; } vgaemu_bios.vbe_pm_interface_len = i; vgaemu_bios.vbe_pm_interface = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vgaemu_bios_pm_interface, i); bios_ptr += i; bios_ptr = (bios_ptr + 3) & ~3; vgaemu_bios.vbe_mode_list = bios_ptr; /* set up video mode list */ for(i = 0x100; i <= vgaemu_bios.vbe_last_mode; i++) { if((vmi = vga_emu_find_mode(i, NULL))) { if(vmi->VESA_mode != -1 && bios_ptr < ((VBE_BIOS_MAXPAGES << 12) - 4)) { WRITE_WORD(dos_vga_bios + bios_ptr, vmi->VESA_mode); bios_ptr += 2; } } } WRITE_WORD(dos_vga_bios + bios_ptr, -1); bios_ptr += 2; /* add fonts */ vgaemu_bios.font_8 = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_08, sizeof vga_rom_08); bios_ptr += sizeof vga_rom_08; vgaemu_bios.font_14 = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_14, sizeof vga_rom_14); bios_ptr += sizeof vga_rom_14; vgaemu_bios.font_16 = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_16, sizeof vga_rom_16); bios_ptr += sizeof vga_rom_16; vgaemu_bios.font_14_alt = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_14_alt, sizeof vga_rom_14_alt); bios_ptr += sizeof vga_rom_14_alt; vgaemu_bios.font_16_alt = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_16_alt, sizeof vga_rom_16_alt); bios_ptr += sizeof vga_rom_16_alt; } else { /* only support the initial video mode, can't change it */ vgaemu_bios_functionality_table.modes[0] = 1 << video_mode; vgaemu_bios_functionality_table.modes[1] = vgaemu_bios_functionality_table.modes[2] = 0; } vgaemu_bios.functionality = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, &vgaemu_bios_functionality_table, sizeof vgaemu_bios_functionality_table); bios_ptr += sizeof vgaemu_bios_functionality_table; vgaemu_bios.size = bios_ptr; WRITE_BYTE(dos_vga_bios + 2, (bios_ptr + ((1 << 9) - 1)) >> 9); vgaemu_bios.pages = (bios_ptr + ((1 << 12) - 1)) >> 12; if (config.vgaemubios_file) { /* EXPERIMENTAL: load and boot the Bochs BIOS */ int fd = open(config.vgaemubios_file, O_RDONLY); int bytes; if (fd != -1) { bytes = read(fd, LINEAR2UNIX(0xc0000), 65536); close(fd); vgaemu_bios.pages = (bytes + PAGE_SIZE - 1) / PAGE_SIZE; config.vbios_post = 1; } } memcheck_addtype('V', "VGAEMU Video BIOS"); memcheck_reserve('V', dos_vga_bios, vgaemu_bios.pages << 12); if(!config.X_pm_interface) { v_printf("VBE: vbe_init: protected mode interface disabled\n"); } v_printf( "VBE: vbe_init: %d pages for VGA BIOS, vga.mem.base = %p\n", vgaemu_bios.pages, vga.mem.base ); }
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; }
int commands_plugin_inte6(void) { #define MAX_ARGS 63 char *args[MAX_ARGS + 1]; struct PSP *psp; struct MCB *mcb; struct com_program_entry *com; int argc; if (pool_used >= MAX_NESTING) { com_error("Cannot invoke more than %i builtins\n", MAX_NESTING); return 0; } if (!pool_used) { if (!(lowmem_pool = lowmem_heap_alloc(LOWMEM_POOL_SIZE))) { error("Unable to allocate memory pool\n"); return 0; } sminit(&mp, lowmem_pool, LOWMEM_POOL_SIZE); } pool_used++; BMEM(allocated) = 0; BMEM(retcode) = 0; if (HI(ax) != BUILTINS_PLUGIN_VERSION) { com_error("builtins plugin version mismatch: found %i, required %i\n", HI(ax), BUILTINS_PLUGIN_VERSION); com_error("You should update your generic.com, ems.sys, isemu.com and other utilities\n" "from the latest dosemu package!\n"); commands_plugin_inte6_done(); return 0; } psp = COM_PSP_ADDR; mcb = LOWMEM(SEGOFF2LINEAR(COM_PSP_SEG - 1,0)); /* first parse commandline */ args[0] = strdup(com_getarg0()); strupperDOS(args[0]); argc = com_argparse((char *)&psp->cmdline_len, &args[1], MAX_ARGS - 1) + 1; /* DOS 4 and up */ strncpy(builtin_name, mcb->name, sizeof(builtin_name) - 1); builtin_name[sizeof(builtin_name) - 1] = 0; strupperDOS(builtin_name); com = find_com_program(builtin_name); /* DOS 3.0->3.31 construct the program name from the environment */ if(!com) { char *p = strrchr(args[0],'\\'); strncpy(builtin_name, p+1, sizeof(builtin_name) - 1); builtin_name[sizeof(builtin_name) - 1] = 0; p = strchr(builtin_name, '.'); if(p) *p = '\0'; com = find_com_program(builtin_name); } if (com) { int err = com->program(argc, args); if (!err) { NOCARRY; } else { CARRY; _AL = err; } } else { com_error("inte6: unknown builtin: %s\n",builtin_name); CARRY; _AL = 1; } free(args[0]); return 1; }