1 /////////////////////////////////////////////////////////////////////////
2 // $Id: shift8.cc,v 1.24 2006/03/26 18:58:01 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define NEED_CPU_REG_SHORTCUTS 1
31 #define LOG_THIS BX_CPU_THIS_PTR
34 void BX_CPU_C::ROL_Eb(bxInstruction_c
*i
)
36 Bit8u op1_8
, result_8
;
41 else if (i
->b1() == 0xd0)
46 /* op1 is a register or memory reference */
48 op1_8
= BX_READ_8BIT_REGx(i
->rm(),i
->extend8bitL());
51 /* pointer, segment address pair */
52 read_RMW_virtual_byte(i
->seg(), RMAddr(i
), &op1_8
);
55 if ( (count
& 0x07) == 0 ) {
57 unsigned bit0
= op1_8
& 1;
59 set_OF(bit0
^ (op1_8
>> 7));
63 count
&= 0x07; // use only lowest 3 bits
65 result_8
= (op1_8
<< count
) | (op1_8
>> (8 - count
));
67 /* now write result back to destination */
69 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), result_8
);
72 write_RMW_virtual_byte(result_8
);
76 * ROL count affects the following flags: C, O
78 bx_bool temp_CF
= (result_8
& 0x01);
81 set_OF(temp_CF
^ (result_8
>> 7));
84 void BX_CPU_C::ROR_Eb(bxInstruction_c
*i
)
86 Bit8u op1_8
, result_8
;
91 else if (i
->b1() == 0xd0)
96 /* op1 is a register or memory reference */
98 op1_8
= BX_READ_8BIT_REGx(i
->rm(),i
->extend8bitL());
101 /* pointer, segment address pair */
102 read_RMW_virtual_byte(i
->seg(), RMAddr(i
), &op1_8
);
105 if ( (count
& 0x07) == 0 ) {
106 if ( count
& 0x18 ) {
107 unsigned bit6
= (op1_8
>> 6) & 1;
108 unsigned bit7
= (op1_8
>> 7);
114 count
&= 0x07; /* use only bottom 3 bits */
116 result_8
= (op1_8
>> count
) | (op1_8
<< (8 - count
));
118 /* now write result back to destination */
120 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), result_8
);
123 write_RMW_virtual_byte(result_8
);
127 * ROR count affects the following flags: C, O
129 bx_bool result_b7
= (result_8
& 0x80) != 0;
130 bx_bool result_b6
= (result_8
& 0x40) != 0;
133 set_OF(result_b7
^ result_b6
);
136 void BX_CPU_C::RCL_Eb(bxInstruction_c
*i
)
138 Bit8u op1_8
, result_8
;
143 else if (i
->b1() == 0xd0)
148 count
= (count
& 0x1f) % 9;
150 /* op1 is a register or memory reference */
152 op1_8
= BX_READ_8BIT_REGx(i
->rm(),i
->extend8bitL());
155 /* pointer, segment address pair */
156 read_RMW_virtual_byte(i
->seg(), RMAddr(i
), &op1_8
);
162 result_8
= (op1_8
<< 1) | getB_CF();
165 result_8
= (op1_8
<< count
) | (getB_CF() << (count
- 1)) |
166 (op1_8
>> (9 - count
));
169 /* now write result back to destination */
171 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), result_8
);
174 write_RMW_virtual_byte(result_8
);
178 * RCL count affects the following flags: C, O
180 bx_bool temp_CF
= (op1_8
>> (8 - count
)) & 0x01;
183 set_OF(temp_CF
^ (result_8
>> 7));
186 void BX_CPU_C::RCR_Eb(bxInstruction_c
*i
)
188 Bit8u op1_8
, result_8
;
193 else if (i
->b1() == 0xd0)
198 count
= (count
& 0x1f) % 9;
200 /* op1 is a register or memory reference */
202 op1_8
= BX_READ_8BIT_REGx(i
->rm(),i
->extend8bitL());
205 /* pointer, segment address pair */
206 read_RMW_virtual_byte(i
->seg(), RMAddr(i
), &op1_8
);
211 result_8
= (op1_8
>> count
) | (getB_CF() << (8 - count
)) |
212 (op1_8
<< (9 - count
));
214 /* now write result back to destination */
216 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), result_8
);
219 write_RMW_virtual_byte(result_8
);
223 * RCR count affects the following flags: C, O
226 set_CF((op1_8
>> (count
- 1)) & 0x01);
227 set_OF((((result_8
<< 1) ^ result_8
) & 0x80) > 0);
230 void BX_CPU_C::SHL_Eb(bxInstruction_c
*i
)
232 Bit8u op1_8
, result_8
;
237 else if (i
->b1() == 0xd0)
244 /* op1 is a register or memory reference */
246 op1_8
= BX_READ_8BIT_REGx(i
->rm(),i
->extend8bitL());
249 /* pointer, segment address pair */
250 read_RMW_virtual_byte(i
->seg(), RMAddr(i
), &op1_8
);
255 result_8
= (op1_8
<< count
);
257 /* now write result back to destination */
259 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), result_8
);
262 write_RMW_virtual_byte(result_8
);
265 SET_FLAGS_OSZAPC_8(op1_8
, count
, result_8
, BX_INSTR_SHL8
);
269 void BX_CPU_C::SHR_Eb(bxInstruction_c
*i
)
271 Bit8u op1_8
, result_8
;
276 else if (i
->b1() == 0xd0)
283 /* op1 is a register or memory reference */
285 op1_8
= BX_READ_8BIT_REGx(i
->rm(),i
->extend8bitL());
288 /* pointer, segment address pair */
289 read_RMW_virtual_byte(i
->seg(), RMAddr(i
), &op1_8
);
294 result_8
= (op1_8
>> count
);
296 /* now write result back to destination */
298 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), result_8
);
301 write_RMW_virtual_byte(result_8
);
304 SET_FLAGS_OSZAPC_8(op1_8
, count
, result_8
, BX_INSTR_SHR8
);
307 void BX_CPU_C::SAR_Eb(bxInstruction_c
*i
)
309 Bit8u op1_8
, result_8
;
314 else if (i
->b1() == 0xd0)
321 /* op1 is a register or memory reference */
323 op1_8
= BX_READ_8BIT_REGx(i
->rm(),i
->extend8bitL());
326 /* pointer, segment address pair */
327 read_RMW_virtual_byte(i
->seg(), RMAddr(i
), &op1_8
);
334 result_8
= (op1_8
>> count
) | (0xff << (8 - count
));
337 result_8
= (op1_8
>> count
);
349 /* now write result back to destination */
351 BX_WRITE_8BIT_REGx(i
->rm(), i
->extend8bitL(), result_8
);
354 write_RMW_virtual_byte(result_8
);
357 SET_FLAGS_OSZAPC_8(op1_8
, count
, result_8
, BX_INSTR_SAR8
);