OSDN Git Service

[General] Convert sourcecode's CRLF format: DOS(WINDOWS) to Unix, to apply patches...
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz3500 / mz3500.cpp
1 /*
2         SHARP MZ-3500 Emulator 'EmuZ-3500'
3
4         Author : Takeda.Toshiya
5         Date   : 2010.08.31-
6
7         [ virtual machine ]
8 */
9
10 #include "mz3500.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../disk.h"
16 #include "../i8251.h"
17 #include "../i8253.h"
18 #include "../i8255.h"
19 #include "../io.h"
20 #include "../pcm1bit.h"
21 #include "../upd1990a.h"
22 #include "../upd7220.h"
23 #include "../upd765a.h"
24 #include "../z80.h"
25
26 #ifdef USE_DEBUGGER
27 #include "../debugger.h"
28 #endif
29
30 #include "main.h"
31 #include "sub.h"
32
33 // ----------------------------------------------------------------------------
34 // initialize
35 // ----------------------------------------------------------------------------
36
37 VM::VM(EMU* parent_emu) : emu(parent_emu)
38 {
39         // create devices
40         first_device = last_device = NULL;
41         dummy = new DEVICE(this, emu);  // must be 1st device
42         event = new EVENT(this, emu);   // must be 2nd device
43         
44         // for main cpu
45         io = new IO(this, emu);
46         fdc = new UPD765A(this, emu);
47         cpu = new Z80(this, emu);
48         main = new MAIN(this, emu);
49         
50         // for sub cpu
51         sio = new I8251(this, emu);
52         pit = new I8253(this, emu);
53         pio = new I8255(this, emu);
54         subio = new IO(this, emu);
55         pcm = new PCM1BIT(this, emu);
56         rtc = new UPD1990A(this, emu);
57         gdc_chr = new UPD7220(this, emu);
58         gdc_gfx = new UPD7220(this, emu);
59         subcpu = new Z80(this, emu);
60         sub = new SUB(this, emu);
61         
62         // set contexts
63         event->set_context_cpu(cpu);
64         event->set_context_cpu(subcpu);
65         event->set_context_sound(pcm);
66         
67         // mz3500sm p.59
68         fdc->set_context_irq(main, SIG_MAIN_INTFD, 1);
69         fdc->set_context_drq(main, SIG_MAIN_DRQ, 1);
70         fdc->set_context_index(main, SIG_MAIN_INDEX, 1);
71         
72         // mz3500sm p.72,77
73         sio->set_context_rxrdy(subcpu, SIG_CPU_NMI, 1);
74         
75         // mz3500sm p.77
76         // i8253 ch.0 -> i8251 txc,rxc
77         pit->set_context_ch1(pcm, SIG_PCM1BIT_SIGNAL, 1);
78         pit->set_context_ch2(pit, SIG_I8253_GATE_1, 1);
79         pit->set_constant_clock(0, 2450000);
80         pit->set_constant_clock(1, 2450000);
81         pit->set_constant_clock(2, 2450000);
82         
83         // mz3500sm p.78,80,81
84         // i8255 pa0-pa7 -> printer data
85         pio->set_context_port_b(rtc, SIG_UPD1990A_STB, 0x01, 0);
86         pio->set_context_port_b(rtc, SIG_UPD1990A_C0,  0x02, 0);
87         pio->set_context_port_b(rtc, SIG_UPD1990A_C1,  0x04, 0);
88         pio->set_context_port_b(rtc, SIG_UPD1990A_C2,  0x08, 0);
89         pio->set_context_port_b(rtc, SIG_UPD1990A_DIN, 0x10, 0);
90         pio->set_context_port_b(rtc, SIG_UPD1990A_CLK, 0x20, 0);
91         pio->set_context_port_b(main, SIG_MAIN_SRDY, 0x40, 0);
92         pio->set_context_port_b(sub, SIG_SUB_PIO_PM, 0x80, 0);  // P/M: CG Selection
93         pio->set_context_port_c(sub, SIG_SUB_KEYBOARD_DC, 0x01, 0);
94         pio->set_context_port_c(sub, SIG_SUB_KEYBOARD_STC, 0x02, 0);
95         pio->set_context_port_c(sub, SIG_SUB_KEYBOARD_ACKC, 0x04, 0);
96         // i8255 pc3 <- intr (not use ???)
97         pio->set_context_port_c(pcm, SIG_PCM1BIT_MUTE, 0x10, 0);
98         // i8255 pc5 -> printer strobe
99         // i8255 pc6 <- printer ack
100         pio->set_context_port_c(sub, SIG_SUB_PIO_OBF, 0x80, 0);
101         
102         // mz3500sm p.80,81
103         rtc->set_context_dout(sub, SIG_SUB_RTC_DOUT, 1);
104         
105         gdc_chr->set_vram_ptr(sub->get_vram_chr(), 0x1000);
106         sub->set_sync_ptr_chr(gdc_chr->get_sync());
107         sub->set_ra_ptr_chr(gdc_chr->get_ra());
108         sub->set_cs_ptr_chr(gdc_chr->get_cs());
109         sub->set_ead_ptr_chr(gdc_chr->get_ead());
110         
111         gdc_gfx->set_vram_ptr(sub->get_vram_gfx(), 0x20000);
112         sub->set_sync_ptr_gfx(gdc_gfx->get_sync());
113         sub->set_ra_ptr_gfx(gdc_gfx->get_ra());
114         sub->set_cs_ptr_gfx(gdc_gfx->get_cs());
115         sub->set_ead_ptr_gfx(gdc_gfx->get_ead());
116         
117         // mz3500sm p.23
118         subcpu->set_context_busack(main, SIG_MAIN_SACK, 1);
119         
120         main->set_context_cpu(cpu);
121         main->set_context_subcpu(subcpu);
122         main->set_context_fdc(fdc);
123         
124         sub->set_context_main(main);
125         sub->set_ipl(main->get_ipl());
126         sub->set_common(main->get_common());
127         
128         // mz3500sm p.17
129         io->set_iomap_range_rw(0xec, 0xef, main);       // reset int0
130         io->set_iomap_range_rw(0xf4, 0xf7, fdc);        // fdc: f4h,f6h = status, f5h,f7h = data
131         io->set_iomap_range_rw(0xf8, 0xfb, main);       // mfd interface
132         io->set_iomap_range_rw(0xfc, 0xff, main);       // memory mpaper
133         
134         // mz3500sm p.18
135         subio->set_iomap_range_rw(0x00, 0x0f, sub);     // int0 to main (set flipflop)
136         subio->set_iomap_range_rw(0x10, 0x1f, sio);
137         subio->set_iomap_range_rw(0x20, 0x2f, pit);
138         subio->set_iomap_range_rw(0x30, 0x3f, pio);
139         subio->set_iomap_range_r(0x40, 0x4f, sub);      // input port
140         subio->set_iomap_range_w(0x50, 0x5f, sub);      // crt control i/o
141         subio->set_iomap_range_rw(0x60, 0x6f, gdc_gfx);
142         subio->set_iomap_range_rw(0x70, 0x7f, gdc_chr);
143         
144         // cpu bus
145         cpu->set_context_mem(main);
146         cpu->set_context_io(io);
147         cpu->set_context_intr(main);
148 #ifdef USE_DEBUGGER
149         cpu->set_context_debugger(new DEBUGGER(this, emu));
150 #endif
151         
152         subcpu->set_context_mem(sub);
153         subcpu->set_context_io(subio);
154         subcpu->set_context_intr(sub);
155 #ifdef USE_DEBUGGER
156         subcpu->set_context_debugger(new DEBUGGER(this, emu));
157 #endif
158         
159         // initialize all devices
160         for(DEVICE* device = first_device; device; device = device->next_device) {
161                 device->initialize();
162         }
163         for(int i = 0; i < 4; i++) {
164                 fdc->set_drive_type(i, DRIVE_TYPE_2DD);
165         }
166 }
167
168 VM::~VM()
169 {
170         // delete all devices
171         for(DEVICE* device = first_device; device;) {
172                 DEVICE *next_device = device->next_device;
173                 device->release();
174                 delete device;
175                 device = next_device;
176         }
177 }
178
179 DEVICE* VM::get_device(int id)
180 {
181         for(DEVICE* device = first_device; device; device = device->next_device) {
182                 if(device->this_device_id == id) {
183                         return device;
184                 }
185         }
186         return NULL;
187 }
188
189 // ----------------------------------------------------------------------------
190 // drive virtual machine
191 // ----------------------------------------------------------------------------
192
193 void VM::reset()
194 {
195         // reset all devices
196         for(DEVICE* device = first_device; device; device = device->next_device) {
197                 device->reset();
198         }
199         
200         // set busreq of sub cpu
201         subcpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
202 }
203
204 void VM::run()
205 {
206         event->drive();
207 }
208
209 double VM::frame_rate()
210 {
211         return event->frame_rate();
212 }
213
214 // ----------------------------------------------------------------------------
215 // debugger
216 // ----------------------------------------------------------------------------
217
218 #ifdef USE_DEBUGGER
219 DEVICE *VM::get_cpu(int index)
220 {
221         if(index == 0) {
222                 return cpu;
223         } else if(index == 1) {
224                 return subcpu;
225         }
226         return NULL;
227 }
228 #endif
229
230 // ----------------------------------------------------------------------------
231 // draw screen
232 // ----------------------------------------------------------------------------
233
234 void VM::draw_screen()
235 {
236         sub->draw_screen();
237 }
238
239 int VM::access_lamp()
240 {
241         uint32 status = fdc->read_signal(0);
242         return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;
243 }
244
245 // ----------------------------------------------------------------------------
246 // soud manager
247 // ----------------------------------------------------------------------------
248
249 void VM::initialize_sound(int rate, int samples)
250 {
251         // init sound manager
252         event->initialize_sound(rate, samples);
253         
254         // init sound gen
255         pcm->init(rate, 8000);
256 }
257
258 uint16* VM::create_sound(int* extra_frames)
259 {
260         return event->create_sound(extra_frames);
261 }
262
263 int VM::sound_buffer_ptr()
264 {
265         return event->sound_buffer_ptr();
266 }
267
268 // ----------------------------------------------------------------------------
269 // notify key
270 // ----------------------------------------------------------------------------
271
272 void VM::key_down(int code, bool repeat)
273 {
274         sub->key_down(code);
275 }
276
277 void VM::key_up(int code)
278 {
279         sub->key_up(code);
280 }
281
282 // ----------------------------------------------------------------------------
283 // user interface
284 // ----------------------------------------------------------------------------
285
286 void VM::open_disk(int drv, _TCHAR* file_path, int offset)
287 {
288         fdc->open_disk(drv, file_path, offset);
289 }
290
291 void VM::close_disk(int drv)
292 {
293         fdc->close_disk(drv);
294 }
295
296 bool VM::disk_inserted(int drv)
297 {
298         return fdc->disk_inserted(drv);
299 }
300
301 bool VM::now_skip()
302 {
303         return event->now_skip();
304 }
305
306 void VM::update_config()
307 {
308         for(DEVICE* device = first_device; device; device = device->next_device) {
309                 device->update_config();
310         }
311 }
312