コード例 #1
0
ファイル: timer.cpp プロジェクト: lewellyn/CockatriceIII
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);
				}
			}
		}
}
コード例 #2
0
ファイル: ether_windows.cpp プロジェクト: tycho/sheepshaver
// 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);
}
コード例 #3
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;
}
コード例 #4
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;
}
コード例 #5
0
ファイル: ether_amiga.cpp プロジェクト: dougmencken/macemu
static __saveds __regargs LONG copy_from_buff(uint8 *to /*a0*/, char *wds /*a1*/, uint32 packet_len /*d0*/)
{
	D(bug("CopyFromBuff to %08lx, wds %08lx, size %08lx\n", to, wds, packet_len));
#if MONITOR
	bug("Sending Ethernet packet:\n");
#endif
	for (;;) {
		int len = ReadMacInt16((uint32)wds);
		if (len == 0)
			break;
#if MONITOR
		uint8 *adr = Mac2HostAddr(ReadMacInt32((uint32)wds + 2));
		for (int i=0; i<len; i++) {
			bug("%02lx ", adr[i]);
		}
#endif
		CopyMem(Mac2HostAddr(ReadMacInt32((uint32)wds + 2)), to, len);
		to += len;
		wds += 6;
	}
#if MONITOR
	bug("\n");
#endif
	return 1;
}
コード例 #6
0
ファイル: gfxaccel.cpp プロジェクト: AlexandreCo/macemu
// Pass-through dirty areas to redraw functions
static inline void NQD_set_dirty_area(uint32 p)
{
	if (ReadMacInt32(p + acclDestBaseAddr) == screen_base) {
		int16 x = (int16)ReadMacInt16(p + acclDestRect + 2) - (int16)ReadMacInt16(p + acclDestBoundsRect + 2);
		int16 y = (int16)ReadMacInt16(p + acclDestRect + 0) - (int16)ReadMacInt16(p + acclDestBoundsRect + 0);
		int16 w  = (int16)ReadMacInt16(p + acclDestRect + 6) - (int16)ReadMacInt16(p + acclDestRect + 2);
		int16 h = (int16)ReadMacInt16(p + acclDestRect + 4) - (int16)ReadMacInt16(p + acclDestRect + 0);
		video_set_dirty_area(x, y, w, h);
	}
}
コード例 #7
0
ファイル: macos_util.cpp プロジェクト: dougmencken/macemu
static bool is_drive_number_free(int num)
{
	uint32 e = ReadMacInt32(0x308 + qHead);
	while (e) {
		uint32 d = e - dsQLink;
		if ((int)ReadMacInt16(d + dsQDrive) == num)
			return false;
		e = ReadMacInt32(e + qLink);
	}
	return true;
}
コード例 #8
0
ファイル: timer.cpp プロジェクト: habnabit/macemu
int16 InsTime(uint32 tm, uint16 trap)
{
	D(bug("InsTime %08lx, trap %04x\n", tm, trap));
	WriteMacInt16((uint32)tm + qType, ReadMacInt16((uint32)tm + qType) & 0x1fff | (trap << 4) & 0x6000);
	if (the_app->find_desc(tm))
		printf("WARNING: InsTime(%08lx): Task re-inserted\n", tm);
	else {
		the_app->add_desc(tm);
	}
	return 0;
}
コード例 #9
0
ファイル: timer.cpp プロジェクト: lewellyn/CockatriceIII
int16 InsTime(uint32 tm, uint16 trap)
{
	D(bug("InsTime %08lx, trap %04x\n", tm, trap));
	WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x1fff | (trap << 4) & 0x6000);
	if (find_desc(tm) >= 0)
		printf("WARNING: InsTime(): Task re-inserted\n");
	else {
		int i = alloc_desc(tm);
		if (i < 0)
			printf("FATAL: InsTime(): No free Time Manager descriptor\n");
	}
	return 0;
}
コード例 #10
0
ファイル: timer.cpp プロジェクト: amade/SheepShaver_oldstuff
int16 InsTime(uint32 tm, uint16 trap)
{
	D(bug("InsTime %08lx, trap %04x\n", tm, trap));
	WriteMacInt16((uint32)tm + qType, ReadMacInt16((uint32)tm + qType) & 0x1fff | (trap << 4) & 0x6000);
	if (find_desc(tm))
		printf("WARNING: InsTime(%08lx): Task re-inserted\n", (long unsigned int)tm);
	else {
		TMDesc *desc = new TMDesc;
		desc->task = tm;
		desc->next = tmDescList;
		tmDescList = desc;
	}
	return 0;
}
コード例 #11
0
ファイル: serial_amiga.cpp プロジェクト: AlexandreCo/macemu
void ASERDPort::set_handshake(uint32 s, bool with_dtr)
{
	D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n",
		ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3),
		ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7)));

	err_mask = ReadMacInt8(s + shkErrs);

	if (is_parallel) {

		// Parallel handshake
		if (with_dtr) {
			if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR))
				((IOExtPar *)control_io)->io_ParFlags |= PARF_ACKMODE;
			else
				((IOExtPar *)control_io)->io_ParFlags &= ~PARF_ACKMODE;
		} else {
			if (ReadMacInt8(s + shkFCTS))
				((IOExtPar *)control_io)->io_ParFlags |= PARF_ACKMODE;
			else
				((IOExtPar *)control_io)->io_ParFlags &= ~PARF_ACKMODE;
		}
		set_par_params();

	} else {

		// Serial handshake
		if (ReadMacInt8(s + shkFXOn) || ReadMacInt8(s + shkFInX))
			control_io->io_SerFlags &= ~SERF_XDISABLED;
		else
			control_io->io_SerFlags |= SERF_XDISABLED;

		if (with_dtr) {
			if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR))
				control_io->io_SerFlags |= SERF_7WIRE;
			else
				control_io->io_SerFlags &= ~SERF_7WIRE;
		} else {
			if (ReadMacInt8(s + shkFCTS))
				control_io->io_SerFlags |= SERF_7WIRE;
			else
				control_io->io_SerFlags &= ~SERF_7WIRE;
		}
		control_io->io_CtlChar = ReadMacInt16(s + shkXOn) << 16;
		set_params();
	}
}
コード例 #12
0
ファイル: gfxaccel.cpp プロジェクト: AlexandreCo/macemu
void NQD_invrect(uint32 p)
{
	D(bug("accl_invrect %08x\n", p));

	// Get inversion parameters
	int16 dest_X = (int16)ReadMacInt16(p + acclDestRect + 2) - (int16)ReadMacInt16(p + acclDestBoundsRect + 2);
	int16 dest_Y = (int16)ReadMacInt16(p + acclDestRect + 0) - (int16)ReadMacInt16(p + acclDestBoundsRect + 0);
	int16 width  = (int16)ReadMacInt16(p + acclDestRect + 6) - (int16)ReadMacInt16(p + acclDestRect + 2);
	int16 height = (int16)ReadMacInt16(p + acclDestRect + 4) - (int16)ReadMacInt16(p + acclDestRect + 0);
	D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y));
	D(bug(" width %d, height %d, bytes_per_row %d\n", width, height, (int32)ReadMacInt32(p + acclDestRowBytes)));

	//!!?? pen_mode == 14

	// And perform the inversion
	const int bpp = bytes_per_pixel(ReadMacInt32(p + acclDestPixelSize));
	const int dest_row_bytes = (int32)ReadMacInt32(p + acclDestRowBytes);
	uint8 *dest = Mac2HostAddr(ReadMacInt32(p + acclDestBaseAddr) + (dest_Y * dest_row_bytes) + (dest_X * bpp));
	width *= bpp;
	switch (bpp) {
	case 1:
		for (int i = 0; i < height; i++) {
			do_invrect<8>(dest, width);
			dest += dest_row_bytes;
		}
		break;
	case 2:
		for (int i = 0; i < height; i++) {
			do_invrect<16>(dest, width);
			dest += dest_row_bytes;
		}
		break;
	case 4:
		for (int i = 0; i < height; i++) {
			do_invrect<32>(dest, width);
			dest += dest_row_bytes;
		}
		break;
	}
}
コード例 #13
0
ファイル: gfxaccel.cpp プロジェクト: AlexandreCo/macemu
void NQD_fillrect(uint32 p)
{
	D(bug("accl_fillrect %08x\n", p));

	// Get filling parameters
	int16 dest_X = (int16)ReadMacInt16(p + acclDestRect + 2) - (int16)ReadMacInt16(p + acclDestBoundsRect + 2);
	int16 dest_Y = (int16)ReadMacInt16(p + acclDestRect + 0) - (int16)ReadMacInt16(p + acclDestBoundsRect + 0);
	int16 width  = (int16)ReadMacInt16(p + acclDestRect + 6) - (int16)ReadMacInt16(p + acclDestRect + 2);
	int16 height = (int16)ReadMacInt16(p + acclDestRect + 4) - (int16)ReadMacInt16(p + acclDestRect + 0);
	uint32 color = htonl(ReadMacInt32(p + acclPenMode) == 8 ? ReadMacInt32(p + acclForePen) : ReadMacInt32(p + acclBackPen));
	D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y));
	D(bug(" width %d, height %d\n", width, height));
	D(bug(" bytes_per_row %d color %08x\n", (int32)ReadMacInt32(p + acclDestRowBytes), color));

	// And perform the fill
	const int bpp = bytes_per_pixel(ReadMacInt32(p + acclDestPixelSize));
	const int dest_row_bytes = (int32)ReadMacInt32(p + acclDestRowBytes);
	uint8 *dest = Mac2HostAddr(ReadMacInt32(p + acclDestBaseAddr) + (dest_Y * dest_row_bytes) + (dest_X * bpp));
	width *= bpp;
	switch (bpp) {
	case 1:
		for (int i = 0; i < height; i++) {
			memset(dest, color, width);
			dest += dest_row_bytes;
		}
		break;
	case 2:
		for (int i = 0; i < height; i++) {
			do_fillrect<16>(dest, color, width);
			dest += dest_row_bytes;
		}
		break;
	case 4:
		for (int i = 0; i < height; i++) {
			do_fillrect<32>(dest, color, width);
			dest += dest_row_bytes;
		}
		break;
	}
}
コード例 #14
0
ファイル: ether_amiga.cpp プロジェクト: dougmencken/macemu
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"));
}
コード例 #15
0
ファイル: emul_op.cpp プロジェクト: Na1w/sheepshear
void EmulOp(M68kRegisters *r, uint32 pc, int selector)
{
	D(bug("EmulOp %04x at %08x\n", selector, pc));
	switch (selector) {
		case OP_BREAK:				// Breakpoint
			printf("*** Breakpoint\n");
			Dump68kRegs(r);
			break;

		case OP_XPRAM1: {			// Read/write from/to XPRam
			uint32 len = r->d[3];
			uint8 *adr = Mac2HostAddr(r->a[3]);
			D(bug("XPRAMReadWrite d3: %08lx, a3: %p\n", len, adr));
			int ofs = len & 0xffff;
			len >>= 16;
			if (len & 0x8000) {
				len &= 0x7fff;
				for (uint32 i=0; i<len; i++)
					XPRAM[((ofs + i) & 0xff) + 0x1300] = *adr++;
			} else {
				for (uint32 i=0; i<len; i++)
					*adr++ = XPRAM[((ofs + i) & 0xff) + 0x1300];
			}
			break;
		}

		case OP_XPRAM2:				// Read from XPRam
			r->d[1] = XPRAM[(r->d[1] & 0xff) + 0x1300];
			break;

		case OP_XPRAM3:				// Write to XPRam
			XPRAM[(r->d[1] & 0xff) + 0x1300] = r->d[2];
			break;

		case OP_NVRAM1: {			// Read from NVRAM
			int ofs = r->d[0];
			r->d[0] = XPRAM[ofs & 0x1fff];
			bool localtalk = !(XPRAM[0x13e0] || XPRAM[0x13e1]);	// LocalTalk enabled?
			switch (ofs) {
				case 0x13e0:			// Disable LocalTalk (use EtherTalk instead)
					if (localtalk)
						r->d[0] = 0x00;
					break;
				case 0x13e1:
					if (localtalk)
						r->d[0] = 0x01;
					break;
				case 0x13e2:
					if (localtalk)
						r->d[0] = 0x00;
					break;
				case 0x13e3:
					if (localtalk)
						r->d[0] = 0x0a;
					break;
			}
			break;
		}

		case OP_NVRAM2:				// Write to NVRAM
			XPRAM[r->d[0] & 0x1fff] = r->d[1];
			break;

		case OP_NVRAM3:				// Read/write from/to NVRAM
			if (r->d[3]) {
				r->d[0] = XPRAM[(r->d[4] + 0x1300) & 0x1fff];
			} else {
				XPRAM[(r->d[4] + 0x1300) & 0x1fff] = r->d[5];
				r->d[0] = 0;
			}
			break;

		case OP_FIX_MEMTOP:			// Fixes MemTop in BootGlobs during startup
			D(bug("Fix MemTop\n"));
			WriteMacInt32(BootGlobsAddr - 20, RAMBase + RAMSize);	// MemTop
			r->a[6] = RAMBase + RAMSize;
			break;

		case OP_FIX_MEMSIZE: {		// Fixes physical/logical RAM size during startup
			D(bug("Fix MemSize\n"));
			uint32 diff = ReadMacInt32(0x1ef8) - ReadMacInt32(0x1ef4);
			WriteMacInt32(0x1ef8, RAMSize);			// Physical RAM size
			WriteMacInt32(0x1ef4, RAMSize - diff);	// Logical RAM size
			break;
		}

		case OP_FIX_BOOTSTACK:		// Fixes boot stack pointer in boot 3 resource
			D(bug("Fix BootStack\n"));
			r->a[1] = r->a[7] = RAMBase + RAMSize * 3 / 4;
			break;

		case OP_SONY_OPEN:			// Floppy driver functions
			r->d[0] = SonyOpen(r->a[0], r->a[1]);
			break;
		case OP_SONY_PRIME:
			r->d[0] = SonyPrime(r->a[0], r->a[1]);
			break;
		case OP_SONY_CONTROL:
			r->d[0] = SonyControl(r->a[0], r->a[1]);
			break;
		case OP_SONY_STATUS:
			r->d[0] = SonyStatus(r->a[0], r->a[1]);
			break;

		case OP_DISK_OPEN:			// Disk driver functions
			r->d[0] = DiskOpen(r->a[0], r->a[1]);
			break;
		case OP_DISK_PRIME:
			r->d[0] = DiskPrime(r->a[0], r->a[1]);
			break;
		case OP_DISK_CONTROL:
			r->d[0] = DiskControl(r->a[0], r->a[1]);
			break;
		case OP_DISK_STATUS:
			r->d[0] = DiskStatus(r->a[0], r->a[1]);
			break;

		case OP_CDROM_OPEN:			// CD-ROM driver functions
			r->d[0] = CDROMOpen(r->a[0], r->a[1]);
			break;
		case OP_CDROM_PRIME:
			r->d[0] = CDROMPrime(r->a[0], r->a[1]);
			break;
		case OP_CDROM_CONTROL:
			r->d[0] = CDROMControl(r->a[0], r->a[1]);
			break;
		case OP_CDROM_STATUS:
			r->d[0] = CDROMStatus(r->a[0], r->a[1]);
			break;

		case OP_AUDIO_DISPATCH:		// Audio component functions
			r->d[0] = gMacAudio->Dispatch(r->a[3], r->a[4]);
			break;

		case OP_SOUNDIN_OPEN:		// Sound input driver functions
			r->d[0] = gMacAudio->InOpen(r->a[0], r->a[1]);
			break;
		case OP_SOUNDIN_PRIME:
			r->d[0] = gMacAudio->InPrime(r->a[0], r->a[1]);
			break;
		case OP_SOUNDIN_CONTROL:
			r->d[0] = gMacAudio->InControl(r->a[0], r->a[1]);
			break;
		case OP_SOUNDIN_STATUS:
			r->d[0] = gMacAudio->InStatus(r->a[0], r->a[1]);
			break;
		case OP_SOUNDIN_CLOSE:
			r->d[0] = gMacAudio->InClose(r->a[0], r->a[1]);
			break;

		case OP_ADBOP:				// ADBOp() replacement
			gADBInput->Op(r->d[0], Mac2HostAddr(ReadMacInt32(r->a[0])));
			break;

		case OP_INSTIME:			// InsTime() replacement
			r->d[0] = InsTime(r->a[0], r->d[1]);
			break;
		case OP_RMVTIME:			// RmvTime() replacement
			r->d[0] = RmvTime(r->a[0]);
			break;
		case OP_PRIMETIME:			// PrimeTime() replacement
			r->d[0] = PrimeTime(r->a[0], r->d[0]);
			break;

		case OP_MICROSECONDS:		// Microseconds() replacement
			Microseconds(r->a[0], r->d[0]);
			break;

		case OP_PUT_SCRAP:			// PutScrap() patch
			PutScrap(ReadMacInt32(r->a[7] + 8), Mac2HostAddr(ReadMacInt32(r->a[7] + 4)), ReadMacInt32(r->a[7] + 12));
			break;

		case OP_GET_SCRAP:			// GetScrap() patch
			GetScrap((void **)Mac2HostAddr(ReadMacInt32(r->a[7] + 4)), ReadMacInt32(r->a[7] + 8), ReadMacInt32(r->a[7] + 12));
			break;

		case OP_DEBUG_STR:			// DebugStr() shows warning message
			if (PrefsFindBool("nogui")) {
				uint8 *pstr = Mac2HostAddr(ReadMacInt32(r->a[7] + 4));
				char str[256];
				int i;
				for (i=0; i<pstr[0]; i++)
					str[i] = pstr[i+1];
				str[i] = 0;
				WarningAlert(str);
			}
			break;

		case OP_INSTALL_DRIVERS: {	// Patch to install our own drivers during startup
			// Install drivers
			InstallDrivers();

			// Patch MakeExecutable()
			MakeExecutableTvec = FindLibSymbol("\023PrivateInterfaceLib", "\016MakeExecutable");
			D(bug("MakeExecutable TVECT at %08x\n", MakeExecutableTvec));
			WriteMacInt32(MakeExecutableTvec, NativeFunction(NATIVE_MAKE_EXECUTABLE));
			
			#if defined(__powerpc__) /* Native PowerPC */
			WriteMacInt32(MakeExecutableTvec + 4, (uint32)TOC);
			#endif

			// Patch DebugStr()
			static const uint8 proc_template[] = {
				M68K_EMUL_OP_DEBUG_STR >> 8, M68K_EMUL_OP_DEBUG_STR & 0xFF,
				0x4e, 0x74,			// rtd	#4
				0x00, 0x04
			};
			BUILD_SHEEPSHAVER_PROCEDURE(proc);
			WriteMacInt32(0x1dfc, proc);
			break;
		}

		case OP_NAME_REGISTRY:		// Patch Name Registry and initialize CallUniversalProc
			r->d[0] = (uint32)-1;
			PatchNameRegistry();
			InitCallUniversalProc();
			break;

		case OP_RESET:				// Early in MacOS reset
			D(bug("*** RESET ***\n"));
			TimerReset();
			MacOSUtilReset();
			gMacAudio->Reset();

			// Enable DR emulator (disabled for now)
			if (PrefsFindBool("jit68k") && 0) {
				D(bug("DR activated\n"));
				WriteMacInt32(KernelDataAddr + 0x17a0, 3);		// Prepare for DR emulator activation
				WriteMacInt32(KernelDataAddr + 0x17c0, DR_CACHE_BASE);
				WriteMacInt32(KernelDataAddr + 0x17c4, DR_CACHE_SIZE);
				WriteMacInt32(KernelDataAddr + 0x1b04, DR_CACHE_BASE);
				WriteMacInt32(KernelDataAddr + 0x1b00, DR_EMULATOR_BASE);
				memcpy((void *)DR_EMULATOR_BASE, (void *)(ROMBase + 0x370000), DR_EMULATOR_SIZE);
				MakeExecutable(0, DR_EMULATOR_BASE, DR_EMULATOR_SIZE);
			}
			break;

		case OP_IRQ:			// Level 1 interrupt
			WriteMacInt16(ReadMacInt32(KernelDataAddr + 0x67c), 0);	// Clear interrupt
			r->d[0] = 0;
			if (HasMacStarted()) {
				if (InterruptFlags & INTFLAG_VIA) {
					ClearInterruptFlag(INTFLAG_VIA);
#if !PRECISE_TIMING
					TimerInterrupt();
#endif
					ExecuteNative(NATIVE_VIDEO_VBL);

					static int tick_counter = 0;
					if (++tick_counter >= 60) {
						tick_counter = 0;
						SonyInterrupt();
						DiskInterrupt();
						CDROMInterrupt();
					}

					r->d[0] = 1;		// Flag: 68k interrupt routine executes VBLTasks etc.
				}
				if (InterruptFlags & INTFLAG_SERIAL) {
					ClearInterruptFlag(INTFLAG_SERIAL);
					SerialInterrupt();
				}
				if (InterruptFlags & INTFLAG_ETHER) {
					ClearInterruptFlag(INTFLAG_ETHER);
					ExecuteNative(NATIVE_ETHER_IRQ);
				}
				if (InterruptFlags & INTFLAG_TIMER) {
					ClearInterruptFlag(INTFLAG_TIMER);
					TimerInterrupt();
				}
				if (InterruptFlags & INTFLAG_AUDIO) {
					ClearInterruptFlag(INTFLAG_AUDIO);
					gMacAudio->Interrupt();
				}
				if (InterruptFlags & INTFLAG_ADB) {
					ClearInterruptFlag(INTFLAG_ADB);
					gADBInput->Interrupt();
				}
			} else
				r->d[0] = 1;
			break;

		case OP_SCSI_DISPATCH: {	// SCSIDispatch() replacement
			uint32 ret = ReadMacInt32(r->a[7]);
			uint16 sel = ReadMacInt16(r->a[7] + 4);
			r->a[7] += 6;
//			D(bug("SCSIDispatch(%d)\n", sel));
			int stack;
			switch (sel) {
				case 0:		// SCSIReset
					WriteMacInt16(r->a[7], SCSIReset());
					stack = 0;
					break;
				case 1:		// SCSIGet
					WriteMacInt16(r->a[7], SCSIGet());
					stack = 0;
					break;
				case 2:		// SCSISelect
				case 11:	// SCSISelAtn
					WriteMacInt16(r->a[7] + 2, SCSISelect(ReadMacInt8(r->a[7] + 1)));
					stack = 2;
					break;
				case 3:		// SCSICmd
					WriteMacInt16(r->a[7] + 6, SCSICmd(ReadMacInt16(r->a[7]), Mac2HostAddr(ReadMacInt32(r->a[7] + 2))));
					stack = 6;
					break;
				case 4:		// SCSIComplete
					WriteMacInt16(r->a[7] + 12, SCSIComplete(ReadMacInt32(r->a[7]), ReadMacInt32(r->a[7] + 4), ReadMacInt32(r->a[7] + 8)));
					stack = 12;
					break;
				case 5:		// SCSIRead
				case 8:		// SCSIRBlind
					WriteMacInt16(r->a[7] + 4, SCSIRead(ReadMacInt32(r->a[7])));
					stack = 4;
					break;
				case 6:		// SCSIWrite
				case 9:		// SCSIWBlind
					WriteMacInt16(r->a[7] + 4, SCSIWrite(ReadMacInt32(r->a[7])));
					stack = 4;
					break;
				case 10:	// SCSIStat
					WriteMacInt16(r->a[7], SCSIStat());
					stack = 0;
					break;
				case 12:	// SCSIMsgIn
					WriteMacInt16(r->a[7] + 4, 0);
					stack = 4;
					break;
				case 13:	// SCSIMsgOut
					WriteMacInt16(r->a[7] + 2, 0);
					stack = 2;
					break;
				case 14:	// SCSIMgrBusy
					WriteMacInt16(r->a[7], SCSIMgrBusy());
					stack = 0;
					break;
				default:
					printf("FATAL: SCSIDispatch: illegal selector\n");
					stack = 0;
					//!! SysError(12)
			}
			r->a[0] = ret;
			r->a[7] += stack;
			break;
		}

		case OP_SCSI_ATOMIC:		// SCSIAtomic() replacement
			D(bug("SCSIAtomic\n"));
			r->d[0] = (uint32)-7887;
			break;

		case OP_CHECK_SYSV: {		// Check we are not using MacOS < 8.1 with a NewWorld ROM
			r->a[1] = r->d[1];
			r->a[0] = ReadMacInt32(r->d[1]);
			uint32 sysv = ReadMacInt16(r->a[0]);
			D(bug("Detected MacOS version %d.%d.%d\n", (sysv >> 8) & 0xf, (sysv >> 4) & 0xf, sysv & 0xf));
			if (ROMType == ROMTYPE_NEWWORLD && sysv < 0x0801)
				r->d[1] = 0;
			break;
		}

		case OP_NTRB_17_PATCH:
			r->a[2] = ReadMacInt32(r->a[7]);
			r->a[7] += 4;
			if (ReadMacInt16(r->a[2] + 6) == 17)
				PatchNativeResourceManager();
			break;

		case OP_NTRB_17_PATCH2:
			r->a[7] += 8;
			PatchNativeResourceManager();
			break;

		case OP_NTRB_17_PATCH3:
			r->a[2] = ReadMacInt32(r->a[7]);
			r->a[7] += 4;
		 	D(bug("%d %d\n", ReadMacInt16(r->a[2]), ReadMacInt16(r->a[2] + 6)));
			if (ReadMacInt16(r->a[2]) == 11 && ReadMacInt16(r->a[2] + 6) == 17)
				PatchNativeResourceManager();
			break;

		case OP_NTRB_17_PATCH4:
			r->d[0] = ReadMacInt16(r->a[7]);
			r->a[7] += 2;
		 	D(bug("%d %d\n", ReadMacInt16(r->a[2]), ReadMacInt16(r->a[2] + 6)));
			if (ReadMacInt16(r->a[2]) == 11 && ReadMacInt16(r->a[2] + 6) == 17)
				PatchNativeResourceManager();
			break;

		case OP_CHECKLOAD: {		// vCheckLoad() patch
			uint32 type = ReadMacInt32(r->a[7]);
			r->a[7] += 4;
			int16 id = ReadMacInt16(r->a[2]);
			if (r->a[0] == 0)
				break;
			uint32 adr = ReadMacInt32(r->a[0]);
			if (adr == 0)
				break;
			uint16 *p = (uint16 *)Mac2HostAddr(adr);
			uint32 size = ReadMacInt32(adr - 8) & 0xffffff;
			CheckLoad(type, id, p, size);
			break;
		}

		case OP_EXTFS_COMM:			// External file system routines
			WriteMacInt16(r->a[7] + 14, ExtFSComm(ReadMacInt16(r->a[7] + 12), ReadMacInt32(r->a[7] + 8), ReadMacInt32(r->a[7] + 4)));
			break;

		case OP_EXTFS_HFS:
			WriteMacInt16(r->a[7] + 20, ExtFSHFS(ReadMacInt32(r->a[7] + 16), ReadMacInt16(r->a[7] + 14), ReadMacInt32(r->a[7] + 10), ReadMacInt32(r->a[7] + 6), ReadMacInt16(r->a[7] + 4)));
			break;

		case OP_IDLE_TIME:
			// Sleep if no events pending
			if (ReadMacInt32(0x14c) == 0)
				idle_wait();
			r->a[0] = ReadMacInt32(0x2b6);
			break;

		case OP_IDLE_TIME_2:
			// Sleep if no events pending
			if (ReadMacInt32(0x14c) == 0)
				idle_wait();
			r->d[0] = (uint32)-2;
			break;

		default:
			printf("FATAL: EMUL_OP called with bogus selector %08x\n", selector);
			QuitEmulator();
			break;
	}
}
コード例 #16
0
ファイル: serial_amiga.cpp プロジェクト: AlexandreCo/macemu
int16 ASERDPort::control(uint32 pb, uint32 dce, uint16 code)
{
	D(bug("control(%ld)\n", (uint32)code));
	switch (code) {
		case 1:			// KillIO
			send_to_proc(MSG_KILL_IO);
			return noErr;

		case kSERDConfiguration:
			if (configure(ReadMacInt16(pb + csParam)))
				return noErr;
			else
				return paramErr;

		case kSERDInputBuffer: {
			if (is_parallel)
				return noErr;
			int buf = ReadMacInt16(pb + csParam + 4) & 0xffffffc0;
			if (buf < 1024)	// 1k minimum
				buf = 1024;
			D(bug(" buffer size is now %08lx\n", buf));
			control_io->io_RBufLen = buf;
			return set_params() ? noErr : paramErr;
		}

		case kSERDSerHShake:
			set_handshake(pb + csParam, false);
			return noErr;

		case kSERDSetBreak:
			if (!is_parallel)
				send_to_proc(MSG_BREAK);
			return noErr;

		case kSERDClearBreak:
			return noErr;

		case kSERDBaudRate:
			if (is_parallel)
				return noErr;
			control_io->io_Baud = ReadMacInt16(pb + csParam);
			D(bug(" baud rate %ld\n", control_io->io_Baud));
			return set_params() ? noErr : paramErr;

		case kSERDHandshake:
		case kSERDHandshakeRS232:
			set_handshake(pb + csParam, true);
			return noErr;

		case kSERDClockMIDI:
			if (is_parallel)
				return noErr;
			control_io->io_Baud = 31250;
			control_io->io_SerFlags = SERF_XDISABLED | SERF_SHARED;
			control_io->io_StopBits = 1;
			control_io->io_ReadLen = control_io->io_WriteLen = 8;
			return set_params() ? noErr : paramErr;

		case kSERDMiscOptions:
		case kSERDAssertDTR:
		case kSERDNegateDTR:
		case kSERDSetPEChar:
		case kSERDSetPEAltChar:
		case kSERDAssertRTS:
		case kSERDNegateRTS:
			return noErr;	// Not supported under AmigaOS

		case kSERD115KBaud:
			if (is_parallel)
				return noErr;
			control_io->io_Baud = 115200;
			return set_params() ? noErr : paramErr;

		case kSERD230KBaud:
		case kSERDSetHighSpeed:
			if (is_parallel)
				return noErr;
			control_io->io_Baud = 230400;
			return set_params() ? noErr : paramErr;

		case kSERDResetChannel:
			send_to_proc(MSG_RESET);
			return noErr;

		default:
			printf("WARNING: SerialControl(): unimplemented control code %d\n", code);
			return controlErr;
	}
}
コード例 #17
0
ファイル: timer.cpp プロジェクト: amade/SheepShaver_oldstuff
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
}
コード例 #18
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;
}
コード例 #19
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;
}
コード例 #20
0
ファイル: serial_unix.cpp プロジェクト: dougmencken/macemu
int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
{
	switch (code) {
		case 1:			// KillIO
			io_killed = true;
			if (protocol == serial)
				tcflush(fd, TCIOFLUSH);
			while (read_pending || write_pending)
				usleep(10000);
			io_killed = false;
			return noErr;

		case kSERDConfiguration:
			if (configure(ReadMacInt16(pb + csParam)))
				return noErr;
			else
				return paramErr;

		case kSERDInputBuffer:
			return noErr;	// Not supported under Unix

		case kSERDSerHShake:
			set_handshake(pb + csParam, false);
			return noErr;

		case kSERDSetBreak:
			if (protocol == serial)
				tcsendbreak(fd, 0);
			return noErr;

		case kSERDClearBreak:
			return noErr;

		case kSERDBaudRate: {
			if (protocol != serial)
				return noErr;
			uint16 rate = ReadMacInt16(pb + csParam);
			speed_t baud_rate;
			if (rate <= 50) {
				rate = 50; baud_rate = B50;
			} else if (rate <= 75) {
				rate = 75; baud_rate = B75;
			} else if (rate <= 110) {
				rate = 110; baud_rate = B110;
			} else if (rate <= 134) {
				rate = 134; baud_rate = B134;
			} else if (rate <= 150) {
				rate = 150; baud_rate = B150;
			} else if (rate <= 200) {
				rate = 200; baud_rate = B200;
			} else if (rate <= 300) {
				rate = 300; baud_rate = B300;
			} else if (rate <= 600) {
				rate = 600; baud_rate = B600;
			} else if (rate <= 1200) {
				rate = 1200; baud_rate = B1200;
			} else if (rate <= 1800) {
				rate = 1800; baud_rate = B1800;
			} else if (rate <= 2400) {
				rate = 2400; baud_rate = B2400;
			} else if (rate <= 4800) {
				rate = 4800; baud_rate = B4800;
			} else if (rate <= 9600) {
				rate = 9600; baud_rate = B9600;
			} else if (rate <= 19200) {
				rate = 19200; baud_rate = B19200;
			} else if (rate <= 38400) {
				rate = 38400; baud_rate = B38400;
			} else if (rate <= 57600) {
				rate = 57600; baud_rate = B57600;
			} else {
				// Just for safety in case someone wants a rate between 57600 and 65535
				rate = 57600; baud_rate = B57600;
			}
			WriteMacInt16(pb + csParam, rate);
			cfsetispeed(&mode, baud_rate);
			cfsetospeed(&mode, baud_rate);
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;
		}

		case kSERDHandshake:
		case kSERDHandshakeRS232:
			set_handshake(pb + csParam, true);
			return noErr;

		case kSERDMiscOptions:
			if (protocol != serial)
				return noErr;
			if (ReadMacInt8(pb + csParam) & kOptionPreserveDTR)
				mode.c_cflag &= ~HUPCL;
			else
				mode.c_cflag |= HUPCL;
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;

		case kSERDAssertDTR: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_DTR;
			ioctl(fd, TIOCMBIS, &status);
			return noErr;
		}

		case kSERDNegateDTR: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_DTR;
			ioctl(fd, TIOCMBIC, &status);
			return noErr;
		}

		case kSERDSetPEChar:
		case kSERDSetPEAltChar:
			return noErr;	// Not supported under Unix

		case kSERDResetChannel:
			if (protocol == serial)
				tcflush(fd, TCIOFLUSH);
			return noErr;

		case kSERDAssertRTS: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_RTS;
			ioctl(fd, TIOCMBIS, &status);
			return noErr;
		}

		case kSERDNegateRTS: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_RTS;
			ioctl(fd, TIOCMBIC, &status);
			return noErr;
		}

		case kSERD115KBaud:
			if (protocol != serial)
				return noErr;
			cfsetispeed(&mode, B115200);
			cfsetospeed(&mode, B115200);
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;

		case kSERD230KBaud:
		case kSERDSetHighSpeed:
			if (protocol != serial)
				return noErr;
			cfsetispeed(&mode, B230400);
			cfsetospeed(&mode, B230400);
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;

		default:
			printf("WARNING: SerialControl(): unimplemented control code %d\n", code);
			return controlErr;
	}
}
コード例 #21
0
ファイル: extfs_beos.cpp プロジェクト: Na1w/sheepshear
			}
		}

		// Set MACOS:CREATOR attribute
		uint32 creator = ReadMacInt32(finfo + fdCreator);
		if (creator) {
			tmp_buf[0] = creator >> 24;
			tmp_buf[1] = creator >> 16;
			tmp_buf[2] = creator >> 8;
			tmp_buf[3] = creator;
			fs_write_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, tmp_buf, 4);
		}
	}

	// Write MACOS:HFS_FLAGS attribute
	uint16 flags = ReadMacInt16(finfo + fdFlags);
	if (flags != DEFAULT_FINDER_FLAGS) {
		tmp_buf[0] = flags >> 8;
		tmp_buf[1] = flags;
		fs_write_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, tmp_buf, 2);
	} else
		fs_remove_attr(fd, "MACOS:HFS_FLAGS");

	// Close file
	close(fd);
}


/*
 *  Resource fork emulation functions
 */
コード例 #22
0
ファイル: ether.cpp プロジェクト: lewellyn/CockatriceIII
int16 EtherControl(uint32 pb, uint32 dce)
{
	uint16 code = ReadMacInt16(pb + csCode);
	D(bug("EtherControl %d\n", code));
	switch (code) {
		case 1:		// KillIO
			return -1;

		case kENetAddMulti:		// Add multicast address
			D(bug("AddMulti %08lx%04x\n", ReadMacInt32(pb + eMultiAddr), ReadMacInt16(pb + eMultiAddr + 4)));
			if (net_open)
				return ether_add_multicast(pb);
			else
				return noErr;

		case kENetDelMulti:		// Delete multicast address
			D(bug("DelMulti %08lx%04x\n", ReadMacInt32(pb + eMultiAddr), ReadMacInt16(pb + eMultiAddr + 4)));
			if (net_open)
				return ether_del_multicast(pb);
			else
				return noErr;

		case kENetAttachPH:		// Attach protocol handler
			D(bug("AttachPH prot %04x, handler %08lx\n", ReadMacInt16(pb + eProtType), ReadMacInt32(pb + ePointer)));
			if (net_open)
				return ether_attach_ph(ReadMacInt16(pb + eProtType), ReadMacInt32(pb + ePointer));
			else
				return noErr;

		case kENetDetachPH:		// Detach protocol handler
			D(bug("DetachPH prot %04x\n", ReadMacInt16(pb + eProtType)));
			if (net_open)
				return ether_detach_ph(ReadMacInt16(pb + eProtType));
			else
				return noErr;

		case kENetWrite:		// Transmit raw Ethernet packet
			D(bug("EtherWrite\n"));
			if (ReadMacInt16(ReadMacInt32(pb + ePointer)) < 14)
				return eLenErr;	// Header incomplete
			if (net_open)
				return ether_write(ReadMacInt32(pb + ePointer));
			else
				return noErr;

		case kENetGetInfo: {	// Get device information/statistics
			D(bug("GetInfo buf %08lx, size %d\n", ReadMacInt32(pb + ePointer), ReadMacInt16(pb + eBuffSize)));

			// Collect info (only ethernet address)
			uint8 buf[18];
			memset(buf, 0, 18);
			memcpy(buf, ether_addr, 6);

			// Transfer info to supplied buffer
			int16 size = ReadMacInt16(pb + eBuffSize);
			if (size > 18)
				size = 18;
			WriteMacInt16(pb + eDataSize, size);	// Number of bytes actually written
			Host2Mac_memcpy(ReadMacInt32(pb + ePointer), buf, size);
			return noErr;
		}

		case kENetSetGeneral:	// Set general mode (always in general mode)
			D(bug("SetGeneral\n"));
			return noErr;

		default:
			printf("WARNING: Unknown EtherControl(%d)\n", code);
			return controlErr;
	}
}
コード例 #23
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);
}
コード例 #24
0
ファイル: posix_emu.cpp プロジェクト: DavidLudwig/macemu
// !!UNC
void init_posix_emu(void)
{
	if(!validate_stat_struct) {
		ErrorAlert( "Invalid struct my_stat -- edit posix_emu.h" );
		QuitEmulator();
	}

#if DEBUG_EXTFS
	debug_extfs = PrefsFindInt16("debugextfs");

	debug_extfs = DB_EXTFS_LOUD;

	if(debug_extfs != DB_EXTFS_NONE) {
		extfs_log_open( EXTFS_LOG_FILE_NAME );
	}
#endif

	// We cannot use ExtFS "RootPath" because of the virtual desktop.
	if(PrefsFindBool("enableextfs")) {
		PrefsReplaceString("extfs", "");
	} else {
		PrefsRemoveItem("extfs");
		D(bug("extfs disabled by user\n"));
#if DEBUG_EXTFS
		extfs_log_close();
#endif
		return;
	}

	const char *extdrives = PrefsFindString("extdrives");

	// Set up drive list.
	size_t outinx = 0;
	for( TCHAR letter = TEXT('A'); letter <= TEXT('Z'); letter++ ) {
		if(extdrives && !strchr(extdrives,letter)) continue;
		TCHAR rootdir[20];
		_sntprintf( rootdir, lengthof(rootdir), TEXT("%c:\\"), letter );
		use_streams[ letter - 'A' ] = false;
		switch(GetDriveType(rootdir)) {
			case DRIVE_FIXED:
			case DRIVE_REMOTE:
			case DRIVE_RAMDISK:
				// TODO: NTFS AFP?
				// fall
			case DRIVE_REMOVABLE:
			case DRIVE_CDROM:
				if(outinx < lengthof(host_drive_list)) {
					host_drive_list[outinx] = letter;
					outinx += 2;
				}
		}
	}

	// Set up virtual desktop root.
	// TODO: this should be customizable.
	GetModuleFileName( NULL, virtual_root, lengthof(virtual_root) );
	TCHAR *p = _tcsrchr( virtual_root, TEXT('\\') );
	if(p) {
		_tcscpy( ++p, desktop_name );
	} else {
		// should never happen
		_sntprintf( virtual_root, lengthof(virtual_root), TEXT("C:\\%s"), desktop_name );
	}
	CreateDirectory( virtual_root, 0 );

	// Set up an icon looking like "My Computer"
	// Can be overwritten just like any other folder custom icon.
	if(my_access(custom_icon_name,0) != 0) {
		int fd = my_creat( custom_icon_name, 0 );
		if(fd >= 0) {
			my_close(fd);
			fd = open_rfork( custom_icon_name, O_RDWR|O_CREAT );
			if(fd >= 0) {
				my_write( fd, my_comp_icon, sizeof(my_comp_icon) );
				my_close(fd);
				static uint8 host_finfo[SIZEOF_FInfo];
				uint32 finfo = Host2MacAddr(host_finfo);
				get_finfo(custom_icon_name, finfo, 0, false);
				WriteMacInt16(finfo + fdFlags, kIsInvisible);
				set_finfo(custom_icon_name, finfo, 0, false);
				get_finfo(my_computer, finfo, 0, true);
				WriteMacInt16(finfo + fdFlags, ReadMacInt16(finfo + fdFlags) | kHasCustomIcon);
				set_finfo(my_computer, finfo, 0, true);
			} else {
				my_remove(custom_icon_name);
			}
		}
	}
}
コード例 #25
0
ファイル: gfxaccel.cpp プロジェクト: AlexandreCo/macemu
void NQD_bitblt(uint32 p)
{
	D(bug("accl_bitblt %08x\n", p));

	// Get blitting parameters
	int16 src_X  = (int16)ReadMacInt16(p + acclSrcRect + 2) - (int16)ReadMacInt16(p + acclSrcBoundsRect + 2);
	int16 src_Y  = (int16)ReadMacInt16(p + acclSrcRect + 0) - (int16)ReadMacInt16(p + acclSrcBoundsRect + 0);
	int16 dest_X = (int16)ReadMacInt16(p + acclDestRect + 2) - (int16)ReadMacInt16(p + acclDestBoundsRect + 2);
	int16 dest_Y = (int16)ReadMacInt16(p + acclDestRect + 0) - (int16)ReadMacInt16(p + acclDestBoundsRect + 0);
	int16 width  = (int16)ReadMacInt16(p + acclDestRect + 6) - (int16)ReadMacInt16(p + acclDestRect + 2);
	int16 height = (int16)ReadMacInt16(p + acclDestRect + 4) - (int16)ReadMacInt16(p + acclDestRect + 0);
	D(bug(" src addr %08x, dest addr %08x\n", ReadMacInt32(p + acclSrcBaseAddr), ReadMacInt32(p + acclDestBaseAddr)));
	D(bug(" src X %d, src Y %d, dest X %d, dest Y %d\n", src_X, src_Y, dest_X, dest_Y));
	D(bug(" width %d, height %d\n", width, height));

	// And perform the blit
	const int bpp = bytes_per_pixel(ReadMacInt32(p + acclSrcPixelSize));
	width *= bpp;
	if ((int32)ReadMacInt32(p + acclSrcRowBytes) > 0) {
		const int src_row_bytes = (int32)ReadMacInt32(p + acclSrcRowBytes);
		const int dst_row_bytes = (int32)ReadMacInt32(p + acclDestRowBytes);
		uint8 *src = Mac2HostAddr(ReadMacInt32(p + acclSrcBaseAddr) + (src_Y * src_row_bytes) + (src_X * bpp));
		uint8 *dst = Mac2HostAddr(ReadMacInt32(p + acclDestBaseAddr) + (dest_Y * dst_row_bytes) + (dest_X * bpp));
		for (int i = 0; i < height; i++) {
			memmove(dst, src, width);
			src += src_row_bytes;
			dst += dst_row_bytes;
		}
	}
	else {
		const int src_row_bytes = -(int32)ReadMacInt32(p + acclSrcRowBytes);
		const int dst_row_bytes = -(int32)ReadMacInt32(p + acclDestRowBytes);
		uint8 *src = Mac2HostAddr(ReadMacInt32(p + acclSrcBaseAddr) + ((src_Y + height - 1) * src_row_bytes) + (src_X * bpp));
		uint8 *dst = Mac2HostAddr(ReadMacInt32(p + acclDestBaseAddr) + ((dest_Y + height - 1) * dst_row_bytes) + (dest_X * bpp));
		for (int i = height - 1; i >= 0; i--) {
			memmove(dst, src, width);
			src -= src_row_bytes;
			dst -= dst_row_bytes;
		}
	}
}