OSDN Git Service

[VM][FMTOWNS][MEMORY] Fix setup around memory banks by I/O 0404h and 0480h.
[csp-qt/common_source_project-fm7.git] / source / src / vm / tk80bs / tk80bs.h
1 /*
2         NEC TK-80BS (COMPO BS/80) Emulator 'eTK-80BS'
3         NEC TK-80 Emulator 'eTK-80'
4         NEC TK-85 Emulator 'eTK-85'
5
6         Author : Takeda.Toshiya
7         Date   : 2008.08.26 -
8
9         [ virtual machine ]
10 */
11
12 #ifndef _TK80BS_H_
13 #define _TK80BS_H_
14
15 #if defined(_TK80BS)
16 #define DEVICE_NAME             "NEC TK-80BS"
17 #define CONFIG_NAME             "tk80bs"
18 #elif defined(_TK80)
19 #define DEVICE_NAME             "NEC TK-80"
20 #define CONFIG_NAME             "tk80"
21 #elif defined(_TK85)
22 #define DEVICE_NAME             "NEC TK-85"
23 #define CONFIG_NAME             "tk85"
24 #endif
25
26 // device informations for virtual machine
27 #if defined(_TK80BS)
28 #define FRAMES_PER_SEC          59.9
29 #define LINES_PER_FRAME         262
30 #elif defined(_TK80) || defined(_TK85)
31 #define FRAMES_PER_SEC          30
32 #define LINES_PER_FRAME         256
33 #endif
34 #if defined(_TK80BS) || defined(_TK80)
35 #define CPU_CLOCKS              2048000
36 #define SCREEN_WIDTH            784
37 #define SCREEN_HEIGHT           428
38 #define HAS_I8080
39 #elif defined(_TK85)
40 #define CPU_CLOCKS              2457600
41 #define SCREEN_WIDTH            784
42 #define SCREEN_HEIGHT           534
43 #define HAS_I8085
44 #endif
45 #define I8255_AUTO_HAND_SHAKE
46
47 // device informations for win32
48 #define ONE_BOARD_MICRO_COMPUTER
49 #if defined(_TK80BS) || defined(_TK80)
50 #define MAX_BUTTONS             25
51 #elif defined(_TK85)
52 #define MAX_BUTTONS             26
53 #endif
54 #if defined(_TK80) || defined(_TK85)
55 #define MAX_DRAW_RANGES         8
56 #endif
57 #if defined(_TK80BS)
58 #define USE_BOOT_MODE           2
59 #endif
60 #define USE_DIPSWITCH
61 #define DIPSWITCH_DEFAULT       0
62 #if defined(_TK80BS)
63 #define USE_TAPE                        2
64 #else
65 #define USE_TAPE                        1
66 #endif
67 #define USE_BINARY_FILE         1
68 #define USE_KEY_LOCKED
69 #define USE_AUTO_KEY            5
70 #define USE_AUTO_KEY_RELEASE    6
71 #define USE_AUTO_KEY_NO_CAPS
72 #define USE_AUTO_KEY_NUMPAD
73 #define USE_SOUND_VOLUME        4
74 #define USE_DEBUGGER
75 #define USE_STATE
76 #define USE_CPU_I8080
77
78 #include "../../common.h"
79 #include "../../fileio.h"
80 #include "../vm_template.h"
81
82 #ifdef USE_SOUND_VOLUME
83 static const _TCHAR *sound_device_caption[] = {
84         _T("Beep #1"), _T("Beep #2"), _T("CMT (Signal)"), _T("Noise (CMT)"),
85 };
86 #endif
87
88 #if defined(_TK80BS) || defined(_TK80)
89 #define BUTTON_SPACE_X  46
90 #define BUTTON_SPACE_Y  46
91 #define BUTTON_SIZE_X   40
92 #define BUTTON_SIZE_Y   40
93 #define BUTTON_POS_X1   523
94 #define BUTTON_POS_X2   (BUTTON_POS_X1 + BUTTON_SPACE_X * 4)
95 #define BUTTON_POS_Y1   374
96 #define BUTTON_POS_Y2   190
97
98 #define LED_SPACE_X     36
99 #define LED_SIZE_X      33
100 #define LED_SIZE_Y      46
101 #define LED_POS_X1      461
102 #define LED_POS_X2      618
103 #define LED_POS_Y       28
104 #else
105 #define BUTTON_SPACE_X  47
106 #define BUTTON_SPACE_Y  47
107 #define BUTTON_SIZE_X   44
108 #define BUTTON_SIZE_Y   44
109 #define BUTTON_POS_X1   536
110 #define BUTTON_POS_X2   729
111 #define BUTTON_POS_Y1   488
112 #define BUTTON_POS_Y2   296
113
114 #define LED_SPACE_X     39
115 #define LED_SIZE_X      29
116 #define LED_SIZE_Y      39
117 #define LED_POS_X1      446
118 #define LED_POS_X2      607
119 #define LED_POS_Y       130
120 #endif
121
122 const struct {
123         int x, y;
124         int width, height;
125         int code;
126 } vm_buttons[] = {
127         // virtual key codes 0x80-0x8f and 0x98-0x9f are not used in pc keyboard
128         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x80},   // 0
129         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x81},   // 1
130         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x82},   // 2
131         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x83},   // 3
132         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x84},   // 4
133         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x85},   // 5
134         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x86},   // 6
135         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x87},   // 7
136         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x88},   // 8
137         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x89},   // 9
138         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8a},   // A
139         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8b},   // B
140         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8c},   // C
141         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8d},   // D
142         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8e},   // E
143         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8f},   // F
144         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x98},   // RET
145         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x99},   // RUN
146         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9a},   // STORE DATA
147         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9b},   // LOAD DATA
148 #if defined(_TK80BS) || defined(_TK80)
149         {BUTTON_POS_X2                     , BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x00},   // RESET
150 #elif defined(_TK85)
151         {BUTTON_POS_X2                     , BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x97},   // MON
152 #endif
153         {BUTTON_POS_X2                     , BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9c},   // ADRS SET
154         {BUTTON_POS_X2                     , BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9d},   // READ INCR
155         {BUTTON_POS_X2                     , BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9e},   // READ DECR
156         {BUTTON_POS_X2                     , BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9f},   // WRITE INCR
157 #if defined(_TK85)
158         {727                               , 237                               , 29           , 29           , 0x00},   // RESET
159 #endif
160 };
161 const struct {
162         int x, y;
163         int width, height;
164 } vm_ranges[] = {
165         {LED_POS_X1 + LED_SPACE_X * 0, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y}, // 7-seg LEDs
166         {LED_POS_X1 + LED_SPACE_X * 1, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
167         {LED_POS_X1 + LED_SPACE_X * 2, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
168         {LED_POS_X1 + LED_SPACE_X * 3, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
169         {LED_POS_X2 + LED_SPACE_X * 0, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
170         {LED_POS_X2 + LED_SPACE_X * 1, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
171         {LED_POS_X2 + LED_SPACE_X * 2, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
172         {LED_POS_X2 + LED_SPACE_X * 3, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
173 #if defined(_TK80BS)
174         {4, 158, 512, 256}, // CRT
175 #endif
176 };
177
178 class EMU;
179 class DEVICE;
180 class EVENT;
181
182 class DATAREC;
183 class I8080;
184 #if defined(_TK80BS)
185 class I8251;
186 class IO;
187 #endif
188 class I8255;
189 class PCM1BIT;
190
191 namespace TK80 {
192 #if defined(_TK80BS) || defined(_TK80)
193         class CMT;
194 #endif
195         //class MEMORY;
196         class DISPLAY;
197         class KEYBOARD;
198         class MEMBUS;
199 }
200
201 class VM : public VM_TEMPLATE
202 {
203 protected:
204         //EMU* emu;
205
206         // devices
207         //EVENT* event;
208
209         DATAREC* drec;
210         I8080* cpu;
211 #if defined(_TK80BS)
212         I8251* sio_b;
213         I8255* pio_b;
214         IO* memio;
215 #endif
216         I8255* pio_t;
217 //      TK80::MEMORY* memory;
218         PCM1BIT* pcm0;
219         PCM1BIT* pcm1;
220
221 #if defined(_TK80BS) || defined(_TK80)
222         TK80::CMT* cmt;
223 #endif
224         TK80::DISPLAY* display;
225         TK80::KEYBOARD* keyboard;
226         TK80::MEMBUS* memory;
227
228         // memory
229         uint8_t mon[0x800];
230         uint8_t ext[0x7000];
231         uint8_t ram[0x5000];    // with TK-M20K
232 #if defined(_TK80BS)
233         uint8_t basic[0x2000];
234         uint8_t bsmon[0x1000];
235         uint8_t vram[0x200];
236
237         int boot_mode;
238 #endif
239
240 public:
241         // ----------------------------------------
242         // initialize
243         // ----------------------------------------
244
245         VM(EMU_TEMPLATE* parent_emu);
246         ~VM();
247
248         // ----------------------------------------
249         // for emulation class
250         // ----------------------------------------
251
252         // drive virtual machine
253         void reset();
254         void run();
255         double get_frame_rate()
256         {
257                 return FRAMES_PER_SEC;
258         }
259
260 #ifdef USE_DEBUGGER
261         // debugger
262         DEVICE *get_cpu(int index);
263 #endif
264
265         // draw screen
266         void draw_screen();
267 #if defined(_TK80BS)
268         int max_draw_ranges();
269 #endif
270
271         // sound generation
272         void initialize_sound(int rate, int samples);
273         uint16_t* create_sound(int* extra_frames);
274         int get_sound_buffer_ptr();
275 #ifdef USE_SOUND_VOLUME
276         void set_sound_device_volume(int ch, int decibel_l, int decibel_r);
277 #endif
278
279         // notify key
280         void key_down(int code, bool repeat);
281         void key_up(int code);
282         bool get_caps_locked();
283         bool get_kana_locked();
284
285         // user interface
286         void load_binary(int drv, const _TCHAR* file_path);
287         void save_binary(int drv, const _TCHAR* file_path);
288         void play_tape(int drv, const _TCHAR* file_path);
289         void rec_tape(int drv, const _TCHAR* file_path);
290         void close_tape(int drv);
291         bool is_tape_inserted(int drv);
292         bool is_tape_playing(int drv);
293         bool is_tape_recording(int drv);
294         int get_tape_position(int drv);
295         const _TCHAR* get_tape_message(int drv);
296         void push_play(int drv);
297         void push_stop(int drv);
298         void push_fast_forward(int drv);
299         void push_fast_rewind(int drv);
300         void push_apss_forward(int drv) {}
301         void push_apss_rewind(int drv) {}
302         bool is_frame_skippable();
303
304         double get_current_usec();
305         uint64_t get_current_clock_uint64();
306
307         void update_config();
308         bool process_state(FILEIO* state_fio, bool loading);
309
310         // ----------------------------------------
311         // for each device
312         // ----------------------------------------
313
314         // devices
315         DEVICE* get_device(int id);
316         //DEVICE* dummy;
317         //DEVICE* first_device;
318         //DEVICE* last_device;
319
320 #if defined(_TK80BS)
321         int draw_ranges;
322 #endif
323 };
324
325 #endif