示例#1
0
// 書き込みフック
bool pro100_hook_write(PRO100_CTX *ctx, UINT offset, UINT data, UINT size)
{
	// 引数チェック
	if (ctx == NULL)
	{
		return false;
	}

	switch (offset)
	{
	case PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0:	// RU Command, CU Command
		if (size == 1)
		{
			UCHAR b = (UCHAR)data;
			UINT ru = PRO100_GET_RU_COMMAND(b);
			UINT cu = PRO100_GET_CU_COMMAND(b);
			char *s1 = NULL;
			char *s2 = NULL;

			s1 = pro100_get_ru_command_string(ru);
			s2 = pro100_get_cu_command_string(cu);

			if (s1 != NULL || s2 != NULL)
			{
				//printf("[%s, %s]  ", s1, s2);
			}

			switch (cu)
			{
			case PRO100_CU_CMD_NOOP:
				break;

			case PRO100_CU_CMD_START:
				//printf("GUEST PRO100_CU_CMD_START: 0x%x\n", (UINT)ctx->guest_last_general_pointer);
				ctx->guest_cu_started = true;
				ctx->guest_cu_suspended = false;
				ctx->guest_cu_start_pointer = (phys_t)ctx->guest_last_general_pointer;
				ctx->guest_cu_current_pointer = ctx->guest_cu_start_pointer;

				pro100_proc_guest_op(ctx);

				cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_RESUME:
				//printf("GUEST PRO100_CU_CMD_RESUME\n");
				pro100_proc_guest_op(ctx);

				cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_LOAD_CU_BASE:
				//printf("GUEST PRO100_CU_CMD_LOAD_CU_BASE: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				cu = PRO100_CU_CMD_NOOP;

				ctx->cu_base_inited = false;

				break;

			case PRO100_CU_CMD_LOAD_DUMP_ADDR:
				//printf("GUEST PRO100_CU_CMD_LOAD_DUMP_ADDR: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				cu = PRO100_CU_CMD_NOOP;
				//pro100_write(ctx, PRO100_CSR_OFFSET_SCB_GENERAL_POINTER, (UINT)ctx->guest_last_general_pointer, 4);

				break;

			case PRO100_CU_CMD_DUMP_STAT:
				//printf("GUEST PRO100_CU_CMD_DUMP_STAT\n");

				cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_DUMP_AND_RESET_STAT:
				//printf("GUEST PRO100_CU_CMD_DUMP_AND_RESET_STAT\n");

				cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_HPQ_START:
				//printf("GUEST PRO100_CU_CMD_HPQ_START: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_CU_STAT_RESUME:
				//printf("GUEST PRO100_CU_CMD_CU_STAT_RESUME\n");

				//pro100_write(ctx, PRO100_CSR_OFFSET_SCB_GENERAL_POINTER, (UINT)ctx->guest_last_general_pointer, 4);
				//cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_HPQ_RESUME:
				//printf("GUEST PRO100_CU_CMD_HPQ_RESUME\n");

				cu = PRO100_CU_CMD_NOOP;

				break;

			default:
				printf("!!!! GUEST SEND UNKNOWN CU CMD: %u\n", cu);
				break;
			}

			switch (ru)
			{
			case PRO100_RU_CMD_NOOP:
				break;

			case PRO100_RU_CMD_START:
				//printf("GUEST PRO100_RU_CMD_START: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				ru = PRO100_CU_CMD_NOOP;

				// ゲスト OS が指定してきた受信バッファのポインタを記憶する
				ctx->guest_rfd_current = ctx->guest_rfd_first = (phys_t)ctx->guest_last_general_pointer;

				pro100_poll_ru(ctx);

				break;

			case PRO100_RU_CMD_RESUME:
				//printf("GUEST PRO100_RU_CMD_RESUME\n");

				ru = PRO100_CU_CMD_NOOP;

				ctx->guest_ru_suspended = false;

				pro100_poll_ru(ctx);

				break;

			case PRO100_RU_CMD_LOAD_HEADER_DATA_SIZE:
				//printf("GUEST PRO100_RU_CMD_LOAD_HEADER_DATA_SIZE: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				ru = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_RU_CMD_LOAD_RU_BASE:
				//printf("GUEST PRO100_RU_CMD_LOAD_RU_BASE: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				ru = PRO100_CU_CMD_NOOP;

				ctx->ru_base_inited = false;

				break;

			default:
				printf("!!!! GUEST SEND UNKNOWN RU CMD: %u\n", cu);
				break;
			}

			ru = 0;

			b = PRO100_MAKE_CU_RU_COMMAND(cu, ru);

			if ((cu != 0 || ru != 0) && (cu == 0 || ru == 0))
			{
				//printf("<P");
				pro100_wait_cu_ru_accepable(ctx);
				//printf(">");
				pro100_write(ctx, PRO100_CSR_OFFSET_SCB_GENERAL_POINTER, (UINT)ctx->guest_last_general_pointer, 4);
				pro100_write(ctx, PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0, b, 1);
				//printf("<Y");
				pro100_wait_cu_ru_accepable(ctx);
				//printf(">");
			}

			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_COMMAND_WORD_1:	// 割り込み制御ビット
		if (size == 1)
		{
			ctx->int_mask_guest_set = data;

			if (true)
			{
				//PRO100_INT_BIT *ib = (PRO100_INT_BIT *)&ctx->int_mask_guest_set;

				//printf("int mask: M=%u   0x%x\n", (UINT)ib->mask_all, (UINT)ctx->int_mask_guest_set);

				/*

				ib->mask_all = true;
				ib->fcp = ib->er = ib->rnr = ib->cna = ib->fr = ib->cx = 1;
				*/

				//pro100_beep((ib->mask_all == 0 ? 880 : 440), 200);

				pro100_write(ctx, PRO100_CSR_OFFSET_SCB_COMMAND_WORD_1,
					ctx->int_mask_guest_set, 4);

				return true;
			}
		}
		break;

	case PRO100_CSR_OFFSET_SCB_GENERAL_POINTER:	// 汎用ポインタ
		if (size == 4)
		{
			ctx->guest_last_general_pointer = data;
			//printf("GUEST WRITES POINTER: 0x%x\n", data);
		}
		return true;

	case PRO100_CSR_OFFSET_SCB_STATUS_WORD_1:	// STAT/ACK
		/*if (size == 1)
		{
			printf("<ACK>");
			if (data != 0)
			{
				pro100_write(ctx, PRO100_CSR_OFFSET_SCB_STATUS_WORD_1, 0xff, 1);
			}

			return true;
		}*/
		pro100_poll_ru(ctx);
		break;

	case PRO100_CSR_OFFSET_SCB_PORT:	// ポート
		break;

	case PRO100_CSR_OFFSET_SCB_MDI:		// MDI
		break;

	default:
		//printf("*** ACCESS TO   0x%x  size=%u   data=0x%x\n", offset, size, data);
		break;
	}

	return false;
}
示例#2
0
// 書き込みフック
bool pro100_hook_write(PRO100_CTX *ctx, UINT offset, UINT data, UINT size)
{
	// 引数チェック
	if (ctx == NULL)
	{
		return false;
	}

	switch (offset)
	{
	case PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0:	// RU Command, CU Command
		if (size != 1)
		{
			debugprint("pro100_hook_write: PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0: BAD SIZE: %u\n", size);
		}
		if (size == 1)
		{
			UCHAR b = (UCHAR)data;
			UINT ru = PRO100_GET_RU_COMMAND(b);
			UINT cu = PRO100_GET_CU_COMMAND(b);
			char *s1 = NULL;
			char *s2 = NULL;

			s1 = pro100_get_ru_command_string(ru);
			s2 = pro100_get_cu_command_string(cu);

			if (s1 != NULL || s2 != NULL)
			{
				//debugprint("[%s, %s]  ", s1, s2);
			}

			switch (cu)
			{
			case PRO100_CU_CMD_NOOP:
				break;

			case PRO100_CU_CMD_START:
				//debugprint("GUEST PRO100_CU_CMD_START: 0x%x\n", (UINT)ctx->guest_last_general_pointer);
				ctx->guest_cu_started = true;
				ctx->guest_cu_suspended = false;
				ctx->guest_cu_start_pointer = (phys_t)ctx->guest_last_general_pointer;
				ctx->guest_cu_current_pointer = ctx->guest_cu_start_pointer;

				pro100_proc_guest_op(ctx);

				cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_RESUME:
				//debugprint("GUEST PRO100_CU_CMD_RESUME\n");
				pro100_proc_guest_op(ctx);

				cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_LOAD_CU_BASE:
				//debugprint("GUEST PRO100_CU_CMD_LOAD_CU_BASE: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				cu = PRO100_CU_CMD_NOOP;

				ctx->cu_base_inited = false;

				break;

			case PRO100_CU_CMD_LOAD_DUMP_ADDR:
				debugprint("GUEST PRO100_CU_CMD_LOAD_DUMP_ADDR: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				cu = PRO100_CU_CMD_NOOP;
				//pro100_write(ctx, PRO100_CSR_OFFSET_SCB_GENERAL_POINTER, (UINT)ctx->guest_last_general_pointer, 4);

				ctx->guest_last_counter_pointer = ctx->guest_last_general_pointer;

				break;

			case PRO100_CU_CMD_DUMP_STAT:
			case PRO100_CU_CMD_DUMP_AND_RESET_STAT:
				debugprint(cu == PRO100_CU_CMD_DUMP_STAT ? "GUEST PRO100_CU_CMD_DUMP_STAT\n" : "GUEST PRO100_CU_CMD_DUMP_AND_RESET_STAT\n");

				if (ctx->guest_last_counter_pointer != 0)
				{
					UINT dummy_data[21];
					// ゲスト OS がカウンタデータのダンプを要求しているのでウソのデータを返す
					// (これをしないと Windows 版ドライバの一部で 2 秒間のビジーループによる待ちが発生してしまう)
					memset(dummy_data, 0, sizeof(dummy_data));

					dummy_data[16] = dummy_data[19] = dummy_data[20] = (cu == PRO100_CU_CMD_DUMP_STAT ? 0xa005 : 0xa007);

					pro100_mem_write((phys_t)ctx->guest_last_counter_pointer, dummy_data, sizeof(dummy_data));
				}
				else
				{
					debugprint("error: ctx->guest_last_counter_pointer == 0\n");
				}

				cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_HPQ_START:
				//debugprint("GUEST PRO100_CU_CMD_HPQ_START: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_CU_STAT_RESUME:
				//debugprint("GUEST PRO100_CU_CMD_CU_STAT_RESUME\n");

				//pro100_write(ctx, PRO100_CSR_OFFSET_SCB_GENERAL_POINTER, (UINT)ctx->guest_last_general_pointer, 4);
				//cu = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_CU_CMD_HPQ_RESUME:
				//debugprint("GUEST PRO100_CU_CMD_HPQ_RESUME\n");

				cu = PRO100_CU_CMD_NOOP;

				break;

			default:
				printf("!!!! GUEST SEND UNKNOWN CU CMD: %u\n", cu);
				break;
			}

			switch (ru)
			{
			case PRO100_RU_CMD_NOOP:
				break;

			case PRO100_RU_CMD_START:
				//debugprint("GUEST PRO100_RU_CMD_START: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				ru = PRO100_CU_CMD_NOOP;

				// ゲスト OS が指定してきた受信バッファのポインタを記憶する
				ctx->guest_rfd_current = ctx->guest_rfd_first = (phys_t)ctx->guest_last_general_pointer;

				pro100_poll_ru(ctx);

				break;

			case PRO100_RU_CMD_RESUME:
				//debugprint("GUEST PRO100_RU_CMD_RESUME\n");

				ru = PRO100_CU_CMD_NOOP;

				ctx->guest_ru_suspended = false;

				pro100_poll_ru(ctx);

				break;

			case PRO100_RU_CMD_LOAD_HEADER_DATA_SIZE:
				//debugprint("GUEST PRO100_RU_CMD_LOAD_HEADER_DATA_SIZE: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				ru = PRO100_CU_CMD_NOOP;

				break;

			case PRO100_RU_CMD_LOAD_RU_BASE:
				//debugprint("GUEST PRO100_RU_CMD_LOAD_RU_BASE: 0x%x\n", (UINT)ctx->guest_last_general_pointer);

				ru = PRO100_CU_CMD_NOOP;

				ctx->ru_base_inited = false;

				break;

			default:
				printf("!!!! GUEST SEND UNKNOWN RU CMD: %u\n", ru);
				break;
			}

			ru = 0;

			b = PRO100_MAKE_CU_RU_COMMAND(cu, ru);

			if ((cu != 0 || ru != 0) && (cu == 0 || ru == 0))
			{
				debugprint("<P");
				pro100_wait_cu_ru_accepable(ctx);
				debugprint(">");
				pro100_write(ctx, PRO100_CSR_OFFSET_SCB_GENERAL_POINTER, (UINT)ctx->guest_last_general_pointer, 4);
				pro100_write(ctx, PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0, b, 1);
				debugprint("<Y");
				pro100_wait_cu_ru_accepable(ctx);
				debugprint(">");
			}

			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_COMMAND_WORD_1:	// 割り込み制御ビット
		if (size != 1)
		{
			debugprint("pro100_hook_write: PRO100_CSR_OFFSET_SCB_COMMAND_WORD_1: BAD SIZE: %u\n", size);
		}
		if (size == 1)
		{
			ctx->int_mask_guest_set = data;

			if (true)
			{
				//PRO100_INT_BIT *ib = (PRO100_INT_BIT *)&ctx->int_mask_guest_set;

				//debugprint("int mask: M=%u   0x%x\n", (UINT)ib->mask_all, (UINT)ctx->int_mask_guest_set);

				/*

				ib->mask_all = true;
				ib->fcp = ib->er = ib->rnr = ib->cna = ib->fr = ib->cx = 1;
				*/

				//pro100_beep((ib->mask_all == 0 ? 880 : 440), 200);

				pro100_write(ctx, PRO100_CSR_OFFSET_SCB_COMMAND_WORD_1,
					ctx->int_mask_guest_set, 4);

				return true;
			}
		}
		break;

	case PRO100_CSR_OFFSET_SCB_GENERAL_POINTER:	// 汎用ポインタ
		if (size != 4)
		{
			debugprint("pro100_hook_write: PRO100_CSR_OFFSET_SCB_GENERAL_POINTER: BAD SIZE: %u\n", size);
		}
		if (size == 4)
		{
			ctx->guest_last_general_pointer = data;
			//debugprint("GUEST WRITES POINTER: 0x%x\n", data);
		}
		return true;

	case PRO100_CSR_OFFSET_SCB_STATUS_WORD_1:	// STAT/ACK
		/*if (size == 1)
		{
			debugprint("<ACK>");
			if (data != 0)
			{
				pro100_write(ctx, PRO100_CSR_OFFSET_SCB_STATUS_WORD_1, 0xff, 1);
			}

			return true;
		}*/
		pro100_poll_ru(ctx);
		break;

	case PRO100_CSR_OFFSET_SCB_PORT:	// ポート
		break;

	case PRO100_CSR_OFFSET_SCB_MDI:		// MDI
		break;

	default:
		if (offset == 0 && size == 2)
		{
			UCHAR buf[4];
			*((UINT *)buf) = data;
			pro100_hook_write(ctx, 1, buf[1], 1);

			return true;
		}
		else
		{
			if (offset < 0x10)
			{
				printf("*** WRITE ACCESS TO   0x%x  size=%u   data=0x%x\n", offset, size, data);
			}
		}
		break;
	}

	return false;
}