OSDN Git Service

[General] Merge upstream : 2015-02-21.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc8201 / pc8201.cpp
1 /*
2         NEC PC-8201 Emulator 'ePC-8201'
3
4         Author : Takeda.Toshiya
5         Date   : 2009.03.31-
6
7         [ virtual machine ]
8 */
9
10 #include "pc8201.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../datarec.h"
16 #include "../i8080.h"
17 #include "../i8155.h"
18 #include "../io.h"
19 #include "../pcm1bit.h"
20 #include "../upd1990a.h"
21
22 #ifdef USE_DEBUGGER
23 #include "../debugger.h"
24 #endif
25
26 #include "cmt.h"
27 #include "keyboard.h"
28 #include "lcd.h"
29 #include "memory.h"
30
31 // ----------------------------------------------------------------------------
32 // initialize
33 // ----------------------------------------------------------------------------
34
35 VM::VM(EMU* parent_emu) : emu(parent_emu)
36 {
37         // create devices
38         first_device = last_device = NULL;
39         dummy = new DEVICE(this, emu);  // must be 1st device
40         event = new EVENT(this, emu);   // must be 2nd device
41         
42         drec = new DATAREC(this, emu);
43         cpu = new I8080(this, emu);
44         pio = new I8155(this, emu);
45         io = new IO(this, emu);
46         pcm = new PCM1BIT(this, emu);
47         rtc = new UPD1990A(this, emu);
48         
49         cmt = new CMT(this, emu);
50         keyboard = new KEYBOARD(this, emu);
51         lcd = new LCD(this, emu);
52         memory = new MEMORY(this, emu);
53         
54         // set contexts
55         event->set_context_cpu(cpu);
56         event->set_context_sound(pcm);
57         
58         drec->set_context_out(cpu, SIG_I8085_SID, 1);
59         cpu->set_context_sod(cmt, SIG_CMT_SOD, 1);
60         pio->set_context_port_a(rtc, SIG_UPD1990A_C0, 1, 0);
61         pio->set_context_port_a(rtc, SIG_UPD1990A_C1, 2, 0);
62         pio->set_context_port_a(rtc, SIG_UPD1990A_C2, 4, 0);
63         pio->set_context_port_a(rtc, SIG_UPD1990A_CLK, 8, 0);
64         pio->set_context_port_a(rtc, SIG_UPD1990A_DIN, 0x10, 0);
65         pio->set_context_port_a(keyboard, SIG_KEYBOARD_COLUMN_L, 0xff, 0);
66         pio->set_context_port_a(lcd, SIG_LCD_CHIPSEL_L, 0xff, 0);
67         pio->set_context_port_b(keyboard, SIG_KEYBOARD_COLUMN_H, 1, 0);
68         pio->set_context_port_b(lcd, SIG_LCD_CHIPSEL_H, 3, 0);
69         pio->set_context_port_b(pcm, SIG_PCM1BIT_MUTE, 0x20, 0);
70         pio->set_context_timer(pcm, SIG_PCM1BIT_SIGNAL, 1);
71         pio->set_constant_clock(CPU_CLOCKS);
72         rtc->set_context_dout(pio, SIG_I8155_PORT_C, 1);
73         rtc->set_context_tp(cpu, SIG_I8085_RST7, 1);
74         
75         memory->set_context_cmt(cmt);
76         memory->set_context_drec(drec);
77         memory->set_context_rtc(rtc);
78         
79         // cpu bus
80         cpu->set_context_mem(memory);
81         cpu->set_context_io(io);
82         cpu->set_context_intr(io);
83 #ifdef USE_DEBUGGER
84         cpu->set_context_debugger(new DEBUGGER(this, emu));
85 #endif
86         
87         // i/o bus
88         io->set_iomap_range_w(0x90, 0x9f, memory);
89         io->set_iomap_range_rw(0xa0, 0xaf, memory);
90         io->set_iomap_range_rw(0xb0, 0xbf, pio);
91         io->set_iomap_range_r(0xe0, 0xef, keyboard);
92         io->set_iomap_range_rw(0xf0, 0xff, lcd);
93         
94         // initialize all devices
95         for(DEVICE* device = first_device; device; device = device->next_device) {
96                 device->initialize();
97         }
98         rtc->write_signal(SIG_UPD1990A_STB, 0, 0);
99 }
100
101 VM::~VM()
102 {
103         // delete all devices
104         for(DEVICE* device = first_device; device;) {
105                 DEVICE *next_device = device->next_device;
106                 device->release();
107                 delete device;
108                 device = next_device;
109         }
110 }
111
112 DEVICE* VM::get_device(int id)
113 {
114         for(DEVICE* device = first_device; device; device = device->next_device) {
115                 if(device->this_device_id == id) {
116                         return device;
117                 }
118         }
119         return NULL;
120 }
121
122 // ----------------------------------------------------------------------------
123 // drive virtual machine
124 // ----------------------------------------------------------------------------
125
126 void VM::reset()
127 {
128         // reset all devices
129         for(DEVICE* device = first_device; device; device = device->next_device) {
130                 device->reset();
131         }
132 }
133
134 void VM::run()
135 {
136         event->drive();
137 }
138
139 // ----------------------------------------------------------------------------
140 // debugger
141 // ----------------------------------------------------------------------------
142
143 #ifdef USE_DEBUGGER
144 DEVICE *VM::get_cpu(int index)
145 {
146         if(index == 0) {
147                 return cpu;
148         }
149         return NULL;
150 }
151 #endif
152
153 // ----------------------------------------------------------------------------
154 // draw screen
155 // ----------------------------------------------------------------------------
156
157 void VM::draw_screen()
158 {
159         lcd->draw_screen();
160 }
161
162 // ----------------------------------------------------------------------------
163 // soud manager
164 // ----------------------------------------------------------------------------
165
166 void VM::initialize_sound(int rate, int samples)
167 {
168         // init sound manager
169         event->initialize_sound(rate, samples);
170         
171         // init sound gen
172         pcm->init(rate, 8000);
173 }
174
175 uint16* VM::create_sound(int* extra_frames)
176 {
177         return event->create_sound(extra_frames);
178 }
179
180 int VM::sound_buffer_ptr()
181 {
182         return event->sound_buffer_ptr();
183 }
184
185 // ----------------------------------------------------------------------------
186 // notify key
187 // ----------------------------------------------------------------------------
188
189 void VM::key_down(int code, bool repeat)
190 {
191         keyboard->key_down(code);
192 }
193
194 void VM::key_up(int code)
195 {
196 }
197
198 // ----------------------------------------------------------------------------
199 // user interface
200 // ----------------------------------------------------------------------------
201
202 void VM::play_tape(_TCHAR* file_path)
203 {
204         cmt->close_tape();
205         drec->play_tape(file_path);
206 }
207
208 void VM::rec_tape(_TCHAR* file_path)
209 {
210         drec->close_tape();
211         cmt->rec_tape(file_path);
212 }
213
214 void VM::close_tape()
215 {
216         drec->close_tape();
217         cmt->close_tape();
218 }
219
220 bool VM::tape_inserted()
221 {
222         return drec->tape_inserted() || cmt->tape_inserted();
223 }
224
225 bool VM::now_skip()
226 {
227         return event->now_skip();
228 }
229
230 void VM::update_config()
231 {
232         for(DEVICE* device = first_device; device; device = device->next_device) {
233                 device->update_config();
234         }
235 }
236