- update sector count before calling write completion function (SF patch #2144692)
[bochs-mirror.git] / cpu / mult16.cc
blobdd123d9de4c184417093f96430df453a1b856def
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: mult16.cc,v 1.32 2008/08/10 21:16:12 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
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::MUL_AXEwR(bxInstruction_c *i)
35 Bit16u op1_16 = AX;
36 Bit16u op2_16 = BX_READ_16BIT_REG(i->rm());
38 Bit32u product_32 = ((Bit32u) op1_16) * ((Bit32u) op2_16);
39 Bit16u product_16l = (product_32 & 0xFFFF);
40 Bit16u product_16h = product_32 >> 16;
42 /* now write product back to destination */
43 AX = product_16l;
44 DX = product_16h;
46 /* set EFLAGS */
47 SET_FLAGS_OSZAPC_LOGIC_16(product_16l);
48 if(product_16h != 0)
50 ASSERT_FLAGS_OxxxxC();
54 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_AXEwR(bxInstruction_c *i)
56 Bit16s op1_16 = AX;
57 Bit16s op2_16 = BX_READ_16BIT_REG(i->rm());
59 Bit32s product_32 = ((Bit32s) op1_16) * ((Bit32s) op2_16);
60 Bit16u product_16l = (product_32 & 0xFFFF);
61 Bit16u product_16h = product_32 >> 16;
63 /* now write product back to destination */
64 AX = product_16l;
65 DX = product_16h;
67 /* set eflags:
68 * IMUL r/m16: condition for clearing CF & OF:
69 * DX:AX = sign-extend of AX
71 SET_FLAGS_OSZAPC_LOGIC_16(product_16l);
72 if(product_32 != (Bit16s)product_32)
74 ASSERT_FLAGS_OxxxxC();
78 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DIV_AXEwR(bxInstruction_c *i)
80 Bit16u op2_16 = BX_READ_16BIT_REG(i->rm());
81 if (op2_16 == 0)
82 exception(BX_DE_EXCEPTION, 0, 0);
84 Bit32u op1_32 = (((Bit32u) DX) << 16) | ((Bit32u) AX);
86 Bit32u quotient_32 = op1_32 / op2_16;
87 Bit16u remainder_16 = op1_32 % op2_16;
88 Bit16u quotient_16l = quotient_32 & 0xFFFF;
90 if (quotient_32 != quotient_16l)
91 exception(BX_DE_EXCEPTION, 0, 0);
93 /* now write quotient back to destination */
94 AX = quotient_16l;
95 DX = remainder_16;
98 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IDIV_AXEwR(bxInstruction_c *i)
100 Bit32s op1_32 = ((((Bit32u) DX) << 16) | ((Bit32u) AX));
102 /* check MIN_INT case */
103 if (op1_32 == ((Bit32s)0x80000000))
104 exception(BX_DE_EXCEPTION, 0, 0);
106 Bit16s op2_16 = BX_READ_16BIT_REG(i->rm());
108 if (op2_16 == 0)
109 exception(BX_DE_EXCEPTION, 0, 0);
111 Bit32s quotient_32 = op1_32 / op2_16;
112 Bit16s remainder_16 = op1_32 % op2_16;
113 Bit16s quotient_16l = quotient_32 & 0xFFFF;
115 if (quotient_32 != quotient_16l)
116 exception(BX_DE_EXCEPTION, 0, 0);
118 /* now write quotient back to destination */
119 AX = quotient_16l;
120 DX = remainder_16;
123 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_GwEwIwR(bxInstruction_c *i)
125 Bit16s op2_16 = BX_READ_16BIT_REG(i->rm());
126 Bit16s op3_16 = i->Iw();
128 Bit32s product_32 = op2_16 * op3_16;
129 Bit16u product_16 = (product_32 & 0xFFFF);
131 /* now write product back to destination */
132 BX_WRITE_16BIT_REG(i->nnn(), product_16);
134 /* set eflags:
135 * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
136 * result exactly fits within r16
138 SET_FLAGS_OSZAPC_LOGIC_16(product_16);
139 if(product_32 != (Bit16s) product_32)
141 ASSERT_FLAGS_OxxxxC();
145 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_GwEwR(bxInstruction_c *i)
147 Bit16s op1_16 = BX_READ_16BIT_REG(i->nnn());
148 Bit16s op2_16 = BX_READ_16BIT_REG(i->rm());
150 Bit32s product_32 = op1_16 * op2_16;
151 Bit16u product_16 = (product_32 & 0xFFFF);
153 /* now write product back to destination */
154 BX_WRITE_16BIT_REG(i->nnn(), product_16);
156 /* set eflags:
157 * IMUL r16,r/m16: condition for clearing CF & OF:
158 * result exactly fits within r16
160 SET_FLAGS_OSZAPC_LOGIC_16(product_16);
161 if(product_32 != (Bit16s) product_32)
163 ASSERT_FLAGS_OxxxxC();