- tftp_send_optack() was not 64-bit clean (patch from SF bug #1787500)
[bochs-mirror.git] / cpu / bcd.cc
blob05bea398974ab042b8577b0c12dab7a6acbd3a5b
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: bcd.cc,v 1.17 2006/03/06 22:02:51 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2002 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::AAA(bxInstruction_c *)
36 /*
37 * Note: This instruction incorrectly documented in Intel's materials.
38 * The right description is:
40 * IF (((AL and 0FH) > 9) or (AF==1)
41 * THEN
42 * IF CPU<286 THEN { AL <- AL+6 }
43 * ELSE { AX <- AX+6 }
44 * AH <- AH+1
45 * CF <- 1
46 * AF <- 1
47 * ELSE
48 * CF <- 0
49 * AF <- 0
50 * ENDIF
51 * AL <- AL and 0Fh
52 */
54 /* Validated against Intel Pentium family hardware. */
56 /* AAA affects the following flags: A,C */
58 if ( ((AL & 0x0f) > 9) || get_AF() )
60 AX = AX + 0x106;
61 set_AF(1);
62 set_CF(1);
64 else {
65 set_AF(0);
66 set_CF(0);
69 AL = AL & 0x0f;
71 /* AAA affects also the following flags: Z,S,O,P */
72 /* modification of the flags is undocumented */
74 /* The following behaviour seems to match the P6 and
75 its derived processors. */
76 set_OF(0);
77 set_SF(0); /* sign is always 0 because bits 4-7 of AL are zeroed */
78 set_ZF(AL == 0);
79 set_PF_base(AL);
82 void BX_CPU_C::AAS(bxInstruction_c *)
84 /* AAS affects the following flags: A,C */
86 if ( ((AL & 0x0F) > 0x09) || get_AF() )
88 AX = AX - 0x106;
89 set_AF(1);
90 set_CF(1);
92 else {
93 set_CF(0);
94 set_AF(0);
97 AL = AL & 0x0f;
99 /* AAS affects also the following flags: Z,S,O,P */
100 /* modification of the flags is undocumented */
102 /* The following behaviour seems to match the P6 and
103 its derived processors. */
104 set_OF(0);
105 set_SF(0); /* sign is always 0 because bits 4-7 of AL are zeroed */
106 set_ZF(AL == 0);
107 set_PF_base(AL);
110 void BX_CPU_C::AAM(bxInstruction_c *i)
112 Bit8u al, imm8 = i->Ib();
114 if (imm8 == 0)
115 exception(BX_DE_EXCEPTION, 0, 0);
117 al = AL;
118 AH = al / imm8;
119 AL = al % imm8;
121 /* AAM effects the following flags: A,C,O,S,Z,P */
122 /* modification of flags A,C,O is undocumented */
124 /* The following behaviour seems to match the P6 and
125 its derived processors. */
126 clear_OF(); /* undocumented flag modification */
127 clear_AF();
128 clear_CF();
130 /* AAM affects the following flags: S,Z,P */
131 set_SF(AL >= 0x80);
132 set_ZF(AL == 0);
133 set_PF_base(AL);
136 void BX_CPU_C::AAD(bxInstruction_c *i)
138 Bit8u imm8 = i->Ib();
140 Bit16u tmp = AH;
141 tmp *= imm8;
142 tmp += AL;
144 AL = tmp & 0xff;
145 AH = 0;
147 /* AAD effects the following flags: A,C,O,S,Z,P */
148 /* modification of flags A,C,O is undocumented */
150 /* The following behaviour seems to match the P6 and
151 its derived processors. */
152 clear_OF(); /* undocumented flag modification */
153 clear_AF();
154 clear_CF();
156 set_SF(AL >= 0x80);
157 set_ZF(AL == 0);
158 set_PF_base(AL);
161 void BX_CPU_C::DAA(bxInstruction_c *)
163 Bit8u tmpAL = AL;
164 int tmpCF = 0;
166 /* Validated against Intel Pentium family hardware. */
168 // DAA affects the following flags: S,Z,A,P,C
170 if (((tmpAL & 0x0F) > 0x09) || get_AF())
172 tmpCF = ((AL > 0xF9) || get_CF());
173 AL = AL + 0x06;
174 set_AF(1);
176 else
177 set_AF(0);
179 if ((tmpAL > 0x99) || get_CF())
181 AL = AL + 0x60;
182 tmpCF = 1;
184 else
185 tmpCF = 0;
187 set_OF(0); /* undocumented flag modification */
188 set_SF(AL >= 0x80);
189 set_ZF(AL==0);
190 set_PF_base(AL);
191 set_CF(tmpCF);
194 void BX_CPU_C::DAS(bxInstruction_c *)
196 /* The algorithm for DAS is fashioned after the pseudo code in the
197 * Pentium Processor Family Developer's Manual, volume 3. It seems
198 * to have changed from earlier processor's manuals. I'm not sure
199 * if this is a correction in the algorithm printed, or Intel has
200 * changed the handling of instruction. Validated against Intel
201 * Pentium family hardware.
204 Bit8u tmpAL = AL;
205 int tmpCF = 0;
207 /* DAS effect the following flags: A,C,S,Z,P */
209 if (((tmpAL & 0x0F) > 0x09) || get_AF())
211 tmpCF = (AL < 0x06) || get_CF();
212 AL = AL - 0x06;
213 set_AF(1);
215 else
216 set_AF(0);
218 if ((tmpAL > 0x99) || get_CF())
220 AL = AL - 0x60;
221 tmpCF = 1;
224 set_OF(0); /* undocumented flag modification */
225 set_SF(AL >= 0x80);
226 set_ZF(AL==0);
227 set_PF_base(AL);
228 set_CF(tmpCF);