- updated the TECH document

- EtherReset() clears the UDP protocol list
- audio_oss_esd.cpp: AudioExit() calls close_audio()
- ether_unix.cpp: uses map<> for protocol handlers
- updated audio_dummy.cpp and ether_dummy.cpp
This commit is contained in:
cebix 2001-07-13 15:39:25 +00:00
parent 1c6d6d7cb2
commit 72c7f0db7a
10 changed files with 223 additions and 253 deletions

View File

@ -223,13 +223,16 @@ Basilisk II only uses level 1 and does it's own interrupt dispatching. The
currently defined interrupt sources (see main.h):
INTFLAG_60HZ - MacOS 60Hz interrupt (unlike a real Mac, we also handle
VBL interrupts, ADB events and the Time Manager here)
VBL interrupts and the Time Manager here)
INTFLAG_1HZ - MacOS 1Hz interrupt (updates system time)
INTFLAG_SERIAL - Interrupt for serial driver I/O completion
INTFLAG_ETHER - Interrupt for Ethernet driver I/O completion and packet
reception
INTFLAG_AUDIO - Interrupt for audio "next block" requests
INTFLAG_TIMER - Reserved for a future implementation of a more precise
Time Manager (currently not used)
INTFLAG_ADB - Interrupt for mouse/keyboard input
INTFLAG_NMI - NMI for debugging (not supported on all platforms)
An interrupt is triggered by calling SetInterruptFlag() with the desired
interrupt flag constant and then TriggerInterrupt(). When the UAE 68k
@ -292,128 +295,138 @@ As described above, instead of emulating custom Mac hardware, Basilisk II
provides replacements for certain parts of MacOS to redirect input, output
and system control functions of the Mac hardware to the underlying operating
systems. This is done by applying patches to the Mac ROM ("ROM patches") and
the MacOS system file ("resource patches", because nearly all system software
is contained in MacOS resources). Unless resources are written back to disk,
the system file patches are not permanent (it would cause many problems if
they were permanent, because some of the patches vary with different
versions of Basilisk II or even every time the emulator is launched).
the MacOS system file ("resource patches", because nearly all system
software is contained in MacOS resources). Unless resources are written back
to disk, the system file patches are not permanent (it would cause many
problems if they were permanent, because some of the patches vary with
different versions of Basilisk II or even every time the emulator is
launched).
ROM patches are contained in "rom_patches.cpp" and resource patches are
contained in "rsrc_patches.cpp". The ROM patches are far more numerous because
nearly all the software needed to run MacOS is contained in the Mac ROM (the
system file itself consists mainly of ROM patches, in addition to pictures and
text). One part of the ROM patches involves the construction of a NuBus slot
declaration ROM (in "slot_rom.cpp") which is used to add the video and Ethernet
drivers. Apart from the CPU emulation, the ROM and resource patches contain
most of the "logic" of the emulator.
contained in "rsrc_patches.cpp". The ROM patches are far more numerous
because nearly all the software needed to run MacOS is contained in the Mac
ROM (the system file itself consists mainly of ROM patches, in addition to
pictures and text). One part of the ROM patches involves the construction of
a NuBus slot declaration ROM (in "slot_rom.cpp") which is used to add the
video and Ethernet drivers. Apart from the CPU emulation, the ROM and
resource patches contain most of the "logic" of the emulator.
6.3. PRAM Utilities
-------------------
MacOS stores certain nonvolatile system parameters in a 256 byte battery
backed-up CMOS RAM area called "Parameter RAM", "PRAM" or "XPRAM" (which refers
to "Extended PRAM" because the earliest Mac models only had 20 bytes of PRAM).
Basilisk II patches the ClkNoMem() MacOS trap which is used to access the XPRAM
(apart from some routines which are only used early during system startup)
and the real-time clock. The XPRAM is emulated in a 256 byte array which is
saved to disk to preserve the contents for the next time Basilisk is launched.
backed-up CMOS RAM area called "Parameter RAM", "PRAM" or "XPRAM" (which
refers to "Extended PRAM" because the earliest Mac models only had 20 bytes
of PRAM). Basilisk II patches the ClkNoMem() MacOS trap which is used to
access the XPRAM (apart from some routines which are only used early during
system startup) and the real-time clock. The XPRAM is emulated in a 256 byte
array which is saved to disk to preserve the contents for the next time
Basilisk is launched.
6.4. ADB Manager
----------------
For emulating a mouse and a keyboard, Basilisk II patches the ADBOp() MacOS
trap. Platform-dependant code reports mouse and keyboard events with the
ADBMouseDown() etc. functions which are queued and sent to MacOS inside the
ADBInterrupt() function (which is called as a part of the 60Hz interrupt
handler) by calling the ADB mouse and keyboard handlers with Execute68k().
ADBMouseDown() etc. functions where they are queued, and the INTFLAG_ADB
interrupt is triggered. The ADBInterrupt() handler function sends the input
events to MacOS by calling the ADB mouse and keyboard handlers with
Execute68k().
6.5. Time Manager
-----------------
Basilisk II completely replaces the Time Manager (InsTime(), RmvTime(),
PrimeTime() and Microseconds() traps). A "TMDesc" structure is associated with
each Time Manager task, that contains additional data. The tasks are executed
in the TimerInterrupt() function which is currently called inside the 60Hz
interrupt handler, thus limiting the resolution of the Time Manager to 16.6ms.
PrimeTime() and Microseconds() traps). A "TMDesc" structure is associated
with each Time Manager task, that contains additional data. The tasks are
executed in the TimerInterrupt() function which is currently called inside
the 60Hz interrupt handler, thus limiting the resolution of the Time Manager
to 16.6ms.
6.6. SCSI Manager
-----------------
The (old-style) SCSI Manager is also completely replaced and the MacOS
SCSIDispatch() trap redirected to the routines in "scsi.cpp". Under the MacOS,
programs have to issue multiple calls for all the different phases of a
SCSI bus interaction (arbitration, selection, command transfer etc.).
SCSIDispatch() trap redirected to the routines in "scsi.cpp". Under the
MacOS, programs have to issue multiple calls for all the different phases of
a SCSI bus interaction (arbitration, selection, command transfer etc.).
Basilisk II maps this API to an atomic API which is used by most modern
operating systems. All action is deferred until the call to SCSIComplete().
The TIB (Transfer Instruction Block) mini-programs used by the MacOS are
translated into a scatter/gather list of data blocks. Operating systems that
don't support scatter/gather SCSI I/O will have to use buffering if more than
one data block is being transmitted. Some more advanced (but rarely used)
aspects of the SCSI Manager (like messaging and compare operations) are not
emulated.
don't support scatter/gather SCSI I/O will have to use buffering if more
than one data block is being transmitted. Some more advanced (but rarely
used) aspects of the SCSI Manager (like messaging and compare operations)
are not emulated.
6.7. Video driver
-----------------
The NuBus slot declaration ROM constructed in "slot_rom.cpp" contains a driver
definition for a video driver. The Control and Status calls of this driver are
implemented in "video.cpp". Run-time video mode and depth switching are
currently not supported.
The NuBus slot declaration ROM constructed in "slot_rom.cpp" contains a
driver definition for a video driver. The Control and Status calls of this
driver are implemented in "video.cpp".
The host-side initialization of the video system is done in VideoInit().
This function must provide access to a frame buffer for MacOS and supply
its address, resolution and color depth in a video_desc structure (there
is currently only one video_desc structure, called VideoMonitor; this is
going to change once multiple displays are supported). In real addressing
mode, this frame buffer must be in a MacOS compatible layout (big-endian
and 1, 2, 4 or 8 bits paletted chunky pixels, RGB 5:5:5 or xRGB 8:8:8:8).
In virtual addressing mode, the frame buffer is located at address
0xa0000000 on the Mac side and you have to supply the host address, size
and layout (BasiliskII will do an automatic pixel format conversion in
virtual addressing mode) in the variables MacFrameBaseHost, MacFrameSize
and MacFrameLayout.
This function must fill the VideoModes vector with a list of supported video
modes (combinations of color depth and resolution). It must then call
video_init_depth_list() and setup the VideoMonitor structure with the
default mode information and the address of a frame buffer for MacOS. In
real addressing mode, this frame buffer must be in a MacOS compatible layout
(big-endian and 1, 2, 4 or 8 bits paletted chunky pixels, RGB 5:5:5 or xRGB
8:8:8:8). In virtual addressing mode, the frame buffer is located at address
0xa0000000 on the Mac side and you have to supply the host address, size and
layout (BasiliskII will do an automatic pixel format conversion in virtual
addressing mode) in the variables MacFrameBaseHost, MacFrameSize and
MacFrameLayout.
There are two functions of the platform-dependant video driver code that get
called during runtime: video_set_palette() to update the CLUT (for indexed
modes) or gamma table (for direct color modes), and video_switch_to_mode()
to switch to a different color depth and/or resolution (in this case the
frame buffer base in VideoMonitor must be updated).
6.8. Audio component
--------------------
Basilisk II provides a Sound Manager 3.x audio component for sound output.
Earlier Sound Manager versions that don't use components but 'snth' resources
are not supported. Nearly all component functions are implemented in
"audio.cpp". The system-dependant modules ("audio_*.cpp") handle the
Earlier Sound Manager versions that don't use components but 'snth'
resources are not supported. Nearly all component functions are implemented
in "audio.cpp". The system-dependant modules ("audio_*.cpp") handle the
initialization of the audio hardware/driver, volume controls, and the actual
sound output.
The mechanism of sound output varies depending on the platform but usually
there will be one "streaming thread" (either a thread that continuously writes
data buffers to the audio device or a callback function that provides the
next data buffer) that reads blocks of sound data from the MacOS Sound Manager
and writes them to the audio device. To request the next data buffer, the
streaming thread triggers the INTFLAG_AUDIO interrupt which will cause the
MacOS thread to eventually call AudioInterrupt(). Inside AudioInterrupt(),
the next data block will be read and the streaming thread is signalled that
new audio data is available.
there will be one "streaming thread" (either a thread that continuously
writes data buffers to the audio device or a callback function that provides
the next data buffer) that reads blocks of sound data from the MacOS Sound
Manager and writes them to the audio device. To request the next data
buffer, the streaming thread triggers the INTFLAG_AUDIO interrupt which will
cause the MacOS thread to eventually call AudioInterrupt(). Inside
AudioInterrupt(), the next data block will be read and the streaming thread
is signalled that new audio data is available.
6.9. Floppy, disk and CD-ROM drivers
------------------------------------
Basilisk II contains three MacOS drivers that implement floppy, disk and CD-ROM
access ("sony.cpp", "disk.cpp" and "cdrom.cpp"). They rely heavily on the
functionality provided by the "sys_*.cpp" module. BTW, the name ".Sony" of the
MacOS floppy driver comes from the fact that the 3.5" floppy drive in the first
Mac models was custom-built for Apple by Sony (this was one of the first
applications of the 3.5" floppy format which was also invented by Sony).
Basilisk II contains three MacOS drivers that implement floppy, disk and
CD-ROM access ("sony.cpp", "disk.cpp" and "cdrom.cpp"). They rely heavily on
the functionality provided by the "sys_*.cpp" module. BTW, the name ".Sony"
of the MacOS floppy driver comes from the fact that the 3.5" floppy drive in
the first Mac models was custom-built for Apple by Sony (this was one of the
first applications of the 3.5" floppy format which was also invented by
Sony).
6.10. External file system
--------------------------
Basilisk II also provides a method for accessing files and direcories on the
host OS from the MacOS side by means of an "external" file system (henceforth
called "ExtFS"). The ExtFS is built upon the File System Manager 1.2 interface
that is built into MacOS 7.6 (and later) and available as a system extension
for earlier MacOS versions. Unlike other parts of Basilisk II, extfs.cpp
requires POSIX file I/O and this is not going to change any time soon, so if
you are porting Basilisk II to a system without POSIX file functions, you
should emulate them.
host OS from the MacOS side by means of an "external" file system
(henceforth called "ExtFS"). The ExtFS is built upon the File System Manager
1.2 interface that is built into MacOS 7.6 (and later) and available as a
system extension for earlier MacOS versions. Unlike other parts of Basilisk
II, extfs.cpp requires POSIX file I/O and this is not going to change any
time soon, so if you are porting Basilisk II to a system without POSIX file
functions, you should emulate them.
6.11. Serial drivers
--------------------
@ -426,18 +439,19 @@ All the real work is done by the "SERDPort" class which is subclassed by the
platform-dependant code. There are two instances (for port A and B) of the
subclasses.
Unlike the disk drivers, the serial driver must be able to handle asynchronous
operations. Calls to SerialPrime() will usually not actually transmit or receive
data but delegate the action to an independant thread. SerialPrime() then
returns "1" to indicate that the I/O operation is not yet completed. The
completion of the I/O request is signalled by calling the MacOS trap "IODone".
However, this can't be done by the I/O thread because it's not in the right
run-time environment to call MacOS functions. Therefore it will trigger the
INTFLAG_SERIAL interrupt which causes the MacOS thread to eventually call
SerialInterrupt(). SerialInterrupt(), in turn, will not call IODone either but
install a Deferred Task to do the job. The Deferred Task will be called by
MacOS when it returns to interrupt level 0. This mechanism sounds complicated
but is necessary to ensure stable operation of the serial driver.
Unlike the disk drivers, the serial driver must be able to handle
asynchronous operations. Calls to SerialPrime() will usually not actually
transmit or receive data but delegate the action to an independant thread.
SerialPrime() then returns "1" to indicate that the I/O operation is not yet
completed. The completion of the I/O request is signalled by calling the
MacOS trap "IODone". However, this can't be done by the I/O thread because
it's not in the right run-time environment to call MacOS functions.
Therefore it will trigger the INTFLAG_SERIAL interrupt which causes the
MacOS thread to eventually call SerialInterrupt(). SerialInterrupt(), in
turn, will not call IODone either but install a Deferred Task to do the job.
The Deferred Task will be called by MacOS when it returns to interrupt level
0. This mechanism sounds complicated but is necessary to ensure stable
operation of the serial driver.
6.12. Ethernet driver
---------------------
@ -450,44 +464,53 @@ but not including the 4-byte CRC. This may not be possible on all platforms
or it may require writing special net drivers or add-ons or running with
superuser priviledges to get access to the raw packets.
Writing packets works as in the serial drivers. The ether_write() routine may
choose to send the packet immediately (e.g. under BeOS) and return noErr or to
delegate the sending to a separate thread (e.g. under AmigaOS) and return "1" to
indicate that the operation is still in progress. For the latter case, a
Deferred Task structure is provided in the ether_data area to call IODone from
EtherInterrupt() when the packet write is complete (see above for a description
of the mechanism).
For situations in which access to raw Ethernet packets is not possible,
Basilisk II implements a special "tunneling" mode in which it sends and
receives packets via UDP, using BSD socket functions. It simply wraps the
Ethernet packets into UDP packets, using dummy Ethernet addresses that are
made up of the IP address of the host. Ethernet broadcast and AppleTalk
multicast packets are sent to the IP broadcast address. Because of this
non-standard way of tunneling, it is only possible to set up a "virtual"
network amongst machines running Basilisk II in this way.
Writing packets works as in the serial drivers. The ether_write() routine
may choose to send the packet immediately (e.g. under BeOS) and return noErr
or to delegate the sending to a separate thread (e.g. under AmigaOS) and
return "1" to indicate that the operation is still in progress. For the
latter case, a Deferred Task structure is provided in the ether_data area to
call IODone from EtherInterrupt() when the packet write is complete (see
above for a description of the mechanism).
Packet reception is a different story. First of all, there are two methods
provided by the MacOS Ethernet driver API to read packets, one of which (ERead/
ERdCancel) is not supported by Basilisk II. Basilisk II only supports reading
packets by attaching protocol handlers. This shouldn't be a problem because
the only network code I've seen so far that uses ERead is some Apple sample
code. AppleTalk, MacTCP, MacIPX, OpenTransport etc. all use protocol handlers.
By attaching a protocol handler, the user of the Ethernet driver supplies a
handler routine that should be called by the driver upon reception of Ethernet
packets of a certain type. 802.2 packets (type/length field of 0..1500 in the
packet header) are a bit special: there can be only one protocol handler attached
for 802.2 packets (by specifying a packet type of "0"). The MacOS LAP Manager
will attach a 802.2 handler upon startup and handle the distribution of 802.2
packets to sub-protocol handlers, but the Basilisk II Ethernet driver is not
concerned with this.
provided by the MacOS Ethernet driver API to read packets, one of which
(ERead/ ERdCancel) is not supported by Basilisk II. Basilisk II only
supports reading packets by attaching protocol handlers. This shouldn't be a
problem because the only network code I've seen so far that uses ERead is
some Apple sample code. AppleTalk, MacTCP, MacIPX, OpenTransport etc. all
use protocol handlers. By attaching a protocol handler, the user of the
Ethernet driver supplies a handler routine that should be called by the
driver upon reception of Ethernet packets of a certain type. 802.2 packets
(type/length field of 0..1500 in the packet header) are a bit special: there
can be only one protocol handler attached for 802.2 packets (by specifying a
packet type of "0"). The MacOS LAP Manager will attach a 802.2 handler upon
startup and handle the distribution of 802.2 packets to sub-protocol
handlers, but the Basilisk II Ethernet driver is not concerned with this.
When the driver receives a packet, it has to look up the protocol handler
installed for the respective packet type (if any has been installed at all)
and call the packet handler routine. This must be done with Execute68k() from
the MacOS thread, so an interrupt (INTFLAG_ETHER) is triggered upon reception
of a packet so the EtherInterrupt() routine can call the protocol handler.
Before calling the handler, the Ethernet packet header has to be copied to
MacOS RAM (the "ed_RHA" field of the ether_data structure is provided for this).
The protocol handler will read the packet data by means of the ReadPacket/ReadRest
routines supplied by the Ethernet driver. Both routines will eventually end up
in EtherReadPacket() which copies the data to Mac address space. EtherReadPacket()
requires the host address and length of the packet to be loaded to a0 and d1
before calling the protocol handler.
and call the packet handler routine. This must be done with Execute68k()
from the MacOS thread, so an interrupt (INTFLAG_ETHER) is triggered upon
reception of a packet so the EtherInterrupt() routine can call the protocol
handler. Before calling the handler, the Ethernet packet header has to be
copied to MacOS RAM (the "ed_RHA" field of the ether_data structure is
provided for this). The protocol handler will read the packet data by means
of the ReadPacket/ReadRest routines supplied by the Ethernet driver. Both
routines will eventually end up in EtherReadPacket() which copies the data
to Mac address space. EtherReadPacket() requires the host address and length
of the packet to be loaded to a0 and d1 before calling the protocol handler.
Does this sound complicated? You are probably right. Here is another description
of what happens upon reception of a packet:
Does this sound complicated? You are probably right. Here is another
description of what happens upon reception of a packet:
1. Ethernet card receives packet and notifies some platform-dependant entity
inside Basilisk II
2. This entity will store the packet in some safe place and trigger the
@ -507,7 +530,8 @@ of what happens upon reception of a packet:
part of the packet data to Mac RAM using the pointer and length which are
still in a0/d1
For a more detailed description of the Ethernet driver, see "Inside AppleTalk".
For a more detailed description of the Ethernet driver, see the book "Inside
AppleTalk".
6.13. System-dependant device access
------------------------------------
@ -521,10 +545,11 @@ standard, Unix-like interface to all kinds of devices.
6.14. User interface strings
----------------------------
To aid in localization, all user interface strings of Basilisk II are collected
in "user_strings.cpp" (for common strings) and "user_strings_*.cpp" (for
platform-specific strings), and accessed via the GetString() function. This
way, Basilisk II may be easily translated to different languages.
To aid in localization, all user interface strings of Basilisk II are
collected in "user_strings.cpp" (for common strings) and
"user_strings_*.cpp" (for platform-specific strings), and accessed via the
GetString() function. This way, Basilisk II may be easily translated to
different languages.
6.15. Preferences management
----------------------------
@ -533,9 +558,10 @@ The module "prefs.cpp" handles user preferences in a system-independant way.
Preferences items are accessed with the PrefsAdd*(), PrefsReplace*() and
PrefsFind*() functions and stored in human-readable and editable text files
on disk. There are two lists of available preferences items. The first one,
common_prefs_items, defines the items which are available on all systems.
The second one, platform_prefs_items, is defined in prefs_*.cpp and lists
the prefs items which are specific to a certain platform.
common_prefs_items, is defined in "prefs_items.cpp" and lists items which
are available on all systems. The second one, platform_prefs_items, is
defined in "prefs_*.cpp" and lists the prefs items which are specific to a
certain platform.
The "prefs_editor_*.cpp" module provides a graphical user interface for
setting the preferences so users won't have to edit the preferences file
@ -544,8 +570,8 @@ manually.
7. Porting Basilisk II
----------------------
Porting Basilisk II to a new platform should not be hard. These are the steps
involved in the process:
Porting Basilisk II to a new platform should not be hard. These are the
steps involved in the process:
1. Create a new directory inside the "src" directory for your platform. If
your platform comes in several "flavours" that require adapted files, you

View File

@ -188,7 +188,7 @@ void ether_exit(void)
* Reset
*/
void EtherReset(void)
void ether_reset(void)
{
// Remove all protocols
if (net_proc)

View File

@ -266,7 +266,7 @@ void ether_exit(void)
* Reset
*/
void EtherReset(void)
void ether_reset(void)
{
remove_all_protocols();
}

View File

@ -338,6 +338,10 @@ static void close_audio(void)
void AudioExit(void)
{
// Close audio device
close_audio();
// Delete semaphore
if (sem_inited) {
sem_destroy(&audio_irq_done_sem);
sem_inited = false;

View File

@ -22,13 +22,13 @@
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <map>
#if defined(__FreeBSD__)
#include <net/if.h>
@ -42,22 +42,16 @@
#include "ether.h"
#include "ether_defs.h"
#ifndef NO_STD_NAMESPACE
using std::map;
#endif
#define DEBUG 0
#include "debug.h"
#define MONITOR 0
// List of attached protocols
struct NetProtocol {
NetProtocol *next;
uint16 type;
uint32 handler;
};
static NetProtocol *prot_list = NULL;
// Global variables
static int fd = -1; // fd of sheep_net device
static pthread_t ether_thread; // Packet reception thread
@ -67,48 +61,13 @@ static sem_t int_ack; // Interrupt acknowledge semaphore
static bool is_ethertap; // Flag: Ethernet device is ethertap
static bool udp_tunnel; // Flag: UDP tunnelling active, fd is the socket descriptor
// Attached network protocols, maps protocol type to MacOS handler address
static map<uint16, uint32> net_protocols;
// Prototypes
static void *receive_func(void *arg);
/*
* Find protocol in list
*/
static NetProtocol *find_protocol(uint16 type)
{
// All 802.2 types are the same
if (type <= 1500)
type = 0;
// Search list (we could use hashing here but there are usually only three
// handlers installed: 0x0000 for AppleTalk and 0x0800/0x0806 for TCP/IP)
NetProtocol *p = prot_list;
while (p) {
if (p->type == type)
return p;
p = p->next;
}
return NULL;
}
/*
* Remove all protocols
*/
static void remove_all_protocols(void)
{
NetProtocol *p = prot_list;
while (p) {
NetProtocol *next = p->next;
delete p;
p = next;
}
prot_list = NULL;
}
/*
* Start packet reception thread
*/
@ -246,9 +205,6 @@ void ether_exit(void)
// Close sheep_net device
if (fd > 0)
close(fd);
// Remove all protocols
remove_all_protocols();
}
@ -256,9 +212,9 @@ void ether_exit(void)
* Reset
*/
void EtherReset(void)
void ether_reset(void)
{
remove_all_protocols();
net_protocols.clear();
}
@ -299,19 +255,10 @@ int16 ether_del_multicast(uint32 pb)
int16 ether_attach_ph(uint16 type, uint32 handler)
{
// Already attached?
NetProtocol *p = find_protocol(type);
if (p != NULL)
if (net_protocols.find(type) != net_protocols.end())
return lapProtErr;
else {
// No, create and attach
p = new NetProtocol;
p->next = prot_list;
p->type = type;
p->handler = handler;
prot_list = p;
return noErr;
}
net_protocols[type] = handler;
return noErr;
}
@ -321,25 +268,9 @@ int16 ether_attach_ph(uint16 type, uint32 handler)
int16 ether_detach_ph(uint16 type)
{
NetProtocol *p = find_protocol(type);
if (p != NULL) {
NetProtocol *q = prot_list;
if (p == q) {
prot_list = p->next;
delete p;
return noErr;
}
while (q) {
if (q->next == p) {
q->next = p->next;
delete p;
return noErr;
}
q = q->next;
}
return lapProtErr;
} else
if (net_protocols.erase(type) == 0)
return lapProtErr;
return noErr;
}
@ -486,12 +417,13 @@ void EtherInterrupt(void)
uint16 type = (p[12] << 8) | p[13];
// Look for protocol
NetProtocol *prot = find_protocol(type);
if (prot == NULL)
uint16 search_type = (type <= 1500 ? 0 : type);
if (net_protocols.find(search_type) == net_protocols.end())
continue;
uint32 handler = net_protocols[search_type];
// No default handler
if (prot->handler == 0)
if (handler == 0)
continue;
// Copy header to RHA
@ -505,8 +437,8 @@ void EtherInterrupt(void)
r.a[0] = (uint32)p + 14; // Pointer to packet (host address, for ReadPacket)
r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA
r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines
D(bug(" calling protocol handler %08x, type %08x, length %08x, data %08x, rha %08x, read_packet %08x\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
Execute68k(prot->handler, &r);
D(bug(" calling protocol handler %08x, type %08x, length %08x, data %08x, rha %08x, read_packet %08x\n", handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
Execute68k(handler, &r);
}
}

View File

@ -27,15 +27,6 @@
#include "debug.h"
// Supported sample rates, sizes and channels
int audio_num_sample_rates = 1;
uint32 audio_sample_rates[] = {44100 << 16};
int audio_num_sample_sizes = 1;
uint16 audio_sample_sizes[] = {16};
int audio_num_channel_counts = 1;
uint16 audio_channel_counts[] = {2};
/*
* Initialization
*/
@ -43,13 +34,18 @@ uint16 audio_channel_counts[] = {2};
void AudioInit(void)
{
// Init audio status and feature flags
AudioStatus.sample_rate = audio_sample_rates[0];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
AudioStatus.sample_rate = 44100 << 16;
AudioStatus.sample_size = 16;
AudioStatus.channels = 2;
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
// Only one sample format is supported
audio_sample_rates.push_back(44100 << 16);
audio_sample_sized.push_back(16);
audio_channel_counts.push_back(2);
// Sound disabled in prefs? Then do nothing
if (PrefsFindBool("nosound"))
return;
@ -98,19 +94,19 @@ void AudioInterrupt(void)
/*
* Set sampling parameters
* "index" is an index into the audio_sample_rates[] etc. arrays
* "index" is an index into the audio_sample_rates[] etc. vectors
* It is guaranteed that AudioStatus.num_sources == 0
*/
void audio_set_sample_rate(int index)
bool audio_set_sample_rate(int index)
{
}
void audio_set_sample_size(int index)
bool audio_set_sample_size(int index)
{
}
void audio_set_channels(int index)
bool audio_set_channels(int index)
{
}

View File

@ -37,7 +37,7 @@
* Initialization
*/
void EtherInit(void)
bool ether_init(void)
{
}
@ -46,7 +46,7 @@ void EtherInit(void)
* Deinitialization
*/
void EtherExit(void)
void ether_exit(void)
{
}
@ -55,7 +55,7 @@ void EtherExit(void)
* Reset
*/
void EtherReset(void)
void ether_reset(void)
{
}

View File

@ -25,16 +25,10 @@
* Inside AppleTalk, chapter 3 "Ethernet and TokenTalk Link Access Protocols"
*/
#include <string.h>
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"
#include "emul_op.h"
#include "prefs.h"
#include "ether.h"
#include "ether_defs.h"
#include <string.h>
#include <map>
#if SUPPORTS_UDP_TUNNEL
#include <netinet/in.h>
@ -44,7 +38,13 @@
#include <errno.h>
#endif
#include <map>
#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"
#include "emul_op.h"
#include "prefs.h"
#include "ether.h"
#include "ether_defs.h"
#ifndef NO_STD_NAMESPACE
using std::map;
@ -170,6 +170,17 @@ void EtherExit(void)
}
/*
* Reset
*/
void EtherReset(void)
{
udp_protocols.clear();
ether_reset();
}
/*
* Check whether Ethernet address is AppleTalk broadcast address
*/

View File

@ -36,6 +36,7 @@ extern void EtherInterrupt(void);
extern bool ether_init(void);
extern void ether_exit(void);
extern void ether_reset(void);
extern int16 ether_add_multicast(uint32 pb);
extern int16 ether_del_multicast(uint32 pb);
extern int16 ether_attach_ph(uint16 type, uint32 handler);

View File

@ -60,7 +60,7 @@ void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
{
uint16 *p16;
uint32 base;
D(bug("vCheckLoad %c%c%c%c (%08x) ID %d, data %08x, size %d\n", (char)(type >> 24), (char)((type >> 16) & 0xff), (char )((type >> 8) & 0xff), (char )(type & 0xff), type, id, p, size));
D(bug("vCheckLoad %c%c%c%c (%08x) ID %d, data %p, size %d\n", (char)(type >> 24), (char)((type >> 16) & 0xff), (char )((type >> 8) & 0xff), (char )(type & 0xff), type, id, p, size));
if (type == FOURCC('b','o','o','t') && id == 3) {
D(bug(" boot 3 found\n"));
@ -76,7 +76,7 @@ void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
}
#if !ROM_IS_WRITE_PROTECTED
// Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.5, 8.0)
// Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.1, 7.5, 8.0)
static const uint8 dat2[] = {0x20, 0x78, 0x02, 0xae, 0xd1, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x21, 0xc8, 0x00, 0x00};
base = find_rsrc_data(p, size, dat2, sizeof(dat2));
if (base) {
@ -101,13 +101,13 @@ void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
} else if (type == FOURCC('b','o','o','t') && id == 2) {
D(bug(" boot 2 found\n"));
// Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.5, 8.0)
// Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.1, 7.5, 8.0)
static const uint8 dat[] = {0x20, 0x78, 0x02, 0xae, 0xd1, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x21, 0xc8, 0x00, 0x00};
base = find_rsrc_data(p, size, dat, sizeof(dat));
if (base) {
p16 = (uint16 *)(p + base);
#if defined(AMIGA) || defined(__NetBSD__) || defined(USE_SCRATCHMEM_SUBTERFUGE)
#if defined(USE_SCRATCHMEM_SUBTERFUGE)
// Set 0x0000 to scratch memory area
extern uint8 *ScratchMem;
const uint32 ScratchMemBase = Host2MacAddr(ScratchMem);
@ -154,7 +154,7 @@ void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
} else if (type == FOURCC('p','t','c','h') && id == 26) {
D(bug(" ptch 26 found\n"));
// Trap ABC4 is initialized with absolute ROM address (7.5, 7.6, 7.6.1, 8.0)
// Trap ABC4 is initialized with absolute ROM address (7.1, 7.5, 7.6, 7.6.1, 8.0)
static const uint8 dat[] = {0x40, 0x83, 0x36, 0x10};
base = find_rsrc_data(p, size, dat, sizeof(dat));
if (base) {