예제 #1
0
static void write_prefs(FILE *f, const prefs_desc *list)
{
	while (list->type != TYPE_ANY) {
		switch (list->type) {
			case TYPE_STRING: {
				int index = 0;
				const char *str;
				while ((str = PrefsFindString(list->name, index++)) != NULL)
					fprintf(f, "%s %s\n", list->name, str);
				break;
			}
			case TYPE_BOOLEAN:
				fprintf(f, "%s %s\n", list->name, PrefsFindBool(list->name) ? "true" : "false");
				break;
			case TYPE_INT16:
				fprintf(f, "%s %d\n", list->name, PrefsFindInt16(list->name));
				break;
			case TYPE_INT32:
				fprintf(f, "%s %ld\n", list->name, PrefsFindInt32(list->name));
				break;
			default:
				break;
		}
		list++;
	}
}
예제 #2
0
void MacWindow::WindowActivated(bool active)
{
	if (active) {
		frame_skip = PrefsFindInt32("frameskip");
		if (frame_skip == 0)
			frame_skip = 1;
	} else
		frame_skip = 12;	// 5Hz in background
}
예제 #3
0
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, 113), "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, 118, pane->Bounds().right/3, 138), "add_volume", GetString(STR_ADD_VOLUME_BUTTON), new BMessage(MSG_ADD_VOLUME)));
	pane->AddChild(new BButton(BRect(pane->Bounds().right/3, 118, pane->Bounds().right*2/3, 138), "create_volume", GetString(STR_CREATE_VOLUME_BUTTON), new BMessage(MSG_CREATE_VOLUME)));
	pane->AddChild(new BButton(BRect(pane->Bounds().right*2/3, 118, pane->Bounds().right-11, 138), "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);
	int32 i32 = PrefsFindInt32("bootdriver");
	BMenuItem *item;
	if (i32 == 0) {
		if ((item = menu->FindItem(GetString(STR_BOOT_ANY_LAB))) != NULL)
			item->SetMarked(true);
	} else if (i32 == 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;
}
예제 #4
0
int main(int argc, char **argv)
{
	char str[256];
	int16 i16;
	HANDLE rom_fh;
	const char *rom_path;
	uint32 rom_size;
	DWORD actual;
	uint8 *rom_tmp;

	// Initialize variables
	RAMBase = 0;

	// Print some info
	printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
	printf(" %s\n", GetString(STR_ABOUT_TEXT2));

	// Read preferences
	PrefsInit(NULL, argc, argv);

	// Parse command line arguments
	for (int i=1; i<argc; i++) {
		if (strcmp(argv[i], "--help") == 0) {
			usage(argv[0]);
		} else if (argv[i][0] == '-') {
			fprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
			usage(argv[0]);
		}
	}

	// Check we are using a Windows NT kernel >= 4.0
	OSVERSIONINFO osvi;
	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	if (!GetVersionEx(&osvi)) {
		ErrorAlert("Could not determine OS type");
		QuitEmulator();
	}
	win_os = osvi.dwPlatformId;
	win_os_major = osvi.dwMajorVersion;
	if (win_os != VER_PLATFORM_WIN32_NT || win_os_major < 4) {
		ErrorAlert(GetString(STR_NO_WIN32_NT_4));
		QuitEmulator();
	}

	// Check that drivers are installed
	if (!check_drivers())
		QuitEmulator();

	// Load win32 libraries
	KernelInit();

	// FIXME: default to DIB driver
	if (getenv("SDL_VIDEODRIVER") == NULL)
	    putenv("SDL_VIDEODRIVER=windib");

	// Initialize SDL system
	int sdl_flags = 0;
#ifdef USE_SDL_VIDEO
	sdl_flags |= SDL_INIT_VIDEO;
#endif
#ifdef USE_SDL_AUDIO
	sdl_flags |= SDL_INIT_AUDIO;
#endif
	assert(sdl_flags != 0);
	if (SDL_Init(sdl_flags) == -1) {
		char str[256];
		sprintf(str, "Could not initialize SDL: %s.\n", SDL_GetError());
		ErrorAlert(str);
		goto quit;
	}
	atexit(SDL_Quit);

#ifdef ENABLE_MON
	// Initialize mon
	mon_init();
#endif

	// Install SIGSEGV handler for CPU emulator
	if (!sigsegv_install_handler(sigsegv_handler)) {
		sprintf(str, GetString(STR_SIGSEGV_INSTALL_ERR), strerror(errno));
		ErrorAlert(str);
		goto quit;
	}

	// Initialize VM system
	vm_init();

	// Get system info
	PVR = 0x00040000;			// Default: 604
	CPUClockSpeed = 100000000;	// Default: 100MHz
	BusClockSpeed = 100000000;	// Default: 100MHz
	TimebaseSpeed =  25000000;	// Default:  25MHz
	PVR = 0x000c0000;			// Default: 7400 (with AltiVec)
	D(bug("PVR: %08x (assumed)\n", PVR));

	// Init system routines
	SysInit();

	// Show preferences editor
	if (!PrefsFindBool("nogui"))
		if (!PrefsEditor())
			goto quit;

	// Create areas for Kernel Data
	if (!kernel_data_init())
		goto quit;
	kernel_data = (KernelData *)Mac2HostAddr(KERNEL_DATA_BASE);
	emulator_data = &kernel_data->ed;
	KernelDataAddr = KERNEL_DATA_BASE;
	D(bug("Kernel Data at %p (%08x)\n", kernel_data, KERNEL_DATA_BASE));
	D(bug("Emulator Data at %p (%08x)\n", emulator_data, KERNEL_DATA_BASE + offsetof(KernelData, ed)));

	// Create area for DR Cache
	if (vm_mac_acquire(DR_EMULATOR_BASE, DR_EMULATOR_SIZE) < 0) {
		sprintf(str, GetString(STR_DR_EMULATOR_MMAP_ERR), strerror(errno));
		ErrorAlert(str);
		goto quit;
	}
	dr_emulator_area_mapped = true;
	if (vm_mac_acquire(DR_CACHE_BASE, DR_CACHE_SIZE) < 0) {
		sprintf(str, GetString(STR_DR_CACHE_MMAP_ERR), strerror(errno));
		ErrorAlert(str);
		goto quit;
	}
	dr_cache_area_mapped = true;
	DRCacheAddr = (uint32)Mac2HostAddr(DR_CACHE_BASE);
	D(bug("DR Cache at %p (%08x)\n", DRCacheAddr, DR_CACHE_BASE));

	// Create area for SheepShaver data
	if (!SheepMem::Init()) {
		sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno));
		ErrorAlert(str);
		goto quit;
	}

	// Create area for Mac ROM
	if (vm_mac_acquire(ROM_BASE, ROM_AREA_SIZE) < 0) {
		sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno));
		ErrorAlert(str);
		goto quit;
	}
	ROMBase = ROM_BASE;
	ROMBaseHost = Mac2HostAddr(ROMBase);
	rom_area_mapped = true;
	D(bug("ROM area at %p (%08x)\n", ROMBaseHost, ROMBase));

	// Create area for Mac RAM
	RAMSize = PrefsFindInt32("ramsize");
	if (RAMSize < 8*1024*1024) {
		WarningAlert(GetString(STR_SMALL_RAM_WARN));
		RAMSize = 8*1024*1024;
	}
	RAMBase = 0;
	if (vm_mac_acquire(RAMBase, RAMSize) < 0) {
		sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno));
		ErrorAlert(str);
		goto quit;
	}
	RAMBaseHost = Mac2HostAddr(RAMBase);
	ram_area_mapped = true;
	D(bug("RAM area at %p (%08x)\n", RAMBaseHost, RAMBase));

	if (RAMBase > ROMBase) {
		ErrorAlert(GetString(STR_RAM_HIGHER_THAN_ROM_ERR));
		goto quit;
	}

	// Load Mac ROM
	rom_path = PrefsFindString("rom");
	rom_fh = CreateFile(rom_path && *rom_path ? rom_path : ROM_FILE_NAME,
						GENERIC_READ, 0, NULL, OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL, NULL);

	if (rom_fh == INVALID_HANDLE_VALUE) {
		rom_fh = CreateFile(ROM_FILE_NAME2,
							GENERIC_READ, 0, NULL, OPEN_EXISTING,
							FILE_ATTRIBUTE_NORMAL, NULL);

		if (rom_fh == INVALID_HANDLE_VALUE) {
			ErrorAlert(GetString(STR_NO_ROM_FILE_ERR));
			goto quit;
		}
	}
	printf(GetString(STR_READING_ROM_FILE));
	rom_size = GetFileSize(rom_fh, NULL);
	rom_tmp = new uint8[ROM_SIZE];
	ReadFile(rom_fh, (void *)rom_tmp, ROM_SIZE, &actual, NULL);
	CloseHandle(rom_fh);
	
	// Decode Mac ROM
	if (!DecodeROM(rom_tmp, actual)) {
		if (rom_size != 4*1024*1024) {
			ErrorAlert(GetString(STR_ROM_SIZE_ERR));
			goto quit;
		} else {
			ErrorAlert(GetString(STR_ROM_FILE_READ_ERR));
			goto quit;
		}
	}
	delete[] rom_tmp;
	
	// Initialize native timers
	timer_init();

	// Initialize everything
	if (!InitAll(NULL))
		goto quit;
	D(bug("Initialization complete\n"));

	// Write protect ROM
	vm_protect(ROMBaseHost, ROM_AREA_SIZE, VM_PAGE_READ);

	// Start 60Hz thread
	tick_thread_cancel = false;
	tick_thread_active = ((tick_thread = create_thread(tick_func)) != NULL);
	SetThreadPriority(tick_thread, THREAD_PRIORITY_ABOVE_NORMAL);
	D(bug("Tick thread installed (%ld)\n", tick_thread));

	// Start NVRAM watchdog thread
	memcpy(last_xpram, XPRAM, XPRAM_SIZE);
	nvram_thread_cancel = false;
	nvram_thread_active = ((nvram_thread = create_thread(nvram_func, NULL)) != NULL);
	SetThreadPriority(nvram_thread, THREAD_PRIORITY_BELOW_NORMAL);
	D(bug("NVRAM thread installed (%ld)\n", nvram_thread));

	// Get my thread ID and jump to ROM boot routine
	emul_thread = GetCurrentThread();
	D(bug("Jumping to ROM\n"));
#ifdef _MSC_VER
	__try {
#endif
		jump_to_rom(ROMBase + 0x310000);
#ifdef _MSC_VER
	} __except (main_exception_filter(GetExceptionInformation())) {}
#endif
	D(bug("Returned from ROM\n"));

quit:
	Quit();
	return 0;
}
예제 #5
0
bool ether_init(void)
{
	char str[256];

	// Do nothing if no Ethernet device specified
	const char *name = PrefsFindString("ether");
	if (name == NULL)
		return false;

	ether_multi_mode = PrefsFindInt32("ethermulticastmode");
	ether_use_permanent = PrefsFindBool("etherpermanentaddress");

	// Determine Ethernet device type
	net_if_type = -1;
	if (PrefsFindBool("routerenabled") || strcmp(name, "router") == 0)
		net_if_type = NET_IF_ROUTER;
	else if (strcmp(name, "slirp") == 0)
		net_if_type = NET_IF_SLIRP;
	else if (strcmp(name, "tap") == 0)
		net_if_type = NET_IF_TAP;
	else
		net_if_type = NET_IF_B2ETHER;

	// Initialize NAT-Router
	if (net_if_type == NET_IF_ROUTER) {
		if (!router_init())
			net_if_type = NET_IF_FAKE;
	}

	// Initialize slirp library
	if (net_if_type == NET_IF_SLIRP) {
		if (slirp_init() < 0) {
			sprintf(str, GetString(STR_SLIRP_NO_DNS_FOUND_WARN));
			WarningAlert(str);
			return false;
		}
	}

	// Open ethernet device
	const char *dev_name;
	switch (net_if_type) {
	case NET_IF_B2ETHER:
		dev_name = PrefsFindString("etherguid");
		if (dev_name == NULL || strcmp(name, "b2ether") != 0)
			dev_name = name;
		break;
	case NET_IF_TAP:
		dev_name = PrefsFindString("etherguid");
		break;
	}
	if (net_if_type == NET_IF_B2ETHER) {
		if (dev_name == NULL) {
			WarningAlert("No ethernet device GUID specified. Ethernet is not available.");
			goto open_error;
		}

		fd = PacketOpenAdapter( dev_name, ether_multi_mode );
		if (!fd) {
			sprintf(str, "Could not open ethernet adapter %s.", dev_name);
			WarningAlert(str);
			goto open_error;
		}

		// Get Ethernet address
		if(!PacketGetMAC(fd,ether_addr,ether_use_permanent)) {
			sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name);
			WarningAlert(str);
			goto open_error;
		}
		D(bug("Real 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]));

		const char *ether_fake_address;
		ether_fake_address = PrefsFindString("etherfakeaddress");
		if(ether_fake_address && strlen(ether_fake_address) == 12) {
			char sm[10];
			strcpy( sm, "0x00" );
			for( int i=0; i<6; i++ ) {
				sm[2] = ether_fake_address[i*2];
				sm[3] = ether_fake_address[i*2+1];
				ether_addr[i] = (uint8)strtoul(sm,0,0);
			}
			D(bug("Fake 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]));
		}
	}
	else if (net_if_type == NET_IF_TAP) {
		if (dev_name == NULL) {
			WarningAlert("No ethernet device GUID specified. Ethernet is not available.");
			goto open_error;
		}

		fd = tap_open_adapter(dev_name);
		if (!fd) {
			sprintf(str, "Could not open ethernet adapter %s.", dev_name);
			WarningAlert(str);
			goto open_error;
		}

		if (!tap_check_version(fd)) {
			sprintf(str, "Minimal TAP-Win32 version supported is %d.%d.", TAP_VERSION_MIN_MAJOR, TAP_VERSION_MIN_MINOR);
			WarningAlert(str);
			goto open_error;
		}

		if (!tap_set_status(fd, true)) {
			sprintf(str, "Could not set media status to connected.");
			WarningAlert(str);
			goto open_error;
		}

		if (!tap_get_mac(fd, ether_addr)) {
			sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name);
			WarningAlert(str);
			goto open_error;
		}
		D(bug("Real 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]));

		const char *ether_fake_address;
		ether_fake_address = PrefsFindString("etherfakeaddress");
		if (ether_fake_address && strlen(ether_fake_address) == 12) {
			char sm[10];
			strcpy( sm, "0x00" );
			for( int i=0; i<6; i++ ) {
				sm[2] = ether_fake_address[i*2];
				sm[3] = ether_fake_address[i*2+1];
				ether_addr[i] = (uint8)strtoul(sm,0,0);
			}
		}
#if 1
		/*
		  If we bridge the underlying ethernet connection and the TAP
		  device altogether, we have to use a fake address.
		 */
		else {
			ether_addr[0] = 0x52;
			ether_addr[1] = 0x54;
			ether_addr[2] = 0x00;
		}
#endif
		D(bug("Fake 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]));
	}
	else if (net_if_type == NET_IF_SLIRP) {
		ether_addr[0] = 0x52;
		ether_addr[1] = 0x54;
		ether_addr[2] = 0x00;
		ether_addr[3] = 0x12;
		ether_addr[4] = 0x34;
		ether_addr[5] = 0x56;
		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]));
	}
	else {
		memcpy( ether_addr, router_mac_addr, 6 );
		D(bug("Fake ethernet address (same as router) %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]));
	}

	// Start packet reception thread
	int_ack = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_ack) {
		WarningAlert("WARNING: Cannot create int_ack semaphore");
		goto open_error;
	}

	// nonsignaled
	int_sig = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_sig) {
		WarningAlert("WARNING: Cannot create int_sig semaphore");
		goto open_error;
	}

	int_sig2 = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_sig2) {
		WarningAlert("WARNING: Cannot create int_sig2 semaphore");
		goto open_error;
	}

	int_send_now = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_send_now) {
		WarningAlert("WARNING: Cannot create int_send_now semaphore");
		goto open_error;
	}

	init_queue();

	if(!allocate_read_packets()) goto open_error;

	// No need to enter wait state if we can avoid it.
	// These all terminate fast.

	if(pfnInitializeCriticalSectionAndSpinCount) {
		pfnInitializeCriticalSectionAndSpinCount( &fetch_csection, 5000 );
	} else {
		InitializeCriticalSection( &fetch_csection );
	}
	if(pfnInitializeCriticalSectionAndSpinCount) {
		pfnInitializeCriticalSectionAndSpinCount( &queue_csection, 5000 );
	} else {
		InitializeCriticalSection( &queue_csection );
	}
	if(pfnInitializeCriticalSectionAndSpinCount) {
		pfnInitializeCriticalSectionAndSpinCount( &send_csection, 5000 );
	} else {
		InitializeCriticalSection( &send_csection );
	}
	if(pfnInitializeCriticalSectionAndSpinCount) {
		pfnInitializeCriticalSectionAndSpinCount( &wpool_csection, 5000 );
	} else {
		InitializeCriticalSection( &wpool_csection );
	}

	ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, &ether_tid );
	if (!ether_th) {
		D(bug("Failed to create ethernet thread\n"));
		goto open_error;
	}
	thread_active = true;

	unsigned int dummy;
	unsigned int (WINAPI *receive_func)(void *);
	switch (net_if_type) {
	case NET_IF_SLIRP:
	  receive_func = slirp_receive_func;
	  break;
	default:
	  receive_func = ether_thread_get_packets_nt;
	  break;
	}
	ether_th2 = (HANDLE)_beginthreadex( 0, 0, receive_func, 0, 0, &dummy );
	ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy );

	// Everything OK
	return true;

 open_error:
	if (thread_active) {
		TerminateThread(ether_th,0);
		ether_th = 0;
		if (int_ack)
			CloseHandle(int_ack);
		int_ack = 0;
		if(int_sig)
			CloseHandle(int_sig);
		int_sig = 0;
		if(int_sig2)
			CloseHandle(int_sig2);
		int_sig2 = 0;
		if(int_send_now)
			CloseHandle(int_send_now);
		int_send_now = 0;
		thread_active = false;
	}
	if (fd) {
		switch (net_if_type) {
		case NET_IF_B2ETHER:
			PacketCloseAdapter(fd);
			break;
		case NET_IF_TAP:
			tap_close_adapter(fd);
			break;
		}
		fd = 0;
	}
	return false;
}
예제 #6
0
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;
}
예제 #7
0
int main(int argc, char **argv)
{
    // Print banner
    printf(
        "SIDPlayer Version 4.4\n\n"
        "Copyright (C) 1996-2004 Christian Bauer\n"
        "E-mail: [email protected]\n"
        "http://www.uni-mainz.de/~bauec002/\n\n"
        "This is free software with ABSOLUTELY NO WARRANTY.\n"
        "You are welcome to redistribute it under certain conditions.\n"
        "For details, see the file COPYING.\n\n"
    );

    // Initialize everything
    if (SDL_Init(SDL_INIT_AUDIO) < 0) {
        fprintf(stderr, "Couldn't initialize SDL (%s)\n", SDL_GetError());
        exit(1);
    }
    atexit(quit);
    InitAll(argc, argv);
    int32 speed = PrefsFindInt32("speed");

    // Parse non-option arguments
    const char *file_name = NULL;
    int song = 0;
    int i;
    for (i=1; i<argc; i++) {
        if (strcmp(argv[i], "--help") == 0)
            usage(argv[0]);
        else if (argv[i][0] == '-') {
            fprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
            usage(argv[0]);
        } else {
            if (file_name == NULL)
                file_name = argv[i];  // First non-option argument is file name
            else
                song = atoi(argv[i]); // Second non-option argument is song number
        }
    }
    if (file_name == NULL)
        usage(argv[0]);

    // Load given PSID file
    if (!LoadPSIDFile(file_name)) {
        fprintf(stderr, "Couldn't load '%s' (not a PSID file?)\n", file_name);
        exit(1);
    }

    // Select song
    if (song > 0) {
        if (song > number_of_songs)
            song = number_of_songs;
        SelectSong(song - 1);
    }

    SIDAdjustSpeed(speed); // SelectSong and LoadPSIDFile() reset this to 100%

    // Print file information
    printf("Module Name: %s\n", module_name);
    printf("Author     : %s\n", author_name);
    printf("Copyright  : %s\n\n", copyright_info);
    printf("Playing song %d/%d\n", current_song + 1, number_of_songs);

    // Start replay and enter main loop
    SDL_PauseAudio(false);
    while (true) {
        SDL_Event e;
        if (SDL_WaitEvent(&e)) {
            if (e.type == SDL_QUIT)
                break;
        }
    }

    ExitAll();
    return 0;
}
예제 #8
0
파일: main.cpp 프로젝트: DavidLudwig/macemu
bool InitAll(const char *vmdir)
{
	// Check ROM version
	if (!CheckROM()) {
		ErrorAlert(STR_UNSUPPORTED_ROM_TYPE_ERR);
		return false;
	}

#if EMULATED_68K
	// Set CPU and FPU type (UAE emulation)
	switch (ROMVersion) {
		case ROM_VERSION_64K:
		case ROM_VERSION_PLUS:
		case ROM_VERSION_CLASSIC:
			CPUType = 0;
			FPUType = 0;
			TwentyFourBitAddressing = true;
			break;
		case ROM_VERSION_II:
			CPUType = PrefsFindInt32("cpu");
			if (CPUType < 2) CPUType = 2;
			if (CPUType > 4) CPUType = 4;
			FPUType = PrefsFindBool("fpu") ? 1 : 0;
			if (CPUType == 4) FPUType = 1;	// 68040 always with FPU
			TwentyFourBitAddressing = true;
			break;
		case ROM_VERSION_32:
			CPUType = PrefsFindInt32("cpu");
			if (CPUType < 2) CPUType = 2;
			if (CPUType > 4) CPUType = 4;
			FPUType = PrefsFindBool("fpu") ? 1 : 0;
			if (CPUType == 4) FPUType = 1;	// 68040 always with FPU
			TwentyFourBitAddressing = false;
			break;
	}
	CPUIs68060 = false;
#endif

	// Load XPRAM
	XPRAMInit(vmdir);

	// Load XPRAM default values if signature not found
	if (XPRAM[0x0c] != 0x4e || XPRAM[0x0d] != 0x75
	 || XPRAM[0x0e] != 0x4d || XPRAM[0x0f] != 0x63) {
		D(bug("Loading XPRAM default values\n"));
		memset(XPRAM, 0, 0x100);
		XPRAM[0x0c] = 0x4e;	// "NuMc" signature
		XPRAM[0x0d] = 0x75;
		XPRAM[0x0e] = 0x4d;
		XPRAM[0x0f] = 0x63;
		XPRAM[0x01] = 0x80;	// InternalWaitFlags = DynWait (don't wait for SCSI devices upon bootup)
		XPRAM[0x10] = 0xa8;	// Standard PRAM values
		XPRAM[0x11] = 0x00;
		XPRAM[0x12] = 0x00;
		XPRAM[0x13] = 0x22;
		XPRAM[0x14] = 0xcc;
		XPRAM[0x15] = 0x0a;
		XPRAM[0x16] = 0xcc;
		XPRAM[0x17] = 0x0a;
		XPRAM[0x1c] = 0x00;
		XPRAM[0x1d] = 0x02;
		XPRAM[0x1e] = 0x63;
		XPRAM[0x1f] = 0x00;
		XPRAM[0x08] = 0x13;
		XPRAM[0x09] = 0x88;
		XPRAM[0x0a] = 0x00;
		XPRAM[0x0b] = 0xcc;
		XPRAM[0x76] = 0x00;	// OSDefault = MacOS
		XPRAM[0x77] = 0x01;
	}

	// Set boot volume
	int16 i16 = PrefsFindInt32("bootdrive");
	XPRAM[0x78] = i16 >> 8;
	XPRAM[0x79] = i16 & 0xff;
	i16 = PrefsFindInt32("bootdriver");
	XPRAM[0x7a] = i16 >> 8;
	XPRAM[0x7b] = i16 & 0xff;

	// Init drivers
	SonyInit();
	DiskInit();
	CDROMInit();
	SCSIInit();

#if SUPPORTS_EXTFS
	// Init external file system
	ExtFSInit();
#endif

	// Init serial ports
	SerialInit();

	// Init network
	EtherInit();

	// Init Time Manager
	TimerInit();

	// Init clipboard
	ClipInit();

	// Init ADB
	ADBInit();

	// Init audio
	AudioInit();

	// Init video
	if (!VideoInit(ROMVersion == ROM_VERSION_64K || ROMVersion == ROM_VERSION_PLUS || ROMVersion == ROM_VERSION_CLASSIC))
		return false;

	// Set default video mode in XPRAM
	XPRAM[0x56] = 0x42;	// 'B'
	XPRAM[0x57] = 0x32;	// '2'
	const monitor_desc &main_monitor = *VideoMonitors[0];
	XPRAM[0x58] = uint8(main_monitor.depth_to_apple_mode(main_monitor.get_current_mode().depth));
	XPRAM[0x59] = 0;

#if EMULATED_68K
	// Init 680x0 emulation (this also activates the memory system which is needed for PatchROM())
	if (!Init680x0())
		return false;
#endif

	// Install ROM patches
	if (!PatchROM()) {
		ErrorAlert(STR_UNSUPPORTED_ROM_TYPE_ERR);
		return false;
	}

#if ENABLE_MON
	// Initialize mon
	mon_init();
	mon_read_byte = mon_read_byte_b2;
	mon_write_byte = mon_write_byte_b2;
#endif

	return true;
}
예제 #9
0
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 = sys_info.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), 1, max_ramsize, B_TRIANGLE_THUMB);
	ramsize_slider->SetValue(value);
	ramsize_slider->UseFillColor(true, &slider_fill_color);
	sprintf(str, GetString(STR_RAMSIZE_FMT), 1);
	sprintf(str2, GetString(STR_RAMSIZE_FMT), max_ramsize);
	ramsize_slider->SetLimitLabels(str, str2);
	pane->AddChild(ramsize_slider);

	BMenuField *menu_field;
	BMenuItem *item;
	BPopUpMenu *menu;

	int id = PrefsFindInt32("modelid");
	menu = new BPopUpMenu("");
	menu_field = new BMenuField(BRect(10, 60, right, 75), "modelid", GetString(STR_MODELID_CTRL), menu);
	menu_field->SetDivider(120);
	menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_5_LAB), new BMessage(MSG_MODELID_5)));
	if (id == 5)
		item->SetMarked(true);
	menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_14_LAB), new BMessage(MSG_MODELID_14)));
	if (id == 14)
		item->SetMarked(true);
	pane->AddChild(menu_field);

	int cpu = PrefsFindInt32("cpu");
	bool fpu = PrefsFindBool("fpu");
	menu = new BPopUpMenu("");
	menu_field = new BMenuField(BRect(10, 82, right, 97), "cpu", GetString(STR_CPU_CTRL), menu);
	menu_field->SetDivider(120);
	menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_LAB), new BMessage(MSG_CPU_68020)));
	if (cpu == 2 && !fpu)
		item->SetMarked(true);
	menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_FPU_LAB), new BMessage(MSG_CPU_68020_FPU)));
	if (cpu == 2 && fpu)
		item->SetMarked(true);
	menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_LAB), new BMessage(MSG_CPU_68030)));
	if (cpu == 3 && !fpu)
		item->SetMarked(true);
	menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_FPU_LAB), new BMessage(MSG_CPU_68030_FPU)));
	if (cpu == 3 && fpu)
		item->SetMarked(true);
	menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68040_LAB), new BMessage(MSG_CPU_68040)));
	if (cpu == 4)
		item->SetMarked(true);
	pane->AddChild(menu_field);

	rom_control = new PathControl(false, BRect(10, 104, right, 119), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL);
	rom_control->SetDivider(117);
	pane->AddChild(rom_control);

	return pane;
}
예제 #10
0
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_SERIALA_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_SERIALB_CTRL), menu_b);
	menu_field->SetDivider(90);
	pane->AddChild(menu_field);
	set_serial_label(menu_b, "serialb");

	ether_checkbox = new BCheckBox(BRect(10, 47, right, 62), "ether", GetString(STR_ETHER_ENABLE_CTRL), new BMessage(MSG_ETHER));
	pane->AddChild(ether_checkbox);
	ether_checkbox->SetValue(PrefsFindString("ether") ? B_CONTROL_ON : B_CONTROL_OFF);

	udptunnel_checkbox = new BCheckBox(BRect(10, 67, right, 72), "udptunnel", GetString(STR_UDPTUNNEL_CTRL), new BMessage(MSG_UDPTUNNEL));
	pane->AddChild(udptunnel_checkbox);
	udptunnel_checkbox->SetValue(PrefsFindBool("udptunnel") ? B_CONTROL_ON : B_CONTROL_OFF);

	udpport_ctrl = new NumberControl(BRect(10, 87, right / 2, 105), 118, "udpport", GetString(STR_UDPPORT_CTRL), PrefsFindInt32("udpport"), NULL);
	pane->AddChild(udpport_ctrl);

	hide_show_serial_ctrls();
	return pane;
}
예제 #11
0
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;

	const char *mode_str = PrefsFindString("screen");
	int width = 512, height = 384;
	scr_mode_bit = 0;
	display_type = DISPLAY_WINDOW;
	if (mode_str) {
		if (sscanf(mode_str, "win/%d/%d", &width, &height) == 2)
			display_type = DISPLAY_WINDOW;
		else if (sscanf(mode_str, "scr/%d", &scr_mode_bit) == 1)
			display_type = DISPLAY_SCREEN;
	}

	BMenuField *menu_field;
	BMenuItem *item;
	BPopUpMenu *menu;

	menu = new BPopUpMenu("");
	menu_field = new BMenuField(BRect(10, 5, right, 20), "videotype", GetString(STR_VIDEO_TYPE_CTRL), menu);
	menu_field->SetDivider(120);
	menu->AddItem(item = new BMenuItem(GetString(STR_WINDOW_LAB), new BMessage(MSG_VIDEO_WINDOW)));
	if (display_type == DISPLAY_WINDOW)
		item->SetMarked(true);
	menu->AddItem(item = new BMenuItem(GetString(STR_FULLSCREEN_LAB), new BMessage(MSG_VIDEO_SCREEN)));
	if (display_type == DISPLAY_SCREEN)
		item->SetMarked(true);
	pane->AddChild(menu_field);

	menu = new BPopUpMenu("");
	frameskip_menu = new BMenuField(BRect(10, 26, right, 41), "frameskip", GetString(STR_FRAMESKIP_CTRL), menu);
	frameskip_menu->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(frameskip_menu);
	int32 i32 = PrefsFindInt32("frameskip");
	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);
	}

	display_x_ctrl = new NumberControl(BRect(10, 48, right / 2, 66), 118, "width", GetString(STR_DISPLAY_X_CTRL), width, NULL);
	pane->AddChild(display_x_ctrl);
	display_y_ctrl = new NumberControl(BRect(10, 69, right / 2, 87), 118, "height", GetString(STR_DISPLAY_Y_CTRL), height, NULL);
	pane->AddChild(display_y_ctrl);

	menu = new BPopUpMenu("");
	scr_mode_menu = new BMenuField(BRect(10, 26, right, 41), "screenmode", GetString(STR_SCREEN_MODE_CTRL), menu);
	scr_mode_menu->SetDivider(120);
	for (int i=0; scr_mode[i].mode_mask; i++) {
		menu->AddItem(item = new BMenuItem(GetString(scr_mode[i].str), new BMessage(MSG_SCREEN_MODE + i)));
		if (scr_mode[i].mode_mask & (1 << scr_mode_bit))
			item->SetMarked(true);
	}
	pane->AddChild(scr_mode_menu);

	nosound_checkbox = new BCheckBox(BRect(10, 90, right, 105), "nosound", GetString(STR_NOSOUND_CTRL), new BMessage(MSG_NOSOUND));
	pane->AddChild(nosound_checkbox);
	nosound_checkbox->SetValue(PrefsFindBool("nosound") ? B_CONTROL_ON : B_CONTROL_OFF);

	hide_show_graphics_ctrls();
	return pane;
}
예제 #12
0
MacWindow::MacWindow(BRect frame, const BeOS_monitor_desc& monitor)
	: BDirectWindow(frame, GetString(STR_WINDOW_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE)
	, monitor(monitor)
{
	supports_direct_mode = SupportsWindowMode();

	// Move window to right position
	Lock();
	MoveTo(80, 60);

	// Allocate bitmap and Mac frame buffer
	uint32 x = frame.IntegerWidth() + 1;
	uint32 y = frame.IntegerHeight() + 1;
	int fbsize = x * y;
	const video_mode &mode = monitor.get_current_mode();
	switch (mode.depth) {
		case VDEPTH_1BIT:
			fprintf(stderr, "1BIT SCREEN CREATED");
			the_bitmap = new BBitmap(frame, B_GRAY1);
			fbsize /= 8;
			break;
		case VDEPTH_8BIT:
			fprintf(stderr, "8BIT SCREEN CREATED");
			the_bitmap = new BBitmap(frame, B_CMAP8);
			break;
		case VDEPTH_32BIT:
			fprintf(stderr, "32BIT SCREEN CREATED");
			the_bitmap = new BBitmap(frame, B_RGB32_BIG);
			fbsize *= 4;
			break;
		default:
			fprintf(stderr, "width: %d", 1 << mode.depth);
			debugger("OOPS");
	}

#if REAL_ADDRESSING
	monitor.set_mac_frame_base((uint32)the_bitmap->Bits());
#else
	monitor.set_mac_frame_base(MacFrameBaseMac);
#endif

#if !REAL_ADDRESSING
	// Set variables for UAE memory mapping
	MacFrameBaseHost = (uint8*)the_bitmap->Bits();
	MacFrameSize = fbsize;
	MacFrameLayout = FLAYOUT_DIRECT;
#endif

	// Create bitmap view
	main_view = new BitmapView(frame, the_bitmap);
	AddChild(main_view);
	main_view->MakeFocus();

	// Read frame skip prefs
	frame_skip = PrefsFindInt32("frameskip");
	if (frame_skip == 0)
		frame_skip = 1;

	// Set up menus
	BRect bounds = Bounds();
	bounds.OffsetBy(0, bounds.IntegerHeight() + 1);
	BMenuItem *item;
	BMenuBar *bar = new BMenuBar(bounds, "menu");
	BMenu *menu = new BMenu(GetString(STR_WINDOW_MENU));
	menu->AddItem(new BMenuItem(GetString(STR_WINDOW_ITEM_ABOUT), new BMessage(MSG_ABOUT_REQUESTED)));
	menu->AddItem(new BSeparatorItem);
	BMenu *submenu = new BMenu(GetString(STR_WINDOW_ITEM_REFRESH));
	submenu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ)));
	submenu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ)));
	submenu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ)));
	submenu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ)));
	submenu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ)));
	submenu->AddItem(new BMenuItem(GetString(STR_REF_60HZ_LAB), new BMessage(MSG_REF_60HZ)));
	submenu->SetRadioMode(true);
	if (frame_skip == 12) {
		if ((item = submenu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL)
			item->SetMarked(true);
	} else if (frame_skip == 8) {
		if ((item = submenu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL)
			item->SetMarked(true);
	} else if (frame_skip == 6) {
		if ((item = submenu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL)
			item->SetMarked(true);
	} else if (frame_skip == 4) {
		if ((item = submenu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL)
			item->SetMarked(true);
	} else if (frame_skip == 2) {
		if ((item = submenu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL)
			item->SetMarked(true);
	} else if (frame_skip == 1) {
		if ((item = submenu->FindItem(GetString(STR_REF_60HZ_LAB))) != NULL)
			item->SetMarked(true);
	}
	menu->AddItem(submenu);
	submenu = new BMenu(GetString(STR_WINDOW_ITEM_MOUNT));
	SysCreateVolumeMenu(submenu, MSG_MOUNT);
	menu->AddItem(submenu);
#if DEBUGGER_AVAILABLE
	menu->AddItem(new BMenuItem("Debugger", new BMessage(MSG_DEBUGGER)));
#endif
	bar->AddItem(menu);
	AddChild(bar);
	SetKeyMenuBar(bar);
	int mbar_height = bar->Frame().IntegerHeight() + 1;

	// Resize window to fit menu bar
	ResizeBy(0, mbar_height);

	// Set absolute mouse mode and get scroll lock state
	ADBSetRelMouseMode(false);
	mouse_in_view = true;
	old_scroll_lock_state = modifiers() & B_SCROLL_LOCK;
	if (old_scroll_lock_state)
		SetTitle(GetString(STR_WINDOW_TITLE_FROZEN));
	else
		SetTitle(GetString(STR_WINDOW_TITLE));

	// Keep window aligned to 8-byte frame buffer boundaries for faster blitting
	SetWindowAlignment(B_BYTE_ALIGNMENT, 8);

	// Create drawing semaphore (for direct mode)
	drawing_sem = create_sem(0, "direct frame buffer access");

	// Start 60Hz interrupt
	tick_thread_active = true;
	tick_thread = spawn_thread(tick_func, "Window Redraw", B_DISPLAY_PRIORITY, this);
	resume_thread(tick_thread);

	// Add filter for keyboard and mouse events
	BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, filter_func);
	main_view->AddFilter(filter);

	// Show window
	Unlock();
	Show();
	Sync();
}