コード例 #1
0
ファイル: extfs_unix.cpp プロジェクト: AlexandreCo/macemu
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 (!strcmp(path + path_len - ext_len, e2t_translation[i].ext)) {
				WriteMacInt32(finfo + fdType, e2t_translation[i].type);
				WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator);
				break;
			}
		}
	}
}
コード例 #2
0
ファイル: timer.cpp プロジェクト: lewellyn/CockatriceIII
int16 RmvTime(uint32 tm)
{
	D(bug("RmvTime %08lx\n", tm));

	// Find descriptor
	int i = find_desc(tm);
	if (i < 0) {
		D(bug("WARNING: RmvTime(%08lx): Descriptor not found\n", tm));
		return 0;
	}

	// Task active?
	if (ReadMacInt16(tm + qType) & 0x8000) {

		// Yes, make task inactive and remove it from the Time Manager queue
		WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x7fff);
		dequeue_tm(tm);

		// Compute remaining time
		tm_time_t remaining, current;
		timer_current_time(current);
		timer_sub_time(remaining, desc[i].wakeup, current);
		WriteMacInt32(tm + tmCount, timer_host2mac_time(remaining));
	} else
		WriteMacInt32(tm + tmCount, 0);
	D(bug(" tmCount %ld\n", ReadMacInt32(tm + tmCount)));

	// Free descriptor
	free_desc(i);
	return 0;
}
コード例 #3
0
ファイル: clip_macosx.cpp プロジェクト: AlexandreCo/macemu
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
		}
コード例 #4
0
ファイル: timer.cpp プロジェクト: amade/SheepShaver_oldstuff
static void enqueue_tm(uint32 tm)
{
#if TM_QUEUE
	uint32 tm_var = ReadMacInt32(0xb30);
	WriteMacInt32(tm + qLink, ReadMacInt32(tm_var));
	WriteMacInt32(tm_var, tm);
#endif
}
コード例 #5
0
ファイル: serial_unix.cpp プロジェクト: dougmencken/macemu
void *XSERDPort::output_func(void *arg)
{
	XSERDPort *s = (XSERDPort *)arg;
	while (!s->output_thread_cancel) {

		// Wait for commands
		sem_wait(&s->output_signal);
		if (s->quitting)
			break;

		// Execute command
		void *buf = Mac2HostAddr(ReadMacInt32(s->output_pb + ioBuffer));
		uint32 length = ReadMacInt32(s->output_pb + ioReqCount);
		D(bug("output_func transmitting %ld bytes of data...\n", length));

#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

		int32 actual = write(s->fd, buf, length);
		D(bug(" %ld bytes transmitted\n", actual));

		// KillIO called? Then simply return
		if (s->io_killed) {

			WriteMacInt16(s->output_pb + ioResult, uint16(abortErr));
			WriteMacInt32(s->output_pb + ioActCount, 0);
			s->write_pending = s->write_done = false;

		} else {

			// Set error code
			if (actual >= 0) {
				WriteMacInt32(s->output_pb + ioActCount, actual);
				WriteMacInt32(s->output_dt + serdtResult, noErr);
			} else {
				WriteMacInt32(s->output_pb + ioActCount, 0);
				WriteMacInt32(s->output_dt + serdtResult, uint16(writErr));
			}

			// Trigger serial interrupt
			D(bug(" triggering serial interrupt\n"));
			s->write_done = true;
			SetInterruptFlag(INTFLAG_SERIAL);
			TriggerInterrupt();
		}
	}
	return NULL;
}
コード例 #6
0
ファイル: macos_util.cpp プロジェクト: dougmencken/macemu
void Enqueue(uint32 elem, uint32 list)
{
	WriteMacInt32(elem + qLink, 0);
	if (!ReadMacInt32(list + qTail)) {
		WriteMacInt32(list + qHead, elem);
		WriteMacInt32(list + qTail, elem);
	} else {
		WriteMacInt32(ReadMacInt32(list + qTail) + qLink, elem);
		WriteMacInt32(list + qTail, elem);
	}
}
コード例 #7
0
ファイル: extfs_beos.cpp プロジェクト: Na1w/sheepshear
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);
}
コード例 #8
0
ファイル: serial_amiga.cpp プロジェクト: AlexandreCo/macemu
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;
	}
}
コード例 #9
0
ファイル: main_windows.cpp プロジェクト: tycho/sheepshaver
static DWORD WINAPI tick_func(void *arg)
{
	int tick_counter = 0;
	uint64 start = GetTicks_usec();
	int64 ticks = 0;
	uint64 next = GetTicks_usec();

	while (!tick_thread_cancel) {

		// Wait
		next += 16625;
		int64 delay = next - GetTicks_usec();
		if (delay > 0)
			Delay_usec(delay);
		else if (delay < -16625)
			next = GetTicks_usec();
		ticks++;

		// Pseudo Mac 1Hz interrupt, update local time
		if (++tick_counter > 60) {
			tick_counter = 0;
			WriteMacInt32(0x20c, TimerDateTime());
		}

		// Trigger 60Hz interrupt
		if (ReadMacInt32(XLM_IRQ_NEST) == 0) {
			SetInterruptFlag(INTFLAG_VIA);
			TriggerInterrupt();
		}
	}

	uint64 end = GetTicks_usec();
	D(bug("%lu ticks in %lu usec = %f ticks/sec\n", (unsigned long)ticks, (unsigned long)(end - start), ticks * 1000000.0 / (end - start)));
	return 0;
}
コード例 #10
0
ファイル: timer.cpp プロジェクト: lewellyn/CockatriceIII
int16 PrimeTime(uint32 tm, int32 time)
{
	D(bug("PrimeTime %08lx, time %ld\n", tm, time));

	// Find descriptor
	int i = find_desc(tm);
	if (i < 0) {
		printf("FATAL: PrimeTime(): Descriptor not found\n");
		return 0;
	}

	// Extended task?
	if (ReadMacInt16(tm + qType) & 0x4000) {

		// Convert delay time
		tm_time_t delay;
		timer_mac2host_time(delay, time);

		// Yes, tmWakeUp set?
		if (ReadMacInt32(tm + tmWakeUp)) {

			//!! PrimeTime(0) means continue previous delay
			// (save wakeup time in RmvTime?)
			if (time == 0) {
				printf("FATAL: Unsupported PrimeTime(0)\n");
				return 0;
			}

			// Yes, calculate wakeup time relative to last scheduled time
			tm_time_t wakeup;
			timer_add_time(wakeup, desc[i].wakeup, delay);
			desc[i].wakeup = wakeup;

		} else {

			// No, calculate wakeup time relative to current time
			tm_time_t now;
			timer_current_time(now);
			timer_add_time(desc[i].wakeup, now, delay);
		}

		// Set tmWakeUp to indicate that task was scheduled
		WriteMacInt32(tm + tmWakeUp, 0x12345678);

	} else {

		// Not extended task, calculate wakeup time relative to current time
		tm_time_t delay;
		timer_mac2host_time(delay, time);
		timer_current_time(desc[i].wakeup);
		timer_add_time(desc[i].wakeup, desc[i].wakeup, delay);
	}

	// Make task active and enqueue it in the Time Manager queue
	WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) | 0x8000);
	enqueue_tm(tm);
	return 0;
}
コード例 #11
0
ファイル: serial_amiga.cpp プロジェクト: AlexandreCo/macemu
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
}
コード例 #12
0
ファイル: serial_unix.cpp プロジェクト: dougmencken/macemu
int16 XSERDPort::prime_in(uint32 pb, uint32 dce)
{
	// Send input command to input_thread
	read_done = false;
	read_pending = true;
	input_pb = pb;
	WriteMacInt32(input_dt + serdtDCE, dce);
	sem_post(&input_signal);
	return 1;	// Command in progress
}
コード例 #13
0
ファイル: serial_unix.cpp プロジェクト: dougmencken/macemu
int16 XSERDPort::prime_out(uint32 pb, uint32 dce)
{
	// Send output command to output_thread
	write_done = false;
	write_pending = true;
	output_pb = pb;
	WriteMacInt32(output_dt + serdtDCE, dce);
	sem_post(&output_signal);
	return 1;	// Command in progress
}
コード例 #14
0
ファイル: serial_amiga.cpp プロジェクト: AlexandreCo/macemu
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
}
コード例 #15
0
ファイル: gfxaccel.cpp プロジェクト: AlexandreCo/macemu
bool NQD_fillrect_hook(uint32 p)
{
	D(bug("accl_fillrect_hook %08x\n", p));
	NQD_set_dirty_area(p);

	// Check if we can accelerate this fillrect
	if (ReadMacInt32(p + 0x284) != 0 && ReadMacInt32(p + acclDestPixelSize) >= 8) {
		const int transfer_mode = ReadMacInt32(p + acclTransferMode);
		if (transfer_mode == 8) {
			// Fill
			WriteMacInt32(p + acclDrawProc, NativeTVECT(NATIVE_NQD_FILLRECT));
			return true;
		}
		else if (transfer_mode == 10) {
			// Invert
			WriteMacInt32(p + acclDrawProc, NativeTVECT(NATIVE_NQD_INVRECT));
			return true;
		}
	}
	return false;
}
コード例 #16
0
ファイル: timer.cpp プロジェクト: amade/SheepShaver_oldstuff
static void dequeue_tm(uint32 tm)
{
#if TM_QUEUE
	uint32 p = ReadMacInt32(0xb30);
	while (p) {
		uint32 next = ReadMacInt32(p + qLink);
		if (next == tm) {
			WriteMacInt32(p + qLink, ReadMacInt32(next + qLink));
			return;
		}
	}
#endif
}
コード例 #17
0
// Execute EMUL_OP routine
void sheepshaver_cpu::execute_emul_op(uint32 emul_op)
{
	M68kRegisters r68;
	WriteMacInt32(XLM_68K_R25, gpr(25));
	WriteMacInt32(XLM_RUN_MODE, MODE_EMUL_OP);
	for (int i = 0; i < 8; i++)
		r68.d[i] = gpr(8 + i);
	for (int i = 0; i < 7; i++)
		r68.a[i] = gpr(16 + i);
	r68.a[7] = gpr(1);
	uint32 saved_cr = get_cr() & 0xff9fffff; // mask_operand::compute(11, 8)
	uint32 saved_xer = get_xer();
	EmulOp(&r68, gpr(24), emul_op);
	set_cr(saved_cr);
	set_xer(saved_xer);
	for (int i = 0; i < 8; i++)
		gpr(8 + i) = r68.d[i];
	for (int i = 0; i < 7; i++)
		gpr(16 + i) = r68.a[i];
	gpr(1) = r68.a[7];
	WriteMacInt32(XLM_RUN_MODE, MODE_68K);
}
コード例 #18
0
ファイル: ether.cpp プロジェクト: lewellyn/CockatriceIII
int16 EtherOpen(uint32 pb, uint32 dce)
{
	D(bug("EtherOpen\n"));

	// Allocate driver data
	M68kRegisters r;
	r.d[0] = SIZEOF_etherdata;
	Execute68kTrap(0xa71e, &r);		// NewPtrSysClear()
	if (r.a[0] == 0)
		return openErr;
	ether_data = r.a[0];
	D(bug(" data %08lx\n", ether_data));

	WriteMacInt16(ether_data + ed_DeferredTask + qType, dtQType);
	WriteMacInt32(ether_data + ed_DeferredTask + dtAddr, ether_data + ed_Code);
	WriteMacInt32(ether_data + ed_DeferredTask + dtParam, ether_data + ed_Result);
															// Deferred function for signalling that packet write is complete (pointer to mydtResult in a1)
	WriteMacInt16(ether_data + ed_Code, 0x2019);			//  move.l	(a1)+,d0	(result)
	WriteMacInt16(ether_data + ed_Code + 2, 0x2251);		//  move.l	(a1),a1		(dce)
	WriteMacInt32(ether_data + ed_Code + 4, 0x207808fc);	//  move.l	JIODone,a0
	WriteMacInt16(ether_data + ed_Code + 8, 0x4ed0);		//  jmp		(a0)

	WriteMacInt32(ether_data + ed_DCE, dce);
															// ReadPacket/ReadRest routines
	WriteMacInt16(ether_data + ed_ReadPacket, 0x6010);		//	bra		2
	WriteMacInt16(ether_data + ed_ReadPacket + 2, 0x3003);	//  move.w	d3,d0
	WriteMacInt16(ether_data + ed_ReadPacket + 4, 0x9041);	//  sub.w	d1,d0
	WriteMacInt16(ether_data + ed_ReadPacket + 6, 0x4a43);	//  tst.w	d3
	WriteMacInt16(ether_data + ed_ReadPacket + 8, 0x6702);	//  beq		1
	WriteMacInt16(ether_data + ed_ReadPacket + 10, M68K_EMUL_OP_ETHER_READ_PACKET);
	WriteMacInt16(ether_data + ed_ReadPacket + 12, 0x3600);	//1 move.w	d0,d3
	WriteMacInt16(ether_data + ed_ReadPacket + 14, 0x7000);	//  moveq	#0,d0
	WriteMacInt16(ether_data + ed_ReadPacket + 16, 0x4e75);	//  rts
	WriteMacInt16(ether_data + ed_ReadPacket + 18, M68K_EMUL_OP_ETHER_READ_PACKET);	//2
	WriteMacInt16(ether_data + ed_ReadPacket + 20, 0x4a43);	//  tst.w	d3
	WriteMacInt16(ether_data + ed_ReadPacket + 22, 0x4e75);	//  rts
	return 0;
}
コード例 #19
0
ファイル: gfxaccel.cpp プロジェクト: AlexandreCo/macemu
void VideoInstallAccel(void)
{
	// Install acceleration hooks
	if (PrefsFindBool("gfxaccel")) {
		D(bug("Video: Installing acceleration hooks\n"));
		uint32 base;

		SheepVar bitblt_hook_info(sizeof(accl_hook_info));
		base = bitblt_hook_info.addr();
		WriteMacInt32(base + 0, NativeTVECT(NATIVE_NQD_BITBLT_HOOK));
		WriteMacInt32(base + 4, NativeTVECT(NATIVE_NQD_SYNC_HOOK));
		WriteMacInt32(base + 8, ACCL_BITBLT);
		NQDMisc(6, bitblt_hook_info.addr());

		SheepVar fillrect_hook_info(sizeof(accl_hook_info));
		base = fillrect_hook_info.addr();
		WriteMacInt32(base + 0, NativeTVECT(NATIVE_NQD_FILLRECT_HOOK));
		WriteMacInt32(base + 4, NativeTVECT(NATIVE_NQD_SYNC_HOOK));
		WriteMacInt32(base + 8, ACCL_FILLRECT);
		NQDMisc(6, fillrect_hook_info.addr());

		for (int op = 0; op < 8; op++) {
			switch (op) {
			case ACCL_BITBLT:
			case ACCL_FILLRECT:
				continue;
			}
			SheepVar unknown_hook_info(sizeof(accl_hook_info));
			base = unknown_hook_info.addr();
			WriteMacInt32(base + 0, NativeTVECT(NATIVE_NQD_UNKNOWN_HOOK));
			WriteMacInt32(base + 4, NativeTVECT(NATIVE_NQD_SYNC_HOOK));
			WriteMacInt32(base + 8, op);
			NQDMisc(6, unknown_hook_info.addr());
		}
	}
}
コード例 #20
0
ファイル: serial_amiga.cpp プロジェクト: AlexandreCo/macemu
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;
}
コード例 #21
0
ファイル: gfxaccel.cpp プロジェクト: AlexandreCo/macemu
bool NQD_bitblt_hook(uint32 p)
{
	D(bug("accl_draw_hook %08x\n", p));
	NQD_set_dirty_area(p);

	// Check if we can accelerate this bitblt
	if (ReadMacInt32(p + 0x018) + ReadMacInt32(p + 0x128) == 0 &&
		ReadMacInt32(p + 0x130) == 0 &&
		ReadMacInt32(p + acclSrcPixelSize) >= 8 &&
		ReadMacInt32(p + acclSrcPixelSize) == ReadMacInt32(p + acclDestPixelSize) &&
		(int32)(ReadMacInt32(p + acclSrcRowBytes) ^ ReadMacInt32(p + acclDestRowBytes)) >= 0 &&	// same sign?
		ReadMacInt32(p + acclTransferMode) == 0 &&												// srcCopy?
		(int32)ReadMacInt32(p + 0x15c) > 0) {

		// Yes, set function pointer
		WriteMacInt32(p + acclDrawProc, NativeTVECT(NATIVE_NQD_BITBLT));
		return true;
	}
	return false;
}
コード例 #22
0
ファイル: serial_unix.cpp プロジェクト: dougmencken/macemu
int16 XSERDPort::status(uint32 pb, uint32 dce, uint16 code)
{
	switch (code) {
		case kSERDInputCount: {
			int num;
			ioctl(fd, FIONREAD, &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 (protocol != serial) {
				WriteMacInt8(p + staCtsHold, 0);
				WriteMacInt8(p + staDsrHold, 0);
				WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent);
			} else {
				unsigned int status;
				ioctl(fd, TIOCMGET, &status);
				WriteMacInt8(p + staCtsHold, status & TIOCM_CTS ? 0 : 1);
				WriteMacInt8(p + staDsrHold, status & TIOCM_DTR ? 0 : 1);
				WriteMacInt8(p + staModemStatus,
					(status & TIOCM_DSR ? dsrEvent : 0)
					| (status & TIOCM_RI ? riEvent : 0)
					| (status & TIOCM_CD ? dcdEvent : 0)
					| (status & TIOCM_CTS ? ctsEvent : 0));
			}
			return noErr;
		}

		default:
			printf("WARNING: SerialStatus(): unimplemented status code %d\n", code);
			return statusErr;
	}
}
コード例 #23
0
ファイル: serial_amiga.cpp プロジェクト: AlexandreCo/macemu
__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);
}
コード例 #24
0
ファイル: thunks.cpp プロジェクト: Klozz/iwidarwin
static void generate_powerpc_thunks(void)
{
	// check_load_invoc() thunk
	uint32 check_load_invoc_opcode = NativeOpcode(NATIVE_CHECK_LOAD_INVOC);
	uint32 base;

	static uint32 get_resource_template[] = {
		PL(0x7c0802a6),		// mflr    r0
		PL(0x90010008),		// stw     r0,8(r1)
		PL(0x9421ffbc),		// stwu    r1,-68(r1)
		PL(0x90610038),		// stw     r3,56(r1)
		PL(0x9081003c),		// stw     r4,60(r1)
		PL(0x00000000),		// lwz     r0,XLM_GET_RESOURCE(r0)
		PL(0x80402834),		// lwz     r2,XLM_RES_LIB_TOC(r0)
		PL(0x7c0903a6),		// mtctr   r0
		PL(0x4e800421),		// bctrl
		PL(0x90610040),		// stw     r3,64(r1)
		PL(0x80610038),		// lwz     r3,56(r1)
		PL(0xa881003e),		// lha     r4,62(r1)
		PL(0x80a10040),		// lwz     r5,64(r1)
		PL(0x00000001),		// <check_load_invoc>
		PL(0x80610040),		// lwz     r3,64(r1)
		PL(0x8001004c),		// lwz     r0,76(r1)
		PL(0x7c0803a6),		// mtlr    r0
		PL(0x38210044),		// addi    r1,r1,68
		PL(0x4e800020)		// blr
	};
	const uint32 get_resource_template_size = sizeof(get_resource_template);

	int xlm_index = -1, check_load_invoc_index = -1;
	for (int i = 0; i < get_resource_template_size/4; i++) {
		uint32 opcode = ntohl(get_resource_template[i]);
		switch (opcode) {
		case 0x00000000:
			xlm_index = i;
			break;
		case 0x00000001:
			check_load_invoc_index = i;
			break;
		}
	}
	assert(xlm_index != -1 && check_load_invoc_index != -1);

	// GetResource()
	get_resource_func = base = SheepMem::Reserve(get_resource_template_size);
	Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
	WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_RESOURCE);
	WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);

	// Get1Resource()
	get_1_resource_func = base = SheepMem::Reserve(get_resource_template_size);
	Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
	WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_1_RESOURCE);
	WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);

	// GetIndResource()
	get_ind_resource_func = base = SheepMem::Reserve(get_resource_template_size);
	Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
	WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_IND_RESOURCE);
	WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);

	// Get1IndResource()
	get_1_ind_resource_func = base = SheepMem::Reserve(get_resource_template_size);
	Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
	WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_1_IND_RESOURCE);
	WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);

	// RGetResource()
	r_get_resource_func = base = SheepMem::Reserve(get_resource_template_size);
	Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
	WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_R_GET_RESOURCE);
	WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);

	// named_check_load_invoc() thunk
	check_load_invoc_opcode = NativeOpcode(NATIVE_NAMED_CHECK_LOAD_INVOC);

	static uint32 get_named_resource_template[] = {
		PL(0x7c0802a6),		// mflr    r0
		PL(0x90010008),		// stw     r0,8(r1)
		PL(0x9421ffbc),		// stwu    r1,-68(r1)
		PL(0x90610038),		// stw     r3,56(r1)
		PL(0x9081003c),		// stw     r4,60(r1)
		PL(0x00000000),		// lwz     r0,XLM_GET_NAMED_RESOURCE(r0)
		PL(0x80402834),		// lwz     r2,XLM_RES_LIB_TOC(r0)
		PL(0x7c0903a6),		// mtctr   r0
		PL(0x4e800421),		// bctrl
		PL(0x90610040),		// stw     r3,64(r1)
		PL(0x80610038),		// lwz     r3,56(r1)
		PL(0x8081003c),		// lwz     r4,60(r1)
		PL(0x80a10040),		// lwz     r5,64(r1)
		PL(0x00000001),		// <named_check_load_invoc>
		PL(0x80610040),		// lwz     r3,64(r1)
		PL(0x8001004c),		// lwz     r0,76(r1)
		PL(0x7c0803a6),		// mtlr    r0
		PL(0x38210044),		// addi    r1,r1,68
		PL(0x4e800020)		// blr
	};
	const uint32 get_named_resource_template_size = sizeof(get_named_resource_template);

	xlm_index = -1, check_load_invoc_index = -1;
	for (int i = 0; i < get_resource_template_size/4; i++) {
		uint32 opcode = ntohl(get_resource_template[i]);
		switch (opcode) {
		case 0x00000000:
			xlm_index = i;
			break;
		case 0x00000001:
			check_load_invoc_index = i;
			break;
		}
	}
	assert(xlm_index != -1 && check_load_invoc_index != -1);

	// GetNamedResource()
	get_named_resource_func = base = SheepMem::Reserve(get_named_resource_template_size);
	Host2Mac_memcpy(base, get_named_resource_template, get_named_resource_template_size);
	WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_NAMED_RESOURCE);
	WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);

	// Get1NamedResource()
	get_1_named_resource_func = base = SheepMem::Reserve(get_named_resource_template_size);
	Host2Mac_memcpy(base, get_named_resource_template, get_named_resource_template_size);
	WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_1_NAMED_RESOURCE);
	WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
}
コード例 #25
0
ファイル: thunks.cpp プロジェクト: Klozz/iwidarwin
bool ThunksInit(void)
{
#if EMULATED_PPC
	for (int i = 0; i < NATIVE_OP_MAX; i++) {
		uintptr base = SheepMem::Reserve(16);
		WriteMacInt32(base + 0, base + 8);
		WriteMacInt32(base + 4, 0); // Fake TVECT
		WriteMacInt32(base + 8, NativeOpcode(i));
		WriteMacInt32(base + 12, POWERPC_BLR);
		native_op[i].tvect = base;
		native_op[i].func  = base + 8;
	}
#if POWERPC_GET_RESOURCE_THUNKS
	generate_powerpc_thunks();
	native_op[NATIVE_GET_RESOURCE].func = get_resource_func;
	native_op[NATIVE_GET_1_RESOURCE].func = get_1_resource_func;
	native_op[NATIVE_GET_IND_RESOURCE].func = get_ind_resource_func;
	native_op[NATIVE_GET_1_IND_RESOURCE].func = get_1_ind_resource_func;
	native_op[NATIVE_R_GET_RESOURCE].func = r_get_resource_func;
	native_op[NATIVE_GET_NAMED_RESOURCE].func = get_named_resource_func;
	native_op[NATIVE_GET_1_NAMED_RESOURCE].func = get_1_named_resource_func;
#endif
#else
#if defined(__linux__) || defined(__NetBSD__) || (defined(__APPLE__) && defined(__MACH__))
#define DEFINE_NATIVE_OP(ID, FUNC) do {				\
		uintptr base = SheepMem::Reserve(8);		\
		WriteMacInt32(base + 0, (uint32)FUNC);		\
		WriteMacInt32(base + 4, (uint32)TOC);		\
		native_op[ID].tvect = base;					\
		native_op[ID].func  = (uint32)FUNC;			\
	} while (0)
#elif defined(__BEOS__)
#define DEFINE_NATIVE_OP(ID, FUNC) do {				\
		native_op[ID].tvect = FUNC;					\
		native_op[ID].func  = ((uint32 *)FUNC)[0];	\
	} while (0)
#else
#error "FIXME: define NativeOp for your platform"
#endif
	// FIXME: add GetResource() and friends for completeness
	DEFINE_NATIVE_OP(NATIVE_PATCH_NAME_REGISTRY, DoPatchNameRegistry);
	DEFINE_NATIVE_OP(NATIVE_VIDEO_INSTALL_ACCEL, VideoInstallAccel);
	DEFINE_NATIVE_OP(NATIVE_VIDEO_VBL, VideoVBL);
	DEFINE_NATIVE_OP(NATIVE_VIDEO_DO_DRIVER_IO, VideoDoDriverIO);
	DEFINE_NATIVE_OP(NATIVE_ETHER_AO_GET_HWADDR, AO_get_ethernet_address);
	DEFINE_NATIVE_OP(NATIVE_ETHER_AO_ADD_MULTI, AO_enable_multicast);
	DEFINE_NATIVE_OP(NATIVE_ETHER_AO_DEL_MULTI, AO_disable_multicast);
	DEFINE_NATIVE_OP(NATIVE_ETHER_AO_SEND_PACKET, AO_transmit_packet);
	DEFINE_NATIVE_OP(NATIVE_ETHER_IRQ, EtherIRQ);
	DEFINE_NATIVE_OP(NATIVE_ETHER_INIT, InitStreamModule);
	DEFINE_NATIVE_OP(NATIVE_ETHER_TERM, TerminateStreamModule);
	DEFINE_NATIVE_OP(NATIVE_ETHER_OPEN, ether_open);
	DEFINE_NATIVE_OP(NATIVE_ETHER_CLOSE, ether_close);
	DEFINE_NATIVE_OP(NATIVE_ETHER_WPUT, ether_wput);
	DEFINE_NATIVE_OP(NATIVE_ETHER_RSRV, ether_rsrv);
	DEFINE_NATIVE_OP(NATIVE_SERIAL_NOTHING, SerialNothing);
	DEFINE_NATIVE_OP(NATIVE_SERIAL_OPEN, SerialOpen);
	DEFINE_NATIVE_OP(NATIVE_SERIAL_PRIME_IN, SerialPrimeIn);
	DEFINE_NATIVE_OP(NATIVE_SERIAL_PRIME_OUT, SerialPrimeOut);
	DEFINE_NATIVE_OP(NATIVE_SERIAL_CONTROL, SerialControl);
	DEFINE_NATIVE_OP(NATIVE_SERIAL_STATUS, SerialStatus);
	DEFINE_NATIVE_OP(NATIVE_SERIAL_CLOSE, SerialClose);
	DEFINE_NATIVE_OP(NATIVE_MAKE_EXECUTABLE, MakeExecutable);
	DEFINE_NATIVE_OP(NATIVE_NQD_SYNC_HOOK, NQD_sync_hook);
	DEFINE_NATIVE_OP(NATIVE_NQD_BITBLT_HOOK, NQD_bitblt_hook);
	DEFINE_NATIVE_OP(NATIVE_NQD_FILLRECT_HOOK, NQD_fillrect_hook);
	DEFINE_NATIVE_OP(NATIVE_NQD_UNKNOWN_HOOK, NQD_unknown_hook);
	DEFINE_NATIVE_OP(NATIVE_NQD_BITBLT, NQD_bitblt);
	DEFINE_NATIVE_OP(NATIVE_NQD_INVRECT, NQD_invrect);
	DEFINE_NATIVE_OP(NATIVE_NQD_FILLRECT, NQD_fillrect);
#undef DEFINE_NATIVE_OP
#endif

	// Initialize routine descriptors (if TVECT exists)
	for (int i = 0; i < NATIVE_OP_MAX; i++) {
		uint32 tvect = native_op[i].tvect;
		if (tvect)
			native_op[i].desc = new SheepRoutineDescriptor(0, tvect);
	}

	return true;
}
コード例 #26
0
ファイル: main_windows.cpp プロジェクト: tycho/sheepshaver
void EnableInterrupt(void)
{
	WriteMacInt32(XLM_IRQ_NEST, int32(ReadMacInt32(XLM_IRQ_NEST)) - 1);
}
コード例 #27
0
ファイル: main_windows.cpp プロジェクト: tycho/sheepshaver
void DisableInterrupt(void)
{
	WriteMacInt32(XLM_IRQ_NEST, int32(ReadMacInt32(XLM_IRQ_NEST)) + 1);
}
コード例 #28
0
ファイル: timer.cpp プロジェクト: amade/SheepShaver_oldstuff
int16 PrimeTime(uint32 tm, int32 time)
{
	D(bug("PrimeTime %08lx, time %ld\n", tm, time));

	// Find descriptor
	TMDesc *desc = find_desc(tm);
	if (!desc) {
		printf("FATAL: PrimeTime(%08lx): Descriptor not found\n", (long unsigned int)tm);
		return 0;
	}

	// Convert delay time
	tm_time_t delay;
	timer_mac2host_time(delay, time);

	// Extended task?
	if (ReadMacInt16(tm + qType) & 0x4000) {

		// Yes, tmWakeUp set?
		if (ReadMacInt32(tm + tmWakeUp)) {

			// PrimeTime(0) can either mean (a) "the task runs as soon as interrupts are enabled"
			// or (b) "continue previous delay" if an expired task was stopped via RmvTime() and
			// then re-installed using InsXTime(). Since tmWakeUp was set, this is case (b).
			// The remaining time was saved in tmCount by RmvTime().
			if (time == 0) {
				timer_mac2host_time(delay, ReadMacInt16(tm + tmCount));
			}

			// Yes, calculate wakeup time relative to last scheduled time
			tm_time_t wakeup;
			timer_add_time(wakeup, desc->wakeup, delay);
			desc->wakeup = wakeup;

		} else {

			// No, calculate wakeup time relative to current time
			tm_time_t now;
			timer_current_time(now);
			timer_add_time(desc->wakeup, now, delay);
		}

		// Set tmWakeUp to indicate that task was scheduled
		WriteMacInt32(tm + tmWakeUp, 0x12345678);

	} else {

		// Not extended task, calculate wakeup time relative to current time
		tm_time_t now;
		timer_current_time(now);
		timer_add_time(desc->wakeup, now, delay);
	}

	// Make task active and enqueue it in the Time Manager queue
#if PRECISE_TIMING_BEOS
	while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
	suspend_thread(timer_thread);
#endif
#ifdef 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
	WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) | 0x8000);
	enqueue_tm(tm);
#if PRECISE_TIMING
	// Look for next task to be called and set wakeup_time
	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;
#ifdef 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
#ifdef PRECISE_TIMING_MACH
	semaphore_signal(wakeup_time_sem);
	thread_abort(timer_thread);
	thread_resume(timer_thread);
#endif
#ifdef PRECISE_TIMING_POSIX
	pthread_mutex_unlock(&wakeup_time_lock);
	timer_thread_resume();
	assert(suspend_count == 0);
#endif
#endif
	return 0;
}
コード例 #29
0
ファイル: timer.cpp プロジェクト: amade/SheepShaver_oldstuff
int16 RmvTime(uint32 tm)
{
	D(bug("RmvTime %08lx\n", tm));

	// Find descriptor
	TMDesc *desc = find_desc(tm);
	if (!desc) {
		printf("WARNING: RmvTime(%08lx): Descriptor not found\n", (long unsigned int)tm);
		return 0;
	}

	// Task active?
#if PRECISE_TIMING_BEOS
	while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
	suspend_thread(timer_thread);
#endif
#ifdef 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
	if (ReadMacInt16(tm + qType) & 0x8000) {

		// Yes, make task inactive and remove it from the Time Manager queue
		WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x7fff);
		dequeue_tm(tm);
#if PRECISE_TIMING
		// Look for next task to be called and set wakeup_time
		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;
#endif

		// Compute remaining time
		tm_time_t remaining, current;
		timer_current_time(current);
		timer_sub_time(remaining, desc->wakeup, current);
		WriteMacInt32(tm + tmCount, timer_host2mac_time(remaining));
	} else
		WriteMacInt32(tm + tmCount, 0);
	D(bug(" tmCount %ld\n", ReadMacInt32(tm + tmCount)));
#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
#ifdef 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

	// Free descriptor
	free_desc(desc);
	return 0;
}
コード例 #30
0
ファイル: ether_amiga.cpp プロジェクト: dougmencken/macemu
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);
}