OSDN Git Service

[VM][General] Merge upstream 2016-02-13. Still don't implement OSD/Gui part of joysti...
[csp-qt/common_source_project-fm7.git] / source / src / vm / j3100 / j3100.cpp
1 /*
2         TOSHIBA J-3100GT Emulator 'eJ-3100GT'
3         TOSHIBA J-3100SL Emulator 'eJ-3100SL'
4
5         Author : Takeda.Toshiya
6         Date   : 2011.08.16-
7
8         [ virtual machine ]
9 */
10
11 #include "j3100.h"
12 #include "../../emu.h"
13 #include "../device.h"
14 #include "../event.h"
15
16 #include "../hd46505.h"
17 #include "../i8237.h"
18 //#include "../i8250.h"
19 #include "../i8253.h"
20 #include "../i8259.h"
21 #include "../i86.h"
22 #include "../io.h"
23 #include "../pcm1bit.h"
24 #include "../upd765a.h"
25 #ifdef TYPE_SL
26 #include "../rp5c01.h"
27 #else
28 #include "../hd146818p.h"
29 #endif
30
31 #include "display.h"
32 #include "dmareg.h"
33 #include "floppy.h"
34 #include "sasi.h"
35 #ifdef TYPE_SL
36 #include "slkeyboard.h"
37 #include "slmemory.h"
38 #include "slsystem.h"
39 #else
40 #include "keyboard.h"
41 #include "memory.h"
42 #include "system.h"
43 #endif
44
45 // ----------------------------------------------------------------------------
46 // initialize
47 // ----------------------------------------------------------------------------
48
49 VM::VM(EMU* parent_emu) : emu(parent_emu)
50 {
51         // create devices
52         first_device = last_device = NULL;
53         dummy = new DEVICE(this, emu);  // must be 1st device
54         event = new EVENT(this, emu);   // must be 2nd device
55         
56         crtc = new HD46505(this, emu);
57         dma = new I8237(this, emu);
58 #ifndef TYPE_SL
59         dma2 = new I8237(this, emu);
60 #endif
61 //      sio = new I8250(this, emu);
62         pit = new I8253(this, emu);     // i8254
63         pic = new I8259(this, emu);
64         cpu = new I86(this, emu);
65         io = new IO(this, emu);
66         pcm = new PCM1BIT(this, emu);
67         fdc = new UPD765A(this, emu);
68 #ifdef TYPE_SL
69         rtc = new RP5C01(this, emu);
70 #else
71         rtc = new HD146818P(this, emu);
72 #endif
73         
74         display = new DISPLAY(this, emu);
75         dmareg = new DMAREG(this, emu);
76         floppy = new FLOPPY(this, emu);
77         keyboard = new KEYBOARD(this, emu);
78         memory = new MEMORY(this, emu);
79         sasi = new SASI(this, emu);
80         system = new SYSTEM(this, emu);
81         
82         // set contexts
83         event->set_context_cpu(cpu);
84         event->set_context_sound(pcm);
85         
86         // cpu bus
87         cpu->set_context_mem(memory);
88         cpu->set_context_io(io);
89         cpu->set_context_intr(pic);
90         
91         // dmac
92         io->set_iomap_range_rw(0x00, 0x0f, dma);
93         io->set_iomap_range_w(0x80, 0x8f, dmareg);
94         dma->set_context_memory(memory);
95         dma->set_context_ch2(fdc);
96         dmareg->set_context_dma(dma);
97 #ifndef TYPE_SL
98         for(int i = 0xc0; i <= 0xde; i += 2) {
99                 io->set_iomap_alias_rw(i, dma2, i >> 1);
100         }
101         dma2->set_context_memory(memory);
102         dma2->set_mode_word(true);
103         dmareg->set_context_dma2(dma2);
104 #endif
105         
106         // pic
107         io->set_iomap_alias_rw(0x20, pic, I8259_ADDR_CHIP0 | 0);
108         io->set_iomap_alias_rw(0x21, pic, I8259_ADDR_CHIP0 | 1);
109 #ifndef TYPE_SL
110         io->set_iomap_alias_rw(0xa0, pic, I8259_ADDR_CHIP1 | 0);
111         io->set_iomap_alias_rw(0xa1, pic, I8259_ADDR_CHIP1 | 1);
112 #endif
113         pic->set_context_cpu(cpu);
114         
115         // pit
116         io->set_iomap_range_rw(0x40, 0x43, pit);
117         pit->set_constant_clock(0, 1190000);
118         pit->set_constant_clock(1, 1190000);
119         pit->set_constant_clock(2, 1190000);
120         pit->set_context_ch0(pic, SIG_I8259_IR0 | SIG_I8259_CHIP0, 1);  // to PIC#0 IR0
121         pit->set_context_ch2(pcm, SIG_PCM1BIT_SIGNAL, 1);
122 #ifndef TYPE_SL
123         pit->set_context_ch2(system, SIG_SYSTEM_TC2O, 1);
124 #endif
125         
126         // system status/command
127 #ifndef TYPE_SL
128         io->set_iomap_single_rw(0x61, system);
129         system->set_context_pcm(pcm);
130         system->set_context_pit(pit);
131 #endif
132         
133         // rtc
134 #ifdef TYPE_SL
135         io->set_iomap_range_rw(0x2c0, 0x2cf, rtc);
136 #else
137         io->set_iomap_alias_w(0x70, rtc, 1);    // bit7 = nmi mask
138         io->set_iomap_alias_rw(0x71, rtc, 0);
139         rtc->set_context_intr(pic, SIG_I8259_IR0 | SIG_I8259_CHIP1, 1); // to PIC#1 IR0 (IR8)
140 #endif
141         
142         // nmi mask register
143 #ifdef TYPE_SL
144         io->set_iomap_single_w(0xa0, system);
145 #else
146         // 0x70 bit7 (not implemented)
147 #endif
148         
149         // crtc
150         io->set_iomap_range_rw(0x3d0, 0x3d1, crtc);
151         io->set_iomap_range_rw(0x3d4, 0x3d5, crtc);
152         io->set_iomap_range_w(0x3d8, 0x3d9, display);
153         io->set_iomap_single_r(0x3da, display);
154         crtc->set_context_disp(display, SIG_DISPLAY_ENABLE, 1);
155         crtc->set_context_vblank(display, SIG_DISPLAY_VBLANK, 1);
156         display->set_regs_ptr(crtc->get_regs());
157         display->set_vram_ptr(memory->get_vram());
158         
159         // fdc
160         io->set_iomap_single_w(0x3f2, floppy);
161         io->set_iomap_range_rw(0x3f4, 0x3f5, fdc);
162         io->set_iomap_single_rw(0x3f7, floppy);
163         fdc->set_context_irq(pic, SIG_I8259_IR6 | SIG_I8259_CHIP0, 1);  // to PIC#0 IR6
164         fdc->set_context_drq(dma, SIG_I8237_CH2, 1);                    // to DMA Ch.2
165         floppy->set_context_fdc(fdc);
166         
167         // printer
168         io->set_flipflop_single_rw(0x378, 0x00);
169         io->set_iovalue_single_r(0x379, 0x78);
170         io->set_flipflop_single_rw(0x37a, 0x00);
171         
172         // keyboard
173 #ifdef TYPE_SL
174         io->set_iomap_range_rw(0x60, 0x61, keyboard);
175 #else
176 #endif
177         keyboard->set_context_pic(pic);
178         
179         // serial port
180         
181         // sasi
182 #if defined(_J3100GT) || defined(TYPE_SL)
183         io->set_iomap_range_rw(0x1f0, 0x1f3, sasi);
184         sasi->set_context_pic(pic);
185 #endif
186         
187         // ems
188         static const int ems_addr[] = {
189                 0x208, 0x4208, 0x8208, 0xc208,
190                 0x218, 0x4218, 0x8218, 0xc218,
191                 0x258, 0x4258, 0x8258, 0xc258,
192                 0x268, 0x4268, 0x8268, 0xc268,
193 #ifdef TYPE_SL
194                 0x2a8, 0x42a8, 0x82a8, 0xc2a8,
195                 0x2b8, 0x42b8, 0x82b8, 0xc2b8,
196                 0x2e8, 0x42e8, 0x82e8, 0xc2e8,
197 #endif
198         };
199         for(int i = 0; i < array_length(ems_addr); i++) {
200                 io->set_iomap_single_rw(ems_addr[i], memory);
201 #ifdef TYPE_SL
202                 io->set_iomap_single_w(ems_addr[i] + 1, memory);
203 #endif
204         }
205 #ifdef TYPE_SL
206         io->set_iomap_range_rw(0xee, 0xef, memory);
207 #endif
208         
209         // special registers for J-3100SL/SS/SE
210 #ifdef TYPE_SL
211 //      62      bit0
212 //              bit1    1=8087\82 \82è
213         io->set_iovalue_single_r(0x62, 0x26);   // unknown
214 //      io->set_flipflop_single_rw(0x63, 0x00); // unknown
215         static const int iovalues[0x20] = {
216                 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x14, 0xff, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xff,
217                 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
218         };
219         for(int i = 0xe0; i <= 0xff; i++) {
220                 if(i == 0xee && i == 0xef) {
221                         continue;
222                 }
223                 io->set_flipflop_single_rw(i, iovalues[i & 0x1f]);
224         }
225 #endif
226
227
228
229
230         
231         // initialize all devices
232         for(DEVICE* device = first_device; device; device = device->next_device) {
233                 device->initialize();
234         }
235 }
236
237 VM::~VM()
238 {
239         // delete all devices
240         for(DEVICE* device = first_device; device;) {
241                 DEVICE *next_device = device->next_device;
242                 device->release();
243                 delete device;
244                 device = next_device;
245         }
246 }
247
248 DEVICE* VM::get_device(int id)
249 {
250         for(DEVICE* device = first_device; device; device = device->next_device) {
251                 if(device->this_device_id == id) {
252                         return device;
253                 }
254         }
255         return NULL;
256 }
257
258 // ----------------------------------------------------------------------------
259 // drive virtual machine
260 // ----------------------------------------------------------------------------
261
262 void VM::reset()
263 {
264         // reset all devices
265         for(DEVICE* device = first_device; device; device = device->next_device) {
266                 device->reset();
267         }
268 }
269
270 void VM::run()
271 {
272         event->drive();
273 }
274
275 // ----------------------------------------------------------------------------
276 // draw screen
277 // ----------------------------------------------------------------------------
278
279 void VM::draw_screen()
280 {
281         display->draw_screen();
282 }
283
284 int VM::access_lamp()
285 {
286         uint32 status = fdc->read_signal(0);
287         return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;
288 }
289
290 // ----------------------------------------------------------------------------
291 // soud manager
292 // ----------------------------------------------------------------------------
293
294 void VM::initialize_sound(int rate, int samples)
295 {
296         // init sound manager
297         event->initialize_sound(rate, samples);
298         
299         // init sound gen
300         pcm->init(rate, 8000);
301 }
302
303 uint16* VM::create_sound(int* extra_frames)
304 {
305         return event->create_sound(extra_frames);
306 }
307
308 int VM::sound_buffer_ptr()
309 {
310         return event->sound_buffer_ptr();
311 }
312
313 #ifdef USE_SOUND_VOLUME
314 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
315 {
316         if(ch == 0) {
317                 pcm->set_volume(0, decibel_l, decibel_r);
318         }
319 }
320 #endif
321
322 // ----------------------------------------------------------------------------
323 // notify key
324 // ----------------------------------------------------------------------------
325
326 void VM::key_down(int code, bool repeat)
327 {
328         keyboard->key_down(code);
329 }
330
331 void VM::key_up(int code)
332 {
333         keyboard->key_up(code);
334 }
335
336 // ----------------------------------------------------------------------------
337 // user interface
338 // ----------------------------------------------------------------------------
339
340 void VM::open_disk(int drv, const _TCHAR* file_path, int bank)
341 {
342         fdc->open_disk(drv, file_path, bank);
343 }
344
345 void VM::close_disk(int drv)
346 {
347         fdc->close_disk(drv);
348 }
349
350 bool VM::disk_inserted(int drv)
351 {
352         return fdc->disk_inserted(drv);
353 }
354
355 void VM::set_disk_protected(int drv, bool value)
356 {
357         fdc->set_disk_protected(drv, value);
358 }
359
360 bool VM::get_disk_protected(int drv)
361 {
362         return fdc->get_disk_protected(drv);
363 }
364
365 bool VM::now_skip()
366 {
367         return event->now_skip();
368 }
369
370 void VM::update_config()
371 {
372         for(DEVICE* device = first_device; device; device = device->next_device) {
373                 device->update_config();
374         }
375 }
376