[SOFTX86]
[reactos.git] / lib / 3rdparty / softx86 / softx86 / ioport.c
1 /*
2 * ioport.c
3 *
4 * Copyright (C) 2003, 2004 Jonathan Campbell <jcampbell@mdjk.com>
5 *
6 * Decompiler and executioneer for IN/OUT instructions.
7 *
8 ***********************************************************************************
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 ************************************************************************************/
23
24 #include <softx86.h>
25 #include <memory.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include "optable.h"
29 #include "ioport.h"
30
31 int Sfx86OpcodeExec_io(sx86_ubyte opcode,softx86_ctx* ctx)
32 {
33 if ((opcode&0xFE) == 0xE4) { // IN AL/AX,imm8
34 sx86_ubyte ionum;
35 sx86_ubyte w16;
36
37 /* TODO: If emulating 386+ and protected/v86 mode check I/O permission bitmap */
38
39 w16 = (opcode&1);
40 ionum = softx86_fetch_exec_byte(ctx); // get imm8
41
42 if (w16) { /* NOTE: It is always assumed that it is in Little Endian */
43 sx86_uword rw;
44
45 ctx->callbacks->on_read_io(ctx,ionum,(sx86_ubyte*)(&rw),2);
46 SWAP_WORD_FROM_LE(rw);
47 ctx->state->general_reg[SX86_REG_AX].w.lo = rw;
48 }
49 else {
50 sx86_ubyte rb;
51
52 ctx->callbacks->on_read_io(ctx,ionum,(sx86_ubyte*)(&rb),1);
53 ctx->state->general_reg[SX86_REG_AX].b.lo = rb;
54 }
55
56 return 1;
57 }
58 else if ((opcode&0xFE) == 0xEC) { // IN AL/AX,DX
59 sx86_ubyte w16;
60
61 /* TODO: If emulating 386+ and protected/v86 mode check I/O permission bitmap */
62
63 w16 = (opcode&1);
64 if (w16) { /* NOTE: It is always assumed that it is in Little Endian */
65 sx86_uword rw;
66
67 ctx->callbacks->on_read_io(ctx,ctx->state->general_reg[SX86_REG_DX].w.lo,(sx86_ubyte*)(&rw),2);
68 SWAP_WORD_FROM_LE(rw);
69 ctx->state->general_reg[SX86_REG_AX].w.lo = rw;
70 }
71 else {
72 sx86_ubyte rb;
73
74 ctx->callbacks->on_read_io(ctx,ctx->state->general_reg[SX86_REG_DX].w.lo,(sx86_ubyte*)(&rb),1);
75 ctx->state->general_reg[SX86_REG_AX].b.lo = rb;
76 }
77
78 return 1;
79 }
80 else if ((opcode&0xFE) == 0xE6) { // OUT AL/AX,imm8
81 sx86_ubyte ionum;
82 sx86_ubyte w16;
83
84 /* TODO: If emulating 386+ and protected/v86 mode check I/O permission bitmap */
85
86 w16 = (opcode&1);
87 ionum = softx86_fetch_exec_byte(ctx); // get imm8
88
89 if (w16) { /* NOTE: It is always assumed that it is in Little Endian */
90 sx86_uword rw;
91
92 rw = ctx->state->general_reg[SX86_REG_AX].w.lo;
93 SWAP_WORD_TO_LE(rw);
94 ctx->callbacks->on_write_io(ctx,ionum,(sx86_ubyte*)(&rw),2);
95 }
96 else {
97 sx86_ubyte rb;
98
99 rb = ctx->state->general_reg[SX86_REG_AX].b.lo;
100 ctx->callbacks->on_write_io(ctx,ionum,(sx86_ubyte*)(&rb),1);
101 }
102
103 return 1;
104 }
105 else if ((opcode&0xFE) == 0xEE) { // OUT AL/AX,DX
106 sx86_ubyte w16;
107
108 /* TODO: If emulating 386+ and protected/v86 mode check I/O permission bitmap */
109
110 w16 = (opcode&1);
111 if (w16) { /* NOTE: It is always assumed that it is in Little Endian */
112 sx86_uword rw;
113
114 rw = ctx->state->general_reg[SX86_REG_AX].w.lo;
115 SWAP_WORD_TO_LE(rw);
116 ctx->callbacks->on_write_io(ctx,ctx->state->general_reg[SX86_REG_DX].w.lo,(sx86_ubyte*)(&rw),2);
117 }
118 else {
119 sx86_ubyte rb;
120
121 rb = ctx->state->general_reg[SX86_REG_AX].b.lo;
122 ctx->callbacks->on_write_io(ctx,ctx->state->general_reg[SX86_REG_DX].w.lo,(sx86_ubyte*)(&rb),1);
123 }
124
125 return 1;
126 }
127
128 return 0;
129 }
130
131 int Sfx86OpcodeDec_io(sx86_ubyte opcode,softx86_ctx* ctx,char buf[128])
132 {
133 if ((opcode&0xFE) == 0xE4) { // IN AL/AX,imm8
134 sx86_ubyte ionum;
135 sx86_ubyte w16;
136
137 w16 = (opcode&1);
138 ionum = softx86_fetch_dec_byte(ctx); // get imm8
139
140 sprintf(buf,"IN %s,%02Xh",w16 ? "AX" : "AL",ionum);
141 return 1;
142 }
143 else if ((opcode&0xFE) == 0xEC) { // IN AL/AX,DX
144 sx86_ubyte w16;
145
146 w16 = (opcode&1);
147 sprintf(buf,"IN %s,DX",w16 ? "AX" : "AL");
148 return 1;
149 }
150 else if ((opcode&0xFE) == 0xE6) { // OUT AL/AX,imm8
151 sx86_ubyte ionum;
152 sx86_ubyte w16;
153
154 w16 = (opcode&1);
155 ionum = softx86_fetch_dec_byte(ctx); // get imm8
156
157 sprintf(buf,"OUT %02Xh,%s",ionum,w16 ? "AX" : "AL");
158 return 1;
159 }
160 else if ((opcode&0xFE) == 0xEE) { // OUT AL/AX,DX
161 sx86_ubyte w16;
162
163 w16 = (opcode&1);
164 sprintf(buf,"OUT DX,%s",w16 ? "AX" : "AL");
165 return 1;
166 }
167
168 return 0;
169 }