Пример #1
0
static int ReadVTOC(int drive, Bit16u volume, unsigned char *buf)
{
	char id[5];
	Bit8u type;
	int error = ReadSectors(drive, 16 + volume, 1, buf);
	if (error)
		return error;
	MEMCPY_2UNIX(id, buf + 1, 5);
	if (memcmp("CD001", id, 5) != 0)
		return MSCDEX_ERROR_BAD_FORMAT;
	type = READ_BYTE(buf);
	return 0;
}
Пример #2
0
static void dma_process_channel(int dma_idx, int chan_idx)
{
    struct dma_channel *chan = &dma[dma_idx].chans[chan_idx];
    Bit32u addr = (chan->page << 16) | (chan->cur_addr.value << dma_idx);
    Bit8u mode = chan->mode;

    /* first, do the transfer */
    switch (mode & 3) {
    case 0:			/* verify */
	q_printf("DMA: verify mode does nothing\n");
	break;
    case 1:			/* write */
	MEMCPY_2DOS(addr, dma_data_bus, 1 << dma_idx);
	break;
    case 2:			/* read */
	MEMCPY_2UNIX(dma_data_bus, addr, 1 << dma_idx);
	break;
    case 3:			/* invalid */
	q_printf("DMA: invalid mode does nothing\n");
	break;
    }

    /* now advance the address */
    if (!(dma[dma_idx].command & 2))
	chan->cur_addr.value += (mode & 8) ? -1 : 1;

    /* and the counter */
    chan->cur_count.value--;
    if (chan->cur_count.value == 0xffff) {	/* overflow */
	if (mode & 4) {		/* auto-init */
	    q_printf("DMA: controller %i, channel %i reinitialized\n",
		     dma_idx, chan_idx);
	    chan->cur_addr.value = chan->base_addr.value;
	    chan->cur_count.value = chan->base_count.value;
	} else {		/* eop */
	    q_printf("DMA: controller %i, channel %i EOP\n", dma_idx,
		     chan_idx);
	    dma[dma_idx].status |= 1 << chan_idx;
	    dma[dma_idx].request &= ~(1 << chan_idx);
	    /* the datasheet says it gets automatically masked too */
	    dma[dma_idx].mask |= 1 << chan_idx;
	}
    }
}
Пример #3
0
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;
}
Пример #4
0
static int GetDirectoryEntry(int drive, int copyFlag, char *pathname,
			     Bit32u buffer)
{
	char searchName[256];
	int error, dirSize;
	unsigned char defBuffer[CD_FRAMESIZE];
	unsigned dirEntrySector, entryLength, index;
	char *searchPos = searchName;
	size_t searchlen;

	/* skip initial \ */
	MEMCPY_2UNIX(searchName, pathname + 1, 255);
	searchName[255] = '\0';
	strupperDOS(searchName);

	//strip of tailing . (XCOM APOCALIPSE)
	searchlen = strlen(searchName);
	if (searchlen > 1 && strcmp(searchName, ".."))
		if (searchName[searchlen - 1] == '.')
			searchName[searchlen - 1] = 0;

	C_printf("MSCDEX: Get DirEntry : Find : %s\n", searchName);
	// read vtoc
	error = ReadSectors(drive, 16, 1, defBuffer);
	if (error)
		return error;
	// TODO: has to be iso 9660
	if (memcmp("CD001", defBuffer + 1, 5) != 0)
		return MSCDEX_ERROR_BAD_FORMAT;
	// get directory position
	dirEntrySector = *(unsigned *)(defBuffer + 156 + 2);
	dirSize = *(int *)(defBuffer + 156 + 10);
	do {
		// Get string part
		char *useName = searchPos;
		size_t useNameLength;

		searchPos = strchr(searchPos, '\\');

		if (searchPos) {
			useNameLength = searchPos - useName;
			searchPos++;
		} else
			useNameLength = strlen(useName);

		while (1) {
			error =
			    ReadSectors(drive, dirEntrySector, 1, defBuffer);
			if (error)
				return error;
			index = 0;

			do {
				char *entryName, *longername;
				unsigned nameLength;

				entryLength = defBuffer[index];
				C_printf("MSCDEX: entryLength=%u, index=%d\n",
					 entryLength, index);
				if (entryLength == 0)
					break;
				nameLength = defBuffer[index + 32];
				entryName = defBuffer + index + 33;
				if (namecomp
				    (entryName, nameLength, useName,
				     useNameLength))
					break;
				/* Xcom Apocalipse searches for MUSIC.
				 * and expects to find MUSIC;1
				 * All Files on the CDROM are of the kind
				 * blah;1
				 */
				longername = memchr(entryName, ';', nameLength);
				if (longername &&
				    namecomp(entryName, longername - entryName,
					     useName, useNameLength))
					break;
				index += entryLength;
			} while (index + 33 <= CD_FRAMESIZE);
			if (index + 33 <= CD_FRAMESIZE)
				break;
			// continue search in next sector
			dirSize -= 2048;
			if (dirSize <= 0)
				return 2;	// file not found
			dirEntrySector++;
		}
		// directory wechseln
		dirEntrySector = *(unsigned *)(defBuffer + index + 2);
		dirSize = *(unsigned *)(defBuffer + index + 10);
	} while (searchPos);
	return fill_buffer(copyFlag, buffer, defBuffer + index, entryLength);
};