bool get_lvds_mode_from_bios(display_mode* sharedInfo) { if (!get_bios()) return false; int vbtOffset = vbios.ReadWord(kVbtPointer); struct vbt_header* vbt = (struct vbt_header*)(vbios.memory + vbtOffset); int bdbOffset = vbtOffset + vbt->bdb_offset; struct bdb_header* bdb = (struct bdb_header*)(vbios.memory + bdbOffset); if (memcmp(bdb->signature, "BIOS_DATA_BLOCK ", 16) != 0) { TRACE((DEVICE_NAME": bad BDB signature\n")); delete_area(vbios.area); } TRACE((DEVICE_NAME": parsing BDB blocks\n")); int blockSize; int panelType = -1; for (int bdbBlockOffset = bdb->header_size; bdbBlockOffset < bdb->bdb_size; bdbBlockOffset += blockSize) { int start = bdbOffset + bdbBlockOffset; int id = vbios.memory[start]; blockSize = vbios.ReadWord(start + 1) + 3; // TRACE((DEVICE_NAME": found BDB block type %d\n", id)); switch (id) { case 40: // FIXME magic numbers { struct lvds_bdb1 *lvds1; lvds1 = (struct lvds_bdb1 *)(vbios.memory + start); panelType = lvds1->panel_type; break; } case 41: { if (panelType == -1) break; struct lvds_bdb2 *lvds2; struct lvds_bdb2_lfp_info *lvds2_lfp_info; lvds2 = (struct lvds_bdb2 *)(vbios.memory + start); lvds2_lfp_info = (struct lvds_bdb2_lfp_info *) (vbios.memory + bdbOffset + lvds2->panels[panelType].lfp_info_offset); /* found bad one terminator */ if (lvds2_lfp_info->terminator != 0xffff) { delete_area(vbios.area); return false; } uint8_t* timing_data = vbios.memory + bdbOffset + lvds2->panels[panelType].lfp_edid_dtd_offset; TRACE((DEVICE_NAME": found LFP of size %d x %d " "in BIOS VBT tables\n", lvds2_lfp_info->x_res, lvds2_lfp_info->y_res)); vbios.timings_common.hsync_start = _H_ACTIVE(timing_data) + _H_SYNC_OFF(timing_data); vbios.timings_common.hsync_end = vbios.timings_common.hsync_start + _H_SYNC_WIDTH(timing_data); vbios.timings_common.hsync_total = _H_ACTIVE(timing_data) + _H_BLANK(timing_data); vbios.timings_common.vsync_start = _V_ACTIVE(timing_data) + _V_SYNC_OFF(timing_data); vbios.timings_common.vsync_end = vbios.timings_common.vsync_start + _V_SYNC_WIDTH(timing_data); vbios.timings_common.vsync_total = _V_ACTIVE(timing_data) + _V_BLANK(timing_data); vbios.shared_info = sharedInfo; return feed_shared_info(timing_data); } } } delete_area(vbios.area); return true; }
void PicoMemSetup32x(void) { unsigned int rs; int i; if (!Pico32xMem) Pico32xMem = malloc(sizeof(*Pico32xMem)); if (Pico32xMem == NULL) { elprintf(EL_STATUS, "OOM"); return; } get_bios(); // cartridge area becomes unmapped // XXX: we take the easy way and don't unmap ROM, // so that we can avoid handling the RV bit. // m68k_map_unmap(0x000000, 0x3fffff); if (!Pico.m.ncart_in) { // MD ROM area rs = sizeof(Pico32xMem->m68k_rom_bank); cpu68k_map_set(m68k_read8_map, 0x000000, rs - 1, Pico32xMem->m68k_rom_bank, 0); cpu68k_map_set(m68k_read16_map, 0x000000, rs - 1, Pico32xMem->m68k_rom_bank, 0); cpu68k_map_set(m68k_write8_map, 0x000000, rs - 1, PicoWrite8_hint, 1); // TODO verify cpu68k_map_set(m68k_write16_map, 0x000000, rs - 1, PicoWrite16_hint, 1); // 32X ROM (unbanked, XXX: consider mirroring?) rs = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK; if (rs > 0x80000) rs = 0x80000; cpu68k_map_set(m68k_read8_map, 0x880000, 0x880000 + rs - 1, Pico.rom, 0); cpu68k_map_set(m68k_read16_map, 0x880000, 0x880000 + rs - 1, Pico.rom, 0); cpu68k_map_set(m68k_write8_map, 0x880000, 0x880000 + rs - 1, PicoWrite8_cart, 1); cpu68k_map_set(m68k_write16_map, 0x880000, 0x880000 + rs - 1, PicoWrite16_cart, 1); #ifdef EMU_F68K // setup FAME fetchmap PicoCpuFM68k.Fetch[0] = (unsigned long)Pico32xMem->m68k_rom; for (rs = 0x88; rs < 0x90; rs++) PicoCpuFM68k.Fetch[rs] = (unsigned long)Pico.rom - 0x880000; #endif // 32X ROM (banked) bank_switch(0); cpu68k_map_set(m68k_write8_map, 0x900000, 0x9fffff, PicoWrite8_bank, 1); cpu68k_map_set(m68k_write16_map, 0x900000, 0x9fffff, PicoWrite16_bank, 1); } // SYS regs cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_32x_on, 1); cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_32x_on, 1); cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_32x_on, 1); cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_32x_on, 1); // SH2 maps: A31,A30,A29,CS1,CS0 // all unmapped by default for (i = 0; i < ARRAY_SIZE(sh2_read8_map); i++) { sh2_read8_map[i].addr = MAP_HANDLER(sh2_read8_unmapped); sh2_read16_map[i].addr = MAP_HANDLER(sh2_read16_unmapped); } for (i = 0; i < ARRAY_SIZE(sh2_write8_map); i++) { sh2_write8_map[i] = sh2_write8_unmapped; sh2_write16_map[i] = sh2_write16_unmapped; } // "purge area" for (i = 0x40; i <= 0x5f; i++) { sh2_write8_map[i >> 1] = sh2_write16_map[i >> 1] = sh2_write_ignore; } // CS0 sh2_read8_map[0x00/2].addr = sh2_read8_map[0x20/2].addr = MAP_HANDLER(sh2_read8_cs0); sh2_read16_map[0x00/2].addr = sh2_read16_map[0x20/2].addr = MAP_HANDLER(sh2_read16_cs0); sh2_write8_map[0x00/2] = sh2_write8_map[0x20/2] = sh2_write8_cs0; sh2_write16_map[0x00/2] = sh2_write16_map[0x20/2] = sh2_write16_cs0; // CS1 - ROM sh2_read8_map[0x02/2].addr = sh2_read8_map[0x22/2].addr = sh2_read16_map[0x02/2].addr = sh2_read16_map[0x22/2].addr = MAP_MEMORY(Pico.rom); sh2_read8_map[0x02/2].mask = sh2_read8_map[0x22/2].mask = sh2_read16_map[0x02/2].mask = sh2_read16_map[0x22/2].mask = 0x3fffff; // FIXME // CS2 - DRAM - done by Pico32xSwapDRAM() sh2_read8_map[0x04/2].mask = sh2_read8_map[0x24/2].mask = sh2_read16_map[0x04/2].mask = sh2_read16_map[0x24/2].mask = 0x01ffff; // CS3 - SDRAM sh2_read8_map[0x06/2].addr = sh2_read8_map[0x26/2].addr = sh2_read16_map[0x06/2].addr = sh2_read16_map[0x26/2].addr = MAP_MEMORY(Pico32xMem->sdram); sh2_write8_map[0x06/2] = sh2_write8_sdram; sh2_write8_map[0x26/2] = sh2_write8_sdram_wt; sh2_write16_map[0x06/2] = sh2_write16_map[0x26/2] = sh2_write16_sdram; sh2_read8_map[0x06/2].mask = sh2_read8_map[0x26/2].mask = sh2_read16_map[0x06/2].mask = sh2_read16_map[0x26/2].mask = 0x03ffff; // SH2 data array sh2_read8_map[0xc0/2].addr = MAP_HANDLER(sh2_read8_da); sh2_read16_map[0xc0/2].addr = MAP_HANDLER(sh2_read16_da); sh2_write8_map[0xc0/2] = sh2_write8_da; sh2_write16_map[0xc0/2] = sh2_write16_da; // SH2 IO sh2_read8_map[0xff/2].addr = MAP_HANDLER(sh2_peripheral_read8); sh2_read16_map[0xff/2].addr = MAP_HANDLER(sh2_peripheral_read16); sh2_write8_map[0xff/2] = sh2_peripheral_write8; sh2_write16_map[0xff/2] = sh2_peripheral_write16; // map DRAM area, both 68k and SH2 Pico32xSwapDRAM(1); msh2.read8_map = ssh2.read8_map = sh2_read8_map; msh2.read16_map = ssh2.read16_map = sh2_read16_map; msh2.write8_tab = ssh2.write8_tab = (const void **)(void *)sh2_write8_map; msh2.write16_tab = ssh2.write16_tab = (const void **)(void *)sh2_write16_map; // z80 hack z80_map_set(z80_write_map, 0x8000, 0xffff, z80_md_bank_write_32x, 1); }