Example #1
0
// Dispatch packet to protocol handler
static void ether_dispatch_packet(uint32 packet, uint32 length)
{
	// Get packet type
	uint16 type = ReadMacInt16(packet + 12);

	// Look for protocol
	NetProtocol *prot = find_protocol(type);
	if (prot == NULL)
		return;

	// No default handler
	if (prot->handler == 0)
		return;

	// 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] = 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);
}
Example #2
0
void TimerInterrupt(void)
{
	// Look for active TMTasks that have expired
	tm_time_t now;
	timer_current_time(now);
	for (int i=0; i<NUM_DESCS; i++)
		if (desc[i].in_use) {
			uint32 tm = desc[i].task;
			if ((ReadMacInt16(tm + qType) & 0x8000) && timer_cmp_time(desc[i].wakeup, now) < 0) {

				// Found one, mark as inactive and remove it from the Time Manager queue
				WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x7fff);
				dequeue_tm(tm);

				// Call timer function
				uint32 addr = ReadMacInt32(tm + tmAddr);
				if (addr) {
					D(bug("Calling TimeTask %08lx, addr %08lx\n", tm, addr));
					M68kRegisters r;
					r.a[0] = addr;
					r.a[1] = tm;
					Execute68k(addr, &r);
				}
			}
		}
}
Example #3
0
void GetScrap(void **handle, uint32 type, int32 offset)
{
#if defined(__LP64__)
	D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset));
	#warning Carbon scrapbook function are not implemented in 64-bit mode
#else
	D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset));
	ScrapRef theScrap;

	if (GetCurrentScrap(&theScrap) != noErr) {
		D(bug(" could not open scrap\n"));
		return;
	}

	Size byteCount;
	if (GetScrapFlavorSize(theScrap, type, &byteCount) == noErr) {

		// Allocate space for new scrap in MacOS side
		M68kRegisters r;
		r.d[0] = byteCount;
		Execute68kTrap(0xa71e, &r);				// NewPtrSysClear()
		uint32 scrap_area = r.a[0];

		// Get the native clipboard data
		if (scrap_area) {
			uint8 * const data = Mac2HostAddr(scrap_area);
			if (GetScrapFlavorData(theScrap, type, &byteCount, data) == noErr) {
				SwapScrapData(type, data, byteCount, FALSE);
				// Add new data to clipboard
				static uint8 proc[] = {
					0x59, 0x8f,					// subq.l	#4,sp
					0xa9, 0xfc,					// ZeroScrap()
					0x2f, 0x3c, 0, 0, 0, 0,		// move.l	#length,-(sp)
					0x2f, 0x3c, 0, 0, 0, 0,		// move.l	#type,-(sp)
					0x2f, 0x3c, 0, 0, 0, 0,		// move.l	#outbuf,-(sp)
					0xa9, 0xfe,					// PutScrap()
					0x58, 0x8f,					// addq.l	#4,sp
					M68K_RTS >> 8, M68K_RTS & 0xff
				};
				r.d[0] = sizeof(proc);
				Execute68kTrap(0xa71e, &r);		// NewPtrSysClear()
				uint32 proc_area = r.a[0];

				if (proc_area) {
					Host2Mac_memcpy(proc_area, proc, sizeof(proc));
					WriteMacInt32(proc_area +  6, byteCount);
					WriteMacInt32(proc_area + 12, type);
					WriteMacInt32(proc_area + 18, scrap_area);
					we_put_this_data = true;
					Execute68k(proc_area, &r);

					r.a[0] = proc_area;
					Execute68kTrap(0xa01f, &r);	// DisposePtr
				}
			}

			r.a[0] = scrap_area;
			Execute68kTrap(0xa01f, &r);			// DisposePtr
		}
Example #4
0
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"));
}
Example #5
0
void TimerInterrupt(void)
{
//	D(bug("TimerIRQ\n"));

	// Look for active TMTasks that have expired
	tm_time_t now;
	timer_current_time(now);
	TMDesc *desc = tmDescList;
	while (desc) {
		TMDesc *next = desc->next;
		uint32 tm = desc->task;
		if ((ReadMacInt16(tm + qType) & 0x8000) && timer_cmp_time(desc->wakeup, now) <= 0) {

			// Found one, mark as inactive and remove it from the Time Manager queue
			WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x7fff);
			dequeue_tm(tm);

			// Call timer function
			uint32 addr = ReadMacInt32(tm + tmAddr);
			if (addr) {
				D(bug("Calling TimeTask %08lx, addr %08lx\n", tm, addr));
				M68kRegisters r;
				r.a[0] = addr;
				r.a[1] = tm;
				Execute68k(r.a[0], &r);
				D(bug(" returned from TimeTask\n"));
			}
		}
		desc = next;
	}

#if PRECISE_TIMING
	// Look for next task to be called and set wakeup_time
#if PRECISE_TIMING_BEOS
	while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
	suspend_thread(timer_thread);
#endif
#if PRECISE_TIMING_MACH
	semaphore_wait(wakeup_time_sem);
	thread_suspend(timer_thread);
#endif
#if PRECISE_TIMING_POSIX
	timer_thread_suspend();
	pthread_mutex_lock(&wakeup_time_lock);
#endif
	wakeup_time = wakeup_time_max;
	for (TMDesc *d = tmDescList; d; d = d->next)
		if ((ReadMacInt16(d->task + qType) & 0x8000))
			if (timer_cmp_time(d->wakeup, wakeup_time) < 0)
				wakeup_time = d->wakeup;
#if PRECISE_TIMING_BEOS
	release_sem(wakeup_time_sem);
	thread_info info;
	do {
		resume_thread(timer_thread);			// This will unblock the thread
		get_thread_info(timer_thread, &info);
	} while (info.state == B_THREAD_SUSPENDED);	// Sometimes, resume_thread() doesn't work (BeOS bug?)
#endif
#if PRECISE_TIMING_MACH
	semaphore_signal(wakeup_time_sem);
	thread_abort(timer_thread);
	thread_resume(timer_thread);
#endif
#if PRECISE_TIMING_POSIX
	pthread_mutex_unlock(&wakeup_time_lock);
	timer_thread_resume();
	assert(suspend_count == 0);
#endif
#endif
}
Example #6
0
uint32 FindLibSymbol(const char *lib_str, const char *sym_str)
{
	SheepVar32 conn_id = 0;
	SheepVar32 main_addr = 0;
	SheepArray<256> err;
	WriteMacInt8(err.addr(), 0);
	SheepVar32 sym_addr = 0;
	SheepVar32 sym_class = 0;

	SheepString lib(lib_str);
	SheepString sym(sym_str);

	D(bug("FindLibSymbol %s in %s...\n", sym.value()+1, lib.value()+1));

	if (ReadMacInt32(XLM_RUN_MODE) == MODE_EMUL_OP) {
		M68kRegisters r;

		// Find shared library
		static const uint8 proc1_template[] = {
			0x55, 0x8f,							// subq.l	#2,a7
			0x2f, 0x08,							// move.l	a0,-(a7)
			0x2f, 0x3c, 0x70, 0x77, 0x70, 0x63,	// move.l	#'pwpc',-(a7)
			0x2f, 0x3c, 0x00, 0x00, 0x00, 0x01,	// move.l	#kReferenceCFrag,-(a7)
			0x2f, 0x09,							// move.l	a1,-(a7)
			0x2f, 0x0a,							// move.l	a2,-(a7)
			0x2f, 0x0b,							// move.l	a3,-(a7)
			0x3f, 0x3c, 0x00, 0x01,				// (GetSharedLibrary)
			0xaa, 0x5a,							// CFMDispatch
			0x30, 0x1f,							// move.w	(a7)+,d0
			M68K_RTS >> 8, M68K_RTS & 0xff
		};
		BUILD_SHEEPSHAVER_PROCEDURE(proc1);
		r.a[0] = lib.addr();
		r.a[1] = conn_id.addr();
		r.a[2] = main_addr.addr();
		r.a[3] = err.addr();
		Execute68k(proc1, &r);
		D(bug(" GetSharedLibrary: ret %d, connection ID %ld, main %p\n", (int16)r.d[0], conn_id.value(), main_addr.value()));
		if (r.d[0])
			return 0;

		// Find symbol
		static const uint8 proc2_template[] = {
			0x55, 0x8f,					// subq.l	#2,a7
			0x2f, 0x00,					// move.l	d0,-(a7)
			0x2f, 0x08,					// move.l	a0,-(a7)
			0x2f, 0x09,					// move.l	a1,-(a7)
			0x2f, 0x0a,					// move.l	a2,-(a7)
			0x3f, 0x3c, 0x00, 0x05,		// (FindSymbol)
			0xaa, 0x5a,					// CFMDispatch
			0x30, 0x1f,					// move.w	(a7)+,d0
			M68K_RTS >> 8, M68K_RTS & 0xff
		};
		BUILD_SHEEPSHAVER_PROCEDURE(proc2);
		r.d[0] = conn_id.value();
		r.a[0] = sym.addr();
		r.a[1] = sym_addr.addr();
		r.a[2] = sym_class.addr();
		Execute68k(proc2, &r);
		D(bug(" FindSymbol1: ret %d, sym_addr %p, sym_class %ld\n", (int16)r.d[0], sym_addr.value(), sym_class.value()));
//!! CloseConnection()?
		if (r.d[0])
			return 0;
		else
			return sym_addr.value();

	} else {
Example #7
0
void ExecuteNative(int selector)
{
	M68kRegisters r;
	Execute68k(NativeRoutineDescriptor(selector), &r);
}
Example #8
0
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;
	}
}