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; }
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; } } }
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; }
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); };