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

Subversion Repositories s80186

[/] [s80186/] [trunk/] [tests/] [instructions/] [TestStringInterrupt.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jamieiles
// Copyright Jamie Iles, 2017
2
//
3
// This file is part of s80x86.
4
//
5
// s80x86 is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// s80x86 is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with s80x86.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
#include <gtest/gtest.h>
19
 
20
#include "EmulateFixture.h"
21
#include "Flags.h"
22
 
23
class StringIntTest : public EmulateFixture
24
{
25
public:
26
    void setup_nmi_handler();
27
    void assert_nmi_taken(int return_offset);
28
    void inject_nmi();
29
};
30
 
31
void StringIntTest::setup_nmi_handler()
32
{
33
    write_mem16(VEC_NMI + 2, 0x8000, CS); // CS
34
    write_mem16(VEC_NMI + 0, 0x0100, CS); // IP
35
 
36
    write_reg(SP, 0x100);
37
}
38
 
39
void StringIntTest::inject_nmi()
40
{
41
    cpu->start_instruction();
42
 
43
    // yield point inside the string instruction
44
    wait_for_int_yield();
45
    cpu->raise_nmi();
46
 
47
    cpu->complete_instruction();
48
}
49
 
50
void StringIntTest::assert_nmi_taken(int return_offset)
51
{
52
    EXPECT_PRED_FORMAT2(AssertFlagsEqual, read_flags() & (TF | IF), 0);
53
    EXPECT_EQ(read_reg(CS), 0x8000);
54
    EXPECT_EQ(read_reg(IP), 0x0100);
55
    EXPECT_EQ(read_reg(SP), 0x0100 - 6);
56
 
57
    EXPECT_EQ(read_mem16(0x100 - 4, SS), 0x0000);
58
    EXPECT_EQ(read_mem16(0x100 - 6, SS), 0x1000 + return_offset);
59
}
60
 
61
// These tests only run on the RTL CPU where we know that we can start single
62
// stepping and then go through cycle by cycle and then inject an NMI.
63
 
64
TEST_F(StringIntTest, ScasbInt)
65
{
66
    setup_nmi_handler();
67
 
68
    write_reg(AL, 0);
69
    write_reg(DI, 0x800);
70
    write_reg(CX, 0xff);
71
    write_cstring(0x800, "8086", ES);
72
 
73
    // repne scasb
74
    set_instruction({0xf2, 0xae});
75
 
76
    inject_nmi();
77
 
78
    ASSERT_EQ(read_reg(DI), 0x801);
79
 
80
    assert_nmi_taken(0);
81
}
82
 
83
TEST_F(StringIntTest, ScaswInt)
84
{
85
    setup_nmi_handler();
86
 
87
    write_reg(AX, 0);
88
    write_reg(DI, 0x800);
89
    write_reg(CX, 0xff);
90
 
91
    for (int i = 0; i < 2; ++i)
92
        write_mem16(0x800 + i * 2, 0xaa55, ES);
93
    write_mem16(0x800 + 2 * 2, 0x0000, ES);
94
 
95
    // repne scasw
96
    set_instruction({0xf2, 0xaf});
97
 
98
    inject_nmi();
99
 
100
    ASSERT_EQ(read_reg(DI), 0x802);
101
 
102
    assert_nmi_taken(0);
103
}
104
 
105
TEST_F(StringIntTest, MovsbInt)
106
{
107
    setup_nmi_handler();
108
 
109
    write_reg(AL, 0);
110
    write_reg(SI, 0x800);
111
    write_reg(DI, 0x400);
112
    write_reg(CX, 0x4);
113
    write_cstring(0x800, "8086");
114
    write_mem8(0x404, 0, ES);
115
 
116
    // repne movsb
117
    set_instruction({0x26, 0xf3, 0xa4});
118
 
119
    inject_nmi();
120
 
121
    ASSERT_EQ(read_reg(DI), 0x401);
122
    ASSERT_EQ(read_reg(SI), 0x801);
123
    ASSERT_EQ(read_reg(CX), 0x3);
124
 
125
    assert_nmi_taken(0);
126
}
127
 
128
TEST_F(StringIntTest, MovswInt)
129
{
130
    setup_nmi_handler();
131
 
132
    write_reg(AL, 0);
133
    write_reg(SI, 0x800);
134
    write_reg(DI, 0x400);
135
    write_reg(CX, 0x2);
136
    write_mem16(0x800, 0xaa55);
137
    write_mem16(0x802, 0x55aa);
138
 
139
    // repne movsw
140
    set_instruction({0xf3, 0xa5});
141
 
142
    inject_nmi();
143
 
144
    ASSERT_EQ(read_reg(DI), 0x402);
145
    ASSERT_EQ(read_reg(SI), 0x802);
146
 
147
    assert_nmi_taken(0);
148
}
149
 
150
TEST_F(StringIntTest, CmpsbInt)
151
{
152
    setup_nmi_handler();
153
 
154
    write_flags(0);
155
 
156
    write_reg(SI, 0x800);
157
    write_reg(DI, 0x400);
158
    write_reg(CX, 8);
159
 
160
    for (auto i = 0; i < 8; ++i) {
161
        write_mem8(0x400 + i, 0, ES);
162
        write_mem8(0x800 + i, 0);
163
    }
164
    write_vector8(0x800, {0, 1, 2, 4, 5, 6, 7});
165
    write_vector8(0x400, {0, 1, 2, 4, 5, 6, 7}, ES);
166
 
167
    set_instruction({0xf3, 0xa6});
168
 
169
    inject_nmi();
170
 
171
    ASSERT_EQ(1, read_reg(SI) - 0x800);
172
 
173
    assert_nmi_taken(0);
174
}
175
 
176
TEST_F(StringIntTest, CmpswInt)
177
{
178
    setup_nmi_handler();
179
 
180
    write_flags(0);
181
 
182
    write_reg(SI, 0x800);
183
    write_reg(DI, 0x400);
184
    write_reg(CX, 4);
185
 
186
    for (auto i = 0; i < 8; ++i) {
187
        write_mem8(0x400 + i, 0, ES);
188
        write_mem8(0x800 + i, 0);
189
    }
190
    write_vector8(0x800, {0, 1, 2, 4, 5, 6, 7});
191
    write_vector8(0x400, {0, 1, 2, 4, 5, 6, 7}, ES);
192
 
193
    set_instruction({0xf3, 0xa7});
194
 
195
    inject_nmi();
196
 
197
    ASSERT_EQ(2, read_reg(SI) - 0x800);
198
 
199
    assert_nmi_taken(0);
200
}
201
 
202
TEST_F(StringIntTest, LodsbInt)
203
{
204
    setup_nmi_handler();
205
 
206
    write_flags(0);
207
    write_reg(SI, 0x800);
208
    write_cstring(0x800, "foo");
209
    write_reg(CX, 3);
210
 
211
    set_instruction({0xf2, 0xac});
212
 
213
    inject_nmi();
214
 
215
    ASSERT_EQ(read_reg(SI), 0x801);
216
 
217
    assert_nmi_taken(0);
218
}
219
 
220
TEST_F(StringIntTest, LodswInt)
221
{
222
    setup_nmi_handler();
223
 
224
    write_flags(0);
225
    write_reg(SI, 0x800);
226
    write_vector16(0x800, {0x1234, 0x5678});
227
    write_reg(CX, 2);
228
 
229
    set_instruction({0xf2, 0xad});
230
 
231
    inject_nmi();
232
 
233
    ASSERT_EQ(read_reg(SI), 0x802);
234
 
235
    assert_nmi_taken(0);
236
}
237
 
238
TEST_F(StringIntTest, StosbInt)
239
{
240
    setup_nmi_handler();
241
 
242
    write_flags(0);
243
    write_reg(DI, 0x800);
244
    write_mem8(0x803, 0);
245
    write_reg(AL, 'a');
246
    write_reg(CX, 3);
247
    write_vector8(0x800, {0, 0, 0, 0, 0, 0, 0, 0}, ES);
248
 
249
    set_instruction({0xf2, 0xaa});
250
 
251
    inject_nmi();
252
 
253
    ASSERT_EQ(read_reg(DI), 0x801);
254
 
255
    assert_nmi_taken(0);
256
}
257
 
258
TEST_F(StringIntTest, StoswInt)
259
{
260
    setup_nmi_handler();
261
 
262
    write_flags(0);
263
    write_reg(DI, 0x800);
264
    write_reg(AX, 0x6261);
265
    write_mem16(0x806, 0x0000);
266
    write_reg(CX, 3);
267
    write_vector16(0x800, {0, 0, 0, 0, 0, 0, 0, 0}, ES);
268
 
269
    set_instruction({0xf2, 0xab});
270
 
271
    inject_nmi();
272
 
273
    ASSERT_EQ(read_reg(DI), 0x802);
274
 
275
    assert_nmi_taken(0);
276
}
277
 
278
TEST_F(StringIntTest, HltBlocks)
279
{
280
    setup_nmi_handler();
281
 
282
    write_flags(0);
283
 
284
    set_instruction({0xf4});
285
 
286
    cpu->start_instruction();
287
 
288
    // Skip over the opcode_fetch yield point
289
    wait_for_int_yield();
290
    for (auto i = 0; i < 256; ++i)
291
        cpu->cycle_cpu();
292
    cpu->raise_nmi();
293
 
294
    cpu->complete_instruction();
295
 
296
    assert_nmi_taken(1);
297
}

powered by: WebSVN 2.1.0

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