#ifndef IO_H_
#define IO_H_

namespace driver {
	/*
	 * IOドライバ
	 */
	template <class T,
		dword (*func_in) (dword address),
		void (*func_out) (dword address, dword data)>
	class IO {
	protected:
		dword address_;
		dword (*func_in_) (dword address);
		void (*func_out_) (dword address, dword data);
	public:
		/*
		 * コンストラクタ
		 */
		IO(dword address) : func_in_(func_in), func_out_(func_out)
		{
			address_ = address;
		}

		/*
		 * 入力
		 */
		T in()
		{
			return in(address_);
		}

		/*
		 * 出力
		 */
		void out(T data)
		{
			out(address_, data);
		}

		/*
		 * 入力演算子
		 */
		IO &operator >>(T &data)
		{
			data = in();
			return *this;
		}

		/*
		 * 出力演算子
		 */
		IO &operator <<(T data)
		{
			out(data);
			return *this;
		}

	public:
		T in(dword address)
		{
			return (*func_in_)(address);
		}

		void out(dword address, T data)
		{
			(*func_out_)(address, data);
		}
	};



	typedef IO<byte, naskfunc::io_in8, naskfunc::io_out8> IO8;
	typedef IO<word, naskfunc::io_in8, naskfunc::io_out8> IO16;
	typedef IO<dword, naskfunc::io_in8, naskfunc::io_out8> IO32;
//	typedef IO<byte, io_in8, io_out8> IO8;
//	typedef IO<word, io_in8, io_out8> IO16;
//	typedef IO<dword, io_in8, io_out8> IO32;
	
	using naskfunc::io_hlt;
	using naskfunc::io_cli;
	using naskfunc::io_sti;
	using naskfunc::io_stihlt;
	using naskfunc::load_tr;
	using naskfunc::farjmp;

}
#endif /*IO_H_*/
