2 NEC TK-80BS (COMPO BS/80) Emulator 'eTK-80BS'
\r
4 Author : Takeda.Toshiya
\r
11 #include "../../emu.h"
\r
12 #include "../device.h"
\r
13 #include "../event.h"
\r
15 #include "../i8080.h"
\r
16 #include "../i8251.h"
\r
17 #include "../i8255.h"
\r
19 #include "../memory.h"
\r
20 #include "../pcm1bit.h"
\r
23 #include "../debugger.h"
\r
27 #include "display.h"
\r
28 #include "keyboard.h"
\r
30 // ----------------------------------------------------------------------------
\r
32 // ----------------------------------------------------------------------------
\r
34 VM::VM(EMU* parent_emu) : emu(parent_emu)
\r
37 // boot_mode = config.boot_mode;
\r
41 first_device = last_device = NULL;
\r
42 dummy = new DEVICE(this, emu); // must be 1st device
\r
43 event = new EVENT(this, emu); // must be 2nd device
\r
45 sio_b = new I8251(this, emu); // on TK-80BS
\r
46 pio_b = new I8255(this, emu);
\r
47 pio_t = new I8255(this, emu); // on TK-80
\r
48 memio = new IO(this, emu);
\r
49 memory = new MEMORY(this, emu);
\r
50 pcm0 = new PCM1BIT(this, emu);
\r
51 pcm1 = new PCM1BIT(this, emu);
\r
52 cpu = new I8080(this, emu);
\r
54 cmt = new CMT(this, emu);
\r
55 display = new DISPLAY(this, emu);
\r
56 keyboard = new KEYBOARD(this, emu);
\r
59 event->set_context_cpu(cpu);
\r
60 event->set_context_sound(pcm0);
\r
61 event->set_context_sound(pcm1);
\r
73 sio_b->set_context_out(cmt, SIG_CMT_OUT);
\r
74 pio_b->set_context_port_c(display, SIG_DISPLAY_MODE, 3, 0);
\r
75 pio_t->set_context_port_c(pcm0, SIG_PCM1BIT_SIGNAL, 2, 0);
\r
76 pio_t->set_context_port_c(pcm1, SIG_PCM1BIT_SIGNAL, 4, 0);
\r
77 pio_t->set_context_port_c(keyboard, SIG_KEYBOARD_COLUMN, 0x70, 0);
\r
78 pio_t->set_context_port_c(display, SIG_DISPLAY_DMA, 0x80, 0);
\r
80 cmt->set_context_sio(sio_b);
\r
81 display->set_context_key(keyboard);
\r
82 display->set_vram_ptr(vram);
\r
83 display->set_led_ptr(ram + 0x3f8);
\r
84 keyboard->set_context_pio_b(pio_b);
\r
85 keyboard->set_context_pio_t(pio_t);
\r
86 keyboard->set_context_cpu(cpu);
\r
89 cpu->set_context_mem(memory);
\r
90 cpu->set_context_io(pio_t);
\r
91 cpu->set_context_intr(keyboard);
\r
93 cpu->set_context_debugger(new DEBUGGER(this, emu));
\r
97 memset(mon, 0xff, sizeof(mon));
\r
98 memset(bsmon, 0xff, sizeof(bsmon));
\r
99 memset(ext, 0xff, sizeof(ext));
\r
101 static const uint8 top[3] = {0xc3, 0x00, 0xf0};
\r
102 static const uint8 rst[3] = {0xc3, 0xdd, 0x83};
\r
104 if(!memory->read_bios(_T("TK80.ROM"), mon, sizeof(mon))) {
\r
106 memcpy(mon, top, sizeof(top));
\r
107 memcpy(mon + 0x38, rst, sizeof(rst));
\r
109 if(memory->read_bios(_T("BSMON.ROM"), bsmon, sizeof(bsmon))) {
\r
111 memcpy(mon + 0x38, rst, sizeof(rst));
\r
113 memory->read_bios(_T("EXT.ROM"), ext, sizeof(ext));
\r
115 memory->set_memory_r(0x0000, 0x07ff, mon);
\r
116 memory->set_memory_r(0x0c00, 0x7bff, ext);
\r
117 memory->set_memory_mapped_io_rw(0x7c00, 0x7dff, memio);
\r
118 memory->set_memory_rw(0x7e00, 0x7fff, vram);
\r
119 memory->set_memory_rw(0x8000, 0xcfff, ram);
\r
120 memory->set_memory_r(0xd000, 0xefff, basic);
\r
121 memory->set_memory_r(0xf000, 0xffff, bsmon);
\r
123 // memory mapped i/o
\r
124 memio->set_iomap_alias_rw(0x7df8, sio_b, 0);
\r
125 memio->set_iomap_alias_rw(0x7df9, sio_b, 1);
\r
126 memio->set_iomap_alias_rw(0x7dfc, pio_b, 0);
\r
127 memio->set_iomap_alias_rw(0x7dfd, pio_b, 1);
\r
128 memio->set_iomap_alias_rw(0x7dfe, pio_b, 2);
\r
129 memio->set_iomap_alias_w(0x7dff, pio_b, 3);
\r
131 // initialize all devices
\r
132 for(DEVICE* device = first_device; device; device = device->next_device) {
\r
133 device->initialize();
\r
139 // delete all devices
\r
140 for(DEVICE* device = first_device; device;) {
\r
141 DEVICE *next_device = device->next_device;
\r
144 device = next_device;
\r
148 DEVICE* VM::get_device(int id)
\r
150 for(DEVICE* device = first_device; device; device = device->next_device) {
\r
151 if(device->this_device_id == id) {
\r
158 // ----------------------------------------------------------------------------
\r
159 // drive virtual machine
\r
160 // ----------------------------------------------------------------------------
\r
165 if(boot_mode != config.boot_mode) {
\r
166 memset(basic, 0xff, sizeof(basic));
\r
167 if(config.boot_mode == 0) {
\r
168 memory->read_bios(_T("LV1BASIC.ROM"), basic + 0x1000, 0x1000);
\r
170 memory->read_bios(_T("LV2BASIC.ROM"), basic, sizeof(basic));
\r
172 boot_mode = config.boot_mode;
\r
174 memset(ram, 0, sizeof(ram));
\r
175 memset(vram, 0x20, sizeof(vram));
\r
178 // reset all devices
\r
179 for(DEVICE* device = first_device; device; device = device->next_device) {
\r
183 // init 8255 on TK-80
\r
184 pio_t->write_io8(0xfb, 0x92);
\r
185 pio_t->write_signal(SIG_I8255_PORT_A, 0xff, 0xff);
\r
193 // ----------------------------------------------------------------------------
\r
195 // ----------------------------------------------------------------------------
\r
197 #ifdef USE_DEBUGGER
\r
198 DEVICE *VM::get_cpu(int index)
\r
207 // ----------------------------------------------------------------------------
\r
209 // ----------------------------------------------------------------------------
\r
211 void VM::draw_screen()
\r
213 display->draw_screen();
\r
216 // ----------------------------------------------------------------------------
\r
218 // ----------------------------------------------------------------------------
\r
220 void VM::initialize_sound(int rate, int samples)
\r
222 // init sound manager
\r
223 event->initialize_sound(rate, samples);
\r
226 pcm0->init(rate, 8000);
\r
227 pcm1->init(rate, 8000);
\r
230 uint16* VM::create_sound(int* extra_frames)
\r
232 return event->create_sound(extra_frames);
\r
235 int VM::sound_buffer_ptr()
\r
237 return event->sound_buffer_ptr();
\r
240 // ----------------------------------------------------------------------------
\r
242 // ----------------------------------------------------------------------------
\r
244 void VM::key_down(int code, bool repeat)
\r
246 keyboard->key_down(code);
\r
249 void VM::key_up(int code)
\r
251 keyboard->key_up(code);
\r
254 // ----------------------------------------------------------------------------
\r
256 // ----------------------------------------------------------------------------
\r
258 void VM::load_binary(int drv, _TCHAR* file_path)
\r
261 memory->read_image(file_path, ram, sizeof(ram));
\r
265 void VM::save_binary(int drv, _TCHAR* file_path)
\r
268 memory->write_image(file_path, ram, sizeof(ram));
\r
272 void VM::play_tape(_TCHAR* file_path)
\r
274 cmt->play_tape(file_path);
\r
277 void VM::rec_tape(_TCHAR* file_path)
\r
279 cmt->rec_tape(file_path);
\r
282 void VM::close_tape()
\r
287 bool VM::tape_inserted()
\r
289 return cmt->tape_inserted();
\r
292 bool VM::now_skip()
\r
294 return event->now_skip();
\r
297 void VM::update_config()
\r
299 if(boot_mode != config.boot_mode) {
\r
300 // boot mode is changed !!!
\r
301 // boot_mode = config.boot_mode;
\r
304 for(DEVICE* device = first_device; device; device = device->next_device) {
\r
305 device->update_config();
\r