2 NEC TK-80BS (COMPO BS/80) Emulator 'eTK-80BS'
4 Author : Takeda.Toshiya
11 #include "../../emu.h"
12 #include "../device.h"
19 #include "../memory.h"
20 #include "../pcm1bit.h"
23 #include "../debugger.h"
30 // ----------------------------------------------------------------------------
32 // ----------------------------------------------------------------------------
34 VM::VM(EMU* parent_emu) : emu(parent_emu)
37 // boot_mode = config.boot_mode;
41 first_device = last_device = NULL;
42 dummy = new DEVICE(this, emu); // must be 1st device
43 event = new EVENT(this, emu); // must be 2nd device
45 sio_b = new I8251(this, emu); // on TK-80BS
46 pio_b = new I8255(this, emu);
47 pio_t = new I8255(this, emu); // on TK-80
48 memio = new IO(this, emu);
49 memory = new MEMORY(this, emu);
50 pcm0 = new PCM1BIT(this, emu);
51 pcm1 = new PCM1BIT(this, emu);
52 cpu = new I8080(this, emu);
54 cmt = new CMT(this, emu);
55 display = new DISPLAY(this, emu);
56 keyboard = new KEYBOARD(this, emu);
59 event->set_context_cpu(cpu);
60 event->set_context_sound(pcm0);
61 event->set_context_sound(pcm1);
73 sio_b->set_context_out(cmt, SIG_CMT_OUT);
74 pio_b->set_context_port_c(display, SIG_DISPLAY_MODE, 3, 0);
75 pio_t->set_context_port_c(pcm0, SIG_PCM1BIT_SIGNAL, 2, 0);
76 pio_t->set_context_port_c(pcm1, SIG_PCM1BIT_SIGNAL, 4, 0);
77 pio_t->set_context_port_c(keyboard, SIG_KEYBOARD_COLUMN, 0x70, 0);
78 pio_t->set_context_port_c(display, SIG_DISPLAY_DMA, 0x80, 0);
80 cmt->set_context_sio(sio_b);
81 display->set_context_key(keyboard);
82 display->set_vram_ptr(vram);
83 display->set_led_ptr(ram + 0x3f8);
84 keyboard->set_context_pio_b(pio_b);
85 keyboard->set_context_pio_t(pio_t);
86 keyboard->set_context_cpu(cpu);
89 cpu->set_context_mem(memory);
90 cpu->set_context_io(pio_t);
91 cpu->set_context_intr(keyboard);
93 cpu->set_context_debugger(new DEBUGGER(this, emu));
97 memset(mon, 0xff, sizeof(mon));
98 memset(bsmon, 0xff, sizeof(bsmon));
99 memset(ext, 0xff, sizeof(ext));
101 static const uint8_t top[3] = {0xc3, 0x00, 0xf0};
102 static const uint8_t rst[3] = {0xc3, 0xdd, 0x83};
104 if(!memory->read_bios(_T("TK80.ROM"), mon, sizeof(mon))) {
106 memcpy(mon, top, sizeof(top));
107 memcpy(mon + 0x38, rst, sizeof(rst));
109 if(memory->read_bios(_T("BSMON.ROM"), bsmon, sizeof(bsmon))) {
111 memcpy(mon + 0x38, rst, sizeof(rst));
113 memory->read_bios(_T("EXT.ROM"), ext, sizeof(ext));
115 memory->set_memory_r(0x0000, 0x07ff, mon);
116 memory->set_memory_r(0x0c00, 0x7bff, ext);
117 memory->set_memory_mapped_io_rw(0x7c00, 0x7dff, memio);
118 memory->set_memory_rw(0x7e00, 0x7fff, vram);
119 memory->set_memory_rw(0x8000, 0xcfff, ram);
120 memory->set_memory_r(0xd000, 0xefff, basic);
121 memory->set_memory_r(0xf000, 0xffff, bsmon);
124 memio->set_iomap_alias_rw(0x7df8, sio_b, 0);
125 memio->set_iomap_alias_rw(0x7df9, sio_b, 1);
126 memio->set_iomap_alias_rw(0x7dfc, pio_b, 0);
127 memio->set_iomap_alias_rw(0x7dfd, pio_b, 1);
128 memio->set_iomap_alias_rw(0x7dfe, pio_b, 2);
129 memio->set_iomap_alias_w(0x7dff, pio_b, 3);
131 // initialize all devices
132 for(DEVICE* device = first_device; device; device = device->next_device) {
133 device->initialize();
139 // delete all devices
140 for(DEVICE* device = first_device; device;) {
141 DEVICE *next_device = device->next_device;
144 device = next_device;
148 DEVICE* VM::get_device(int id)
150 for(DEVICE* device = first_device; device; device = device->next_device) {
151 if(device->this_device_id == id) {
158 // ----------------------------------------------------------------------------
159 // drive virtual machine
160 // ----------------------------------------------------------------------------
165 if(boot_mode != config.boot_mode) {
166 memset(basic, 0xff, sizeof(basic));
167 if(config.boot_mode == 0) {
168 memory->read_bios(_T("LV1BASIC.ROM"), basic + 0x1000, 0x1000);
170 memory->read_bios(_T("LV2BASIC.ROM"), basic, sizeof(basic));
172 boot_mode = config.boot_mode;
174 memset(ram, 0, sizeof(ram));
178 emu->reload_bitmap();
180 memset(vram, 0x20, sizeof(vram));
183 for(DEVICE* device = first_device; device; device = device->next_device) {
187 // init 8255 on TK-80
188 pio_t->write_io8(0xfb, 0x92);
189 pio_t->write_signal(SIG_I8255_PORT_A, 0xff, 0xff);
197 // ----------------------------------------------------------------------------
199 // ----------------------------------------------------------------------------
202 DEVICE *VM::get_cpu(int index)
211 // ----------------------------------------------------------------------------
213 // ----------------------------------------------------------------------------
215 void VM::draw_screen()
217 display->draw_screen();
220 int VM::max_draw_ranges()
225 // ----------------------------------------------------------------------------
227 // ----------------------------------------------------------------------------
229 void VM::initialize_sound(int rate, int samples)
231 // init sound manager
232 event->initialize_sound(rate, samples);
235 pcm0->initialize_sound(rate, 8000);
236 pcm1->initialize_sound(rate, 8000);
239 uint16_t* VM::create_sound(int* extra_frames)
241 return event->create_sound(extra_frames);
244 int VM::get_sound_buffer_ptr()
246 return event->get_sound_buffer_ptr();
249 #ifdef USE_SOUND_VOLUME
250 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
253 pcm0->set_volume(0, decibel_l, decibel_r);
255 pcm1->set_volume(0, decibel_l, decibel_r);
260 // ----------------------------------------------------------------------------
262 // ----------------------------------------------------------------------------
264 void VM::key_down(int code, bool repeat)
266 keyboard->key_down(code);
269 void VM::key_up(int code)
271 keyboard->key_up(code);
274 // ----------------------------------------------------------------------------
276 // ----------------------------------------------------------------------------
278 void VM::load_binary(int drv, const _TCHAR* file_path)
281 memory->read_image(file_path, ram, sizeof(ram));
285 void VM::save_binary(int drv, const _TCHAR* file_path)
288 memory->write_image(file_path, ram, sizeof(ram));
292 void VM::play_tape(const _TCHAR* file_path)
294 cmt->play_tape(file_path);
297 void VM::rec_tape(const _TCHAR* file_path)
299 cmt->rec_tape(file_path);
302 void VM::close_tape()
307 bool VM::is_tape_inserted()
309 return cmt->is_tape_inserted();
312 bool VM::is_frame_skippable()
314 return event->is_frame_skippable();
317 void VM::update_config()
319 if(boot_mode != config.boot_mode) {
320 // boot mode is changed !!!
321 // boot_mode = config.boot_mode;
324 for(DEVICE* device = first_device; device; device = device->next_device) {
325 device->update_config();
330 #define STATE_VERSION 1
332 void VM::save_state(FILEIO* state_fio)
334 state_fio->FputUint32(STATE_VERSION);
336 for(DEVICE* device = first_device; device; device = device->next_device) {
337 device->save_state(state_fio);
339 state_fio->Fwrite(ram, sizeof(ram), 1);
340 state_fio->Fwrite(vram, sizeof(vram), 1);
341 state_fio->FputInt32(boot_mode);
342 // state_fio->FputInt32(draw_ranges);
345 bool VM::load_state(FILEIO* state_fio)
347 if(state_fio->FgetUint32() != STATE_VERSION) {
350 for(DEVICE* device = first_device; device; device = device->next_device) {
351 if(!device->load_state(state_fio)) {
355 state_fio->Fread(ram, sizeof(ram), 1);
356 state_fio->Fread(vram, sizeof(vram), 1);
357 boot_mode = state_fio->FgetInt32();
358 // draw_ranges = state_fio->FgetInt32();
361 emu->reload_bitmap();