OSDN Git Service

[General] Merge Upstream 2017-03-07.
[csp-qt/common_source_project-fm7.git] / source / src / vm / babbage2nd / babbage2nd.cpp
1 /*
2         Gijutsu-Hyoron-Sha Babbage-2nd Emulator 'eBabbage-2nd'
3
4         Author : Takeda.Toshiya
5         Date   : 2009.12.26 -
6
7         [ virtual machine ]
8 */
9
10 #include "babbage2nd.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../io.h"
16 #include "../memory.h"
17 #include "../z80.h"
18 #include "../z80ctc.h"
19 #include "../z80pio.h"
20
21 #include "display.h"
22 #include "keyboard.h"
23
24 // ----------------------------------------------------------------------------
25 // initialize
26 // ----------------------------------------------------------------------------
27
28 VM::VM(EMU* parent_emu) : emu(parent_emu)
29 {
30         // create devices
31         first_device = last_device = NULL;
32         dummy = new DEVICE(this, emu);  // must be 1st device
33         event = new EVENT(this, emu);   // must be 2nd device
34         
35         io = new IO(this, emu);
36         memory = new MEMORY(this, emu);
37         cpu = new Z80(this, emu);
38         ctc = new Z80CTC(this, emu);
39         pio1 = new Z80PIO(this, emu);
40         pio1->set_device_name(_T("Z80 PIO (LEDs)"));
41         pio2 = new Z80PIO(this, emu);
42         pio2->set_device_name(_T("Z80 PIO (7-Seg/Keyboard)"));
43         
44         display = new DISPLAY(this, emu);
45         keyboard = new KEYBOARD(this, emu);
46
47         // Set names
48 #if defined(_USE_QT)
49         dummy->set_device_name(_T("1st Dummy"));
50         event->set_device_name(_T("EVENT"));
51         cpu->set_device_name(_T("CPU(Z80)"));
52         ctc->set_device_name(_T("Z80 CTC"));
53         pio1->set_device_name(_T("Z80 PIO(LEDs)"));
54         pio2->set_device_name(_T("Z80 PIO(7SEG/KEYBOARD)"));
55         display->set_device_name(_T("7SEG/LEDs"));
56         keyboard->set_device_name(_T("KEYBOARD"));
57 #endif
58         // set contexts
59         event->set_context_cpu(cpu);
60         
61         pio2->set_context_port_b(display, SIG_DISPLAY_7SEG_LED, 0xff, 0);
62         keyboard->set_context_pio(pio2);
63         // p.145, fig.3-4
64         ctc->set_context_zc2(ctc, SIG_Z80CTC_TRIG_1, 1);
65         ctc->set_context_zc1(ctc, SIG_Z80CTC_TRIG_0, 1);
66         // p.114, fig.2-52
67         pio1->set_context_port_b(display, SIG_DISPLAY_8BIT_LED, 0xff, 0);
68         //pio1->set_context_port_b(pio1, SIG_Z80PIO_PORT_A, 0xff, 0);
69         
70         // cpu bus
71         cpu->set_context_mem(memory);
72         cpu->set_context_io(io);
73         cpu->set_context_intr(ctc);
74         
75         // z80 family daisy chain
76         ctc->set_context_intr(cpu, 0);
77         ctc->set_context_child(pio1);
78         pio1->set_context_intr(cpu, 1);
79         pio1->set_context_child(pio2);
80         pio2->set_context_intr(cpu, 2);
81         
82         // memory bus
83         memset(ram, 0, sizeof(ram));
84         memset(rom, 0xff, sizeof(rom));
85         
86         memory->read_bios(_T("MON.ROM"), rom, sizeof(rom));
87         
88         memory->set_memory_r(0x0000, 0x07ff, rom);
89         memory->set_memory_rw(0x1000, 0x17ff, ram);
90         
91         // i/o bus
92         io->set_iomap_range_rw(0x00, 0x03, ctc);
93         io->set_iomap_range_rw(0x10, 0x13, pio1);
94         io->set_iomap_range_rw(0x20, 0x23, pio2);
95         
96         // initialize all devices
97         for(DEVICE* device = first_device; device; device = device->next_device) {
98                 device->initialize();
99         }
100 }
101
102 VM::~VM()
103 {
104         // delete all devices
105         for(DEVICE* device = first_device; device;) {
106                 DEVICE *next_device = device->next_device;
107                 device->release();
108                 delete device;
109                 device = next_device;
110         }
111 }
112
113 DEVICE* VM::get_device(int id)
114 {
115         for(DEVICE* device = first_device; device; device = device->next_device) {
116                 if(device->this_device_id == id) {
117                         return device;
118                 }
119         }
120         return NULL;
121 }
122
123 // ----------------------------------------------------------------------------
124 // drive virtual machine
125 // ----------------------------------------------------------------------------
126
127 void VM::reset()
128 {
129         // reset all devices
130         for(DEVICE* device = first_device; device; device = device->next_device) {
131                 device->reset();
132         }
133 }
134
135 void VM::run()
136 {
137         event->drive();
138 }
139
140 // ----------------------------------------------------------------------------
141 // draw screen
142 // ----------------------------------------------------------------------------
143
144 void VM::draw_screen()
145 {
146         display->draw_screen();
147 }
148
149 // ----------------------------------------------------------------------------
150 // soud manager
151 // ----------------------------------------------------------------------------
152
153 void VM::initialize_sound(int rate, int samples)
154 {
155         // init sound manager
156         event->initialize_sound(rate, samples);
157 }
158
159 uint16_t* VM::create_sound(int* extra_frames)
160 {
161         return event->create_sound(extra_frames);
162 }
163
164 int VM::get_sound_buffer_ptr()
165 {
166         return event->get_sound_buffer_ptr();
167 }
168
169 // ----------------------------------------------------------------------------
170 // notify key
171 // ----------------------------------------------------------------------------
172
173 void VM::key_down(int code, bool repeat)
174 {
175         keyboard->key_down(code);
176 }
177
178 void VM::key_up(int code)
179 {
180         //keyboard->key_up(code);
181 }
182
183 // ----------------------------------------------------------------------------
184 // user interface
185 // ----------------------------------------------------------------------------
186
187 void VM::load_binary(int drv, const _TCHAR* file_path)
188 {
189         if(drv == 0) {
190                 memory->read_image(file_path, ram, sizeof(ram));
191         }
192 }
193
194 void VM::save_binary(int drv, const _TCHAR* file_path)
195 {
196         if(drv == 0) {
197                 memory->write_image(file_path, ram, sizeof(ram));
198         }
199 }
200
201 bool VM::is_frame_skippable()
202 {
203         return event->is_frame_skippable();
204 }
205
206 void VM::update_config()
207 {
208         for(DEVICE* device = first_device; device; device = device->next_device) {
209                 device->update_config();
210         }
211 }
212