ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/slot_rom.cpp
Revision: 1.15
Committed: 2004-01-12T15:29:22Z (20 years, 10 months ago) by cebix
Branch: MAIN
CVS Tags: nigel-build-16, nigel-build-15
Changes since 1.14: +1 -1 lines
Log Message:
Happy New Year! :)

File Contents

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