--- BasiliskII/src/slot_rom.cpp 1999/10/03 14:16:25 1.1.1.1 +++ BasiliskII/src/slot_rom.cpp 2010/02/21 12:00:01 1.18 @@ -1,7 +1,7 @@ /* * slot_rom.cpp - Slot declaration ROM * - * Basilisk II (C) 1996-1997 Christian Bauer + * Basilisk II (C) Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +42,9 @@ static uint8 srom[4096]; // Index in srom static uint32 p; +// Length of slot ROM +static int slot_rom_size = 0; + /* * Construct slot declaration ROM and copy it into the Mac ROM (must be called after VideoInit()) @@ -86,14 +89,14 @@ static void Word(uint16 data) srom[p++] = data; } -static void String(char *str) +static void String(const char *str) { while ((srom[p++] = *str++) != 0) ; if (p & 1) srom[p++] = 0; } -static void PString(char *str) +static void PString(const char *str) { srom[p++] = strlen(str); while ((srom[p++] = *str++) != 0) ; @@ -102,13 +105,134 @@ static void PString(char *str) srom[p++] = 0; } +static uint32 VModeParms(const monitor_desc &m, video_depth depth) +{ + const video_mode &mode = m.get_current_mode(); + + uint32 ret = p; + Long(50); // Length + Long(0); // Base offset + Word(m.get_bytes_per_row(depth, mode.resolution_id)); + Word(0); // Bounds + Word(0); + Word(mode.y); + Word(mode.x); + Word(0); // Version + Word(0); // Pack type + Long(0); // Pack size + Long(0x00480000); // HRes + Long(0x00480000); // VRes + switch (depth) { + case VDEPTH_1BIT: + Word(0); // Pixel type (indirect) + Word(1); // Pixel size + Word(1); // CmpCount + Word(1); // CmpSize + break; + case VDEPTH_2BIT: + Word(0); // Pixel type (indirect) + Word(2); // Pixel size + Word(1); // CmpCount + Word(2); // CmpSize + break; + case VDEPTH_4BIT: + Word(0); // Pixel type (indirect) + Word(4); // Pixel size + Word(1); // CmpCount + Word(4); // CmpSize + break; + case VDEPTH_8BIT: + Word(0); // Pixel type (indirect) + Word(8); // Pixel size + Word(1); // CmpCount + Word(8); // CmpSize + break; + case VDEPTH_16BIT: + Word(16); // Pixel type (direct) + Word(16); // Pixel size + Word(3); // CmpCount + Word(5); // CmpSize + break; + case VDEPTH_32BIT: + Word(16); // Pixel type (direct) + Word(32); // Pixel size + Word(3); // CmpCount + Word(8); // CmpSize + break; + } + Long(0); // Plane size + Long(0); // Reserved + return ret; +} + +static uint32 VModeDesc(uint32 params, bool direct) +{ + uint32 ret = p; + Offs(0x01, params); // Video parameters + Rsrc(0x03, 1); // Page count + Rsrc(0x04, direct ? 2 : 0); // Device type + EndOfList(); + return ret; +} + +static uint32 VMonitor(const monitor_desc &m, uint32 videoType, uint32 videoName, uint32 vidDrvrDir, uint32 gammaDir) +{ + uint32 minorBase, minorLength; + uint32 vidModeParms1, vidModeParms2, vidModeParms4, vidModeParms8, vidModeParms16, vidModeParms32; + uint32 vidMode1, vidMode2, vidMode4, vidMode8, vidMode16, vidMode32; + uint32 ret; + + minorBase = p; + Long(m.get_mac_frame_base()); // Frame buffer base + minorLength = p; + Long(0); // Frame buffer size (unspecified) + + vidModeParms1 = VModeParms(m, VDEPTH_1BIT); + vidModeParms2 = VModeParms(m, VDEPTH_2BIT); + vidModeParms4 = VModeParms(m, VDEPTH_4BIT); + vidModeParms8 = VModeParms(m, VDEPTH_8BIT); + vidModeParms16 = VModeParms(m, VDEPTH_16BIT); + vidModeParms32 = VModeParms(m, VDEPTH_32BIT); + + vidMode1 = VModeDesc(vidModeParms1, false); + vidMode2 = VModeDesc(vidModeParms2, false); + vidMode4 = VModeDesc(vidModeParms4, false); + vidMode8 = VModeDesc(vidModeParms8, false); + vidMode16 = VModeDesc(vidModeParms16, true); + vidMode32 = VModeDesc(vidModeParms32, true); + + ret = p; + Offs(0x01, videoType); // Video type descriptor + Offs(0x02, videoName); // Driver name + Offs(0x04, vidDrvrDir); // Driver directory + Rsrc(0x08, 0x4232); // Hardware device ID ('B2') + Offs(0x0a, minorBase); // Frame buffer base + Offs(0x0b, minorLength); // Frame buffer length + Offs(0x40, gammaDir); // Gamma directory + Rsrc(0x7d, 6); // Video attributes: Default to color, built-in + if (m.has_depth(VDEPTH_1BIT)) + Offs(m.depth_to_apple_mode(VDEPTH_1BIT), vidMode1); // Video mode parameters for 1 bit + if (m.has_depth(VDEPTH_2BIT)) + Offs(m.depth_to_apple_mode(VDEPTH_2BIT), vidMode2); // Video mode parameters for 2 bit + if (m.has_depth(VDEPTH_4BIT)) + Offs(m.depth_to_apple_mode(VDEPTH_4BIT), vidMode4); // Video mode parameters for 4 bit + if (m.has_depth(VDEPTH_8BIT)) + Offs(m.depth_to_apple_mode(VDEPTH_8BIT), vidMode8); // Video mode parameters for 8 bit + if (m.has_depth(VDEPTH_16BIT)) + Offs(m.depth_to_apple_mode(VDEPTH_16BIT), vidMode16); // Video mode parameters for 16 bit + if (m.has_depth(VDEPTH_32BIT)) + Offs(m.depth_to_apple_mode(VDEPTH_32BIT), vidMode32); // Video mode parameters for 32 bit + EndOfList(); + return ret; +} + bool InstallSlotROM(void) { uint32 boardType, boardName, vendorID, revLevel, partNum, date; uint32 vendorInfo, sRsrcBoard; - uint32 videoType, videoName, minorBase, minorLength, videoDrvr, vidDrvrDir; - uint32 defaultGamma, gammaDir, vidModeParms, vidMode, sRsrcVideo; + uint32 videoType, videoName, videoDrvr, vidDrvrDir; + uint32 defaultGamma, gammaDir; uint32 cpuType, cpuName, cpuMajor, cpuMinor, sRsrcCPU; @@ -116,7 +240,11 @@ bool InstallSlotROM(void) uint32 sRsrcDir; + vector::const_iterator m, mend = VideoMonitors.end(); + vector sRsrcVideo; + char str[256]; + int i; p = 0; // Board sResource @@ -148,15 +276,10 @@ bool InstallSlotROM(void) Offs(0x24, vendorInfo); // Vendor Info EndOfList(); - // Video sResource - videoType = p; // Literals - Word(3); Word(1); Word(1); Word(0x4232); // Display Video Apple 'B2' + videoType = p; + Word(3); Word(1); Word(1); Word(0x4232); // Display Video Apple 'B2' videoName = p; String("Display_Video_Apple_Basilisk"); - minorBase = p; - Long(VideoMonitor.mac_frame_base); // Frame buffer base - minorLength = p; - Long(VideoMonitor.bytes_per_row * VideoMonitor.y); // Frame buffer size videoDrvr = p; // Video driver Long(0x72); // Length @@ -229,77 +352,8 @@ bool InstallSlotROM(void) Offs(0x80, defaultGamma); EndOfList(); - vidModeParms = p; // Video mode parameters - Long(50); // Length - Long(0); // Base offset - Word(VideoMonitor.bytes_per_row); // Row bytes - Word(0); // Bounds - Word(0); - Word(VideoMonitor.y); - Word(VideoMonitor.x); - Word(0); // Version - Word(0); // Pack type - Long(0); // Pack size - Long(0x00480000); // HRes - Long(0x00480000); // VRes - switch (VideoMonitor.mode) { - case VMODE_1BIT: - Word(0); // Pixel type (indirect) - Word(1); // Pixel size - Word(1); // CmpCount - Word(1); // CmpSize - break; - case VMODE_2BIT: - Word(0); // Pixel type (indirect) - Word(2); // Pixel size - Word(1); // CmpCount - Word(2); // CmpSize - break; - case VMODE_4BIT: - Word(0); // Pixel type (indirect) - Word(4); // Pixel size - Word(1); // CmpCount - Word(4); // CmpSize - break; - case VMODE_8BIT: - Word(0); // Pixel type (indirect) - Word(8); // Pixel size - Word(1); // CmpCount - Word(8); // CmpSize - break; - case VMODE_16BIT: - Word(16); // Pixel type (direct) - Word(16); // Pixel size - Word(3); // CmpCount - Word(5); // CmpSize - break; - case VMODE_32BIT: - Word(16); // Pixel type (direct) - Word(32); // Pixel size - Word(3); // CmpCount - Word(8); // CmpSize - break; - } - Long(0); // Plane size - Long(0); // Reserved - - vidMode = p; // Video mode description - Offs(0x01, vidModeParms); // Video parameters - Rsrc(0x03, 1); // Page count - Rsrc(0x04, IsDirectMode(VideoMonitor.mode) ? 2 :0); // Device type - EndOfList(); - - sRsrcVideo = p; - Offs(0x01, videoType); // Video type descriptor - Offs(0x02, videoName); // Driver name - Offs(0x04, vidDrvrDir); // Driver directory - Rsrc(0x08, 0x4232); // Hardware device ID ('B2') - Offs(0x0a, minorBase); // Frame buffer base - Offs(0x0b, minorLength); // Frame buffer length - Offs(0x40, gammaDir); // Gamma directory - Rsrc(0x7d, 6); // Video attributes: Default to color, built-in - Offs(0x80, vidMode); // Video mode parameters - EndOfList(); + for (m = VideoMonitors.begin(); m != mend; ++m) + sRsrcVideo.push_back(VMonitor(**m, videoType, videoName, vidDrvrDir, gammaDir)); // CPU sResource cpuType = p; // Literals @@ -377,7 +431,8 @@ bool InstallSlotROM(void) // sResource directory sRsrcDir = p; Offs(0x01, sRsrcBoard); - Offs(0x80, sRsrcVideo); + for (m = VideoMonitors.begin(), i = 0; m != mend; ++m, ++i) + Offs((*m)->get_slot_id(), sRsrcVideo[i]); Offs(0xf0, sRsrcCPU); Offs(0xf1, sRsrcEther); EndOfList(); @@ -385,23 +440,39 @@ bool InstallSlotROM(void) // Format/header block Offs(0, sRsrcDir); // sResource directory Long(p + 16); // Length of declaration data - Long(0); // CRC (calculated below) + Long(0); // CRC (calculated later) Word(0x0101); // Rev. level, format Long(0x5a932bc7); // Test pattern Word(0x000f); // Byte lanes + // Copy slot ROM to Mac ROM + slot_rom_size = p; + memcpy(ROMBaseHost + ROMSize - slot_rom_size, srom, slot_rom_size); + + // Calculate checksum + ChecksumSlotROM(); + return true; +} + +/* + * Calculate slot ROM checksum (in-place) + */ + +void ChecksumSlotROM(void) +{ // Calculate CRC + uint8 *p = ROMBaseHost + ROMSize - slot_rom_size; + p[slot_rom_size - 12] = 0; + p[slot_rom_size - 11] = 0; + p[slot_rom_size - 10] = 0; + p[slot_rom_size - 9] = 0; uint32 crc = 0; - for (int i=0; i> 31); - crc += srom[i]; + crc += p[i]; } - srom[p - 12] = crc >> 24; - srom[p - 11] = crc >> 16; - srom[p - 10] = crc >> 8; - srom[p - 9] = crc; - - // Copy slot ROM to Mac ROM - memcpy(ROMBaseHost + ROMSize - p, srom, p); - return true; + p[slot_rom_size - 12] = crc >> 24; + p[slot_rom_size - 11] = crc >> 16; + p[slot_rom_size - 10] = crc >> 8; + p[slot_rom_size - 9] = crc; }