/* * 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 fill_buffer(int copyFlag, Bit32u buffer, unsigned char *readBuf, unsigned entryLength) { // TO DO : name gefunden, Daten in den Buffer kopieren if (copyFlag) { Bit8u writeBuf[256]; C_printf ("MSCDEX: GetDirEntry: Copyflag structure not entirely " "accurate maybe\n"); if (entryLength > 256) return MSCDEX_ERROR_BAD_FORMAT; // 00h BYTE length of XAR in Logical Block Numbers writeBuf[0] = readBuf[1]; // 01h DWORD Logical Block Number of file start memcpy(&writeBuf[1], &readBuf[0x2], 4); // 05h WORD size of disk in logical blocks writeBuf[5] = 0; writeBuf[6] = 8; // 07h DWORD file length in bytes memcpy(&writeBuf[7], &readBuf[0xa], 4); // 0bh DWORD date and time memcpy(&writeBuf[0xb], &readBuf[0x12], 7); // 12h BYTE bit flags writeBuf[0x12] = readBuf[0x19]; // 13h BYTE interleave size writeBuf[0x13] = readBuf[0x1a]; // 14h BYTE interleave skip factor writeBuf[0x14] = readBuf[0x1b]; // 15h WORD volume set sequence number memcpy(&writeBuf[0x15], &readBuf[0x1c], 2); writeBuf[0x17] = readBuf[0x20]; memcpy(&writeBuf[0x18], &readBuf[21], readBuf[0x20] <= 38 ? readBuf[0x20] : 38); MEMCPY_2DOS(buffer, writeBuf, 0x18 + 40); } else { // Direct copy MEMCPY_2DOS(buffer, readBuf, entryLength); } return 1; /* ISO 9660 */ }
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; } } }
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; }