| version 1.2, 2004/02/04 13:24:35 | version 1.7, 2005/03/12 12:32:54 | 
| Line 12 | Line 12 | 
 | * 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | 
 | *    notice, this list of conditions and the following disclaimer in the | *    notice, this list of conditions and the following disclaimer in the | 
 | *    documentation and/or other materials provided with the distribution. | *    documentation and/or other materials provided with the distribution. | 
 | * 3. The name of the author may not be used to endorse or promote products |  | 
 | *    derived from this software without specific prior written permission. |  | 
 | * | * | 
 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 
 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
| Line 28 | Line 26 | 
 | */ | */ | 
 |  |  | 
 | #include "compiler.h" | #include "compiler.h" | 
 |  |  | 
 | #include "cpu.h" | #include "cpu.h" | 
 | #include "pccore.h" | #include "pccore.h" | 
 | #include "iocore.h" | #include "iocore.h" | 
 |  | #include "memory.h" | 
 |  |  | 
 |  | static void IOOUTCALL check_io(UINT port, UINT len) GCC_ATTR_REGPARM; | 
 |  |  | 
| static void | static void IOOUTCALL | 
| check_io(WORD port, int len) | check_io(UINT port, UINT len) | 
 | { | { | 
| WORD off; | UINT off; | 
| BYTE bit; | UINT8 bit; | 
| BYTE map; | UINT8 map; | 
 |  |  | 
 | /* そもそも I/O 許可マップが無い場合 */ |  | 
 | if (CPU_STAT_IOLIMIT == 0) { | if (CPU_STAT_IOLIMIT == 0) { | 
 |  | VERBOSE(("check_io: CPU_STAT_IOLIMIT == 0 (port = %04x, len = %d)", port, len)); | 
 | EXCEPTION(GP_EXCEPTION, 0); | EXCEPTION(GP_EXCEPTION, 0); | 
 | } | } | 
 |  |  | 
 | off = port / 8; | off = port / 8; | 
 | bit = 1 << (port % 8); | bit = 1 << (port % 8); | 
 | for (; len > 0; ++off, bit = 0x01) { | for (; len > 0; ++off, bit = 0x01) { | 
| /* I/O 許可マップはビット単位なので */ | if (off >= CPU_STAT_IOLIMIT) { | 
| if (off * 8 >= CPU_STAT_IOLIMIT) { | VERBOSE(("check_io: off(%08x) >= CPU_STAT_IOLIMIT(%08x) (port = %04x, len = %d)", off, CPU_STAT_IOLIMIT, port, len)); | 
 | EXCEPTION(GP_EXCEPTION, 0); | EXCEPTION(GP_EXCEPTION, 0); | 
 | } | } | 
 |  |  | 
 | map = cpu_kmemoryread(CPU_STAT_IOADDR + off); | map = cpu_kmemoryread(CPU_STAT_IOADDR + off); | 
 | for (; (len > 0) && (bit != 0x00); bit <<= 1, --len) { | for (; (len > 0) && (bit != 0x00); bit <<= 1, --len) { | 
 | if (map & bit) { | if (map & bit) { | 
 |  | VERBOSE(("check_io: (bitmap(0x%02x) & bit(0x%02x)) != 0 (port = %04x, len = %d)", map, bit, port, len)); | 
 | EXCEPTION(GP_EXCEPTION, 0); | EXCEPTION(GP_EXCEPTION, 0); | 
 | } | } | 
 | } | } | 
 | } | } | 
 | } | } | 
 |  |  | 
| BYTE | #if defined(IA32_SUPPORT_DEBUG_REGISTER) && CPU_FAMILY >= 5 | 
| cpu_in(WORD port) | INLINE static void IOOUTCALL | 
|  | check_ioport_break_point(UINT port, UINT length) | 
|  | { | 
|  | int i; | 
|  |  | 
|  | if (CPU_STAT_BP && !(CPU_EFLAG & RF_FLAG)) { | 
|  | for (i = 0; i < CPU_DEBUG_REG_INDEX_NUM; i++) { | 
|  | if ((CPU_STAT_BP & (1 << i)) | 
|  | && (CPU_DR7_GET_RW(i) == CPU_DR7_RW_IO) | 
|  |  | 
|  | && ((port <= CPU_DR(i) && port + length > CPU_DR(i)) | 
|  | || (port > CPU_DR(i) && port <= CPU_DR(i) + CPU_DR7_GET_LEN(i)))) { | 
|  | CPU_STAT_BP_EVENT |= CPU_STAT_BP_EVENT_B(i); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | #else | 
|  | #define check_ioport_break_point(port, length) | 
|  | #endif | 
|  |  | 
|  | UINT8 | 
|  | cpu_in(UINT port) | 
 | { | { | 
 |  |  | 
 | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | 
 | check_io(port, 1); | check_io(port, 1); | 
 | } | } | 
 |  | check_ioport_break_point(port, 1); | 
 | return iocore_inp8(port); | return iocore_inp8(port); | 
 | } | } | 
 |  |  | 
| WORD | UINT16 | 
| cpu_in_w(WORD port) | cpu_in_w(UINT port) | 
 | { | { | 
 |  |  | 
 | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | 
 | check_io(port, 2); | check_io(port, 2); | 
 | } | } | 
 |  | check_ioport_break_point(port, 2); | 
 | return iocore_inp16(port); | return iocore_inp16(port); | 
 | } | } | 
 |  |  | 
| DWORD | UINT32 | 
| cpu_in_d(WORD port) | cpu_in_d(UINT port) | 
 | { | { | 
 |  |  | 
 | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | 
 | check_io(port, 4); | check_io(port, 4); | 
 | } | } | 
 |  | check_ioport_break_point(port, 4); | 
 | return iocore_inp32(port); | return iocore_inp32(port); | 
 | } | } | 
 |  |  | 
 | void | void | 
| cpu_out(WORD port, BYTE data) | cpu_out(UINT port, UINT8 data) | 
 | { | { | 
 |  |  | 
 | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | 
 | check_io(port, 1); | check_io(port, 1); | 
 | } | } | 
 |  | check_ioport_break_point(port, 1); | 
 | iocore_out8(port, data); | iocore_out8(port, data); | 
 | } | } | 
 |  |  | 
 | void | void | 
| cpu_out_w(WORD port, WORD data) | cpu_out_w(UINT port, UINT16 data) | 
 | { | { | 
 |  |  | 
 | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | 
 | check_io(port, 2); | check_io(port, 2); | 
 | } | } | 
 |  | check_ioport_break_point(port, 2); | 
 | iocore_out16(port, data); | iocore_out16(port, data); | 
 | } | } | 
 |  |  | 
 | void | void | 
| cpu_out_d(WORD port, DWORD data) | cpu_out_d(UINT port, UINT32 data) | 
 | { | { | 
 |  |  | 
 | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { | 
 | check_io(port, 4); | check_io(port, 4); | 
 | } | } | 
 |  | check_ioport_break_point(port, 4); | 
 | iocore_out32(port, data); | iocore_out32(port, data); | 
 | } | } |