OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [bochs486/] [cpu/] [stack16.cc] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/////////////////////////////////////////////////////////////////////////
2
// $Id: stack16.cc 11313 2012-08-05 13:52:40Z sshwarts $
3
/////////////////////////////////////////////////////////////////////////
4
//
5
//  Copyright (C) 2001-2012  The Bochs Project
6
//
7
//  This library is free software; you can redistribute it and/or
8
//  modify it under the terms of the GNU Lesser General Public
9
//  License as published by the Free Software Foundation; either
10
//  version 2 of the License, or (at your option) any later version.
11
//
12
//  This library is distributed in the hope that it will be useful,
13
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
//  Lesser General Public License for more details.
16
//
17
//  You should have received a copy of the GNU Lesser General Public
18
//  License along with this library; if not, write to the Free Software
19
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
20
/////////////////////////////////////////////////////////////////////////
21
 
22
#define NEED_CPU_REG_SHORTCUTS 1
23
#include "bochs.h"
24
#include "cpu.h"
25
#define LOG_THIS BX_CPU_THIS_PTR
26
 
27
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH_RX(bxInstruction_c *i)
28
{
29
  push_16(BX_READ_16BIT_REG(i->dst()));
30
 
31
  BX_NEXT_INSTR(i);
32
}
33
 
34
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH16_Sw(bxInstruction_c *i)
35
{
36
  push_16(BX_CPU_THIS_PTR sregs[i->src()].selector.value);
37
 
38
  BX_NEXT_INSTR(i);
39
}
40
 
41
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POP16_Sw(bxInstruction_c *i)
42
{
43
  RSP_SPECULATIVE;
44
 
45
  Bit16u selector = pop_16();
46
  load_seg_reg(&BX_CPU_THIS_PTR sregs[i->dst()], selector);
47
 
48
  RSP_COMMIT;
49
 
50
  if (i->dst() == BX_SEG_REG_SS) {
51
    // POP SS inhibits interrupts, debug exceptions and single-step
52
    // trap exceptions until the execution boundary following the
53
    // next instruction is reached.
54
    // Same code as MOV_SwEw()
55
    inhibit_interrupts(BX_INHIBIT_INTERRUPTS_BY_MOVSS);
56
  }
57
 
58
  BX_NEXT_INSTR(i);
59
}
60
 
61
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POP_RX(bxInstruction_c *i)
62
{
63
  BX_WRITE_16BIT_REG(i->dst(), pop_16());
64
 
65
  BX_NEXT_INSTR(i);
66
}
67
 
68
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POP_EwM(bxInstruction_c *i)
69
{
70
  RSP_SPECULATIVE;
71
 
72
  Bit16u val16 = pop_16();
73
 
74
  // Note: there is one little weirdism here.  It is possible to use
75
  // SP in the modrm addressing. If used, the value of SP after the
76
  // pop is used to calculate the address.
77
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
78
 
79
  write_virtual_word(i->seg(), eaddr, val16);
80
 
81
  RSP_COMMIT;
82
 
83
  BX_NEXT_INSTR(i);
84
}
85
 
86
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH_Iw(bxInstruction_c *i)
87
{
88
  push_16(i->Iw());
89
 
90
  BX_NEXT_INSTR(i);
91
}
92
 
93
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH_EwM(bxInstruction_c *i)
94
{
95
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
96
 
97
  Bit16u op1_16 = read_virtual_word(i->seg(), eaddr);
98
 
99
  push_16(op1_16);
100
 
101
  BX_NEXT_INSTR(i);
102
}
103
 
104
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSHAD16(bxInstruction_c *i)
105
{
106
  Bit32u temp_ESP = ESP;
107
  Bit16u temp_SP  = SP;
108
 
109
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
110
  {
111
    stack_write_word((Bit32u)(temp_ESP -  2), AX);
112
    stack_write_word((Bit32u)(temp_ESP -  4), CX);
113
    stack_write_word((Bit32u)(temp_ESP -  6), DX);
114
    stack_write_word((Bit32u)(temp_ESP -  8), BX);
115
    stack_write_word((Bit32u)(temp_ESP - 10), temp_SP);
116
    stack_write_word((Bit32u)(temp_ESP - 12), BP);
117
    stack_write_word((Bit32u)(temp_ESP - 14), SI);
118
    stack_write_word((Bit32u)(temp_ESP - 16), DI);
119
    ESP -= 16;
120
  }
121
  else
122
  {
123
    stack_write_word((Bit16u)(temp_SP -  2), AX);
124
    stack_write_word((Bit16u)(temp_SP -  4), CX);
125
    stack_write_word((Bit16u)(temp_SP -  6), DX);
126
    stack_write_word((Bit16u)(temp_SP -  8), BX);
127
    stack_write_word((Bit16u)(temp_SP - 10), temp_SP);
128
    stack_write_word((Bit16u)(temp_SP - 12), BP);
129
    stack_write_word((Bit16u)(temp_SP - 14), SI);
130
    stack_write_word((Bit16u)(temp_SP - 16), DI);
131
    SP -= 16;
132
  }
133
 
134
  BX_NEXT_INSTR(i);
135
}
136
 
137
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POPAD16(bxInstruction_c *i)
138
{
139
  Bit16u di, si, bp, bx, dx, cx, ax;
140
 
141
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
142
  {
143
    Bit32u temp_ESP = ESP;
144
    di = stack_read_word((Bit32u)(temp_ESP +  0));
145
    si = stack_read_word((Bit32u)(temp_ESP +  2));
146
    bp = stack_read_word((Bit32u)(temp_ESP +  4));
147
         stack_read_word((Bit32u)(temp_ESP +  6));
148
    bx = stack_read_word((Bit32u)(temp_ESP +  8));
149
    dx = stack_read_word((Bit32u)(temp_ESP + 10));
150
    cx = stack_read_word((Bit32u)(temp_ESP + 12));
151
    ax = stack_read_word((Bit32u)(temp_ESP + 14));
152
    ESP += 16;
153
  }
154
  else
155
  {
156
    Bit16u temp_SP = SP;
157
    di = stack_read_word((Bit16u)(temp_SP +  0));
158
    si = stack_read_word((Bit16u)(temp_SP +  2));
159
    bp = stack_read_word((Bit16u)(temp_SP +  4));
160
         stack_read_word((Bit16u)(temp_SP +  6));
161
    bx = stack_read_word((Bit16u)(temp_SP +  8));
162
    dx = stack_read_word((Bit16u)(temp_SP + 10));
163
    cx = stack_read_word((Bit16u)(temp_SP + 12));
164
    ax = stack_read_word((Bit16u)(temp_SP + 14));
165
    SP += 16;
166
  }
167
 
168
  DI = di;
169
  SI = si;
170
  BP = bp;
171
  BX = bx;
172
  DX = dx;
173
  CX = cx;
174
  AX = ax;
175
 
176
  BX_NEXT_INSTR(i);
177
}
178
 
179
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER16_IwIb(bxInstruction_c *i)
180
{
181
  Bit16u imm16 = i->Iw();
182
  Bit8u level = i->Ib2();
183
  level &= 0x1F;
184
 
185
  RSP_SPECULATIVE;
186
 
187
  push_16(BP);
188
  Bit16u frame_ptr16 = SP;
189
 
190
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
191
    Bit32u ebp = EBP; // Use temp copy for case of exception.
192
 
193
    if (level > 0) {
194
      /* do level-1 times */
195
      while (--level) {
196
        ebp -= 2;
197
        Bit16u temp16 = stack_read_word(ebp);
198
        push_16(temp16);
199
      }
200
 
201
      /* push(frame pointer) */
202
      push_16(frame_ptr16);
203
    }
204
 
205
    ESP -= imm16;
206
 
207
    // ENTER finishes with memory write check on the final stack pointer
208
    // the memory is touched but no write actually occurs
209
    // emulate it by doing RMW read access from SS:ESP
210
    read_RMW_virtual_word(BX_SEG_REG_SS, ESP);
211
 
212
    BP = frame_ptr16;
213
  }
214
  else {
215
    Bit16u bp = BP;
216
 
217
    if (level > 0) {
218
      /* do level-1 times */
219
      while (--level) {
220
        bp -= 2;
221
        Bit16u temp16 = stack_read_word(bp);
222
        push_16(temp16);
223
      }
224
 
225
      /* push(frame pointer) */
226
      push_16(frame_ptr16);
227
    }
228
 
229
    SP -= imm16;
230
 
231
    // ENTER finishes with memory write check on the final stack pointer
232
    // the memory is touched but no write actually occurs
233
    // emulate it by doing RMW read access from SS:SP
234
    read_RMW_virtual_word_32(BX_SEG_REG_SS, SP);
235
  }
236
 
237
  BP = frame_ptr16;
238
 
239
  RSP_COMMIT;
240
 
241
  BX_NEXT_INSTR(i);
242
}
243
 
244
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LEAVE16(bxInstruction_c *i)
245
{
246
  BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
247
 
248
  Bit16u value16;
249
 
250
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
251
    value16 = stack_read_word(EBP);
252
    ESP = EBP + 2;
253
  }
254
  else {
255
    value16 = stack_read_word(BP);
256
    SP = BP + 2;
257
  }
258
 
259
  BP = value16;
260
 
261
  BX_NEXT_INSTR(i);
262
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.