ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/TECH
Revision: 1.5
Committed: 2001-02-10T09:20:54Z (23 years, 9 months ago) by gbeauche
Branch: MAIN
CVS Tags: snapshot-17022001, snapshot-29052001, release-0_9-1
Changes since 1.4: +49 -27 lines
Log Message:
Mode of operations
- detailed a little more Banked Memory Addressing
- added a description of Direct (Constant-Offset) Addressing
- real addressing works on some non-68k, little-endian systems

File Contents

# Content
1 BASILISK II TECHNICAL MANUAL
2 ============================
3
4 0. Table of Contents
5 --------------------
6
7 1. Introduction
8 2. Modes of operation
9 3. Memory access
10 4. Calling native routines from 68k mode and vice-versa
11 5. Interrupts
12 6. Parts of Basilisk II
13 7. Porting Basilisk II
14
15 1. Introduction
16 ---------------
17
18 Basilisk II can emulate two kind of Macs, depending on the ROM being used:
19
20 1. A Mac Classic
21 2. A Mac II series computer ("Mac II series" here means all 68020/30/40
22 based Macs with 32-bit clean ROMs (this excludes the original Mac II,
23 the IIx/IIcx and the SE/030), except PowerBooks; in the following,
24 "Mac II" is used as an abbreviation of "Mac II series computer", as
25 defined above)
26
27 More precisely spoken, MacOS under Basilisk II behaves like on a Mac Classic
28 or Mac II because, apart from the CPU, the RAM and the ROM, absolutely no Mac
29 hardware is emulated. Rather, Basilisk II provides replacements (usually in
30 the form of MacOS drivers) for the parts of MacOS that access hardware. As
31 there are practically no Mac applications that access hardware directly (this
32 is also due to the fact that the hardware of different Mac models is sometimes
33 as different as, say, the hardware of an Atari ST and an Amiga 500), both the
34 compatibility and speed of this approach are very high.
35
36 2. Modes of operation
37 ---------------------
38
39 Basilisk II is designed to run on many different hardware platforms and on
40 many different operating systems. To provide optimal performance under all
41 environments, it can run in four different modes, depending on the features
42 of the underlying environment (the modes are selected with the REAL_ADDRESSING,
43 DIRECT_ADDRESSING and EMULATED_68K defines in "sysdeps.h"):
44
45 1. Emulated CPU, "virtual" addressing (EMULATED_68K = 1, REAL_ADDRESSING = 0):
46 This mode is designed for non-68k or little-endian systems or systems that
47 don't allow accessing RAM at 0x0000..0x1fff. This is also the only mode
48 that allows 24-bit addressing, and thus the only mode that allows Mac
49 Classic emulation. The 68k processor is emulated with the UAE CPU engine
50 and two memory areas are allocated for Mac RAM and ROM. The memory map
51 seen by the emulated CPU and the host CPU are different. Mac RAM starts at
52 address 0 for the emulated 68k, but it may start at a different address for
53 the host CPU.
54
55 In order to handle the particularities of each memory area (RAM, ROM and
56 Frame Buffer), the address space of the emulated 68k is broken down into
57 banks. Each bank is associated with a series of pointers to specific
58 memory access functions that carry out the necessary operations (e.g.
59 byte-swapping, catching illegal writes to memory). A generic memory access
60 function, get_long() for example, goes through the table of memory banks
61 (mem_banks) and fetches the appropriate specific memory access fonction,
62 lget() in our example. This slows down the emulator, of course.
63
64 2. Emulated CPU, "direct" addressing (EMULATED_68K = 1, DIRECT_ADDRESSING = 1):
65 As in the virtual addressing mode, the 68k processor is emulated with the
66 UAE CPU engine and two memory areas are set up for RAM and ROM. Mac RAM
67 starts at address 0 for the emulated 68k, but it may start at a different
68 address for the host CPU. Besides, the virtual memory areas seen by the
69 emulated 68k are separated by exactly the same amount of bytes as the
70 corresponding memory areas allocated on the host CPU. This means that
71 address translation simply implies the addition of a constant offset
72 (MEMBaseDiff). Therefore, the memory banks are no longer used and the
73 memory access functions are replaced by inline memory accesses.
74
75 3. Emulated CPU, "real" addressing (EMULATED_68K = 1, REAL_ADDRESSING = 1):
76 This mode is intended for non-68k systems that do allow access to RAM
77 at 0x0000..0x1fff. As in the virtual addressing mode, the 68k processor
78 is emulated with the UAE CPU engine and two areas are allocated for RAM
79 and ROM but the emulated CPU lives in the same address space as the host
80 CPU. This means that if something is located at a certain address for
81 the 68k, it is located at the exact same address for the host CPU. Mac
82 addresses and host addresses are the same. The memory accesses of the CPU
83 emulation still go through access functions but the address translation
84 is no longer needed. The memory access functions are replaced by direct,
85 inlined memory accesses, making for the fastest possible speed of the
86 emulator. On little-endian systems, byte-swapping is still required, of
87 course.
88
89 A usual consequence of the real addressing mode is that the Mac RAM doesn't
90 any longer begin at address 0 for the Mac and that the Mac ROM also is not
91 located where it usually is on a real Mac. But as the Mac ROM is relocatable
92 and the available RAM is defined for MacOS by the start of the system zone
93 (which is relocated to the start of the allocated RAM area) and the MemTop
94 variable (which is also set correctly) this is not a problem. There is,
95 however, one RAM area that must lie in a certain address range. This area
96 contains the Mac "Low Memory Globals" which (on a Mac II) are located at
97 0x0000..0x1fff and which cannot be moved to a different address range.
98 The Low Memory Globals constitute of many important MacOS and application
99 global variables (e.g. the above mentioned "MemTop" variable which is
100 located at 0x0108). For the real addressing mode to work, the host CPU
101 needs access to 0x0000..0x1fff. Under most operating systems, this is a
102 big problem. On some systems, patches (like PrepareEmul on the Amiga or
103 the sheep_driver under BeOS) can be installed to "open up" this area. On
104 other systems, it might be possible to use access exception handlers to
105 emulate accesses to this area. But if the Low Memory Globals area cannot
106 be made available, using the real addressing mode is not possible.
107
108 Note: currently, real addressing mode is known to work only on AmigaOS,
109 NetBSD/m68k, and Linux/i386.
110
111 4. Native CPU (EMULATED_68K = 0, this also requires REAL_ADDRESSING = 1)
112 This mode is designed for systems that use a 68k (68020 or better) processor
113 as host CPU and is the technically most difficult mode to handle. The Mac
114 CPU is no longer emulated (the UAE CPU emulation is not needed) but MacOS
115 and Mac applications run natively on the existing 68k CPU. This means that
116 the emulator has its maximum possible speed (very close to that of a real
117 Mac with the same CPU). As there is no control over the memory accesses of
118 the CPU, real addressing mode is implied, and so the Low Memory area must
119 be accessible (an MMU might be used to set up different address spaces for
120 the Mac and the host, but this is not implemented in Basilisk II). The
121 native CPU mode has some possible pitfalls that might make its
122 implementation difficult on some systems:
123 a) Implied real addressing (this also means that Mac programs that go out
124 of control can crash the emulator or the whole system)
125 b) MacOS and Mac applications assume that they always run in supervisor
126 mode (more precisely, they assume that they can safely use certain
127 priviledged instructions, mostly for interrupt control). So either
128 the whole emulator has to be run in supervisor mode (which usually is
129 not possible on multitasking systems) or priviledged instructions have
130 to be trapped and emulated. The Amiga and NetBSD/m68k versions of
131 Basilisk II use the latter approach (it is possible to run supervisor
132 mode tasks under the AmigaOS multitasking kernel (ShapeShifter does
133 this) but it requires modifying the Exec task switcher and makes the
134 emulator more unstable).
135 c) On multitasking systems, interrupts can usually not be handled as on
136 a real Mac (or with the UAE CPU). The interrupt levels of the host
137 will not be the same as on a Mac, and the operating systems might not
138 allow installing hardware interrupt handlers or the interrupt handlers
139 might have different stack frames and run-time environments than 68k
140 hardware interrupts. The usual solution is to use some sort of software
141 interrupts or signals to interrupt the main emulation process and to
142 manually call the Mac 68k interrupt handler with a faked stack frame.
143 d) 68060 systems are a small problem because there is no Mac that ever
144 used the 68060 and MacOS doesn't know about this processor. Basilisk II
145 reports the 68060 as being a 68040 to the MacOS and patches some places
146 where MacOS makes use of certain 68040-specific features such as the
147 FPU state frame layout or the PTEST instruction. Also, Basilisk II
148 requires that all of the Motorola support software for the 68060 to
149 emulate missing FPU and integer instructions and addressing modes is
150 provided by the host operating system (this also applies to the 68040).
151 e) The "EMUL_OP" mechanism described below requires the interception and
152 handling of certain emulator-defined instructions.
153
154 3. Memory access
155 ----------------
156
157 There is often a need to access Mac RAM and ROM inside the emulator. As
158 Basilisk II may run in "real" or "virtual" addressing mode on many different
159 architectures, big-endian or little-endian, certain platform-independent
160 data types and functions are provided:
161
162 a) "sysdeps.h" defines the types int8, uint8, int16, uint16, int32 and uint32
163 for numeric quantities of a certain signedness and bit length
164 b) "cpu_emulation.h" defines the ReadMacInt*() and WriteMacInt*() functions
165 which should always be used to read from or write to Mac RAM or ROM
166 c) "cpu_emulation.h" also defines the Mac2HostAddr() function that translates
167 a Mac memory address to a (uint8 *) in host address space. This allows you
168 to access larger chunks of Mac memory directly, without going through the
169 read/write functions for every access. But doing so you have to perform
170 any needed endianess conversion of the data yourself by using the ntohs()
171 etc. macros which are available on most systems or defined in "sysdeps.h".
172
173 4. Calling native routines from 68k mode and vice-versa
174 -------------------------------------------------------
175
176 An emulator like Basilisk II requires two kinds of cross-platform function
177 calls:
178
179 a) Calling a native routine from the Mac 68k context
180 b) Calling a Mac 68k routine from the native context
181
182 Situation a) arises in nearly all Basilisk drivers and system patches while
183 case b) is needed for the invocation of Mac call-back or interrupt routines.
184 Basilisk II tries to solve both problems in a way that provides the same
185 interface whether it is running on a 68k or a non-68k system.
186
187 4.1. The EMUL_OP mechanism
188 --------------------------
189
190 Calling native routines from the Mac 68k context requires breaking out of the
191 68k emulator or interrupting the current instruction flow and is done via
192 unimplemented 68k opcodes (called "EMUL_OP" opcodes). Basilisk II uses opcodes
193 of the form 0x71xx (these are invalid MOVEQ opcodes) which are defined in
194 "emul_op.h". When such an opcode is encountered, whether by the emulated CPU
195 or a real 68k, the execution is interrupted, all CPU registers saved and the
196 EmulOp() function from "emul_op.cpp" is called. EmulOp() decides which opcode
197 caused the interrupt and performs the required actions (mostly by calling other
198 emulator routines). The EMUL_OP handler routines have access to nearly all of
199 the 68k user mode registers (exceptions being the PC, A7 and SR). So the
200 EMUL_OP opcodes can be thought of as extensions to the 68k instruction set.
201 Some of these opcodes are used to implement ROM or resource patches because
202 they only occupy 2 bytes and there is sometimes not more room for a patch.
203
204 4.2. Execute68k()
205 -----------------
206
207 "cpu_emulation.h" declares the functions Execute68k() and Execute68kTrap() to
208 call Mac 68k routines or MacOS system traps from inside an EMUL_OP handler
209 routine. They allow setting all 68k user mode registers (except PC and SR)
210 before the call and examining all register contents after the call has
211 returned. EMUL_OP and Execute68k() may be nested, i.e. a routine called with
212 Execute68k() may contain EMUL_OP opcodes and the EMUL_OP handlers may in turn
213 call Execute68k() again.
214
215 5. Interrupts
216 -------------
217
218 Various parts of Basilisk II (such as the Time Manager and the serial driver)
219 need an interrupt facility to trigger asynchronous events. The MacOS uses
220 different 68k interrupt levels for different events, but for simplicity
221 Basilisk II only uses level 1 and does it's own interrupt dispatching. The
222 "InterruptFlags" contains a bit mask of the pending interrupts. These are the
223 currently defined interrupt sources (see main.h):
224
225 INTFLAG_60HZ - MacOS 60Hz interrupt (unlike a real Mac, we also handle
226 VBL interrupts, ADB events and the Time Manager here)
227 INTFLAG_SERIAL - Interrupt for serial driver I/O completion
228 INTFLAG_ETHER - Interrupt for Ethernet driver I/O completion and packet
229 reception
230 INTFLAG_AUDIO - Interrupt for audio "next block" requests
231 INTFLAG_TIMER - Reserved for a future implementation of a more precise
232 Time Manager (currently not used)
233
234 An interrupt is triggered by calling SetInterruptFlag() with the desired
235 interrupt flag constant and then TriggerInterrupt(). When the UAE 68k
236 emulator is used, this will signal a hardware interrupt to the emulated 680x0.
237 On a native 68k machine, some other method for interrupting the MacOS thread
238 has to be used (e.g. on AmigaOS, a signal exception is used). Care has to be
239 taken because with the UAE CPU, the interrupt will only occur when Basilisk II
240 is executing MacOS code while on a native 68k machine, the interrupt could
241 occur at any time (e.g. inside an EMUL_OP handler routine). In any case, the
242 MacOS thread will eventually end up in the level 1 interrupt handler which
243 contains an M68K_EMUL_OP_IRQ opcode. The opcode handler in emul_op.cpp will
244 then look at InterruptFlags and decide which routines to call.
245
246 6. Parts of Basilisk II
247 -----------------------
248
249 The conception of Basilisk II is quite modular and consists of many parts
250 which are relatively independent from each other:
251
252 - UAE CPU engine ("uae_cpu/*", not needed on all systems)
253 - ROM patches ("rom_patches.cpp", "slot_rom.cpp" and "emul_op.cpp")
254 - resource patches ("rsrc_patches.cpp" and "emul_op.cpp")
255 - PRAM Utilities replacement ("xpram.cpp")
256 - ADB Manager replacement ("adb.cpp")
257 - Time Manager replacement ("timer.cpp")
258 - SCSI Manager replacement ("scsi.cpp")
259 - video driver ("video.cpp")
260 - audio component ("audio.cpp")
261 - floppy driver ("sony.cpp")
262 - disk driver ("disk.cpp")
263 - CD-ROM driver ("cdrom.cpp")
264 - external file system ("extfs.cpp")
265 - serial drivers ("serial.cpp")
266 - Ethernet driver ("ether.cpp")
267 - system-dependant device access ("sys_*.cpp")
268 - user interface strings ("user_strings.cpp")
269 - preferences management ("prefs.cpp" and "prefs_editor_*.cpp")
270
271 Most modules consist of a platform-independant part (such as video.cpp) and a
272 platform-dependant part (such as video_beos.cpp). The "dummy" directory
273 contains generic "do-nothing" versions of some of the platform-dependant
274 parts to aid in testing and porting.
275
276 6.1. UAE CPU engine
277 -------------------
278
279 All files relating to the UAE 680x0 emulation are kept in the "uae_cpu"
280 directory. The "cpu_emulation.h" header file defines the link between the
281 UAE CPU and the rest of Basilisk II, and "basilisk_glue.cpp" implements the
282 link. It should be possible to replace the UAE CPU with a different 680x0
283 emulation by creating a new "xxx_cpu" directory with an appropriate
284 "cpu_emulation.h" header file (for the inlined memory access functions) and
285 writing glue code between the functions declared in "cpu_emulation.h" and
286 those provided by the 680x0 emulator.
287
288 6.2. ROM and resource patches
289 -----------------------------
290
291 As described above, instead of emulating custom Mac hardware, Basilisk II
292 provides replacements for certain parts of MacOS to redirect input, output
293 and system control functions of the Mac hardware to the underlying operating
294 systems. This is done by applying patches to the Mac ROM ("ROM patches") and
295 the MacOS system file ("resource patches", because nearly all system software
296 is contained in MacOS resources). Unless resources are written back to disk,
297 the system file patches are not permanent (it would cause many problems if
298 they were permanent, because some of the patches vary with different
299 versions of Basilisk II or even every time the emulator is launched).
300
301 ROM patches are contained in "rom_patches.cpp" and resource patches are
302 contained in "rsrc_patches.cpp". The ROM patches are far more numerous because
303 nearly all the software needed to run MacOS is contained in the Mac ROM (the
304 system file itself consists mainly of ROM patches, in addition to pictures and
305 text). One part of the ROM patches involves the construction of a NuBus slot
306 declaration ROM (in "slot_rom.cpp") which is used to add the video and Ethernet
307 drivers. Apart from the CPU emulation, the ROM and resource patches contain
308 most of the "logic" of the emulator.
309
310 6.3. PRAM Utilities
311 -------------------
312
313 MacOS stores certain nonvolatile system parameters in a 256 byte battery
314 backed-up CMOS RAM area called "Parameter RAM", "PRAM" or "XPRAM" (which refers
315 to "Extended PRAM" because the earliest Mac models only had 20 bytes of PRAM).
316 Basilisk II patches the ClkNoMem() MacOS trap which is used to access the XPRAM
317 (apart from some routines which are only used early during system startup)
318 and the real-time clock. The XPRAM is emulated in a 256 byte array which is
319 saved to disk to preserve the contents for the next time Basilisk is launched.
320
321 6.4. ADB Manager
322 ----------------
323
324 For emulating a mouse and a keyboard, Basilisk II patches the ADBOp() MacOS
325 trap. Platform-dependant code reports mouse and keyboard events with the
326 ADBMouseDown() etc. functions which are queued and sent to MacOS inside the
327 ADBInterrupt() function (which is called as a part of the 60Hz interrupt
328 handler) by calling the ADB mouse and keyboard handlers with Execute68k().
329
330 6.5. Time Manager
331 -----------------
332
333 Basilisk II completely replaces the Time Manager (InsTime(), RmvTime(),
334 PrimeTime() and Microseconds() traps). A "TMDesc" structure is associated with
335 each Time Manager task, that contains additional data. The tasks are executed
336 in the TimerInterrupt() function which is currently called inside the 60Hz
337 interrupt handler, thus limiting the resolution of the Time Manager to 16.6ms.
338
339 6.6. SCSI Manager
340 -----------------
341
342 The (old-style) SCSI Manager is also completely replaced and the MacOS
343 SCSIDispatch() trap redirected to the routines in "scsi.cpp". Under the MacOS,
344 programs have to issue multiple calls for all the different phases of a
345 SCSI bus interaction (arbitration, selection, command transfer etc.).
346 Basilisk II maps this API to an atomic API which is used by most modern
347 operating systems. All action is deferred until the call to SCSIComplete().
348 The TIB (Transfer Instruction Block) mini-programs used by the MacOS are
349 translated into a scatter/gather list of data blocks. Operating systems that
350 don't support scatter/gather SCSI I/O will have to use buffering if more than
351 one data block is being transmitted. Some more advanced (but rarely used)
352 aspects of the SCSI Manager (like messaging and compare operations) are not
353 emulated.
354
355 6.7. Video driver
356 -----------------
357
358 The NuBus slot declaration ROM constructed in "slot_rom.cpp" contains a driver
359 definition for a video driver. The Control and Status calls of this driver are
360 implemented in "video.cpp". Run-time video mode and depth switching are
361 currently not supported.
362
363 The host-side initialization of the video system is done in VideoInit().
364 This function must provide access to a frame buffer for MacOS and supply
365 its address, resolution and color depth in a video_desc structure (there
366 is currently only one video_desc structure, called VideoMonitor; this is
367 going to change once multiple displays are supported). In real addressing
368 mode, this frame buffer must be in a MacOS compatible layout (big-endian
369 and 1, 2, 4 or 8 bits paletted chunky pixels, RGB 5:5:5 or xRGB 8:8:8:8).
370 In virtual addressing mode, the frame buffer is located at address
371 0xa0000000 on the Mac side and you have to supply the host address, size
372 and layout (BasiliskII will do an automatic pixel format conversion in
373 virtual addressing mode) in the variables MacFrameBaseHost, MacFrameSize
374 and MacFrameLayout.
375
376 6.8. Audio component
377 --------------------
378
379 Basilisk II provides a Sound Manager 3.x audio component for sound output.
380 Earlier Sound Manager versions that don't use components but 'snth' resources
381 are not supported. Nearly all component functions are implemented in
382 "audio.cpp". The system-dependant modules ("audio_*.cpp") handle the
383 initialization of the audio hardware/driver, volume controls, and the actual
384 sound output.
385
386 The mechanism of sound output varies depending on the platform but usually
387 there will be one "streaming thread" (either a thread that continuously writes
388 data buffers to the audio device or a callback function that provides the
389 next data buffer) that reads blocks of sound data from the MacOS Sound Manager
390 and writes them to the audio device. To request the next data buffer, the
391 streaming thread triggers the INTFLAG_AUDIO interrupt which will cause the
392 MacOS thread to eventually call AudioInterrupt(). Inside AudioInterrupt(),
393 the next data block will be read and the streaming thread is signalled that
394 new audio data is available.
395
396 6.9. Floppy, disk and CD-ROM drivers
397 ------------------------------------
398
399 Basilisk II contains three MacOS drivers that implement floppy, disk and CD-ROM
400 access ("sony.cpp", "disk.cpp" and "cdrom.cpp"). They rely heavily on the
401 functionality provided by the "sys_*.cpp" module. BTW, the name ".Sony" of the
402 MacOS floppy driver comes from the fact that the 3.5" floppy drive in the first
403 Mac models was custom-built for Apple by Sony (this was one of the first
404 applications of the 3.5" floppy format which was also invented by Sony).
405
406 6.10. External file system
407 --------------------------
408
409 Basilisk II also provides a method for accessing files and direcories on the
410 host OS from the MacOS side by means of an "external" file system (henceforth
411 called "ExtFS"). The ExtFS is built upon the File System Manager 1.2 interface
412 that is built into MacOS 7.6 (and later) and available as a system extension
413 for earlier MacOS versions. Unlike other parts of Basilisk II, extfs.cpp
414 requires POSIX file I/O and this is not going to change any time soon, so if
415 you are porting Basilisk II to a system without POSIX file functions, you
416 should emulate them.
417
418 6.11. Serial drivers
419 --------------------
420
421 Similar to the disk drivers, Basilisk II contains replacement serial drivers
422 for the emulation of Mac modem and printer ports. To avoid duplicating code,
423 both ports are handled by the same set of routines. The SerialPrime() etc.
424 functions are mostly wrappers that determine which port is being accessed.
425 All the real work is done by the "SERDPort" class which is subclassed by the
426 platform-dependant code. There are two instances (for port A and B) of the
427 subclasses.
428
429 Unlike the disk drivers, the serial driver must be able to handle asynchronous
430 operations. Calls to SerialPrime() will usually not actually transmit or receive
431 data but delegate the action to an independant thread. SerialPrime() then
432 returns "1" to indicate that the I/O operation is not yet completed. The
433 completion of the I/O request is signalled by calling the MacOS trap "IODone".
434 However, this can't be done by the I/O thread because it's not in the right
435 run-time environment to call MacOS functions. Therefore it will trigger the
436 INTFLAG_SERIAL interrupt which causes the MacOS thread to eventually call
437 SerialInterrupt(). SerialInterrupt(), in turn, will not call IODone either but
438 install a Deferred Task to do the job. The Deferred Task will be called by
439 MacOS when it returns to interrupt level 0. This mechanism sounds complicated
440 but is necessary to ensure stable operation of the serial driver.
441
442 6.12. Ethernet driver
443 ---------------------
444
445 A driver for Ethernet networking is also contained in the NuBus slot ROM.
446 Only one ethernet card can be handled by Basilisk II. For Ethernet to work,
447 Basilisk II must be able to send and receive raw Ethernet packets, including
448 the 14-byte header (destination and source address and type/length field),
449 but not including the 4-byte CRC. This may not be possible on all platforms
450 or it may require writing special net drivers or add-ons or running with
451 superuser priviledges to get access to the raw packets.
452
453 Writing packets works as in the serial drivers. The ether_write() routine may
454 choose to send the packet immediately (e.g. under BeOS) and return noErr or to
455 delegate the sending to a separate thread (e.g. under AmigaOS) and return "1" to
456 indicate that the operation is still in progress. For the latter case, a
457 Deferred Task structure is provided in the ether_data area to call IODone from
458 EtherInterrupt() when the packet write is complete (see above for a description
459 of the mechanism).
460
461 Packet reception is a different story. First of all, there are two methods
462 provided by the MacOS Ethernet driver API to read packets, one of which (ERead/
463 ERdCancel) is not supported by Basilisk II. Basilisk II only supports reading
464 packets by attaching protocol handlers. This shouldn't be a problem because
465 the only network code I've seen so far that uses ERead is some Apple sample
466 code. AppleTalk, MacTCP, MacIPX, OpenTransport etc. all use protocol handlers.
467 By attaching a protocol handler, the user of the Ethernet driver supplies a
468 handler routine that should be called by the driver upon reception of Ethernet
469 packets of a certain type. 802.2 packets (type/length field of 0..1500 in the
470 packet header) are a bit special: there can be only one protocol handler attached
471 for 802.2 packets (by specifying a packet type of "0"). The MacOS LAP Manager
472 will attach a 802.2 handler upon startup and handle the distribution of 802.2
473 packets to sub-protocol handlers, but the Basilisk II Ethernet driver is not
474 concerned with this.
475
476 When the driver receives a packet, it has to look up the protocol handler
477 installed for the respective packet type (if any has been installed at all)
478 and call the packet handler routine. This must be done with Execute68k() from
479 the MacOS thread, so an interrupt (INTFLAG_ETHER) is triggered upon reception
480 of a packet so the EtherInterrupt() routine can call the protocol handler.
481 Before calling the handler, the Ethernet packet header has to be copied to
482 MacOS RAM (the "ed_RHA" field of the ether_data structure is provided for this).
483 The protocol handler will read the packet data by means of the ReadPacket/ReadRest
484 routines supplied by the Ethernet driver. Both routines will eventually end up
485 in EtherReadPacket() which copies the data to Mac address space. EtherReadPacket()
486 requires the host address and length of the packet to be loaded to a0 and d1
487 before calling the protocol handler.
488
489 Does this sound complicated? You are probably right. Here is another description
490 of what happens upon reception of a packet:
491 1. Ethernet card receives packet and notifies some platform-dependant entity
492 inside Basilisk II
493 2. This entity will store the packet in some safe place and trigger the
494 INTFLAG_ETHER interrupt
495 3. The MacOS thread will execute the EtherInterrupt() routine and look for
496 received packets
497 4. If a packet was received of a type to which a protocol handler had been
498 attached, the packet header is copied to ed_RHA, a0/d1 are loaded with
499 the host address and length of the packet data, a3 is loaded with the
500 Mac address of the first byte behing ed_RHA and a4 is loaded with the
501 Mac address of the ed_ReadPacket code inside ether_data, and the protocol
502 handler is called with Execute68k()
503 5. The protocol handler will eventually try to read the packet data with
504 a "jsr (a4)" or "jsr 2(a4)"
505 6. This will execute an M68K_EMUL_OP_ETHER_READ_PACKET opcode
506 7. The EtherReadPacket() opcode handling routine will copy the requested
507 part of the packet data to Mac RAM using the pointer and length which are
508 still in a0/d1
509
510 For a more detailed description of the Ethernet driver, see "Inside AppleTalk".
511
512 6.13. System-dependant device access
513 ------------------------------------
514
515 The method for accessing floppy drives, hard disks, CD-ROM drives and files
516 vary greatly between different operating systems. To make Basilisk II easily
517 portable, all device I/O is made via the functions declared in "sys.h" and
518 implemented by the (system-dependant) "sys_*.cpp" modules which provides a
519 standard, Unix-like interface to all kinds of devices.
520
521 6.14. User interface strings
522 ----------------------------
523
524 To aid in localization, all user interface strings of Basilisk II are collected
525 in "user_strings.cpp" (for common strings) and "user_strings_*.cpp" (for
526 platform-specific strings), and accessed via the GetString() function. This
527 way, Basilisk II may be easily translated to different languages.
528
529 6.15. Preferences management
530 ----------------------------
531
532 The module "prefs.cpp" handles user preferences in a system-independant way.
533 Preferences items are accessed with the PrefsAdd*(), PrefsReplace*() and
534 PrefsFind*() functions and stored in human-readable and editable text files
535 on disk. There are two lists of available preferences items. The first one,
536 common_prefs_items, defines the items which are available on all systems.
537 The second one, platform_prefs_items, is defined in prefs_*.cpp and lists
538 the prefs items which are specific to a certain platform.
539
540 The "prefs_editor_*.cpp" module provides a graphical user interface for
541 setting the preferences so users won't have to edit the preferences file
542 manually.
543
544 7. Porting Basilisk II
545 ----------------------
546
547 Porting Basilisk II to a new platform should not be hard. These are the steps
548 involved in the process:
549
550 1. Create a new directory inside the "src" directory for your platform. If
551 your platform comes in several "flavours" that require adapted files, you
552 should consider creating subdirectories inside the platform directory.
553 All files needed for your port must be placed inside the new directory.
554 Don't scatter platform-dependant files across the "src" hierarchy.
555 2. Decide in which mode (virtual addressing, real addressing or native CPU)
556 Basilisk II will run.
557 3. Create a "sysdeps.h" file which defines the mode and system-dependant
558 data types and memory access functions. Things which are used in Basilisk
559 but missing on your platform (such as endianess macros) should also be
560 defined here.
561 4. Implement the system-specific parts of Basilisk:
562 main_*.cpp, sys_*.cpp, prefs_*.cpp, prefs_editor_*.cpp, xpram_*.cpp,
563 timer_*.cpp, audio_*.cpp, video_*.cpp, serial_*.cpp, ether_*.cpp,
564 scsi_*.cpp and clip_*.cpp
565 You may want to take the skeleton implementations in the "dummy" directory
566 as a starting point and look at the implementation for other platforms
567 before writing your own.
568 5. Important things to remember:
569 - Use the ReadMacInt*() and WriteMacInt*() functions from "cpu_emulation.h"
570 to access Mac memory
571 - Use the ntohs() etc. macros to convert endianess when accessing Mac
572 memory directly
573 - Don't modify any source files outside of your platform directory unless
574 you really, really have to. Instead of adding "#ifdef PLATFORM" blocks
575 to one of the platform-independant source files, you should contact me
576 so that we may find a more elegant and more portable solution.
577 6. Coding style: indent -kr -ts4
578
579
580 Christian Bauer
581 <Christian.Bauer@uni-mainz.de>