ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/slot_rom.cpp
Revision: 1.14
Committed: 2002-04-25T11:00:30Z (22 years, 6 months ago) by cebix
Branch: MAIN
CVS Tags: nigel-build-12, nigel-build-13
Changes since 1.13: +66 -49 lines
Log Message:
- added infrastructure for multi-monitor support; only video_x.cpp is
  converted for the new scheme; not actually tested with a mult-monitor
  setup yet but at least single-monitor display doesn't seem to be broken
  (UAE banked addressing would definitely require some extensions to handle
  multiple frame buffers)
- struct video_mode has an extra field that is free for use by platform-
  specific code

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * slot_rom.cpp - Slot declaration ROM
3     *
4 cebix 1.13 * Basilisk II (C) 1997-2002 Christian Bauer
5 cebix 1.1 *
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 cebix 1.9 // Length of slot ROM
46     static int slot_rom_size = 0;
47    
48 cebix 1.1
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 cebix 1.14 static uint32 VModeParms(const monitor_desc &m, video_depth depth)
109 cebix 1.5 {
110 cebix 1.14 const video_mode &mode = m.get_current_mode();
111    
112 cebix 1.5 uint32 ret = p;
113 cebix 1.7 Long(50); // Length
114     Long(0); // Base offset
115 cebix 1.14 Word(m.get_bytes_per_row(depth, mode.resolution_id));
116 cebix 1.7 Word(0); // Bounds
117 cebix 1.5 Word(0);
118 cebix 1.11 Word(mode.y);
119     Word(mode.x);
120 cebix 1.7 Word(0); // Version
121     Word(0); // Pack type
122     Long(0); // Pack size
123     Long(0x00480000); // HRes
124     Long(0x00480000); // VRes
125 cebix 1.5 switch (depth) {
126     case VDEPTH_1BIT:
127 cebix 1.7 Word(0); // Pixel type (indirect)
128     Word(1); // Pixel size
129     Word(1); // CmpCount
130     Word(1); // CmpSize
131 cebix 1.5 break;
132     case VDEPTH_2BIT:
133 cebix 1.7 Word(0); // Pixel type (indirect)
134     Word(2); // Pixel size
135     Word(1); // CmpCount
136     Word(2); // CmpSize
137 cebix 1.5 break;
138     case VDEPTH_4BIT:
139 cebix 1.7 Word(0); // Pixel type (indirect)
140     Word(4); // Pixel size
141     Word(1); // CmpCount
142     Word(4); // CmpSize
143 cebix 1.5 break;
144     case VDEPTH_8BIT:
145 cebix 1.7 Word(0); // Pixel type (indirect)
146     Word(8); // Pixel size
147     Word(1); // CmpCount
148     Word(8); // CmpSize
149 cebix 1.5 break;
150     case VDEPTH_16BIT:
151 cebix 1.7 Word(16); // Pixel type (direct)
152     Word(16); // Pixel size
153     Word(3); // CmpCount
154     Word(5); // CmpSize
155 cebix 1.5 break;
156     case VDEPTH_32BIT:
157 cebix 1.7 Word(16); // Pixel type (direct)
158     Word(32); // Pixel size
159     Word(3); // CmpCount
160     Word(8); // CmpSize
161 cebix 1.5 break;
162     }
163 cebix 1.7 Long(0); // Plane size
164     Long(0); // Reserved
165 cebix 1.5 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 cebix 1.14 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 cebix 1.1 bool InstallSlotROM(void)
230     {
231     uint32 boardType, boardName, vendorID, revLevel, partNum, date;
232     uint32 vendorInfo, sRsrcBoard;
233    
234 cebix 1.14 uint32 videoType, videoName, videoDrvr, vidDrvrDir;
235     uint32 defaultGamma, gammaDir;
236 cebix 1.1
237     uint32 cpuType, cpuName, cpuMajor, cpuMinor, sRsrcCPU;
238    
239     uint32 etherType, etherName, etherDrvr, etherDrvrDir, sRsrcEther;
240    
241     uint32 sRsrcDir;
242    
243 cebix 1.14 vector<monitor_desc *>::const_iterator m, mend = VideoMonitors.end();
244     vector<uint32> sRsrcVideo;
245    
246 cebix 1.1 char str[256];
247 cebix 1.14 int i;
248 cebix 1.1 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 cebix 1.14 videoType = p;
280 cebix 1.7 Word(3); Word(1); Word(1); Word(0x4232); // Display Video Apple 'B2'
281 cebix 1.1 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 cebix 1.14 for (m = VideoMonitors.begin(); m != mend; ++m)
356     sRsrcVideo.push_back(VMonitor(**m, videoType, videoName, vidDrvrDir, gammaDir));
357 cebix 1.1
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 cebix 1.14 for (m = VideoMonitors.begin(), i = 0; m != mend; ++m, ++i)
435     Offs((*m)->get_slot_id(), sRsrcVideo[i]);
436 cebix 1.1 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 cebix 1.9 Long(0); // CRC (calculated later)
444 cebix 1.1 Word(0x0101); // Rev. level, format
445     Long(0x5a932bc7); // Test pattern
446     Word(0x000f); // Byte lanes
447    
448 cebix 1.9 // 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 cebix 1.1 // Calculate CRC
464 cebix 1.9 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 cebix 1.1 uint32 crc = 0;
470 cebix 1.12 for (int i=0; i<slot_rom_size; i++) {
471 cebix 1.1 crc = (crc << 1) | (crc >> 31);
472 cebix 1.9 crc += p[i];
473 cebix 1.1 }
474 cebix 1.9 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 cebix 1.1 }