- compare disk size with the size calculated from geometry to avoid image
[bochs-mirror.git] / cpu / shift8.cc
blob54725ffce132362906a7a6eff06373f0cfa2ddee
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: shift8.cc,v 1.24 2006/03/26 18:58:01 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2001 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
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
29 #include "bochs.h"
30 #include "cpu.h"
31 #define LOG_THIS BX_CPU_THIS_PTR
34 void BX_CPU_C::ROL_Eb(bxInstruction_c *i)
36 Bit8u op1_8, result_8;
37 unsigned count;
39 if (i->b1() == 0xc0)
40 count = i->Ib();
41 else if (i->b1() == 0xd0)
42 count = 1;
43 else // 0xd2
44 count = CL;
46 /* op1 is a register or memory reference */
47 if (i->modC0()) {
48 op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
50 else {
51 /* pointer, segment address pair */
52 read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
55 if ( (count & 0x07) == 0 ) {
56 if ( count & 0x18 ) {
57 unsigned bit0 = op1_8 & 1;
58 set_CF(bit0);
59 set_OF(bit0 ^ (op1_8 >> 7));
61 return;
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 */
68 if (i->modC0()) {
69 BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), result_8);
71 else {
72 write_RMW_virtual_byte(result_8);
75 /* set eflags:
76 * ROL count affects the following flags: C, O
78 bx_bool temp_CF = (result_8 & 0x01);
80 set_CF(temp_CF);
81 set_OF(temp_CF ^ (result_8 >> 7));
84 void BX_CPU_C::ROR_Eb(bxInstruction_c *i)
86 Bit8u op1_8, result_8;
87 unsigned count;
89 if (i->b1() == 0xc0)
90 count = i->Ib();
91 else if (i->b1() == 0xd0)
92 count = 1;
93 else // 0xd2
94 count = CL;
96 /* op1 is a register or memory reference */
97 if (i->modC0()) {
98 op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
100 else {
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);
109 set_CF(bit7);
110 set_OF(bit7 ^ bit6);
112 return;
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 */
119 if (i->modC0()) {
120 BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), result_8);
122 else {
123 write_RMW_virtual_byte(result_8);
126 /* set eflags:
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;
132 set_CF(result_b7);
133 set_OF(result_b7 ^ result_b6);
136 void BX_CPU_C::RCL_Eb(bxInstruction_c *i)
138 Bit8u op1_8, result_8;
139 unsigned count;
141 if (i->b1() == 0xc0)
142 count = i->Ib();
143 else if (i->b1() == 0xd0)
144 count = 1;
145 else // 0xd2
146 count = CL;
148 count = (count & 0x1f) % 9;
150 /* op1 is a register or memory reference */
151 if (i->modC0()) {
152 op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
154 else {
155 /* pointer, segment address pair */
156 read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
159 if (! count) return;
161 if (count==1) {
162 result_8 = (op1_8 << 1) | getB_CF();
164 else {
165 result_8 = (op1_8 << count) | (getB_CF() << (count - 1)) |
166 (op1_8 >> (9 - count));
169 /* now write result back to destination */
170 if (i->modC0()) {
171 BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), result_8);
173 else {
174 write_RMW_virtual_byte(result_8);
177 /* set eflags:
178 * RCL count affects the following flags: C, O
180 bx_bool temp_CF = (op1_8 >> (8 - count)) & 0x01;
182 set_CF(temp_CF);
183 set_OF(temp_CF ^ (result_8 >> 7));
186 void BX_CPU_C::RCR_Eb(bxInstruction_c *i)
188 Bit8u op1_8, result_8;
189 unsigned count;
191 if (i->b1() == 0xc0)
192 count = i->Ib();
193 else if (i->b1() == 0xd0)
194 count = 1;
195 else // 0xd2
196 count = CL;
198 count = (count & 0x1f) % 9;
200 /* op1 is a register or memory reference */
201 if (i->modC0()) {
202 op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
204 else {
205 /* pointer, segment address pair */
206 read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
209 if (! count) return;
211 result_8 = (op1_8 >> count) | (getB_CF() << (8 - count)) |
212 (op1_8 << (9 - count));
214 /* now write result back to destination */
215 if (i->modC0()) {
216 BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), result_8);
218 else {
219 write_RMW_virtual_byte(result_8);
222 /* set eflags:
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;
233 unsigned count;
235 if (i->b1() == 0xc0)
236 count = i->Ib();
237 else if (i->b1() == 0xd0)
238 count = 1;
239 else // 0xd2
240 count = CL;
242 count &= 0x1f;
244 /* op1 is a register or memory reference */
245 if (i->modC0()) {
246 op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
248 else {
249 /* pointer, segment address pair */
250 read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
253 if (!count) return;
255 result_8 = (op1_8 << count);
257 /* now write result back to destination */
258 if (i->modC0()) {
259 BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), result_8);
261 else {
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;
272 unsigned count;
274 if (i->b1() == 0xc0)
275 count = i->Ib();
276 else if (i->b1() == 0xd0)
277 count = 1;
278 else // 0xd2
279 count = CL;
281 count &= 0x1f;
283 /* op1 is a register or memory reference */
284 if (i->modC0()) {
285 op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
287 else {
288 /* pointer, segment address pair */
289 read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
292 if (!count) return;
294 result_8 = (op1_8 >> count);
296 /* now write result back to destination */
297 if (i->modC0()) {
298 BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), result_8);
300 else {
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;
310 unsigned count;
312 if (i->b1() == 0xc0)
313 count = i->Ib();
314 else if (i->b1() == 0xd0)
315 count = 1;
316 else // 0xd2
317 count = CL;
319 count &= 0x1f;
321 /* op1 is a register or memory reference */
322 if (i->modC0()) {
323 op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
325 else {
326 /* pointer, segment address pair */
327 read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
330 if (!count) return;
332 if (count < 8) {
333 if (op1_8 & 0x80) {
334 result_8 = (op1_8 >> count) | (0xff << (8 - count));
336 else {
337 result_8 = (op1_8 >> count);
340 else {
341 if (op1_8 & 0x80) {
342 result_8 = 0xff;
344 else {
345 result_8 = 0;
349 /* now write result back to destination */
350 if (i->modC0()) {
351 BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), result_8);
353 else {
354 write_RMW_virtual_byte(result_8);
357 SET_FLAGS_OSZAPC_8(op1_8, count, result_8, BX_INSTR_SAR8);