- added instructions how to update the online documentation
[bochs-mirror.git] / cpu / bcd.cc
blob49c9c6bd1f9682308699fad510d8b0646bdd14c2
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: bcd.cc,v 1.25 2008/09/19 19:18:56 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
26 /////////////////////////////////////////////////////////////////////////
28 #define NEED_CPU_REG_SHORTCUTS 1
29 #include "bochs.h"
30 #include "cpu.h"
31 #define LOG_THIS BX_CPU_THIS_PTR
33 void BX_CPP_AttrRegparmN(1) BX_CPU_C::AAA(bxInstruction_c *i)
36 * Note: This instruction incorrectly documented in Intel's materials.
37 * The right description is:
39 * IF (((AL and 0FH) > 9) or (AF==1)
40 * THEN
41 * IF CPU<286 THEN { AL <- AL+6 }
42 * ELSE { AX <- AX+6 }
43 * AH <- AH+1
44 * CF <- 1
45 * AF <- 1
46 * ELSE
47 * CF <- 0
48 * AF <- 0
49 * ENDIF
50 * AL <- AL and 0Fh
51 */
53 /* Validated against Intel Pentium family hardware. */
55 /* AAA affects the following flags: A,C */
57 if (((AL & 0x0f) > 9) || get_AF())
59 AX = AX + 0x106;
60 assert_AF();
61 assert_CF();
63 else {
64 clear_AF();
65 clear_CF();
68 AL = AL & 0x0f;
70 /* AAA affects also the following flags: Z,S,O,P */
71 /* modification of the flags is undocumented */
73 /* The following behaviour seems to match the P6 and
74 its derived processors. */
75 clear_OF();
76 clear_SF(); /* sign is always 0 because bits 4-7 of AL are zeroed */
77 set_ZF(AL == 0);
78 set_PF_base(AL);
81 void BX_CPP_AttrRegparmN(1) BX_CPU_C::AAS(bxInstruction_c *i)
83 /* AAS affects the following flags: A,C */
85 if (((AL & 0x0F) > 0x09) || get_AF())
87 AX = AX - 0x106;
88 assert_AF();
89 assert_CF();
91 else {
92 clear_CF();
93 clear_AF();
96 AL = AL & 0x0f;
98 /* AAS affects also the following flags: Z,S,O,P */
99 /* modification of the flags is undocumented */
101 /* The following behaviour seems to match the P6 and
102 its derived processors. */
103 clear_OF();
104 clear_SF(); /* sign is always 0 because bits 4-7 of AL are zeroed */
105 set_ZF(AL == 0);
106 set_PF_base(AL);
109 void BX_CPP_AttrRegparmN(1) BX_CPU_C::AAM(bxInstruction_c *i)
111 Bit8u al, imm8 = i->Ib();
113 if (imm8 == 0)
114 exception(BX_DE_EXCEPTION, 0, 0);
116 al = AL;
117 AH = al / imm8;
118 AL = al % imm8;
120 /* modification of flags A,C,O is undocumented */
121 /* The following behaviour seems to match the P6 and
122 its derived processors. */
123 SET_FLAGS_OSZAPC_LOGIC_8(AL);
126 void BX_CPP_AttrRegparmN(1) BX_CPU_C::AAD(bxInstruction_c *i)
128 Bit16u tmp = AH;
129 tmp *= i->Ib();
130 tmp += AL;
132 AX = (tmp & 0xff);
134 /* modification of flags A,C,O is undocumented */
135 /* The following behaviour seems to match the P6 and
136 its derived processors. */
137 SET_FLAGS_OSZAPC_LOGIC_8(AL);
140 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DAA(bxInstruction_c *i)
142 Bit8u tmpAL = AL;
143 int tmpCF = 0;
145 /* Validated against Intel Pentium family hardware. */
147 // DAA affects the following flags: S,Z,A,P,C
149 if (((tmpAL & 0x0F) > 0x09) || get_AF())
151 tmpCF = ((AL > 0xF9) || get_CF());
152 AL = AL + 0x06;
153 assert_AF();
155 else
156 clear_AF();
158 if ((tmpAL > 0x99) || get_CF())
160 AL = AL + 0x60;
161 tmpCF = 1;
163 else
164 tmpCF = 0;
166 clear_OF(); /* undocumented flag modification */
167 set_SF(AL >= 0x80);
168 set_ZF(AL==0);
169 set_PF_base(AL);
170 set_CF(tmpCF);
173 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DAS(bxInstruction_c *i)
175 /* The algorithm for DAS is fashioned after the pseudo code in the
176 * Pentium Processor Family Developer's Manual, volume 3. It seems
177 * to have changed from earlier processor's manuals. I'm not sure
178 * if this is a correction in the algorithm printed, or Intel has
179 * changed the handling of instruction. Validated against Intel
180 * Pentium family hardware.
183 Bit8u tmpAL = AL;
184 int tmpCF = 0;
186 /* DAS effect the following flags: A,C,S,Z,P */
188 if (((tmpAL & 0x0F) > 0x09) || get_AF())
190 tmpCF = (AL < 0x06) || get_CF();
191 AL = AL - 0x06;
192 assert_AF();
194 else
195 clear_AF();
197 if ((tmpAL > 0x99) || get_CF())
199 AL = AL - 0x60;
200 tmpCF = 1;
203 clear_OF(); /* undocumented flag modification */
204 set_SF(AL >= 0x80);
205 set_ZF(AL==0);
206 set_PF_base(AL);
207 set_CF(tmpCF);