#ifndef __HAL_H__
#define __HAL_H__
/*****************************************************************************
filename : hal.h
模擬ハードウェア(C-Machine)モジュール

 (C) Copyright 2002 佐々木芳


Windowsのシミュレーション環境上で動作するアプリケーションプログラムのコンパイル時には以下のマクロ定義が必要
	_CMTOY

以下の順番にインクルードする。
#include "hal.h"
#include "itron.h"
*****************************************************************************/
#ifdef _CMTOY
/*Windowsシミュレーション環境*/
#include <time.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>

#ifdef __cplisplus
#define EXTERN extern "C"
#else
#include <windows.h>
#include <process.h>    /* _beginthread, _endthread */
#include <Winbase.h>

#define EXTERN extern
#endif/*__cplisplus*/

#ifdef _CM_EXPORT
/*cm.dll作成時に使用する定義*/
#define CM_EXTERN __declspec(dllexport)
#else
/*cm.dllを呼び出す側で使用する定義*/
#define CM_EXTERN __declspec( dllimport ) 
#endif/*_CM_EXPORT*/

#else
/*実機*/
#define EXTERN extern
#define CM_EXTERN extern

#endif/*_CMTOY*/


/**************************************************************************
共通定数、変数タイプ、構造体、マクロ
**************************************************************************/
#ifndef _CMTOY
typedef unsigned char	BYTE;	/* 8ビット*/
typedef unsigned short	WORD;	/*16ビット*/
typedef unsigned long	DWORD;	/*32ビット*/
typedef char	CHAR;
typedef short	SHORT;
typedef long	LONG;
#ifndef NULL
#define	NULL	((void *)0)		/*無効ポインタ値*/
#endif

#define MAKEWORD(l, h)      ((WORD)(((BYTE)(l)) | ((WORD)((BYTE)(h))) << 8))
#define MAKELONG(a, b)      ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16))
#define LOWORD(l)           ((WORD)(l))
#define HIWORD(l)           ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))
#define LOBYTE(w)           ((BYTE)(w))
#define HIBYTE(w)           ((BYTE)(((WORD)(w) >> 8) & 0xFF))
#define SWAPWORD(w)			MAKEWORD(HIBYTE(w), LOBYTE(w))
#define SWAPDLONG(l)		MAKELONG(HIWORD(l), LOWORD(l))
#define ABS(a)				(int)(a) >= 0 ? (a) : -(a)


#ifndef FALSE
#define FALSE	0
#endif

#ifndef TRUE
#define TRUE	1
#endif

#ifndef BOOL
typedef int BOOL;
#endif

#endif	/*_CMTOY*/

#define COUNT_OF(array)		sizeof(array)/sizeof(array[0])


#ifdef _CMTOY
/*Windowsシミュレーション環境*/
#define IFCMTOY(x)			x
#define IFTARGET(x)			
#define FATAL_ERROR(x)	{													\
							DIS_INT											\
							halStopTimer();									\
							CMTRACE("▲▲致命的エラー：%s <%s(%d)>\n",(x),__FILE__,__LINE__);	\
							MessageBox(NULL, x, "致命的エラー", MB_OK);		\
							while(1) {}										\
						}
/*
#define FATAL_ERROR(x)	{													\
							CMTRACE("▲▲致命的エラー %s(%d)：%s\n",(x),__FILE__,__LINE__);	\
							MessageBox(NULL, x, "致命的エラー", MB_OK);		\
							halInvokeDebugger();							\
							exit(1);										\
						}
*/
#define CMTRACE				halDebugPrintf
#define DECLARE_CRISEC		BOOL __prev_stat;
#define ENTER_CRISEC		__prev_stat = halEnterCriticalSection();
#define LEAVE_CRISEC		halLeaveCriticalSection(__prev_stat);
#define	DIS_INT				halDisableInterrupt();
#define	ENA_INT				halEnableInterrupt();

/*Windows 32bit App 有効アドレス範囲*/
#define ADDR_LIMIT_LOW		(0x00010000)
#define ADDR_LIMIT_HIGH		(0x80000000-1)
/*#define INVALIDPTR(p)		FALSE		//pが不正なときTRUEを返す*/
#define INVALIDPTR(p)		(((DWORD)(p) < ADDR_LIMIT_LOW) || ((DWORD)(p) > ADDR_LIMIT_HIGH))



#else
/*実機*/
#define IFCMTOY(x)	
#define IFTARGET(x)			x
#define FATAL_ERROR(x)		while(1);
#define CMTRACE	
	
/*以下はINTEL x86互換CPUの例(Microsoft C/C++ Compiler)*/		
#define DECLARE_CRISEC
#define ENTER_CRISEC	__asm { __asm pushf __asm cli }
#define LEAVE_CRISEC	__asm popf
#define DIS_INT			__asm cli
#define ENA_INT			__asm sti

/*以下はTMS320C54x, TMS320LC54x, TMS320VC54xの例(CL500)*/
#define DECLARE_CRISEC
#define ENTER_CRISEC	asm(" PSHM ST1");\
						asm(" SSBX INTM")
#define LEAVE_CRISEC	asm(" POPM ST1")
#define DIS_INT			asm(" SSBX INTM")
#define ENA_INT			asm(" RSBX INTM")

/*以下はMCC68Kの例*/
#define DECLARE_CRISEC
#define ENTER_CRISEC	asm(" move sr,-(sp)"," ori #0700h,sr")
#define LEAVE_CRISEC	asm(" move (sp)+,sr")
#define DIS_INT			asm(" ORI.W	#0700H,SR")
#define ENA_INT			asm(" ANDI.W	#0F8FFH,SR")


/*実機　有効アドレス範囲（例）*/
#define ADDR_LIMIT_LOW		0x1820
#define ADDR_LIMIT_HIGH		(0x8000-1)
#define INVALIDPTR(p)		(((WORD)(p) < ADDR_LIMIT_LOW) || ((WORD)(p) > ADDR_LIMIT_HIGH))

#endif/*_CMTOY*/



#define PRINT_INFO			CMTRACE			/*メッセージ出力*/
#ifdef _DEBUG
#define DEBUG_TRACE			CMTRACE			/*debugバージョンではトレース出力*/
#else
#define DEBUG_TRACE		
#endif


#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
//ターゲットプログラムの使う模擬ハードウェア関数郡
CMTOYの用意するハードウェア
・CPUは１ビットの割込み禁止／許可フラグを持つ、INTR信号、LOCK信号、HOLD信号（x86的）
・割込みコントローラ（IRC)は、固定優先度の１６レベルのIRが入力、INTR信号をCPUへ出力（8259的だがカスケードはなし）
・外部割込み要求IR（16個）	多重割り込みはない（IRCのレベル0〜15）
・システムタイマ		IRCのレベル０
・LEDランプ（８個）
・７セグメントLEDの２桁表示器
・ボリューム(１個）	例えばA/Dコンバータ
・DIPスイッチ（4個）
・ボタン(１個）
・シリアルポート（２個）
・IOポート／メモリマップドIO
・ROM／書換可能永続的メモリ（メモリ空間にマップ）
・PN符号生成
*****************************************************************************/
CM_EXTERN void	halInitialize(void);
#define HAL_BUILD_NO	(0x01000012)		//ビルド番号（halGetVersionで返す） at 2026,3,8
CM_EXTERN DWORD halGetVersion(void);
CM_EXTERN DWORD halGetKpVersion(void);
#ifdef _CMTOY
/*Windowsシミュレーション環境*/
CM_EXTERN void halWin32FormatErrorMessage(const char *heading);
CM_EXTERN void halWin32CheckLastError(const char *heading);
CM_EXTERN void halInvokeDebugger(void);
#endif	/*_CMTOY*/

/*割込みレベルは０〜１５、割込みレベル０はタイマ*/
#define MAX_IRQ_LEVEL				(15)
#define NUM_IRQ_LEVEL				(MAX_IRQ_LEVEL+1)
#define INTNO_TO_LEVEL(intno)		((intno))			/* ユーザ割込み番号（1..15)をIRCの割込みレベル(1..15)に変換*/
#define LEVEL_TO_INTNO(level)		((level))			/* IRCの割込みレベルをユーザ割込み番号に変換*/
#define TIMER_IRQ_LEVEL				(0)					/* システムタイマのレベル*/
#define IS_VALID_IRQ_LEVEL(level)	(((level) >= 0) && ((level) < NUM_IRQ_LEVEL))

/*CPU*/
typedef long CPU_STAT_REG;			/*CPU のステータスレジスタのビット幅*/
CM_EXTERN void halDisableInterrupt(void);
CM_EXTERN void halEnableInterrupt(void);
CM_EXTERN BOOL halEnterCriticalSection(void);				/*割込み禁止フラグを読み出して、割込み禁止にする*/
CM_EXTERN void halLeaveCriticalSection(BOOL pre_stat);		/*割込み禁止フラグを設定*/
CM_EXTERN CPU_STAT_REG halInquireCpuStatusRegister(void);
CM_EXTERN void halRestoreCpuStatusRegister(CPU_STAT_REG stat);
CM_EXTERN BOOL halInquireCpuInterruptFlag(void);
CM_EXTERN BOOL halTestInterruptFlag(CPU_STAT_REG stat);
CM_EXTERN void halSetInterruptFlag(CPU_STAT_REG *p_stat, BOOL ifl);

/*IRC*/
CM_EXTERN void halIrcEndOfInterrupt(int level);
CM_EXTERN void halIrcMaskInterrupt(int level, BOOL mask);
CM_EXTERN BOOL halIrcGetInterruptMask(int level);
CM_EXTERN BOOL halIrcGetInterruptInService(int level);
CM_EXTERN int halIrcInquireInServiceLevel(void);

/*System Timer*/
CM_EXTERN void halStartTimer(int interval);
CM_EXTERN void halStopTimer(void);

/*アプリケーションで使う関数*/
CM_EXTERN void halDebugOutputString(const char *cstr);//現在のコンソールへ表示。
CM_EXTERN void halDebugPrintf(const char *formatstring, ...);//現在のコンソールへ表示。
CM_EXTERN void halDebugSetTitle(const char* title);

#define NUM_OF_ADC				(1)			//A/Dコンバータ
#define MIN_ADC_SIZE			(0xf)		//15	4bits
#define MAX_ADC_SIZE			(0xffff)	//65535	16bits
#define INITIAL_ADC_SIZE		(0xff)		//255	8bits
#define NUM_OF_SWITCH			(4)			//DIPスイッチ
#define NUM_OF_INTR_BUTTON		(8)			//割込みボタン
#define NUM_OF_PUSH_BUTTON		(1)			//ボタン
#define NUM_OF_SERIAL			(2)			//シリアルUART

CM_EXTERN void halInitDevices(void);
CM_EXTERN void halSetLED(WORD led);
CM_EXTERN void halSetSegLED(WORD stat);
CM_EXTERN WORD halGetVolume(int VolumeNo);
CM_EXTERN WORD halGetSwitch(void);
CM_EXTERN BOOL halGetPushButton(int ButtonNo);

#define VALID_SERIAL_NO(SerialNo)	(((SerialNo)>=0) && ((SerialNo)<NUM_OF_SERIAL))
/*簡易シリアル制御*/
CM_EXTERN void halSerialInit(int SerialNo);
CM_EXTERN int  halSerialReadChar(int SerialNo);
CM_EXTERN void halSerialWriteChar(int SerialNo, int c);
/*シリアル制御(16550相当)*/
CM_EXTERN void hal16550WriteDATA(int SerialNo, BYTE d);
CM_EXTERN BYTE hal16550ReadDATA(int SerialNo);
CM_EXTERN void hal16550WriteIER(int SerialNo, BYTE d);
CM_EXTERN BYTE hal16550ReadIER(int SerialNo);
CM_EXTERN BYTE hal16550ReadIID(int SerialNo);
CM_EXTERN void hal16550WriteFCR(int SerialNo, BYTE d);
CM_EXTERN BYTE hal16550ReadLSR(int SerialNo);
CM_EXTERN BYTE hal16550ReadMSR(int SerialNo);
CM_EXTERN void hal16550WriteLCR(int SerialNo, BYTE d);
CM_EXTERN BYTE hal16550ReadLCR(int SerialNo);
CM_EXTERN void hal16550WriteMCR(int SerialNo, BYTE d);
CM_EXTERN BYTE hal16550ReadMCR(int SerialNo);

/*ターゲット依存メモリ操作（IOポート／メモリマップドIO、ROM／書換可能永続的メモリ）*/
typedef enum{
	MEM_DEFINED = 0,	//0:undef, 1:defined
	MEM_ENDIAN	= 1,	//0;undef, 1:big endian, 2:little endoan
	MEM_ADDRESSING = 2,	//0:undef, 1:byte addressing, 2:word addresiing
}MEM_INDEX;
CM_EXTERN UINT halInquireMemorySystem(MEM_INDEX index);
CM_EXTERN void halWriteByte(DWORD taddr, BYTE data);
CM_EXTERN void halWriteWord(DWORD taddr, WORD data);
CM_EXTERN void halWriteDword(DWORD taddr, DWORD data);
CM_EXTERN void halOrByte(DWORD taddr, BYTE data);
CM_EXTERN void halOrWord(DWORD taddr, WORD data);
CM_EXTERN void halOrDword(DWORD taddr, DWORD data);
CM_EXTERN void halAndByte(DWORD taddr, BYTE data);
CM_EXTERN void halAndWord(DWORD taddr, WORD data);
CM_EXTERN void halAndDword(DWORD taddr, DWORD data);
CM_EXTERN void halXorByte(DWORD taddr, BYTE data);
CM_EXTERN void halXorWord(DWORD taddr, WORD data);
CM_EXTERN void halXorDword(DWORD taddr, DWORD data);
CM_EXTERN BYTE halXchgByte(DWORD taddr, BYTE data);
CM_EXTERN WORD halXchgWord(DWORD taddr, WORD data);
CM_EXTERN DWORD halXchgDword(DWORD taddr, DWORD data);
CM_EXTERN BYTE halReadByte(DWORD taddr);
CM_EXTERN WORD halReadWord(DWORD taddr);
CM_EXTERN DWORD halReadDword(DWORD taddr);

CM_EXTERN void halOutByte(DWORD tport, BYTE data);
CM_EXTERN void halOutWord(DWORD tport, WORD data);
CM_EXTERN void halOutDword(DWORD tport, DWORD data);
CM_EXTERN BYTE halInByte(DWORD tport);
CM_EXTERN WORD halInWord(DWORD tport);
CM_EXTERN DWORD halInDword(DWORD tport);

CM_EXTERN void* halGetEmemPointer(DWORD taddr, int data_size);//x86(Little Endian, 8bit cell)の場合だけ使える
CM_EXTERN int halGetCurrentBank(DWORD taddr);
CM_EXTERN int halSelectBank(DWORD taddr, int newbank);
CM_EXTERN void halRotateBank(DWORD taddr);

/*PN 符号，疑似ランダム雑音（PseudorandomNoise）の生成*/
CM_EXTERN WORD halCalcPN9(WORD pn_code);
CM_EXTERN WORD halGenPN9(WORD pn_code, BYTE *buf, int bytes);
CM_EXTERN WORD halCalcPN15(WORD pn_code);
CM_EXTERN WORD halGenPN15(WORD pn_code, BYTE *buf, int bytes);


#ifdef _CMTOY
/**********************/
/*Windowsシミュレーション環境*/
/**********************/

/*ターゲットメモリ/IO操作用のマクロ
x86と同じリトルエンディアンかつ8bitセルタイプのメモリの場合だけ使える*/
#define VOID_PTR(TADDR)		(void*)halGetEmemPointer((DWORD)(TADDR), sizeof(BYTE))
#define BYTE_PTR(TADDR)		(BYTE*)halGetEmemPointer((DWORD)(TADDR), sizeof(BYTE))
#define WORD_PTR(TADDR)		(WORD*)halGetEmemPointer((DWORD)(TADDR), sizeof(WORD))
#define DWORD_PTR(TADDR)	(DWORD*)halGetEmemPointer((DWORD)(TADDR), sizeof(DWORD))
#define CHAR_PTR(TADDR)		(CHAR*)halGetEmemPointer((DWORD)(TADDR), sizeof(char))
#define SHORT_PTR(TADDR)	(SHORT*)halGetEmemPointer((DWORD)(TADDR), sizeof(short))
#define LONG_PTR(TADDR)		(LONG*)halGetEmemPointer((DWORD)(TADDR), sizeof(long))


/*メモリマップドIO,ROM,RAM（バスロックで実行するアトミック操作）*/
#define OR_BYTE(TADDR,DATA)			halOrByte((DWORD)(TADDR),(BYTE)DATA)
#define OR_WORD(TADDR,DATA)			halOrWord((DWORD)(TADDR),(WORD)DATA)
#define OR_DWORD(TADDR,DATA)		halOrDword((DWORD)(TADDR),(DWORD)DATA)
#define AND_BYTE(TADDR,DATA)		halAndByte((DWORD)(TADDR),(BYTE)DATA)
#define AND_WORD(TADDR,DATA)		halAndWord((DWORD)(TADDR),(WORD)DATA)
#define AND_DWORD(TADDR,DATA)		halAndDword((DWORD)(TADDR),(DWORD)DATA)
#define XOR_BYTE(TADDR,DATA)		halXorByte((DWORD)(TADDR),(BYTE)DATA)
#define XOR_WORD(TADDR,DATA)		halXorWord((DWORD)(TADDR),(WORD)DATA)
#define XOR_DWORD(TADDR,DATA)		halXorDword((DWORD)(TADDR),(DWORD)DATA)
#define XCHG_BYTE(TADDR,DATA)		halXchgByte((DWORD)(TADDR),(BYTE)DATA)
#define XCHG_WORD(TADDR,DATA)		halXchgWord((DWORD)(TADDR),(WORD)DATA)
#define XCHG_DWORD(TADDR,DATA)		halXchgDword((DWORD)(TADDR),(DWORD)DATA)

#define WRITE_BYTE(TADDR,DATA)		halWriteByte((DWORD)(TADDR),(BYTE)DATA)
#define WRITE_WORD(TADDR,DATA)		halWriteWord((DWORD)(TADDR),(WORD)DATA)
#define WRITE_DWORD(TADDR,DATA)		halWriteDword((DWORD)(TADDR),(DWORD)DATA)
#define READ_BYTE(TADDR)			halReadByte((DWORD)(TADDR))
#define READ_WORD(TADDR)			halReadWord((DWORD)(TADDR))
#define READ_DWORD(TADDR)			halReadDword((DWORD)(TADDR))

/*ポートIO*/
#define OUT_BYTE(TPORT,DATA)		halOutByte((DWORD)(TPORT),(BYTE)DATA)
#define OUT_WORD(TPORT,DATA)		halOutWord((DWORD)(TPORT),(WORD)DATA)
#define OUT_DWORD(TPORT,DATA)		halOutDword((DWORD)(TPORT),(DWORD)DATA)
#define IN_BYTE(TPORT)				halInByte((DWORD)(TPORT))
#define IN_WORD(TPORT)				halInWord((DWORD)(TPORT))
#define IN_DWORD(TPORT)				halInDword((DWORD)(TPORT))

/*構造体のMEMBERへのリード／ライト*/
#define PVOID_PTR(MEMBER)			VOID_PTR(& ## MEMBER)
#define PBYTE_PTR(MEMBER)			BYTE_PTR(& ## MEMBER)
#define PWORD_PTR(MEMBER)			WORD_PTR(& ## MEMBER)
#define PDWORD_PTR(MEMBER)			DWORD_PTR(& ## MEMBER)
#define PCHAR_PTR(MEMBER)			CHAR_PTR(& ## MEMBER)
#define PSHORT_PTR(MEMBER)			SHORT_PTR(& ## MEMBER)
#define PLONG_PTR(MEMBER)			LONG_PTR(& ## MEMBER)

#define POR_BYTE(MEMBER,DATA)		OR_BYTE(& ## MEMBER,DATA)
#define POR_WORD(MEMBER,DATA)		OR_WORD(& ## MEMBER,DATA)
#define POR_DWORD(MEMBER,DATA)		OR_DWORD(& ## MEMBER,DATA)
#define PAND_BYTE(MEMBER,DATA)		AND_BYTE(& ## MEMBER,DATA)
#define PAND_WORD(MEMBER,DATA)		AND_WORD(& ## MEMBER,DATA)
#define PAND_DWORD(MEMBER,DATA)		AND_DWORD(& ## MEMBER,DATA)
#define PXOR_BYTE(MEMBER,DATA)		XOR_BYTE(& ## MEMBER,DATA)
#define PXOR_WORD(MEMBER,DATA)		XOR_WORD(& ## MEMBER,DATA)
#define PXOR_DWORD(MEMBER,DATA)		XOR_DWORD(& ## MEMBER,DATA)
#define PXCHG_BYTE(MEMBER,DATA)		XCHG_BYTE(& ## MEMBER,DATA)
#define PXCHG_WORD(MEMBER,DATA)		XCHG_WORD(& ## MEMBER,DATA)
#define PXCHG_DWORD(MEMBER,DATA)	XCHG_DWORD(& ## MEMBER,DATA)

#define PWRITE_BYTE(MEMBER,DATA)	WRITE_BYTE(& ## MEMBER, DATA)
#define PWRITE_WORD(MEMBER,DATA)	WRITE_WORD(& ## MEMBER, DATA)
#define PWRITE_DWORD(MEMBER,DATA)	WRITE_DWORD(& ## MEMBER, DATA)
#define PREAD_BYTE(MEMBER)			READ_BYTE(& ## MEMBER)
#define PREAD_WORD(MEMBER)			READ_WORD(& ## MEMBER)
#define PREAD_DWORD(MEMBER)			READ_DWORD(& ## MEMBER)

#else
/**********************/
/*実機*/
/**********************/
#define IFDEBUG(x)	
#define IFTARGET(x)			x
#define FATAL_ERROR(x)		while(1){};

/*ターゲットメモリ/IO操作用のマクロ*/
#define VOID_PTR(TADDR)			(void*)(TADDR)
#define BYTE_PTR(TADDR)			(BYTE*)(TADDR)
#define WORD_PTR(TADDR)			(WORD*)(TADDR)
#define DWORD_PTR(TADDR)		(DWORD*)(TADDR)
#define CHAR_PTR(TADDR)			(CHAR*)(TADDR)
#define SHORT_PTR(TADDR)		(SHORT*)(TADDR)
#define LONG_PTR(TADDR)			(LONG*)(TADDR)


/*メモリマップドIO（バスロックで実行するアトミック操作）*/
#define OR_BYTE(TADDR,DATA)			*(BYTE*)(TADDR)|=(BYTE)(DATA)
#define OR_WORD(TADDR,DATA)			*(WORD*)(TADDR)|=(WORD)(DATA)
#define OR_DWORD(TADDR,DATA)		*(DWORD*)(TADDR)|=(DWORD)(DATA)
#define AND_BYTE(TADDR,DATA)		*(BYTE*)(TADDR)&=(BYTE)(DATA)
#define AND_WORD(TADDR,DATA)		*(WORD*)(TADDR)&=(WORD)(DATA)
#define AND_DWORD(TADDR,DATA)		*(DWORD*)(TADDR)&=(DWORD)(DATA)
#define XOR_BYTE(TADDR,DATA)		*(BYTE*)(TADDR)^=(BYTE)(DATA)
#define XOR_WORD(TADDR,DATA)		*(WORD*)(TADDR)^=(WORD)(DATA)
#define XOR_DWORD(TADDR,DATA)		*(DWORD*)(TADDR)^=(DWORD)(DATA)
#define XCHG_BYTE(TADDR,DATA)		
#define XCHG_WORD(TADDR,DATA)		
#define XCHG_DWORD(TADDR,DATA)		
#define WRITE_BYTE(TADDR,DATA)		*(BYTE*)(TADDR)=(BYTE)(DATA)
#define WRITE_WORD(TADDR,DATA)		*(WORD*)(TADDR)=(WORD)(DATA)
#define WRITE_DWORD(TADDR,DATA)		*(DWORD*)(TADDR)=(DWORD)(DATA)
#define READ_BYTE(TADDR)			*(BYTE*)(TADDR)
#define READ_WORD(TADDR)			*(WORD*)(TADDR)
#define READ_DWORD(TADDR)			*(DWORD*)(TADDR)

/*ポートIO*/
#define OUT_BYTE(TPORT,DATA)		
#define OUT_WORD(TPORT,DATA)		
#define OUT_DWORD(TPORT,DATA)		
#define IN_BYTE(TPORT)				
#define IN_WORD(TPORT)				
#define IN_DWORD(TPORT)				
//ＩＯポートから入力(Microsoft C/C++ Compiler)
DWORD in_dword( WORD port )
{
	DWORD data;
	_asm{
		mov	dx,port
		in	eax,dx
		mov	data,eax
	}
	return data;
}

//ＩＯポートへ出力(Microsoft C/C++ Compiler)
void out_dword( WORD port, DWORD data)
{
	_asm{
		mov	eax,data
		mov	dx,port
		out	dx,eax
	}
}


/*構造体のMEMBERへのリード／ライト*/
#define PVOID_PTR(MEMBER)			(& ## MEMBER)
#define PBYTE_PTR(MEMBER)			(& ## MEMBER)
#define PWORD_PTR(MEMBER)			(& ## MEMBER)
#define PDWORD_PTR(MEMBER)			(& ## MEMBER)
#define PCHAR_PTR(MEMBER)			(& ## MEMBER)
#define PSHORT_PTR(MEMBER)			(& ## MEMBER)
#define PLONG_PTR(MEMBER)			(& ## MEMBER)

#define POR_BYTE(MEMBER,DATA)		MEMBER|=DATA
#define POR_WORD(MEMBER,DATA)		MEMBER|=DATA
#define POR_DWORD(MEMBER,DATA)		MEMBER|=DATA
#define PAND_BYTE(MEMBER,DATA)		MEMBER&=DATA
#define PAND_WORD(MEMBER,DATA)		MEMBER&=DATA
#define PAND_DWORD(MEMBER,DATA)		MEMBER&=DATA
#define PXOR_BYTE(MEMBER,DATA)		MEMBER^=DATA
#define PXOR_WORD(MEMBER,DATA)		MEMBER^=DATA
#define PXOR_DWORD(MEMBER,DATA)		MEMBER^=DATA
#define PXCHG_BYTE(MEMBER,DATA)		
#define PXCHG_WORD(MEMBER,DATA)		
#define PXCHG_DWORD(MEMBER,DATA)	

#define PWRITE_BYTE(MEMBER,DATA)	MEMBER=DATA
#define PWRITE_WORD(MEMBER,DATA)	MEMBER=DATA
#define PWRITE_DWORD(MEMBER,DATA)	MEMBER=DATA
#define PREAD_BYTE(MEMBER)			MEMBER
#define PREAD_WORD(MEMBER)			MEMBER
#define PREAD_DWORD(MEMBER)			MEMBER



#endif/*_CMTOY*/


#ifdef __cplusplus
}
#endif


#endif /*__HAL_H__*/