2 TOSHIBA J-3100GT Emulator 'eJ-3100GT'
3 TOSHIBA J-3100SL Emulator 'eJ-3100SL'
5 Author : Takeda.Toshiya
12 #include "../../emu.h"
13 #include "../device.h"
16 #include "../hd46505.h"
18 //#include "../i8250.h"
21 //#if defined(HAS_I286)
28 #include "../pcm1bit.h"
29 #include "../upd765a.h"
31 #include "../rp5c01.h"
33 #include "../hd146818p.h"
37 #include "../debugger.h"
45 #include "slkeyboard.h"
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
61 first_device = last_device = NULL;
62 dummy = new DEVICE(this, emu); // must be 1st device
63 event = new EVENT(this, emu); // must be 2nd device
64 dummy->set_device_name(_T("1st Dummy"));
66 crtc = new HD46505(this, emu);
67 dma = new I8237(this, emu);
69 dma2 = new I8237(this, emu);
72 dma->set_device_name(_T("i8237 DMAC #1"));
73 dma2->set_device_name(_T("i8237 DMAC #2"));
75 // sio = new I8250(this, emu);
76 pit = new I8253(this, emu); // i8254
77 pic = new I8259(this, emu);
78 //#if defined(HAS_I286)
79 cpu = new I286(this, emu);
81 // cpu = new I86(this, emu);
83 io = new IO(this, emu);
84 pcm = new PCM1BIT(this, emu);
85 fdc = new UPD765A(this, emu);
86 fdc->set_context_noise_seek(new NOISE(this, emu));
87 fdc->set_context_noise_head_down(new NOISE(this, emu));
88 fdc->set_context_noise_head_up(new NOISE(this, emu));
90 rtc = new RP5C01(this, emu);
92 rtc = new HD146818P(this, emu);
95 display = new DISPLAY(this, emu);
96 dmareg = new DMAREG(this, emu);
97 floppy = new FLOPPY(this, emu);
98 keyboard = new KEYBOARD(this, emu);
99 memory = new MEMORY(this, emu);
100 sasi = new SASI(this, emu);
101 system = new SYSTEM(this, emu);
103 event->set_context_cpu(cpu);
104 event->set_context_sound(pcm);
105 event->set_context_sound(fdc->get_context_noise_seek());
106 event->set_context_sound(fdc->get_context_noise_head_down());
107 event->set_context_sound(fdc->get_context_noise_head_up());
110 cpu->set_context_mem(memory);
111 cpu->set_context_io(io);
112 cpu->set_context_intr(pic);
114 cpu->set_context_debugger(new DEBUGGER(this, emu));
118 io->set_iomap_range_rw(0x00, 0x0f, dma);
119 io->set_iomap_range_w(0x80, 0x8f, dmareg);
120 dma->set_context_memory(memory);
121 dma->set_context_ch2(fdc);
122 dmareg->set_context_dma(dma);
124 for(int i = 0xc0; i <= 0xde; i += 2) {
125 io->set_iomap_alias_rw(i, dma2, i >> 1);
127 dma2->set_context_memory(memory);
128 dma2->set_mode_word(true);
129 dmareg->set_context_dma2(dma2);
133 io->set_iomap_alias_rw(0x20, pic, I8259_ADDR_CHIP0 | 0);
134 io->set_iomap_alias_rw(0x21, pic, I8259_ADDR_CHIP0 | 1);
136 io->set_iomap_alias_rw(0xa0, pic, I8259_ADDR_CHIP1 | 0);
137 io->set_iomap_alias_rw(0xa1, pic, I8259_ADDR_CHIP1 | 1);
139 pic->set_context_cpu(cpu);
142 io->set_iomap_range_rw(0x40, 0x43, pit);
143 pit->set_constant_clock(0, 1190000);
144 pit->set_constant_clock(1, 1190000);
145 pit->set_constant_clock(2, 1190000);
146 pit->set_context_ch0(pic, SIG_I8259_IR0 | SIG_I8259_CHIP0, 1); // to PIC#0 IR0
147 pit->set_context_ch2(pcm, SIG_PCM1BIT_SIGNAL, 1);
149 pit->set_context_ch2(system, SIG_SYSTEM_TC2O, 1);
152 // system status/command
154 io->set_iomap_single_rw(0x61, system);
155 system->set_context_pcm(pcm);
156 system->set_context_pit(pit);
161 io->set_iomap_range_rw(0x2c0, 0x2cf, rtc);
163 io->set_iomap_alias_w(0x70, rtc, 1); // bit7 = nmi mask
164 io->set_iomap_alias_rw(0x71, rtc, 0);
165 rtc->set_context_intr(pic, SIG_I8259_IR0 | SIG_I8259_CHIP1, 1); // to PIC#1 IR0 (IR8)
170 io->set_iomap_single_w(0xa0, system);
172 // 0x70 bit7 (not implemented)
176 io->set_iomap_range_rw(0x3d0, 0x3d1, crtc);
177 io->set_iomap_range_rw(0x3d4, 0x3d5, crtc);
178 io->set_iomap_range_w(0x3d8, 0x3d9, display);
179 io->set_iomap_single_r(0x3da, display);
180 crtc->set_context_disp(display, SIG_DISPLAY_ENABLE, 1);
181 crtc->set_context_vblank(display, SIG_DISPLAY_VBLANK, 1);
182 display->set_regs_ptr(crtc->get_regs());
183 display->set_vram_ptr(memory->get_vram());
186 io->set_iomap_single_w(0x3f2, floppy);
187 io->set_iomap_range_rw(0x3f4, 0x3f5, fdc);
188 io->set_iomap_single_rw(0x3f7, floppy);
189 fdc->set_context_irq(pic, SIG_I8259_IR6 | SIG_I8259_CHIP0, 1); // to PIC#0 IR6
190 fdc->set_context_drq(dma, SIG_I8237_CH2, 1); // to DMA Ch.2
191 floppy->set_context_fdc(fdc);
194 io->set_flipflop_single_rw(0x378, 0x00);
195 io->set_iovalue_single_r(0x379, 0x78);
196 io->set_flipflop_single_rw(0x37a, 0x00);
200 io->set_iomap_range_rw(0x60, 0x61, keyboard);
203 keyboard->set_context_pic(pic);
208 #if defined(_J3100GT) || defined(TYPE_SL)
209 io->set_iomap_range_rw(0x1f0, 0x1f3, sasi);
210 sasi->set_context_pic(pic);
214 static const int ems_addr[] = {
215 0x208, 0x4208, 0x8208, 0xc208,
216 0x218, 0x4218, 0x8218, 0xc218,
217 0x258, 0x4258, 0x8258, 0xc258,
218 0x268, 0x4268, 0x8268, 0xc268,
220 0x2a8, 0x42a8, 0x82a8, 0xc2a8,
221 0x2b8, 0x42b8, 0x82b8, 0xc2b8,
222 0x2e8, 0x42e8, 0x82e8, 0xc2e8,
225 for(int i = 0; i < array_length(ems_addr); i++) {
226 io->set_iomap_single_rw(ems_addr[i], memory);
228 io->set_iomap_single_w(ems_addr[i] + 1, memory);
232 io->set_iomap_range_rw(0xee, 0xef, memory);
235 // special registers for J-3100SL/SS/SE
238 // bit1 1=8087
\82 \82è
239 io->set_iovalue_single_r(0x62, 0x26); // unknown
240 // io->set_flipflop_single_rw(0x63, 0x00); // unknown
241 static const int iovalues[0x20] = {
242 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x14, 0xff, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xff,
243 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
245 for(int i = 0xe0; i <= 0xff; i++) {
246 if(i == 0xee && i == 0xef) {
249 io->set_flipflop_single_rw(i, iovalues[i & 0x1f]);
252 // initialize all devices
253 #if defined(__GIT_REPO_VERSION)
254 strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1);
256 for(DEVICE* device = first_device; device; device = device->next_device) {
257 device->initialize();
260 //pcm->set_realtime_render(true);
266 // delete all devices
267 for(DEVICE* device = first_device; device;) {
268 DEVICE *next_device = device->next_device;
271 device = next_device;
275 DEVICE* VM::get_device(int id)
277 for(DEVICE* device = first_device; device; device = device->next_device) {
278 if(device->this_device_id == id) {
285 // ----------------------------------------------------------------------------
286 // drive virtual machine
287 // ----------------------------------------------------------------------------
292 for(DEVICE* device = first_device; device; device = device->next_device) {
302 // ----------------------------------------------------------------------------
304 // ----------------------------------------------------------------------------
307 DEVICE *VM::get_cpu(int index)
316 // ----------------------------------------------------------------------------
318 // ----------------------------------------------------------------------------
320 void VM::draw_screen()
322 display->draw_screen();
325 // ----------------------------------------------------------------------------
327 // ----------------------------------------------------------------------------
329 void VM::initialize_sound(int rate, int samples)
331 // init sound manager
332 event->initialize_sound(rate, samples);
335 pcm->initialize_sound(rate, 8000);
338 uint16_t* VM::create_sound(int* extra_frames)
340 return event->create_sound(extra_frames);
343 int VM::get_sound_buffer_ptr()
345 return event->get_sound_buffer_ptr();
348 #ifdef USE_SOUND_VOLUME
349 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
352 pcm->set_volume(0, decibel_l, decibel_r);
354 fdc->get_context_noise_seek()->set_volume(0, decibel_l, decibel_r);
355 fdc->get_context_noise_head_down()->set_volume(0, decibel_l, decibel_r);
356 fdc->get_context_noise_head_up()->set_volume(0, decibel_l, decibel_r);
361 // ----------------------------------------------------------------------------
363 // ----------------------------------------------------------------------------
365 void VM::key_down(int code, bool repeat)
367 keyboard->key_down(code);
370 void VM::key_up(int code)
372 keyboard->key_up(code);
375 // ----------------------------------------------------------------------------
377 // ----------------------------------------------------------------------------
379 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
381 fdc->open_disk(drv, file_path, bank);
384 void VM::close_floppy_disk(int drv)
386 fdc->close_disk(drv);
389 bool VM::is_floppy_disk_inserted(int drv)
391 return fdc->is_disk_inserted(drv);
394 void VM::is_floppy_disk_protected(int drv, bool value)
396 fdc->is_disk_protected(drv, value);
399 bool VM::is_floppy_disk_protected(int drv)
401 return fdc->is_disk_protected(drv);
404 uint32_t VM::is_floppy_disk_accessed()
406 return fdc->read_signal(0);
409 bool VM::is_frame_skippable()
411 return event->is_frame_skippable();
414 void VM::update_config()
416 for(DEVICE* device = first_device; device; device = device->next_device) {
417 device->update_config();
421 #define STATE_VERSION 1
423 bool VM::process_state(FILEIO* state_fio, bool loading)
425 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
428 for(DEVICE* device = first_device; device; device = device->next_device) {
429 const char *name = typeid(*device).name() + 6; // skip "class "
430 int len = strlen(name);
432 if(!state_fio->StateCheckInt32(len)) {
435 if(!state_fio->StateCheckBuffer(name, len, 1)) {
438 if(!device->process_state(state_fio, loading)) {
445 bool VM::process_state(FILEIO* state_fio, bool loading)
447 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
450 for(DEVICE* device = first_device; device; device = device->next_device) {
451 const char *name = typeid(*device).name() + 6; // skip "class "
452 int len = strlen(name);
454 if(!state_fio->StateCheckInt32(len)) {
457 if(!state_fio->StateCheckBuffer(name, len, 1)) {
460 if(!device->process_state(state_fio, loading)) {