Remove BeOS and AmigaOS

This commit is contained in:
Seg 2020-12-12 10:51:56 -08:00
parent 58e367a73d
commit 06747d4a7b
114 changed files with 53 additions and 27184 deletions

View File

@ -39,8 +39,7 @@ Some features of Basilisk II:
- Serial drivers
- SCSI Manager (old-style) emulation
- Emulates extended ADB keyboard and 3-button mouse
- Uses UAE 68k emulation or (under AmigaOS and NetBSD/m68k) real 68k
processor
- Uses UAE 68k emulation or real 68k processor
%prep
%setup -q

View File

@ -6,9 +6,6 @@ RELEASE := $(shell sed <BasiliskII.spec -n '/^\%define release */s///p')
VERNAME := BasiliskII-$(VERSION)
SRCARCHIVE := $(shell date +BasiliskII_src_%d%m%Y.tar.gz)
AMIGAARCHIVE := $(VERNAME)-$(RELEASE).amiga.lzh
BEOSPPCARCHIVE := $(VERNAME)-$(RELEASE).beosppc.zip
BEOSX86ARCHIVE := $(VERNAME)-$(RELEASE).beosx86.zip
MACOSXARCHIVE := $(VERNAME)-$(RELEASE).tar.gz
TMPDIR := $(shell date +/tmp/build%M%S)
@ -27,14 +24,10 @@ help:
@echo "The following targets are available:"
@echo " tarball source tarball ($(SRCARCHIVE))"
@echo " rpm source and binary RPMs"
@echo " amiga AmigaOS binary archive ($(AMIGAARCHIVE))"
@echo " beosppc BeOS/ppc binary archive ($(BEOSPPCARCHIVE))"
@echo " beosx86 BeOS/x86 binary archive ($(BEOSX86ARCHIVE))"
@echo " macosx MacOS X binary archive ($(MACOSXARCHIVE))"
clean:
-rm -f $(SRCARCHIVE)
-rm -f $(AMIGAARCHIVE) $(BEOSPPCARCHIVE) $(BEOSX86ARCHIVE)
#
# Source tarball
@ -59,55 +52,6 @@ $(SRCARCHIVE): $(SRCS) $(DOCS)
rpm: $(SRCARCHIVE)
rpmbuild -ta --clean $(SRCARCHIVE)
#
# Binary archive for AmigaOS
#
amiga: $(AMIGAARCHIVE)
$(AMIGAARCHIVE): $(SRCS) $(DOCS) src/AmigaOS/BasiliskII
-rm -rf $(TMPDIR)
mkdir $(TMPDIR)
mkdir $(TMPDIR)/$(VERNAME)
cp $(DOCS) $(TMPDIR)/$(VERNAME)
cp src/AmigaOS/BasiliskII $(TMPDIR)/$(VERNAME)
cp src/AmigaOS/BasiliskII.info $(TMPDIR)/$(VERNAME)
chmod 775 $(TMPDIR)/$(VERNAME)/BasiliskII
cd $(TMPDIR); lha a $@ $(VERNAME)
mv $(TMPDIR)/$@ .
rm -rf $(TMPDIR)
#
# Binary archive for BeOS/ppc
#
beosppc: $(BEOSPPCARCHIVE)
$(BEOSPPCARCHIVE): $(SRCS) $(DOCS) src/BeOS/obj.ppc/BasiliskII
-rm -rf $(TMPDIR)
mkdir $(TMPDIR)
mkdir $(TMPDIR)/$(VERNAME)
cp $(DOCS) $(TMPDIR)/$(VERNAME)
cp src/BeOS/obj.ppc/BasiliskII $(TMPDIR)/$(VERNAME)
mimeset -f $(TMPDIR)
cd $(TMPDIR); zip -ry $@ $(VERNAME)/
mv $(TMPDIR)/$@ .
rm -rf $(TMPDIR)
#
# Binary archive for BeOS/x86
#
beosx86: $(BEOSX86ARCHIVE)
$(BEOSX86ARCHIVE): $(SRCS) $(DOCS) src/BeOS/obj.x86/BasiliskII
-rm -rf $(TMPDIR)
mkdir $(TMPDIR)
mkdir $(TMPDIR)/$(VERNAME)
cp $(DOCS) $(TMPDIR)/$(VERNAME)
cp src/BeOS/obj.x86/BasiliskII $(TMPDIR)/$(VERNAME)
mimeset -f $(TMPDIR)
cd $(TMPDIR); zip -ry $@ $(VERNAME)/
mv $(TMPDIR)/$@ .
rm -rf $(TMPDIR)
#
# Binary archive for MacOS X
#

View File

@ -1,64 +0,0 @@
# AmigaOS makefile for Basilisk II (GeekGadgets tool chain)
## System specific configuration
CC = gcc
CXX = c++
CXXFLAGS = -g -O1 -noixemul -m68020 -msmall-code -Wno-multichar
CPPFLAGS = -I../include -I../native_cpu -I.
DEFS =
LDFLAGS = -noixemul
LIBS = /gg/lib/libnix/swapstack.o
AS = PhxAss
ASFLAGS = OPT ! INCPATH GG:os-include FPU=1
## Files
SRCS = ../main.cpp main_amiga.cpp ../prefs.cpp ../prefs_items.cpp \
prefs_amiga.cpp prefs_editor_amiga.cpp sys_amiga.cpp ../rom_patches.cpp \
../slot_rom.cpp ../rsrc_patches.cpp ../emul_op.cpp \
../macos_util.cpp ../xpram.cpp xpram_amiga.cpp ../timer.cpp \
timer_amiga.cpp clip_amiga.cpp ../adb.cpp ../serial.cpp \
serial_amiga.cpp ../ether.cpp ether_amiga.cpp ../sony.cpp ../disk.cpp \
../cdrom.cpp ../scsi.cpp scsi_amiga.cpp ../video.cpp video_amiga.cpp \
../audio.cpp audio_amiga.cpp ../extfs.cpp extfs_amiga.cpp \
../user_strings.cpp user_strings_amiga.cpp asm_support.asm
APP = BasiliskII
## Rules
.PHONY: clean distclean
.SUFFIXES:
.SUFFIXES: .c .cpp .asm .o .h
all: $(APP)
OBJ_DIR = obj
$(OBJ_DIR)::
@[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1
define SRCS_LIST_TO_OBJS
$(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \
$(basename $(notdir $(file))))))
endef
OBJS = $(SRCS_LIST_TO_OBJS)
SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file))))
VPATH :=
VPATH += $(addprefix :, $(subst ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS))))
$(APP): $(OBJ_DIR) $(OBJS)
$(CXX) -o $(APP) $(LDFLAGS) $(LIBS) $(OBJS)
clean:
rm -f $(APP) $(OBJ_DIR)/* *~ *.bak obj.0000.*
distclean: clean
rm -rf $(OBJ_DIR)
$(OBJ_DIR)/%.o : %.cpp
$(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/%.o : %.asm
$(AS) $(ASFLAGS) $< TO $(OBJ_DIR)/$*.obj
hunk2aout $(OBJ_DIR)/$*.obj >/dev/null
mv obj.0000.* $@
#-------------------------------------------------------------------------
# DO NOT DELETE THIS LINE -- make depend depends on it.

File diff suppressed because it is too large Load Diff

View File

@ -1,515 +0,0 @@
/*
* audio_amiga.cpp - Audio support, AmigaOS implementation using AHI
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/ahi.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/ahi.h>
#include <inline/exec.h>
#include <inline/ahi.h>
#include "cpu_emulation.h"
#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "audio.h"
#include "audio_defs.h"
#define DEBUG 0
#include "debug.h"
#define D1(x) ;
// Global variables
static ULONG ahi_id = AHI_DEFAULT_ID; // AHI audio ID
static struct AHIAudioCtrl *ahi_ctrl = NULL;
static struct AHISampleInfo sample[2]; // Two sample infos for double-buffering
static struct Hook sf_hook;
static int play_buf = 0; // Number of currently played buffer
static long sound_buffer_size; // Size of one audio buffer in bytes
static int audio_block_fetched = 0; // Number of audio blocks fetched by interrupt routine
static bool main_mute = false;
static bool speaker_mute = false;
static ULONG supports_volume_changes = false;
static ULONG supports_stereo_panning = false;
static ULONG current_main_volume;
static ULONG current_speaker_volume;
// Prototypes
static __saveds __attribute__((regparm(3))) ULONG audio_callback(struct Hook *hook /*a0*/, struct AHISoundMessage *msg /*a1*/, struct AHIAudioCtrl *ahi_ctrl /*a2*/);
void audio_set_sample_rate_byval(uint32 value);
void audio_set_sample_size_byval(uint32 value);
void audio_set_channels_byval(uint32 value);
/*
* Initialization
*/
// Set AudioStatus to reflect current audio stream format
static void set_audio_status_format(int sample_rate_index)
{
AudioStatus.sample_rate = audio_sample_rates[sample_rate_index];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
}
void AudioInit(void)
{
sample[0].ahisi_Address = sample[1].ahisi_Address = NULL;
// Init audio status and feature flags
audio_channel_counts.push_back(2);
// set_audio_status_format();
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
// Sound disabled in prefs? Then do nothing
if (PrefsFindBool("nosound"))
return;
// AHI available?
if (AHIBase == NULL) {
WarningAlert(GetString(STR_NO_AHI_WARN));
return;
}
// Initialize callback hook
sf_hook.h_Entry = (HOOKFUNC)audio_callback;
// Read "sound" preferences
const char *str = PrefsFindString("sound");
if (str)
sscanf(str, "ahi/%08lx", &ahi_id);
// Open audio control structure
if ((ahi_ctrl = AHI_AllocAudio(
AHIA_AudioID, ahi_id,
AHIA_MixFreq, AudioStatus.sample_rate >> 16,
AHIA_Channels, 1,
AHIA_Sounds, 2,
AHIA_SoundFunc, (ULONG)&sf_hook,
TAG_END)) == NULL) {
WarningAlert(GetString(STR_NO_AHI_CTRL_WARN));
return;
}
ULONG max_channels, sample_rate, frequencies, sample_rate_index;
AHI_GetAudioAttrs(ahi_id, ahi_ctrl,
AHIDB_MaxChannels, (ULONG) &max_channels,
AHIDB_Frequencies, (ULONG) &frequencies,
TAG_END);
D(bug("AudioInit: max_channels=%ld frequencies=%ld\n", max_channels, frequencies));
for (int n=0; n<frequencies; n++)
{
AHI_GetAudioAttrs(ahi_id, ahi_ctrl,
AHIDB_FrequencyArg, n,
AHIDB_Frequency, (ULONG) &sample_rate,
TAG_END);
D(bug("AudioInit: f=%ld Hz\n", sample_rate));
audio_sample_rates.push_back(sample_rate << 16);
}
ULONG sample_size_bits = 16;
D(bug("AudioInit: sampe_rates=%ld\n", audio_sample_rates.size() ));
// get index of sample rate closest to 22050 Hz
AHI_GetAudioAttrs(ahi_id, ahi_ctrl,
AHIDB_IndexArg, 22050,
AHIDB_Bits, (ULONG) &sample_size_bits,
AHIDB_Index, (ULONG) &sample_rate_index,
AHIDB_Volume, (ULONG) &supports_volume_changes,
AHIDB_Panning, (ULONG) &supports_stereo_panning,
TAG_END);
audio_sample_sizes.push_back(16);
set_audio_status_format(sample_rate_index);
// 2048 frames per block
audio_frames_per_block = 2048;
sound_buffer_size = (AudioStatus.sample_size >> 3) * AudioStatus.channels * audio_frames_per_block;
// Prepare SampleInfos and load sounds (two sounds for double buffering)
sample[0].ahisi_Type = AudioStatus.sample_size == 16 ? AHIST_S16S : AHIST_S8S;
sample[0].ahisi_Length = audio_frames_per_block;
sample[0].ahisi_Address = AllocVec(sound_buffer_size, MEMF_PUBLIC | MEMF_CLEAR);
sample[1].ahisi_Type = AudioStatus.sample_size == 16 ? AHIST_S16S : AHIST_S8S;
sample[1].ahisi_Length = audio_frames_per_block;
sample[1].ahisi_Address = AllocVec(sound_buffer_size, MEMF_PUBLIC | MEMF_CLEAR);
if (sample[0].ahisi_Address == NULL || sample[1].ahisi_Address == NULL)
return;
AHI_LoadSound(0, AHIST_DYNAMICSAMPLE, &sample[0], ahi_ctrl);
AHI_LoadSound(1, AHIST_DYNAMICSAMPLE, &sample[1], ahi_ctrl);
// Set parameters
play_buf = 0;
current_main_volume = current_speaker_volume = 0x10000;
AHI_SetVol(0, current_speaker_volume, 0x8000, ahi_ctrl, AHISF_IMM);
AHI_SetFreq(0, AudioStatus.sample_rate >> 16, ahi_ctrl, AHISF_IMM);
AHI_SetSound(0, play_buf, 0, 0, ahi_ctrl, AHISF_IMM);
// Everything OK
audio_open = true;
}
/*
* Deinitialization
*/
void AudioExit(void)
{
// Free everything
if (ahi_ctrl != NULL) {
AHI_ControlAudio(ahi_ctrl, AHIC_Play, FALSE, TAG_END);
AHI_FreeAudio(ahi_ctrl);
}
FreeVec(sample[0].ahisi_Address);
FreeVec(sample[1].ahisi_Address);
}
/*
* First source added, start audio stream
*/
void audio_enter_stream()
{
AHI_ControlAudio(ahi_ctrl, AHIC_Play, TRUE, TAG_END);
}
/*
* Last source removed, stop audio stream
*/
void audio_exit_stream()
{
AHI_ControlAudio(ahi_ctrl, AHIC_Play, FALSE, TAG_END);
}
/*
* AHI sound callback, request next buffer
*/
static __saveds __attribute__((regparm(3))) ULONG audio_callback(struct Hook *hook /*a0*/, struct AHISoundMessage *msg /*a1*/, struct AHIAudioCtrl *ahi_ctrl /*a2*/)
{
play_buf ^= 1;
// New buffer available?
if (audio_block_fetched)
{
audio_block_fetched--;
if (main_mute || speaker_mute)
{
memset(sample[play_buf].ahisi_Address, 0, sound_buffer_size);
}
else
{
// Get size of audio data
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
if (apple_stream_info) {
int32 sample_count = ReadMacInt32(apple_stream_info + scd_sampleCount);
uint32 num_channels = ReadMacInt16(apple_stream_info + scd_numChannels);
uint32 sample_size = ReadMacInt16(apple_stream_info + scd_sampleSize);
uint32 sample_rate = ReadMacInt32(apple_stream_info + scd_sampleRate);
D(bug("stream: sample_count=%ld num_channels=%ld sample_size=%ld sample_rate=%ld\n", sample_count, num_channels, sample_size, sample_rate >> 16));
// Yes, this can happen.
if(sample_count != 0) {
if(sample_rate != AudioStatus.sample_rate) {
audio_set_sample_rate_byval(sample_rate);
}
if(num_channels != AudioStatus.channels) {
audio_set_channels_byval(num_channels);
}
if(sample_size != AudioStatus.sample_size) {
audio_set_sample_size_byval(sample_size);
}
}
if (sample_count < 0)
sample_count = 0;
int work_size = sample_count * num_channels * (sample_size>>3);
D(bug("stream: work_size=%ld sound_buffer_size=%ld\n", work_size, sound_buffer_size));
if (work_size > sound_buffer_size)
work_size = sound_buffer_size;
// Put data into AHI buffer (convert 8-bit data unsigned->signed)
if (AudioStatus.sample_size == 16)
Mac2Host_memcpy(sample[play_buf].ahisi_Address, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
else {
uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer));
uint32 *q = (uint32 *)sample[play_buf].ahisi_Address;
int r = work_size >> 2;
while (r--)
*q++ = *p++ ^ 0x80808080;
}
if (work_size != sound_buffer_size)
memset((uint8 *)sample[play_buf].ahisi_Address + work_size, 0, sound_buffer_size - work_size);
}
}
}
else
memset(sample[play_buf].ahisi_Address, 0, sound_buffer_size);
// Play next buffer
AHI_SetSound(0, play_buf, 0, 0, ahi_ctrl, 0);
// Trigger audio interrupt to get new buffer
if (AudioStatus.num_sources) {
D1(bug("stream: triggering irq\n"));
SetInterruptFlag(INTFLAG_AUDIO);
TriggerInterrupt();
}
return 0;
}
/*
* MacOS audio interrupt, read next data block
*/
void AudioInterrupt(void)
{
D1(bug("AudioInterrupt\n"));
// Get data from apple mixer
if (AudioStatus.mixer) {
M68kRegisters r;
r.a[0] = audio_data + adatStreamInfo;
r.a[1] = AudioStatus.mixer;
Execute68k(audio_data + adatGetSourceData, &r);
D1(bug(" GetSourceData() returns %08lx\n", r.d[0]));
} else
WriteMacInt32(audio_data + adatStreamInfo, 0);
// Signal stream function
audio_block_fetched++;
D1(bug("AudioInterrupt done\n"));
}
/*
* Set sampling parameters
* "index" is an index into the audio_sample_rates[] etc. arrays
* It is guaranteed that AudioStatus.num_sources == 0
*/
void audio_set_sample_rate_byval(uint32 value)
{
bool changed = (AudioStatus.sample_rate != value);
if(changed)
{
ULONG sample_rate_index;
// get index of sample rate closest to <value> Hz
AHI_GetAudioAttrs(ahi_id, ahi_ctrl,
AHIDB_IndexArg, value >> 16,
AHIDB_Index, (ULONG) &sample_rate_index,
TAG_END);
D(bug(" audio_set_sample_rate_byval requested rate=%ld Hz\n", value >> 16));
AudioStatus.sample_rate = audio_sample_rates[sample_rate_index];
AHI_SetFreq(0, AudioStatus.sample_rate >> 16, ahi_ctrl, 0);
}
D(bug(" audio_set_sample_rate_byval rate=%ld Hz\n", AudioStatus.sample_rate >> 16));
}
void audio_set_sample_size_byval(uint32 value)
{
bool changed = (AudioStatus.sample_size != value);
if(changed) {
// AudioStatus.sample_size = value;
// update_sound_parameters();
// WritePrivateProfileInt( "Audio", "SampleSize", AudioStatus.sample_size, ini_file_name );
}
D(bug(" audio_set_sample_size_byval %d\n", AudioStatus.sample_size));
}
void audio_set_channels_byval(uint32 value)
{
bool changed = (AudioStatus.channels != value);
if(changed) {
// AudioStatus.channels = value;
// update_sound_parameters();
// WritePrivateProfileInt( "Audio", "Channels", AudioStatus.channels, ini_file_name );
}
D(bug(" audio_set_channels_byval %d\n", AudioStatus.channels));
}
bool audio_set_sample_rate(int index)
{
if(index >= 0 && index < audio_sample_rates.size() ) {
audio_set_sample_rate_byval( audio_sample_rates[index] );
D(bug(" audio_set_sample_rate index=%ld rate=%ld\n", index, AudioStatus.sample_rate >> 16));
}
return true;
}
bool audio_set_sample_size(int index)
{
if(index >= 0 && index < audio_sample_sizes.size() ) {
audio_set_sample_size_byval( audio_sample_sizes[index] );
D(bug(" audio_set_sample_size %d,%d\n", index,AudioStatus.sample_size));
}
return true;
}
bool audio_set_channels(int index)
{
if(index >= 0 && index < audio_channel_counts.size() ) {
audio_set_channels_byval( audio_channel_counts[index] );
D(bug(" audio_set_channels %d,%d\n", index,AudioStatus.channels));
}
return true;
}
/*
* Get/set volume controls (volume values received/returned have the left channel
* volume in the upper 16 bits and the right channel volume in the lower 16 bits;
* both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume"))
*/
bool audio_get_main_mute(void)
{
D(bug("audio_get_main_mute: mute=%ld\n", main_mute));
return main_mute;
}
uint32 audio_get_main_volume(void)
{
D(bug("audio_get_main_volume\n"));
ULONG volume = current_main_volume >> 8; // 0x10000 => 0x100
D(bug("audio_get_main_volume: volume=%08lx\n", volume));
return (volume << 16) + volume;
return 0x01000100;
}
bool audio_get_speaker_mute(void)
{
D(bug("audio_get_speaker_mute: mute=%ld\n", speaker_mute));
return speaker_mute;
}
uint32 audio_get_speaker_volume(void)
{
D(bug("audio_get_speaker_volume: \n"));
if (audio_open)
{
ULONG volume = current_speaker_volume >> 8; // 0x10000 => 0x100
D(bug("audio_get_speaker_volume: volume=%08lx\n", volume));
return (volume << 16) + volume;
}
return 0x01000100;
}
void audio_set_main_mute(bool mute)
{
D(bug("audio_set_main_mute: mute=%ld\n", mute));
if (mute != main_mute)
{
main_mute = mute;
}
}
void audio_set_main_volume(uint32 vol)
{
D(bug("audio_set_main_volume: vol=%08lx\n", vol));
if (audio_open && supports_volume_changes)
{
ULONG volume = 0x80 * ((vol >> 16) + (vol & 0xffff));
D(bug("audio_set_main_volume: volume=%08lx\n", volume));
current_main_volume = volume;
AHI_SetVol(0, volume, 0x8000, ahi_ctrl, AHISF_IMM);
}
}
void audio_set_speaker_mute(bool mute)
{
D(bug("audio_set_speaker_mute: mute=%ld\n", mute));
if (mute != speaker_mute)
{
speaker_mute = mute;
}
}
void audio_set_speaker_volume(uint32 vol)
{
D(bug("audio_set_speaker_volume: vol=%08lx\n", vol));
if (audio_open && supports_volume_changes)
{
ULONG volume = 0x80 * ((vol >> 16) + (vol & 0xffff));
D(bug("audio_set_speaker_volume: volume=%08lx\n", volume));
current_speaker_volume = volume;
AHI_SetVol(0, volume, 0x8000, ahi_ctrl, AHISF_IMM);
}
}

View File

@ -1,166 +0,0 @@
/*
* clip_amiga.cpp - Clipboard handling, AmigaOS implementation
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <exec/types.h>
#include <libraries/iffparse.h>
#include <devices/clipboard.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/iffparse.h>
#include <inline/exec.h>
#include <inline/iffparse.h>
#include "clip.h"
#include "prefs.h"
#define DEBUG 0
#include "debug.h"
// Global variables
static struct IFFHandle *iffw = NULL;
static struct ClipboardHandle *ch = NULL;
static bool clipboard_open = false;
static bool no_clip_conversion;
// Conversion tables
static const uint8 mac2iso[0x80] = {
0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1,
0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8,
0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3,
0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc,
0x2b, 0xb0, 0xa2, 0xa3, 0xa7, 0xb7, 0xb6, 0xdf,
0xae, 0xa9, 0x20, 0xb4, 0xa8, 0x23, 0xc6, 0xd8,
0x20, 0xb1, 0x3c, 0x3e, 0xa5, 0xb5, 0xf0, 0x53,
0x50, 0x70, 0x2f, 0xaa, 0xba, 0x4f, 0xe6, 0xf8,
0xbf, 0xa1, 0xac, 0x2f, 0x66, 0x7e, 0x44, 0xab,
0xbb, 0x2e, 0x20, 0xc0, 0xc3, 0xd5, 0x4f, 0x6f,
0x2d, 0x2d, 0x22, 0x22, 0x60, 0x27, 0xf7, 0x20,
0xff, 0x59, 0x2f, 0xa4, 0x3c, 0x3e, 0x66, 0x66,
0x23, 0xb7, 0x2c, 0x22, 0x25, 0xc2, 0xca, 0xc1,
0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4,
0x20, 0xd2, 0xda, 0xdb, 0xd9, 0x69, 0x5e, 0x7e,
0xaf, 0x20, 0xb7, 0xb0, 0xb8, 0x22, 0xb8, 0x20
};
/*
* Initialization
*/
void ClipInit(void)
{
no_clip_conversion = PrefsFindBool("noclipconversion");
// Create clipboard IFF handle
iffw = AllocIFF();
if (iffw) {
ch = OpenClipboard(PRIMARY_CLIP);
if (ch) {
iffw->iff_Stream = (ULONG)ch;
InitIFFasClip(iffw);
clipboard_open = true;
}
}
}
/*
* Deinitialization
*/
void ClipExit(void)
{
if (ch)
CloseClipboard(ch);
if (iffw)
FreeIFF(iffw);
}
/*
* Mac application zeroes clipboard
*/
void ZeroScrap()
{
}
/*
* Mac application reads clipboard
*/
void GetScrap(void **handle, uint32 type, int32 offset)
{
D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset));
}
/*
* Mac application wrote to clipboard
*/
void PutScrap(uint32 type, void *scrap, int32 length)
{
D(bug("PutScrap type %08lx, data %08lx, length %ld\n", type, scrap, length));
if (length <= 0 || !clipboard_open)
return;
switch (type) {
case 'TEXT': {
D(bug(" clipping TEXT\n"));
// Open IFF stream
if (OpenIFF(iffw, IFFF_WRITE))
break;
// Convert text from Mac charset to ISO-Latin1
uint8 *buf = new uint8[length];
uint8 *p = (uint8 *)scrap;
uint8 *q = buf;
for (int i=0; i<length; i++) {
uint8 c = *p++;
if (c < 0x80) {
if (c == 13) // CR -> LF
c = 10;
} else if (!no_clip_conversion)
c = mac2iso[c & 0x7f];
*q++ = c;
}
// Write text
if (!PushChunk(iffw, 'FTXT', 'FORM', IFFSIZE_UNKNOWN)) {
if (!PushChunk(iffw, 0, 'CHRS', IFFSIZE_UNKNOWN)) {
WriteChunkBytes(iffw, scrap, length);
PopChunk(iffw);
}
PopChunk(iffw);
}
// Close IFF stream
CloseIFF(iffw);
delete[] buf;
break;
}
}
}

View File

@ -1,705 +0,0 @@
/*
* ether_amiga.cpp - Ethernet device driver, AmigaOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/errors.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <devices/sana2.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/dos.h>
#include <inline/exec.h>
#include <inline/dos.h>
#include <clib/alib_protos.h>
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "macos_util.h"
#include "ether.h"
#include "ether_defs.h"
#define DEBUG 0
#include "debug.h"
#define MONITOR 0
// These messages are sent to the network process
const uint32 MSG_CLEANUP = 'clea'; // Remove all protocols
const uint32 MSG_ADD_MULTI = 'addm'; // Add multicast address
const uint32 MSG_DEL_MULTI = 'delm'; // Add multicast address
const uint32 MSG_ATTACH_PH = 'atph'; // Attach protocol handler
const uint32 MSG_DETACH_PH = 'deph'; // Attach protocol handler
const uint32 MSG_WRITE = 'writ'; // Write packet
struct NetMessage : public Message {
NetMessage(uint32 what_, const struct MsgPort *reply_port)
{
what = what_;
mn_ReplyPort = (struct MsgPort *)reply_port;
mn_Length = sizeof(*this);
}
uint32 what;
uint32 pointer;
uint16 type;
int16 result;
};
// List of attached protocols
static const int NUM_READ_REQUESTS = 32; // Number of read requests that are sent to device in advance
struct NetProtocol : public Node {
struct IOSana2Req read_io[NUM_READ_REQUESTS];
uint8 read_buf[NUM_READ_REQUESTS][1518]; // 14 bytes header, 1500 bytes data, 4 bytes CRC
uint16 type;
uint32 handler;
};
static struct List prot_list;
// Global variables
static struct Process *net_proc = NULL; // Network device handler process
static bool proc_error; // Flag: process didn't initialize
static struct MsgPort *proc_port = NULL; // Message port of process, for communication with main task
static struct MsgPort *reply_port = NULL; // Reply port for communication with process
static struct MsgPort *read_port = NULL; // Reply port for read IORequests (set up and owned by network process)
static bool write_done = false; // Flag: write request done
extern struct Task *MainTask; // Pointer to main task (from main_amiga.cpp)
// Prototypes
static void net_func(void);
/*
* Send message to network process
*/
static int16 send_to_proc(uint32 what, uint32 pointer = 0, uint16 type = 0)
{
D(bug("sending %08lx to net_proc\n", what));
NetMessage msg(what, reply_port);
msg.pointer = pointer;
msg.type = type;
PutMsg(proc_port, &msg);
WaitPort(reply_port);
GetMsg(reply_port);
D(bug(" sent\n"));
return msg.result;
}
/*
* Initialization
*/
bool ether_init(void)
{
// Do nothing if no Ethernet device specified
if (PrefsFindString("ether") == NULL)
return false;
// Initialize protocol list
NewList(&prot_list);
// Create message port
reply_port = CreateMsgPort();
if (reply_port == NULL)
goto open_error;
D(bug("signal mask %08lx\n", 1 << reply_port->mp_SigBit));
// Start process
proc_error = false;
SetSignal(0, SIGF_SINGLE);
net_proc = CreateNewProcTags(
NP_Entry, (ULONG)net_func,
NP_Name, (ULONG)"Basilisk II Ethernet Task",
NP_Priority, 1,
TAG_END
);
if (net_proc == NULL)
goto open_error;
// Wait for signal from process
Wait(SIGF_SINGLE);
// Initialization error? Then bail out
if (proc_error)
goto open_error;
// Everything OK
return true;
open_error:
net_proc = NULL;
if (reply_port) {
DeleteMsgPort(reply_port);
reply_port = NULL;
}
return false;
}
/*
* Deinitialization
*/
void ether_exit(void)
{
// Stop process
if (net_proc) {
SetSignal(0, SIGF_SINGLE);
Signal(&net_proc->pr_Task, SIGBREAKF_CTRL_C);
Wait(SIGF_SINGLE);
}
// Delete reply port
if (reply_port) {
DeleteMsgPort(reply_port);
reply_port = NULL;
}
}
/*
* Reset
*/
void ether_reset(void)
{
// Remove all protocols
if (net_proc)
send_to_proc(MSG_CLEANUP);
}
/*
* Add multicast address
*/
int16 ether_add_multicast(uint32 pb)
{
return send_to_proc(MSG_ADD_MULTI, pb);
}
/*
* Delete multicast address
*/
int16 ether_del_multicast(uint32 pb)
{
return send_to_proc(MSG_DEL_MULTI, pb);
}
/*
* Attach protocol handler
*/
int16 ether_attach_ph(uint16 type, uint32 handler)
{
return send_to_proc(MSG_ATTACH_PH, handler, type);
}
/*
* Detach protocol handler
*/
int16 ether_detach_ph(uint16 type)
{
return send_to_proc(MSG_DETACH_PH, type);
}
/*
* Transmit raw ethernet packet
*/
int16 ether_write(uint32 wds)
{
send_to_proc(MSG_WRITE, wds);
return 1; // Command in progress
}
/*
* Remove protocol from protocol list
*/
static void remove_protocol(NetProtocol *p)
{
// Remove from list
Forbid();
Remove(p);
Permit();
// Cancel read requests
for (int i=0; i<NUM_READ_REQUESTS; i++) {
AbortIO((struct IORequest *)(p->read_io + i));
WaitIO((struct IORequest *)(p->read_io + i));
}
// Free protocol struct
FreeMem(p, sizeof(NetProtocol));
}
/*
* Remove all protocols
*/
static void remove_all_protocols(void)
{
NetProtocol *n = (NetProtocol *)prot_list.lh_Head, *next;
while ((next = (NetProtocol *)n->ln_Succ) != NULL) {
remove_protocol(n);
n = next;
}
}
/*
* Copy received network packet to Mac side
*/
static __saveds __regargs LONG copy_to_buff(uint8 *to /*a0*/, uint8 *from /*a1*/, uint32 packet_len /*d0*/)
{
D(bug("CopyToBuff to %08lx, from %08lx, size %08lx\n", to, from, packet_len));
// It would be more efficient (and take up less memory) if we
// could invoke the packet handler from here. But we don't know
// in what context we run, so calling Execute68k() would not be
// a good idea, and even worse, we might run inside a hardware
// interrupt, so we can't even trigger a Basilisk interrupt from
// here and wait for its completion.
CopyMem(from, to, packet_len);
#if MONITOR
bug("Receiving Ethernet packet:\n");
for (int i=0; i<packet_len; i++) {
bug("%02lx ", from[i]);
}
bug("\n");
#endif
return 1;
}
/*
* Copy data from Mac WDS to outgoing network packet
*/
static __saveds __regargs LONG copy_from_buff(uint8 *to /*a0*/, char *wds /*a1*/, uint32 packet_len /*d0*/)
{
D(bug("CopyFromBuff to %08lx, wds %08lx, size %08lx\n", to, wds, packet_len));
#if MONITOR
bug("Sending Ethernet packet:\n");
#endif
for (;;) {
int len = ReadMacInt16((uint32)wds);
if (len == 0)
break;
#if MONITOR
uint8 *adr = Mac2HostAddr(ReadMacInt32((uint32)wds + 2));
for (int i=0; i<len; i++) {
bug("%02lx ", adr[i]);
}
#endif
CopyMem(Mac2HostAddr(ReadMacInt32((uint32)wds + 2)), to, len);
to += len;
wds += 6;
}
#if MONITOR
bug("\n");
#endif
return 1;
}
/*
* Process for communication with the Ethernet device
*/
static __saveds void net_func(void)
{
const char *str;
BYTE od_error;
struct MsgPort *write_port = NULL, *control_port = NULL;
struct IOSana2Req *write_io = NULL, *control_io = NULL;
bool opened = false;
ULONG read_mask = 0, write_mask = 0, proc_port_mask = 0;
struct Sana2DeviceQuery query_data = {sizeof(Sana2DeviceQuery)};
ULONG buffer_tags[] = {
S2_CopyToBuff, (uint32)copy_to_buff,
S2_CopyFromBuff, (uint32)copy_from_buff,
TAG_END
};
// Default: error occured
proc_error = true;
// Create message port for communication with main task
proc_port = CreateMsgPort();
if (proc_port == NULL)
goto quit;
proc_port_mask = 1 << proc_port->mp_SigBit;
// Create message ports for device I/O
read_port = CreateMsgPort();
if (read_port == NULL)
goto quit;
read_mask = 1 << read_port->mp_SigBit;
write_port = CreateMsgPort();
if (write_port == NULL)
goto quit;
write_mask = 1 << write_port->mp_SigBit;
control_port = CreateMsgPort();
if (control_port == NULL)
goto quit;
// Create control IORequest
control_io = (struct IOSana2Req *)CreateIORequest(control_port, sizeof(struct IOSana2Req));
if (control_io == NULL)
goto quit;
control_io->ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug
// Parse device name
char dev_name[256];
ULONG dev_unit;
str = PrefsFindString("ether");
if (str) {
const char *FirstSlash = strchr(str, '/');
const char *LastSlash = strrchr(str, '/');
if (FirstSlash && FirstSlash && FirstSlash != LastSlash) {
// Device name contains path, i.e. "Networks/xyzzy.device"
const char *lp = str;
char *dp = dev_name;
while (lp != LastSlash)
*dp++ = *lp++;
*dp = '\0';
if (strlen(dev_name) < 1)
goto quit;
if (sscanf(LastSlash, "/%ld", &dev_unit) != 1)
goto quit;
} else {
if (sscanf(str, "%[^/]/%ld", dev_name, &dev_unit) != 2)
goto quit;
}
} else
goto quit;
// Open device
control_io->ios2_BufferManagement = buffer_tags;
od_error = OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)control_io, 0);
if (od_error != 0 || control_io->ios2_Req.io_Device == 0) {
printf("WARNING: OpenDevice(<%s>, unit=%d) returned error %d)\n", (UBYTE *)dev_name, dev_unit, od_error);
goto quit;
}
opened = true;
// Is it Ethernet?
control_io->ios2_Req.io_Command = S2_DEVICEQUERY;
control_io->ios2_StatData = (void *)&query_data;
DoIO((struct IORequest *)control_io);
if (control_io->ios2_Req.io_Error)
goto quit;
if (query_data.HardwareType != S2WireType_Ethernet) {
WarningAlert(GetString(STR_NOT_ETHERNET_WARN));
goto quit;
}
// Yes, create IORequest for writing
write_io = (struct IOSana2Req *)CreateIORequest(write_port, sizeof(struct IOSana2Req));
if (write_io == NULL)
goto quit;
memcpy(write_io, control_io, sizeof(struct IOSana2Req));
write_io->ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug
write_io->ios2_Req.io_Message.mn_ReplyPort = write_port;
// Configure Ethernet
control_io->ios2_Req.io_Command = S2_GETSTATIONADDRESS;
DoIO((struct IORequest *)control_io);
memcpy(ether_addr, control_io->ios2_DstAddr, 6);
memcpy(control_io->ios2_SrcAddr, control_io->ios2_DstAddr, 6);
control_io->ios2_Req.io_Command = S2_CONFIGINTERFACE;
DoIO((struct IORequest *)control_io);
D(bug("Ethernet address %08lx %08lx\n", *(uint32 *)ether_addr, *(uint16 *)(ether_addr + 4)));
// Initialization went well, inform main task
proc_error = false;
Signal(MainTask, SIGF_SINGLE);
// Main loop
for (;;) {
// Wait for I/O and messages (CTRL_C is used for quitting the task)
ULONG sig = Wait(proc_port_mask | read_mask | write_mask | SIGBREAKF_CTRL_C);
// Main task wants to quit us
if (sig & SIGBREAKF_CTRL_C)
break;
// Main task sent a command to us
if (sig & proc_port_mask) {
struct NetMessage *msg;
while (msg = (NetMessage *)GetMsg(proc_port)) {
D(bug("net_proc received %08lx\n", msg->what));
switch (msg->what) {
case MSG_CLEANUP:
remove_all_protocols();
break;
case MSG_ADD_MULTI:
control_io->ios2_Req.io_Command = S2_ADDMULTICASTADDRESS;
Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6);
DoIO((struct IORequest *)control_io);
if (control_io->ios2_Req.io_Error == S2ERR_NOT_SUPPORTED) {
WarningAlert(GetString(STR_NO_MULTICAST_WARN));
msg->result = noErr;
} else if (control_io->ios2_Req.io_Error)
msg->result = eMultiErr;
else
msg->result = noErr;
break;
case MSG_DEL_MULTI:
control_io->ios2_Req.io_Command = S2_DELMULTICASTADDRESS;
Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6);
DoIO((struct IORequest *)control_io);
if (control_io->ios2_Req.io_Error)
msg->result = eMultiErr;
else
msg->result = noErr;
break;
case MSG_ATTACH_PH: {
uint16 type = msg->type;
uint32 handler = msg->pointer;
// Protocol of that type already installed?
NetProtocol *p = (NetProtocol *)prot_list.lh_Head, *next;
while ((next = (NetProtocol *)p->ln_Succ) != NULL) {
if (p->type == type) {
msg->result = lapProtErr;
goto reply;
}
p = next;
}
// Allocate NetProtocol, set type and handler
p = (NetProtocol *)AllocMem(sizeof(NetProtocol), MEMF_PUBLIC);
if (p == NULL) {
msg->result = lapProtErr;
goto reply;
}
p->type = type;
p->handler = handler;
// Set up and submit read requests
for (int i=0; i<NUM_READ_REQUESTS; i++) {
memcpy(p->read_io + i, control_io, sizeof(struct IOSana2Req));
p->read_io[i].ios2_Req.io_Message.mn_Node.ln_Name = (char *)p; // Hide pointer to NetProtocol in node name
p->read_io[i].ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug
p->read_io[i].ios2_Req.io_Message.mn_ReplyPort = read_port;
p->read_io[i].ios2_Req.io_Command = CMD_READ;
p->read_io[i].ios2_PacketType = type;
p->read_io[i].ios2_Data = p->read_buf[i];
p->read_io[i].ios2_Req.io_Flags = SANA2IOF_RAW;
BeginIO((struct IORequest *)(p->read_io + i));
}
// Add protocol to list
AddTail(&prot_list, p);
// Everything OK
msg->result = noErr;
break;
}
case MSG_DETACH_PH: {
uint16 type = msg->type;
msg->result = lapProtErr;
NetProtocol *p = (NetProtocol *)prot_list.lh_Head, *next;
while ((next = (NetProtocol *)p->ln_Succ) != NULL) {
if (p->type == type) {
remove_protocol(p);
msg->result = noErr;
break;
}
p = next;
}
break;
}
case MSG_WRITE: {
// Get pointer to Write Data Structure
uint32 wds = msg->pointer;
write_io->ios2_Data = (void *)wds;
// Calculate total packet length
long len = 0;
uint32 tmp = wds;
for (;;) {
int16 w = ReadMacInt16(tmp);
if (w == 0)
break;
len += w;
tmp += 6;
}
write_io->ios2_DataLength = len;
// Get destination address
uint32 hdr = ReadMacInt32(wds + 2);
Mac2Host_memcpy(write_io->ios2_DstAddr, hdr, 6);
// Get packet type
uint32 type = ReadMacInt16(hdr + 12);
if (type <= 1500)
type = 0; // 802.3 packet
write_io->ios2_PacketType = type;
// Multicast/broadcard packet?
if (write_io->ios2_DstAddr[0] & 1) {
if (*(uint32 *)(write_io->ios2_DstAddr) == 0xffffffff && *(uint16 *)(write_io->ios2_DstAddr + 4) == 0xffff)
write_io->ios2_Req.io_Command = S2_BROADCAST;
else
write_io->ios2_Req.io_Command = S2_MULTICAST;
} else
write_io->ios2_Req.io_Command = CMD_WRITE;
// Send packet
write_done = false;
write_io->ios2_Req.io_Flags = SANA2IOF_RAW;
BeginIO((IORequest *)write_io);
break;
}
}
reply: D(bug(" net_proc replying\n"));
ReplyMsg(msg);
}
}
// Packet received
if (sig & read_mask) {
D(bug(" packet received, triggering Ethernet interrupt\n"));
SetInterruptFlag(INTFLAG_ETHER);
TriggerInterrupt();
}
// Packet write completed
if (sig & write_mask) {
GetMsg(write_port);
WriteMacInt32(ether_data + ed_Result, write_io->ios2_Req.io_Error ? excessCollsns : 0);
write_done = true;
D(bug(" packet write done, triggering Ethernet interrupt\n"));
SetInterruptFlag(INTFLAG_ETHER);
TriggerInterrupt();
}
}
quit:
// Close everything
remove_all_protocols();
if (opened) {
if (CheckIO((struct IORequest *)write_io) == 0) {
AbortIO((struct IORequest *)write_io);
WaitIO((struct IORequest *)write_io);
}
CloseDevice((struct IORequest *)control_io);
}
if (write_io)
DeleteIORequest(write_io);
if (control_io)
DeleteIORequest(control_io);
if (control_port)
DeleteMsgPort(control_port);
if (write_port)
DeleteMsgPort(write_port);
if (read_port)
DeleteMsgPort(read_port);
// Send signal to main task to confirm termination
Forbid();
Signal(MainTask, SIGF_SINGLE);
}
/*
* Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers
*/
void EtherInterrupt(void)
{
D(bug("EtherIRQ\n"));
// Packet write done, enqueue DT to call IODone
if (write_done) {
EnqueueMac(ether_data + ed_DeferredTask, 0xd92);
write_done = false;
}
// Call protocol handler for received packets
IOSana2Req *io;
while (io = (struct IOSana2Req *)GetMsg(read_port)) {
// Get pointer to NetProtocol (hidden in node name)
NetProtocol *p = (NetProtocol *)io->ios2_Req.io_Message.mn_Node.ln_Name;
// No default handler
if (p->handler == 0)
continue;
// Copy header to RHA
Host2Mac_memcpy(ether_data + ed_RHA, io->ios2_Data, 14);
D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12)));
// Call protocol handler
M68kRegisters r;
r.d[0] = *(uint16 *)((uint32)io->ios2_Data + 12); // Packet type
r.d[1] = io->ios2_DataLength - 18; // Remaining packet length (without header, for ReadPacket) (-18 because the CRC is also included)
r.a[0] = (uint32)io->ios2_Data + 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 %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", p->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
Execute68k(p->handler, &r);
// Resend IORequest
io->ios2_Req.io_Flags = SANA2IOF_RAW;
BeginIO((struct IORequest *)io);
}
D(bug(" EtherIRQ done\n"));
}

View File

@ -1,387 +0,0 @@
/*
* extfs_amiga.cpp - MacOS file system for access native file system access, AmigaOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <exec/types.h>
#define __USE_SYSBASE
#include <proto/dos.h>
#include <inline/dos.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include "sysdeps.h"
#include "extfs.h"
#include "extfs_defs.h"
#define DEBUG 0
#include "debug.h"
// Default Finder flags
const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited;
/*
* Initialization
*/
void extfs_init(void)
{
}
/*
* Deinitialization
*/
void extfs_exit(void)
{
}
/*
* Add component to path name
*/
void add_path_component(char *path, const char *component)
{
AddPart(path, (char *)component, MAX_PATH_LENGTH);
}
/*
* Finder info and resource forks are kept in helper files
*
* Finder info:
* /path/.finf/file
* Resource fork:
* /path/.rsrc/file
*
* The .finf files store a FInfo/DInfo, followed by a FXInfo/DXInfo
* (16+16 bytes)
*/
static void make_helper_path(const char *src, char *dest, const char *add, bool only_dir = false)
{
dest[0] = 0;
// Get pointer to last component of path
const char *last_part = FilePart((char *)src);
// Copy everything before
strncpy(dest, src, last_part-src);
dest[last_part-src] = 0;
// Add additional component
AddPart(dest, (char *)add, MAX_PATH_LENGTH);
// Add last component
if (!only_dir)
AddPart(dest, (char *)last_part, MAX_PATH_LENGTH);
}
static int create_helper_dir(const char *path, const char *add)
{
char helper_dir[MAX_PATH_LENGTH];
make_helper_path(path, helper_dir, add, true);
if (helper_dir[strlen(helper_dir) - 1] == '/') // Remove trailing "/"
helper_dir[strlen(helper_dir) - 1] = 0;
return mkdir(helper_dir, 0777);
}
static int open_helper(const char *path, const char *add, int flag)
{
char helper_path[MAX_PATH_LENGTH];
make_helper_path(path, helper_path, add);
if ((flag & O_ACCMODE) == O_RDWR || (flag & O_ACCMODE) == O_WRONLY)
flag |= O_CREAT;
int fd = open(helper_path, flag, 0666);
if (fd < 0) {
if (errno == ENOENT && (flag & O_CREAT)) {
// One path component was missing, probably the helper
// directory. Try to create it and re-open the file.
int ret = create_helper_dir(path, add);
if (ret < 0)
return ret;
fd = open(helper_path, flag, 0666);
}
}
return fd;
}
static int open_finf(const char *path, int flag)
{
return open_helper(path, ".finf/", flag);
}
static int open_rsrc(const char *path, int flag)
{
return open_helper(path, ".rsrc/", flag);
}
/*
* Get/set finder type/creator for file specified by full path
*/
struct ext2type {
const char *ext;
uint32 type;
uint32 creator;
};
static const ext2type e2t_translation[] = {
{".z", FOURCC('Z','I','V','M'), FOURCC('L','Z','I','V')},
{".gz", FOURCC('G','z','i','p'), FOURCC('G','z','i','p')},
{".hqx", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
{".bin", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
{".pdf", FOURCC('P','D','F',' '), FOURCC('C','A','R','O')},
{".ps", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')},
{".sit", FOURCC('S','I','T','!'), FOURCC('S','I','T','x')},
{".tar", FOURCC('T','A','R','F'), FOURCC('T','A','R',' ')},
{".uu", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
{".uue", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
{".zip", FOURCC('Z','I','P',' '), FOURCC('Z','I','P',' ')},
{".8svx", FOURCC('8','S','V','X'), FOURCC('S','N','D','M')},
{".aifc", FOURCC('A','I','F','C'), FOURCC('T','V','O','D')},
{".aiff", FOURCC('A','I','F','F'), FOURCC('T','V','O','D')},
{".au", FOURCC('U','L','A','W'), FOURCC('T','V','O','D')},
{".mid", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')},
{".midi", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')},
{".mp2", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')},
{".mp3", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')},
{".wav", FOURCC('W','A','V','E'), FOURCC('T','V','O','D')},
{".bmp", FOURCC('B','M','P','f'), FOURCC('o','g','l','e')},
{".gif", FOURCC('G','I','F','f'), FOURCC('o','g','l','e')},
{".lbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')},
{".ilbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')},
{".jpg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')},
{".jpeg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')},
{".pict", FOURCC('P','I','C','T'), FOURCC('o','g','l','e')},
{".png", FOURCC('P','N','G','f'), FOURCC('o','g','l','e')},
{".sgi", FOURCC('.','S','G','I'), FOURCC('o','g','l','e')},
{".tga", FOURCC('T','P','I','C'), FOURCC('o','g','l','e')},
{".tif", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')},
{".tiff", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')},
{".htm", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')},
{".html", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')},
{".txt", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')},
{".rtf", FOURCC('T','E','X','T'), FOURCC('M','S','W','D')},
{".c", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".cc", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".cpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".cxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".h", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".hh", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".hpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".hxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".s", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".i", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".mpg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')},
{".mpeg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')},
{".mov", FOURCC('M','o','o','V'), FOURCC('T','V','O','D')},
{".fli", FOURCC('F','L','I',' '), FOURCC('T','V','O','D')},
{".avi", FOURCC('V','f','W',' '), FOURCC('T','V','O','D')},
{".qxd", FOURCC('X','D','O','C'), FOURCC('X','P','R','3')},
{".hfv", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')},
{".dsk", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')},
{".img", FOURCC('r','o','h','d'), FOURCC('d','d','s','k')},
{NULL, 0, 0} // End marker
};
void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
{
// Set default finder info
Mac_memset(finfo, 0, SIZEOF_FInfo);
if (fxinfo)
Mac_memset(fxinfo, 0, SIZEOF_FXInfo);
WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS);
WriteMacInt32(finfo + fdLocation, (uint32)-1);
// Read Finder info file
int fd = open_finf(path, O_RDONLY);
if (fd >= 0) {
ssize_t actual = read(fd, Mac2HostAddr(finfo), SIZEOF_FInfo);
if (fxinfo)
actual += read(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo);
close(fd);
if (actual >= SIZEOF_FInfo)
return;
}
// No Finder info file, translate file name extension to MacOS type/creator
if (!is_dir) {
int path_len = strlen(path);
for (int i=0; e2t_translation[i].ext; i++) {
int ext_len = strlen(e2t_translation[i].ext);
if (path_len < ext_len)
continue;
if (!strcasecmp(path + path_len - ext_len, e2t_translation[i].ext)) {
WriteMacInt32(finfo + fdType, e2t_translation[i].type);
WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator);
break;
}
}
}
}
void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
{
// Open Finder info file
int fd = open_finf(path, O_RDWR);
if (fd < 0)
return;
// Write file
write(fd, Mac2HostAddr(finfo), SIZEOF_FInfo);
if (fxinfo)
write(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo);
close(fd);
}
/*
* Resource fork emulation functions
*/
uint32 get_rfork_size(const char *path)
{
// Open resource file
int fd = open_rsrc(path, O_RDONLY);
if (fd < 0)
return 0;
// Get size
off_t size = lseek(fd, 0, SEEK_END);
// Close file and return size
close(fd);
return size < 0 ? 0 : size;
}
int open_rfork(const char *path, int flag)
{
return open_rsrc(path, flag);
}
void close_rfork(const char *path, int fd)
{
close(fd);
}
/*
* Read "length" bytes from file to "buffer",
* returns number of bytes read (or -1 on error)
*/
ssize_t extfs_read(int fd, void *buffer, size_t length)
{
return read(fd, buffer, length);
}
/*
* Write "length" bytes from "buffer" to file,
* returns number of bytes written (or -1 on error)
*/
ssize_t extfs_write(int fd, void *buffer, size_t length)
{
return write(fd, buffer, length);
}
/*
* Remove file/directory (and associated helper files),
* returns false on error (and sets errno)
*/
bool extfs_remove(const char *path)
{
// Remove helpers first, don't complain if this fails
char helper_path[MAX_PATH_LENGTH];
make_helper_path(path, helper_path, ".finf/", false);
remove(helper_path);
make_helper_path(path, helper_path, ".rsrc/", false);
remove(helper_path);
// Now remove file or directory (and helper directories in the directory)
if (remove(path) < 0) {
if (errno == EISDIR || errno == ENOTEMPTY) {
helper_path[0] = 0;
strncpy(helper_path, path, MAX_PATH_LENGTH-1);
add_path_component(helper_path, ".finf");
rmdir(helper_path);
helper_path[0] = 0;
strncpy(helper_path, path, MAX_PATH_LENGTH-1);
add_path_component(helper_path, ".rsrc");
rmdir(helper_path);
return rmdir(path) == 0;
} else
return false;
}
return true;
}
/*
* Rename/move file/directory (and associated helper files),
* returns false on error (and sets errno)
*/
bool extfs_rename(const char *old_path, const char *new_path)
{
// Rename helpers first, don't complain if this fails
char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH];
make_helper_path(old_path, old_helper_path, ".finf/", false);
make_helper_path(new_path, new_helper_path, ".finf/", false);
create_helper_dir(new_path, ".finf/");
rename(old_helper_path, new_helper_path);
make_helper_path(old_path, old_helper_path, ".rsrc/", false);
make_helper_path(new_path, new_helper_path, ".rsrc/", false);
create_helper_dir(new_path, ".rsrc/");
rename(old_helper_path, new_helper_path);
// Now rename file
return rename(old_path, new_path) == 0;
}
/*
* ftruncate() is missing from libnix
*/
extern unsigned long *__stdfiledes;
int ftruncate(int fd, off_t size)
{
if (SetFileSize(__stdfiledes[fd], size, OFFSET_BEGINNING) < 0)
return -1;
else
return 0;
}

View File

@ -1,743 +0,0 @@
/*
* main_amiga.cpp - Startup code for AmigaOS
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <dos/dostags.h>
#include <intuition/intuition.h>
#include <devices/timer.h>
#include <devices/ahi.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <inline/exec.h>
#include <inline/dos.h>
#include <inline/intuition.h>
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "xpram.h"
#include "timer.h"
#include "sony.h"
#include "disk.h"
#include "cdrom.h"
#include "scsi.h"
#include "audio.h"
#include "video.h"
#include "serial.h"
#include "ether.h"
#include "clip.h"
#include "emul_op.h"
#include "rom_patches.h"
#include "prefs.h"
#include "prefs_editor.h"
#include "sys.h"
#include "user_strings.h"
#include "version.h"
#define DEBUG 0
#include "debug.h"
// Options for libnix
unsigned long __stack = 0x4000; // Stack requirement
int __nocommandline = 1; // Disable command line parsing
// Constants
static const char ROM_FILE_NAME[] = "ROM";
static const char __ver[] = "$VER: " VERSION_STRING " " __DATE__;
static const int SCRATCH_MEM_SIZE = 65536;
// RAM and ROM pointers
uint32 RAMBaseMac; // RAM base (Mac address space)
uint8 *RAMBaseHost; // RAM base (host address space)
uint32 RAMSize; // Size of RAM
uint32 ROMBaseMac; // ROM base (Mac address space)
uint8 *ROMBaseHost; // ROM base (host address space)
uint32 ROMSize; // Size of ROM
// CPU and FPU type, addressing mode
int CPUType;
bool CPUIs68060;
int FPUType;
bool TwentyFourBitAddressing;
// Global variables
extern ExecBase *SysBase;
struct Library *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library *GadToolsBase = NULL;
struct Library *IFFParseBase = NULL;
struct Library *AslBase = NULL;
struct Library *P96Base = NULL;
struct Library *CyberGfxBase = NULL;
struct Library *TimerBase = NULL;
struct Library *AHIBase = NULL;
struct Library *DiskBase = NULL;
struct Task *MainTask; // Our task
uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes
APTR OldTrapHandler = NULL; // Old trap handler
APTR OldExceptionHandler = NULL; // Old exception handler
BYTE IRQSig = -1; // "Interrupt" signal number
ULONG IRQSigMask = 0; // "Interrupt" signal mask
static struct timerequest *timereq = NULL; // IORequest for timer
static struct MsgPort *ahi_port = NULL; // Port for AHI
static struct AHIRequest *ahi_io = NULL; // IORequest for AHI
static struct Process *xpram_proc = NULL; // XPRAM watchdog
static volatile bool xpram_proc_active = true; // Flag for quitting the XPRAM watchdog
static struct Process *tick_proc = NULL; // 60Hz process
static volatile bool tick_proc_active = true; // Flag for quitting the 60Hz process
static bool stack_swapped = false; // Stack swapping
static StackSwapStruct stack_swap;
// Assembly functions
struct trap_regs;
extern "C" void AtomicAnd(uint32 *p, uint32 val);
extern "C" void AtomicOr(uint32 *p, uint32 val);
extern "C" void MoveVBR(void);
extern "C" void DisableSuperBypass(void);
extern "C" void TrapHandlerAsm(void);
extern "C" void ExceptionHandlerAsm(void);
extern "C" void IllInstrHandler(trap_regs *regs);
extern "C" void PrivViolHandler(trap_regs *regs);
extern "C" void quit_emulator(void);
extern "C" void AsmTriggerNMI(void);
uint16 EmulatedSR; // Emulated SR (supervisor bit and interrupt mask)
// Prototypes
static void jump_to_rom(void);
static void xpram_func(void);
static void tick_func(void);
/*
* Main program
*/
int main(int argc, char **argv)
{
// Initialize variables
RAMBaseHost = NULL;
ROMBaseHost = NULL;
MainTask = FindTask(NULL);
struct DateStamp ds;
DateStamp(&ds);
srand(ds.ds_Tick);
// Print some info
printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
printf(" %s\n", GetString(STR_ABOUT_TEXT2));
// Open libraries
GfxBase = OpenLibrary((UBYTE *) "graphics.library", 39);
if (GfxBase == NULL) {
printf("Cannot open graphics.library V39.\n");
exit(1);
}
IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *) "intuition.library", 39);
if (IntuitionBase == NULL) {
printf("Cannot open intuition.library V39.\n");
CloseLibrary(GfxBase);
exit(1);
}
DiskBase = (struct Library *)OpenResource((UBYTE *) "disk.resource");
if (DiskBase == NULL)
QuitEmulator();
GadToolsBase = OpenLibrary((UBYTE *) "gadtools.library", 39);
if (GadToolsBase == NULL) {
ErrorAlert(STR_NO_GADTOOLS_LIB_ERR);
QuitEmulator();
}
IFFParseBase = OpenLibrary((UBYTE *) "iffparse.library", 39);
if (IFFParseBase == NULL) {
ErrorAlert(STR_NO_IFFPARSE_LIB_ERR);
QuitEmulator();
}
AslBase = OpenLibrary((UBYTE *) "asl.library", 36);
if (AslBase == NULL) {
ErrorAlert(STR_NO_ASL_LIB_ERR);
QuitEmulator();
}
if (FindTask((UBYTE *) "« Enforcer »")) {
ErrorAlert(STR_ENFORCER_RUNNING_ERR);
QuitEmulator();
}
// These two can fail (the respective gfx support won't be available, then)
P96Base = OpenLibrary((UBYTE *) "Picasso96API.library", 2);
CyberGfxBase = OpenLibrary((UBYTE *) "cybergraphics.library", 2);
// Read preferences
PrefsInit(NULL, argc, argv);
// Open AHI
ahi_port = CreateMsgPort();
if (ahi_port) {
ahi_io = (struct AHIRequest *)CreateIORequest(ahi_port, sizeof(struct AHIRequest));
if (ahi_io) {
ahi_io->ahir_Version = 2;
if (OpenDevice((UBYTE *) AHINAME, AHI_NO_UNIT, (struct IORequest *)ahi_io, 0) == 0) {
AHIBase = (struct Library *)ahi_io->ahir_Std.io_Device;
}
}
}
// Init system routines
SysInit();
// Show preferences editor
if (!PrefsFindBool("nogui"))
if (!PrefsEditor())
QuitEmulator();
// Check start of Chip memory (because we need access to 0x0000..0x2000)
if ((uint32)FindName(&SysBase->MemList, (UBYTE *) "chip memory") < 0x2000) {
ErrorAlert(STR_NO_PREPARE_EMUL_ERR);
QuitEmulator();
}
// Open timer.device
timereq = (struct timerequest *)AllocVec(sizeof(timerequest), MEMF_PUBLIC | MEMF_CLEAR);
if (timereq == NULL) {
ErrorAlert(STR_NO_MEM_ERR);
QuitEmulator();
}
if (OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timereq, 0)) {
ErrorAlert(STR_NO_TIMER_DEV_ERR);
QuitEmulator();
}
TimerBase = (struct Library *)timereq->tr_node.io_Device;
// Allocate scratch memory
ScratchMem = (uint8 *)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC);
if (ScratchMem == NULL) {
ErrorAlert(STR_NO_MEM_ERR);
QuitEmulator();
}
ScratchMem += SCRATCH_MEM_SIZE/2; // ScratchMem points to middle of block
// Create area for Mac RAM and ROM (ROM must be higher in memory,
// so we allocate one big chunk and put the ROM at the top of it)
RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary
if (RAMSize < 1024*1024) {
WarningAlert(GetString(STR_SMALL_RAM_WARN));
RAMSize = 1024*1024;
}
RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC);
if (RAMBaseHost == NULL) {
uint32 newRAMSize = AvailMem(MEMF_LARGEST) - 0x100000;
char xText[120];
sprintf(xText, GetString(STR_NOT_ENOUGH_MEM_WARN), RAMSize, newRAMSize);
if (ChoiceAlert(xText, "Use", "Quit") != 1)
QuitEmulator();
RAMSize = newRAMSize;
RAMBaseHost = (uint8 *)AllocVec(RAMSize - 0x100000, MEMF_PUBLIC);
if (RAMBaseHost == NULL) {
ErrorAlert(STR_NO_MEM_ERR);
QuitEmulator();
}
}
RAMBaseMac = (uint32)RAMBaseHost;
D(bug("Mac RAM starts at %08lx\n", RAMBaseHost));
ROMBaseHost = RAMBaseHost + RAMSize;
ROMBaseMac = (uint32)ROMBaseHost;
D(bug("Mac ROM starts at %08lx\n", ROMBaseHost));
// Get rom file path from preferences
const char *rom_path = PrefsFindString("rom");
// Load Mac ROM
BPTR rom_fh = Open(rom_path ? (char *)rom_path : (char *)ROM_FILE_NAME, MODE_OLDFILE);
if (rom_fh == 0) {
ErrorAlert(STR_NO_ROM_FILE_ERR);
QuitEmulator();
}
printf(GetString(STR_READING_ROM_FILE));
Seek(rom_fh, 0, OFFSET_END);
ROMSize = Seek(rom_fh, 0, OFFSET_CURRENT);
if (ROMSize != 512*1024 && ROMSize != 1024*1024) {
ErrorAlert(STR_ROM_SIZE_ERR);
Close(rom_fh);
QuitEmulator();
}
Seek(rom_fh, 0, OFFSET_BEGINNING);
if (Read(rom_fh, ROMBaseHost, ROMSize) != ROMSize) {
ErrorAlert(STR_ROM_FILE_READ_ERR);
Close(rom_fh);
QuitEmulator();
}
// Set CPU and FPU type
UWORD attn = SysBase->AttnFlags;
CPUType = attn & AFF_68040 ? 4 : (attn & AFF_68030 ? 3 : 2);
CPUIs68060 = attn & AFF_68060;
FPUType = attn & AFF_68881 ? 1 : 0;
// Initialize everything
if (!InitAll(NULL))
QuitEmulator();
// Move VBR away from 0 if neccessary
MoveVBR();
// On 68060, disable Super Bypass mode because of a CPU bug that is triggered by MacOS 8
if (CPUIs68060)
DisableSuperBypass();
memset((UBYTE *) 8, 0, 0x2000-8);
// Install trap handler
EmulatedSR = 0x2700;
OldTrapHandler = MainTask->tc_TrapCode;
MainTask->tc_TrapCode = (APTR)TrapHandlerAsm;
// Allocate signal for interrupt emulation and install exception handler
IRQSig = AllocSignal(-1);
IRQSigMask = 1 << IRQSig;
OldExceptionHandler = MainTask->tc_ExceptCode;
MainTask->tc_ExceptCode = (APTR)ExceptionHandlerAsm;
SetExcept(SIGBREAKF_CTRL_C | IRQSigMask, SIGBREAKF_CTRL_C | IRQSigMask);
// Start XPRAM watchdog process
xpram_proc = CreateNewProcTags(
NP_Entry, (ULONG)xpram_func,
NP_Name, (ULONG)"Basilisk II XPRAM Watchdog",
NP_Priority, 0,
TAG_END
);
// Start 60Hz process
tick_proc = CreateNewProcTags(
NP_Entry, (ULONG)tick_func,
NP_Name, (ULONG)"Basilisk II 60Hz",
NP_Priority, 5,
TAG_END
);
// Set task priority to -1 so we don't use all processing time
SetTaskPri(MainTask, -1);
WriteMacInt32(0xbff, 0); // MacsBugFlags
// Swap stack to Mac RAM area
stack_swap.stk_Lower = RAMBaseHost;
stack_swap.stk_Upper = (ULONG)RAMBaseHost + RAMSize;
stack_swap.stk_Pointer = RAMBaseHost + 0x8000;
StackSwap(&stack_swap);
stack_swapped = true;
// Jump to ROM boot routine
Start680x0();
QuitEmulator();
return 0;
}
void Start680x0(void)
{
typedef void (*rom_func)(void);
rom_func fp = (rom_func)(ROMBaseHost + 0x2a);
fp();
}
/*
* Quit emulator (__saveds because it might be called from an exception)
*/
// Assembly entry point
void __saveds quit_emulator(void)
{
QuitEmulator();
}
void QuitEmulator(void)
{
// Stop 60Hz process
if (tick_proc) {
SetSignal(0, SIGF_SINGLE);
tick_proc_active = false;
Wait(SIGF_SINGLE);
}
// Stop XPRAM watchdog process
if (xpram_proc) {
SetSignal(0, SIGF_SINGLE);
xpram_proc_active = false;
Wait(SIGF_SINGLE);
}
// Restore stack
if (stack_swapped) {
stack_swapped = false;
StackSwap(&stack_swap);
}
// Remove exception handler
if (IRQSig >= 0) {
SetExcept(0, SIGBREAKF_CTRL_C | IRQSigMask);
MainTask->tc_ExceptCode = OldExceptionHandler;
FreeSignal(IRQSig);
}
// Remove trap handler
MainTask->tc_TrapCode = OldTrapHandler;
// Deinitialize everything
ExitAll();
// Delete RAM/ROM area
if (RAMBaseHost)
FreeVec(RAMBaseHost);
// Delete scratch memory area
if (ScratchMem)
FreeMem((void *)(ScratchMem - SCRATCH_MEM_SIZE/2), SCRATCH_MEM_SIZE);
// Close timer.device
if (TimerBase)
CloseDevice((struct IORequest *)timereq);
if (timereq)
FreeVec(timereq);
// Exit system routines
SysExit();
// Close AHI
if (AHIBase)
CloseDevice((struct IORequest *)ahi_io);
if (ahi_io)
DeleteIORequest((struct IORequest *)ahi_io);
if (ahi_port)
DeleteMsgPort(ahi_port);
// Exit preferences
PrefsExit();
// Close libraries
if (CyberGfxBase)
CloseLibrary(CyberGfxBase);
if (P96Base)
CloseLibrary(P96Base);
if (AslBase)
CloseLibrary(AslBase);
if (IFFParseBase)
CloseLibrary(IFFParseBase);
if (GadToolsBase)
CloseLibrary(GadToolsBase);
if (IntuitionBase)
CloseLibrary((struct Library *)IntuitionBase);
if (GfxBase)
CloseLibrary(GfxBase);
exit(0);
}
/*
* Code was patched, flush caches if neccessary (i.e. when using a real 680x0
* or a dynamically recompiling emulator)
*/
void FlushCodeCache(void *start, uint32 size)
{
CacheClearE(start, size, CACRF_ClearI | CACRF_ClearD);
}
/*
* Mutexes
*/
struct B2_mutex {
int dummy; //!!
};
B2_mutex *B2_create_mutex(void)
{
return new B2_mutex;
}
void B2_lock_mutex(B2_mutex *mutex)
{
}
void B2_unlock_mutex(B2_mutex *mutex)
{
}
void B2_delete_mutex(B2_mutex *mutex)
{
delete mutex;
}
/*
* Interrupt flags (must be handled atomically!)
*/
uint32 InterruptFlags;
void SetInterruptFlag(uint32 flag)
{
AtomicOr(&InterruptFlags, flag);
}
void ClearInterruptFlag(uint32 flag)
{
AtomicAnd(&InterruptFlags, ~flag);
}
void TriggerInterrupt(void)
{
Signal(MainTask, IRQSigMask);
}
void TriggerNMI(void)
{
AsmTriggerNMI();
}
/*
* 60Hz thread (really 60.15Hz)
*/
static __saveds void tick_func(void)
{
int tick_counter = 0;
struct MsgPort *timer_port = NULL;
struct timerequest *timer_io = NULL;
ULONG timer_mask = 0;
// Start 60Hz timer
timer_port = CreateMsgPort();
if (timer_port) {
timer_io = (struct timerequest *)CreateIORequest(timer_port, sizeof(struct timerequest));
if (timer_io) {
if (!OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timer_io, 0)) {
timer_mask = 1 << timer_port->mp_SigBit;
timer_io->tr_node.io_Command = TR_ADDREQUEST;
timer_io->tr_time.tv_secs = 0;
timer_io->tr_time.tv_micro = 16625;
SendIO((struct IORequest *)timer_io);
}
}
}
while (tick_proc_active) {
// Wait for timer tick
Wait(timer_mask);
// Restart timer
timer_io->tr_node.io_Command = TR_ADDREQUEST;
timer_io->tr_time.tv_secs = 0;
timer_io->tr_time.tv_micro = 16625;
SendIO((struct IORequest *)timer_io);
// Pseudo Mac 1Hz interrupt, update local time
if (++tick_counter > 60) {
tick_counter = 0;
WriteMacInt32(0x20c, TimerDateTime());
SetInterruptFlag(INTFLAG_1HZ);
TriggerInterrupt();
}
// Trigger 60Hz interrupt
SetInterruptFlag(INTFLAG_60HZ);
TriggerInterrupt();
}
// Stop timer
if (timer_io) {
if (!CheckIO((struct IORequest *)timer_io))
AbortIO((struct IORequest *)timer_io);
WaitIO((struct IORequest *)timer_io);
CloseDevice((struct IORequest *)timer_io);
DeleteIORequest(timer_io);
}
if (timer_port)
DeleteMsgPort(timer_port);
// Main task asked for termination, send signal
Forbid();
Signal(MainTask, SIGF_SINGLE);
}
/*
* XPRAM watchdog thread (saves XPRAM every minute)
*/
static __saveds void xpram_func(void)
{
uint8 last_xpram[XPRAM_SIZE];
memcpy(last_xpram, XPRAM, XPRAM_SIZE);
while (xpram_proc_active) {
for (int i=0; i<60 && xpram_proc_active; i++)
Delay(50); // Only wait 1 second so we quit promptly when xpram_proc_active becomes false
if (memcmp(last_xpram, XPRAM, XPRAM_SIZE)) {
memcpy(last_xpram, XPRAM, XPRAM_SIZE);
SaveXPRAM();
}
}
// Main task asked for termination, send signal
Forbid();
Signal(MainTask, SIGF_SINGLE);
}
/*
* Display error alert
*/
void ErrorAlert(const char *text)
{
if (PrefsFindBool("nogui")) {
printf(GetString(STR_SHELL_ERROR_PREFIX), text);
return;
}
EasyStruct req;
req.es_StructSize = sizeof(EasyStruct);
req.es_Flags = 0;
req.es_Title = (UBYTE *)GetString(STR_ERROR_ALERT_TITLE);
req.es_TextFormat = (UBYTE *)GetString(STR_GUI_ERROR_PREFIX);
req.es_GadgetFormat = (UBYTE *)GetString(STR_QUIT_BUTTON);
EasyRequest(NULL, &req, NULL, (ULONG)text);
}
/*
* Display warning alert
*/
void WarningAlert(const char *text)
{
if (PrefsFindBool("nogui")) {
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
return;
}
EasyStruct req;
req.es_StructSize = sizeof(EasyStruct);
req.es_Flags = 0;
req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE);
req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX);
req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON);
EasyRequest(NULL, &req, NULL, (ULONG)text);
}
/*
* Display choice alert
*/
bool ChoiceAlert(const char *text, const char *pos, const char *neg)
{
char str[256];
sprintf(str, "%s|%s", pos, neg);
EasyStruct req;
req.es_StructSize = sizeof(EasyStruct);
req.es_Flags = 0;
req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE);
req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX);
req.es_GadgetFormat = (UBYTE *)str;
return EasyRequest(NULL, &req, NULL, (ULONG)text);
}
/*
* Illegal Instruction and Privilege Violation trap handlers
*/
struct trap_regs { // This must match the layout of M68kRegisters
uint32 d[8];
uint32 a[8];
uint16 sr;
uint32 pc;
};
void __saveds IllInstrHandler(trap_regs *r)
{
// D(bug("IllInstrHandler/%ld\n", __LINE__));
uint16 opcode = *(uint16 *)(r->pc);
if ((opcode & 0xff00) != 0x7100) {
printf("Illegal Instruction %04x at %08lx\n", *(uint16 *)(r->pc), r->pc);
printf("d0 %08lx d1 %08lx d2 %08lx d3 %08lx\n"
"d4 %08lx d5 %08lx d6 %08lx d7 %08lx\n"
"a0 %08lx a1 %08lx a2 %08lx a3 %08lx\n"
"a4 %08lx a5 %08lx a6 %08lx a7 %08lx\n"
"sr %04x\n",
r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7],
r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7],
r->sr);
QuitEmulator();
} else {
// Disable interrupts
uint16 sr = EmulatedSR;
EmulatedSR |= 0x0700;
// Call opcode routine
EmulOp(opcode, (M68kRegisters *)r);
r->pc += 2;
// Restore interrupts
EmulatedSR = sr;
if ((EmulatedSR & 0x0700) == 0 && InterruptFlags)
Signal(MainTask, IRQSigMask);
}
}
void __saveds PrivViolHandler(trap_regs *r)
{
printf("Privileged instruction %04x %04x at %08lx\n", *(uint16 *)(r->pc), *(uint16 *)(r->pc + 2), r->pc);
printf("d0 %08lx d1 %08lx d2 %08lx d3 %08lx\n"
"d4 %08lx d5 %08lx d6 %08lx d7 %08lx\n"
"a0 %08lx a1 %08lx a2 %08lx a3 %08lx\n"
"a4 %08lx a5 %08lx a6 %08lx a7 %08lx\n"
"sr %04x\n",
r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7],
r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7],
r->sr);
QuitEmulator();
}

View File

@ -1,89 +0,0 @@
/*
* prefs_amiga.cpp - Preferences handling, AmigaOS specifix stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include "sysdeps.h"
#include "prefs.h"
// Platform-specific preferences items
prefs_desc platform_prefs_items[] = {
{"sound", TYPE_STRING, false, "sound output mode description"},
{"scsimemtype", TYPE_INT32, false, "SCSI buffer memory type"},
{NULL, TYPE_END, false, NULL} // End of list
};
// Prefs file name
const char PREFS_FILE_NAME[] = "ENV:BasiliskII_prefs";
const char PREFS_FILE_NAME_ARC[] = "ENVARC:BasiliskII_prefs";
/*
* Load preferences from settings file
*/
void LoadPrefs(void)
{
// Read preferences from settings file
FILE *f = fopen(PREFS_FILE_NAME, "r");
if (f != NULL) {
// Prefs file found, load settings
LoadPrefsFromStream(f);
fclose(f);
} else {
// No prefs file, save defaults
SavePrefs();
}
}
/*
* Save preferences to settings file
*/
void SavePrefs(void)
{
FILE *f;
if ((f = fopen(PREFS_FILE_NAME, "w")) != NULL) {
SavePrefsToStream(f);
fclose(f);
}
if ((f = fopen(PREFS_FILE_NAME_ARC, "w")) != NULL) {
SavePrefsToStream(f);
fclose(f);
}
}
/*
* Add defaults of platform-specific prefs items
* You may also override the defaults set in PrefsInit()
*/
void AddPlatformPrefsDefaults(void)
{
PrefsReplaceString("extfs", "WORK:");
PrefsAddInt32("scsimemtype", 0);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,289 +0,0 @@
/*
* scsi_amiga.cpp - SCSI Manager, Amiga specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/trackdisk.h>
#include <devices/scsidisk.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <inline/exec.h>
#include "sysdeps.h"
#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "scsi.h"
#define DEBUG 0
#include "debug.h"
// Global variables
static struct SCSICmd scsi;
static IOStdReq *ios[8*8]; // IORequests for 8 units and 8 LUNs each
static IOStdReq *io; // Active IORequest (selected target)
static struct MsgPort *the_port = NULL; // Message port for device communication
static ULONG buffer_size; // Size of data buffer
static UBYTE *buffer = NULL; // Pointer to data buffer
static ULONG buffer_memf; // Buffer memory flags
static UBYTE cmd_buffer[12]; // Buffer for SCSI command
const int SENSE_LENGTH = 256;
static UBYTE *sense_buffer = NULL; // Buffer for autosense data
static bool direct_transfers_supported = false; // Direct data transfers (bypassing the buffer) are supported
/*
* Initialization
*/
void SCSIInit(void)
{
int id, lun;
int memtype = PrefsFindInt32("scsimemtype");
switch (memtype) {
case 1:
buffer_memf = MEMF_24BITDMA | MEMF_PUBLIC;
break;
case 2:
buffer_memf = MEMF_ANY | MEMF_PUBLIC;
direct_transfers_supported = true;
break;
default:
buffer_memf = MEMF_CHIP | MEMF_PUBLIC;
break;
}
// Create port and buffers
the_port = CreateMsgPort();
buffer = (UBYTE *)AllocMem(buffer_size = 0x10000, buffer_memf);
sense_buffer = (UBYTE *)AllocMem(SENSE_LENGTH, MEMF_CHIP | MEMF_PUBLIC);
if (the_port == NULL || buffer == NULL || sense_buffer == NULL) {
ErrorAlert(STR_NO_MEM_ERR);
QuitEmulator();
}
// Create and open IORequests for all 8 units (and all 8 LUNs)
for (id=0; id<8; id++) {
for (lun=0; lun<8; lun++)
ios[id*8+lun] = NULL;
char prefs_name[16];
sprintf(prefs_name, "scsi%d", id);
const char *str = PrefsFindString(prefs_name);
if (str) {
char dev_name[256];
ULONG dev_unit = 0;
if (sscanf(str, "%[^/]/%ld", dev_name, &dev_unit) == 2) {
for (lun=0; lun<8; lun++) {
struct IOStdReq *io = (struct IOStdReq *)CreateIORequest(the_port, sizeof(struct IOStdReq));
if (io == NULL)
continue;
if (OpenDevice((UBYTE *) dev_name, dev_unit + lun * 10, (struct IORequest *)io, 0)) {
DeleteIORequest(io);
continue;
}
io->io_Data = &scsi;
io->io_Length = sizeof(scsi);
io->io_Command = HD_SCSICMD;
ios[id*8+lun] = io;
}
}
}
}
// Reset SCSI bus
SCSIReset();
// Init SCSICmd
memset(&scsi, 0, sizeof(scsi));
scsi.scsi_Command = cmd_buffer;
scsi.scsi_SenseData = sense_buffer;
scsi.scsi_SenseLength = SENSE_LENGTH;
}
/*
* Deinitialization
*/
void SCSIExit(void)
{
// Close all devices
for (int i=0; i<8; i++)
for (int j=0; j<8; j++) {
struct IOStdReq *io = ios[i*8+j];
if (io) {
CloseDevice((struct IORequest *)io);
DeleteIORequest(io);
}
}
// Delete port and buffers
if (the_port)
DeleteMsgPort(the_port);
if (buffer)
FreeMem(buffer, buffer_size);
if (sense_buffer)
FreeMem(sense_buffer, SENSE_LENGTH);
}
/*
* Check if requested data size fits into buffer, allocate new buffer if needed
*/
static bool try_buffer(int size)
{
if (size <= buffer_size)
return true;
UBYTE *new_buffer = (UBYTE *)AllocMem(size, buffer_memf);
if (new_buffer == NULL)
return false;
FreeMem(buffer, buffer_size);
buffer = new_buffer;
buffer_size = size;
return true;
}
/*
* Set SCSI command to be sent by scsi_send_cmd()
*/
void scsi_set_cmd(int cmd_length, uint8 *cmd)
{
scsi.scsi_CmdLength = cmd_length;
memcpy(cmd_buffer, cmd, cmd_length);
}
/*
* Check for presence of SCSI target
*/
bool scsi_is_target_present(int id)
{
return ios[id * 8] != NULL;
}
/*
* Set SCSI target (returns false on error)
*/
bool scsi_set_target(int id, int lun)
{
struct IOStdReq *new_io = ios[id * 8 + lun];
if (new_io == NULL)
return false;
if (new_io != io)
scsi.scsi_SenseActual = 0; // Clear sense data when selecting new target
io = new_io;
return true;
}
/*
* Send SCSI command to active target (scsi_set_command() must have been called),
* read/write data according to S/G table (returns false on error); timeout is in 1/60 sec
*/
bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout)
{
// Bypass the buffer if there's only one S/G table entry
bool do_direct_transfer = (sg_size == 1 && ((uint32)sg_ptr[0] & 1) == 0 && direct_transfers_supported);
if (!do_direct_transfer) {
// Check if buffer is large enough, allocate new buffer if needed
if (!try_buffer(data_length)) {
char str[256];
sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length);
ErrorAlert(str);
return false;
}
// Process S/G table when writing
if (!reading) {
D(bug(" writing to buffer\n"));
uint8 *buffer_ptr = buffer;
for (int i=0; i<sg_size; i++) {
uint32 len = sg_len[i];
D(bug(" %d bytes from %08lx\n", len, sg_ptr[i]));
memcpy(buffer_ptr, sg_ptr[i], len);
buffer_ptr += len;
}
}
}
// Request Sense and autosense data valid?
BYTE res = 0;
if (cmd_buffer[0] == 0x03 && scsi.scsi_SenseActual) {
// Yes, fake command
D(bug(" autosense\n"));
memcpy(buffer, sense_buffer, scsi.scsi_SenseActual);
scsi.scsi_Status = 0;
do_direct_transfer = false;
} else {
// No, send regular command
D(bug(" sending command, length %ld\n", data_length));
if (do_direct_transfer) {
scsi.scsi_Data = (UWORD *)sg_ptr[0];
scsi.scsi_Length = sg_len[0];
} else {
scsi.scsi_Data = (UWORD *)buffer;
scsi.scsi_Length = data_length;
}
scsi.scsi_Actual = 0;
scsi.scsi_Flags = (reading ? SCSIF_READ : SCSIF_WRITE) | SCSIF_AUTOSENSE;
scsi.scsi_SenseActual = 0;
scsi.scsi_Status = 0;
res = DoIO((struct IORequest *)io);
D(bug(" command sent, res %d, status %d\n", res, scsi.scsi_Status));
*stat = scsi.scsi_Status;
}
if (!do_direct_transfer) {
// Process S/G table when reading
if (reading && res == 0) {
D(bug(" reading from buffer\n"));
uint8 *buffer_ptr = buffer;
for (int i=0; i<sg_size; i++) {
uint32 len = sg_len[i];
D(bug(" %d bytes to %08lx\n", len, sg_ptr[i]));
memcpy(sg_ptr[i], buffer_ptr, len);
buffer_ptr += len;
}
}
}
return res == 0;
}

View File

@ -1,861 +0,0 @@
/*
* serial_amiga.cpp - Serial device driver, AmigaOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/errors.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <devices/serial.h>
#include <devices/parallel.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/dos.h>
#include <inline/exec.h>
#include <inline/dos.h>
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"
#include "prefs.h"
#include "serial.h"
#include "serial_defs.h"
#define DEBUG 0
#include "debug.h"
#define MONITOR 0
// These messages are sent to the serial process
const uint32 MSG_QUERY = 'qery'; // Query port status, return status in control_io
const uint32 MSG_SET_PARAMS = 'setp'; // Set serial parameters (parameters in control_io)
const uint32 MSG_SET_PAR_PARAMS = 'pstp'; // Set parallel parameters (parameters in control_io)
const uint32 MSG_KILL_IO = 'kill'; // Kill pending I/O requests
const uint32 MSG_BREAK = 'brek'; // Send break
const uint32 MSG_RESET = 'rset'; // Reset channel
const uint32 MSG_PRIME_IN = 'prin'; // Data input
const uint32 MSG_PRIME_OUT = 'pout'; // Data output
struct SerMessage : public Message {
SerMessage(uint32 what_, const struct MsgPort *reply_port = NULL)
{
what = what_;
mn_ReplyPort = (struct MsgPort *)reply_port;
mn_Length = sizeof(*this);
}
uint32 what;
uint32 pb;
};
// Driver private variables
class ASERDPort : public SERDPort {
public:
ASERDPort(const char *dev)
{
device_name = dev;
if (dev && dev[0] == '*') {
is_parallel = true;
device_name++;
} else
is_parallel = false;
control_io = NULL;
serial_proc = NULL;
reply_port = NULL;
}
virtual ~ASERDPort()
{
}
virtual int16 open(uint16 config);
virtual int16 prime_in(uint32 pb, uint32 dce);
virtual int16 prime_out(uint32 pb, uint32 dce);
virtual int16 control(uint32 pb, uint32 dce, uint16 code);
virtual int16 status(uint32 pb, uint32 dce, uint16 code);
virtual int16 close(void);
private:
bool configure(uint16 config);
void set_handshake(uint32 s, bool with_dtr);
void send_to_proc(uint32 what, uint32 pb = 0);
bool query(void);
bool set_params(void);
bool set_par_params(void);
void conv_error(struct IOExtSer *io, uint32 dt);
static void serial_func(void);
const char *device_name; // Device name
bool is_parallel; // Flag: Port is parallel
IOExtSer *control_io; // IORequest for setting serial port characteristics etc.
struct Process *serial_proc; // Serial device handler process
bool proc_error; // Flag: process didn't initialize
struct MsgPort *proc_port; // Message port of process, for communication with main task
struct MsgPort *reply_port; // Reply port for communication with process
uint8 err_mask; // shkErrs
};
// Global variables
static void *proc_arg; // Argument to process
extern struct Task *MainTask; // Pointer to main task (from main_amiga.cpp)
/*
* Initialization
*/
void SerialInit(void)
{
// Read serial preferences and create structs for both ports
the_serd_port[0] = new ASERDPort(PrefsFindString("seriala"));
the_serd_port[1] = new ASERDPort(PrefsFindString("serialb"));
}
/*
* Deinitialization
*/
void SerialExit(void)
{
delete (ASERDPort *)the_serd_port[0];
delete (ASERDPort *)the_serd_port[1];
}
/*
* Open serial port
*/
int16 ASERDPort::open(uint16 config)
{
// Don't open NULL name devices
if (device_name == NULL)
return openErr;
// Init variables
err_mask = 0;
// Create message port
reply_port = CreateMsgPort();
if (reply_port == NULL)
goto open_error;
// Start process
proc_error = false;
proc_arg = this;
SetSignal(0, SIGF_SINGLE);
serial_proc = CreateNewProcTags(
NP_Entry, (ULONG)serial_func,
NP_Name, (ULONG)"Basilisk II Serial Task",
NP_Priority, 1,
TAG_END
);
if (serial_proc == NULL)
goto open_error;
// Wait for signal from process
Wait(SIGF_SINGLE);
// Initialization error? Then bail out
if (proc_error)
goto open_error;
// Configure port
configure(config);
return noErr;
open_error:
serial_proc = NULL;
if (reply_port) {
DeleteMsgPort(reply_port);
reply_port = NULL;
}
return openErr;
}
/*
* Read data from port
*/
int16 ASERDPort::prime_in(uint32 pb, uint32 dce)
{
// Send input command to serial process
D(bug("primein\n"));
read_done = false;
read_pending = true;
WriteMacInt32(input_dt + serdtDCE, dce);
send_to_proc(MSG_PRIME_IN, pb);
return 1; // Command in progress
}
/*
* Write data to port
*/
int16 ASERDPort::prime_out(uint32 pb, uint32 dce)
{
// Send output command to serial process
D(bug("primeout\n"));
write_done = false;
write_pending = true;
WriteMacInt32(output_dt + serdtDCE, dce);
send_to_proc(MSG_PRIME_OUT, pb);
return 1; // Command in progress
}
/*
* Control calls
*/
int16 ASERDPort::control(uint32 pb, uint32 dce, uint16 code)
{
D(bug("control(%ld)\n", (uint32)code));
switch (code) {
case 1: // KillIO
send_to_proc(MSG_KILL_IO);
return noErr;
case kSERDConfiguration:
if (configure(ReadMacInt16(pb + csParam)))
return noErr;
else
return paramErr;
case kSERDInputBuffer: {
if (is_parallel)
return noErr;
int buf = ReadMacInt16(pb + csParam + 4) & 0xffffffc0;
if (buf < 1024) // 1k minimum
buf = 1024;
D(bug(" buffer size is now %08lx\n", buf));
control_io->io_RBufLen = buf;
return set_params() ? noErr : paramErr;
}
case kSERDSerHShake:
set_handshake(pb + csParam, false);
return noErr;
case kSERDSetBreak:
if (!is_parallel)
send_to_proc(MSG_BREAK);
return noErr;
case kSERDClearBreak:
return noErr;
case kSERDBaudRate:
if (is_parallel)
return noErr;
control_io->io_Baud = ReadMacInt16(pb + csParam);
D(bug(" baud rate %ld\n", control_io->io_Baud));
return set_params() ? noErr : paramErr;
case kSERDHandshake:
case kSERDHandshakeRS232:
set_handshake(pb + csParam, true);
return noErr;
case kSERDClockMIDI:
if (is_parallel)
return noErr;
control_io->io_Baud = 31250;
control_io->io_SerFlags = SERF_XDISABLED | SERF_SHARED;
control_io->io_StopBits = 1;
control_io->io_ReadLen = control_io->io_WriteLen = 8;
return set_params() ? noErr : paramErr;
case kSERDMiscOptions:
case kSERDAssertDTR:
case kSERDNegateDTR:
case kSERDSetPEChar:
case kSERDSetPEAltChar:
case kSERDAssertRTS:
case kSERDNegateRTS:
return noErr; // Not supported under AmigaOS
case kSERD115KBaud:
if (is_parallel)
return noErr;
control_io->io_Baud = 115200;
return set_params() ? noErr : paramErr;
case kSERD230KBaud:
case kSERDSetHighSpeed:
if (is_parallel)
return noErr;
control_io->io_Baud = 230400;
return set_params() ? noErr : paramErr;
case kSERDResetChannel:
send_to_proc(MSG_RESET);
return noErr;
default:
printf("WARNING: SerialControl(): unimplemented control code %d\n", code);
return controlErr;
}
}
/*
* Status calls
*/
int16 ASERDPort::status(uint32 pb, uint32 dce, uint16 code)
{
D(bug("status(%ld)\n", (uint32)code));
switch (code) {
case kSERDInputCount:
WriteMacInt32(pb + csParam, 0);
if (!is_parallel) {
if (!query())
return noErr;
D(bug("status(2) successful, returning %08lx\n", control_io->IOSer.io_Actual));
WriteMacInt32(pb + csParam, control_io->IOSer.io_Actual);
}
return noErr;
case kSERDStatus: {
uint32 p = pb + csParam;
WriteMacInt8(p + staCumErrs, cum_errors);
cum_errors = 0;
WriteMacInt8(p + staRdPend, read_pending);
WriteMacInt8(p + staWrPend, write_pending);
if (is_parallel) {
WriteMacInt8(p + staXOffSent, 0);
WriteMacInt8(p + staXOffHold, 0);
WriteMacInt8(p + staCtsHold, 0);
WriteMacInt8(p + staDsrHold, 0);
WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent);
} else {
query();
WriteMacInt8(p + staXOffSent,
(control_io->io_Status & IO_STATF_XOFFREAD ? xOffWasSent : 0)
| (control_io->io_Status & (1 << 6) ? dtrNegated : 0)); // RTS
WriteMacInt8(p + staXOffHold, control_io->io_Status & IO_STATF_XOFFWRITE);
WriteMacInt8(p + staCtsHold, control_io->io_Status & (1 << 4)); // CTS
WriteMacInt8(p + staDsrHold, control_io->io_Status & (1 << 3)); // DSR
WriteMacInt8(p + staModemStatus,
(control_io->io_Status & (1 << 3) ? 0 : dsrEvent)
| (control_io->io_Status & (1 << 2) ? riEvent : 0)
| (control_io->io_Status & (1 << 5) ? 0 : dcdEvent)
| (control_io->io_Status & (1 << 4) ? 0 : ctsEvent)
| (control_io->io_Status & IO_STATF_READBREAK ? breakEvent : 0));
}
return noErr;
}
default:
printf("WARNING: SerialStatus(): unimplemented status code %d\n", code);
return statusErr;
}
}
/*
* Close serial port
*/
int16 ASERDPort::close()
{
// Stop process
if (serial_proc) {
SetSignal(0, SIGF_SINGLE);
Signal(&serial_proc->pr_Task, SIGBREAKF_CTRL_C);
Wait(SIGF_SINGLE);
}
// Delete reply port
if (reply_port) {
DeleteMsgPort(reply_port);
reply_port = NULL;
}
return noErr;
}
/*
* Configure serial port with MacOS config word
*/
bool ASERDPort::configure(uint16 config)
{
D(bug(" configure %04lx\n", (uint32)config));
if (is_parallel)
return true;
// Set number of stop bits
switch (config & 0xc000) {
case stop10:
control_io->io_StopBits = 1;
break;
case stop20:
control_io->io_StopBits = 2;
break;
default:
return false;
}
// Set parity mode
switch (config & 0x3000) {
case noParity:
control_io->io_SerFlags &= ~SERF_PARTY_ON;
break;
case oddParity:
control_io->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
break;
case evenParity:
control_io->io_SerFlags |= SERF_PARTY_ON;
control_io->io_SerFlags &= ~SERF_PARTY_ODD;
break;
default:
return false;
}
// Set number of data bits
switch (config & 0x0c00) {
case data5:
control_io->io_ReadLen = control_io->io_WriteLen = 5;
break;
case data6:
control_io->io_ReadLen = control_io->io_WriteLen = 6;
break;
case data7:
control_io->io_ReadLen = control_io->io_WriteLen = 7;
break;
case data8:
control_io->io_ReadLen = control_io->io_WriteLen = 8;
break;
}
// Set baud rate
control_io->io_Baud = 115200 / ((config & 0x03ff) + 2);
return set_params();
}
/*
* Set serial handshaking
*/
void ASERDPort::set_handshake(uint32 s, bool with_dtr)
{
D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n",
ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3),
ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7)));
err_mask = ReadMacInt8(s + shkErrs);
if (is_parallel) {
// Parallel handshake
if (with_dtr) {
if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR))
((IOExtPar *)control_io)->io_ParFlags |= PARF_ACKMODE;
else
((IOExtPar *)control_io)->io_ParFlags &= ~PARF_ACKMODE;
} else {
if (ReadMacInt8(s + shkFCTS))
((IOExtPar *)control_io)->io_ParFlags |= PARF_ACKMODE;
else
((IOExtPar *)control_io)->io_ParFlags &= ~PARF_ACKMODE;
}
set_par_params();
} else {
// Serial handshake
if (ReadMacInt8(s + shkFXOn) || ReadMacInt8(s + shkFInX))
control_io->io_SerFlags &= ~SERF_XDISABLED;
else
control_io->io_SerFlags |= SERF_XDISABLED;
if (with_dtr) {
if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR))
control_io->io_SerFlags |= SERF_7WIRE;
else
control_io->io_SerFlags &= ~SERF_7WIRE;
} else {
if (ReadMacInt8(s + shkFCTS))
control_io->io_SerFlags |= SERF_7WIRE;
else
control_io->io_SerFlags &= ~SERF_7WIRE;
}
control_io->io_CtlChar = ReadMacInt16(s + shkXOn) << 16;
set_params();
}
}
/*
* Send message to serial process
*/
void ASERDPort::send_to_proc(uint32 what, uint32 pb)
{
D(bug("sending %08lx to serial_proc\n", what));
SerMessage msg(what, reply_port);
msg.pb = pb;
PutMsg(proc_port, &msg);
WaitPort(reply_port);
GetMsg(reply_port);
D(bug(" sent\n"));
}
/*
* Query serial port status
*/
bool ASERDPort::query(void)
{
send_to_proc(MSG_QUERY);
return control_io->IOSer.io_Error == 0;
}
/*
* Set serial parameters
*/
bool ASERDPort::set_params(void)
{
// Set/clear RadBoogie
UBYTE flags = control_io->io_SerFlags;
if (!(flags & SERF_PARTY_ON) && (flags & SERF_XDISABLED) && control_io->io_ReadLen == 8)
control_io->io_SerFlags |= SERF_RAD_BOOGIE;
else
control_io->io_SerFlags &= ~SERF_RAD_BOOGIE;
// Send message to serial process
send_to_proc(MSG_SET_PARAMS);
return control_io->IOSer.io_Error == 0;
}
/*
* Set parallel parameters
*/
bool ASERDPort::set_par_params(void)
{
send_to_proc(MSG_SET_PAR_PARAMS);
return control_io->IOSer.io_Error == 0;
}
/*
* Convert AmigaOS error code to MacOS error code, set serdtResult and cum_errors
*/
void ASERDPort::conv_error(struct IOExtSer *io, uint32 dt)
{
int16 oserr;
uint8 cum;
BYTE err = io->IOSer.io_Error;
if (err == 0 || err == IOERR_NOCMD) {
oserr = 0;
cum = 0;
} else {
if (is_parallel) {
oserr = (err_mask & framingErr) ? rcvrErr : 0;
cum = framingErr;
} else {
switch (io->IOSer.io_Error) {
case SerErr_DetectedBreak:
oserr = breakRecd;
cum = breakErr;
break;
case SerErr_ParityErr:
oserr = (err_mask & parityErr) ? rcvrErr : 0;
cum = parityErr;
break;
case SerErr_BufOverflow:
oserr = (err_mask & swOverrunErr) ? rcvrErr : 0;
cum = swOverrunErr;
break;
case SerErr_LineErr:
oserr = (err_mask & hwOverrunErr) ? rcvrErr : 0;
cum = hwOverrunErr;
break;
default:
oserr = (err_mask & framingErr) ? rcvrErr : 0;
cum = framingErr;
break;
}
}
}
WriteMacInt32(dt + serdtResult, oserr);
cum_errors |= cum;
}
/*
* Process for communication with the serial.device
*/
__saveds void ASERDPort::serial_func(void)
{
struct ASERDPort *obj = (ASERDPort *)proc_arg;
struct MsgPort *proc_port = NULL, *io_port = NULL, *control_port = NULL;
struct IOExtSer *read_io = NULL, *write_io = NULL, *control_io = NULL;
uint8 orig_params[sizeof(struct IOExtSer)];
bool opened = false;
ULONG io_mask = 0, proc_port_mask = 0;
// Default: error occured
obj->proc_error = true;
// Create message port for communication with main task
proc_port = CreateMsgPort();
if (proc_port == NULL)
goto quit;
proc_port_mask = 1 << proc_port->mp_SigBit;
// Create message ports for serial.device I/O
io_port = CreateMsgPort();
if (io_port == NULL)
goto quit;
io_mask = 1 << io_port->mp_SigBit;
control_port = CreateMsgPort();
if (control_port == NULL)
goto quit;
// Create IORequests
read_io = (struct IOExtSer *)CreateIORequest(io_port, sizeof(struct IOExtSer));
write_io = (struct IOExtSer *)CreateIORequest(io_port, sizeof(struct IOExtSer));
control_io = (struct IOExtSer *)CreateIORequest(control_port, sizeof(struct IOExtSer));
if (read_io == NULL || write_io == NULL || control_io == NULL)
goto quit;
read_io->IOSer.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug
write_io->IOSer.io_Message.mn_Node.ln_Type = 0;
control_io->IOSer.io_Message.mn_Node.ln_Type = 0;
// Parse device name
char dev_name[256];
ULONG dev_unit;
if (sscanf(obj->device_name, "%[^/]/%ld", dev_name, &dev_unit) < 2)
goto quit;
// Open device
if (obj->is_parallel)
((IOExtPar *)read_io)->io_ParFlags = PARF_SHARED;
else
read_io->io_SerFlags = SERF_SHARED | SERF_7WIRE;
if (OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)read_io, 0) || read_io->IOSer.io_Device == NULL)
goto quit;
opened = true;
// Copy IORequests
memcpy(write_io, read_io, sizeof(struct IOExtSer));
memcpy(control_io, read_io, sizeof(struct IOExtSer));
// Attach control_io to control_port and set default values
control_io->IOSer.io_Message.mn_ReplyPort = control_port;
if (!obj->is_parallel) {
control_io->io_CtlChar = SER_DEFAULT_CTLCHAR;
control_io->io_RBufLen = 64;
control_io->io_ExtFlags = 0;
control_io->io_Baud = 9600;
control_io->io_BrkTime = 250000;
control_io->io_ReadLen = control_io->io_WriteLen = 8;
control_io->io_StopBits = 1;
control_io->io_SerFlags = SERF_SHARED;
control_io->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO((struct IORequest *)control_io);
memcpy(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar));
}
// Initialization went well, inform main task
obj->proc_port = proc_port;
obj->control_io = control_io;
obj->proc_error = false;
Signal(MainTask, SIGF_SINGLE);
// Main loop
for (;;) {
// Wait for I/O and messages (CTRL_C is used for quitting the task)
ULONG sig = Wait(proc_port_mask | io_mask | SIGBREAKF_CTRL_C);
// Main task wants to quit us
if (sig & SIGBREAKF_CTRL_C)
break;
// Main task sent a command to us
if (sig & proc_port_mask) {
struct SerMessage *msg;
while (msg = (SerMessage *)GetMsg(proc_port)) {
D(bug("serial_proc received %08lx\n", msg->what));
switch (msg->what) {
case MSG_QUERY:
control_io->IOSer.io_Command = SDCMD_QUERY;
DoIO((struct IORequest *)control_io);
D(bug(" query returned %08lx, actual %08lx\n", control_io->IOSer.io_Error, control_io->IOSer.io_Actual));
break;
case MSG_SET_PARAMS:
// Only send SDCMD_SETPARAMS when configuration has changed
if (memcmp(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar))) {
memcpy(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar));
memcpy(&(read_io->io_CtlChar), &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar));
memcpy(&(write_io->io_CtlChar), &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar));
control_io->IOSer.io_Command = SDCMD_SETPARAMS;
D(bug(" params %08lx %08lx %08lx %08lx %08lx %08lx\n", control_io->io_CtlChar, control_io->io_RBufLen, control_io->io_ExtFlags, control_io->io_Baud, control_io->io_BrkTime, *(uint32 *)((uint8 *)control_io + 76)));
DoIO((struct IORequest *)control_io);
D(bug(" set_parms returned %08lx\n", control_io->IOSer.io_Error));
}
break;
case MSG_SET_PAR_PARAMS:
control_io->IOSer.io_Command = PDCMD_SETPARAMS;
DoIO((struct IORequest *)control_io);
D(bug(" set_par_parms returned %08lx\n", control_io->IOSer.io_Error));
break;
case MSG_BREAK:
control_io->IOSer.io_Command = SDCMD_BREAK;
DoIO((struct IORequest *)control_io);
D(bug(" break returned %08lx\n", control_io->IOSer.io_Error));
break;
case MSG_RESET:
control_io->IOSer.io_Command = CMD_RESET;
DoIO((struct IORequest *)control_io);
D(bug(" reset returned %08lx\n", control_io->IOSer.io_Error));
break;
case MSG_KILL_IO:
AbortIO((struct IORequest *)read_io);
AbortIO((struct IORequest *)write_io);
WaitIO((struct IORequest *)read_io);
WaitIO((struct IORequest *)write_io);
obj->read_pending = obj->write_pending = false;
obj->read_done = obj->write_done = false;
break;
case MSG_PRIME_IN:
read_io->IOSer.io_Message.mn_Node.ln_Name = (char *)msg->pb;
read_io->IOSer.io_Data = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer));
read_io->IOSer.io_Length = ReadMacInt32(msg->pb + ioReqCount);
read_io->IOSer.io_Actual = 0;
read_io->IOSer.io_Command = CMD_READ;
D(bug("serial_proc receiving %ld bytes from %08lx\n", read_io->IOSer.io_Length, read_io->IOSer.io_Data));
SendIO((struct IORequest *)read_io);
break;
case MSG_PRIME_OUT: {
write_io->IOSer.io_Message.mn_Node.ln_Name = (char *)msg->pb;
write_io->IOSer.io_Data = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer));
write_io->IOSer.io_Length = ReadMacInt32(msg->pb + ioReqCount);
write_io->IOSer.io_Actual = 0;
write_io->IOSer.io_Command = CMD_WRITE;
D(bug("serial_proc transmitting %ld bytes from %08lx\n", write_io->IOSer.io_Length, write_io->IOSer.io_Data));
#if MONITOR
bug("Sending serial data:\n");
uint8 *adr = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer));
for (int i=0; i<len; i++) {
bug("%02lx ", adr[i]);
}
bug("\n");
#endif
SendIO((struct IORequest *)write_io);
break;
}
}
D(bug(" serial_proc replying\n"));
ReplyMsg(msg);
}
}
// I/O operation completed
if (sig & io_mask) {
struct IOExtSer *io;
while (io = (struct IOExtSer *)GetMsg(io_port)) {
if (io == read_io) {
D(bug("read_io complete, %ld bytes received, error %ld\n", read_io->IOSer.io_Actual, read_io->IOSer.io_Error));
uint32 pb = (uint32)read_io->IOSer.io_Message.mn_Node.ln_Name;
#if MONITOR
bug("Receiving serial data:\n");
uint8 *adr = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer));
for (int i=0; i<read_io->IOSer.io_Actual; i++) {
bug("%02lx ", adr[i]);
}
bug("\n");
#endif
WriteMacInt32(pb + ioActCount, read_io->IOSer.io_Actual);
obj->conv_error(read_io, obj->input_dt);
obj->read_done = true;
SetInterruptFlag(INTFLAG_SERIAL);
TriggerInterrupt();
} else if (io == write_io) {
D(bug("write_io complete, %ld bytes sent, error %ld\n", write_io->IOSer.io_Actual, write_io->IOSer.io_Error));
uint32 pb = (uint32)write_io->IOSer.io_Message.mn_Node.ln_Name;
WriteMacInt32(pb + ioActCount, write_io->IOSer.io_Actual);
obj->conv_error(write_io, obj->output_dt);
obj->write_done = true;
SetInterruptFlag(INTFLAG_SERIAL);
TriggerInterrupt();
}
}
}
}
quit:
// Close everything
if (opened) {
if (CheckIO((struct IORequest *)write_io) == 0) {
AbortIO((struct IORequest *)write_io);
WaitIO((struct IORequest *)write_io);
}
if (CheckIO((struct IORequest *)read_io) == 0) {
AbortIO((struct IORequest *)read_io);
WaitIO((struct IORequest *)read_io);
}
CloseDevice((struct IORequest *)read_io);
}
if (control_io)
DeleteIORequest(control_io);
if (write_io)
DeleteIORequest(write_io);
if (read_io)
DeleteIORequest(read_io);
if (control_port)
DeleteMsgPort(control_port);
if (io_port)
DeleteMsgPort(io_port);
// Send signal to main task to confirm termination
Forbid();
Signal(MainTask, SIGF_SINGLE);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,76 +0,0 @@
/*
* sysdeps.h - System dependent definitions for AmigaOS
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SYSDEPS_H
#define SYSDEPS_H
#include <exec/types.h>
#include <devices/timer.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "user_strings_amiga.h"
// Mac and host address space are the same
#define REAL_ADDRESSING 1
// Using 68k natively
#define EMULATED_68K 0
// Mac ROM is not write protected
#define ROM_IS_WRITE_PROTECTED 0
#define USE_SCRATCHMEM_SUBTERFUGE 1
// ExtFS is supported
#define SUPPORTS_EXTFS 1
// mon is not supported
#undef ENABLE_MON
// Data types
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned long uint32;
typedef signed long int32;
typedef unsigned long long uint64;
typedef signed long long int64;
typedef unsigned long long loff_t;
// Time data type for Time Manager emulation
typedef struct timeval tm_time_t;
// Endianess conversion (not needed)
#define ntohs(x) (x)
#define ntohl(x) (x)
#define htons(x) (x)
#define htonl(x) (x)
// Some systems don't define this (ExecBase->AttnFlags)
#ifndef AFF_68060
#define AFF_68060 (1L<<7)
#endif
#endif

View File

@ -1,157 +0,0 @@
/*
* timer_amiga.cpp - Time Manager emulation, AmigaOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <exec/types.h>
#include <devices/timer.h>
#define __USE_SYSBASE
#include <proto/timer.h>
#include <proto/intuition.h>
#include <inline/timer.h>
#include <inline/intuition.h>
#include "sysdeps.h"
#include "timer.h"
#define DEBUG 0
#include "debug.h"
/*
* Return microseconds since boot (64 bit)
*/
void Microseconds(uint32 &hi, uint32 &lo)
{
D(bug("Microseconds\n"));
struct timeval tv;
GetSysTime(&tv);
uint64 tl = (uint64)tv.tv_secs * 1000000 + tv.tv_micro;
hi = tl >> 32;
lo = tl;
}
/*
* Return local date/time in Mac format (seconds since 1.1.1904)
*/
uint32 TimerDateTime(void)
{
ULONG secs, mics;
CurrentTime(&secs, &mics);
return secs + 0x8b31ef80;
}
/*
* Get current time
*/
void timer_current_time(tm_time_t &t)
{
GetSysTime(&t);
}
/*
* Add times
*/
void timer_add_time(tm_time_t &res, tm_time_t a, tm_time_t b)
{
res = a;
AddTime(&res, &b);
}
/*
* Subtract times
*/
void timer_sub_time(tm_time_t &res, tm_time_t a, tm_time_t b)
{
res = a;
SubTime(&res, &b);
}
/*
* Compare times (<0: a < b, =0: a = b, >0: a > b)
*/
int timer_cmp_time(tm_time_t a, tm_time_t b)
{
return CmpTime(&b, &a);
}
/*
* Convert Mac time value (>0: microseconds, <0: microseconds) to tm_time_t
*/
void timer_mac2host_time(tm_time_t &res, int32 mactime)
{
if (mactime > 0) {
res.tv_secs = mactime / 1000; // Time in milliseconds
res.tv_micro = (mactime % 1000) * 1000;
} else {
res.tv_secs = -mactime / 1000000; // Time in negative microseconds
res.tv_micro = -mactime % 1000000;
}
}
/*
* Convert positive tm_time_t to Mac time value (>0: microseconds, <0: microseconds)
* A negative input value for hosttime results in a zero return value
* As long as the microseconds value fits in 32 bit, it must not be converted to milliseconds!
*/
int32 timer_host2mac_time(tm_time_t hosttime)
{
if (hosttime.tv_secs < 0)
return 0;
else {
uint64 t = (uint64)hosttime.tv_secs * 1000000 + hosttime.tv_micro;
if (t > 0x7fffffff)
return t / 1000; // Time in milliseconds
else
return -t; // Time in negative microseconds
}
}
/*
* Suspend emulator thread, virtual CPU in idle mode
*/
void idle_wait(void)
{
// XXX if you implement this make sure to call idle_resume() from TriggerInterrupt()
}
/*
* Resume execution of emulator thread, events just arrived
*/
void idle_resume(void)
{
}

View File

@ -1,85 +0,0 @@
/*
* user_strings_amiga.cpp - AmigaOS-specific localizable strings
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include "user_strings.h"
// Platform-specific string definitions
user_string_def platform_strings[] = {
// Common strings that have a platform-specific variant
{STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under AmigaOS. Basilisk II will try to unmount it."},
{STR_EXTFS_CTRL, "Amiga Root"},
{STR_EXTFS_NAME, "Amiga Directory Tree"},
{STR_EXTFS_VOLUME_NAME, "Amiga"},
// Purely platform-specific strings
{STR_NO_PREPARE_EMUL_ERR, "PrepareEmul is not installed. Run PrepareEmul and then try again to start Basilisk II."},
{STR_NO_GADTOOLS_LIB_ERR, "Cannot open gadtools.library V39."},
{STR_NO_IFFPARSE_LIB_ERR, "Cannot open iffparse.library V39."},
{STR_NO_ASL_LIB_ERR, "Cannot open asl.library V36."},
{STR_NO_TIMER_DEV_ERR, "Cannot open timer.device."},
{STR_NO_P96_MODE_ERR, "The selected screen mode is not a Picasso96 or CyberGraphX mode."},
{STR_NO_VIDEO_MODE_ERR, "Cannot obtain selected video mode."},
{STR_WRONG_SCREEN_DEPTH_ERR, "Basilisk II only supports 8, 16 or 24 bit screens."},
{STR_WRONG_SCREEN_FORMAT_ERR, "Basilisk II only supports big-endian chunky ARGB screen modes."},
{STR_ENFORCER_RUNNING_ERR, "Enforcer/CyberGuard is running. Remove and then try again to start Basilisk II."},
{STR_NOT_ETHERNET_WARN, "The selected network device is not an Ethernet device. Networking will be disabled."},
{STR_NO_MULTICAST_WARN, "Your Ethernet card does not support multicast and is not usable with AppleTalk. Please report this to the manufacturer of the card."},
{STR_NO_GTLAYOUT_LIB_WARN, "Cannot open gtlayout.library V39. The preferences editor GUI will not be available."},
{STR_NO_AHI_WARN, "Cannot open ahi.device V2. Audio output will be disabled."},
{STR_NO_AHI_CTRL_WARN, "Cannot open AHI control structure. Audio output will be disabled."},
{STR_NOT_ENOUGH_MEM_WARN, "Could not get %lu MBytes of memory.\nShould I use the largest Block (%lu MBytes) instead ?"},
{STR_AHI_MODE_CTRL, "AHI Mode"},
{STR_SCSI_MEMTYPE_CTRL, "Buffer Memory Type"},
{STR_MEMTYPE_CHIP_LAB, "Chip"},
{STR_MEMTYPE_24BITDMA_LAB, "24-Bit DMA"},
{STR_MEMTYPE_ANY_LAB, "Any"},
{STR_SCSI_DEVICES_CTRL, "Virtual SCSI Devices"},
{-1, NULL} // End marker
};
/*
* Fetch pointer to string, given the string number
*/
const char *GetString(int num)
{
// First search for platform-specific string
int i = 0;
while (platform_strings[i].num >= 0) {
if (platform_strings[i].num == num)
return platform_strings[i].str;
i++;
}
// Not found, search for common string
i = 0;
while (common_strings[i].num >= 0) {
if (common_strings[i].num == num)
return common_strings[i].str;
i++;
}
return NULL;
}

View File

@ -1,51 +0,0 @@
/*
* user_strings_amiga.h - AmigaOS-specific localizable strings
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef USER_STRINGS_AMIGA_H
#define USER_STRINGS_AMIGA_H
enum {
STR_NO_PREPARE_EMUL_ERR = 10000,
STR_NO_GADTOOLS_LIB_ERR,
STR_NO_IFFPARSE_LIB_ERR,
STR_NO_ASL_LIB_ERR,
STR_NO_TIMER_DEV_ERR,
STR_NO_P96_MODE_ERR,
STR_NO_VIDEO_MODE_ERR,
STR_WRONG_SCREEN_DEPTH_ERR,
STR_WRONG_SCREEN_FORMAT_ERR,
STR_ENFORCER_RUNNING_ERR,
STR_NOT_ETHERNET_WARN,
STR_NO_MULTICAST_WARN,
STR_NO_GTLAYOUT_LIB_WARN,
STR_NO_AHI_WARN,
STR_NO_AHI_CTRL_WARN,
STR_NOT_ENOUGH_MEM_WARN,
STR_AHI_MODE_CTRL,
STR_SCSI_MEMTYPE_CTRL,
STR_MEMTYPE_CHIP_LAB,
STR_MEMTYPE_24BITDMA_LAB,
STR_MEMTYPE_ANY_LAB,
STR_SCSI_DEVICES_CTRL
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +0,0 @@
/*
* xpram_amiga.cpp - XPRAM handling, AmigaOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <exec/types.h>
#define __USE_SYSBASE
#include <proto/dos.h>
#include <inline/dos.h>
#include "sysdeps.h"
#include "xpram.h"
// XPRAM file name
#if POWERPC_ROM
static char XPRAM_FILE_NAME[] = "ENV:SheepShaver_NVRAM";
static char XPRAM_FILE_NAME_ARC[] = "ENVARC:SheepShaver_NVRAM";
#else
static char XPRAM_FILE_NAME[] = "ENV:BasiliskII_XPRAM";
static char XPRAM_FILE_NAME_ARC[] = "ENVARC:BasiliskII_XPRAM";
#endif
/*
* Load XPRAM from settings file
*/
void LoadXPRAM(void)
{
BPTR fh;
if ((fh = Open(XPRAM_FILE_NAME, MODE_OLDFILE)) != NULL) {
Read(fh, XPRAM, XPRAM_SIZE);
Close(fh);
}
}
/*
* Save XPRAM to settings file
*/
void SaveXPRAM(void)
{
BPTR fh;
if ((fh = Open(XPRAM_FILE_NAME, MODE_NEWFILE)) != NULL) {
Write(fh, XPRAM, XPRAM_SIZE);
Close(fh);
}
if ((fh = Open(XPRAM_FILE_NAME_ARC, MODE_NEWFILE)) != NULL) {
Write(fh, XPRAM, XPRAM_SIZE);
Close(fh);
}
}
/*
* Delete PRAM file
*/
void ZapPRAM(void)
{
DeleteFile(XPRAM_FILE_NAME);
DeleteFile(XPRAM_FILE_NAME_ARC);
}

View File

@ -1,151 +0,0 @@
## BeOS Generic Makefile v2.1 ##
## Fill in this file to specify the project being created, and the referenced
## makefile-engine will do all of the hard work for you. This handles both
## Intel and PowerPC builds of the BeOS.
## Application Specific Settings ---------------------------------------------
# specify the name of the binary
NAME= BasiliskII
# specify the type of binary
# APP: Application
# SHARED: Shared library or add-on
# STATIC: Static library archive
# DRIVER: Kernel Driver
TYPE= APP
# add support for new Pe and Eddie features
# to fill in generic makefile
#%{
# @src->@
# specify the source files to use
# full paths or paths relative to the makefile can be included
# all files, regardless of directory, will have their object
# files created in the common object directory.
# Note that this means this makefile will not work correctly
# if two source files with the same name (source.c or source.cpp)
# are included from different directories. Also note that spaces
# in folder names do not work well with this makefile.
MACHINE=$(shell uname -m)
ifeq ($(MACHINE), BePC)
CPUSRCS = ../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp \
../uae_cpu/readcpu.cpp ../uae_cpu/fpu/fpu_x86.cpp cpustbl.cpp cpudefs.cpp cpufast.s
else
# CPUSRCS = ../powerrom_cpu/powerrom_cpu.cpp
CPUSRCS = ../uae_cpu/basilisk_glue.cpp ../uae_cpu/newcpu.cpp \
../uae_cpu/readcpu.cpp ../uae_cpu/fpu/fpu_uae.cpp cpustbl.cpp cpudefs.cpp cpuemu.cpp
endif
SRCS = ../main.cpp main_beos.cpp ../prefs.cpp ../prefs_items.cpp prefs_beos.cpp \
prefs_editor_beos.cpp sys_beos.cpp ../rom_patches.cpp ../slot_rom.cpp \
../rsrc_patches.cpp ../emul_op.cpp ../macos_util.cpp ../xpram.cpp \
xpram_beos.cpp ../timer.cpp timer_beos.cpp clip_beos.cpp ../adb.cpp \
../serial.cpp serial_beos.cpp ../ether.cpp ether_beos.cpp ../sony.cpp \
../disk.cpp ../cdrom.cpp ../scsi.cpp scsi_beos.cpp ../video.cpp \
video_beos.cpp ../audio.cpp audio_beos.cpp ../extfs.cpp extfs_beos.cpp \
../user_strings.cpp user_strings_beos.cpp about_window.cpp \
$(CPUSRCS)
# specify the resource files to use
# full path or a relative path to the resource file can be used.
RSRCS=
# @<-src@
#%}
# end support for Pe and Eddie
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
LIBS=be game media device textencoding tracker net
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
# or paths relative to the makefile. The paths included may not
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
# source file directories are NOT auto-included here
SYSTEM_INCLUDE_PATHS =
# additional paths to look for local headers
# thes use the form: #include "header"
# source file directories are automatically included
LOCAL_INCLUDE_PATHS = ../include SheepDriver SheepNet
# specify the level of optimization that you desire
# NONE, SOME, FULL
OPTIMIZE= FULL
# specify any preprocessor symbols to be defined. The symbols will not
# have their values set automatically; you must supply the value (if any)
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
# would pass "-DDEBUG" on the compiler's command line.
DEFINES= FPU_X86 SIZEOF_FLOAT=4 SIZEOF_DOUBLE=8 SIZEOF_LONG_DOUBLE=10
# specify special warning levels
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
WARNINGS =
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
SYMBOLS =
# specify debug settings
# if TRUE will allow application to be run from
# a source-level debugger
DEBUGGER =
# specify additional compiler flags for all files
COMPILER_FLAGS = -fomit-frame-pointer -fno-PIC
# specify additional linker flags
LINKER_FLAGS =
## include the makefile-engine
include /boot/system/develop/etc/makefile-engine
# special handling of UAE CPU engine
$(OBJ_DIR)/%.o : %.s
$(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@
$(OBJ_DIR)/cpuopti: $(OBJ_DIR)/cpuopti.o
$(CC) $(LDFLAGS) -o $(OBJ_DIR)/cpuopti $(OBJ_DIR)/cpuopti.o
$(OBJ_DIR)/build68k: $(OBJ_DIR)/build68k.o
$(CC) $(LDFLAGS) -o $(OBJ_DIR)/build68k $(OBJ_DIR)/build68k.o
$(OBJ_DIR)/gencpu: $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o
$(CC) $(LDFLAGS) -o $(OBJ_DIR)/gencpu $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o
cpudefs.cpp: $(OBJ_DIR)/build68k ../uae_cpu/table68k
$(OBJ_DIR)/build68k <../uae_cpu/table68k >cpudefs.cpp
cpuemu.cpp: $(OBJ_DIR)/gencpu
$(OBJ_DIR)/gencpu
cpustbl.cpp: cpuemu.cpp
cputbl.h: cpuemu.cpp
cpufast.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(INCLUDES) -S $(CFLAGS) $< -o cputmp.s
$(OBJ_DIR)/cpuopti <cputmp.s >$@ || mv cputmp.s $@
rm -f cputmp.s
streifenfrei:
-rm -f $(OBJ_DIR)/gencpu $(OBJ_DIR)/build68k $(OBJ_DIR)/cpuopti
-rm -f cpuemu.cpp cpudefs.cpp cputmp.s cpufast*.s cpustbl.cpp cputbl.h

View File

@ -1,117 +0,0 @@
## BeOS Generic Makefile v2.1 ##
## Fill in this file to specify the project being created, and the referenced
## makefile-engine will do all of the hard work for you. This handles both
## Intel and PowerPC builds of the BeOS.
## Application Specific Settings ---------------------------------------------
# specify the name of the binary
NAME= sheep
# specify the type of binary
# APP: Application
# SHARED: Shared library or add-on
# STATIC: Static library archive
# DRIVER: Kernel Driver
TYPE= DRIVER
# add support for new Pe and Eddie features
# to fill in generic makefile
#%{
# @src->@
# specify the source files to use
# full paths or paths relative to the makefile can be included
# all files, regardless of directory, will have their object
# files created in the common object directory.
# Note that this means this makefile will not work correctly
# if two source files with the same name (source.c or source.cpp)
# are included from different directories. Also note that spaces
# in folder names do not work well with this makefile.
SRCS= sheep_driver.c
# specify the resource files to use
# full path or a relative path to the resource file can be used.
RSRCS=
# @<-src@
#%}
# end support for Pe and Eddie
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
LIBS=
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
# or paths relative to the makefile. The paths included may not
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
# source file directories are NOT auto-included here
SYSTEM_INCLUDE_PATHS =
# additional paths to look for local headers
# thes use the form: #include "header"
# source file directories are automatically included
LOCAL_INCLUDE_PATHS =
# specify the level of optimization that you desire
# NONE, SOME, FULL
OPTIMIZE= FULL
# specify any preprocessor symbols to be defined. The symbols will not
# have their values set automatically; you must supply the value (if any)
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
# would pass "-DDEBUG" on the compiler's command line.
DEFINES=
# specify special warning levels
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
WARNINGS =
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
SYMBOLS =
# specify debug settings
# if TRUE will allow application to be run from a source-level
# debugger. Note that this will disable all optimzation.
DEBUGGER =
# specify additional compiler flags for all files
COMPILER_FLAGS =
# specify additional linker flags
LINKER_FLAGS =
## include the makefile-engine
include /boot/develop/etc/makefile-engine
install: $(TARGET)
cp $(TARGET) /boot/home/config/add-ons/kernel/drivers/bin
ln -sf /boot/home/config/add-ons/kernel/drivers/bin/$(NAME) /boot/home/config/add-ons/kernel/drivers/dev/$(NAME)
uninstall:
rm /boot/home/config/add-ons/kernel/drivers/bin/$(NAME)
rm /boot/home/config/add-ons/kernel/drivers/dev/$(NAME)

View File

@ -1,476 +0,0 @@
/*
* sheep_driver.c - Low memory and ROM access driver for SheepShaver and
* Basilisk II on PowerPC systems
*
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
* Basilisk II (C) 1997-2002 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __i386__
#error The sheep driver only runs on PowerPC machines.
#endif
#include <drivers/KernelExport.h>
#include <drivers/Drivers.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <fcntl.h>
#include "sheep_driver.h"
#define DEBUG 0
#if DEBUG==1
#define bug pprintf
#elif DEBUG==2
#define bug dprintf
#endif
#if DEBUG
#define D(x) (x)
#else
#define D(x) ;
#endif
#define PORT_NAME "sheep_driver installed"
/*
* For debugging
*/
static int pprintf(const char* format, ...)
{
port_id PortNum;
int len, ret;
char Buffer[1024];
va_list ap;
if ((PortNum = find_port("PortLogger")) == B_NAME_NOT_FOUND)
return(PortNum);
for (len=0; len<1024; len++)
Buffer[len]='\0';
va_start(ap, format);
vsprintf(Buffer, format, ap);
ret = write_port(PortNum, 0, Buffer, strlen(Buffer));
return ret;
}
/*
* Page table functions
*/
static uint32 *pte_address = 0;
static uint32 vsid;
static uint32 table_size;
static status_t map_page(uint32 ea, uint32 ra, uint32 **free_pte, uint32 bits)
{
int i;
int pte_class;
uint32 hash1, hash2, api, *pteg1, *pteg2;
D(bug("Trying to map EA %p -> RA %p\n", ea, ra));
// Find PTEG addresses for given EA
hash1 = (vsid & 0x7ffff) ^ ((ea >> 12) & 0xffff);
hash2 = ~hash1 & 0x7ffff;
api = (ea >> 22) & 0x3f;
pteg1 = (uint32 *)((uint32)pte_address + ((hash1 << 6) & (table_size - 1)));
pteg2 = (uint32 *)((uint32)pte_address + ((hash2 << 6) & (table_size - 1)));
D(bug("PTEG1 at %p, PTEG2 at %p\n", pteg1, pteg2));
// Search all 8 PTEs of each PTEG
*free_pte = NULL;
pte_class = 0;
for (i=0; i<8; i++) {
D(bug(" found %08lx %08lx\n", pteg1[i*2], pteg1[i*2+1]));
if (pteg1[i*2] == (0x80000000 | (vsid << 7) | (pte_class << 6) | api)) {
*free_pte = pteg1 + i*2;
D(bug(" existing PTE found (PTEG1)\n"));
break;
} else if (!pteg1[i*2]) {
*free_pte = pteg1 + i*2;
D(bug(" free PTE found (PTEG1)\n"));
break;
}
}
if (*free_pte == NULL) {
pte_class = 1;
for (i=0; i<8; i++) {
D(bug(" found %08lx %08lx\n", pteg2[i*2], pteg2[i*2+1]));
if (pteg2[i*2] == (0x80000000 | (vsid << 7) | (pte_class << 6) | api)) {
*free_pte = pteg2 + i*2;
D(bug(" existing PTE found (PTEG2)\n"));
break;
} else if (!pteg2[i*2]) {
*free_pte = pteg2 + i*2;
D(bug(" free PTE found (PTEG2)\n"));
break;
}
}
}
// Remap page
if (*free_pte == NULL) {
D(bug(" No free PTE found :-(\m"));
return B_DEVICE_FULL;
} else {
(*free_pte)[0] = 0x80000000 | (vsid << 7) | (pte_class << 6) | api;
(*free_pte)[1] = ra | bits;
D(bug(" written %08lx %08lx to PTE\n", (*free_pte)[0], (*free_pte)[1]));
return B_NO_ERROR;
}
}
static status_t remap_page(uint32 *free_pte, uint32 ra, uint32 bits)
{
D(bug("Remapping PTE %p -> RA %p\n", free_pte, ra));
// Remap page
if (free_pte == NULL) {
D(bug(" Invalid PTE :-(\n"));
return B_BAD_ADDRESS;
} else {
free_pte[1] = ra | bits;
D(bug(" written %08lx %08lx to PTE\n", free_pte[0], free_pte[1]));
return B_NO_ERROR;
}
}
/*
* Foward declarations for hook functions
*/
static status_t sheep_open(const char *name, uint32 flags, void **cookie);
static status_t sheep_close(void *cookie);
static status_t sheep_free(void *cookie);
static status_t sheep_control(void *cookie, uint32 op, void *data, size_t len);
static status_t sheep_read(void *cookie, off_t pos, void *data, size_t *len);
static status_t sheep_write(void *cookie, off_t pos, const void *data, size_t *len);
/*
* Version of our driver
*/
int32 api_version = B_CUR_DRIVER_API_VERSION;
/*
* Device_hooks structure - has function pointers to the
* various entry points for device operations
*/
static device_hooks my_device_hooks = {
&sheep_open,
&sheep_close,
&sheep_free,
&sheep_control,
&sheep_read,
&sheep_write,
NULL,
NULL,
NULL,
NULL
};
/*
* List of device names to be returned by publish_devices()
*/
static char *device_name_list[] = {
"sheep",
0
};
/*
* Init - do nothing
*/
status_t init_hardware(void)
{
#if DEBUG==2
set_dprintf_enabled(true);
#endif
D(bug("init_hardware()\n"));
return B_NO_ERROR;
}
status_t init_driver(void)
{
D(bug("init_driver()\n"));
return B_NO_ERROR;
}
void uninit_driver(void)
{
D(bug("uninit_driver()\n"));
}
/*
* publish_devices - return list of device names implemented by this driver
*/
const char **publish_devices(void)
{
return device_name_list;
}
/*
* find_device - return device hooks for a specific device name
*/
device_hooks *find_device(const char *name)
{
if (!strcmp(name, device_name_list[0]))
return &my_device_hooks;
return NULL;
}
/*
* sheep_open - hook function for the open call.
*/
static status_t sheep_open(const char *name, uint32 flags, void **cookie)
{
return B_NO_ERROR;
}
/*
* sheep_close - hook function for the close call.
*/
static status_t sheep_close(void *cookie)
{
return B_NO_ERROR;
}
/*
* sheep_free - hook function to free the cookie returned
* by the open hook. Since the open hook did not return
* a cookie, this is a no-op.
*/
static status_t sheep_free(void *cookie)
{
return B_NO_ERROR;
}
/*
* sheep_control - hook function for the ioctl call
*/
static asm void inval_tlb(uint32 ea)
{
isync
tlbie r3
sync
blr
}
static asm void tlbsync(void)
{
machine 604
tlbsync
sync
blr
}
static status_t sheep_control(void *cookie, uint32 op, void *data, size_t len)
{
static void *block;
static void *block_aligned;
physical_entry pe[2];
system_info sysinfo;
area_id id;
area_info info;
cpu_status cpu_st;
status_t res;
uint32 ra0, ra1;
uint32 *free_pte_0, *free_pte_1;
int i;
D(bug("control(%d) data %p, len %08x\n", op, data, len));
switch (op) {
case SHEEP_UP:
// Already messed up? Then do nothing now
if (find_port(PORT_NAME) != B_NAME_NOT_FOUND)
return B_NO_ERROR;
// Get system info
get_system_info(&sysinfo);
// Prepare replacement memory
block = malloc(B_PAGE_SIZE * 3);
D(bug("3 pages malloc()ed at %p\n", block));
block_aligned = (void *)(((uint32)block + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE-1));
D(bug("Address aligned to %p\n", block_aligned));
res = lock_memory(block_aligned, B_PAGE_SIZE * 2, 0);
if (res < 0)
return res;
// Get memory mapping
D(bug("Memory locked\n"));
res = get_memory_map(block_aligned, B_PAGE_SIZE * 2, pe, 2);
D(bug("get_memory_map returned %d\n", res));
if (res != B_NO_ERROR)
return res;
// Find PTE table area
id = find_area("pte_table");
get_area_info(id, &info);
pte_address = (uint32 *)info.address;
D(bug("PTE table seems to be at %p\n", pte_address));
table_size = info.size;
D(bug("PTE table size: %dKB\n", table_size / 1024));
// Disable interrupts
cpu_st = disable_interrupts();
// Find vsid and real addresses of replacement memory
for (i=0; i<table_size/8; i++) {
if (((uint32)pe[0].address & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) {
D(bug("Found page 0 PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n",
i << 2,
((pte_address[i*2]&0x80000000) >> 31),((pte_address[i*2]&0x7fffff80) >> 7),
((pte_address[i*2]&0x00000040) >> 6),(pte_address[i*2] & 0x3f),
((pte_address[i*2+1]&0xfffff000) >> 12),((pte_address[i*2+1]&0x00000100) >> 8),
((pte_address[i*2+1]&0x00000080) >> 7),((pte_address[i*2+1]&0x00000078) >> 3),
(pte_address[i*2+1]&0x00000003)));
vsid = (pte_address[i*2]&0x7fffff80) >> 7;
ra0 = (uint32)pe[0].address & 0xfffff000;
}
if ((uint32)pe[0].size == B_PAGE_SIZE) {
if (((uint32)pe[1].address & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) {
D(bug("Found page 1f PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n",
i << 2,
((pte_address[i*2]&0x80000000) >> 31), ((pte_address[i*2]&0x7fffff80) >> 7),
((pte_address[i*2]&0x00000040) >> 6), (pte_address[i*2] & 0x3f),
((pte_address[i*2+1]&0xfffff000) >> 12), ((pte_address[i*2+1]&0x00000100) >> 8),
((pte_address[i*2+1]&0x00000080) >> 7), ((pte_address[i*2+1]&0x00000078) >> 3),
(pte_address[i*2+1]&0x00000003)));
ra1 = (uint32)pe[1].address & 0xfffff000;
}
} else {
if ((((uint32)pe[0].address + B_PAGE_SIZE) & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) {
D(bug("Found page 1d PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n",
i << 2,
((pte_address[i*2]&0x80000000) >> 31), ((pte_address[i*2]&0x7fffff80) >> 7),
((pte_address[i*2]&0x00000040) >> 6), (pte_address[i*2] & 0x3f),
((pte_address[i*2+1]&0xfffff000) >> 12), ((pte_address[i*2+1]&0x00000100) >> 8),
((pte_address[i*2+1]&0x00000080) >> 7), ((pte_address[i*2+1]&0x00000078) >> 3),
(pte_address[i*2+1]&0x00000003)));
ra1 = ((uint32)pe[0].address + B_PAGE_SIZE) & 0xfffff000;
}
}
}
// Map low memory for emulator
free_pte_0 = NULL;
free_pte_1 = NULL;
__sync();
__isync();
inval_tlb(0);
inval_tlb(B_PAGE_SIZE);
if (sysinfo.cpu_type != B_CPU_PPC_603 && sysinfo.cpu_type != B_CPU_PPC_603e)
tlbsync();
res = map_page(0, ra0, &free_pte_0, 0x12);
if (res == B_NO_ERROR)
res = map_page(B_PAGE_SIZE, ra1, &free_pte_1, 0x12);
inval_tlb(0);
inval_tlb(B_PAGE_SIZE);
if (sysinfo.cpu_type != B_CPU_PPC_603 && sysinfo.cpu_type != B_CPU_PPC_603e)
tlbsync();
__sync();
__isync();
// Restore interrupts
restore_interrupts(cpu_st);
// Create port so we know that messing was successful
set_port_owner(create_port(1, PORT_NAME), B_SYSTEM_TEAM);
return B_NO_ERROR;
case SHEEP_DOWN:
return B_NO_ERROR;
default:
return B_BAD_VALUE;
}
}
/*
* sheep_read - hook function for the read call
*/
static status_t sheep_read(void *cookie, off_t pos, void *data, size_t *len)
{
void *rom_adr;
area_id area;
system_info info;
D(bug("read() pos %Lx, data %p, len %08x\n", pos, data, *len));
get_system_info(&info);
if (info.platform_type == B_BEBOX_PLATFORM) {
*len = 0;
return B_ERROR;
}
if (*len != 0x400000 && pos != 0) {
*len = 0;
return B_BAD_VALUE;
}
area = map_physical_memory("mac_rom", (void *)0xff000000, 0x00400000, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &rom_adr);
D(bug("Mapped ROM to %p, area id %d\n", rom_adr, area));
if (area < 0) {
*len = 0;
return area;
}
D(bug("Copying ROM\n"));
memcpy(data, rom_adr, *len);
D(bug("Deleting area\n"));
delete_area(area);
return B_NO_ERROR;
}
/*
* sheep_write - hook function for the write call
*/
static status_t sheep_write(void *cookie, off_t pos, const void *data, size_t *len)
{
D(bug("write() pos %Lx, data %p, len %08x\n", pos, data, *len));
return B_READ_ONLY_DEVICE;
}

View File

@ -1,33 +0,0 @@
/*
* sheep_driver.h - Low memory and ROM access driver for SheepShaver and
* Basilisk II on PowerPC systems
*
* SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SHEEP_DRIVER_H
#define SHEEP_DRIVER_H
#include <drivers/Drivers.h>
enum {
SHEEP_UP = B_DEVICE_OP_CODES_END + 1,
SHEEP_DOWN
};
#endif

View File

@ -1,115 +0,0 @@
## BeOS Generic Makefile v2.1 ##
## Fill in this file to specify the project being created, and the referenced
## makefile-engine will do all of the hard work for you. This handles both
## Intel and PowerPC builds of the BeOS.
## Application Specific Settings ---------------------------------------------
# specify the name of the binary
NAME= sheep_net
# specify the type of binary
# APP: Application
# SHARED: Shared library or add-on
# STATIC: Static library archive
# DRIVER: Kernel Driver
TYPE= SHARED
# add support for new Pe and Eddie features
# to fill in generic makefile
#%{
# @src->@
# specify the source files to use
# full paths or paths relative to the makefile can be included
# all files, regardless of directory, will have their object
# files created in the common object directory.
# Note that this means this makefile will not work correctly
# if two source files with the same name (source.c or source.cpp)
# are included from different directories. Also note that spaces
# in folder names do not work well with this makefile.
SRCS= sheep_net.cpp
# specify the resource files to use
# full path or a relative path to the resource file can be used.
RSRCS=
# @<-src@
#%}
# end support for Pe and Eddie
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
LIBS= netdev
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
# or paths relative to the makefile. The paths included may not
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
# source file directories are NOT auto-included here
SYSTEM_INCLUDE_PATHS =
# additional paths to look for local headers
# thes use the form: #include "header"
# source file directories are automatically included
LOCAL_INCLUDE_PATHS =
# specify the level of optimization that you desire
# NONE, SOME, FULL
OPTIMIZE= FULL
# specify any preprocessor symbols to be defined. The symbols will not
# have their values set automatically; you must supply the value (if any)
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
# would pass "-DDEBUG" on the compiler's command line.
DEFINES=
# specify special warning levels
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
WARNINGS =
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
SYMBOLS =
# specify debug settings
# if TRUE will allow application to be run from a source-level
# debugger. Note that this will disable all optimzation.
DEBUGGER =
# specify additional compiler flags for all files
COMPILER_FLAGS =
# specify additional linker flags
LINKER_FLAGS =
## include the makefile-engine
include /boot/develop/etc/makefile-engine
install: $(TARGET)
cp $(TARGET) /boot/beos/system/add-ons/net_server/$(NAME)
uninstall:
rm /boot/beos/system/add-ons/net_server/$(NAME)

View File

@ -1,294 +0,0 @@
/*
* sheep_net.cpp - Net server add-on for SheepShaver and Basilisk II
*
* SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <KernelKit.h>
#include <SupportKit.h>
#include <add-ons/net_server/NetDevice.h>
#include <add-ons/net_server/NetProtocol.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include "sheep_net.h"
#define DEBUG 0
#if DEBUG==1
#define bug pprintf
#elif DEBUG==2
#define bug kprintf
#endif
#if DEBUG
#define D(x) (x)
#else
#define D(x) ;
#endif
static int pprintf(const char* format, ...)
{
port_id PortNum;
int len,Ret;
char Buffer[1024];
va_list ap;
if ((PortNum = find_port("PortLogger")) == B_NAME_NOT_FOUND)
return(PortNum);
for (len=0; len<1024; len++)
Buffer[len]='\0';
va_start(ap, format);
vsprintf(Buffer, format, ap);
Ret = write_port(PortNum, 0, Buffer, strlen(Buffer));
return(Ret);
}
// Constants
#define NETDUMP_PRIO 1 // Default is 0
const uint32 buffer_size = (sizeof(net_buffer) / B_PAGE_SIZE + 1) * B_PAGE_SIZE;
// SheepNet add-on object
class SheepNetAddOn : public BNetProtocol, BPacketHandler {
public:
void AddDevice(BNetDevice *dev, const char *name);
bool PacketReceived(BNetPacket *buf, BNetDevice *dev);
};
// Global variables
static bool shutdown_now = false;
static bool active = false;
static thread_id write_thread; // Packet writer
static sem_id write_sem; // Semaphore to trigger packet writing
static BNetDevice *EtherCard = NULL; // The Ethernet card we are attached to
static area_id buffer_area; // Packet buffer area
static net_buffer *net_buffer_ptr; // Pointer to packet buffer
static uint32 rd_pos; // Current read position in packet buffer
static uint32 wr_pos; // Current write position in packet buffer
/*
* Clear packet buffer
*/
static void clear(void)
{
int i;
for (i=0;i<READ_PACKET_COUNT;i++) {
net_buffer_ptr->read[i].cmd = 0;
net_buffer_ptr->read[i].length = 0;
net_buffer_ptr->read[i].card = 0;
net_buffer_ptr->read[i].reserved = 0;
}
for (i=0;i<WRITE_PACKET_COUNT;i++) {
net_buffer_ptr->write[i].cmd = 0;
net_buffer_ptr->write[i].length = 0;
net_buffer_ptr->write[i].card = 0;
net_buffer_ptr->write[i].reserved = 0;
}
rd_pos = wr_pos = 0;
}
/*
* Packet writer thread
*/
static status_t write_packet_func(void *arg)
{
while (!shutdown_now) {
// Read and execute command
net_packet *p = &net_buffer_ptr->write[wr_pos];
while (p->cmd & IN_USE) {
D(bug("wp: %d\n", wr_pos));
switch (p->cmd >> 8) {
case ACTIVATE_SHEEP_NET:
D(bug("activate sheep-net\n"));
active = false;
clear();
active = true;
goto next;
case DEACTIVATE_SHEEP_NET:
D(bug("deactivate sheep-net\n"));
active = false;
clear();
goto next;
case SHUTDOWN_SHEEP_NET:
D(bug("shutdown sheep-net\n"));
active = false;
clear();
shutdown_now = true;
goto next;
case ADD_MULTICAST: {
const char *data = (const char *)p->data;
D(bug("add multicast %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4], data[5]));
if (active) {
status_t result;
if ((result = EtherCard->AddMulticastAddress(data)) != B_OK) {
// !! handle error !! error while creating multicast address
D(bug("error while creating multicast address %d\n", result));
}
}
break;
}
case REMOVE_MULTICAST: {
const char *data = (const char *)p->data;
D(bug("remove multicast %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4], data[5]));
if (active) {
status_t result;
if ((result = EtherCard->RemoveMulticastAddress(data)) != B_OK) {
// !! handle error !! error while removing multicast address
D(bug("error while removing multicast address %d\n", result));
}
}
break;
}
case SHEEP_PACKET: {
uint32 length = p->length;
// D(bug("sheep packet %d\n", length));
if (active) {
BStandardPacket *packet = new BStandardPacket(length);
packet->Write(0, (const char *)p->data, length);
EtherCard->SendPacket(packet);
}
break;
}
default:
D(bug("error: unknown port packet type\n"));
break;
}
p->cmd = 0; // Free packet
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
p = &net_buffer_ptr->write[wr_pos];
}
// Wait for next packet
next: acquire_sem_etc(write_sem, 1, B_TIMEOUT, 25000);
}
return 0;
}
/*
* Init the net add-on
*/
static void init_addon()
{
int i;
D(bug("init sheep-net\n"));
// Create packet buffer
if ((buffer_area = create_area("packet buffer", (void **)&net_buffer_ptr, B_ANY_ADDRESS, buffer_size, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA)) < B_NO_ERROR) {
D(bug("FATAL ERROR: can't create shared area\n"));
return;
}
// Init packet buffer
clear();
EtherCard->Address((char *)net_buffer_ptr->ether_addr);
net_buffer_ptr->read_sem = -1;
net_buffer_ptr->read_ofs = (uint32)(net_buffer_ptr->read) - (uint32)net_buffer_ptr;
net_buffer_ptr->read_packet_size = sizeof(net_packet);
net_buffer_ptr->read_packet_count = READ_PACKET_COUNT;
if ((write_sem = create_sem(0, "ether write")) < B_NO_ERROR) {
D(bug("FATAL ERROR: can't create semaphore\n"));
return;
}
net_buffer_ptr->write_sem = write_sem;
net_buffer_ptr->write_ofs = (uint32)(net_buffer_ptr->write) - (uint32)net_buffer_ptr;
net_buffer_ptr->write_packet_size = sizeof(net_packet);
net_buffer_ptr->write_packet_count = WRITE_PACKET_COUNT;
// Start packet writer thread
write_thread = spawn_thread(write_packet_func, "sheep_net ether write", B_URGENT_DISPLAY_PRIORITY, NULL);
resume_thread(write_thread);
}
/*
* Add-on attached to Ethernet card
*/
void SheepNetAddOn::AddDevice(BNetDevice *dev, const char *name)
{
if (dev->Type() != B_ETHER_NET_DEVICE)
return;
if (EtherCard != NULL) {
// !! handle error !! support for multiple ethernet cards ...
D(bug("error: SheepShaver doesn't support multiple Ethernetcards !\n"));
return;
}
EtherCard = dev;
init_addon();
register_packet_handler(this, dev, NETDUMP_PRIO);
}
/*
* Ethernet packet received
*/
bool SheepNetAddOn::PacketReceived(BNetPacket *pkt, BNetDevice *dev)
{
if (shutdown_now) {
unregister_packet_handler(this, dev);
return false;
}
// D(bug("read_packet_func %d\n", pkt->Size()));
if (active) {
D(bug("rp: %d\n", rd_pos));
net_packet *p = &net_buffer_ptr->read[rd_pos];
if (p->cmd & IN_USE) {
D(bug("error: full read buffer ... lost packet\n"));
} else {
memcpy(p->data, pkt->Data(), pkt->Size());
p->length = pkt->Size();
p->cmd = IN_USE | (SHEEP_PACKET << 8);
rd_pos = (rd_pos + 1) % READ_PACKET_COUNT;
release_sem(net_buffer_ptr->read_sem);
}
}
//D(bug("%02x %02x %02x %02x %02x %02x", (uchar) (pkt->Data())[0],(uchar) (pkt->Data())[1],(uchar) (pkt->Data())[2],(uchar) (pkt->Data())[3],(uchar) (pkt->Data())[4],(uchar) (pkt->Data())[5]));
return false;
}
#pragma export on
extern "C" BNetProtocol *open_protocol(const char *device)
{
SheepNetAddOn *dev = new SheepNetAddOn;
return dev;
}
#pragma export off

View File

@ -1,65 +0,0 @@
/*
* sheep_net.h - Net server add-on for SheepShaver and Basilisk II
*
* SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SHEEP_NET_H
#define SHEEP_NET_H
// Net buffer dimensions
#define READ_PACKET_COUNT 10
#define WRITE_PACKET_COUNT 10
// Net packet
struct net_packet {
uint32 cmd; // Command
uint32 length; // Data length
uint32 card; // Network card ID
uint32 reserved;
uint8 data[1584];
};
// Net buffer (shared area)
struct net_buffer {
uint8 ether_addr[6]; // Ethernet address
uint8 filler1[2];
sem_id read_sem; // Semaphore for read packets
uint32 read_ofs;
uint32 read_packet_size;
uint32 read_packet_count;
sem_id write_sem; // Semaphore for write packets
uint32 write_ofs;
uint32 write_packet_size;
uint32 write_packet_count;
uint8 filler[24];
net_packet read[READ_PACKET_COUNT];
net_packet write[WRITE_PACKET_COUNT];
};
// Packet commands
#define SHEEP_PACKET 0
#define ADD_MULTICAST 1
#define REMOVE_MULTICAST 2
#define ACTIVATE_SHEEP_NET 8
#define DEACTIVATE_SHEEP_NET 9
#define SHUTDOWN_SHEEP_NET 10
#define IN_USE 1
#endif

View File

@ -1,59 +0,0 @@
/*
* about_window.cpp - "About" window
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <InterfaceKit.h>
#include <stdio.h>
#include "sysdeps.h"
#include "version.h"
#include "user_strings.h"
/*
* Display "About" window
*/
void ShowAboutWindow(void)
{
char str[512];
sprintf(str,
"Basilisk II\nVersion %d.%d\n\n"
"Copyright " B_UTF8_COPYRIGHT " 1997-2008 Christian Bauer et al.\n"
"E-mail: Christian.Bauer@uni-mainz.de\n"
"http://www.uni-mainz.de/~bauec002/B2Main.html\n\n"
"Basilisk II comes with ABSOLUTELY NO\n"
"WARRANTY. This is free software, and\n"
"you are welcome to redistribute it\n"
"under the terms of the GNU General\n"
"Public License.\n",
VERSION_MAJOR, VERSION_MINOR
);
BAlert *about = new BAlert("", str, GetString(STR_OK_BUTTON), NULL, NULL, B_WIDTH_FROM_LABEL);
BTextView *theText = about->TextView();
if (theText) {
theText->SetStylable(true);
theText->Select(0, 11);
BFont ourFont;
theText->SetFontAndColor(be_bold_font);
theText->GetFontAndColor(2, &ourFont, NULL);
ourFont.SetSize(24);
theText->SetFontAndColor(&ourFont);
}
about->Go();
}

View File

@ -1,27 +0,0 @@
/*
* about_window.h - "About" window
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef ABOUT_WINDOW_H
#define ABOUT_WINDOW_H
// Display "About" window
extern void ShowAboutWindow(void);
#endif

View File

@ -1,342 +0,0 @@
/*
* audio_beos.cpp - Audio support, BeOS implementation
*
* Basilisk II (C) 1997-2008 Christian Bauer
* Portions written by Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <KernelKit.h>
#include <MediaKit.h>
#include "cpu_emulation.h"
#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "audio.h"
#include "audio_defs.h"
#define DEBUG 0
#include "debug.h"
// Global variables
static int audio_irq_done_sem = -1; // Signal from interrupt to streaming thread: data block read
static BSoundPlayer *the_player;
// Prototypes
static void playbuffer_func(void *arg, void *buf, size_t size, const media_raw_audio_format &format);
/*
* Audio manager thread (for calling media kit functions;
* this is not safe under R4 when running on the MacOS stack in kernel space)
*/
// Message constants
const uint32 MSG_QUIT_AUDIO_MANAGER = 'quit';
const uint32 MSG_ENTER_STREAM = 'entr';
const uint32 MSG_EXIT_STREAM = 'exit';
const uint32 MSG_GET_VOLUME = 'getv';
const uint32 MSG_SET_VOLUME = 'setv';
static thread_id am_thread = -1;
static sem_id am_done_sem = -1;
static volatile float am_volume;
static status_t audio_manager(void *arg)
{
for (;;) {
// Receive message
thread_id sender;
uint32 code = receive_data(&sender, NULL, 0);
D(bug("Audio manager received %08lx\n", code));
switch (code) {
case MSG_QUIT_AUDIO_MANAGER:
return 0;
case MSG_ENTER_STREAM:
the_player->Start();
break;
case MSG_EXIT_STREAM:
the_player->Stop();
break;
case MSG_GET_VOLUME:
am_volume = the_player->Volume();
break;
case MSG_SET_VOLUME:
the_player->SetVolume(am_volume);
break;
}
// Acknowledge
release_sem(am_done_sem);
}
}
/*
* Initialization
*/
// Set AudioStatus to reflect current audio stream format
static void set_audio_status_format(void)
{
AudioStatus.sample_rate = audio_sample_rates[0];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
}
void AudioInit(void)
{
// Init audio status and feature flags
audio_sample_rates.push_back(44100 << 16);
audio_sample_sizes.push_back(16);
audio_channel_counts.push_back(2);
set_audio_status_format();
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
// Sound disabled in prefs? Then do nothing
if (PrefsFindBool("nosound"))
return;
// Init semaphores
audio_irq_done_sem = create_sem(0, "Audio IRQ Done");
am_done_sem = create_sem(0, "Audio Manager Done");
// Start audio manager thread
am_thread = spawn_thread(audio_manager, "Audio Manager", B_NORMAL_PRIORITY, NULL);
resume_thread(am_thread);
// Start stream
media_raw_audio_format format;
format.frame_rate = AudioStatus.sample_rate >> 16;
format.channel_count = AudioStatus.channels;
format.format = media_raw_audio_format::B_AUDIO_SHORT;
format.byte_order = B_MEDIA_BIG_ENDIAN;
audio_frames_per_block = 4096;
size_t block_size = (AudioStatus.sample_size >> 3) * AudioStatus.channels * audio_frames_per_block;
D(bug("AudioInit: block size %d\n", block_size));
format.buffer_size = block_size;
the_player = new BSoundPlayer(&format, "MacOS Audio", playbuffer_func, NULL, NULL);
if (the_player->InitCheck() != B_NO_ERROR) {
printf("FATAL: Cannot initialize BSoundPlayer\n");
delete the_player;
the_player = NULL;
return;
} else
the_player->SetHasData(true);
// Everything OK
audio_open = true;
}
/*
* Deinitialization
*/
void AudioExit(void)
{
// Stop stream
if (the_player) {
the_player->Stop();
delete the_player;
the_player = NULL;
}
// Stop audio manager
if (am_thread > 0) {
status_t l;
send_data(am_thread, MSG_QUIT_AUDIO_MANAGER, NULL, 0);
wait_for_thread(am_thread, &l);
}
// Delete semaphores
delete_sem(am_done_sem);
delete_sem(audio_irq_done_sem);
}
/*
* First source added, start audio stream
*/
void audio_enter_stream()
{
while (send_data(am_thread, MSG_ENTER_STREAM, NULL, 0) == B_INTERRUPTED) ;
while (acquire_sem(am_done_sem) == B_INTERRUPTED) ;
}
/*
* Last source removed, stop audio stream
*/
void audio_exit_stream()
{
while (send_data(am_thread, MSG_EXIT_STREAM, NULL, 0) == B_INTERRUPTED) ;
while (acquire_sem(am_done_sem) == B_INTERRUPTED) ;
}
/*
* Streaming function
*/
static uint32 apple_stream_info; // Mac address of SoundComponentData struct describing next buffer
static void playbuffer_func(void *arg, void *buf, size_t size, const media_raw_audio_format &format)
{
// Check if new buffer is available
if (acquire_sem_etc(audio_irq_done_sem, 1, B_TIMEOUT, 0) == B_NO_ERROR) {
// Get size of audio data
D(bug("stream: new buffer present\n"));
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
if (apple_stream_info) {
size_t work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
D(bug("stream: size %d, work_size %d\n", size, work_size));
if (work_size > size)
work_size = size;
if (format.format != media_raw_audio_format::B_AUDIO_SHORT) {
D(bug("Wrong audio format %04x\n", format.format));
return;
}
// Place data into Media Kit buffer
Mac2Host_memcpy(buf, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
if (work_size != size)
memset((uint8 *)buf + work_size, 0, size - work_size);
}
} else
memset(buf, 0, size);
// Trigger audio interrupt to get new buffer
if (AudioStatus.num_sources) {
D(bug("stream: triggering irq\n"));
SetInterruptFlag(INTFLAG_AUDIO);
TriggerInterrupt();
}
}
/*
* MacOS audio interrupt, read next data block
*/
void AudioInterrupt(void)
{
D(bug("AudioInterrupt\n"));
// Get data from apple mixer
if (AudioStatus.mixer) {
M68kRegisters r;
r.a[0] = audio_data + adatStreamInfo;
r.a[1] = AudioStatus.mixer;
Execute68k(audio_data + adatGetSourceData, &r);
D(bug(" GetSourceData() returns %08lx\n", r.d[0]));
} else
WriteMacInt32(audio_data + adatStreamInfo, 0);
// Signal stream function
release_sem(audio_irq_done_sem);
D(bug("AudioInterrupt done\n"));
}
/*
* Set sampling parameters
* "index" is an index into the audio_sample_rates[] etc. arrays
* It is guaranteed that AudioStatus.num_sources == 0
*/
bool audio_set_sample_rate(int index)
{
return true;
}
bool audio_set_sample_size(int index)
{
return true;
}
bool audio_set_channels(int index)
{
return true;
}
/*
* Get/set audio info
*/
bool audio_get_main_mute(void)
{
return false;
}
uint32 audio_get_main_volume(void)
{
if (audio_open) {
while (send_data(am_thread, MSG_GET_VOLUME, NULL, 0) == B_INTERRUPTED) ;
while (acquire_sem(am_done_sem) == B_INTERRUPTED) ;
return int(am_volume * 256.0) * 0x00010001;
} else
return 0x01000100;
}
bool audio_get_speaker_mute(void)
{
return false;
}
uint32 audio_get_speaker_volume(void)
{
return 0x01000100;
}
void audio_set_main_mute(bool mute)
{
}
void audio_set_main_volume(uint32 vol)
{
if (audio_open) {
am_volume = float((vol >> 16) + (vol & 0xffff)) / 512.0;
while (send_data(am_thread, MSG_SET_VOLUME, NULL, 0) == B_INTERRUPTED) ;
while (acquire_sem(am_done_sem) == B_INTERRUPTED) ;
}
}
void audio_set_speaker_mute(bool mute)
{
}
void audio_set_speaker_volume(uint32 vol)
{
}

View File

@ -1,128 +0,0 @@
/*
* clip_beos.cpp - Clipboard handling, BeOS implementation
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <AppKit.h>
#include <support/UTF8.h>
#include "clip.h"
#include "prefs.h"
#define DEBUG 1
#include "debug.h"
// Flag: Don't convert clipboard text
static bool no_clip_conversion;
/*
* Initialization
*/
void ClipInit(void)
{
no_clip_conversion = PrefsFindBool("noclipconversion");
}
/*
* Deinitialization
*/
void ClipExit(void)
{
}
/*
* Mac application zeroes clipboard
*/
void ZeroScrap()
{
}
/*
* Mac application reads clipboard
*/
void GetScrap(void **handle, uint32 type, int32 offset)
{
D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset));
}
/*
* Mac application wrote to clipboard
*/
void PutScrap(uint32 type, void *scrap, int32 length)
{
D(bug("PutScrap type %08lx, data %08lx, length %ld\n", type, scrap, length));
if (length <= 0)
return;
switch (type) {
case 'TEXT':
D(bug(" clipping TEXT\n"));
if (be_clipboard->Lock()) {
be_clipboard->Clear();
BMessage *clipper = be_clipboard->Data();
if (no_clip_conversion) {
// Only convert CR->LF
char *buf = new char[length];
for (int i=0; i<length; i++) {
if (i[(char *)scrap] == 13)
buf[i] = 10;
else
buf[i] = i[(char *)scrap];
}
// Add text to Be clipboard
clipper->AddData("text/plain", B_MIME_TYPE, buf, length);
be_clipboard->Commit();
delete[] buf;
} else {
// Convert text from Mac charset to UTF-8
int32 dest_length = length*3;
int32 state = 0;
char *buf = new char[dest_length];
if (convert_to_utf8(B_MAC_ROMAN_CONVERSION, (char *)scrap, &length, buf, &dest_length, &state) == B_OK) {
for (int i=0; i<dest_length; i++)
if (buf[i] == 13)
buf[i] = 10;
// Add text to Be clipboard
clipper->AddData("text/plain", B_MIME_TYPE, buf, dest_length);
be_clipboard->Commit();
}
delete[] buf;
}
be_clipboard->Unlock();
}
break;
}
}

View File

@ -1,532 +0,0 @@
/*
* ether_beos.cpp - Ethernet device driver, BeOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
* Portions written by Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <KernelKit.h>
#include <AppKit.h>
#include <StorageKit.h>
#include <support/List.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#ifdef __HAIKU__
#include <sys/select.h>
#include <netinet/in.h>
#endif
#include "cpu_emulation.h"
#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "macos_util.h"
#include "ether.h"
#include "ether_defs.h"
#include "sheep_net.h"
#define DEBUG 0
#include "debug.h"
#define MONITOR 0
// List of attached protocols
struct NetProtocol {
uint16 type;
uint32 handler;
};
static BList prot_list;
// Global variables
static thread_id read_thread; // Packet reception thread
static bool ether_thread_active = true; // Flag for quitting the reception thread
static area_id buffer_area; // Packet buffer area
static net_buffer *net_buffer_ptr; // Pointer to packet buffer
static uint32 rd_pos; // Current read position in packet buffer
static uint32 wr_pos; // Current write position in packet buffer
static sem_id read_sem, write_sem; // Semaphores to trigger packet reading/writing
static int fd = -1; // UDP socket fd
static bool udp_tunnel = false;
// Prototypes
static status_t receive_proc(void *data);
/*
* 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;
for (int i=0; (p = (NetProtocol *)prot_list.ItemAt(i)) != NULL; i++)
if (p->type == type)
return p;
return NULL;
}
/*
* Remove all protocols
*/
static void remove_all_protocols(void)
{
NetProtocol *p;
while ((p = (NetProtocol *)prot_list.RemoveItem((long)0)) != NULL)
delete p;
}
/*
* Initialization
*/
bool ether_init(void)
{
// Do nothing if no Ethernet device specified
if (PrefsFindString("ether") == NULL)
return false;
// Find net_server team
i_wanna_try_that_again:
bool found_add_on = false;
team_info t_info;
int32 t_cookie = 0;
image_info i_info;
int32 i_cookie = 0;
while (get_next_team_info(&t_cookie, &t_info) == B_NO_ERROR) {
if (strstr(t_info.args,"net_server")!=NULL) {
// Check if sheep_net add-on is loaded
while (get_next_image_info(t_info.team, &i_cookie, &i_info) == B_NO_ERROR) {
if (strstr(i_info.name, "sheep_net") != NULL) {
found_add_on = true;
break;
}
}
}
if (found_add_on) break;
}
if (!found_add_on) {
// Search for sheep_net in network config file
char str[1024];
bool sheep_net_found = false;
FILE *fin = fopen("/boot/home/config/settings/network", "r");
while (!feof(fin)) {
fgets(str, 1024, fin);
if (strstr(str, "PROTOCOLS"))
if (strstr(str, "sheep_net"))
sheep_net_found = true;
}
fclose(fin);
// It was found, so something else must be wrong
if (sheep_net_found) {
WarningAlert(GetString(STR_NO_NET_ADDON_WARN));
return false;
}
// Not found, inform the user
if (!ChoiceAlert(GetString(STR_NET_CONFIG_MODIFY_WARN), GetString(STR_OK_BUTTON), GetString(STR_CANCEL_BUTTON)))
return false;
// Change the network config file and restart the network
fin = fopen("/boot/home/config/settings/network", "r");
FILE *fout = fopen("/boot/home/config/settings/network.2", "w");
bool global_found = false;
bool modified = false;
while (!feof(fin)) {
str[0] = 0;
fgets(str, 1024, fin);
if (!global_found && strstr(str, "GLOBAL:")) {
global_found = true;
} else if (global_found && !modified && strstr(str, "PROTOCOLS")) {
str[strlen(str)-1] = 0;
strcat(str, " sheep_net\n");
modified = true;
} else if (global_found && !modified && strlen(str) > 2 && str[strlen(str) - 2] == ':') {
fputs("\tPROTOCOLS = sheep_net\n", fout);
modified = true;
}
fputs(str, fout);
}
if (!modified)
fputs("\tPROTOCOLS = sheep_net\n", fout);
fclose(fout);
fclose(fin);
remove("/boot/home/config/settings/network.orig");
rename("/boot/home/config/settings/network", "/boot/home/config/settings/network.orig");
rename("/boot/home/config/settings/network.2", "/boot/home/config/settings/network");
app_info ai;
if (be_roster->GetAppInfo("application/x-vnd.Be-NETS", &ai) == B_OK) {
BMessenger msg(NULL, ai.team);
if (msg.IsValid()) {
while (be_roster->IsRunning("application/x-vnd.Be-NETS")) {
msg.SendMessage(B_QUIT_REQUESTED);
snooze(500000);
}
}
}
BPath path;
find_directory(B_BEOS_BOOT_DIRECTORY, &path);
path.Append("Netscript");
const char *argv[3] = {"/bin/sh", path.Path(), NULL};
thread_id net_server = load_image(2, argv, (const char **)environ);
resume_thread(net_server);
status_t l;
wait_for_thread(net_server, &l);
goto i_wanna_try_that_again;
}
// Set up communications with add-on
area_id handler_buffer;
if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) {
WarningAlert(GetString(STR_NET_ADDON_INIT_FAILED));
return false;
}
if ((buffer_area = clone_area("local packet buffer", (void **)&net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) {
D(bug("EtherInit: couldn't clone packet area\n"));
WarningAlert(GetString(STR_NET_ADDON_CLONE_FAILED));
return false;
}
if ((read_sem = create_sem(0, "ether read")) < B_NO_ERROR) {
printf("FATAL: can't create Ethernet semaphore\n");
return false;
}
net_buffer_ptr->read_sem = read_sem;
write_sem = net_buffer_ptr->write_sem;
read_thread = spawn_thread(receive_proc, "Ethernet Receiver", B_URGENT_DISPLAY_PRIORITY, NULL);
resume_thread(read_thread);
for (int i=0; i<WRITE_PACKET_COUNT; i++)
net_buffer_ptr->write[i].cmd = IN_USE | (ACTIVATE_SHEEP_NET << 8);
rd_pos = wr_pos = 0;
release_sem(write_sem);
// Get Ethernet address
memcpy(ether_addr, net_buffer_ptr->ether_addr, 6);
D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
// Everything OK
return true;
}
/*
* Deinitialization
*/
void ether_exit(void)
{
// Close communications with add-on
for (int i=0; i<WRITE_PACKET_COUNT; i++)
net_buffer_ptr->write[i].cmd = IN_USE | (DEACTIVATE_SHEEP_NET << 8);
release_sem(write_sem);
// Quit reception thread
ether_thread_active = false;
status_t result;
release_sem(read_sem);
wait_for_thread(read_thread, &result);
delete_sem(read_sem);
delete_area(buffer_area);
// Remove all protocols
remove_all_protocols();
}
/*
* Reset
*/
void ether_reset(void)
{
remove_all_protocols();
}
/*
* Add multicast address
*/
int16 ether_add_multicast(uint32 pb)
{
net_packet *p = &net_buffer_ptr->write[wr_pos];
if (p->cmd & IN_USE) {
D(bug("WARNING: Couldn't enable multicast address\n"));
} else {
Mac2Host_memcpy(p->data, pb + eMultiAddr, 6);
p->length = 6;
p->cmd = IN_USE | (ADD_MULTICAST << 8);
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
release_sem(write_sem);
}
return noErr;
}
/*
* Delete multicast address
*/
int16 ether_del_multicast(uint32 pb)
{
net_packet *p = &net_buffer_ptr->write[wr_pos];
if (p->cmd & IN_USE) {
D(bug("WARNING: Couldn't enable multicast address\n"));
} else {
Mac2Host_memcpy(p->data, pb + eMultiAddr, 6);
p->length = 6;
p->cmd = IN_USE | (REMOVE_MULTICAST << 8);
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
release_sem(write_sem);
}
return noErr;
}
/*
* Attach protocol handler
*/
int16 ether_attach_ph(uint16 type, uint32 handler)
{
// Already attached?
NetProtocol *p = find_protocol(type);
if (p != NULL)
return lapProtErr;
else {
// No, create and attach
p = new NetProtocol;
p->type = type;
p->handler = handler;
prot_list.AddItem(p);
return noErr;
}
}
/*
* Detach protocol handler
*/
int16 ether_detach_ph(uint16 type)
{
NetProtocol *p = find_protocol(type);
if (p != NULL) {
prot_list.RemoveItem(p);
delete p;
return noErr;
} else
return lapProtErr;
}
/*
* Transmit raw ethernet packet
*/
int16 ether_write(uint32 wds)
{
net_packet *p = &net_buffer_ptr->write[wr_pos];
if (p->cmd & IN_USE) {
D(bug("WARNING: Couldn't transmit packet (buffer full)\n"));
} else {
// Copy packet to buffer
int len = ether_wds_to_buffer(wds, p->data);
#if MONITOR
bug("Sending Ethernet packet:\n");
for (int i=0; i<len; i++) {
bug("%02x ", p->data[i]);
}
bug("\n");
#endif
// Notify add-on
p->length = len;
p->cmd = IN_USE | (SHEEP_PACKET << 8);
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
release_sem(write_sem);
}
return noErr;
}
/*
* Packet reception thread (non-UDP)
*/
static status_t receive_proc(void *data)
{
while (ether_thread_active) {
if (net_buffer_ptr->read[rd_pos].cmd & IN_USE) {
D(bug(" packet received, triggering Ethernet interrupt\n"));
SetInterruptFlag(INTFLAG_ETHER);
TriggerInterrupt();
}
acquire_sem_etc(read_sem, 1, B_TIMEOUT, 25000);
}
return 0;
}
/*
* Packet reception thread (UDP)
*/
static status_t receive_proc_udp(void *data)
{
while (ether_thread_active) {
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if (select(fd+1, &readfds, NULL, NULL, &timeout) > 0) {
D(bug(" packet received, triggering Ethernet interrupt\n"));
SetInterruptFlag(INTFLAG_ETHER);
TriggerInterrupt();
}
}
return 0;
}
/*
* Start UDP packet reception thread
*/
bool ether_start_udp_thread(int socket_fd)
{
fd = socket_fd;
udp_tunnel = true;
ether_thread_active = true;
read_thread = spawn_thread(receive_proc_udp, "UDP Receiver", B_URGENT_DISPLAY_PRIORITY, NULL);
resume_thread(read_thread);
return true;
}
/*
* Stop UDP packet reception thread
*/
void ether_stop_udp_thread(void)
{
ether_thread_active = false;
status_t result;
wait_for_thread(read_thread, &result);
}
/*
* Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers
*/
void EtherInterrupt(void)
{
D(bug("EtherIRQ\n"));
EthernetPacket ether_packet;
uint32 packet = ether_packet.addr();
if (udp_tunnel) {
ssize_t length;
// Read packets from socket and hand to ether_udp_read() for processing
while (true) {
struct sockaddr_in from;
socklen_t from_len = sizeof(from);
length = recvfrom(fd, Mac2HostAddr(packet), 1514, 0, (struct sockaddr *)&from, &from_len);
if (length < 14)
break;
ether_udp_read(packet, length, &from);
}
} else {
// Call protocol handler for received packets
net_packet *p = &net_buffer_ptr->read[rd_pos];
while (p->cmd & IN_USE) {
if ((p->cmd >> 8) == SHEEP_PACKET) {
Host2Mac_memcpy(packet, p->data, p->length);
#if MONITOR
bug("Receiving Ethernet packet:\n");
for (int i=0; i<p->length; i++) {
bug("%02x ", ReadMacInt8(packet + i));
}
bug("\n");
#endif
// Get packet type
uint16 type = ReadMacInt16(packet + 12);
// Look for protocol
NetProtocol *prot = find_protocol(type);
if (prot == NULL)
goto next;
// No default handler
if (prot->handler == 0)
goto next;
// Copy header to RHA
Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12)));
// Call protocol handler
M68kRegisters r;
r.d[0] = type; // Packet type
r.d[1] = p->length - 14; // Remaining packet length (without header, for ReadPacket)
r.a[0] = packet + 14; // Pointer to packet (Mac 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 %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
Execute68k(prot->handler, &r);
}
next: p->cmd = 0; // Free packet
rd_pos = (rd_pos + 1) % READ_PACKET_COUNT;
p = &net_buffer_ptr->read[rd_pos];
}
}
D(bug(" EtherIRQ done\n"));
}

View File

@ -1,489 +0,0 @@
/*
* extfs_beos.cpp - MacOS file system for access native file system access, BeOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <fs_attr.h>
#include <support/TypeConstants.h>
#include <support/UTF8.h>
#include <storage/Mime.h>
#include "extfs.h"
#include "extfs_defs.h"
#define DEBUG 0
#include "debug.h"
// Default Finder flags
const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited;
// Temporary buffer for transfers from/to kernel space
const int TMP_BUF_SIZE = 0x10000;
static uint8 *tmp_buf = NULL;
/*
* Initialization
*/
void extfs_init(void)
{
// Allocate temporary buffer
tmp_buf = new uint8[TMP_BUF_SIZE];
}
/*
* Deinitialization
*/
void extfs_exit(void)
{
// Delete temporary buffer
delete[] tmp_buf;
}
/*
* Add component to path name
*/
void add_path_component(char *path, const char *component)
{
int l = strlen(path);
if (l < MAX_PATH_LENGTH-1 && path[l-1] != '/') {
path[l] = '/';
path[l+1] = 0;
}
strncat(path, component, MAX_PATH_LENGTH-1);
}
/*
* Get/set finder info for file/directory specified by full path
*/
struct mime2type {
const char *mime;
uint32 type;
uint32 creator;
bool reversible; // type -> mime translation possible
};
static const mime2type m2t_translation[] = {
{"application/x-compress", 'ZIVM', 'LZIV', true},
{"application/x-gzip", 'Gzip', 'Gzip', true},
{"application/x-macbinary", 'BINA', '????', false},
{"application/mac-binhex40", 'TEXT', 'SITx', false},
{"application/pdf", 'PDF ', 'CARO', true},
{"application/postscript", 'TEXT', 'ttxt', false},
{"application/x-stuffit", 'SIT!', 'SITx', true},
{"application/x-tar", 'TARF', 'TAR ', true},
{"application/x-uuencode", 'TEXT', 'SITx', false},
{"application/zip", 'ZIP ', 'ZIP ', true},
{"audio/x-8svx", '8SVX', 'SNDM', true},
{"audio/x-aifc", 'AIFC', 'TVOD', true},
{"audio/x-aiff", 'AIFF', 'TVOD', true},
{"audio/basic", 'ULAW', 'TVOD', true},
{"audio/x-midi", 'MIDI', 'TVOD', true},
{"audio/x-mpeg", 'MPG ', 'TVOD', true},
{"audio/x-wav", 'WAVE', 'TVOD', true},
{"image/x-bmp", 'BMPf', 'ogle', true},
{"image/gif", 'GIFf', 'ogle', true},
{"image/x-ilbm", 'ILBM', 'GKON', true},
{"image/jpeg", 'JPEG', 'ogle', true},
{"image/jpeg", 'JFIF', 'ogle', true},
{"image/x-photoshop", '8BPS', '8BIM', true},
{"image/pict", 'PICT', 'ogle', true},
{"image/png", 'PNGf', 'ogle', true},
{"image/x-sgi", '.SGI', 'ogle', true},
{"image/x-targa", 'TPIC', 'ogle', true},
{"image/tiff", 'TIFF', 'ogle', true},
{"text/html", 'TEXT', 'MOSS', false},
{"text/plain", 'TEXT', 'ttxt', true},
{"text/rtf", 'TEXT', 'MSWD', false},
{"text/x-source-code", 'TEXT', 'R*ch', false},
{"video/mpeg", 'MPEG', 'TVOD', true},
{"video/quicktime", 'MooV', 'TVOD', true},
{"video/x-flc", 'FLI ', 'TVOD', true},
{"video/x-msvideo", 'VfW ', 'TVOD', true},
{NULL, 0, 0, false} // End marker
};
void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
{
// Set default finder info
Mac_memset(finfo, 0, SIZEOF_FInfo);
if (fxinfo)
Mac_memset(fxinfo, 0, SIZEOF_FXInfo);
WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS);
WriteMacInt32(finfo + fdLocation, (uint32)-1);
// Open file
int fd = open(path, O_RDONLY);
if (fd < 0)
return;
if (!is_dir) {
// Read BeOS MIME type
ssize_t actual = fs_read_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, tmp_buf, 256);
tmp_buf[255] = 0;
if (actual > 0) {
// Translate MIME type to MacOS type/creator
uint8 mactype[4];
if (sscanf((char *)tmp_buf, "application/x-MacOS-%c%c%c%c", mactype, mactype+1, mactype+2, mactype+3) == 4) {
// MacOS style type
WriteMacInt32(finfo + fdType, (mactype[0] << 24) | (mactype[1] << 16) | (mactype[2] << 8) | mactype[3]);
} else {
// MIME string, look in table
for (int i=0; m2t_translation[i].mime; i++) {
if (!strcmp((char *)tmp_buf, m2t_translation[i].mime)) {
WriteMacInt32(finfo + fdType, m2t_translation[i].type);
WriteMacInt32(finfo + fdCreator, m2t_translation[i].creator);
break;
}
}
}
}
// Override file type with MACOS:CREATOR attribute
if (fs_read_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, tmp_buf, 4) == 4)
WriteMacInt32(finfo + fdCreator, (tmp_buf[0] << 24) | (tmp_buf[1] << 16) | (tmp_buf[2] << 8) | tmp_buf[3]);
}
// Read MACOS:HFS_FLAGS attribute
if (fs_read_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, tmp_buf, 2) == 2)
WriteMacInt16(finfo + fdFlags, (tmp_buf[0] << 8) | tmp_buf[1]);
// Close file
close(fd);
}
void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
{
// Open file
int fd = open(path, O_WRONLY);
if (fd < 0)
return;
if (!is_dir) {
// Set BEOS:TYPE attribute
uint32 type = ReadMacInt32(finfo + fdType);
if (type) {
for (int i=0; m2t_translation[i].mime; i++) {
if (m2t_translation[i].type == type && m2t_translation[i].reversible) {
fs_write_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, m2t_translation[i].mime, strlen(m2t_translation[i].mime) + 1);
break;
}
}
}
// Set MACOS:CREATOR attribute
uint32 creator = ReadMacInt32(finfo + fdCreator);
if (creator) {
tmp_buf[0] = creator >> 24;
tmp_buf[1] = creator >> 16;
tmp_buf[2] = creator >> 8;
tmp_buf[3] = creator;
fs_write_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, tmp_buf, 4);
}
}
// Write MACOS:HFS_FLAGS attribute
uint16 flags = ReadMacInt16(finfo + fdFlags);
if (flags != DEFAULT_FINDER_FLAGS) {
tmp_buf[0] = flags >> 8;
tmp_buf[1] = flags;
fs_write_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, tmp_buf, 2);
} else
fs_remove_attr(fd, "MACOS:HFS_FLAGS");
// Close file
close(fd);
}
/*
* Resource fork emulation functions
*/
uint32 get_rfork_size(const char *path)
{
// Open file
int fd = open(path, O_RDONLY);
if (fd < 0)
return 0;
// Get size of MACOS:RFORK attribute
struct attr_info info;
if (fs_stat_attr(fd, "MACOS:RFORK", &info) < 0)
info.size = 0;
// Close file and return size
close(fd);
return info.size;
}
int open_rfork(const char *path, int flag)
{
// Open original file
int fd = open(path, flag);
if (fd < 0)
return -1;
// Open temporary file for resource fork
char rname[L_tmpnam];
tmpnam(rname);
int rfd = open(rname, O_RDWR | O_CREAT | O_TRUNC, 0666);
if (rfd < 0) {
close(fd);
return -1;
}
unlink(rname); // File will be deleted when closed
// Get size of MACOS:RFORK attribute
struct attr_info info;
if (fs_stat_attr(fd, "MACOS:RFORK", &info) < 0)
info.size = 0;
// Copy resource data from attribute to temporary file
if (info.size > 0) {
// Allocate buffer
void *buf = malloc(info.size);
if (buf == NULL) {
close(rfd);
close(fd);
return -1;
}
// Copy data
fs_read_attr(fd, "MACOS:RFORK", B_RAW_TYPE, 0, buf, info.size);
write(rfd, buf, info.size);
lseek(rfd, 0, SEEK_SET);
// Free buffer
if (buf)
free(buf);
}
// Close original file
close(fd);
return rfd;
}
void close_rfork(const char *path, int fd)
{
if (fd < 0)
return;
// Get size of temporary file
struct stat st;
if (fstat(fd, &st) < 0)
st.st_size = 0;
// Open original file
int ofd = open(path, O_WRONLY);
if (ofd > 0) {
// Copy resource data to MACOS:RFORK attribute
if (st.st_size > 0) {
// Allocate buffer
void *buf = malloc(st.st_size);
if (buf == NULL) {
close(ofd);
close(fd);
return;
}
// Copy data
lseek(fd, 0, SEEK_SET);
read(fd, buf, st.st_size);
fs_write_attr(ofd, "MACOS:RFORK", B_RAW_TYPE, 0, buf, st.st_size);
// Free buffer
if (buf)
free(buf);
} else
fs_remove_attr(ofd, "MACOS:RFORK");
// Close original file
close(ofd);
}
// Close temporary file
close(fd);
}
/*
* Read "length" bytes from file to "buffer",
* returns number of bytes read (or -1 on error)
*/
static inline ssize_t sread(int fd, void *buf, size_t count)
{
ssize_t res;
while ((res = read(fd, buf, count)) == B_INTERRUPTED) ;
return res;
}
ssize_t extfs_read(int fd, void *buffer, size_t length)
{
// Buffer in kernel space?
if ((uint32)buffer < 0x80000000) {
// Yes, transfer via buffer
ssize_t actual = 0;
while (length) {
size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length;
ssize_t res = sread(fd, tmp_buf, transfer_size);
if (res < 0)
return res;
memcpy(buffer, tmp_buf, res);
buffer = (void *)((uint8 *)buffer + res);
length -= res;
actual += res;
if (res != transfer_size)
return actual;
}
return actual;
} else {
// No, transfer directly
return sread(fd, buffer, length);
}
}
/*
* Write "length" bytes from "buffer" to file,
* returns number of bytes written (or -1 on error)
*/
static inline ssize_t swrite(int fd, void *buf, size_t count)
{
ssize_t res;
while ((res = write(fd, buf, count)) == B_INTERRUPTED) ;
return res;
}
ssize_t extfs_write(int fd, void *buffer, size_t length)
{
// Buffer in kernel space?
if ((uint32)buffer < 0x80000000) {
// Yes, transfer via buffer
ssize_t actual = 0;
while (length) {
size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length;
memcpy(tmp_buf, buffer, transfer_size);
ssize_t res = swrite(fd, tmp_buf, transfer_size);
if (res < 0)
return res;
buffer = (void *)((uint8 *)buffer + res);
length -= res;
actual += res;
if (res != transfer_size)
return actual;
}
return actual;
} else {
// No, transfer directly
return swrite(fd, buffer, length);
}
}
/*
* Remove file/directory, returns false on error (and sets errno)
*/
bool extfs_remove(const char *path)
{
if (remove(path) < 0) {
if (errno == EISDIR)
return rmdir(path) == 0;
else
return false;
}
return true;
}
/*
* Rename/move file/directory, returns false on error (and sets errno)
*/
bool extfs_rename(const char *old_path, const char *new_path)
{
return rename(old_path, new_path) == 0;
}
/*
* Strings (filenames) conversion
*/
// Convert from the host OS filename encoding to MacRoman
const char *host_encoding_to_macroman(const char *filename)
{
int32 state = 0;
static char buffer[512];
int32 size = sizeof(buffer) - 1;
int32 insize = strlen(filename);
convert_from_utf8(B_MAC_ROMAN_CONVERSION, filename, &insize, buffer, &size, &state);
buffer[size] = 0;
return buffer;
}
// Convert from MacRoman to host OS filename encoding
const char *macroman_to_host_encoding(const char *filename)
{
int32 state = 0;
static char buffer[512];
int32 insize = strlen(filename);
int32 size = sizeof(buffer) - 1;
convert_to_utf8(B_MAC_ROMAN_CONVERSION, filename, &insize, buffer, &size, &state);
buffer[size] = 0;
return buffer;
}

View File

@ -1,826 +0,0 @@
/*
* main_beos.cpp - Startup code for BeOS
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <AppKit.h>
#include <InterfaceKit.h>
#include <KernelKit.h>
#include <StorageKit.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "xpram.h"
#include "timer.h"
#include "video.h"
#include "rom_patches.h"
#include "prefs.h"
#include "prefs_editor.h"
#include "sys.h"
#include "user_strings.h"
#include "version.h"
#include "main.h"
#include "sheep_driver.h"
#define DEBUG 0
#include "debug.h"
// Constants
const char APP_SIGNATURE[] = "application/x-vnd.cebix-BasiliskII";
const char ROM_FILE_NAME[] = "ROM";
const char RAM_AREA_NAME[] = "Macintosh RAM";
const char ROM_AREA_NAME[] = "Macintosh ROM";
const uint32 MSG_START = 'strt'; // Emulator start message
const uint32 ROM_AREA_SIZE = 0x500000; // Enough to hold PowerMac ROM (for powerrom_cpu)
// Prototypes
#if __POWERPC__
static void sigsegv_handler(vregs *r);
#endif
// Application object
class BasiliskII : public BApplication {
public:
BasiliskII() : BApplication(APP_SIGNATURE)
{
// Find application directory and cwd to it
app_info the_info;
GetAppInfo(&the_info);
BEntry the_file(&the_info.ref);
BEntry the_dir;
the_file.GetParent(&the_dir);
BPath the_path;
the_dir.GetPath(&the_path);
chdir(the_path.Path());
// Initialize other variables
rom_area = ram_area = -1;
xpram_thread = tick_thread = -1;
xpram_thread_active = true;
tick_thread_active = true;
AllowQuitting = true;
}
virtual void ReadyToRun(void);
virtual void MessageReceived(BMessage *msg);
void StartEmulator(void);
virtual bool QuitRequested(void);
virtual void Quit(void);
thread_id xpram_thread; // XPRAM watchdog
thread_id tick_thread; // 60Hz thread
volatile bool xpram_thread_active; // Flag for quitting the XPRAM thread
volatile bool tick_thread_active; // Flag for quitting the 60Hz thread
bool AllowQuitting; // Flag: Alt-Q quitting allowed
private:
static status_t emul_func(void *arg);
static status_t tick_func(void *arg);
static status_t xpram_func(void *arg);
static void sigsegv_invoc(int sig, void *arg, vregs *r);
void init_rom(void);
void load_rom(void);
area_id rom_area; // ROM area ID
area_id ram_area; // RAM area ID
struct sigaction sigsegv_action; // Data access exception signal (of emulator thread)
// Exceptions
class area_error {};
class file_open_error {};
class file_read_error {};
class rom_size_error {};
char* vmdir;
};
static BasiliskII *the_app;
// CPU and FPU type, addressing mode
int CPUType;
bool CPUIs68060;
int FPUType;
bool TwentyFourBitAddressing;
// Global variables for PowerROM CPU
thread_id emul_thread = -1; // Emulator thread
#if __POWERPC__
int sheep_fd = -1; // fd of sheep driver
#endif
/*
* Create application object and start it
*/
int main(int argc, char **argv)
{
the_app = new BasiliskII();
the_app->Run();
delete the_app;
return 0;
}
/*
* Run application
*/
void BasiliskII::ReadyToRun(void)
{
// Initialize variables
RAMBaseHost = NULL;
ROMBaseHost = NULL;
srand(real_time_clock());
tzset();
// Print some info
printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
printf(" %s\n", GetString(STR_ABOUT_TEXT2));
// Delete old areas
area_id old_ram_area = find_area(RAM_AREA_NAME);
if (old_ram_area > 0)
delete_area(old_ram_area);
area_id old_rom_area = find_area(ROM_AREA_NAME);
if (old_rom_area > 0)
delete_area(old_rom_area);
// Read preferences
int argc = 0;
char **argv = NULL;
PrefsInit(vmdir, argc, argv);
// Init system routines
SysInit();
// Show preferences editor (or start emulator directly)
if (!PrefsFindBool("nogui"))
PrefsEditor();
else
PostMessage(MSG_START);
}
/*
* Message received
*/
void BasiliskII::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case MSG_START:
StartEmulator();
break;
default:
BApplication::MessageReceived(msg);
}
}
/*
* Start emulator
*/
void BasiliskII::StartEmulator(void)
{
char str[256];
#if REAL_ADDRESSING
// Open sheep driver and remap low memory
sheep_fd = open("/dev/sheep", 0);
if (sheep_fd < 0) {
sprintf(str, GetString(STR_NO_SHEEP_DRIVER_ERR), strerror(sheep_fd), sheep_fd);
ErrorAlert(str);
PostMessage(B_QUIT_REQUESTED);
return;
}
status_t res = ioctl(sheep_fd, SHEEP_UP);
if (res < 0) {
sprintf(str, GetString(STR_SHEEP_UP_ERR), strerror(res), res);
ErrorAlert(str);
PostMessage(B_QUIT_REQUESTED);
return;
}
#endif
// Create area for Mac RAM
RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary
if (RAMSize < 1024*1024) {
WarningAlert(GetString(STR_SMALL_RAM_WARN));
RAMSize = 1024*1024;
}
RAMBaseHost = (uint8 *)0x10000000;
ram_area = create_area(RAM_AREA_NAME, (void **)&RAMBaseHost, B_BASE_ADDRESS, RAMSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (ram_area < 0) {
ErrorAlert(STR_NO_RAM_AREA_ERR);
PostMessage(B_QUIT_REQUESTED);
return;
}
D(bug("RAM area %ld at %p\n", ram_area, RAMBaseHost));
// Create area and load Mac ROM
try {
init_rom();
} catch (area_error) {
ErrorAlert(STR_NO_ROM_AREA_ERR);
PostMessage(B_QUIT_REQUESTED);
return;
} catch (file_open_error) {
ErrorAlert(STR_NO_ROM_FILE_ERR);
PostMessage(B_QUIT_REQUESTED);
return;
} catch (file_read_error) {
ErrorAlert(STR_ROM_FILE_READ_ERR);
PostMessage(B_QUIT_REQUESTED);
return;
} catch (rom_size_error) {
ErrorAlert(STR_ROM_SIZE_ERR);
PostMessage(B_QUIT_REQUESTED);
return;
}
// Initialize everything
if (!InitAll(NULL)) {
PostMessage(B_QUIT_REQUESTED);
return;
}
// Write protect ROM
set_area_protection(rom_area, B_READ_AREA);
// Disallow quitting with Alt-Q from now on
AllowQuitting = false;
// Start XPRAM watchdog thread
xpram_thread = spawn_thread(xpram_func, "XPRAM Watchdog", B_LOW_PRIORITY, this);
resume_thread(xpram_thread);
// Start 60Hz interrupt
tick_thread = spawn_thread(tick_func, "60Hz", B_REAL_TIME_PRIORITY, this);
resume_thread(tick_thread);
// Start emulator thread
emul_thread = spawn_thread(emul_func, "MacOS", B_NORMAL_PRIORITY, this);
resume_thread(emul_thread);
}
/*
* Quit emulator
*/
void QuitEmulator(void)
{
the_app->AllowQuitting = true;
be_app->PostMessage(B_QUIT_REQUESTED);
exit_thread(0);
}
bool BasiliskII::QuitRequested(void)
{
if (AllowQuitting)
return BApplication::QuitRequested();
else
return false;
}
void BasiliskII::Quit(void)
{
status_t l;
// Stop 60Hz interrupt
if (tick_thread > 0) {
tick_thread_active = false;
wait_for_thread(tick_thread, &l);
}
// Wait for emulator thread to finish
if (emul_thread > 0)
wait_for_thread(emul_thread, &l);
// Exit 680x0 emulation
Exit680x0();
// Stop XPRAM watchdog thread
if (xpram_thread > 0) {
xpram_thread_active = false;
suspend_thread(xpram_thread); // Wake thread up from snooze()
snooze(1000);
resume_thread(xpram_thread);
wait_for_thread(xpram_thread, &l);
}
// Deinitialize everything
ExitAll();
// Delete ROM area
if (rom_area >= 0)
delete_area(rom_area);
// Delete RAM area
if (ram_area >= 0)
delete_area(ram_area);
#if REAL_ADDRESSING
// Unmap low memory and close memory mess driver
if (sheep_fd >= 0) {
ioctl(sheep_fd, SHEEP_DOWN);
close(sheep_fd);
}
#endif
// Exit system routines
SysExit();
// Exit preferences
PrefsExit();
BApplication::Quit();
}
/*
* Create area for ROM (sets rom_area) and load ROM file
*
* area_error : Cannot create area
* file_open_error: Cannot open ROM file
* file_read_error: Cannot read ROM file
*/
void BasiliskII::init_rom(void)
{
// Create area for ROM
ROMBaseHost = (uint8 *)0x40800000;
rom_area = create_area(ROM_AREA_NAME, (void **)&ROMBaseHost, B_BASE_ADDRESS, ROM_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (rom_area < 0)
throw area_error();
D(bug("ROM area %ld at %p\n", rom_area, ROMBaseHost));
// Load ROM
load_rom();
}
/*
* Load ROM file
*
* file_open_error: Cannot open ROM file
* file_read_error: Cannot read ROM file
*/
void BasiliskII::load_rom(void)
{
// Get rom file path from preferences
const char *rom_path = PrefsFindString("rom");
// Try to open ROM file
BFile file(rom_path ? rom_path : ROM_FILE_NAME, B_READ_ONLY);
if (file.InitCheck() != B_NO_ERROR)
throw file_open_error();
printf(GetString(STR_READING_ROM_FILE));
// Is the ROM size correct?
off_t rom_size = 0;
file.GetSize(&rom_size);
if (rom_size != 64*1024 && rom_size != 128*1024 && rom_size != 256*1024 && rom_size != 512*1024 && rom_size != 1024*1024)
throw rom_size_error();
uint8 *rom = new uint8[rom_size]; // Reading directly into the area doesn't work
ssize_t actual = file.Read((void *)rom, rom_size);
if (actual == rom_size)
memcpy(ROMBaseHost, rom, rom_size);
delete[] rom;
if (actual != rom_size)
throw file_read_error();
ROMSize = rom_size;
}
/*
* Emulator thread function
*/
status_t BasiliskII::emul_func(void *arg)
{
BasiliskII *obj = (BasiliskII *)arg;
#if __POWERPC__
// Install data access signal handler
sigemptyset(&obj->sigsegv_action.sa_mask);
obj->sigsegv_action.sa_handler = (__signal_func_ptr)(obj->sigsegv_invoc);
obj->sigsegv_action.sa_flags = 0;
obj->sigsegv_action.sa_userdata = arg;
sigaction(SIGSEGV, &obj->sigsegv_action, NULL);
#endif
// Exceptions will send signals
disable_debugger(true);
// Start 68k and jump to ROM boot routine
Start680x0();
// Quit program
obj->AllowQuitting = true;
be_app->PostMessage(B_QUIT_REQUESTED);
return 0;
}
/*
* Code was patched, flush caches if neccessary (i.e. when using a real 680x0
* or a dynamically recompiling emulator)
*/
void FlushCodeCache(void *start, uint32 size)
{
}
/*
* Mutexes
*/
struct B2_mutex {
int dummy; //!!
};
B2_mutex *B2_create_mutex(void)
{
return new B2_mutex;
}
void B2_lock_mutex(B2_mutex *mutex)
{
}
void B2_unlock_mutex(B2_mutex *mutex)
{
}
void B2_delete_mutex(B2_mutex *mutex)
{
delete mutex;
}
/*
* Interrupt flags (must be handled atomically!)
*/
uint32 InterruptFlags = 0;
void SetInterruptFlag(uint32 flag)
{
atomic_or((int32 *)&InterruptFlags, flag);
}
void ClearInterruptFlag(uint32 flag)
{
atomic_and((int32 *)&InterruptFlags, ~flag);
}
/*
* 60Hz thread (really 60.15Hz)
*/
status_t BasiliskII::tick_func(void *arg)
{
BasiliskII *obj = (BasiliskII *)arg;
int tick_counter = 0;
bigtime_t current = system_time();
while (obj->tick_thread_active) {
// Wait
current += 16625;
snooze_until(current, B_SYSTEM_TIMEBASE);
// Pseudo Mac 1Hz interrupt, update local time
if (++tick_counter > 60) {
tick_counter = 0;
WriteMacInt32(0x20c, TimerDateTime());
SetInterruptFlag(INTFLAG_1HZ);
TriggerInterrupt();
}
// Trigger 60Hz interrupt
SetInterruptFlag(INTFLAG_60HZ);
TriggerInterrupt();
}
return 0;
}
/*
* XPRAM watchdog thread (saves XPRAM every minute)
*/
status_t BasiliskII::xpram_func(void *arg)
{
uint8 last_xpram[XPRAM_SIZE];
memcpy(last_xpram, XPRAM, XPRAM_SIZE);
while (((BasiliskII *)arg)->xpram_thread_active) {
snooze(60*1000000);
if (memcmp(last_xpram, XPRAM, XPRAM_SIZE)) {
memcpy(last_xpram, XPRAM, XPRAM_SIZE);
SaveXPRAM();
}
}
return 0;
}
/*
* Display error alert
*/
void ErrorAlert(const char *text)
{
if (PrefsFindBool("nogui")) {
printf(GetString(STR_SHELL_ERROR_PREFIX), text);
return;
}
VideoQuitFullScreen();
char str[256];
sprintf(str, GetString(STR_GUI_ERROR_PREFIX), text);
BAlert *alert = new BAlert(GetString(STR_ERROR_ALERT_TITLE), str, GetString(STR_QUIT_BUTTON), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT);
alert->Go();
}
/*
* Display warning alert
*/
void WarningAlert(const char *text)
{
if (PrefsFindBool("nogui")) {
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
return;
}
char str[256];
sprintf(str, GetString(STR_GUI_WARNING_PREFIX), text);
BAlert *alert = new BAlert(GetString(STR_WARNING_ALERT_TITLE), str, GetString(STR_OK_BUTTON), NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT);
alert->Go();
}
/*
* Display choice alert
*/
bool ChoiceAlert(const char *text, const char *pos, const char *neg)
{
char str[256];
sprintf(str, GetString(STR_GUI_WARNING_PREFIX), text);
BAlert *alert = new BAlert(GetString(STR_WARNING_ALERT_TITLE), str, pos, neg, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT);
return alert->Go() == 0;
}
/*
* SEGV handler
*/
#if __POWERPC__
static uint32 segv_r[32];
asm void BasiliskII::sigsegv_invoc(register int sig, register void *arg, register vregs *r)
{
mflr r0
stw r0,8(r1)
stwu r1,-56(r1)
lwz r3,segv_r(r2)
stmw r13,13*4(r3)
mr r3,r5
bl sigsegv_handler
lwz r3,segv_r(r2)
lmw r13,13*4(r3)
lwz r0,56+8(r1)
mtlr r0
addi r1,r1,56
blr
}
static void sigsegv_handler(vregs *r)
{
// Fetch volatile registers
segv_r[0] = r->r0;
segv_r[1] = r->r1;
segv_r[2] = r->r2;
segv_r[3] = r->r3;
segv_r[4] = r->r4;
segv_r[5] = r->r5;
segv_r[6] = r->r6;
segv_r[7] = r->r7;
segv_r[8] = r->r8;
segv_r[9] = r->r9;
segv_r[10] = r->r10;
segv_r[11] = r->r11;
segv_r[12] = r->r12;
// Get opcode and divide into fields
uint32 opcode = *(uint32 *)r->pc;
uint32 primop = opcode >> 26;
uint32 exop = (opcode >> 1) & 0x3ff;
uint32 ra = (opcode >> 16) & 0x1f;
uint32 rb = (opcode >> 11) & 0x1f;
uint32 rd = (opcode >> 21) & 0x1f;
uint32 imm = opcode & 0xffff;
// Analyze opcode
enum {
TYPE_UNKNOWN,
TYPE_LOAD,
TYPE_STORE
} transfer_type = TYPE_UNKNOWN;
enum {
SIZE_UNKNOWN,
SIZE_BYTE,
SIZE_HALFWORD,
SIZE_WORD
} transfer_size = SIZE_UNKNOWN;
enum {
MODE_UNKNOWN,
MODE_NORM,
MODE_U,
MODE_X,
MODE_UX
} addr_mode = MODE_UNKNOWN;
switch (primop) {
case 31:
switch (exop) {
case 23: // lwzx
transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
case 55: // lwzux
transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
case 87: // lbzx
transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
case 119: // lbzux
transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
case 151: // stwx
transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
case 183: // stwux
transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
case 215: // stbx
transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
case 247: // stbux
transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
case 279: // lhzx
transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break;
case 311: // lhzux
transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break;
case 343: // lhax
transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break;
case 375: // lhaux
transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break;
case 407: // sthx
transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break;
case 439: // sthux
transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break;
}
break;
case 32: // lwz
transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
case 33: // lwzu
transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
case 34: // lbz
transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
case 35: // lbzu
transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
case 36: // stw
transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
case 37: // stwu
transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
case 38: // stb
transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
case 39: // stbu
transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
case 40: // lhz
transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break;
case 41: // lhzu
transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break;
case 42: // lha
transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break;
case 43: // lhau
transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break;
case 44: // sth
transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break;
case 45: // sthu
transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break;
}
// Calculate effective address
uint32 addr = 0;
switch (addr_mode) {
case MODE_X:
case MODE_UX:
if (ra == 0)
addr = segv_r[rb];
else
addr = segv_r[ra] + segv_r[rb];
break;
case MODE_NORM:
case MODE_U:
if (ra == 0)
addr = (int32)(int16)imm;
else
addr = segv_r[ra] + (int32)(int16)imm;
break;
}
// Ignore ROM writes
if (transfer_type == TYPE_STORE && addr >= (uint32)ROMBaseHost && addr < (uint32)ROMBaseHost + ROMSize) {
// D(bug("WARNING: %s write access to ROM at %p, 68k pc %p\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->pc));
if (addr_mode == MODE_U || addr_mode == MODE_UX)
segv_r[ra] = addr;
r->pc += 4;
goto rti;
}
// For all other errors, jump into debugger
char str[256];
sprintf(str, "SIGSEGV\n"
" pc %08lx lr %08lx ctr %08lx msr %08lx\n"
" xer %08lx cr %08lx fpscr %08lx\n"
" r0 %08lx r1 %08lx r2 %08lx r3 %08lx\n"
" r4 %08lx r5 %08lx r6 %08lx r7 %08lx\n"
" r8 %08lx r9 %08lx r10 %08lx r11 %08lx\n"
" r12 %08lx r13 %08lx r14 %08lx r15 %08lx\n"
" r16 %08lx r17 %08lx r18 %08lx r19 %08lx\n"
" r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n"
" r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n"
" r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n",
r->pc, r->lr, r->ctr, r->msr,
r->xer, r->cr, r->fpscr,
r->r0, r->r1, r->r2, r->r3,
r->r4, r->r5, r->r6, r->r7,
r->r8, r->r9, r->r10, r->r11,
r->r12, segv_r[13], segv_r[14], segv_r[15],
segv_r[16], segv_r[17], segv_r[18], segv_r[19],
segv_r[20], segv_r[21], segv_r[22], segv_r[23],
segv_r[24], segv_r[25], segv_r[26], segv_r[27],
segv_r[28], segv_r[29], segv_r[30], segv_r[31]);
disable_debugger(false);
debugger(str);
QuitEmulator();
return;
rti:
// Restore volatile registers
r->r0 = segv_r[0];
r->r1 = segv_r[1];
r->r2 = segv_r[2];
r->r3 = segv_r[3];
r->r4 = segv_r[4];
r->r5 = segv_r[5];
r->r6 = segv_r[6];
r->r7 = segv_r[7];
r->r8 = segv_r[8];
r->r9 = segv_r[9];
r->r10 = segv_r[10];
r->r11 = segv_r[11];
r->r12 = segv_r[12];
}
#endif

View File

@ -1,106 +0,0 @@
/*
* prefs_beos.cpp - Preferences handling, BeOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <StorageKit.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sysdeps.h"
#include "prefs.h"
#include "main.h"
// Platform-specific preferences items
prefs_desc platform_prefs_items[] = {
{"powerrom", TYPE_STRING, false, "path of PowerMac ROM"},
{NULL, TYPE_END, false, NULL} // End of list
};
// Preferences file name and path
const char PREFS_FILE_NAME[] = "BasiliskII_prefs";
static BPath prefs_path;
/*
* Load preferences from settings file
*/
void LoadPrefs(const char* vmdir)
{
#if 0
if (vmdir) {
prefs_path.SetTo(vmdir);
prefs_path.Append("prefs");
FILE *prefs = fopen(prefs_path.Path(), "r");
if (!prefs) {
printf("No file at %s found.\n", prefs_path.Path());
exit(1);
}
LoadPrefsFromStream(prefs);
fclose(prefs);
return;
}
#endif
// Construct prefs path
find_directory(B_USER_SETTINGS_DIRECTORY, &prefs_path, true);
prefs_path.Append(PREFS_FILE_NAME);
// Read preferences from settings file
FILE *f = fopen(prefs_path.Path(), "r");
if (f != NULL) {
// Prefs file found, load settings
LoadPrefsFromStream(f);
fclose(f);
} else {
// No prefs file, save defaults
SavePrefs();
}
}
/*
* Save preferences to settings file
*/
void SavePrefs(void)
{
FILE *f;
if ((f = fopen(prefs_path.Path(), "w")) != NULL) {
SavePrefsToStream(f);
fclose(f);
}
}
/*
* Add defaults of platform-specific prefs items
* You may also override the defaults set in PrefsInit()
*/
void AddPlatformPrefsDefaults(void)
{
PrefsReplaceString("extfs", "/boot");
}

File diff suppressed because it is too large Load Diff

View File

@ -1,237 +0,0 @@
/*
* scsi_beos.cpp - SCSI Manager, BeOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <device/scsi.h>
#ifdef __HAIKU__
#include <CAM.h>
#else
#include <drivers/CAM.h>
#endif
#include "sysdeps.h"
#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "scsi.h"
#define DEBUG 0
#include "debug.h"
// Global variables
static raw_device_command rdc;
static int fds[8*8]; // fd's for 8 units and 8 LUNs each
static int fd; // Active fd (selected target)
static uint32 buffer_size; // Size of data buffer
static uint8 *buffer = NULL; // Pointer to data buffer
static uint8 sense_data[256]; // Buffer for autosense data
/*
* Initialization
*/
void SCSIInit(void)
{
int id, lun;
// Allocate buffer
buffer = (uint8 *)malloc(buffer_size = 0x10000);
// Open scsi_raw driver for all 8 units (and all 8 LUNs)
char dev_name[256];
for (id=0; id<8; id++) {
for (lun=0; lun<8; lun++)
fds[id*8+lun] = -1;
char prefs_name[16];
sprintf(prefs_name, "scsi%d", id);
const char *str = PrefsFindString(prefs_name);
if (str) {
int bus, unit;
if (sscanf(str, "%d/%d", &bus, &unit) == 2) {
for (lun=0; lun<8; lun++) {
sprintf(dev_name, "/dev/bus/scsi/%d/%d/%d/raw", bus, unit, lun);
D(bug("SCSI %d: Opening %s\n", id, dev_name));
fds[id*8+lun] = open(dev_name, O_RDWR);
}
}
}
}
// Reset SCSI bus
SCSIReset();
// Init rdc
memset(&rdc, 0, sizeof(rdc));
rdc.data = buffer;
rdc.sense_data = sense_data;
}
/*
* Deinitialization
*/
void SCSIExit(void)
{
// Close all devices
for (int i=0; i<8; i++)
for (int j=0; j<8; j++) {
int fd = fds[i*8+j];
if (fd > 0)
close(fd);
}
// Free buffer
if (buffer) {
free(buffer);
buffer = NULL;
}
}
/*
* Check if requested data size fits into buffer, allocate new buffer if needed
*/
static bool try_buffer(int size)
{
if (size <= buffer_size)
return true;
uint8 *new_buffer = (uint8 *)malloc(size);
if (new_buffer == NULL)
return false;
free(buffer);
buffer = new_buffer;
buffer_size = size;
return true;
}
/*
* Set SCSI command to be sent by scsi_send_cmd()
*/
void scsi_set_cmd(int cmd_length, uint8 *cmd)
{
rdc.command_length = cmd_length;
memcpy(rdc.command, cmd, cmd_length);
}
/*
* Check for presence of SCSI target
*/
bool scsi_is_target_present(int id)
{
return fds[id * 8] > 0;
}
/*
* Set SCSI target (returns false on error)
*/
bool scsi_set_target(int id, int lun)
{
int new_fd = fds[id * 8 + lun];
if (new_fd < 0)
return false;
if (new_fd != fd)
rdc.cam_status &= ~CAM_AUTOSNS_VALID; // Clear sense data when selecting new target
fd = new_fd;
return true;
}
/*
* Send SCSI command to active target (scsi_set_command() must have been called),
* read/write data according to S/G table (returns false on error); timeout is in 1/60 sec
*/
bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout)
{
// Check if buffer is large enough, allocate new buffer if needed
if (!try_buffer(data_length)) {
char str[256];
sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length);
ErrorAlert(str);
return false;
}
// Process S/G table when writing
if (!reading) {
D(bug(" writing to buffer\n"));
uint8 *buffer_ptr = buffer;
for (int i=0; i<sg_size; i++) {
uint32 len = sg_len[i];
D(bug(" %d bytes from %08lx\n", len, sg_ptr[i]));
memcpy(buffer_ptr, sg_ptr[i], len);
buffer_ptr += len;
}
}
// Request Sense and autosense data valid?
status_t res = B_NO_ERROR;
if (rdc.command[0] == 0x03 && (rdc.cam_status & CAM_AUTOSNS_VALID)) {
// Yes, fake command
D(bug(" autosense\n"));
memcpy(buffer, sense_data, 256 - rdc.sense_data_length);
rdc.scsi_status = 0;
rdc.cam_status = CAM_REQ_CMP;
} else {
// No, send regular command
D(bug(" sending command, length %d\n", data_length));
rdc.flags = (reading ? B_RAW_DEVICE_DATA_IN : 0) | B_RAW_DEVICE_REPORT_RESIDUAL | B_RAW_DEVICE_SHORT_READ_VALID;
rdc.data_length = data_length;
rdc.sense_data_length = 256;
rdc.scsi_status = 0;
rdc.cam_status = CAM_REQ_CMP;
rdc.timeout = timeout * 16667;
res = ioctl(fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc));
D(bug(" command sent, res %08x, status %d, cam_status %02x\n", res, rdc.scsi_status, rdc.cam_status));
*stat = rdc.scsi_status;
}
// Process S/G table when reading
if (reading && rdc.cam_status == CAM_REQ_CMP) {
D(bug(" reading from buffer\n"));
uint8 *buffer_ptr = buffer;
for (int i=0; i<sg_size; i++) {
uint32 len = sg_len[i];
D(bug(" %d bytes to %08lx\n", len, sg_ptr[i]));
memcpy(sg_ptr[i], buffer_ptr, len);
buffer_ptr += len;
}
}
return res ? false : true;
}

View File

@ -1,873 +0,0 @@
/*
* serial_beos.cpp - Serial device driver, BeOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <DeviceKit.h>
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"
#include "prefs.h"
#include "serial.h"
#include "serial_defs.h"
#define DEBUG 0
#include "debug.h"
#define MONITOR 0
// Buffer size for kernel-space transfers
const int TMP_BUF_SIZE = 2048;
// These packets are sent to the input/output threads
const uint32 CMD_READ = 'read';
const uint32 CMD_WRITE = 'writ';
const uint32 CMD_QUIT = 'quit';
struct ThreadPacket {
uint32 pb;
};
// Driver private variables
class BeSERDPort : public SERDPort {
public:
BeSERDPort(const char *dev)
{
device_name = dev;
if (strstr(dev, "parallel")) {
is_parallel = true;
fd = -1;
device = NULL;
} else {
is_parallel = false;
device = new BSerialPort;
}
device_sem = create_sem(1, "serial port");
input_thread = output_thread = 0;
}
virtual ~BeSERDPort()
{
status_t l;
if (input_thread > 0) {
send_data(input_thread, CMD_QUIT, NULL, 0);
suspend_thread(input_thread); // Unblock thread
snooze(1000);
resume_thread(input_thread);
while (wait_for_thread(input_thread, &l) == B_INTERRUPTED) ;
}
if (output_thread > 0) {
send_data(output_thread, CMD_QUIT, NULL, 0);
suspend_thread(output_thread); // Unblock thread
snooze(1000);
resume_thread(output_thread);
while (wait_for_thread(output_thread, &l) == B_INTERRUPTED) ;
}
acquire_sem(device_sem);
delete_sem(device_sem);
delete device;
}
virtual int16 open(uint16 config);
virtual int16 prime_in(uint32 pb, uint32 dce);
virtual int16 prime_out(uint32 pb, uint32 dce);
virtual int16 control(uint32 pb, uint32 dce, uint16 code);
virtual int16 status(uint32 pb, uint32 dce, uint16 code);
virtual int16 close(void);
private:
bool configure(uint16 config);
void set_handshake(uint32 s, bool with_dtr);
static status_t input_func(void *arg);
static status_t output_func(void *arg);
const char *device_name; // Name of BeOS port
BSerialPort *device; // BeOS port object
bool is_parallel; // Flag: Port is parallel, use fd
int fd; // FD for parallel ports
sem_id device_sem; // BSerialPort arbitration
thread_id input_thread; // Data input thread
thread_id output_thread; // Data output thread
bool io_killed; // Flag: KillIO called, I/O threads must not call deferred tasks
bool drop_dtr_on_close; // Flag: Negate DTR when driver is closed
uint8 tmp_in_buf[TMP_BUF_SIZE]; // Buffers for copying from/to kernel space
uint8 tmp_out_buf[TMP_BUF_SIZE];
};
#if DEBUG
static const int baud_rates[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 31250
};
#endif
/*
* Initialization
*/
void SerialInit(void)
{
// Read serial preferences and create structs for both ports
the_serd_port[0] = new BeSERDPort(PrefsFindString("seriala"));
the_serd_port[1] = new BeSERDPort(PrefsFindString("serialb"));
}
/*
* Deinitialization
*/
void SerialExit(void)
{
delete (BeSERDPort *)the_serd_port[0];
delete (BeSERDPort *)the_serd_port[1];
}
/*
* Open serial port
*/
int16 BeSERDPort::open(uint16 config)
{
// Don't open NULL name devices
if (device_name == NULL)
return openErr;
// Init variables
io_killed = false;
drop_dtr_on_close = true;
// Open port
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
if (is_parallel) {
char name[256];
sprintf(name, "/dev/parallel/%s", device_name);
fd = ::open(name, O_WRONLY);
if (fd < 0) {
release_sem(device_sem);
return openErr;
}
} else {
device->SetFlowControl(B_HARDWARE_CONTROL); // Must be set before port is opened
if (device->Open(device_name) > 0) {
device->SetBlocking(true);
device->SetTimeout(10000000);
device->SetDTR(true);
device->SetRTS(true);
} else {
release_sem(device_sem);
return openErr;
}
}
// Start input/output threads
release_sem(device_sem);
configure(config);
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
while ((input_thread = spawn_thread(input_func, "Serial Input", B_NORMAL_PRIORITY, this)) == B_INTERRUPTED) ;
resume_thread(input_thread);
while ((output_thread = spawn_thread(output_func, "Serial Output", B_NORMAL_PRIORITY, this)) == B_INTERRUPTED) ;
resume_thread(output_thread);
release_sem(device_sem);
return noErr;
}
/*
* Read data from port
*/
int16 BeSERDPort::prime_in(uint32 pb, uint32 dce)
{
// Send input command to input_thread
read_done = false;
read_pending = true;
ThreadPacket p;
p.pb = pb;
WriteMacInt32(input_dt + serdtDCE, dce);
while (send_data(input_thread, CMD_READ, &p, sizeof(ThreadPacket)) == B_INTERRUPTED) ;
return 1; // Command in progress
}
/*
* Write data to port
*/
int16 BeSERDPort::prime_out(uint32 pb, uint32 dce)
{
// Send output command to output_thread
write_done = false;
write_pending = true;
ThreadPacket p;
p.pb = pb;
WriteMacInt32(output_dt + serdtDCE, dce);
while (send_data(output_thread, CMD_WRITE, &p, sizeof(ThreadPacket)) == B_INTERRUPTED) ;
return 1; // Command in progress
}
/*
* Control calls
*/
int16 BeSERDPort::control(uint32 pb, uint32 dce, uint16 code)
{
switch (code) {
case 1: // KillIO
io_killed = true;
suspend_thread(input_thread); // Unblock threads
suspend_thread(output_thread);
snooze(1000);
resume_thread(input_thread);
resume_thread(output_thread);
while (read_pending || write_pending)
snooze(10000);
if (!is_parallel) {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
device->ClearInput();
device->ClearOutput();
release_sem(device_sem);
}
io_killed = false;
return noErr;
case kSERDConfiguration:
if (configure(ReadMacInt16(pb + csParam)))
return noErr;
else
return paramErr;
case kSERDInputBuffer:
return noErr; // Not supported under BeOS
case kSERDSerHShake:
set_handshake(pb + csParam, false);
return noErr;
case kSERDClearBreak:
case kSERDSetBreak:
return noErr; // Not supported under BeOS
case kSERDBaudRate:
if (!is_parallel) {
uint16 rate = ReadMacInt16(pb + csParam);
data_rate baud_rate;
if (rate <= 50) {
rate = 50; baud_rate = B_50_BPS;
} else if (rate <= 75) {
rate = 75; baud_rate = B_75_BPS;
} else if (rate <= 110) {
rate = 110; baud_rate = B_110_BPS;
} else if (rate <= 134) {
rate = 134; baud_rate = B_134_BPS;
} else if (rate <= 150) {
rate = 150; baud_rate = B_150_BPS;
} else if (rate <= 200) {
rate = 200; baud_rate = B_200_BPS;
} else if (rate <= 300) {
rate = 300; baud_rate = B_300_BPS;
} else if (rate <= 600) {
rate = 600; baud_rate = B_600_BPS;
} else if (rate <= 1200) {
rate = 1200; baud_rate = B_1200_BPS;
} else if (rate <= 1800) {
rate = 1800; baud_rate = B_1800_BPS;
} else if (rate <= 2400) {
rate = 2400; baud_rate = B_2400_BPS;
} else if (rate <= 4800) {
rate = 4800; baud_rate = B_4800_BPS;
} else if (rate <= 9600) {
rate = 9600; baud_rate = B_9600_BPS;
} else if (rate <= 19200) {
rate = 19200; baud_rate = B_19200_BPS;
} else if (rate <= 31250) {
rate = 31250; baud_rate = B_31250_BPS;
} else if (rate <= 38400) {
rate = 38400; baud_rate = B_38400_BPS;
} else if (rate <= 57600) {
rate = 57600; baud_rate = B_57600_BPS;
}
WriteMacInt16(pb + csParam, rate);
acquire_sem(device_sem);
if (device->SetDataRate(baud_rate) == B_OK) {
release_sem(device_sem);
return noErr;
} else {
release_sem(device_sem);
return paramErr;
}
} else
return noErr;
case kSERDHandshake:
case kSERDHandshakeRS232:
set_handshake(pb + csParam, true);
return noErr;
case kSERDClockMIDI:
if (!is_parallel) {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
device->SetParityMode(B_NO_PARITY);
device->SetDataBits(B_DATA_BITS_8);
device->SetStopBits(B_STOP_BITS_1);
if (device->SetDataRate(B_31250_BPS) == B_OK) {
release_sem(device_sem);
return noErr;
} else {
release_sem(device_sem);
return paramErr;
}
} else
return noErr;
case kSERDMiscOptions:
drop_dtr_on_close = !(ReadMacInt8(pb + csParam) & kOptionPreserveDTR);
return noErr;
case kSERDAssertDTR:
if (!is_parallel) {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
device->SetDTR(true);
release_sem(device_sem);
}
return noErr;
case kSERDNegateDTR:
if (!is_parallel) {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
device->SetDTR(false);
release_sem(device_sem);
}
return noErr;
case kSERDSetPEChar:
case kSERDSetPEAltChar:
return noErr; // Not supported under BeOS
case kSERDResetChannel:
if (!is_parallel) {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
device->ClearInput();
device->ClearOutput();
release_sem(device_sem);
}
return noErr;
case kSERDAssertRTS:
if (!is_parallel) {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
device->SetRTS(true);
release_sem(device_sem);
}
return noErr;
case kSERDNegateRTS:
if (!is_parallel) {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
device->SetRTS(false);
release_sem(device_sem);
}
return noErr;
case kSERD115KBaud:
if (!is_parallel) {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
if (device->DataRate() != B_115200_BPS)
if (device->SetDataRate(B_115200_BPS) != B_OK) {
release_sem(device_sem);
return paramErr;
}
release_sem(device_sem);
}
return noErr;
case kSERD230KBaud:
case kSERDSetHighSpeed:
if (!is_parallel) {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
if (device->DataRate() != B_230400_BPS)
if (device->SetDataRate(B_230400_BPS) != B_OK) {
release_sem(device_sem);
return paramErr;
}
release_sem(device_sem);
}
return noErr;
default:
printf("WARNING: SerialControl(): unimplemented control code %d\n", code);
return controlErr;
}
}
/*
* Status calls
*/
int16 BeSERDPort::status(uint32 pb, uint32 dce, uint16 code)
{
switch (code) {
case kSERDInputCount:
WriteMacInt32(pb + csParam, 0);
if (!is_parallel) {
int32 num = 0;
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
device->NumCharsAvailable(&num);
release_sem(device_sem);
D(bug(" %d bytes in buffer\n", num));
WriteMacInt32(pb + csParam, num);
}
return noErr;
case kSERDStatus: {
uint32 p = pb + csParam;
WriteMacInt8(p + staCumErrs, cum_errors);
cum_errors = 0;
WriteMacInt8(p + staXOffSent, 0);
WriteMacInt8(p + staXOffHold, 0);
WriteMacInt8(p + staRdPend, read_pending);
WriteMacInt8(p + staWrPend, write_pending);
if (is_parallel) {
WriteMacInt8(p + staCtsHold, 0);
WriteMacInt8(p + staDsrHold, 0);
WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent);
} else {
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
WriteMacInt8(p + staCtsHold, !device->IsCTS());
WriteMacInt8(p + staDsrHold, !device->IsDSR());
WriteMacInt8(p + staModemStatus,
(device->IsDSR() ? dsrEvent : 0)
| (device->IsRI() ? riEvent : 0)
| (device->IsDCD() ? dcdEvent : 0)
| (device->IsCTS() ? ctsEvent : 0));
release_sem(device_sem);
}
return noErr;
}
default:
printf("WARNING: SerialStatus(): unimplemented status code %d\n", code);
return statusErr;
}
}
/*
* Close serial port
*/
int16 BeSERDPort::close()
{
// Kill threads
status_t l;
io_killed = true;
if (input_thread > 0) {
while (send_data(input_thread, CMD_QUIT, NULL, 0) == B_INTERRUPTED) ;
if (read_pending) {
suspend_thread(input_thread); // Unblock thread
snooze(1000);
resume_thread(input_thread);
}
while (wait_for_thread(input_thread, &l) == B_INTERRUPTED) ;
}
if (output_thread > 0) {
while (send_data(output_thread, CMD_QUIT, NULL, 0) == B_INTERRUPTED) ;
if (write_pending) {
suspend_thread(output_thread); // Unblock thread
snooze(1000);
resume_thread(output_thread);
}
while (wait_for_thread(output_thread, &l) == B_INTERRUPTED) ;
}
input_thread = output_thread = 0;
// Close port
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
if (is_parallel) {
::close(fd);
fd = -1;
} else {
if (drop_dtr_on_close)
device->SetDTR(false);
device->Close();
}
release_sem(device_sem);
return noErr;
}
/*
* Configure serial port with MacOS config word
*/
bool BeSERDPort::configure(uint16 config)
{
D(bug(" configure %04x\n", config));
if (is_parallel)
return true;
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
// Set number of stop bits
switch (config & 0xc000) {
case stop10:
if (device->StopBits() != B_STOP_BITS_1)
device->SetStopBits(B_STOP_BITS_1);
break;
case stop20:
if (device->StopBits() != B_STOP_BITS_2)
device->SetStopBits(B_STOP_BITS_2);
break;
default:
release_sem(device_sem);
return false;
}
// Set parity mode
switch (config & 0x3000) {
case noParity:
if (device->ParityMode() != B_NO_PARITY)
device->SetParityMode(B_NO_PARITY);
break;
case oddParity:
if (device->ParityMode() != B_ODD_PARITY)
device->SetParityMode(B_ODD_PARITY);
break;
case evenParity:
if (device->ParityMode() != B_EVEN_PARITY)
device->SetParityMode(B_EVEN_PARITY);
break;
default:
release_sem(device_sem);
return false;
}
// Set number of data bits
switch (config & 0x0c00) {
case data7:
if (device->DataBits() != B_DATA_BITS_7)
device->SetDataBits(B_DATA_BITS_7);
break;
case data8:
if (device->DataBits() != B_DATA_BITS_8)
device->SetDataBits(B_DATA_BITS_8);
break;
default:
release_sem(device_sem);
return false;
}
// Set baud rate
data_rate baud_rate;
switch (config & 0x03ff) {
case baud150: baud_rate = B_150_BPS; break;
case baud300: baud_rate = B_300_BPS; break;
case baud600: baud_rate = B_600_BPS; break;
case baud1200: baud_rate = B_1200_BPS; break;
case baud1800: baud_rate = B_1800_BPS; break;
case baud2400: baud_rate = B_2400_BPS; break;
case baud4800: baud_rate = B_4800_BPS; break;
case baud9600: baud_rate = B_9600_BPS; break;
case baud19200: baud_rate = B_19200_BPS; break;
case baud38400: baud_rate = B_38400_BPS; break;
case baud57600: baud_rate = B_57600_BPS; break;
default:
release_sem(device_sem);
return false;
}
D(bug(" baud rate %d, %d stop bits, %s parity, %d data bits\n", baud_rates[baud_rate], device->StopBits() == B_STOP_BITS_1 ? 1 : 2, device->ParityMode() == B_NO_PARITY ? "no" : device->ParityMode() == B_ODD_PARITY ? "odd" : "even", device->DataBits() == B_DATA_BITS_7 ? 7 : 8));
if (device->DataRate() != baud_rate) {
bool res = device->SetDataRate(baud_rate) == B_OK;
release_sem(device_sem);
return res;
} else {
release_sem(device_sem);
return true;
}
}
/*
* Set serial handshaking
*/
void BeSERDPort::set_handshake(uint32 s, bool with_dtr)
{
D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n",
ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3),
ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7)));
if (is_parallel)
return;
uint32 flow;
if (with_dtr) {
if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR))
flow = B_HARDWARE_CONTROL;
else
flow = B_SOFTWARE_CONTROL;
} else {
if (ReadMacInt8(s + shkFCTS))
flow = B_HARDWARE_CONTROL;
else
flow = B_SOFTWARE_CONTROL;
}
D(bug(" %sware flow control\n", flow == B_HARDWARE_CONTROL ? "hard" : "soft"));
while (acquire_sem(device_sem) == B_INTERRUPTED) ;
if (device->FlowControl() != flow) {
device->Close();
device->SetFlowControl(flow);
device->Open(device_name);
}
release_sem(device_sem);
}
/*
* Data input thread
*/
status_t BeSERDPort::input_func(void *arg)
{
BeSERDPort *s = (BeSERDPort *)arg;
for (;;) {
// Wait for commands
thread_id sender;
ThreadPacket p;
uint32 code = receive_data(&sender, &p, sizeof(ThreadPacket));
if (code == CMD_QUIT)
break;
if (code != CMD_READ)
continue;
// Execute command
void *buf = Mac2HostAddr(ReadMacInt32(p.pb + ioBuffer));
uint32 length = ReadMacInt32(p.pb + ioReqCount);
D(bug("input_func waiting for %ld bytes of data...\n", length));
int32 actual;
// Buffer in kernel space?
if ((uint32)buf < 0x80000000) {
// Yes, transfer via buffer
actual = 0;
while (length) {
uint32 transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length;
int32 transferred;
acquire_sem(s->device_sem);
if (s->is_parallel) {
if ((transferred = read(s->fd, s->tmp_in_buf, transfer_size)) < 0 || s->io_killed) {
// Error
actual = transferred;
release_sem(s->device_sem);
break;
}
} else {
if ((transferred = s->device->Read(s->tmp_in_buf, transfer_size)) < 0 || s->io_killed) {
// Error
actual = transferred;
release_sem(s->device_sem);
break;
}
}
release_sem(s->device_sem);
memcpy(buf, s->tmp_in_buf, transferred);
buf = (void *)((uint8 *)buf + transferred);
length -= transferred;
actual += transferred;
}
} else {
// No, transfer directly
acquire_sem(s->device_sem);
if (s->is_parallel)
actual = read(s->fd, buf, length);
else
actual = s->device->Read(buf, length);
release_sem(s->device_sem);
}
D(bug(" %ld bytes received\n", actual));
#if MONITOR
bug("Receiving serial data:\n");
uint8 *adr = Mac2HostAddr(ReadMacInt32(p.pb + ioBuffer));
for (int i=0; i<actual; i++) {
bug("%02x ", adr[i]);
}
bug("\n");
#endif
// KillIO called? Then simply return
if (s->io_killed) {
WriteMacInt16(p.pb + ioResult, abortErr);
WriteMacInt32(p.pb + ioActCount, 0);
s->read_pending = s->read_done = false;
} else {
// Set error code
if (actual >= 0) {
WriteMacInt32(p.pb + ioActCount, actual);
WriteMacInt32(s->input_dt + serdtResult, noErr);
} else {
WriteMacInt32(p.pb + ioActCount, 0);
WriteMacInt32(s->input_dt + serdtResult, readErr);
}
// Trigger serial interrupt
D(bug(" triggering serial interrupt\n"));
s->read_done = true;
SetInterruptFlag(INTFLAG_SERIAL);
TriggerInterrupt();
}
}
return 0;
}
/*
* Data output thread
*/
status_t BeSERDPort::output_func(void *arg)
{
BeSERDPort *s = (BeSERDPort *)arg;
for (;;) {
// Wait for commands
thread_id sender;
ThreadPacket p;
uint32 code = receive_data(&sender, &p, sizeof(ThreadPacket));
if (code == CMD_QUIT)
break;
if (code != CMD_WRITE)
continue;
// Execute command
void *buf = Mac2HostAddr(ReadMacInt32(p.pb + ioBuffer));
uint32 length = ReadMacInt32(p.pb + ioReqCount);
D(bug("output_func transmitting %ld bytes of data...\n", length));
int32 actual;
#if MONITOR
bug("Sending serial data:\n");
uint8 *adr = (uint8 *)buf;
for (int i=0; i<length; i++) {
bug("%02x ", adr[i]);
}
bug("\n");
#endif
// Buffer in kernel space?
if ((uint32)buf < 0x80000000) {
// Yes, transfer via buffer
actual = 0;
while (length) {
uint32 transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length;
memcpy(s->tmp_out_buf, buf, transfer_size);
int32 transferred;
acquire_sem(s->device_sem);
if (s->is_parallel) {
if ((transferred = write(s->fd, s->tmp_out_buf, transfer_size)) < transfer_size || s->io_killed) {
if (transferred < 0) // Error
actual = transferred;
else
actual += transferred;
release_sem(s->device_sem);
break;
}
} else {
if ((transferred = s->device->Write(s->tmp_out_buf, transfer_size)) < transfer_size || s->io_killed) {
if (transferred < 0) // Error
actual = transferred;
else
actual += transferred;
release_sem(s->device_sem);
break;
}
}
release_sem(s->device_sem);
if (transferred > transfer_size) // R3 parallel port driver bug
transferred = transfer_size;
buf = (void *)((uint8 *)buf + transferred);
length -= transferred;
actual += transferred;
}
} else {
// No, transfer directly
acquire_sem(s->device_sem);
if (s->is_parallel)
actual = write(s->fd, buf, length);
else
actual = s->device->Write(buf, length);
release_sem(s->device_sem);
if (actual > length) // R3 parallel port driver bug
actual = length;
}
D(bug(" %ld bytes transmitted\n", actual));
// KillIO called? Then simply return
if (s->io_killed) {
WriteMacInt16(p.pb + ioResult, abortErr);
WriteMacInt32(p.pb + ioActCount, 0);
s->write_pending = s->write_done = false;
} else {
// Set error code
if (actual >= 0) {
WriteMacInt32(p.pb + ioActCount, actual);
WriteMacInt32(s->output_dt + serdtResult, noErr);
} else {
WriteMacInt32(p.pb + ioActCount, 0);
WriteMacInt32(s->output_dt + serdtResult, writErr);
}
// Trigger serial interrupt
D(bug(" triggering serial interrupt\n"));
s->write_done = true;
SetInterruptFlag(INTFLAG_SERIAL);
TriggerInterrupt();
}
}
return 0;
}

View File

@ -1,841 +0,0 @@
/*
* sys_beos.cpp - System dependent routines, BeOS implementation
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <StorageKit.h>
#include <InterfaceKit.h>
#include <kernel/fs_info.h>
#include <drivers/Drivers.h>
#include <device/scsi.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "sysdeps.h"
#include "main.h"
#include "macos_util.h"
#include "prefs.h"
#include "user_strings.h"
#include "sys.h"
#define DEBUG 0
#include "debug.h"
#ifdef __HAIKU__
#include <fs_volume.h>
#define unmount(x) fs_unmount_volume(x, 0)
#endif
// File handles are pointers to these structures
struct file_handle {
file_handle *next; // Pointer to next file handle (must be first in struct!)
const char *name; // File/device name (copied, for mount menu)
int fd; // fd of file/device
bool is_file; // Flag: plain file or /dev/something?
bool read_only; // Copy of Sys_open() flag
loff_t start_byte; // Size of file header (if any)
loff_t file_size; // Size of file data (only valid if is_file is true)
};
// Linked list of file handles
static file_handle *first_file_handle;
// Temporary buffer for transfers from/to kernel space
const int TMP_BUF_SIZE = 0x10000;
static uint8 *tmp_buf;
// For B_SCSI_PREVENT_ALLOW
static const int32 PREVENT = 1;
static const int32 ALLOW = 0;
/*
* Check if device is a mounted HFS volume, get mount name
*/
static bool is_drive_mounted(const char *dev_name, char *mount_name)
{
int32 i = 0;
dev_t d;
fs_info info;
while ((d = next_dev(&i)) >= 0) {
fs_stat_dev(d, &info);
if (strcmp(dev_name, info.device_name) == 0) {
status_t err = -1;
BPath mount;
BDirectory dir;
BEntry entry;
node_ref node;
node.device = info.dev;
node.node = info.root;
err = dir.SetTo(&node);
if (!err)
err = dir.GetEntry(&entry);
if (!err)
err = entry.GetPath(&mount);
if (!err) {
strcpy(mount_name, mount.Path());
return true;
}
}
}
return false;
}
/*
* Initialization
*/
void SysInit(void)
{
first_file_handle = NULL;
// Allocate temporary buffer
tmp_buf = new uint8[TMP_BUF_SIZE];
}
/*
* Deinitialization
*/
void SysExit(void)
{
delete[] tmp_buf;
}
/*
* Create menu of used volumes (for "mount" menu)
*/
void SysCreateVolumeMenu(BMenu *menu, uint32 msg)
{
for (file_handle *fh=first_file_handle; fh; fh=fh->next)
if (!SysIsFixedDisk(fh))
menu->AddItem(new BMenuItem(fh->name, new BMessage(msg)));
}
/*
* Mount volume given name from mount menu
*/
void SysMountVolume(const char *name)
{
file_handle *fh;
for (fh=first_file_handle; fh && strcmp(fh->name, name); fh=fh->next) ;
if (fh)
MountVolume(fh);
}
/*
* This gets called when no "floppy" prefs items are found
* It scans for available floppy drives and adds appropriate prefs items
*/
void SysAddFloppyPrefs(void)
{
// Only one floppy drive under BeOS
PrefsAddString("floppy", "/dev/disk/floppy/raw");
}
/*
* This gets called when no "disk" prefs items are found
* It scans for available HFS volumes and adds appropriate prefs items
*/
void SysAddDiskPrefs(void)
{
// Let BeOS scan for HFS drives
D(bug("Looking for Mac volumes...\n"));
system("mountvolume -allhfs");
// Add all HFS volumes
int32 i = 0;
dev_t d;
fs_info info;
while ((d = next_dev(&i)) >= 0) {
fs_stat_dev(d, &info);
status_t err = -1;
BPath mount;
if (!strcmp(info.fsh_name, "hfs")) {
BDirectory dir;
BEntry entry;
node_ref node;
node.device = info.dev;
node.node = info.root;
err = dir.SetTo(&node);
if (!err)
err = dir.GetEntry(&entry);
if (!err)
err = entry.GetPath(&mount);
}
if (!err)
err = unmount(mount.Path());
if (!err) {
char dev_name[B_FILE_NAME_LENGTH];
if (info.flags & B_FS_IS_READONLY) {
dev_name[0] = '*';
dev_name[1] = 0;
} else
dev_name[0] = 0;
strcat(dev_name, info.device_name);
PrefsAddString("disk", dev_name);
}
}
}
/*
* This gets called when no "cdrom" prefs items are found
* It scans for available CD-ROM drives and adds appropriate prefs items
*/
// Scan directory for CD-ROM drives, add them to prefs
static void scan_for_cdrom_drives(const char *directory)
{
// Set directory
BDirectory dir;
dir.SetTo(directory);
if (dir.InitCheck() != B_NO_ERROR)
return;
dir.Rewind();
// Scan each entry
BEntry entry;
while (dir.GetNextEntry(&entry) >= 0) {
// Get path and ref for entry
BPath path;
if (entry.GetPath(&path) != B_NO_ERROR)
continue;
const char *name = path.Path();
entry_ref e;
if (entry.GetRef(&e) != B_NO_ERROR)
continue;
// Recursively enter subdirectories (except for floppy)
if (entry.IsDirectory()) {
if (!strcmp(e.name, "floppy"))
continue;
scan_for_cdrom_drives(name);
} else {
D(bug(" checking '%s'\n", name));
// Ignore partitions
if (strcmp(e.name, "raw"))
continue;
// Open device
int fd = open(name, O_RDONLY);
if (fd < 0)
continue;
// Get geometry and device type
device_geometry g;
if (ioctl(fd, B_GET_GEOMETRY, &g, sizeof(g)) < 0) {
close(fd);
continue;
}
// Insert to list if it is a CD drive
if (g.device_type == B_CD)
PrefsAddString("cdrom", name);
close(fd);
}
}
}
void SysAddCDROMPrefs(void)
{
// Don't scan for drives if nocdrom option given
if (PrefsFindBool("nocdrom"))
return;
// Look for CD-ROM drives and add prefs items
D(bug("Looking for CD-ROM drives...\n"));
scan_for_cdrom_drives("/dev/disk");
}
/*
* Add default serial prefs (must be added, even if no ports present)
*/
void SysAddSerialPrefs(void)
{
#ifdef __HAIKU__
PrefsAddString("seriala", "serial1");
PrefsAddString("serialb", "serial2");
#else
system_info info;
get_system_info(&info);
switch (info.platform_type) {
case B_BEBOX_PLATFORM:
case B_AT_CLONE_PLATFORM:
PrefsAddString("seriala", "serial1");
PrefsAddString("serialb", "serial2");
break;
case B_MAC_PLATFORM:
PrefsAddString("seriala", "modem");
PrefsAddString("serialb", "printer");
break;
default:
PrefsAddString("seriala", "none");
PrefsAddString("serialb", "none");
break;
}
#endif
}
/*
* Open file/device, create new file handle (returns NULL on error)
*/
void *Sys_open(const char *name, bool read_only)
{
static bool published_all = false;
bool is_file = (strstr(name, "/dev/") != name);
D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write"));
// Print warning message and eventually unmount drive when this is an HFS volume mounted under BeOS (double mounting will corrupt the volume)
char mount_name[B_FILE_NAME_LENGTH];
if (!is_file && !read_only && is_drive_mounted(name, mount_name)) {
char str[256 + B_FILE_NAME_LENGTH];
sprintf(str, GetString(STR_VOLUME_IS_MOUNTED_WARN), mount_name);
WarningAlert(str);
if (unmount(mount_name) != 0) {
sprintf(str, GetString(STR_CANNOT_UNMOUNT_WARN), mount_name);
WarningAlert(str);
return NULL;
}
}
int fd = open(name, read_only ? O_RDONLY : O_RDWR);
if (fd < 0 && !published_all) {
// Open failed, create all device nodes and try again, but only the first time
system("mountvolume -publishall");
published_all = true;
fd = open(name, read_only ? O_RDONLY : O_RDWR);
}
if (fd >= 0) {
file_handle *fh = new file_handle;
fh->name = strdup(name);
fh->fd = fd;
fh->is_file = is_file;
fh->read_only = read_only;
fh->start_byte = 0;
if (fh->is_file) {
// Detect disk image file layout
loff_t size = lseek(fd, 0, SEEK_END);
uint8 data[256];
lseek(fd, 0, SEEK_SET);
read(fd, data, 256);
FileDiskLayout(size, data, fh->start_byte, fh->file_size);
}
// Enqueue file handle
fh->next = NULL;
file_handle *q = first_file_handle;
if (q) {
while (q->next)
q = q->next;
q->next = fh;
} else
first_file_handle = fh;
return fh;
} else
return NULL;
}
/*
* Close file/device, delete file handle
*/
void Sys_close(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return;
// Free device name and close file/device
free((void *)fh->name);
close(fh->fd);
// Dequeue file handle
file_handle *q = first_file_handle;
if (q == fh) {
first_file_handle = NULL;
delete fh;
return;
}
while (q) {
if (q->next == fh) {
q->next = fh->next;
delete fh;
return;
}
q = q->next;
}
}
/*
* Read "length" bytes from file/device, starting at "offset", to "buffer",
* returns number of bytes read (or 0)
*/
static inline ssize_t sread(int fd, void *buf, size_t count)
{
ssize_t res;
while ((res = read(fd, buf, count)) == B_INTERRUPTED) ;
return res;
}
size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return 0;
// D(bug("Sys_read(%08lx, %08lx, %Ld, %d)\n", fh, buffer, offset, length));
// Seek to position
if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0)
return 0;
// Buffer in kernel space?
size_t actual = 0;
if ((uint32)buffer < 0x80000000) {
// Yes, transfer via buffer
while (length) {
size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length;
if (sread(fh->fd, tmp_buf, transfer_size) != transfer_size)
return actual;
memcpy(buffer, tmp_buf, transfer_size);
buffer = (void *)((uint8 *)buffer + transfer_size);
length -= transfer_size;
actual += transfer_size;
}
} else {
// No, transfer directly
actual = sread(fh->fd, buffer, length);
if (actual < 0)
actual = 0;
}
return actual;
}
/*
* Write "length" bytes from "buffer" to file/device, starting at "offset",
* returns number of bytes written (or 0)
*/
static inline ssize_t swrite(int fd, void *buf, size_t count)
{
ssize_t res;
while ((res = write(fd, buf, count)) == B_INTERRUPTED) ;
return res;
}
size_t Sys_write(void *arg, void *buffer, loff_t offset, size_t length)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return 0;
// D(bug("Sys_write(%08lx, %08lx, %Ld, %d)\n", fh, buffer, offset, length));
// Seek to position
if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0)
return 0;
// Buffer in kernel space?
size_t actual = 0;
if ((uint32)buffer < 0x80000000) {
// Yes, transfer via buffer
while (length) {
size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length;
memcpy(tmp_buf, buffer, transfer_size);
if (swrite(fh->fd, tmp_buf, transfer_size) != transfer_size)
return actual;
buffer = (void *)((uint8 *)buffer + transfer_size);
length -= transfer_size;
actual += transfer_size;
}
} else {
// No, transfer directly
actual = swrite(fh->fd, buffer, length);
if (actual < 0)
actual = 0;
}
return actual;
}
/*
* Return size of file/device (minus header)
*/
loff_t SysGetFileSize(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return true;
if (fh->is_file)
return fh->file_size;
else {
device_geometry g;
if (ioctl(fh->fd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0)
return (loff_t)g.bytes_per_sector * g.sectors_per_track * g.cylinder_count * g.head_count;
else
return 0;
}
}
/*
* Eject volume (if applicable)
*/
void SysEject(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return;
if (!fh->is_file)
ioctl(fh->fd, B_EJECT_DEVICE);
}
/*
* Format volume (if applicable)
*/
bool SysFormat(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return false;
if (!fh->is_file)
return ioctl(fh->fd, B_FORMAT_DEVICE) >= 0;
else
return false;
}
/*
* Check if file/device is read-only (this includes the read-only flag on Sys_open())
*/
bool SysIsReadOnly(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return true;
if (fh->is_file) {
// File, return flag given to Sys_open
return fh->read_only;
} else {
// Device, check write protection
device_geometry g;
if (ioctl(fh->fd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0)
return g.read_only | fh->read_only;
else
return fh->read_only; // Removable but not inserted
}
}
/*
* Check if the given file handle refers to a fixed or a removable disk
*/
bool SysIsFixedDisk(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return true;
if (fh->is_file)
return true;
else {
device_geometry g;
if (ioctl(fh->fd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0)
return !g.removable;
else
return false; // Removable but not inserted
}
}
/*
* Check if a disk is inserted in the drive (always true for files)
*/
bool SysIsDiskInserted(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return false;
if (fh->is_file)
return true;
else {
status_t l;
if (ioctl(fh->fd, B_GET_MEDIA_STATUS, &l, sizeof(l)) >= 0 && l == B_NO_ERROR)
return true;
else
return false;
}
}
/*
* Prevent medium removal (if applicable)
*/
void SysPreventRemoval(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return;
if (!fh->is_file)
ioctl(fh->fd, B_SCSI_PREVENT_ALLOW, &PREVENT, sizeof(PREVENT));
}
/*
* Allow medium removal (if applicable)
*/
void SysAllowRemoval(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return;
if (!fh->is_file)
ioctl(fh->fd, B_SCSI_PREVENT_ALLOW, &ALLOW, sizeof(ALLOW));
}
/*
* Read CD-ROM TOC (binary MSF format, 804 bytes max.)
*/
bool SysCDReadTOC(void *arg, uint8 *toc)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return false;
if (!fh->is_file) {
memset(tmp_buf, 0, 804);
if (ioctl(fh->fd, B_SCSI_GET_TOC, tmp_buf, 804) < 0)
return false;
memcpy(toc, tmp_buf, 804);
return true;
} else
return false;
}
/*
* Read CD-ROM position data (Sub-Q Channel, 16 bytes, see SCSI standard)
*/
bool SysCDGetPosition(void *arg, uint8 *pos)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return false;
if (!fh->is_file) {
if (ioctl(fh->fd, B_SCSI_GET_POSITION, tmp_buf, 16) < 0)
return false;
memcpy(pos, tmp_buf, 16);
return true;
} else
return false;
}
/*
* Play CD audio
*/
bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return false;
if (!fh->is_file) {
scsi_play_position *p = (scsi_play_position *)tmp_buf;
p->start_m = start_m;
p->start_s = start_s;
p->start_f = start_f;
p->end_m = end_m;
p->end_s = end_s;
p->end_f = end_f;
return ioctl(fh->fd, B_SCSI_PLAY_POSITION, p, sizeof(scsi_play_position)) == 0;
} else
return false;
}
/*
* Pause CD audio
*/
bool SysCDPause(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return true;
if (!fh->is_file)
return ioctl(fh->fd, B_SCSI_PAUSE_AUDIO) == 0;
else
return false;
}
/*
* Resume paused CD audio
*/
bool SysCDResume(void *arg)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return false;
if (!fh->is_file)
return ioctl(fh->fd, B_SCSI_RESUME_AUDIO) == 0;
else
return false;
}
/*
* Stop CD audio
*/
bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return false;
if (!fh->is_file)
return ioctl(fh->fd, B_SCSI_STOP_AUDIO) == 0;
else
return false;
}
/*
* Perform CD audio fast-forward/fast-reverse operation starting from specified address
*/
bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return false;
if (!fh->is_file) {
scsi_scan *p = (scsi_scan *)tmp_buf;
p->speed = 0;
p->direction = reverse ? -1 : 1;
return ioctl(fh->fd, B_SCSI_SCAN, p, sizeof(scsi_scan)) == 0;
} else
return false;
}
/*
* Set CD audio volume (0..255 each channel)
*/
void SysCDSetVolume(void *arg, uint8 left, uint8 right)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return;
if (!fh->is_file) {
scsi_volume *p = (scsi_volume *)tmp_buf;
p->flags = B_SCSI_PORT0_VOLUME | B_SCSI_PORT1_VOLUME;
p->port0_volume = left;
p->port1_volume = right;
ioctl(fh->fd, B_SCSI_SET_VOLUME, p, sizeof(scsi_volume));
}
}
/*
* Get CD audio volume (0..255 each channel)
*/
void SysCDGetVolume(void *arg, uint8 &left, uint8 &right)
{
file_handle *fh = (file_handle *)arg;
if (!fh)
return;
left = right = 0;
if (!fh->is_file) {
scsi_volume *p = (scsi_volume *)tmp_buf;
p->flags = B_SCSI_PORT0_VOLUME | B_SCSI_PORT1_VOLUME;
if (ioctl(fh->fd, B_SCSI_GET_VOLUME, p, sizeof(scsi_volume)) == 0) {
left = p->port0_volume;
right = p->port1_volume;
}
}
}

View File

@ -1,144 +0,0 @@
/*
* sysdeps.h - System dependent definitions for BeOS
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SYSDEPS_H
#define SYSDEPS_H
#ifdef __POWERPC__
#define NO_STD_NAMESPACE
#endif
#include <assert.h>
#include <support/SupportDefs.h>
#include <support/ByteOrder.h>
#include "user_strings_beos.h"
// Are the Mac and the host address space the same?
#ifdef __i386__
#define REAL_ADDRESSING 0
#undef WORDS_BIGENDIAN
#else
#define REAL_ADDRESSING 1
#define WORDS_BIGENDIAN 1
#endif
// Using 68k emulator
#define EMULATED_68K 1
// Mac ROM is write protected
#define ROM_IS_WRITE_PROTECTED 1
// ExtFS is supported
#define SUPPORTS_EXTFS 1
// BSD socket API is supported
#define SUPPORTS_UDP_TUNNEL 1
// mon is not supported
#undef ENABLE_MON
// Time data type for Time Manager emulation
typedef bigtime_t tm_time_t;
// 64 bit file offsets
typedef off_t loff_t;
// Networking types
#define PF_INET AF_INET
#ifndef __HAIKU__
typedef int socklen_t;
#endif
// UAE CPU data types
#define uae_s8 int8
#define uae_u8 uint8
#define uae_s16 int16
#define uae_u16 uint16
#define uae_s32 int32
#define uae_u32 uint32
#define uae_s64 int64
#define uae_u64 uint64
typedef uae_u32 uaecptr;
#define VAL64(a) (a ## LL)
#define UVAL64(a) (a ## uLL)
typedef uint32 uintptr;
typedef int32 intptr;
/* Timing functions */
extern void Delay_usec(uint32 usec);
// UAE CPU defines
#ifdef __i386__
// Intel x86 assembler optimizations
#define X86_PPRO_OPT
static inline uae_u32 do_get_mem_long(uae_u32 *a) {uint32 retval; __asm__ ("bswap %0" : "=r" (retval) : "0" (*a) : "cc"); return retval;}
#ifdef X86_PPRO_OPT
static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("movzwl %w1,%k0\n\tshll $16,%k0\n\tbswap %k0\n" : "=&r" (retval) : "m" (*a) : "cc"); return retval;}
#else
static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("xorl %k0,%k0\n\tmovw %w1,%w0\n\trolw $8,%w0" : "=&r" (retval) : "m" (*a) : "cc"); return retval;}
#endif
#define HAVE_GET_WORD_UNSWAPPED
#define do_get_mem_word_unswapped(a) ((uae_u32)*((uae_u16 *)(a)))
static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {__asm__ ("bswap %0" : "=r" (v) : "0" (v) : "cc"); *a = v;}
#ifdef X86_PPRO_OPT
static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("bswap %0" : "=&r" (v) : "0" (v << 16) : "cc"); *a = v;}
#else
static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("rolw $8,%0" : "=r" (v) : "0" (v) : "cc"); *a = v;}
#endif
#define X86_ASSEMBLY
#define UNALIGNED_PROFITABLE
#define OPTIMIZED_FLAGS
#define ASM_SYM(a) __asm__(a)
#define REGPARAM __attribute__((regparm(3)))
#else
// PowerPC (memory.cpp not used, so no optimization neccessary)
static inline uae_u32 do_get_mem_long(uae_u32 *a) {return *a;}
static inline uae_u32 do_get_mem_word(uae_u16 *a) {return *a;}
static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {*a = v;}
static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {*a = v;}
#undef X86_ASSEMBLY
#define UNALIGNED_PROFITABLE
#undef OPTIMIZED_FLAGS
#define ASM_SYM(a)
#define REGPARAM
#endif
#define do_get_mem_byte(a) ((uae_u32)*((uae_u8 *)(a)))
#define do_put_mem_byte(a, v) (*(uae_u8 *)(a) = (v))
#define call_mem_get_func(func, addr) ((*func)(addr))
#define call_mem_put_func(func, addr, v) ((*func)(addr, v))
#define __inline__ inline
#define CPU_EMU_SIZE 0
#undef NO_INLINE_MEMORY_ACCESS
#undef MD_HAVE_MEM_1_FUNCS
#undef USE_COMPILER
#define REGPARAM2
#define ENUMDECL typedef enum
#define ENUMNAME(name) name
#define write_log printf
#endif

View File

@ -1,166 +0,0 @@
/*
* timer_beos.cpp - Time Manager emulation, BeOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <KernelKit.h>
#include "sysdeps.h"
#include "macos_util.h"
#include "timer.h"
#define DEBUG 0
#include "debug.h"
// From main_beos.cpp
extern thread_id emul_thread;
/*
* Return microseconds since boot (64 bit)
*/
void Microseconds(uint32 &hi, uint32 &lo)
{
D(bug("Microseconds\n"));
bigtime_t time = system_time();
hi = time >> 32;
lo = time;
}
/*
* Return local date/time in Mac format (seconds since 1.1.1904)
*/
uint32 TimerDateTime(void)
{
return TimeToMacTime(time(NULL));
}
/*
* Get current time
*/
void timer_current_time(tm_time_t &t)
{
t = system_time();
}
/*
* Add times
*/
void timer_add_time(tm_time_t &res, tm_time_t a, tm_time_t b)
{
res = a + b;
}
/*
* Subtract times
*/
void timer_sub_time(tm_time_t &res, tm_time_t a, tm_time_t b)
{
res = a - b;
}
/*
* Compare times (<0: a < b, =0: a = b, >0: a > b)
*/
int timer_cmp_time(tm_time_t a, tm_time_t b)
{
tm_time_t r = a - b;
return r < 0 ? -1 : (r > 0 ? 1 : 0);
}
/*
* Convert Mac time value (>0: microseconds, <0: microseconds) to tm_time_t
*/
void timer_mac2host_time(tm_time_t &res, int32 mactime)
{
if (mactime > 0)
res = mactime * 1000; // Time in milliseconds
else
res = -mactime; // Time in negative microseconds
}
/*
* Convert positive tm_time_t to Mac time value (>0: microseconds, <0: microseconds)
* A negative input value for hosttime results in a zero return value
* As long as the microseconds value fits in 32 bit, it must not be converted to milliseconds!
*/
int32 timer_host2mac_time(tm_time_t hosttime)
{
if (hosttime < 0)
return 0;
else if (hosttime > 0x7fffffff)
return hosttime / 1000; // Time in milliseconds
else
return -hosttime; // Time in negative microseconds
}
/*
* Delay by specified number of microseconds (<1 second)
*/
void Delay_usec(uint32 usec)
{
snooze(usec);
}
/*
* Suspend emulator thread, virtual CPU in idle mode
*/
void idle_wait(void)
{
#if 0
/*
FIXME: add a semaphore (counter) to avoid a B_BAD_THREAD_STATE
return if we call idle_resume() when thread is not suspended?
Sorry, I can't test -- gb.
*/
suspend_thread(emul_thread);
#endif
}
/*
* Resume execution of emulator thread, events just arrived
*/
void idle_resume(void)
{
#if 0
resume_thread(emul_thread);
#endif
}

View File

@ -1,69 +0,0 @@
/*
* user_strings_beos.cpp - BeOS-specific localizable strings
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include "user_strings.h"
// Platform-specific string definitions
user_string_def platform_strings[] = {
// Common strings that have a platform-specific variant
{STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under BeOS. Basilisk II will try to unmount it."},
{STR_EXTFS_CTRL, "BeOS Root"},
{STR_EXTFS_NAME, "BeOS Directory Tree"},
{STR_EXTFS_VOLUME_NAME, "BeOS"},
// Purely platform-specific strings
{STR_NO_SHEEP_DRIVER_ERR, "Cannot open /dev/sheep: %s (%08x). Basilisk II is not properly installed."},
{STR_SHEEP_UP_ERR, "Cannot allocate Low Memory Globals: %s (%08x)."},
{STR_NO_KERNEL_DATA_ERR, "Cannot create Kernel Data area: %s (%08x)."},
{STR_NO_NET_ADDON_WARN, "The SheepShaver net server add-on cannot be found. Ethernet will not be available."},
{STR_NET_CONFIG_MODIFY_WARN, "To enable Ethernet networking for Basilisk II, your network configuration has to be modified and the network restarted. Do you want this to be done now (selecting \"Cancel\" will disable Ethernet under Basilisk II)?."},
{STR_NET_ADDON_INIT_FAILED, "SheepShaver net server add-on found\nbut there seems to be no network hardware.\nPlease check your network preferences."},
{STR_NET_ADDON_CLONE_FAILED, "Cloning of the network transfer area failed."},
{STR_VIDEO_FAILED, "Failed to set video mode."},
{-1, NULL} // End marker
};
/*
* Fetch pointer to string, given the string number
*/
const char *GetString(int num)
{
// First search for platform-specific string
int i = 0;
while (platform_strings[i].num >= 0) {
if (platform_strings[i].num == num)
return platform_strings[i].str;
i++;
}
// Not found, search for common string
i = 0;
while (common_strings[i].num >= 0) {
if (common_strings[i].num == num)
return common_strings[i].str;
i++;
}
return NULL;
}

View File

@ -1,35 +0,0 @@
/*
* user_strings_beos.h - BeOS-specific localizable strings
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef USER_STRINGS_BEOS_H
#define USER_STRINGS_BEOS_H
enum {
STR_NO_SHEEP_DRIVER_ERR = 10000,
STR_SHEEP_UP_ERR,
STR_NO_KERNEL_DATA_ERR,
STR_NO_NET_ADDON_WARN,
STR_NET_CONFIG_MODIFY_WARN,
STR_NET_ADDON_INIT_FAILED,
STR_NET_ADDON_CLONE_FAILED,
STR_VIDEO_FAILED
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,84 +0,0 @@
/*
* xpram_beos.cpp - XPRAM handling, BeOS specific stuff
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <StorageKit.h>
#include <unistd.h>
#include "sysdeps.h"
#include "xpram.h"
// XPRAM file name and path
#if POWERPC_ROM
const char XPRAM_FILE_NAME[] = "SheepShaver_NVRAM";
#else
const char XPRAM_FILE_NAME[] = "BasiliskII_XPRAM";
#endif
static BPath xpram_path;
/*
* Load XPRAM from settings file
*/
void LoadXPRAM(const char *vmdir)
{
// Construct XPRAM path
find_directory(B_USER_SETTINGS_DIRECTORY, &xpram_path, true);
xpram_path.Append(XPRAM_FILE_NAME);
// Load XPRAM from settings file
int fd;
if ((fd = open(xpram_path.Path(), O_RDONLY)) >= 0) {
read(fd, XPRAM, XPRAM_SIZE);
close(fd);
}
}
/*
* Save XPRAM to settings file
*/
void SaveXPRAM(void)
{
if (xpram_path.InitCheck() != B_NO_ERROR)
return;
int fd;
if ((fd = open(xpram_path.Path(), O_WRONLY | O_CREAT, 0666)) >= 0) {
write(fd, XPRAM, XPRAM_SIZE);
close(fd);
}
}
/*
* Delete PRAM file
*/
void ZapPRAM(void)
{
// Construct PRAM path
find_directory(B_USER_SETTINGS_DIRECTORY, &xpram_path, true);
xpram_path.Append(XPRAM_FILE_NAME);
// Delete file
unlink(xpram_path.Path());
}

View File

@ -2,7 +2,7 @@
* $Id$
*
* video_macosx.mm - Interface between Basilisk II and Cocoa windowing.
* Based on video_amiga.cpp and video_x.cpp
* Based on video_x.cpp
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
@ -51,7 +51,7 @@
// Global variables
uint8 display_type = DISPLAY_WINDOW, // These are used by PrefsEditor
frame_skip;
frame_skip;
uint16 init_width = MIN_WIDTH, // as well as this code
init_height = MIN_HEIGHT,
init_depth = 32;
@ -919,7 +919,7 @@ OSX_monitor::switch_to_current_mode(void)
const char *failure = NULL;
D(bug("switch_to_current_mode(): width=%d height=%d depth=%d bytes_per_row=%d\n", mode.x, mode.y, bits_from_depth(mode.depth), mode.bytes_per_row));
if ( display_type == DISPLAY_SCREEN && originalMode )
{
D(NSLog(@"About to call CGDisplayBestModeForParameters()"));
@ -958,7 +958,7 @@ OSX_monitor::switch_to_current_mode(void)
CGColorSpaceRef oldColourSpace = colourSpace;
CGDataProviderRef oldProvider = provider;
void *oldBuffer = the_buffer;
if ( video_open(mode) )
{
CGImageRelease(oldImageRef);
@ -979,7 +979,7 @@ OSX_monitor::switch_to_current_mode(void)
// if ( CGDisplayMoveCursorToPoint(theDisplay, CGPointMake(15,15))
// == CGDisplayNoErr )
// {
//
//
[output fullscreenMouseMove];
// }
// else

View File

@ -41,7 +41,7 @@ and a Macintosh ROM image to use Basilisk II.
.TP
- Emulates extended ADB keyboard and 3-button mouse
.TP
- Uses UAE 68k emulation or (under AmigaOS and NetBSD/m68k) real 68k processor
- Uses UAE 68k emulation or real 68k processor
.SH OPTIONS
.TP
.BI "\-\-display " display-name

View File

@ -139,17 +139,17 @@ bool open_audio(void)
}
alSetChannels(config, audio_channel_counts[audio_channel_count_index]);
alSetDevice(config, AL_DEFAULT_OUTPUT); // Allow selecting via prefs?
// Try to open the audio library
port = alOpenPort("BasiliskII", "w", config);
if (port == NULL) {
fprintf(stderr, "ERROR: Cannot open audio port: %s\n",
fprintf(stderr, "ERROR: Cannot open audio port: %s\n",
alGetErrorString(oserror()));
WarningAlert(GetString(STR_NO_AUDIO_WARN));
return false;
}
// Set the sample rate
pv[0].param = AL_RATE;
@ -180,7 +180,7 @@ bool open_audio(void)
// Put a limit on the Mac sound buffer size, to decrease delay
#define AUDIO_BUFFER_MSEC 50 // milliseconds of sound to buffer
int target_frames_per_block =
int target_frames_per_block =
(audio_sample_rates[audio_sample_rate_index] >> 16) *
AUDIO_BUFFER_MSEC / 1000;
if (audio_frames_per_block > target_frames_per_block)
@ -190,14 +190,14 @@ bool open_audio(void)
alZeroFrames(port, audio_frames_per_block); // so we don't underflow
// Try to keep the buffer pretty full
sound_buffer_fill_point = alGetQueueSize(config) -
sound_buffer_fill_point = alGetQueueSize(config) -
2 * audio_frames_per_block;
if (sound_buffer_fill_point < 0)
sound_buffer_fill_point = alGetQueueSize(config) / 3;
D(bug("fill point %d\n", sound_buffer_fill_point));
sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) *
audio_channel_counts[audio_channel_count_index] *
audio_channel_counts[audio_channel_count_index] *
audio_frames_per_block;
set_audio_status_format();
@ -342,7 +342,7 @@ static void *stream_func(void *arg)
goto silence;
// Send data to audio library. Convert 8-bit data
// unsigned->signed, using same algorithm as audio_amiga.cpp.
// unsigned->signed
// It works fine for 8-bit mono, but not stereo.
if (AudioStatus.sample_size == 8) {
uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer));
@ -473,7 +473,7 @@ static void set_volume(uint32 vol)
alGetParamInfo(dev, AL_GAIN, &pi);
maxgain = alFixedToDouble(pi.max.ll);
mingain = alFixedToDouble(pi.min.ll);
mingain = alFixedToDouble(pi.min.ll);
// Set the new gain values

View File

@ -56,12 +56,7 @@ using std::map;
#define MONITOR 0
#ifdef __BEOS__
#define CLOSESOCKET closesocket
#else
#define CLOSESOCKET close
#endif
// Global variables
@ -138,12 +133,8 @@ void EtherInit(void)
// Set socket options
int on = 1;
#ifdef __BEOS__
setsockopt(udp_socket, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(on));
#else
setsockopt(udp_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
ioctl(udp_socket, FIONBIO, &on);
#endif
// Start thread for packet reception
if (!ether_start_udp_thread(udp_socket)) {

View File

@ -1053,7 +1053,7 @@ static int16 fs_volume_mount(uint32 pb)
// Init VCB
WriteMacInt16(vcb + vcbSigWord, 0x4244);
#if defined(__BEOS__) || defined(WIN32)
#if defined(WIN32)
WriteMacInt32(vcb + vcbCrDate, TimeToMacTime(root_stat.st_crtime));
#elif defined __APPLE__ && defined __MACH__
WriteMacInt32(vcb + vcbCrDate, get_creation_time(RootPath));
@ -1118,7 +1118,7 @@ static int16 fs_get_vol_info(uint32 pb, bool hfs)
// Fill in struct
if (ReadMacInt32(pb + ioNamePtr))
pstrcpy((char *)Mac2HostAddr(ReadMacInt32(pb + ioNamePtr)), VOLUME_NAME);
#if defined(__BEOS__) || defined(WIN32)
#if defined(WIN32)
WriteMacInt32(pb + ioVCrDate, TimeToMacTime(root_stat.st_crtime));
#elif defined __APPLE__ && defined __MACH__
WriteMacInt32(pb + ioVCrDate, get_creation_time(RootPath));
@ -1312,7 +1312,7 @@ read_next_de:
WriteMacInt8(pb + ioFlAttrib, access(full_path, W_OK) == 0 ? 0 : faLocked);
WriteMacInt32(pb + ioDirID, fs_item->id);
#if defined(__BEOS__) || defined(WIN32)
#if defined(WIN32)
WriteMacInt32(pb + ioFlCrDat, TimeToMacTime(st.st_crtime));
#elif defined __APPLE__ && defined __MACH__
WriteMacInt32(pb + ioFlCrDat, get_creation_time(full_path));
@ -1437,7 +1437,7 @@ read_next_de:
WriteMacInt8(pb + ioACUser, 0);
WriteMacInt32(pb + ioDirID, fs_item->id);
WriteMacInt32(pb + ioFlParID, fs_item->parent_id);
#if defined(__BEOS__) || defined(WIN32)
#if defined(WIN32)
WriteMacInt32(pb + ioFlCrDat, TimeToMacTime(st.st_crtime));
#elif defined __APPLE__ && defined __MACH__
WriteMacInt32(pb + ioFlCrDat, get_creation_time(full_path));

View File

@ -89,18 +89,6 @@ static inline void _cdecl winbug(wchar_t *s, ...)
#define bug winbug
#define wbug wwinbug
#elif defined(AMIGA)
// Amiga debugging info goes to serial port (or sushi)
#ifdef __cplusplus
extern "C" {
#endif
extern void kprintf(const char *, ...);
#ifdef __cplusplus
}
#endif
#define bug kprintf
#else
// Other systems just print it to stdout

View File

@ -1,66 +0,0 @@
/*
* cpu_emulation.h - Definitions for Basilisk II CPU emulation module (Apple PowerMac ROM 680x0 emulator version (BeOS/PPC))
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CPU_EMULATION_H
#define CPU_EMULATION_H
/*
* Memory system
*/
// RAM and ROM pointers (allocated and set by main_*.cpp)
extern uint32 RAMBaseMac; // RAM base (Mac address space), does not include Low Mem when != 0
extern uint8 *RAMBaseHost; // RAM base (host address space)
extern uint32 RAMSize; // Size of RAM
extern uint32 ROMBaseMac; // ROM base (Mac address space)
extern uint8 *ROMBaseHost; // ROM base (host address space)
extern uint32 ROMSize; // Size of ROM
// Mac memory access functions
static inline uint32 ReadMacInt32(uint32 addr) {return ntohl(*(uint32 *)addr);}
static inline uint32 ReadMacInt16(uint32 addr) {return ntohs(*(uint16 *)addr);}
static inline uint32 ReadMacInt8(uint32 addr) {return *(uint8 *)addr;}
static inline void WriteMacInt32(uint32 addr, uint32 l) {*(uint32 *)addr = htonl(l);}
static inline void WriteMacInt16(uint32 addr, uint32 w) {*(uint16 *)addr = htons(w);}
static inline void WriteMacInt8(uint32 addr, uint32 b) {*(uint8 *)addr = b;}
static inline uint8 *Mac2HostAddr(uint32 addr) {return (uint8 *)addr;}
static inline uint32 Host2MacAddr(uint8 *addr) {return (uint32)addr;}
/*
* 680x0 emulation
*/
// Initialization
extern bool Init680x0(void); // This routine may want to look at CPUType/FPUType to set up the apropriate emulation
extern void Exit680x0(void);
// 680x0 emulation functions
struct M68kRegisters;
extern void Start680x0(void); // Reset and start 680x0
extern "C" void Execute68k(uint32 addr, M68kRegisters *r); // Execute 68k code from EMUL_OP routine
extern "C" void Execute68kTrap(uint16 trap, M68kRegisters *r); // Execute MacOS 68k trap from EMUL_OP routine
// Interrupt functions
extern void TriggerInterrupt(void); // Trigger interrupt (InterruptFlag must be set first)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1040,7 +1040,7 @@ static bool patch_rom_32(void)
if (PatchHWBases) {
extern uint8 *ScratchMem;
const uint32 ScratchMemBase = Host2MacAddr(ScratchMem);
D(bug("LMGlob\tOfs/4\tBase\n"));
base = ROMBaseMac + UniversalInfo + ReadMacInt32(ROMBaseMac + UniversalInfo); // decoderInfoPtr
wp = (uint16 *)(ROMBaseHost + 0x94a);
@ -1048,7 +1048,7 @@ static bool patch_rom_32(void)
int16 ofs = ntohs(*wp++); // offset in decoderInfo (/4)
int16 lmg = ntohs(*wp++); // address of LowMem global
D(bug("0x%04x\t%d\t0x%08x\n", lmg, ofs, ReadMacInt32(base + ofs*4)));
// Fake address only if this is not the ASC base
if (lmg != 0xcc0)
WriteMacInt32(base + ofs*4, ScratchMemBase);
@ -1280,20 +1280,13 @@ static bool patch_rom_32(void)
#endif
#endif
#if REAL_ADDRESSING && defined(AMIGA)
// Don't overwrite SysBase under AmigaOS
wp = (uint16 *)(ROMBaseHost + 0xccb4);
*wp++ = htons(M68K_NOP);
*wp = htons(M68K_NOP);
#endif
#if REAL_ADDRESSING && !defined(AMIGA)
#if REAL_ADDRESSING
// gb-- Temporary hack to get rid of crashes in Speedometer
wp = (uint16 *)(ROMBaseHost + 0xdba2);
if (ntohs(*wp) == 0x662c) // bne.b #$2c
*wp = htons(0x602c); // bra.b #$2c
#endif
// Don't write to VIA in InitTimeMgr
wp = (uint16 *)(ROMBaseHost + 0xb0e2);
*wp++ = htons(0x4cdf); // movem.l (sp)+,d0-d5/a0-a4

View File

@ -50,11 +50,7 @@ using std::vector;
// Check for inserted disks by polling?
#ifdef AMIGA
#define DISK_INSERT_CHECK 1
#else
#define DISK_INSERT_CHECK 0
#endif
// Floppy disk icon

View File

@ -33,11 +33,7 @@
#include "sysdeps.h"
#include "user_strings.h"
#ifdef __BEOS__
#define ELLIPSIS "\xE2\x80\xA6"
#else
#define ELLIPSIS "..."
#endif
// Common string definitions

View File

@ -59,9 +59,6 @@ links:
include/prefs.h include/scsi.h include/serial.h \
include/serial_defs.h include/sony.h include/sys.h \
include/timer.h include/xpram.h \
BeOS/audio_beos.cpp BeOS/extfs_beos.cpp BeOS/scsi_beos.cpp \
BeOS/serial_beos.cpp BeOS/sys_beos.cpp BeOS/timer_beos.cpp \
BeOS/xpram_beos.cpp BeOS/SheepDriver BeOS/SheepNet \
CrossPlatform/sigsegv.h CrossPlatform/vm_alloc.h CrossPlatform/vm_alloc.cpp \
CrossPlatform/video_vosf.h CrossPlatform/video_blit.h CrossPlatform/video_blit.cpp \
Unix/audio_oss_esd.cpp \

View File

@ -1,24 +0,0 @@
<HTML>
<HEAD>
<TITLE>Acknowledgements</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1>Acknowledgements</H1>
The following persons/companies deserve special thanks from us as they
made a significant contribution to the development of SheepShaver:
<P>
<UL>
<LI><A HREF="http://www.be.com/">Be Inc.</A>, and especially Dominic Giampaolo, for their support
<LI>Tai Kahn from the <A HREF="http://www.ecafenet.com/">eCafe Network</A> for hosting the <A HREF="http://www.sheepshaver.com/">SheepShaver web site</A>
<LI>Tinic Uro for the SheepShaver icon
</UL>
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

View File

@ -1,47 +0,0 @@
<HTML>
<HEAD>
<TITLE>Contact Information</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1>Contact Information and Copyright</H1>
SheepShaver was brought to you by
<UL>
<LI><A HREF="mailto:Christian.Bauer@uni-mainz.de">Christian Bauer</A> (kernel, disk I/O)
<LI><A HREF="mailto:Marc.Hellwig@uni-mainz.de">Marc Hellwig</A> (graphics, sound, networking)
</UL>
<H3><IMG SRC="iconsmall.gif" ALIGN=MIDDLE>SheepShaver WWW Site:</H3>
<BLOCKQUOTE>
<A HREF="http://www.sheepshaver.com/">www.sheepshaver.com</A><BR>
</BLOCKQUOTE>
<H3>EMail:</H3>
<BLOCKQUOTE>
<A HREF="mailto:Christian.Bauer@uni-mainz.de">Christian.Bauer@uni-mainz.de</A><BR>
</BLOCKQUOTE>
<H3>License</H3>
<P>SheepShaver is available under the terms of the GNU General Public License.
See the file "COPYING" that is included in the distribution for details.
<P>&copy; Copyright 1997-2004 Christian Bauer and Marc Hellwig
<P>Names of hardware and software items mentioned in this manual and
in program texts are in most cases registered trade marks of the respective
companies and not marked as such. So the lack of such a note may not be
used as an indication that these names are free.
<P>SheepShaver is not designed, intended, or authorized for use as a component
in systems intended for surgical implant within the body, or other applications intended
to support or sustain life, or for any other application in which the failure of SheepShaver
could create a situation where personal injury or death may occur (so-called "killer application").
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -1,59 +0,0 @@
<HTML>
<HEAD>
<TITLE>Revision History</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1>SheepShaver Revision History</H1>
<H2>V2.2 (04-Feb-2002)</H2>
<UL>
<LI>Integrated code from Basilisk II
<LI>Source released under GPL
</UL>
<H2>V2.1 (31-Mar-2001)</H2>
<UL>
<LI>Support for MacOS 8.5 and 8.6
<LI>Support for G3 ROMs
<LI>It's possible to select which video modes are to be used by MacOS
<LI>SheepShaver will not use up all CPU time when "nothing" is running
<LI>More stable networking
<LI>16 and 32 bit window modes
<LI>Small bug fixes
</UL>
<H2>V2.0 (20-Jan-1999)</H2>
<UL>
<LI>"BeOS" icon on the Mac desktop to access files on BeOS volumes from Mac applications.
<LI>Handling of removable media (i.e. automatic detection of disk insertion)
<LI>More flexible parallel port selection on BeBox
<LI>Greatly improved Time Manager (higher accuracy)
<LI>Fixed "audio lags"
<LI>Option to ignore illegal memory accesses
<LI>Adapted for (and requires) BeOS R4
<LI>MacOS 7.5.5/7.6/7.6.1 run better on some systems
<LI>Small bug fixes
</UL>
<H2>V1.1 (13-Jul-1998)</H2>
<UL>
<LI>Support for more machine types (esp. PowerMac 4400)
<LI>Corrected time zone handling
<LI>Volume list in preferences handles dropped volumes and files
<LI>BeBox: 16/24 bit modes have correct colors with a Millennium II
<LI>Video/SetEntries didn't set last palette entry
<LI>Mac programs trying to use the (non-existant) SCSI Manager shouldn't crash any longer
</UL>
<H2>V1.0 (18-May-1998)</H2>
<UL>
<LI>Initial release
</UL>
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,28 +0,0 @@
<HTML>
<HEAD>
<TITLE>The SheepShaver User's Guide</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1><IMG SRC="icon.gif" ALIGN=MIDDLE>SheepShaver V2.2 Installation and User's Guide (BeOS)</H1>
<H2>Contents</H2>
<UL>
<LI><A HREF="introduction.html">Introduction</A>
<LI><A HREF="installation.html">Installation</A>
<LI><A HREF="quickstart.html">Quick Start</A>
<LI><A HREF="settings.html">Setting up SheepShaver</A>
<LI><A HREF="using.html">Using SheepShaver</A>
<LI><A HREF="troubleshooting.html">Troubleshooting</A>
<LI><A HREF="acknowledgements.html">Acknowledgements</A>
<LI><A HREF="contact.html">Contact Information and Copyright</A>
<LI><A HREF="history.html">Revision History</A>
</UL>
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

View File

@ -1,25 +0,0 @@
<HTML>
<HEAD>
<TITLE>Installation</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1>Installation</H1>
You need BeOS/PowerPC R4. R3 or earlier versions will not work.
<OL>
<LI>Unpack the SheepShaver package (if you are reading this, you probably have already done this)
<LI>On a BeBox, you need a copy of a PCI PowerMac ROM (4MB) in a file
called "ROM" in the same folder SheepShaver is in (but you can select a different
location in the settings window). SheepShaver can also use the "Mac OS ROM" file
that comes with MacOS 8.5/8.6 (look in the System Folder on your MacOS CD). In
order to legally use SheepShaver, you have to own the ROM the image file was taken from.
</OL>
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

View File

@ -1,45 +0,0 @@
<HTML>
<HEAD>
<TITLE>Introduction</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1>Introduction</H1>
SheepShaver is a MacOS run-time environment for BeOS that allows you
to run MacOS applications at native speed inside the BeOS multitasking
environment on PowerPC-based BeOS systems. This means that both BeOS
and MacOS applications can run at the same time and data can be exchanged
between them.
<P>SheepShaver is neither a MacOS replacement nor an emulator. It runs an
unmodified PowerPC MacOS under control of the BeOS at full speed without
any kind of emulation. So it also uses the MacOS 68k emulator to run 68k
applications. In this way, SheepShaver is comparable to the "Blue Box" of
Apple's Rhapsody operating system.
<H2>Some of SheepShaver's features:</H2>
<UL>
<LI>Compatibility: SheepShaver runs MacOS 7.5.2 thru 8.6 with all system
extensions like AppleGuide, AppleScript, QuickTime, QuickTime VR,
QuickDraw 3D, Open Transport, PPP, Language Kits, ColorSync, etc.
<LI>Graphics: The MacOS user interface is displayed in a BeOS window or
full-screen (with QuickDraw acceleration) in resolutions up to
1600x1200 in 24 bit.
<LI>Sound: CD-quality stereo sound output
<LI>Networking: SheepShaver supports Internet and LAN networking via
Ethernet and PPP with all Open Transport compatible MacOS applications.
<LI>Volumes: Any HFS or HFS+ volume can be used with SheepShaver (this
includes Zip/Jaz/SyQuest drives etc.). It also features a built-in
CD-ROM driver and a driver for HD floppy disks.
<LI>Data Exchange: You can access BeOS files from the MacOS via a "BeOS"
icon on the Mac desktop and copy and paste text between BeOS and MacOS
</UL>
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -1,38 +0,0 @@
<HTML>
<HEAD>
<TITLE>Quick Start</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1>Quick Start</H1>
The following is a step-by-step guide that shows you how to get SheepShaver
up and running in the quickest possible way. We assume that you are running
on a PowerMac that already has MacOS installed on a partition of your hard drive
and that you have booted into BeOS.
<P>
<OL>
<LI>Double-click the SheepShaver icon. The "SheepShaver Settings" window will appear.
<LI>Click on "Start". SheepShaver will try to detect on which partition MacOS is installed and should then start booting MacOS.
<LI>If this is the first time you start SheepShaver you will be asked if you want your
network configuration to be modified to enable Ethernet networking under SheepShaver.
If you want to use Ethernet with SheepShaver you should press "OK" (this will change the
file <CODE>/boot/home/config/settings/network</CODE>; a backup of the the original file will
be stored in <CODE>network.orig</CODE>).
<LI>To quit SheepShaver, select "Shutdown" from the Finder's "Special" menu.
</OL>
<H3>One word of caution:</H3>
Volumes which are used by SheepShaver must not also be mounted under BeOS
while SheepShaver is running. <STRONG>You will lose data and corrupt the
volume if you do this! Don't press the "Mount all disks now" button in the
BeOS "Disk Mount Settings" window while SheepShaver is running!</STRONG>
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,127 +0,0 @@
<HTML>
<HEAD>
<TITLE>Setting up SheepShaver</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1>Setting up SheepShaver</H1>
In the "SheepShaver Settings" window that pops up when you double-click on
the SheepShaver icon, you can configure certain features of SheepShaver.
When you click on <B>"Start"</B>, the current settings are saved to disk and will be
available next time you start SheepShaver.
<P>The settings are divided into four groups: Volumes, Graphics/Sound, Serial/Network and Memory/Misc.
<H2>Volumes</H2>
<IMG SRC="volumes.gif">
<P>The main part of the volumes pane is a <B>list</B> that contains all volumes to be mounted
by SheepShaver. If this list is empty, SheepShaver will try to detect and mount all HFS partitions
it can find. CD-ROM drives are always automatically detected and used.
<P>SheepShaver can use HFS partitions, whole HFS formatted drives, and it can also
emulate hard disks in single BeOS files ("hardfiles").
<P>To add a Mac volume to the list, mount it on the BeOS side, click on <B>"Add..."</B>, go to the "Disks"
level in the topmost popup menu of the file panel, click once on the volume you want and
click on "Add". A line beginning with "/dev/disk/" should then appear in the volume list.
After adding volumes to the list, you should unmount them on the BeOS side again.To remove
a Mac volume, select it in the list and click on <B>"Remove"</B>.
<P>You can create a new, empty hardfile by clicking on <B>"Create..."</B>. Enter the file
name and the size of the hardfile and click on "Create". The hardfile will be created (this may
take some seconds) and added to the volume list. The so-created hardfile will have to be
formatted under MacOS before you can store something in it. If you start up SheepShaver,
the Finder will display a message about an "unreadable" volume being found and give you the
option to format it.
<P>Double-clicking on an entry in the volume list will add or remove a "*" in front of the
device name. Volumes marked with a "*" are read-only for the MacOS under SheepShaver.
<P>SheepShaver will show a "BeOS" disk icon on the Mac desktop that allows access to BeOS
files from Mac applications. In <B>"BeOS Root"</B> you specify which BeOS directory will
be at the root of this virtual "BeOS" disk. You can enter a path name here or drag and drop a
Tracker folder onto it. The default setting of "/boot" means that the "BeOS" icon in the MacOS
Finder will correspond to your BeOS boot volume. If you want to access files on other BeOS
volumes, you should enter "/" here. The "BeOS" disk will then contain folders for each BeOS
volume (among other things). The MacOS will create files and folders like "Desktop", "Trash",
"OpenFolderListDF" etc. in the directory you specify as "BeOS Root". If they annoy you, you
can delete them.
<P>To boot from CD-ROM, set the <B>"Boot From"</B> setting to <B>"CD-ROM"</B>.
The <B>"Disable CD-ROM Driver"</B> box is used to disable SheepShaver's built-in CD-ROM driver.
This is currently of not much use and you should leave the box unselected.
<H2>Graphics/Sound</H2>
<IMG SRC="graphics.gif">
<P>WIth <B>"Window Refresh Rate"</B> you can set the refresh rate of the MacOS window.
Higher rates mean faster screen updates and less "sluggish" behaviour, but also require more CPU time.
<P>The <B>"QuickDraw Acceleration"</B> box should always be enabled. It allows for faster graphics in
full-screen modes. But if your machine uses the "IXMicro" BeOS video driver, you have to disable the
QuickDraw acceleration or full-screen modes won't work (this is because of BeOS bug #981112-032247).
<P>The main part of the window is occupied by a list of checkboxes that allows you to select
which <B>graphics modes</B> are available for displaying the MacOS desktop. You can, for
example, disable the modes that your monitor or graphics card can't display, or disable the
window modes when you want to run some Mac programs in full-screen mode that would otherwise
erroneously switch to a window mode. The actual mode to be used is selected in the "Monitors"
control panel under MacOS.
<P>The <B>"Disable Sound Output"</B> box allows you to disable all sound output by SheepShaver.
This is useful if the sound takes too much CPU time on your machine or to get rid of warning
messages if SheepShaver can't use your audio hardware.
<H2>Serial/Network</H2>
<IMG SRC="serial.gif">
<P>You can select to which ports the MacOS <B>modem and printer ports</B> are redirected.
This doesn't make much sense on a PowerMac, but on a BeBox you can assign the modem
and printer ports to any of the four serial ports (or com3/com4) or even parallel ports of
the BeBox (useful for printing if you have Mac drivers for parallel printers, like the PowerPrint
package from <A HREF="http://www.gdt.com">www.gdt.com</A>).
<P>If you don't want SheepShaver's Ethernet support to be enabled for some reason, you
can use the <B>"Disable Ethernet"</B> checkbox to disable it (this will also get rid of the annoying
"no network hardware" messages if your Mac is not equipped with Ethernet).
<H2>Memory/Misc</H2>
<IMG SRC="memory.gif">
<P>With <B>"MacOS RAM Size"</B> you select how much RAM will be available to the MacOS
(and all MacOS applications running under it). SheepShaver uses the BeOS virtual memory system,
so you can select more RAM than you physically have in your machine. The MacOS virtual memory
system is not available under SheepShaver (i.e. if you have 32MB of RAM in your computer and
select 64MB to be used for MacOS in the SheepShaver settings, MacOS will behave as if it's running on
a computer that has 64MB of RAM but no virtual memory).
<P>The <B>"Ignore Illegal Memory Accesses"</B> option is there to make some broken Mac
programs work that access addresses where there is no RAM or ROM. With this option unchecked,
SheepShaver will in this case display an error message and quit. When the option is activated,
SheepShaver will try to continue as if the illegal access never happened (writes are ignored, reads
return 0). This may or may not make the program work (when a program performs an illegal access,
it is most likely that something else went wrong). When a Mac program behaves strangely or hangs,
you can quit SheepShaver, uncheck this option and retry. If you get an "illegal access" message,
you will know that something is broken.
<P>If the <B>"Don't Use CPU When Idle"</B> option is enabled, SheepShaver will try to reduce
CPU usage to a minimum when the MacOS is doing "nothing" but waiting for user input. This doesn't
work with all programs and it may confuse the timing of some games but in general you should
leave it enabled.
<P><B>"ROM File"</B> specifies the path name of the Mac ROM file to be used. If it is left
blank, SheepShaver expects the ROM file to be called "ROM" and be in the same directory as
the SheepShaver application.
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

View File

@ -1,79 +0,0 @@
<HTML>
<HEAD>
<TITLE>Troubleshooting</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1>Troubleshooting</H1>
<H2>SheepShaver doesn't boot</H2>
SheepShaver should boot all MacOS versions &gt;=7.5.2, except MacOS X. However,
your mileage may vary. If it doesn't boot, try again with extensions disabled
(by pressing the shift key) and then remove some of these extensions:
"MacOS Licensing Extension", Speed Doubler, 68k FPU extensions and MacsBug.
<H2>The colors are wrong in 16 or 32 bit graphics modes</H2>
If you're running SheepShaver on a BeBox, the only graphics modes that have
the right colors are the 8 bit modes (this is actually a hardware problem
and has to do with frame buffers being little-endian on the BeBox), unless
you are using a Matrox Milennium I/II.
<P>You should also be aware that not all graphics cards support 16 bit modes
under BeOS (especially S3 cards don't). Check the BeOS "Screen" preferences
application to see if your card does.
<H2>SheepShaver appears to be very slow</H2>
<UL>
<LI>Don't use the window modes, the fullscreen modes are much faster.
<LI>If you nevertheless want (or have) to use a window mode, you should set the
color depth in MacOS to the same as the BeOS workspace you are running SheepShaver on
(e.g. if you are on a 16-bit workspace, set the color depth in MacOS to "Thousands").
Also, set the window refresh rate to a low value (high values like 30Hz will make SheepShaver
(and BeOS) slower, not faster!).
</UL>
<H2>Full-screen mode doesn't work</H2>
If your machine uses the "IXMicro" BeOS video driver (TwinTurbo cards), you
will have to disable the "QuickDraw Acceleration" in the "Video" pane of the
SheepShaver settings.
<H2>Ethernet doesn't work</H2>
<UL>
<LI>Is the Ethernet set up under BeOS? Ethernet will not work in SheepShaver if you didn't set it up in the BeOS "Network" preferences.
<LI>If you're using TCP/IP on the MacOS side, you have to set up different IP addresses for the BeOS and for the MacOS.
<LI>Try disabling AppleTalk in the BeOS Network preferences (there might be conflicts between BeOS AppleTalk and SheepShaver networking).
</UL>
<H2>SheepShaver crashes, but yesterday it worked</H2>
Try the "Zap PRAM File" item in the main menu of the SheepShaver preferences editor.
When you are using a ROM file and switching to a different ROM version, you <B>have</B>
to zap the PRAM file or SheepShaver might behave very weird.
<H2>Known incompatibilities</H2>
<UL>
<LI>MacOS programs or drivers which access Mac hardware directly are not supported by SheepShaver.
<LI>Speed Doubler, RAM Doubler, 68k FPU emulators and similar programs don't run under SheepShaver.
<LI>MacsBug is not compatible with SheepShaver.
<LI>If you want to run RealPC on a BeBox, you have to disable one CPU in the "Pulse" application or it will crash.
</UL>
<H2>Known bugs</H2>
<UL>
<LI>The QuickTime 2.5 Cinepak codec crashes the emulator.
<LI>Programs that use InputSprockets crash the emulator when in window mode.
<LI>The mouse cursor hotspot in window mode is not correct.
</UL>
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

View File

@ -1,76 +0,0 @@
<HTML>
<HEAD>
<TITLE>Using SheepShaver</TITLE>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<H1>Using SheepShaver</H1>
<H2>Changing the display mode</H2>
SheepShaver can display the MacOS user interface in a BeOS window or full-screen
(much faster) in several resolutions and color depths. You select the display mode
as usual under MacOS in the "Monitors" control panel (under System 7.x, click on "Options").
The "75Hz" modes are full-screen modes, the "60Hz" modes are window modes
(this doesn't mean that the video refresh rate is 75 or 60Hz in the respective modes;
the rate displayed has no meaning; it's simply there to distinguish full screen modes
from window modes).
<H2>Window mode</H2>
The SheepShaver window has a menu at the bottom that allows you to change the
graphics refresh rate and to mount floppy disks (see below). The window refresh is
disabled as long as the "Scroll Lock" key is pressed (the graphics output is then frozen).
<H2>Full-screen mode</H2>
The full-screen mode uses a whole BeOS workspace for displaying the MacOS user
interface. You can switch workspaces with Command-F1/F2/F3/etc. Please note that
the MacOS (and all MacOS applications) will be suspended when you switch to a different
workspace. It will only be resumed when you go back to the SheepShaver workspace.
<H2>Networking</H2>
SheepShaver only supports Ethernet networking (and PPP via the serial
ports). If there are multiple Ethernet cards installed, only the first
card will be used. The Ethernet support is implemented at the data-link
level. This implies that the "Mac" and the "Be" side must have two different
network addresses.
<H2>Using floppy disks</H2>
Floppy disks are not automatically detected when they are inserted. They have to be
mounted explicitly. After inserting a floppy disk, select the "Mount Floppy" item in the
"SheepShaver" menu (when running in window mode), or press Ctrl-F1 (when running in
full-screen mode). BeBox users should note that floppy disks also have to be unmounted
under MacOS before ejecting them from the drive.
<H2>Accessing BeOS files</H2>
SheepShaver will display a "BeOS" disk icon on the Mac desktop that allows you
to access any BeOS files/folders which are in the directory specified as "BeOS Root"
in the "Volumes" pane of the SheepShaver settings. You can open and save files on the
"BeOS" disk from Mac applications, copy, move or rename files from the Finder etc.
Putting files/folder to the trash may however not always work. SheepShaver translates
some BeOS file types to MacOS types and vice versa, so e.g. JPEG and PDF files will
show up the correct icons in the Finder. To store Mac resources and other additional
data, SheepShaver uses the following BeOS file attributes:
<UL>
<LI><CODE>MACOS:RFORK</CODE> contains the complete Mac resource fork of the file
<LI><CODE>MACOS:HFS_FLAGS</CODE> contains Finder flags
<LI><CODE>MACOS:CREATOR</CODE> contains the MacOS creator application ID
</UL>
<H2>Copying text via the clipboard</H2>
SheepShaver tries to keep the BeOS and MacOS clipboards synchronized. That means,
when you copy a piece of text under BeOS, you can paste it into a MacOS application
and vice versa.
<HR>
<ADDRESS>
SheepShaver User's Guide
</ADDRESS>
</BODY>
</HTML>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -1,256 +0,0 @@
/*
* Ethernet.cpp - SheepShaver ethernet PCI driver stub
*
* SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <stddef.h>
#include "xlowmem.h"
#include "ether_defs.h"
/*
* Driver Description structure
*/
struct DriverDescription {
uint32 driverDescSignature;
uint32 driverDescVersion;
char nameInfoStr[32];
uint32 version;
uint32 driverRuntime;
char driverName[32];
uint32 driverDescReserved[8];
uint32 nServices;
uint32 serviceCategory;
uint32 serviceType;
uint32 serviceVersion;
};
#pragma export on
DriverDescription TheDriverDescription = {
'mtej',
0,
"\pSheepShaver Ethernet",
0x01008000, // V1.0.0final
4, // kDriverIsUnderExpertControl
"\penet",
0, 0, 0, 0, 0, 0, 0, 0,
1,
'otan',
0x000a0b01, // Ethernet, Framing: Ethernet/EthernetIPX/802.2, IsDLPI
0x01000000, // V1.0.0
};
#pragma export off
/*
* install_info and related structures
*/
static int ether_open(queue_t *rdq, void *dev, int flag, int sflag, void *creds);
static int ether_close(queue_t *rdq, int flag, void *creds);
static int ether_wput(queue_t *q, msgb *mp);
static int ether_wsrv(queue_t *q);
static int ether_rput(queue_t *q, msgb *mp);
static int ether_rsrv(queue_t *q);
struct ot_module_info {
uint16 mi_idnum;
char *mi_idname;
int32 mi_minpsz; // Minimum packet size
int32 mi_maxpsz; // Maximum packet size
uint32 mi_hiwat; // Queue hi-water mark
uint32 mi_lowat; // Queue lo-water mark
};
static ot_module_info module_information = {
kEnetModuleID,
"SheepShaver Ethernet",
0,
kEnetTSDU,
6000,
5000
};
typedef int (*putp_t)(queue_t *, msgb *);
typedef int (*srvp_t)(queue_t *);
typedef int (*openp_t)(queue_t *, void *, int, int, void *);
typedef int (*closep_t)(queue_t *, int, void *);
struct qinit {
putp_t qi_putp;
srvp_t qi_srvp;
openp_t qi_qopen;
closep_t qi_qclose;
void *qi_qadmin;
struct ot_module_info *qi_minfo;
void *qi_mstat;
};
static qinit read_side = {
NULL,
ether_rsrv,
ether_open,
ether_close,
NULL,
&module_information,
NULL
};
static qinit write_side = {
ether_wput,
NULL,
ether_open,
ether_close,
NULL,
&module_information,
NULL
};
struct streamtab {
struct qinit *st_rdinit;
struct qinit *st_wrinit;
struct qinit *st_muxrinit;
struct qinit *st_muxwinit;
};
static streamtab the_streamtab = {
&read_side,
&write_side,
NULL,
NULL
};
struct install_info {
struct streamtab *install_str;
uint32 install_flags;
uint32 install_sqlvl;
char *install_buddy;
void *ref_load;
uint32 ref_count;
};
enum {
kOTModIsDriver = 0x00000001,
kOTModUpperIsDLPI = 0x00002000,
SQLVL_MODULE = 3,
};
static install_info the_install_info = {
&the_streamtab,
kOTModIsDriver /*| kOTModUpperIsDLPI */,
SQLVL_MODULE,
NULL,
NULL,
0
};
// Prototypes for exported functions
extern "C" {
#pragma export on
extern uint32 ValidateHardware(void *theID);
extern install_info* GetOTInstallInfo();
extern uint8 InitStreamModule(void *theID);
extern void TerminateStreamModule(void);
#pragma export off
}
/*
* Validate that our hardware is available (always available)
*/
uint32 ValidateHardware(void *theID)
{
return 0;
}
/*
* Return pointer to install_info structure
*/
install_info *GetOTInstallInfo(void)
{
return &the_install_info;
}
/*
* Init module
*/
asm uint8 InitStreamModule(register void *theID)
{
lwz r2,XLM_TOC
lwz r0,XLM_ETHER_INIT
mtctr r0
bctr
}
/*
* Terminate module
*/
asm void TerminateStreamModule(void)
{
lwz r2,XLM_TOC
lwz r0,XLM_ETHER_TERM
mtctr r0
bctr
}
/*
* DLPI functions
*/
static asm int ether_open(register queue_t *rdq, register void *dev, register int flag, register int sflag, register void *creds)
{
lwz r2,XLM_TOC
lwz r0,XLM_ETHER_OPEN
mtctr r0
bctr
}
static asm int ether_close(register queue_t *rdq, register int flag, register void *creds)
{
lwz r2,XLM_TOC
lwz r0,XLM_ETHER_CLOSE
mtctr r0
bctr
}
static asm int ether_wput(register queue_t *q, register msgb *mp)
{
lwz r2,XLM_TOC
lwz r0,XLM_ETHER_WPUT
mtctr r0
bctr
}
static asm int ether_rsrv(register queue_t *q)
{
lwz r2,XLM_TOC
lwz r0,XLM_ETHER_RSRV
mtctr r0
bctr
}

View File

@ -1,25 +0,0 @@
all: ../../EthernetDriverStub.i ../../VideoDriverStub.i
clean:
-rm *.o hexconv Ethernet Video
../../EthernetDriverStub.i: Ethernet hexconv
hexconv $< $@
../../VideoDriverStub.i: Video hexconv
hexconv $< $@
hexconv: hexconv.cpp
mwcc -o hexconv hexconv.cpp
Ethernet.o: Ethernet.cpp
mwcc -I.. -I../../include -o $@ -c $<
Video.o: Video.cpp
mwcc -I.. -I../../include -o $@ -c $<
Ethernet: Ethernet.o
mwldppc -xms -export pragma -nostdentry -nostdlib -o $@ $<
Video: Video.o
mwldppc -xms -export pragma -nostdentry -nostdlib -o $@ $<

View File

@ -1,78 +0,0 @@
/*
* Video.cpp - SheepShaver video PCI driver stub
*
* SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include "xlowmem.h"
/*
* Driver Description structure
*/
struct DriverDescription {
uint32 driverDescSignature;
uint32 driverDescVersion;
char nameInfoStr[32];
uint32 version;
uint32 driverRuntime;
char driverName[32];
uint32 driverDescReserved[8];
uint32 nServices;
uint32 serviceCategory;
uint32 serviceType;
uint32 serviceVersion;
};
#pragma export on
struct DriverDescription TheDriverDescription = {
'mtej',
0,
"\pvideo",
0x01008000, // V1.0.0final
6, // kDriverIsUnderExpertControl, kDriverIsOpenedUponLoad
"\pDisplay_Video_Apple_Sheep",
0, 0, 0, 0, 0, 0, 0, 0,
1,
'ndrv',
'vido',
0x01000000, // V1.0.0
};
#pragma export off
// Prototypes for exported functions
extern "C" {
#pragma export on
extern int16 DoDriverIO(void *spaceID, void *commandID, void *commandContents, uint32 commandCode, uint32 commandKind);
#pragma export off
}
/*
* Do driver IO
*/
asm int16 DoDriverIO(void *spaceID, void *commandID, void *commandContents, uint32 commandCode, uint32 commandKind)
{
lwz r2,XLM_TOC
lwz r0,XLM_VIDEO_DOIO
mtctr r0
bctr
}

View File

@ -1,34 +0,0 @@
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc != 3) {
printf("Usage: %s <raw file> <C source>\n", argv[0]);
return 0;
}
FILE *fin = fopen(argv[1], "rb");
if (fin == NULL) {
printf("Can't open '%s' for reading\n", argv[1]);
return 0;
}
FILE *fout = fopen(argv[2], "w");
if (fout == NULL) {
printf("Can't open '%s' for writing\n", argv[2]);
return 0;
}
unsigned char buf[16];
while (!feof(fin)) {
fprintf(fout, "\t");
int actual = fread(buf, 1, 16, fin);
for (int i=0; i<actual; i++)
fprintf(fout, "0x%02x, ", buf[i]);
fprintf(fout, "\n");
}
fclose(fin);
fclose(fout);
return 0;
}

View File

@ -1,117 +0,0 @@
## BeOS Generic Makefile v2.1 ##
## Fill in this file to specify the project being created, and the referenced
## makefile-engine will do all of the hard work for you. This handles both
## Intel and PowerPC builds of the BeOS.
## Application Specific Settings ---------------------------------------------
# specify the name of the binary
NAME= SheepShaver
# specify the type of binary
# APP: Application
# SHARED: Shared library or add-on
# STATIC: Static library archive
# DRIVER: Kernel Driver
TYPE= APP
# add support for new Pe and Eddie features
# to fill in generic makefile
#%{
# @src->@
# specify the source files to use
# full paths or paths relative to the makefile can be included
# all files, regardless of directory, will have their object
# files created in the common object directory.
# Note that this means this makefile will not work correctly
# if two source files with the same name (source.c or source.cpp)
# are included from different directories. Also note that spaces
# in folder names do not work well with this makefile.
SRCS= ../main.cpp main_beos.cpp ../prefs.cpp ../prefs_items.cpp prefs_beos.cpp \
prefs_editor_beos.cpp sys_beos.cpp ../rom_patches.cpp ../rsrc_patches.cpp \
../emul_op.cpp ../name_registry.cpp ../macos_util.cpp ../timer.cpp \
timer_beos.cpp ../xpram.cpp xpram_beos.cpp ../adb.cpp clip_beos.cpp \
../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp scsi_beos.cpp \
../video.cpp video_beos.cpp ../audio.cpp audio_beos.cpp ../ether.cpp \
ether_beos.cpp ../serial.cpp serial_beos.cpp ../extfs.cpp extfs_beos.cpp \
about_window_beos.cpp ../user_strings.cpp user_strings_beos.cpp ../thunks.cpp
# specify the resource files to use
# full path or a relative path to the resource file can be used.
RSRCS= SheepShaver.rsrc
# @<-src@
#%}
# end support for Pe and Eddie
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
LIBS= be tracker game media translation textencoding device GL
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
# or paths relative to the makefile. The paths included may not
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
# source file directories are NOT auto-included here
SYSTEM_INCLUDE_PATHS =
# additional paths to look for local headers
# thes use the form: #include "header"
# source file directories are automatically included
LOCAL_INCLUDE_PATHS = ../include SheepDriver SheepNet
# specify the level of optimization that you desire
# NONE, SOME, FULL
OPTIMIZE= FULL
# specify any preprocessor symbols to be defined. The symbols will not
# have their values set automatically; you must supply the value (if any)
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
# would pass "-DDEBUG" on the compiler's command line.
DEFINES=
# specify special warning levels
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
WARNINGS =
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
SYMBOLS =
# specify debug settings
# if TRUE will allow application to be run from a source-level
# debugger. Note that this will disable all optimzation.
DEBUGGER =
# specify additional compiler flags for all files
COMPILER_FLAGS = -prefix BeHeaders
# specify additional linker flags
LINKER_FLAGS =
## include the makefile-engine
include /boot/develop/etc/makefile-engine

View File

@ -1,110 +0,0 @@
## BeOS Generic Makefile v2.1 ##
## Fill in this file to specify the project being created, and the referenced
## makefile-engine will do all of the hard work for you. This handles both
## Intel and PowerPC builds of the BeOS.
## Application Specific Settings ---------------------------------------------
# specify the name of the binary
NAME= NetPeek
# specify the type of binary
# APP: Application
# SHARED: Shared library or add-on
# STATIC: Static library archive
# DRIVER: Kernel Driver
TYPE= APP
# add support for new Pe and Eddie features
# to fill in generic makefile
#%{
# @src->@
# specify the source files to use
# full paths or paths relative to the makefile can be included
# all files, regardless of directory, will have their object
# files created in the common object directory.
# Note that this means this makefile will not work correctly
# if two source files with the same name (source.c or source.cpp)
# are included from different directories. Also note that spaces
# in folder names do not work well with this makefile.
SRCS= NetPeek.cpp
# specify the resource files to use
# full path or a relative path to the resource file can be used.
RSRCS=
# @<-src@
#%}
# end support for Pe and Eddie
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
LIBS=
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
# or paths relative to the makefile. The paths included may not
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
# source file directories are NOT auto-included here
SYSTEM_INCLUDE_PATHS =
# additional paths to look for local headers
# thes use the form: #include "header"
# source file directories are automatically included
LOCAL_INCLUDE_PATHS = ../ ../../include ../NetAddOn
# specify the level of optimization that you desire
# NONE, SOME, FULL
OPTIMIZE= FULL
# specify any preprocessor symbols to be defined. The symbols will not
# have their values set automatically; you must supply the value (if any)
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
# would pass "-DDEBUG" on the compiler's command line.
DEFINES=
# specify special warning levels
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
WARNINGS =
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
SYMBOLS =
# specify debug settings
# if TRUE will allow application to be run from a source-level
# debugger. Note that this will disable all optimzation.
DEBUGGER =
# specify additional compiler flags for all files
COMPILER_FLAGS =
# specify additional linker flags
LINKER_FLAGS =
## include the makefile-engine
include /boot/develop/etc/makefile-engine

View File

@ -1,49 +0,0 @@
/*
* NetPeek.cpp - Utility program for monitoring SheepNet add-on
*/
#include "sysdeps.h"
#include "sheep_net.h"
#include <stdio.h>
static area_id buffer_area; // Packet buffer area
static net_buffer *net_buffer_ptr; // Pointer to packet buffer
int main(void)
{
area_id handler_buffer;
if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) {
printf("Can't find packet buffer\n");
return 10;
}
if ((buffer_area = clone_area("local packet buffer", &net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) {
printf("Can't clone packet buffer\n");
return 10;
}
uint8 *p = net_buffer_ptr->ether_addr;
printf("Ethernet address : %02x %02x %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
printf("read_sem : %d\n", net_buffer_ptr->read_sem);
printf("read_ofs : %d\n", net_buffer_ptr->read_ofs);
printf("read_packet_size : %d\n", net_buffer_ptr->read_packet_size);
printf("read_packet_count : %d\n", net_buffer_ptr->read_packet_count);
printf("write_sem : %d\n", net_buffer_ptr->write_sem);
printf("write_ofs : %d\n", net_buffer_ptr->write_ofs);
printf("write_packet_size : %d\n", net_buffer_ptr->write_packet_size);
printf("write_packet_count: %d\n", net_buffer_ptr->write_packet_count);
printf("\nRead packets:\n");
for (int i=0; i<READ_PACKET_COUNT; i++) {
net_packet *p = &net_buffer_ptr->read[i];
printf("cmd : %08lx\n", p->cmd);
printf("length: %d\n", p->length);
}
printf("\nWrite packets:\n");
for (int i=0; i<WRITE_PACKET_COUNT; i++) {
net_packet *p = &net_buffer_ptr->write[i];
printf("cmd : %08lx\n", p->cmd);
printf("length: %d\n", p->length);
}
return 0;
}

View File

@ -1,110 +0,0 @@
## BeOS Generic Makefile v2.1 ##
## Fill in this file to specify the project being created, and the referenced
## makefile-engine will do all of the hard work for you. This handles both
## Intel and PowerPC builds of the BeOS.
## Application Specific Settings ---------------------------------------------
# specify the name of the binary
NAME= SaveROM
# specify the type of binary
# APP: Application
# SHARED: Shared library or add-on
# STATIC: Static library archive
# DRIVER: Kernel Driver
TYPE= APP
# add support for new Pe and Eddie features
# to fill in generic makefile
#%{
# @src->@
# specify the source files to use
# full paths or paths relative to the makefile can be included
# all files, regardless of directory, will have their object
# files created in the common object directory.
# Note that this means this makefile will not work correctly
# if two source files with the same name (source.c or source.cpp)
# are included from different directories. Also note that spaces
# in folder names do not work well with this makefile.
SRCS= SaveROM.cpp
# specify the resource files to use
# full path or a relative path to the resource file can be used.
RSRCS= SaveROM.rsrc
# @<-src@
#%}
# end support for Pe and Eddie
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
LIBS= be
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
# or paths relative to the makefile. The paths included may not
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
# source file directories are NOT auto-included here
SYSTEM_INCLUDE_PATHS =
# additional paths to look for local headers
# thes use the form: #include "header"
# source file directories are automatically included
LOCAL_INCLUDE_PATHS = ../ ../../include ../NetAddOn
# specify the level of optimization that you desire
# NONE, SOME, FULL
OPTIMIZE= FULL
# specify any preprocessor symbols to be defined. The symbols will not
# have their values set automatically; you must supply the value (if any)
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
# would pass "-DDEBUG" on the compiler's command line.
DEFINES=
# specify special warning levels
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
WARNINGS =
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
SYMBOLS =
# specify debug settings
# if TRUE will allow application to be run from a source-level
# debugger. Note that this will disable all optimzation.
DEBUGGER =
# specify additional compiler flags for all files
COMPILER_FLAGS =
# specify additional linker flags
LINKER_FLAGS =
## include the makefile-engine
include /boot/develop/etc/makefile-engine

View File

@ -1,8 +0,0 @@
"SaveROM" is a program that allows you to save the ROM of
a PowerMac running under BeOS to a file.
1. Copy "sheep_driver" to ~/config/add-ons/kernel/drivers.
2. Double-click the "SaveROM" icon.
This will create a file called "ROM" which should be 4MB
in size.

View File

@ -1,128 +0,0 @@
/*
* SaveROM - Save Mac ROM to file
*
* Copyright (C) 1998-2004 Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <AppKit.h>
#include <InterfaceKit.h>
#include <StorageKit.h>
#include <stdio.h>
#include <unistd.h>
// Constants
const char APP_SIGNATURE[] = "application/x-vnd.cebix-SaveROM";
const char ROM_FILE_NAME[] = "ROM";
// Global variables
static uint8 buf[0x400000];
// Application object
class SaveROM : public BApplication {
public:
SaveROM() : BApplication(APP_SIGNATURE)
{
// Find application directory and cwd to it
app_info the_info;
GetAppInfo(&the_info);
BEntry the_file(&the_info.ref);
BEntry the_dir;
the_file.GetParent(&the_dir);
BPath the_path;
the_dir.GetPath(&the_path);
chdir(the_path.Path());
}
virtual void ReadyToRun(void);
};
/*
* Create application object and start it
*/
int main(int argc, char **argv)
{
SaveROM *the_app = new SaveROM();
the_app->Run();
delete the_app;
return 0;
}
/*
* Display error alert
*/
static void ErrorAlert(const char *text)
{
BAlert *alert = new BAlert("SaveROM Error", text, "Quit", NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT);
alert->Go();
}
/*
* Display OK alert
*/
static void InfoAlert(const char *text)
{
BAlert *alert = new BAlert("SaveROM Message", text, "Quit", NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT);
alert->Go();
}
/*
* Main program
*/
void SaveROM::ReadyToRun(void)
{
int fd = open("/dev/sheep", 0);
if (fd < 0) {
ErrorAlert("Cannot open '/dev/sheep'.");
goto done;
}
if (read(fd, buf, 0x400000) != 0x400000) {
ErrorAlert("Cannot read ROM.");
close(fd);
goto done;
}
FILE *f = fopen(ROM_FILE_NAME, "wb");
if (f == NULL) {
ErrorAlert("Cannot open ROM file.");
close(fd);
goto done;
}
if (fwrite(buf, 1, 0x400000, f) != 0x400000) {
ErrorAlert("Cannot write ROM.");
fclose(f);
close(fd);
goto done;
}
InfoAlert("ROM saved.");
fclose(f);
close(fd);
done:
PostMessage(B_QUIT_REQUESTED);
}

View File

@ -1 +0,0 @@
../../../BasiliskII/src/BeOS/SheepDriver

View File

@ -1 +0,0 @@
../../../BasiliskII/src/BeOS/SheepNet

View File

@ -1,289 +0,0 @@
/*
* about_window_beos.cpp - "About" window, BeOS implementation
*
* SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <GLView.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include "about_window.h"
#include "video.h"
#include "version.h"
#include "user_strings.h"
// About window dimensions
static const BRect about_frame = BRect(0, 0, 383, 99);
// Special colors
const rgb_color fill_color = {216, 216, 216, 0};
// SheepShaver icon
static const uint8 sheep_icon[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xda, 0x15, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xff, 0x00, 0x00, 0x00, 0x16, 0xda, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16,
0x00, 0x1d, 0xda, 0x1e, 0x1e, 0x1e, 0xda, 0x16, 0x00, 0x00, 0x16, 0xda, 0x16, 0xda, 0x08, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x00, 0x00, 0x00, 0x0b, 0xff, 0xff, 0x11, 0x00, 0xda,
0x1d, 0xda, 0x1e, 0xda, 0x1e, 0xda, 0x1e, 0xda, 0x1e, 0x16, 0x00, 0x00, 0x0c, 0xff, 0xff, 0xff,
0xff, 0x0b, 0x00, 0x00, 0x16, 0x16, 0x00, 0x12, 0xfd, 0x1d, 0x0b, 0x00, 0x00, 0x1d, 0xfd, 0x1d,
0xfd, 0x1e, 0xda, 0x1e, 0xda, 0x1e, 0xda, 0x3f, 0xda, 0x3f, 0xda, 0x15, 0x00, 0xff, 0xff, 0xff,
0x16, 0x00, 0x17, 0x16, 0x00, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x16, 0x0f, 0x0b, 0x1d,
0x1e, 0xfd, 0x1e, 0xda, 0x1e, 0xda, 0x3f, 0xda, 0x3f, 0xda, 0x1d, 0x5a, 0x15, 0xff, 0xff, 0xff,
0x05, 0x17, 0x16, 0x00, 0x12, 0x1d, 0x00, 0x1d, 0xfd, 0x00, 0xfd, 0x00, 0x00, 0x16, 0x0b, 0x00,
0x00, 0x0e, 0x1d, 0x3f, 0xda, 0x3f, 0xda, 0x1d, 0xda, 0x1b, 0x5a, 0x1b, 0x0f, 0x1d, 0xff, 0xff,
0xff, 0x05, 0x00, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x1a, 0xfd, 0x00, 0x0f, 0x14, 0x14,
0x16, 0x00, 0x15, 0xfd, 0x1d, 0xda, 0x1b, 0xda, 0x1b, 0x5a, 0x1b, 0x5a, 0x0f, 0x14, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x1a, 0xfd, 0x12, 0x00, 0x16, 0x00, 0x0f,
0x00, 0x1b, 0xfd, 0x1e, 0xfd, 0x1b, 0xda, 0x1b, 0x5a, 0x1b, 0x5a, 0x1b, 0x5a, 0x14, 0xff, 0xff,
0xff, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x1a, 0xfd, 0x12, 0x00, 0x16, 0x1b, 0x16, 0x0e,
0x1b, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd, 0x1b, 0x5a, 0x18, 0x00, 0x00, 0x5a, 0x1b, 0x00, 0xff, 0xff,
0xff, 0x00, 0xfd, 0x14, 0xfd, 0x14, 0xfd, 0x1d, 0xfd, 0x12, 0x00, 0x16, 0xfd, 0x1b, 0xfd, 0x1b,
0xfd, 0x1b, 0xfd, 0x1e, 0xfd, 0x1b, 0x5a, 0x18, 0x5a, 0x00, 0x00, 0x1b, 0x9b, 0x00, 0xff, 0xff,
0xff, 0x00, 0x0f, 0xfd, 0x1d, 0xfd, 0x0f, 0xfd, 0x12, 0x00, 0x16, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd,
0x1b, 0xfd, 0x18, 0xfd, 0x1b, 0xf9, 0x18, 0x5a, 0x00, 0x12, 0x00, 0x9b, 0x1b, 0x00, 0xff, 0xff,
0xff, 0x00, 0xfd, 0x0a, 0x0a, 0x0a, 0xfd, 0x10, 0x00, 0x1b, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd, 0x18,
0xfd, 0x15, 0xfa, 0x15, 0xf9, 0x18, 0x15, 0x00, 0x12, 0x9b, 0x00, 0x1b, 0x9b, 0x00, 0x15, 0x15,
0xff, 0xff, 0x00, 0xfd, 0x1d, 0xfd, 0x1d, 0x00, 0x16, 0x00, 0x1b, 0xfd, 0x1b, 0xfd, 0x15, 0xfd,
0x15, 0xfa, 0x15, 0xf9, 0x15, 0x16, 0x00, 0x0f, 0x9b, 0x12, 0x00, 0x9b, 0x1b, 0x00, 0x15, 0x15,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x1d, 0x00, 0xfa, 0x1e, 0x00, 0x1e, 0xfa, 0x15,
0xfa, 0x15, 0x16, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x12, 0x15, 0x15,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1d, 0xf9, 0x00, 0x3f, 0xfa, 0x00, 0xfa, 0x1b, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x00, 0x00, 0x12, 0x15, 0x15, 0x15, 0x15,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf9, 0x1d, 0x00, 0xf9, 0x1b, 0x00, 0x1b, 0xf9, 0x00,
0xff, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1d, 0xf9, 0x00, 0x3f, 0xf9, 0x00, 0xf9, 0x1b, 0x00,
0xff, 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x16, 0x1d, 0x00, 0xf9, 0x1b, 0x00, 0x1b, 0xf9, 0x00,
0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x00, 0x00, 0x00, 0x16, 0xf9, 0x00, 0x1b, 0x16, 0x00,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x00, 0x00, 0x12, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x15, 0x00, 0x0a, 0x19, 0x0a, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x12, 0x00, 0x00, 0x00, 0x16, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x19, 0x1c, 0x18, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
0x0f, 0xff, 0xff, 0xff, 0x00, 0x18, 0x11, 0x00, 0x15, 0x00, 0x1c, 0x18, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x00, 0x00, 0x00, 0x0b, 0x0b,
0x00, 0x00, 0x0f, 0xff, 0x12, 0x00, 0x18, 0x19, 0x00, 0x15, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x00, 0x00, 0x14, 0x1e, 0xfd, 0x01, 0xfd, 0x14,
0xfa, 0xf9, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x19, 0x1c, 0x00, 0x18, 0x1c, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x14, 0xfd, 0x1e, 0xf9, 0x1e, 0xfa, 0x1e, 0xf9,
0x14, 0xfa, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x18, 0x00, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x14, 0x1e, 0xf9, 0x14, 0xfa, 0x1e, 0xf9, 0x1e,
0xfd, 0x1e, 0x00, 0x15, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0x00, 0x00, 0x18, 0x00, 0x1c, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x00, 0xfd, 0x1e, 0xfd, 0x14, 0xfd, 0x1e, 0xfd,
0x1e, 0x01, 0x00, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x00, 0x00, 0x1c, 0x00, 0x15,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x14, 0xfa, 0x01, 0xf9, 0x1e, 0xf9, 0x14,
0x14, 0x00, 0x0f, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x00, 0x00, 0x15, 0x15,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
// View class
class AboutViewT : public BView {
public:
AboutViewT(BRect r) : BView(r, "", B_FOLLOW_NONE, B_WILL_DRAW) {}
virtual void Draw(BRect update)
{
char str[256];
sprintf(str, GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
SetFont(be_bold_font);
SetDrawingMode(B_OP_OVER);
MovePenTo(20, 20);
DrawString(str);
SetFont(be_plain_font);
MovePenTo(20, 40);
DrawString(GetString(STR_ABOUT_TEXT2));
MovePenTo(20, 60);
DrawString(B_UTF8_COPYRIGHT "1997-2008 Christian Bauer and Marc Hellwig");
}
virtual void MouseDown(BPoint point)
{
Window()->PostMessage(B_QUIT_REQUESTED);
}
};
// 3D view class
class AboutView3D : public BGLView {
public:
AboutView3D(BRect r) : BGLView(r, "", B_FOLLOW_NONE, 0, BGL_RGB | BGL_DOUBLE)
{
rot_x = rot_y = 0;
if (!VideoSnapshot(64, 64, texture)) {
uint8 *p = texture;
const uint8 *q = sheep_icon;
const color_map *cm = system_colors();
for (int i=0; i<32*32; i++) {
uint8 red = cm->color_list[*q].red;
uint8 green = cm->color_list[*q].green;
uint8 blue = cm->color_list[*q++].blue;
p[0] = p[3] = p[64*3] = p[65*3] = red;
p[1] = p[4] = p[64*3+1] = p[65*3+1] = green;
p[2] = p[5] = p[64*3+2] = p[65*3+2] = blue;
p += 6;
if ((i & 31) == 31)
p += 64*3;
}
}
}
virtual void AttachedToWindow(void)
{
BGLView::AttachedToWindow();
LockGL();
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glShadeModel(GL_SMOOTH);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30, 1, 0.5, 20);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat light_color[4] = {1, 1, 1, 1};
GLfloat light_dir[4] = {1, 2, 1.5, 1};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
glLightfv(GL_LIGHT0, GL_POSITION, light_dir);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, 4, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
glEnable(GL_TEXTURE_2D);
UnlockGL();
tick_thread_active = true;
tick_thread = spawn_thread(tick_func, "OpenGL Animation", B_NORMAL_PRIORITY, this);
resume_thread(tick_thread);
}
virtual void DetachedFromWindow(void)
{
status_t l;
tick_thread_active = false;
wait_for_thread(tick_thread, &l);
BGLView::DetachedFromWindow();
}
virtual void Draw(BRect update)
{
LockGL();
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
glNormal3d(0, 0, 1);
glTexCoord2f(0, 0);
glVertex3d(-1, 1, 0);
glTexCoord2f(1, 0);
glVertex3d(1, 1, 0);
glTexCoord2f(1, 1);
glVertex3d(1, -1, 0);
glTexCoord2f(0, 1);
glVertex3d(-1, -1, 0);
glEnd();
SwapBuffers();
UnlockGL();
}
static status_t tick_func(void *arg)
{
AboutView3D *obj = (AboutView3D *)arg;
while (obj->tick_thread_active) {
obj->rot_x += 2;
obj->rot_y += 2;
obj->LockGL();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -5);
glRotatef(obj->rot_x, 1, 0, 0);
glRotatef(obj->rot_y, 0, 1, 0);
obj->UnlockGL();
if (obj->LockLooperWithTimeout(20000) == B_OK) {
obj->Draw(obj->Bounds());
obj->UnlockLooper();
}
snooze(16667);
}
return 0;
}
private:
thread_id tick_thread;
bool tick_thread_active;
float rot_x, rot_y;
uint8 texture[64*64*3];
};
// Window class
class AboutWindowT : public BWindow {
public:
AboutWindowT() : BWindow(about_frame, NULL, B_MODAL_WINDOW_LOOK, B_FLOATING_APP_WINDOW_FEEL, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK)
{
Lock();
MoveTo(100, 100);
BRect r = Bounds();
r.right = 100;
AboutView3D *view_3d = new AboutView3D(r);
AddChild(view_3d);
r = Bounds();
r.left = 100;
AboutViewT *view = new AboutViewT(r);
AddChild(view);
view->SetHighColor(0, 0, 0);
view->SetViewColor(fill_color);
view->MakeFocus();
Unlock();
Show();
}
};
/*
* Open "About" window
*/
void OpenAboutWindow(void)
{
new AboutWindowT;
}

View File

@ -1 +0,0 @@
../../../BasiliskII/src/BeOS/audio_beos.cpp

View File

@ -1,374 +0,0 @@
/*
* clip_beos.cpp - Clipboard handling, BeOS implementation
*
* SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <support/UTF8.h>
#include "clip.h"
#include "main.h"
#include "cpu_emulation.h"
#include "emul_op.h"
#define DEBUG 0
#include "debug.h"
// Global variables
static bool we_put_this_data = false; // Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the Be side
static BTranslatorRoster *roster;
static float input_cap = 0;
static translator_info input_info;
static float output_cap = 0;
static translator_id output_trans = 0;
/*
* Clipboard manager thread (for calling clipboard functions; this is not safe
* under R4 when running on the MacOS stack in kernel space)
*/
// Message constants
const uint32 MSG_QUIT_CLIP_MANAGER = 'quit';
const uint32 MSG_PUT_TEXT = 'ptxt';
static thread_id cm_thread = -1;
static sem_id cm_done_sem = -1;
// Argument passing
static void *cm_scrap;
static int32 cm_length;
static status_t clip_manager(void *arg)
{
for (;;) {
// Receive message
thread_id sender;
uint32 code = receive_data(&sender, NULL, 0);
D(bug("Clipboard manager received %08lx\n", code));
switch (code) {
case MSG_QUIT_CLIP_MANAGER:
return 0;
case MSG_PUT_TEXT:
if (be_clipboard->Lock()) {
be_clipboard->Clear();
BMessage *clipper = be_clipboard->Data();
// Convert text from Mac charset to UTF-8
int32 dest_length = cm_length * 3;
int32 state = 0;
char *inbuf = new char[cm_length];
memcpy(inbuf, cm_scrap, cm_length); // Copy to user space
char *outbuf = new char[dest_length];
if (convert_to_utf8(B_MAC_ROMAN_CONVERSION, inbuf, &cm_length, outbuf, &dest_length, &state) == B_OK) {
for (int i=0; i<dest_length; i++)
if (outbuf[i] == 13)
outbuf[i] = 10;
// Add text to Be clipboard
clipper->AddData("text/plain", B_MIME_TYPE, outbuf, dest_length);
be_clipboard->Commit();
} else {
D(bug(" text conversion failed\n"));
}
delete[] outbuf;
delete[] inbuf;
be_clipboard->Unlock();
}
break;
}
// Acknowledge
release_sem(cm_done_sem);
}
}
/*
* Initialize clipboard
*/
void ClipInit(void)
{
// check if there is a translator that can handle the pict datatype
roster = BTranslatorRoster::Default();
int32 num_translators, i,j;
translator_id *translators;
const char *translator_name, *trans_info;
int32 translator_version;
const translation_format *t_formats;
long t_num;
roster->GetAllTranslators(&translators, &num_translators);
for (i=0;i<num_translators;i++) {
roster->GetTranslatorInfo(translators[i], &translator_name,
&trans_info, &translator_version);
D(bug("found translator %s: %s (%.2f)\n", translator_name, trans_info,
translator_version/100.));
// does this translator support the pict datatype ?
roster->GetInputFormats(translators[i], &t_formats,&t_num);
//printf(" supports %d input formats \n",t_num);
for (j=0;j<t_num;j++) {
if (!strcmp (t_formats[j].MIME,"image/pict")) {
// matching translator found
if (t_formats[j].capability>input_cap) {
input_info.type = t_formats[j].type;
input_info.group = t_formats[j].group;
input_info.quality = t_formats[j].quality;
input_info.capability = t_formats[j].capability;
strcpy(input_info.MIME,t_formats[j].MIME);
strcpy(input_info.name,t_formats[j].name);
input_info.translator=translators[i];
input_cap = t_formats[j].capability;
}
D(bug("matching input translator found:type:%c%c%c%c group:%c%c%c%c quality:%f capability:%f MIME:%s name:%s\n",
t_formats[j].type>>24,t_formats[j].type>>16,t_formats[j].type>>8,t_formats[j].type,
t_formats[j].group>>24,t_formats[j].group>>16,t_formats[j].group>>8,t_formats[j].group,
t_formats[j].quality,
t_formats[j].capability,t_formats[j].MIME,
t_formats[j].name));
}
}
roster->GetOutputFormats(translators[i], &t_formats,&t_num);
//printf("and %d output formats \n",t_num);
for (j=0;j<t_num;j++) {
if (!strcmp (t_formats[j].MIME,"image/pict")) {
if (t_formats[j].capability>output_cap) {
output_trans = translators[i];
output_cap = t_formats[j].capability;
}
D(bug("matching output translator found:type:%c%c%c%c group:%c%c%c%c quality:%f capability:%f MIME:%s name:%s\n",
t_formats[j].type>>24,t_formats[j].type>>16,t_formats[j].type>>8,t_formats[j].type,
t_formats[j].group>>24,t_formats[j].group>>16,t_formats[j].group>>8,t_formats[j].group,
t_formats[j].quality,
t_formats[j].capability,t_formats[j].MIME,
t_formats[j].name));
}
}
}
delete [] translators; // clean up our droppings
// Start clipboard manager thread
cm_done_sem = create_sem(0, "Clipboard Manager Done");
cm_thread = spawn_thread(clip_manager, "Clipboard Manager", B_NORMAL_PRIORITY, NULL);
resume_thread(cm_thread);
}
/*
* Deinitialize clipboard
*/
void ClipExit(void)
{
// Stop clipboard manager
if (cm_thread > 0) {
status_t l;
send_data(cm_thread, MSG_QUIT_CLIP_MANAGER, NULL, 0);
while (wait_for_thread(cm_thread, &l) == B_INTERRUPTED) ;
}
// Delete semaphores
delete_sem(cm_done_sem);
}
/*
* Mac application wrote to clipboard
*/
void PutScrap(uint32 type, void *scrap, int32 length)
{
D(bug("PutScrap type %08lx, data %p, length %ld\n", type, scrap, length));
if (we_put_this_data) {
we_put_this_data = false;
return;
}
if (length <= 0)
return;
switch (type) {
case 'TEXT':
D(bug(" clipping TEXT\n"));
cm_scrap = scrap;
cm_length = length;
while (send_data(cm_thread, MSG_PUT_TEXT, NULL, 0) == B_INTERRUPTED) ;
while (acquire_sem(cm_done_sem) == B_INTERRUPTED) ;
break;
case 'PICT':
D(bug(" clipping PICT\n"));
//!! this has to be converted to use the Clipboard Manager
#if 0
if (be_clipboard->Lock()) {
be_clipboard->Clear();
BMessage *clipper = be_clipboard->Data();
// Waaaah! This crashes!
if (input_cap > 0) { // if there is an converter for PICT datatype convert data to bitmap.
BMemoryIO *in_buffer = new BMemoryIO(scrap, length);
BMallocIO *out_buffer = new BMallocIO();
status_t result=roster->Translate(in_buffer,&input_info,NULL,out_buffer,B_TRANSLATOR_BITMAP);
clipper->AddData("image/x-be-bitmap", B_MIME_TYPE, out_buffer->Buffer(), out_buffer->BufferLength());
D(bug("conversion result:%08x buffer_size:%d\n",result,out_buffer->BufferLength()));
delete in_buffer;
delete out_buffer;
}
clipper->AddData("image/pict", B_MIME_TYPE, scrap, length);
be_clipboard->Commit();
be_clipboard->Unlock();
}
#endif
break;
}
}
/*
* Mac application zeroes clipboard
*/
void ZeroScrap()
{
}
/*
* Mac application reads clipboard
*/
void GetScrap(void **handle, uint32 type, int32 offset)
{
M68kRegisters r;
D(bug("GetScrap handle %p, type %08lx, offset %ld\n", handle, type, offset));
return; //!! GetScrap is currently broken (should use Clipboard Manager)
//!! replace with clipboard notification in BeOS R4.1
switch (type) {
case 'TEXT':
D(bug(" clipping TEXT\n"));
if (be_clipboard->Lock()) {
BMessage *clipper = be_clipboard->Data();
char *clip;
ssize_t length;
// Check if we already copied this data
if (clipper->HasData("application/x-SheepShaver-cookie", B_MIME_TYPE))
return;
bigtime_t cookie = system_time();
clipper->AddData("application/x-SheepShaver-cookie", B_MIME_TYPE, &cookie, sizeof(bigtime_t));
// No, is there text in it?
if (clipper->FindData("text/plain", B_MIME_TYPE, &clip, &length) == B_OK) {
D(bug(" text/plain found\n"));
// Convert text from UTF-8 to Mac charset
int32 src_length = length;
int32 dest_length = length;
int32 state = 0;
char *outbuf = new char[dest_length];
if (convert_from_utf8(B_MAC_ROMAN_CONVERSION, clip, &src_length, outbuf, &dest_length, &state) == B_OK) {
for (int i=0; i<dest_length; i++)
if (outbuf[i] == 10)
outbuf[i] = 13;
// Add text to Mac clipboard
static uint16 proc[] = {
0x598f, // subq.l #4,sp
0xa9fc, // ZeroScrap()
0x2f3c, 0, 0, // move.l #length,-(sp)
0x2f3c, 'TE', 'XT', // move.l #'TEXT',-(sp)
0x2f3c, 0, 0, // move.l #outbuf,-(sp)
0xa9fe, // PutScrap()
0x588f, // addq.l #4,sp
M68K_RTS
};
*(int32 *)(proc + 3) = dest_length;
*(char **)(proc + 9) = outbuf;
we_put_this_data = true;
Execute68k((uint32)proc, &r);
} else {
D(bug(" text conversion failed\n"));
}
delete[] outbuf;
}
be_clipboard->Commit();
be_clipboard->Unlock();
}
break;
case 'PICT':
D(bug(" clipping PICT\n"));
if (be_clipboard->Lock()) {
BMessage *clipper = be_clipboard->Data();
char *clip;
ssize_t length;
// Check if we already copied this data
if (clipper->HasData("application/x-SheepShaver-cookie", B_MIME_TYPE))
return;
bigtime_t cookie = system_time();
clipper->AddData("application/x-SheepShaver-cookie", B_MIME_TYPE, &cookie, sizeof(bigtime_t));
static uint16 proc2[] = {
0x598f, // subq.l #4,sp
0xa9fc, // ZeroScrap()
0x2f3c, 0, 0, // move.l #length,-(sp)
0x2f3c, 'PI', 'CT', // move.l #'PICT',-(sp)
0x2f3c, 0, 0, // move.l #buf,-(sp)
0xa9fe, // PutScrap()
0x588f, // addq.l #4,sp
M68K_RTS
};
// No, is there a pict ?
if (clipper->FindData("image/pict", B_MIME_TYPE, &clip, &length) == B_OK ) {
D(bug(" image/pict found\n"));
// Add pict to Mac clipboard
*(int32 *)(proc2 + 3) = length;
*(char **)(proc2 + 9) = clip;
we_put_this_data = true;
Execute68k((uint32)proc2, &r);
#if 0
// No, is there a bitmap ?
} else if (clipper->FindData("image/x-be-bitmap", B_MIME_TYPE, &clip, &length) == B_OK || output_cap > 0) {
D(bug(" image/x-be-bitmap found\nstarting conversion to PICT\n"));
BMemoryIO *in_buffer = new BMemoryIO(clip, length);
BMallocIO *out_buffer = new BMallocIO();
status_t result=roster->Translate(output_trans,in_buffer,NULL,out_buffer,'PICT');
D(bug("result of conversion:%08x buffer_size:%d\n",result,out_buffer->BufferLength()));
// Add pict to Mac clipboard
*(int32 *)(proc2 + 3) = out_buffer->BufferLength();
*(char **)(proc2 + 9) = (char *)out_buffer->Buffer();
we_put_this_data = true;
Execute68k(proc2, &r);
delete in_buffer;
delete out_buffer;
#endif
}
be_clipboard->Commit();
be_clipboard->Unlock();
}
break;
}
}

View File

@ -1,400 +0,0 @@
/*
* ether_beos.cpp - SheepShaver Ethernet Device Driver (DLPI), BeOS specific stuff
*
* SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include "ether.h"
#include "ether_defs.h"
#include "prefs.h"
#include "xlowmem.h"
#include "main.h"
#include "user_strings.h"
#include "sheep_net.h"
#define DEBUG 0
#include "debug.h"
#define STATISTICS 0
#define MONITOR 0
// Global variables
static thread_id read_thread; // Packet receiver thread
static bool ether_thread_active = true; // Flag for quitting the receiver thread
static area_id buffer_area; // Packet buffer area
static net_buffer *net_buffer_ptr; // Pointer to packet buffer
static sem_id read_sem, write_sem; // Semaphores to trigger packet reading/writing
static uint32 rd_pos; // Current read position in packet buffer
static uint32 wr_pos; // Current write position in packet buffer
static bool net_open = false; // Flag: initialization succeeded, network device open
// Prototypes
static status_t AO_receive_thread(void *data);
/*
* Initialize ethernet
*/
void EtherInit(void)
{
// Do nothing if the user disabled the network
if (PrefsFindBool("nonet"))
return;
// find net-server team
i_wanna_try_that_again:
bool found_add_on = false;
team_info t_info;
int32 t_cookie = 0;
image_info i_info;
int32 i_cookie = 0;
while (get_next_team_info(&t_cookie, &t_info) == B_NO_ERROR) {
if (strstr(t_info.args,"net_server")!=NULL) {
// check if sheep_net add-on is loaded
while (get_next_image_info(t_info.team,&i_cookie,&i_info) == B_NO_ERROR) {
if (strstr(i_info.name,"sheep_net")!=NULL) {
found_add_on = true;
break;
}
}
}
if (found_add_on) break;
}
if (!found_add_on) {
// Search for sheep_net in network config file
char str[1024];
bool sheep_net_found = false;
FILE *fin = fopen("/boot/home/config/settings/network", "r");
while (!feof(fin)) {
fgets(str, 1024, fin);
if (strstr(str, "PROTOCOLS"))
if (strstr(str, "sheep_net"))
sheep_net_found = true;
}
fclose(fin);
// It was found, so something else must be wrong
if (sheep_net_found) {
WarningAlert(GetString(STR_NO_NET_ADDON_WARN));
return;
}
// Not found, inform the user
if (!ChoiceAlert(GetString(STR_NET_CONFIG_MODIFY_WARN), GetString(STR_OK_BUTTON), GetString(STR_CANCEL_BUTTON)))
return;
// Change the network config file and restart the network
fin = fopen("/boot/home/config/settings/network", "r");
FILE *fout = fopen("/boot/home/config/settings/network.2", "w");
bool global_found = false;
bool modified = false;
while (!feof(fin)) {
str[0] = 0;
fgets(str, 1024, fin);
if (!global_found && strstr(str, "GLOBAL:")) {
global_found = true;
} else if (global_found && !modified && strstr(str, "PROTOCOLS")) {
str[strlen(str)-1] = 0;
strcat(str, " sheep_net\n");
modified = true;
} else if (global_found && !modified && strlen(str) > 2 && str[strlen(str) - 2] == ':') {
fputs("\tPROTOCOLS = sheep_net\n", fout);
modified = true;
}
fputs(str, fout);
}
if (!modified)
fputs("\tPROTOCOLS = sheep_net\n", fout);
fclose(fout);
fclose(fin);
remove("/boot/home/config/settings/network.orig");
rename("/boot/home/config/settings/network", "/boot/home/config/settings/network.orig");
rename("/boot/home/config/settings/network.2", "/boot/home/config/settings/network");
app_info ai;
if (be_roster->GetAppInfo("application/x-vnd.Be-NETS", &ai) == B_OK) {
BMessenger msg(NULL, ai.team);
if (msg.IsValid()) {
while (be_roster->IsRunning("application/x-vnd.Be-NETS")) {
msg.SendMessage(B_QUIT_REQUESTED);
snooze(500000);
}
}
}
BPath path;
find_directory(B_BEOS_BOOT_DIRECTORY, &path);
path.Append("Netscript");
char *argv[3] = {"/bin/sh", (char *)path.Path(), NULL};
thread_id net_server = load_image(2, argv, environ);
resume_thread(net_server);
status_t l;
wait_for_thread(net_server, &l);
goto i_wanna_try_that_again;
}
// Set up communications with add-on
area_id handler_buffer;
if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) {
WarningAlert(GetString(STR_NET_ADDON_INIT_FAILED));
return;
}
if ((buffer_area = clone_area("local packet buffer", &net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) {
D(bug("EtherInit: couldn't clone packet area\n"));
WarningAlert(GetString(STR_NET_ADDON_CLONE_FAILED));
return;
}
if ((read_sem = create_sem(0, "ether read")) < B_NO_ERROR) {
printf("FATAL: can't create Ethernet semaphore\n");
return;
}
net_buffer_ptr->read_sem = read_sem;
write_sem = net_buffer_ptr->write_sem;
read_thread = spawn_thread(AO_receive_thread, "ether read", B_URGENT_DISPLAY_PRIORITY, NULL);
resume_thread(read_thread);
for (int i=0; i<WRITE_PACKET_COUNT; i++)
net_buffer_ptr->write[i].cmd = IN_USE | (ACTIVATE_SHEEP_NET << 8);
rd_pos = wr_pos = 0;
release_sem(write_sem);
// Everything OK
net_open = true;
}
/*
* Exit ethernet
*/
void EtherExit(void)
{
if (net_open) {
// Close communications with add-on
for (int i=0; i<WRITE_PACKET_COUNT; i++)
net_buffer_ptr->write[i].cmd = IN_USE | (DEACTIVATE_SHEEP_NET << 8);
release_sem(write_sem);
// Quit receiver thread
ether_thread_active = false;
status_t result;
release_sem(read_sem);
while (wait_for_thread(read_thread, &result) == B_INTERRUPTED) ;
delete_sem(read_sem);
delete_area(buffer_area);
}
#if STATISTICS
// Show statistics
printf("%ld messages put on write queue\n", num_wput);
printf("%ld error acks\n", num_error_acks);
printf("%ld packets transmitted (%ld raw, %ld normal)\n", num_tx_packets, num_tx_raw_packets, num_tx_normal_packets);
printf("%ld tx packets dropped because buffer full\n", num_tx_buffer_full);
printf("%ld packets received\n", num_rx_packets);
printf("%ld packets passed upstream (%ld Fast Path, %ld normal)\n", num_rx_fastpath + num_unitdata_ind, num_rx_fastpath, num_unitdata_ind);
printf("EtherIRQ called %ld times\n", num_ether_irq);
printf("%ld rx packets dropped due to low memory\n", num_rx_no_mem);
printf("%ld rx packets dropped because no stream found\n", num_rx_dropped);
printf("%ld rx packets dropped because stream not ready\n", num_rx_stream_not_ready);
printf("%ld rx packets dropped because no memory for unitdata_ind\n", num_rx_no_unitdata_mem);
#endif
}
/*
* Ask add-on for ethernet hardware address
*/
void AO_get_ethernet_address(uint32 arg)
{
uint8 *addr = Mac2HostAddr(arg);
if (net_open) {
OTCopy48BitAddress(net_buffer_ptr->ether_addr, addr);
} else {
addr[0] = 0x12;
addr[1] = 0x34;
addr[2] = 0x56;
addr[3] = 0x78;
addr[4] = 0x9a;
addr[5] = 0xbc;
}
D(bug("AO_get_ethernet_address: got address %02x%02x%02x%02x%02x%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]));
}
/*
* Tell add-on to enable multicast address
*/
void AO_enable_multicast(uint32 addr)
{
D(bug("AO_enable_multicast\n"));
if (net_open) {
net_packet *p = &net_buffer_ptr->write[wr_pos];
if (p->cmd & IN_USE) {
D(bug("WARNING: couldn't enable multicast address\n"));
} else {
Mac2host_memcpy(p->data, addr, 6);
p->length = 6;
p->cmd = IN_USE | (ADD_MULTICAST << 8);
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
release_sem(write_sem);
}
}
}
/*
* Tell add-on to disable multicast address
*/
void AO_disable_multicast(uint32 addr)
{
D(bug("AO_disable_multicast\n"));
if (net_open) {
net_packet *p = &net_buffer_ptr->write[wr_pos];
if (p->cmd & IN_USE) {
D(bug("WARNING: couldn't enable multicast address\n"));
} else {
Mac2host_memcpy(p->data, addr, 6);
p->length = 6;
p->cmd = IN_USE | (REMOVE_MULTICAST << 8);
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
release_sem(write_sem);
}
D(bug("WARNING: couldn't disable multicast address\n"));
}
}
/*
* Tell add-on to transmit one packet
*/
void AO_transmit_packet(uint32 mp_arg)
{
D(bug("AO_transmit_packet\n"));
if (net_open) {
net_packet *p = &net_buffer_ptr->write[wr_pos];
if (p->cmd & IN_USE) {
D(bug("WARNING: couldn't transmit packet (buffer full)\n"));
num_tx_buffer_full++;
} else {
D(bug(" write packet pos %d\n", i));
num_tx_packets++;
// Copy packet to buffer
uint8 *start;
uint8 *bp = start = p->data;
mblk_t *mp = Mac2HostAddr(mp_arg);
while (mp) {
uint32 size = mp->b_wptr - mp->b_rptr;
memcpy(bp, mp->b_rptr, size);
bp += size;
mp = mp->b_cont;
}
#if MONITOR
bug("Sending Ethernet packet:\n");
for (int i=0; i<(uint32)(bp - start); i++) {
bug("%02lx ", start[i]);
}
bug("\n");
#endif
// Notify add-on
p->length = (uint32)(bp - start);
p->cmd = IN_USE | (SHEEP_PACKET << 8);
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
release_sem(write_sem);
}
}
}
/*
* Packet reception thread
*/
static status_t AO_receive_thread(void *data)
{
while (ether_thread_active) {
if (net_buffer_ptr->read[rd_pos].cmd & IN_USE) {
if (ether_driver_opened) {
D(bug(" packet received, triggering Ethernet interrupt\n"));
SetInterruptFlag(INTFLAG_ETHER);
TriggerInterrupt();
}
}
acquire_sem_etc(read_sem, 1, B_TIMEOUT, 25000);
}
return 0;
}
/*
* Ethernet interrupt
*/
void EtherIRQ(void)
{
D(bug("EtherIRQ\n"));
num_ether_irq++;
OTEnterInterrupt();
// Send received packets to OpenTransport
net_packet *p = &net_buffer_ptr->read[rd_pos];
while (p->cmd & IN_USE) {
if ((p->cmd >> 8) == SHEEP_PACKET) {
num_rx_packets++;
D(bug(" read packet pos %d\n", i));
uint32 size = p->length;
#if MONITOR
bug("Receiving Ethernet packet:\n");
for (int i=0; i<size; i++) {
bug("%02lx ", p->data[i]);
}
bug("\n");
#endif
// Wrap packet in message block
//!! maybe use esballoc()
mblk_t *mp;
if ((mp = allocb(size, 0)) != NULL) {
D(bug(" packet data at %p\n", (void *)mp->b_rptr));
memcpy(mp->b_rptr, p->data, size);
mp->b_wptr += size;
ether_packet_received(mp);
} else {
D(bug("WARNING: Cannot allocate mblk for received packet\n"));
num_rx_no_mem++;
}
}
p->cmd = 0; // Free packet
rd_pos = (rd_pos + 1) % READ_PACKET_COUNT;
p = &net_buffer_ptr->read[rd_pos];
}
OTLeaveInterrupt();
}

View File

@ -1 +0,0 @@
../../../BasiliskII/src/BeOS/extfs_beos.cpp

File diff suppressed because it is too large Load Diff

View File

@ -1,112 +0,0 @@
/*
* prefs_beos.cpp - Preferences handling, BeOS specific things
*
* SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <StorageKit.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "sysdeps.h"
#include "prefs.h"
#include "main.h"
// Platform-specific preferences items
prefs_desc platform_prefs_items[] = {
{"bitbang", TYPE_BOOLEAN, false, "draw Mac desktop directly on screen in window mode"},
{"idlewait", TYPE_BOOLEAN, false, "sleep when idle"},
{NULL, TYPE_END, false, NULL} // End of list
};
// Preferences file name and path
const char PREFS_FILE_NAME[] = "SheepShaver_prefs";
static BPath prefs_path;
// Modification date of prefs file
time_t PrefsFileDate = 0;
/*
* Load preferences from settings file
*/
void LoadPrefs(const char *vmdir)
{
// Construct prefs path
find_directory(B_USER_SETTINGS_DIRECTORY, &prefs_path, true);
prefs_path.Append(PREFS_FILE_NAME);
// Read preferences from settings file
FILE *f = fopen(prefs_path.Path(), "r");
if (f == NULL) // Not found in settings directory, look in app directory
f = fopen(PREFS_FILE_NAME, "r");
if (f != NULL) {
LoadPrefsFromStream(f);
struct stat s;
fstat(fileno(f), &s);
PrefsFileDate = s.st_ctime;
fclose(f);
} else {
// No prefs file, save defaults
SavePrefs();
PrefsFileDate = real_time_clock();
}
}
/*
* Save preferences to settings file
*/
void SavePrefs(void)
{
FILE *f;
if ((f = fopen(prefs_path.Path(), "w")) != NULL) {
SavePrefsToStream(f);
fclose(f);
}
}
/*
* Add defaults of platform-specific prefs items
* You may also override the defaults set in PrefsInit()
*/
void AddPlatformPrefsDefaults(void)
{
PrefsReplaceString("extfs", "/boot");
PrefsAddInt32("windowmodes",
B_8_BIT_640x480 | B_15_BIT_640x480 | B_32_BIT_640x480 |
B_8_BIT_800x600 | B_15_BIT_800x600 | B_32_BIT_800x600
);
PrefsAddInt32("screenmodes",
B_8_BIT_640x480 | B_15_BIT_640x480 | B_32_BIT_640x480 |
B_8_BIT_800x600 | B_15_BIT_800x600 | B_32_BIT_800x600 |
B_8_BIT_1024x768 | B_15_BIT_1024x768
);
PrefsAddBool("bitbang", false);
PrefsAddBool("idlewait", true);
}

View File

@ -1,877 +0,0 @@
/*
* prefs_editor_beos.cpp - Preferences editor, BeOS implementation
*
* SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <SerialPort.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fs_info.h>
#include "prefs_editor.h"
#include "prefs.h"
#include "main.h"
#include "cdrom.h"
#include "xpram.h"
#include "about_window.h"
#include "user_strings.h"
// Special colors
const rgb_color fill_color = {216, 216, 216, 0};
const rgb_color slider_fill_color = {102, 152, 255, 0};
// Window messages
const uint32 MSG_OK = 'okok'; // "Start" clicked
const uint32 MSG_CANCEL = 'cncl'; // "Quit" clicked
const uint32 MSG_ZAP_PRAM = 'zprm';
const int NUM_PANES = 4;
const uint32 MSG_VOLUME_SELECTED = 'volu'; // "Volumes" pane
const uint32 MSG_VOLUME_INVOKED = 'voli';
const uint32 MSG_ADD_VOLUME = 'addv';
const uint32 MSG_CREATE_VOLUME = 'crev';
const uint32 MSG_REMOVE_VOLUME = 'remv';
const uint32 MSG_ADD_VOLUME_PANEL = 'advp';
const uint32 MSG_CREATE_VOLUME_PANEL = 'crvp';
const uint32 MSG_DEVICE_NAME = 'devn';
const uint32 MSG_BOOT_ANY = 'bany';
const uint32 MSG_BOOT_CDROM = 'bcdr';
const uint32 MSG_NOCDROM = 'nocd';
const uint32 MSG_REF_5HZ = ' 5Hz'; // "Graphics" pane
const uint32 MSG_REF_7_5HZ = ' 7Hz';
const uint32 MSG_REF_10HZ = '10Hz';
const uint32 MSG_REF_15HZ = '15Hz';
const uint32 MSG_REF_30HZ = '30Hz';
const uint32 MSG_GFXACCEL = 'gfac';
const uint32 MSG_WINDOW_MODE = 'wmod';
const uint32 MSG_SCREEN_MODE = 'smod';
const uint32 MSG_NOSOUND = 'nosn';
const uint32 MSG_SER_A = 'sera'; // "Serial"/"Network" pane
const uint32 MSG_SER_B = 'serb';
const uint32 MSG_NONET = 'noet';
const uint32 MSG_RAMSIZE = 'rmsz'; // "Memory" pane
const uint32 MSG_IGNORESEGV = 'isgv';
const uint32 MSG_IDLEWAIT = 'idlw';
// RAM size slider class
class RAMSlider : public BSlider {
public:
RAMSlider(BRect frame, const char *name, const char *label, BMessage *message,
int32 minValue, int32 maxValue, thumb_style thumbType = B_BLOCK_THUMB,
uint32 resizingMode = B_FOLLOW_LEFT |
B_FOLLOW_TOP,
uint32 flags = B_NAVIGABLE | B_WILL_DRAW |
B_FRAME_EVENTS) : BSlider(frame, name, label, message, minValue, maxValue, thumbType, resizingMode, flags)
{
update_text = (char *)malloc(256);
}
virtual ~RAMSlider()
{
if (update_text)
free(update_text);
}
virtual char *UpdateText(void) const
{
if (update_text) {
sprintf(update_text, GetString(STR_RAMSIZE_FMT), Value());
}
return update_text;
}
private:
char *update_text;
};
// Volumes list view class
class VolumeListView : public BListView {
public:
VolumeListView(BRect frame, const char *name, list_view_type type = B_SINGLE_SELECTION_LIST, uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE)
: BListView(frame, name, type, resizeMask, flags)
{}
// Handle dropped files and volumes
virtual void MessageReceived(BMessage *msg)
{
if (msg->what == B_SIMPLE_DATA) {
BMessage msg2(MSG_ADD_VOLUME_PANEL);
entry_ref ref;
for (int i=0; msg->FindRef("refs", i, &ref) == B_NO_ERROR; i++)
msg2.AddRef("refs", &ref);
Window()->PostMessage(&msg2);
} else
BListView::MessageReceived(msg);
}
};
// Number-entry BTextControl
class NumberControl : public BTextControl {
public:
NumberControl(BRect frame, float divider, const char *name, const char *label, long value, BMessage *message)
: BTextControl(frame, name, label, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE)
{
SetDivider(divider);
for (int c=0; c<256; c++)
if (!isdigit(c) && c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
((BTextView *)ChildAt(0))->DisallowChar(c);
SetValue(value);
}
// Set integer value
void SetValue(long value)
{
char str[32];
sprintf(str, "%ld", value);
SetText(str);
}
// Get integer value
long Value(void)
{
return atol(Text());
}
};
// Path-entry BTextControl
class PathControl : public BTextControl {
public:
PathControl(bool dir_ctrl_, BRect frame, const char *name, const char *label, const char *text, BMessage *message) : BTextControl(frame, name, label, text, message), dir_ctrl(dir_ctrl_)
{
for (int c=0; c<' '; c++)
if (c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
((BTextView *)ChildAt(0))->DisallowChar(c);
}
virtual void MessageReceived(BMessage *msg)
{
if (msg->what == B_SIMPLE_DATA) {
entry_ref the_ref;
BEntry the_entry;
// Look for dropped refs
if (msg->FindRef("refs", &the_ref) == B_NO_ERROR) {
if (the_entry.SetTo(&the_ref) == B_NO_ERROR && (dir_ctrl&& the_entry.IsDirectory() || !dir_ctrl && the_entry.IsFile())) {
BPath the_path;
the_entry.GetPath(&the_path);
SetText(the_path.Path());
}
} else
BTextControl::MessageReceived(msg);
MakeFocus();
} else
BTextControl::MessageReceived(msg);
}
private:
bool dir_ctrl;
};
// Preferences window class
class PrefsWindow : public BWindow {
public:
PrefsWindow(uint32 msg);
virtual ~PrefsWindow();
virtual void MessageReceived(BMessage *msg);
private:
BView *create_volumes_pane(void);
BView *create_graphics_pane(void);
BView *create_serial_pane(void);
BView *create_memory_pane(void);
uint32 ok_message;
bool send_quit_on_close;
BMessenger this_messenger;
BView *top;
BRect top_frame;
BTabView *pane_tabs;
BView *panes[NUM_PANES];
int current_pane;
VolumeListView *volume_list;
BCheckBox *nocdrom_checkbox;
BCheckBox *gfxaccel_checkbox;
BCheckBox *nosound_checkbox;
BCheckBox *nonet_checkbox;
BCheckBox *ignoresegv_checkbox;
BCheckBox *idlewait_checkbox;
RAMSlider *ramsize_slider;
PathControl *extfs_control;
PathControl *rom_control;
BFilePanel *add_volume_panel;
BFilePanel *create_volume_panel;
uint32 max_ramsize; // In MB
};
/*
* Show preferences editor
* When the user clicks on "OK", the message given as parameter is sent
* to the application; if he clicks on "Quit", B_QUIT_REQUESTED is sent
*/
void PrefsEditor(uint32 msg)
{
new PrefsWindow(msg);
}
/*
* Preferences window constructor
*/
PrefsWindow::PrefsWindow(uint32 msg) : BWindow(BRect(0, 0, 400, 289), GetString(STR_PREFS_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS), this_messenger(this)
{
int i;
ok_message = msg;
send_quit_on_close = true;
// Move window to right position
Lock();
MoveTo(80, 80);
// Set up menus
BMenuBar *bar = new BMenuBar(Bounds(), "menu");
BMenu *menu = new BMenu(GetString(STR_PREFS_MENU));
menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ABOUT), new BMessage(B_ABOUT_REQUESTED)));
menu->AddItem(new BSeparatorItem);
menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_START), new BMessage(MSG_OK)));
menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ZAP_PRAM), new BMessage(MSG_ZAP_PRAM)));
menu->AddItem(new BSeparatorItem);
menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_QUIT), new BMessage(MSG_CANCEL), 'Q'));
bar->AddItem(menu);
AddChild(bar);
SetKeyMenuBar(bar);
int mbar_height = bar->Bounds().bottom + 1;
// Resize window to fit menu bar
ResizeBy(0, mbar_height);
// Light gray background
BRect b = Bounds();
top = new BView(BRect(0, mbar_height, b.right, b.bottom), "top", B_FOLLOW_NONE, B_WILL_DRAW);
AddChild(top);
top->SetViewColor(fill_color);
top_frame = top->Bounds();
// Create panes
panes[0] = create_volumes_pane();
panes[1] = create_graphics_pane();
panes[2] = create_serial_pane();
panes[3] = create_memory_pane();
// Prefs item tab view
pane_tabs = new BTabView(BRect(10, 10, top_frame.right-10, top_frame.bottom-50), "items", B_WIDTH_FROM_LABEL);
for (i=0; i<NUM_PANES; i++)
pane_tabs->AddTab(panes[i]);
top->AddChild(pane_tabs);
volume_list->Select(0);
// Create volume file panels
add_volume_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_ADD_VOLUME_PANEL));
add_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_ADD_VOLUME_PANEL_BUTTON));
add_volume_panel->Window()->SetTitle(GetString(STR_ADD_VOLUME_TITLE));
create_volume_panel = new BFilePanel(B_SAVE_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_CREATE_VOLUME_PANEL));
create_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_CREATE_VOLUME_PANEL_BUTTON));
create_volume_panel->Window()->SetTitle(GetString(STR_CREATE_VOLUME_TITLE));
create_volume_panel->Window()->Lock();
BView *background = create_volume_panel->Window()->ChildAt(0);
background->FindView("PoseView")->ResizeBy(0, -30);
background->FindView("VScrollBar")->ResizeBy(0, -30);
background->FindView("CountVw")->MoveBy(0, -30);
BView *v = background->FindView("HScrollBar");
if (v)
v->MoveBy(0, -30);
else {
i = 0;
while ((v = background->ChildAt(i++)) != NULL) {
if (v->Name() == NULL || v->Name()[0] == 0) {
v->MoveBy(0, -30); // unnamed horizontal scroll bar
break;
}
}
}
BView *filename = background->FindView("text view");
BRect fnr(filename->Frame());
fnr.OffsetBy(0, -30);
NumberControl *nc = new NumberControl(fnr, 80, "hardfile_size", GetString(STR_HARDFILE_SIZE_CTRL), 40, NULL);
background->AddChild(nc);
create_volume_panel->Window()->Unlock();
// "Start" button
BButton *button = new BButton(BRect(20, top_frame.bottom-35, 90, top_frame.bottom-10), "start", GetString(STR_START_BUTTON), new BMessage(MSG_OK));
top->AddChild(button);
SetDefaultButton(button);
// "Quit" button
top->AddChild(new BButton(BRect(top_frame.right-90, top_frame.bottom-35, top_frame.right-20, top_frame.bottom-10), "cancel", GetString(STR_QUIT_BUTTON), new BMessage(MSG_CANCEL)));
Unlock();
Show();
}
/*
* Preferences window destructor
*/
PrefsWindow::~PrefsWindow()
{
delete add_volume_panel;
if (send_quit_on_close)
be_app->PostMessage(B_QUIT_REQUESTED);
}
/*
* Create "Volumes" pane
*/
BView *PrefsWindow::create_volumes_pane(void)
{
BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_VOLUMES_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
pane->SetViewColor(fill_color);
float right = pane->Bounds().right-10;
const char *str;
int32 index = 0;
volume_list = new VolumeListView(BRect(15, 10, pane->Bounds().right-30, 108), "volumes");
while ((str = PrefsFindString("disk", index++)) != NULL)
volume_list->AddItem(new BStringItem(str));
volume_list->SetSelectionMessage(new BMessage(MSG_VOLUME_SELECTED));
volume_list->SetInvocationMessage(new BMessage(MSG_VOLUME_INVOKED));
pane->AddChild(new BScrollView("volumes_border", volume_list, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true));
pane->AddChild(new BButton(BRect(10, 113, pane->Bounds().right/3, 133), "add_volume", GetString(STR_ADD_VOLUME_BUTTON), new BMessage(MSG_ADD_VOLUME)));
pane->AddChild(new BButton(BRect(pane->Bounds().right/3, 113, pane->Bounds().right*2/3, 133), "create_volume", GetString(STR_CREATE_VOLUME_BUTTON), new BMessage(MSG_CREATE_VOLUME)));
pane->AddChild(new BButton(BRect(pane->Bounds().right*2/3, 113, pane->Bounds().right-11, 133), "remove_volume", GetString(STR_REMOVE_VOLUME_BUTTON), new BMessage(MSG_REMOVE_VOLUME)));
extfs_control = new PathControl(true, BRect(10, 145, right, 160), "extfs", GetString(STR_EXTFS_CTRL), PrefsFindString("extfs"), NULL);
extfs_control->SetDivider(90);
pane->AddChild(extfs_control);
BMenuField *menu_field;
BPopUpMenu *menu = new BPopUpMenu("");
menu_field = new BMenuField(BRect(10, 165, right, 180), "bootdriver", GetString(STR_BOOTDRIVER_CTRL), menu);
menu_field->SetDivider(90);
menu->AddItem(new BMenuItem(GetString(STR_BOOT_ANY_LAB), new BMessage(MSG_BOOT_ANY)));
menu->AddItem(new BMenuItem(GetString(STR_BOOT_CDROM_LAB), new BMessage(MSG_BOOT_CDROM)));
pane->AddChild(menu_field);
int16 i16 = PrefsFindInt32("bootdriver");
BMenuItem *item;
if (i16 == 0) {
if ((item = menu->FindItem(GetString(STR_BOOT_ANY_LAB))) != NULL)
item->SetMarked(true);
} else if (i16 == CDROMRefNum) {
if ((item = menu->FindItem(GetString(STR_BOOT_CDROM_LAB))) != NULL)
item->SetMarked(true);
}
nocdrom_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nocdrom", GetString(STR_NOCDROM_CTRL), new BMessage(MSG_NOCDROM));
pane->AddChild(nocdrom_checkbox);
nocdrom_checkbox->SetValue(PrefsFindBool("nocdrom") ? B_CONTROL_ON : B_CONTROL_OFF);
return pane;
}
/*
* Create "Graphics/Sound" pane
*/
struct video_mode_box {
uint32 mode;
int mode_string_id, bit_string_id;
float left, top;
BCheckBox *box;
};
const int NUM_WINDOW_MODES = 6;
const int NUM_SCREEN_MODES = 18;
static video_mode_box window_mode_boxes[NUM_SCREEN_MODES] = {
{B_8_BIT_640x480, STR_W_640x480_CTRL, STR_8_BIT_CTRL, 140, 48, NULL},
{B_15_BIT_640x480, STR_W_640x480_CTRL, STR_16_BIT_CTRL, 220, 48, NULL},
{B_32_BIT_640x480, STR_W_640x480_CTRL, STR_32_BIT_CTRL, 300, 48, NULL},
{B_8_BIT_800x600, STR_W_800x600_CTRL, STR_8_BIT_CTRL, 140, 65, NULL},
{B_15_BIT_800x600, STR_W_800x600_CTRL, STR_16_BIT_CTRL, 220, 65, NULL},
{B_32_BIT_800x600, STR_W_800x600_CTRL, STR_32_BIT_CTRL, 300, 65, NULL},
};
static video_mode_box screen_mode_boxes[NUM_SCREEN_MODES] = {
{B_8_BIT_640x480, STR_640x480_CTRL, STR_8_BIT_CTRL, 140, 82, NULL},
{B_15_BIT_640x480, STR_640x480_CTRL, STR_16_BIT_CTRL, 220, 82, NULL},
{B_32_BIT_640x480, STR_640x480_CTRL, STR_32_BIT_CTRL, 300, 82, NULL},
{B_8_BIT_800x600, STR_800x600_CTRL, STR_8_BIT_CTRL, 140, 99, NULL},
{B_15_BIT_800x600, STR_800x600_CTRL, STR_16_BIT_CTRL, 220, 99, NULL},
{B_32_BIT_800x600, STR_800x600_CTRL, STR_32_BIT_CTRL, 300, 99, NULL},
{B_8_BIT_1024x768, STR_1024x768_CTRL, STR_8_BIT_CTRL, 140, 116, NULL},
{B_15_BIT_1024x768, STR_1024x768_CTRL, STR_16_BIT_CTRL, 220, 116, NULL},
{B_32_BIT_1024x768, STR_1024x768_CTRL, STR_32_BIT_CTRL, 300, 116, NULL},
{B_8_BIT_1152x900, STR_1152x900_CTRL, STR_8_BIT_CTRL, 140, 133, NULL},
{B_15_BIT_1152x900, STR_1152x900_CTRL, STR_16_BIT_CTRL, 220, 133, NULL},
{B_32_BIT_1152x900, STR_1152x900_CTRL, STR_32_BIT_CTRL, 300, 133, NULL},
{B_8_BIT_1280x1024, STR_1280x1024_CTRL, STR_8_BIT_CTRL, 140, 150, NULL},
{B_15_BIT_1280x1024, STR_1280x1024_CTRL, STR_16_BIT_CTRL, 220, 150, NULL},
{B_32_BIT_1280x1024, STR_1280x1024_CTRL, STR_32_BIT_CTRL, 300, 150, NULL},
{B_8_BIT_1600x1200, STR_1600x1200_CTRL, STR_8_BIT_CTRL, 140, 167, NULL},
{B_15_BIT_1600x1200, STR_1600x1200_CTRL, STR_16_BIT_CTRL, 220, 167, NULL},
{B_32_BIT_1600x1200, STR_1600x1200_CTRL, STR_32_BIT_CTRL, 300, 167, NULL}
};
BView *PrefsWindow::create_graphics_pane(void)
{
BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_GRAPHICS_SOUND_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
pane->SetViewColor(fill_color);
float right = pane->Bounds().right-10;
BMenuField *menu_field;
BPopUpMenu *menu = new BPopUpMenu("");
menu_field = new BMenuField(BRect(10, 5, right, 20), "frameskip", GetString(STR_FRAMESKIP_CTRL), menu);
menu_field->SetDivider(120);
menu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ)));
menu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ)));
menu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ)));
menu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ)));
menu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ)));
pane->AddChild(menu_field);
int32 i32 = PrefsFindInt32("frameskip");
BMenuItem *item;
if (i32 == 12) {
if ((item = menu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL)
item->SetMarked(true);
} else if (i32 == 8) {
if ((item = menu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL)
item->SetMarked(true);
} else if (i32 == 6) {
if ((item = menu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL)
item->SetMarked(true);
} else if (i32 == 4) {
if ((item = menu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL)
item->SetMarked(true);
} else if (i32 == 2) {
if ((item = menu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL)
item->SetMarked(true);
}
gfxaccel_checkbox = new BCheckBox(BRect(10, 25, right, 40), "gfxaccel", GetString(STR_GFXACCEL_CTRL), new BMessage(MSG_GFXACCEL));
pane->AddChild(gfxaccel_checkbox);
gfxaccel_checkbox->SetValue(PrefsFindBool("gfxaccel") ? B_CONTROL_ON : B_CONTROL_OFF);
uint32 window_modes = PrefsFindInt32("windowmodes");
for (int i=0; i<NUM_WINDOW_MODES; i++) {
video_mode_box *p = window_mode_boxes + i;
if (p->bit_string_id == STR_8_BIT_CTRL) {
BStringView *text = new BStringView(BRect(10, p->top, 120, p->top + 15), "", GetString(p->mode_string_id));
pane->AddChild(text);
}
p->box = new BCheckBox(BRect(p->left, p->top, p->left + 80, p->top + 15), "", GetString(p->bit_string_id), new BMessage(MSG_WINDOW_MODE));
pane->AddChild(p->box);
p->box->SetValue(window_modes & p->mode ? B_CONTROL_ON : B_CONTROL_OFF);
}
uint32 screen_modes = PrefsFindInt32("screenmodes");
for (int i=0; i<NUM_SCREEN_MODES; i++) {
video_mode_box *p = screen_mode_boxes + i;
if (p->bit_string_id == STR_8_BIT_CTRL) {
BStringView *text = new BStringView(BRect(10, p->top, 120, p->top + 15), "", GetString(p->mode_string_id));
pane->AddChild(text);
}
p->box = new BCheckBox(BRect(p->left, p->top, p->left + 80, p->top + 15), "", GetString(p->bit_string_id), new BMessage(MSG_SCREEN_MODE));
pane->AddChild(p->box);
p->box->SetValue(screen_modes & p->mode ? B_CONTROL_ON : B_CONTROL_OFF);
}
nosound_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nosound", GetString(STR_NOSOUND_CTRL), new BMessage(MSG_NOSOUND));
pane->AddChild(nosound_checkbox);
nosound_checkbox->SetValue(PrefsFindBool("nosound") ? B_CONTROL_ON : B_CONTROL_OFF);
return pane;
}
/*
* Create "Serial/Network" pane
*/
static void add_serial_names(BPopUpMenu *menu, uint32 msg)
{
BSerialPort *port = new BSerialPort;
char name[B_PATH_NAME_LENGTH];
for (int i=0; i<port->CountDevices(); i++) {
port->GetDeviceName(i, name);
menu->AddItem(new BMenuItem(name, new BMessage(msg)));
}
if (SysInfo.platform_type == B_BEBOX_PLATFORM) {
BDirectory dir;
BEntry entry;
dir.SetTo("/dev/parallel");
if (dir.InitCheck() == B_NO_ERROR) {
dir.Rewind();
while (dir.GetNextEntry(&entry) >= 0) {
if (!entry.IsDirectory()) {
entry.GetName(name);
menu->AddItem(new BMenuItem(name, new BMessage(msg)));
}
}
}
}
delete port;
}
static void set_serial_label(BPopUpMenu *menu, const char *prefs_name)
{
const char *str;
BMenuItem *item;
if ((str = PrefsFindString(prefs_name)) != NULL)
if ((item = menu->FindItem(str)) != NULL)
item->SetMarked(true);
}
BView *PrefsWindow::create_serial_pane(void)
{
BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_SERIAL_NETWORK_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
pane->SetViewColor(fill_color);
float right = pane->Bounds().right-10;
BMenuField *menu_field;
BPopUpMenu *menu_a = new BPopUpMenu("");
add_serial_names(menu_a, MSG_SER_A);
menu_field = new BMenuField(BRect(10, 5, right, 20), "seriala", GetString(STR_SERPORTA_CTRL), menu_a);
menu_field->SetDivider(90);
pane->AddChild(menu_field);
set_serial_label(menu_a, "seriala");
BPopUpMenu *menu_b = new BPopUpMenu("");
add_serial_names(menu_b, MSG_SER_B);
menu_field = new BMenuField(BRect(10, 26, right, 41), "serialb", GetString(STR_SERPORTB_CTRL), menu_b);
menu_field->SetDivider(90);
pane->AddChild(menu_field);
set_serial_label(menu_b, "serialb");
nonet_checkbox = new BCheckBox(BRect(10, 47, right, 62), "nonet", GetString(STR_NONET_CTRL), new BMessage(MSG_NONET));
pane->AddChild(nonet_checkbox);
nonet_checkbox->SetValue(PrefsFindBool("nonet") ? B_CONTROL_ON : B_CONTROL_OFF);
return pane;
}
/*
* Create "Memory/Misc" pane
*/
BView *PrefsWindow::create_memory_pane(void)
{
char str[256], str2[256];
BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_MEMORY_MISC_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
pane->SetViewColor(fill_color);
float right = pane->Bounds().right-10;
BEntry entry("/boot/var/swap");
off_t swap_space;
if (entry.GetSize(&swap_space) == B_NO_ERROR)
max_ramsize = swap_space / (1024 * 1024) - 8;
else
max_ramsize = SysInfo.max_pages * B_PAGE_SIZE / (1024 * 1024) - 8;
int32 value = PrefsFindInt32("ramsize") / (1024 * 1024);
ramsize_slider = new RAMSlider(BRect(10, 5, right, 55), "ramsize", GetString(STR_RAMSIZE_SLIDER), new BMessage(MSG_RAMSIZE), 8, max_ramsize, B_TRIANGLE_THUMB);
ramsize_slider->SetValue(value);
ramsize_slider->UseFillColor(true, &slider_fill_color);
sprintf(str, GetString(STR_RAMSIZE_FMT), 8);
sprintf(str2, GetString(STR_RAMSIZE_FMT), max_ramsize);
ramsize_slider->SetLimitLabels(str, str2);
pane->AddChild(ramsize_slider);
ignoresegv_checkbox = new BCheckBox(BRect(10, 60, right, 75), "ignoresegv", GetString(STR_IGNORESEGV_CTRL), new BMessage(MSG_IGNORESEGV));
pane->AddChild(ignoresegv_checkbox);
ignoresegv_checkbox->SetValue(PrefsFindBool("ignoresegv") ? B_CONTROL_ON : B_CONTROL_OFF);
idlewait_checkbox = new BCheckBox(BRect(10, 80, right, 95), "idlewait", GetString(STR_IDLEWAIT_CTRL), new BMessage(MSG_IDLEWAIT));
pane->AddChild(idlewait_checkbox);
idlewait_checkbox->SetValue(PrefsFindBool("idlewait") ? B_CONTROL_ON : B_CONTROL_OFF);
rom_control = new PathControl(false, BRect(10, 100, right, 115), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL);
rom_control->SetDivider(117);
pane->AddChild(rom_control);
return pane;
}
/*
* Message from controls/menus received
*/
void PrefsWindow::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case MSG_OK: // "Start" button clicked
PrefsReplaceString("extfs", extfs_control->Text());
const char *str = rom_control->Text();
if (strlen(str))
PrefsReplaceString("rom", str);
else
PrefsRemoveItem("rom");
SavePrefs();
send_quit_on_close = false;
PostMessage(B_QUIT_REQUESTED);
be_app->PostMessage(ok_message);
break;
case MSG_CANCEL: // "Quit" button clicked
send_quit_on_close = false;
PostMessage(B_QUIT_REQUESTED);
be_app->PostMessage(B_QUIT_REQUESTED);
break;
case B_ABOUT_REQUESTED: // "About" menu item selected
OpenAboutWindow();
break;
case MSG_ZAP_PRAM: // "Zap PRAM File" menu item selected
ZapPRAM();
break;
case MSG_VOLUME_INVOKED: { // Double-clicked on volume name, toggle read-only flag
int selected = volume_list->CurrentSelection();
if (selected >= 0) {
const char *str = PrefsFindString("disk", selected);
BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected);
delete item;
char newstr[256];
if (str[0] == '*')
strcpy(newstr, str+1);
else {
strcpy(newstr, "*");
strcat(newstr, str);
}
PrefsReplaceString("disk", newstr, selected);
volume_list->AddItem(new BStringItem(newstr), selected);
volume_list->Select(selected);
}
break;
}
case MSG_ADD_VOLUME:
add_volume_panel->Show();
break;
case MSG_CREATE_VOLUME:
create_volume_panel->Show();
break;
case MSG_ADD_VOLUME_PANEL: {
entry_ref ref;
if (msg->FindRef("refs", &ref) == B_NO_ERROR) {
BEntry entry(&ref, true);
BPath path;
entry.GetPath(&path);
if (entry.IsFile()) {
PrefsAddString("disk", path.Path());
volume_list->AddItem(new BStringItem(path.Path()));
} else if (entry.IsDirectory()) {
BVolume volume;
if (path.Path()[0] == '/' && strchr(path.Path()+1, '/') == NULL && entry.GetVolume(&volume) == B_NO_ERROR) {
int32 i = 0;
dev_t d;
fs_info info;
while ((d = next_dev(&i)) >= 0) {
fs_stat_dev(d, &info);
if (volume.Device() == info.dev) {
PrefsAddString("disk", info.device_name);
volume_list->AddItem(new BStringItem(info.device_name));
}
}
}
}
}
break;
}
case MSG_CREATE_VOLUME_PANEL: {
entry_ref dir;
if (msg->FindRef("directory", &dir) == B_NO_ERROR) {
BEntry entry(&dir, true);
BPath path;
entry.GetPath(&path);
path.Append(msg->FindString("name"));
create_volume_panel->Window()->Lock();
BView *background = create_volume_panel->Window()->ChildAt(0);
NumberControl *v = (NumberControl *)background->FindView("hardfile_size");
int size = v->Value();
char cmd[1024];
sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", path.Path(), size);
int ret = system(cmd);
if (ret == 0) {
PrefsAddString("disk", path.Path());
volume_list->AddItem(new BStringItem(path.Path()));
} else {
sprintf(cmd, GetString(STR_CREATE_VOLUME_WARN), strerror(ret));
WarningAlert(cmd);
}
}
break;
}
case MSG_REMOVE_VOLUME: {
int selected = volume_list->CurrentSelection();
if (selected >= 0) {
PrefsRemoveItem("disk", selected);
BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected);
delete item;
volume_list->Select(selected);
}
break;
}
case MSG_BOOT_ANY:
PrefsReplaceInt32("bootdriver", 0);
break;
case MSG_BOOT_CDROM:
PrefsReplaceInt32("bootdriver", CDROMRefNum);
break;
case MSG_NOCDROM:
PrefsReplaceBool("nocdrom", nocdrom_checkbox->Value() == B_CONTROL_ON);
break;
case MSG_GFXACCEL:
PrefsReplaceBool("gfxaccel", gfxaccel_checkbox->Value() == B_CONTROL_ON);
break;
case MSG_NOSOUND:
PrefsReplaceBool("nosound", nosound_checkbox->Value() == B_CONTROL_ON);
break;
case MSG_WINDOW_MODE: {
BCheckBox *source = NULL;
msg->FindPointer("source", &source);
if (source == NULL)
break;
for (int i=0; i<NUM_WINDOW_MODES; i++) {
video_mode_box *p = window_mode_boxes + i;
if (p->box == source) {
if (p->box->Value() == B_CONTROL_ON)
PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") | p->mode);
else
PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") & ~(p->mode));
break;
}
}
break;
}
case MSG_SCREEN_MODE: {
BCheckBox *source = NULL;
msg->FindPointer("source", &source);
if (source == NULL)
break;
for (int i=0; i<NUM_SCREEN_MODES; i++) {
video_mode_box *p = screen_mode_boxes + i;
if (p->box == source) {
if (p->box->Value() == B_CONTROL_ON)
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | p->mode);
else
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~(p->mode));
break;
}
}
break;
}
case MSG_REF_5HZ:
PrefsReplaceInt32("frameskip", 12);
break;
case MSG_REF_7_5HZ:
PrefsReplaceInt32("frameskip", 8);
break;
case MSG_REF_10HZ:
PrefsReplaceInt32("frameskip", 6);
break;
case MSG_REF_15HZ:
PrefsReplaceInt32("frameskip", 4);
break;
case MSG_REF_30HZ:
PrefsReplaceInt32("frameskip", 2);
break;
case MSG_SER_A: {
BMenuItem *source = NULL;
msg->FindPointer("source", &source);
if (source)
PrefsReplaceString("seriala", source->Label());
break;
}
case MSG_SER_B: {
BMenuItem *source = NULL;
msg->FindPointer("source", &source);
if (source)
PrefsReplaceString("serialb", source->Label());
break;
}
case MSG_NONET:
PrefsReplaceBool("nonet", nonet_checkbox->Value() == B_CONTROL_ON);
break;
case MSG_IGNORESEGV:
PrefsReplaceBool("ignoresegv", ignoresegv_checkbox->Value() == B_CONTROL_ON);
break;
case MSG_IDLEWAIT:
PrefsReplaceBool("idlewait", idlewait_checkbox->Value() == B_CONTROL_ON);
break;
case MSG_RAMSIZE:
PrefsReplaceInt32("ramsize", ramsize_slider->Value() * 1024 * 1024);
break;
default:
BWindow::MessageReceived(msg);
}
}

View File

@ -1 +0,0 @@
../../../BasiliskII/src/BeOS/scsi_beos.cpp

View File

@ -1 +0,0 @@
../../../BasiliskII/src/BeOS/serial_beos.cpp

View File

@ -1 +0,0 @@
../../../BasiliskII/src/BeOS/sys_beos.cpp

View File

@ -1,74 +0,0 @@
/*
* sysdeps.h - System dependent definitions for BeOS
*
* SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SYSDEPS_H
#define SYSDEPS_H
// Do we have std namespace?
#ifdef __POWERPC__
#define NO_STD_NAMESPACE
#endif
#include <assert.h>
#include <sys/types.h>
#include <KernelKit.h>
#include "user_strings_beos.h"
// Are we using a PPC emulator or the real thing?
#ifdef __POWERPC__
#define EMULATED_PPC 0
#define WORDS_BIGENDIAN 1
#define SYSTEM_CLOBBERS_R2 1
#else
#define EMULATED_PPC 1
#undef WORDS_BIGENDIAN
#endif
// High precision timing
#define PRECISE_TIMING 1
#define PRECISE_TIMING_BEOS 1
#define POWERPC_ROM 1
// Time data type for Time Manager emulation
typedef bigtime_t tm_time_t;
// 64 bit file offsets
typedef off_t loff_t;
// Data types
typedef uint32 uintptr;
typedef int32 intptr;
// Timing functions
extern void Delay_usec(uint32 usec);
// Macro for calling MacOS routines
#define CallMacOS(type, proc) (*(type)proc)()
#define CallMacOS1(type, proc, arg1) (*(type)proc)(arg1)
#define CallMacOS2(type, proc, arg1, arg2) (*(type)proc)(arg1, arg2)
#define CallMacOS3(type, proc, arg1, arg2, arg3) (*(type)proc)(arg1, arg2, arg3)
#define CallMacOS4(type, proc, arg1, arg2, arg3, arg4) (*(type)proc)(arg1, arg2, arg3, arg4)
#define CallMacOS5(type, proc, arg1, arg2, arg3, arg4, arg5) (*(type)proc)(arg1, arg2, arg3, arg4, arg5)
#define CallMacOS6(type, proc, arg1, arg2, arg3, arg4, arg5, arg6) (*(type)proc)(arg1, arg2, arg3, arg4, arg5, arg6)
#define CallMacOS7(type, proc, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (*(type)proc)(arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#endif

Some files were not shown because too many files have changed in this diff Show More