ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/slot_rom.cpp
Revision: 1.9
Committed: 2001-06-29T12:51:20Z (23 years, 5 months ago) by cebix
Branch: MAIN
Changes since 1.8: +30 -11 lines
Log Message:
slot ROM checksum is recalculated after patching during resolution switch

File Contents

# Content
1 /*
2 * slot_rom.cpp - Slot declaration ROM
3 *
4 * Basilisk II (C) 1996-2001 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 /*
22 * SEE ALSO
23 * Inside Macintosh: Devices, chapter 2 "Slot Manager"
24 * Designing Cards and Drivers for the Macintosh Family, Second Edition
25 */
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "sysdeps.h"
31 #include "cpu_emulation.h"
32 #include "main.h"
33 #include "video.h"
34 #include "emul_op.h"
35 #include "version.h"
36 #include "slot_rom.h"
37
38
39 // Temporary buffer for slot ROM
40 static uint8 srom[4096];
41
42 // Index in srom
43 static uint32 p;
44
45 // Length of slot ROM
46 static int slot_rom_size = 0;
47
48
49 // Check whether a mode with the specified depth exists
50 static bool has_depth(video_depth depth)
51 {
52 std::vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
53 while (i != end) {
54 if (i->depth == depth)
55 return true;
56 ++i;
57 }
58 return false;
59 }
60
61
62 /*
63 * Construct slot declaration ROM and copy it into the Mac ROM (must be called after VideoInit())
64 */
65
66 static void Offs(uint8 type, uint32 ptr)
67 {
68 uint32 offs = ptr - p;
69 srom[p++] = type;
70 srom[p++] = offs >> 16;
71 srom[p++] = offs >> 8;
72 srom[p++] = offs;
73 }
74
75 static void Rsrc(uint8 type, uint32 data)
76 {
77 srom[p++] = type;
78 srom[p++] = data >> 16;
79 srom[p++] = data >> 8;
80 srom[p++] = data;
81 }
82
83 static void EndOfList(void)
84 {
85 srom[p++] = 0xff;
86 srom[p++] = 0;
87 srom[p++] = 0;
88 srom[p++] = 0;
89 }
90
91 static void Long(uint32 data)
92 {
93 srom[p++] = data >> 24;
94 srom[p++] = data >> 16;
95 srom[p++] = data >> 8;
96 srom[p++] = data;
97 }
98
99 static void Word(uint16 data)
100 {
101 srom[p++] = data >> 8;
102 srom[p++] = data;
103 }
104
105 static void String(char *str)
106 {
107 while ((srom[p++] = *str++) != 0) ;
108 if (p & 1)
109 srom[p++] = 0;
110 }
111
112 static void PString(char *str)
113 {
114 srom[p++] = strlen(str);
115 while ((srom[p++] = *str++) != 0) ;
116 p--;
117 if (p & 1)
118 srom[p++] = 0;
119 }
120
121 static uint32 VModeParms(uint32 width, uint32 height, uint32 bytes_per_row, video_depth depth)
122 {
123 uint32 ret = p;
124 Long(50); // Length
125 Long(0); // Base offset
126 Word(bytes_per_row); // Row bytes
127 Word(0); // Bounds
128 Word(0);
129 Word(height);
130 Word(width);
131 Word(0); // Version
132 Word(0); // Pack type
133 Long(0); // Pack size
134 Long(0x00480000); // HRes
135 Long(0x00480000); // VRes
136 switch (depth) {
137 case VDEPTH_1BIT:
138 Word(0); // Pixel type (indirect)
139 Word(1); // Pixel size
140 Word(1); // CmpCount
141 Word(1); // CmpSize
142 break;
143 case VDEPTH_2BIT:
144 Word(0); // Pixel type (indirect)
145 Word(2); // Pixel size
146 Word(1); // CmpCount
147 Word(2); // CmpSize
148 break;
149 case VDEPTH_4BIT:
150 Word(0); // Pixel type (indirect)
151 Word(4); // Pixel size
152 Word(1); // CmpCount
153 Word(4); // CmpSize
154 break;
155 case VDEPTH_8BIT:
156 Word(0); // Pixel type (indirect)
157 Word(8); // Pixel size
158 Word(1); // CmpCount
159 Word(8); // CmpSize
160 break;
161 case VDEPTH_16BIT:
162 Word(16); // Pixel type (direct)
163 Word(16); // Pixel size
164 Word(3); // CmpCount
165 Word(5); // CmpSize
166 break;
167 case VDEPTH_32BIT:
168 Word(16); // Pixel type (direct)
169 Word(32); // Pixel size
170 Word(3); // CmpCount
171 Word(8); // CmpSize
172 break;
173 }
174 Long(0); // Plane size
175 Long(0); // Reserved
176 return ret;
177 }
178
179 static uint32 VModeDesc(uint32 params, bool direct)
180 {
181 uint32 ret = p;
182 Offs(0x01, params); // Video parameters
183 Rsrc(0x03, 1); // Page count
184 Rsrc(0x04, direct ? 2 : 0); // Device type
185 EndOfList();
186 return ret;
187 }
188
189 bool InstallSlotROM(void)
190 {
191 uint32 boardType, boardName, vendorID, revLevel, partNum, date;
192 uint32 vendorInfo, sRsrcBoard;
193
194 uint32 videoType, videoName, minorBase, minorLength, videoDrvr, vidDrvrDir;
195 uint32 defaultGamma, gammaDir, sRsrcVideo;
196 uint32 vidModeParms1, vidModeParms2, vidModeParms4, vidModeParms8, vidModeParms16, vidModeParms32;
197 uint32 vidMode1, vidMode2, vidMode4, vidMode8, vidMode16, vidMode32;
198
199 uint32 cpuType, cpuName, cpuMajor, cpuMinor, sRsrcCPU;
200
201 uint32 etherType, etherName, etherDrvr, etherDrvrDir, sRsrcEther;
202
203 uint32 sRsrcDir;
204
205 char str[256];
206 p = 0;
207
208 // Board sResource
209 boardType = p; // Literals
210 Word(1); Word(0); Word(0); Word(0); // Board sResource
211 boardName = p;
212 String("Basilisk II Slot ROM");
213 vendorID = p;
214 String("Christian Bauer");
215 revLevel = p;
216 sprintf(str, "V%d.%d", VERSION_MAJOR, VERSION_MINOR);
217 String(str);
218 partNum = p;
219 String("BasiliskII");
220 date = p;
221 String(__DATE__);
222
223 vendorInfo = p; // Vendor Info
224 Offs(0x01, vendorID); // Vendor ID
225 Offs(0x03, revLevel); // Revision level
226 Offs(0x04, partNum); // Part number
227 Offs(0x05, date); // ROM build date
228 EndOfList();
229
230 sRsrcBoard = p;
231 Offs(0x01, boardType); // Board descriptor
232 Offs(0x02, boardName); // Board name
233 Rsrc(0x20, 0x4232); // Board ID ('B2')
234 Offs(0x24, vendorInfo); // Vendor Info
235 EndOfList();
236
237 // Video sResource for default mode
238 videoType = p; // Literals
239 Word(3); Word(1); Word(1); Word(0x4232); // Display Video Apple 'B2'
240 videoName = p;
241 String("Display_Video_Apple_Basilisk");
242 minorBase = p;
243 Long(VideoMonitor.mac_frame_base); // Frame buffer base
244 minorLength = p;
245 Long(0); // Frame buffer size (unspecified)
246
247 videoDrvr = p; // Video driver
248 Long(0x72); // Length
249 Word(0x4c00); Word(0); Word(0); Word(0);
250 Word(0x32); // Open offset
251 Word(0x36); // Prime offset
252 Word(0x3a); // Control offset
253 Word(0x46); // Status offset
254 Word(0x6c); // Close offset
255 PString(".Display_Video_Apple_Basilisk");
256 Word(1); // Driver version
257 Word(M68K_EMUL_OP_VIDEO_OPEN); // Open()
258 Word(0x4e75);
259 Word(0x70ff); // Prime()
260 Word(0x600e);
261 Word(M68K_EMUL_OP_VIDEO_CONTROL); // Control()
262 Word(0x0c68); Word(0x0001); Word(0x001a);
263 Word(0x6604);
264 Word(0x4e75);
265 Word(M68K_EMUL_OP_VIDEO_STATUS); // Status()
266 Word(0x3228); Word(0x0006); // IOReturn
267 Word(0x0801); Word(0x0009);
268 Word(0x670c);
269 Word(0x4a40);
270 Word(0x6f02);
271 Word(0x4240);
272 Word(0x3140); Word(0x0010);
273 Word(0x4e75);
274 Word(0x4a40);
275 Word(0x6f04);
276 Word(0x4240);
277 Word(0x4e75);
278 Word(0x2f38); Word(0x08fc);
279 Word(0x4e75);
280 Word(0x70e8); // Close()
281 Word(0x4e75);
282
283 vidDrvrDir = p; // Driver directory
284 Offs(0x02, videoDrvr); // sMacOS68020
285 EndOfList();
286
287 defaultGamma = p; // Gamma table
288 Long(38 + 0x100); // Length
289 Word(0x2000); // Resource ID
290 String("Mac HiRes Std Gamma");
291 Word(0); // Version
292 Word(0); // Type
293 Word(0); // FormulaSize
294 Word(1); // ChanCnt
295 Word(0x0100); // DataCnt
296 Word(8); // ChanWidth
297 Long(0x0005090B); Long(0x0E101315); Long(0x17191B1D); Long(0x1E202224);
298 Long(0x2527282A); Long(0x2C2D2F30); Long(0x31333436); Long(0x37383A3B);
299 Long(0x3C3E3F40); Long(0x42434445); Long(0x4748494A); Long(0x4B4D4E4F);
300 Long(0x50515254); Long(0x55565758); Long(0x595A5B5C); Long(0x5E5F6061);
301 Long(0x62636465); Long(0x66676869); Long(0x6A6B6C6D); Long(0x6E6F7071);
302 Long(0x72737475); Long(0x76777879); Long(0x7A7B7C7D); Long(0x7E7F8081);
303 Long(0x81828384); Long(0x85868788); Long(0x898A8B8C); Long(0x8C8D8E8F);
304 Long(0x90919293); Long(0x94959596); Long(0x9798999A); Long(0x9B9B9C9D);
305 Long(0x9E9FA0A1); Long(0xA1A2A3A4); Long(0xA5A6A6A7); Long(0xA8A9AAAB);
306 Long(0xABACADAE); Long(0xAFB0B0B1); Long(0xB2B3B4B4); Long(0xB5B6B7B8);
307 Long(0xB8B9BABB); Long(0xBCBCBDBE); Long(0xBFC0C0C1); Long(0xC2C3C3C4);
308 Long(0xC5C6C7C7); Long(0xC8C9CACA); Long(0xCBCCCDCD); Long(0xCECFD0D0);
309 Long(0xD1D2D3D3); Long(0xD4D5D6D6); Long(0xD7D8D9D9); Long(0xDADBDCDC);
310 Long(0xDDDEDFDF); Long(0xE0E1E1E2); Long(0xE3E4E4E5); Long(0xE6E7E7E8);
311 Long(0xE9E9EAEB); Long(0xECECEDEE); Long(0xEEEFF0F1); Long(0xF1F2F3F3);
312 Long(0xF4F5F5F6); Long(0xF7F8F8F9); Long(0xFAFAFBFC); Long(0xFCFDFEFF);
313
314 gammaDir = p; // Gamma directory
315 Offs(0x80, defaultGamma);
316 EndOfList();
317
318 vidModeParms1 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_1BIT);
319 vidModeParms2 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_2BIT);
320 vidModeParms4 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_4BIT);
321 vidModeParms8 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_8BIT);
322 vidModeParms16 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_16BIT);
323 vidModeParms32 = VModeParms(VideoMonitor.mode.x, VideoMonitor.mode.y, VideoMonitor.mode.bytes_per_row, VDEPTH_32BIT);
324
325 vidMode1 = VModeDesc(vidModeParms1, false);
326 vidMode2 = VModeDesc(vidModeParms2, false);
327 vidMode4 = VModeDesc(vidModeParms4, false);
328 vidMode8 = VModeDesc(vidModeParms8, false);
329 vidMode16 = VModeDesc(vidModeParms16, true);
330 vidMode32 = VModeDesc(vidModeParms32, true);
331
332 sRsrcVideo = p;
333 Offs(0x01, videoType); // Video type descriptor
334 Offs(0x02, videoName); // Driver name
335 Offs(0x04, vidDrvrDir); // Driver directory
336 Rsrc(0x08, 0x4232); // Hardware device ID ('B2')
337 Offs(0x0a, minorBase); // Frame buffer base
338 Offs(0x0b, minorLength); // Frame buffer length
339 Offs(0x40, gammaDir); // Gamma directory
340 Rsrc(0x7d, 6); // Video attributes: Default to color, built-in
341 if (has_depth(VDEPTH_1BIT))
342 Offs(0x80, vidMode1); // Video mode parameters for 1 bit
343 if (has_depth(VDEPTH_2BIT))
344 Offs(0x81, vidMode2); // Video mode parameters for 2 bit
345 if (has_depth(VDEPTH_4BIT))
346 Offs(0x82, vidMode4); // Video mode parameters for 4 bit
347 if (has_depth(VDEPTH_8BIT))
348 Offs(0x83, vidMode8); // Video mode parameters for 8 bit
349 if (has_depth(VDEPTH_16BIT))
350 Offs(0x84, vidMode16); // Video mode parameters for 16 bit
351 if (has_depth(VDEPTH_32BIT))
352 Offs(0x85, vidMode32); // Video mode parameters for 32 bit
353 EndOfList();
354
355 // CPU sResource
356 cpuType = p; // Literals
357 Word(10); Word(3); Word(0); Word(24); // CPU 68020
358 cpuName = p;
359 String("CPU_68020");
360 cpuMajor = p;
361 Long(0); Long(0x7fffffff);
362 cpuMinor = p;
363 Long(0xf0800000); Long(0xf0ffffff);
364
365 sRsrcCPU = p;
366 Offs(0x01, cpuType); // Type descriptor
367 Offs(0x02, cpuName); // CPU name
368 Offs(0x81, cpuMajor); // Major RAM space
369 Offs(0x82, cpuMinor); // Minor RAM space
370 EndOfList();
371
372 // Ethernet sResource
373 etherType = p; // Literals
374 Word(4); Word(1); Word(1); Word(0x4232); // Network Ethernet Apple 'B2'
375 etherName = p;
376 String("Network_Ethernet_Apple_BasiliskII");
377
378 etherDrvr = p; // Video driver
379 Long(0x88); // Length
380 Word(0x4400); Word(0); Word(0); Word(0);
381 Word(0x4a); // Open offset
382 Word(0x4e); // Prime offset
383 Word(0x52); // Control offset
384 Word(0x4e); // Status offset
385 Word(0x82); // Close offset
386 PString(".ENET");
387 Word(0x0111); Word(0x8000); // Driver version
388 Word(0);
389 PString("1.1.1 ");
390 PString("Basilisk II Ethernet Network Driver");
391 Word(M68K_EMUL_OP_ETHER_OPEN); // Open()
392 Word(0x4e75);
393 Word(0x70ef); // Prime()/Status()
394 Word(0x600c);
395 Word(M68K_EMUL_OP_ETHER_CONTROL); // Control()
396 Word(0x0c68); Word(0x0001); Word(0x001a);
397 Word(0x6602);
398 Word(0x4e75);
399 Word(0x3228); Word(0x0006); // IOReturn
400 Word(0x0801); Word(0x0009);
401 Word(0x670c);
402 Word(0x4a40);
403 Word(0x6f02);
404 Word(0x4240);
405 Word(0x3140); Word(0x0010);
406 Word(0x4e75);
407 Word(0x4a40);
408 Word(0x6f04);
409 Word(0x4240);
410 Word(0x4e75);
411 Word(0x2f38); Word(0x08fc);
412 Word(0x4e75);
413 Word(0x70e8); // Close()
414 Word(0x4e75);
415
416 etherDrvrDir = p; // Driver directory
417 Offs(0x02, etherDrvr); // sMacOS68020
418 EndOfList();
419
420 sRsrcEther = p;
421 Offs(0x01, etherType); // Type descriptor
422 Offs(0x02, etherName); // Driver name
423 Offs(0x04, etherDrvrDir); // Driver directory
424 Rsrc(0x07, 2); // Flags: OpenAtStart
425 Rsrc(0x08, 0x4232); // Hardware device ID ('B2')
426 EndOfList();
427
428 // sResource directory
429 sRsrcDir = p;
430 Offs(0x01, sRsrcBoard);
431 Offs(0x80, sRsrcVideo);
432 Offs(0xf0, sRsrcCPU);
433 Offs(0xf1, sRsrcEther);
434 EndOfList();
435
436 // Format/header block
437 Offs(0, sRsrcDir); // sResource directory
438 Long(p + 16); // Length of declaration data
439 Long(0); // CRC (calculated later)
440 Word(0x0101); // Rev. level, format
441 Long(0x5a932bc7); // Test pattern
442 Word(0x000f); // Byte lanes
443
444 // Copy slot ROM to Mac ROM
445 slot_rom_size = p;
446 memcpy(ROMBaseHost + ROMSize - slot_rom_size, srom, slot_rom_size);
447
448 // Calculate checksum
449 ChecksumSlotROM();
450 return true;
451 }
452
453 /*
454 * Calculate slot ROM checksum (in-place)
455 */
456
457 void ChecksumSlotROM(void)
458 {
459 // Calculate CRC
460 uint8 *p = ROMBaseHost + ROMSize - slot_rom_size;
461 p[slot_rom_size - 12] = 0;
462 p[slot_rom_size - 11] = 0;
463 p[slot_rom_size - 10] = 0;
464 p[slot_rom_size - 9] = 0;
465 uint32 crc = 0;
466 for (uint32 i=0; i<slot_rom_size; i++) {
467 crc = (crc << 1) | (crc >> 31);
468 crc += p[i];
469 }
470 p[slot_rom_size - 12] = crc >> 24;
471 p[slot_rom_size - 11] = crc >> 16;
472 p[slot_rom_size - 10] = crc >> 8;
473 p[slot_rom_size - 9] = crc;
474 }