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

Subversion Repositories s80186

[/] [s80186/] [trunk/] [sim/] [cppmodel/] [SoftwareCPU.h] - 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
#pragma once
19
#include <map>
20
 
21
#include "CPU.h"
22
#include "Emulate.h"
23
 
24
class Emulator;
25
class EmulatorPimpl;
26
 
27
class SoftwareCPU : public SimCPU
28
{
29
public:
30
    SoftwareCPU() : SoftwareCPU("default")
31
    {
32
    }
33
    SoftwareCPU(const std::string &name)
34
        : SimCPU(name), emulator(&registers, this)
35
    {
36
        (void)name;
37
 
38
        emulator.set_memory(&mem);
39
        emulator.set_io(&io);
40
    }
41
 
42
    void write_reg(GPR regnum, uint16_t val)
43
    {
44
        registers.set(regnum, val);
45
    }
46
 
47
    uint16_t read_reg(GPR regnum) const
48
    {
49
        return registers.get(regnum);
50
    }
51
 
52
    size_t step()
53
    {
54
        return emulator.step();
55
    }
56
 
57
    size_t step_with_io(std::function<void(unsigned long)> io_callback)
58
    {
59
        return emulator.step_with_io(io_callback);
60
    }
61
 
62
    void write_flags(uint16_t val)
63
    {
64
        registers.set_flags(val);
65
    }
66
 
67
    uint16_t read_flags() const
68
    {
69
        return registers.get_flags();
70
    }
71
 
72
    bool has_trapped()
73
    {
74
        return emulator.has_trapped();
75
    }
76
 
77
    void reset()
78
    {
79
        emulator.reset();
80
    }
81
 
82
    bool instruction_had_side_effects() const
83
    {
84
        return mem.has_written() || registers.has_written();
85
    }
86
 
87
    void clear_side_effects()
88
    {
89
        registers.clear_has_written();
90
        mem.clear_has_written();
91
    }
92
 
93
    void write_mem8(uint16_t segment, uint16_t addr, uint8_t val)
94
    {
95
        mem.write<uint8_t>(get_phys_addr(segment, addr), val);
96
    }
97
    void write_mem16(uint16_t segment, uint16_t addr, uint16_t val)
98
    {
99
        mem.write<uint16_t>(get_phys_addr(segment, addr), val);
100
    }
101
    void write_mem32(uint16_t segment, uint16_t addr, uint32_t val)
102
    {
103
        mem.write<uint32_t>(get_phys_addr(segment, addr), val);
104
    }
105
 
106
    uint8_t read_mem8(uint16_t segment, uint16_t addr)
107
    {
108
        return mem.read<uint8_t>(get_phys_addr(segment, addr));
109
    }
110
    uint16_t read_mem16(uint16_t segment, uint16_t addr)
111
    {
112
        return mem.read<uint16_t>(get_phys_addr(segment, addr));
113
    }
114
    uint32_t read_mem32(uint16_t segment, uint16_t addr)
115
    {
116
        return mem.read<uint32_t>(get_phys_addr(segment, addr));
117
    }
118
 
119
    void write_io8(uint32_t addr, uint8_t val)
120
    {
121
        if (!io.count(addr & ~1))
122
            return;
123
 
124
        auto p = io[addr & ~1];
125
        p->write8((addr & -1) - p->get_base(), addr & 1, val);
126
    }
127
    void write_io16(uint32_t addr, uint16_t val)
128
    {
129
        if (!io.count(addr & ~1))
130
            return;
131
 
132
        auto p = io[addr & ~1];
133
        p->write16((addr & -1) - p->get_base(), val);
134
    }
135
 
136
    uint8_t read_io8(uint32_t addr)
137
    {
138
        if (!io.count(addr & ~1))
139
            return 0;
140
 
141
        auto p = io[addr & ~1];
142
        return p->read8((addr & -1) - p->get_base(), addr & 1);
143
    }
144
    uint16_t read_io16(uint32_t addr)
145
    {
146
        if (!io.count(addr & ~1))
147
            return 0;
148
 
149
        auto p = io[addr & ~1];
150
        return p->read16((addr & -1) - p->get_base());
151
    }
152
 
153
    virtual bool has_instruction_length() const
154
    {
155
        return true;
156
    }
157
 
158
    virtual void add_ioport(IOPorts *p)
159
    {
160
        for (size_t m = 0; m < p->get_num_ports(); ++m)
161
            io[p->get_base() + m * sizeof(uint16_t)] = p;
162
    }
163
 
164
    virtual void raise_nmi()
165
    {
166
        emulator.raise_nmi();
167
    }
168
 
169
    virtual void raise_irq(int irq_num)
170
    {
171
        emulator.raise_irq(irq_num);
172
    }
173
 
174
    unsigned long cycle_count() const
175
    {
176
        return emulator.cycle_count();
177
    }
178
 
179
private:
180
    RegisterFile registers;
181
    Emulator emulator;
182
 
183
    std::map<uint16_t, IOPorts *> io;
184
};

powered by: WebSVN 2.1.0

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