OSDN Git Service

df1aacb5d8e0b10598a1fa00d6c57f9eb7356afe
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / pc9801.h
1 /*
2         NEC PC-9801 Emulator 'ePC-9801'
3         NEC PC-9801E/F/M Emulator 'ePC-9801E'
4         NEC PC-9801U Emulator 'ePC-9801U'
5         NEC PC-9801VF Emulator 'ePC-9801VF'
6         NEC PC-9801VM Emulator 'ePC-9801VM'
7         NEC PC-9801VX Emulator 'ePC-9801VX'
8         NEC PC-9801RA Emulator 'ePC-9801RA'
9         NEC PC-98XA Emulator 'ePC-98XA'
10         NEC PC-98XL Emulator 'ePC-98XL'
11         NEC PC-98RL Emulator 'ePC-98RL'
12         NEC PC-98DO Emulator 'ePC-98DO'
13
14         Author : Takeda.Toshiya
15         Date   : 2010.09.15-
16
17         [ virtual machine ]
18 */
19
20 #ifndef _PC9801_H_
21 #define _PC9801_H_
22
23 /*
24         PC-9801         8086    5MHz
25         PC-9801E/F/M    8086    5/8MHz
26
27         PC-9801U/VF     V30     8MHz
28         PC-9801VM       V30     8/10MHz
29         PC-98DO         V30     8/10MHz
30         PC-98DO+        V33     8/16MHz
31
32         PC-9801VX       80286   8/10MHz
33         PC-9801RX/DX    80286   12MHz
34
35         PC-9801RA       80386   16MHz
36         PC-9801DA       80386   20MHz
37
38         PC-98XA         80286   8MHz
39         PC-98XL         80286   8MHz/10MHz
40
41         PC-98XL^2       80386   16MHz
42         PC-98RL         80386   20MHz
43 */
44
45 #if defined(_PC9801)
46         #define DEVICE_NAME             "NEC PC-9801"
47         #define CONFIG_NAME             "pc9801"
48         #define HAS_I86
49         #define CPU_CLOCKS              4992030
50         #define PIT_CLOCK_5MHZ
51 #elif defined(_PC9801E)
52         #define DEVICE_NAME             "NEC PC-9801E/F/M"
53         #define CONFIG_NAME             "pc9801e"
54         #define HAS_I86
55         #define CPU_CLOCKS              7987248
56         #define PIT_CLOCK_8MHZ
57 //      #define CPU_CLOCKS              4992030
58 //      #define PIT_CLOCK_5MHZ
59         #define USE_CPU_TYPE            2
60 #elif defined(_PC9801U) || defined(_PC9801VF)
61         #if defined(_PC9801U)
62                 #define DEVICE_NAME     "NEC PC-9801U"
63                 #define CONFIG_NAME     "pc9801u"
64         #elif defined(_PC9801VF)
65                 #define DEVICE_NAME     "NEC PC-9801VF"
66                 #define CONFIG_NAME     "pc9801vf"
67         #endif
68         #define HAS_V30
69         #define CPU_CLOCKS              7987248
70         #define PIT_CLOCK_8MHZ
71 #elif defined(_PC9801VM) || defined(_PC98DO)
72         #if defined(_PC9801VM)
73                 #define DEVICE_NAME     "NEC PC-9801VM"
74                 #define CONFIG_NAME     "pc9801vm"
75         #elif defined(_PC98DO)
76                 #define DEVICE_NAME     "NEC PC-98DO"
77                 #define CONFIG_NAME     "pc98do"
78         #endif
79         #define HAS_V30
80         #define CPU_CLOCKS              9984060
81         #define PIT_CLOCK_5MHZ
82 //      #define CPU_CLOCKS              7987248
83 //      #define PIT_CLOCK_8MHZ
84         #define USE_CPU_TYPE            2
85 #elif defined(_PC98DOPLUS)
86         #define DEVICE_NAME             "NEC PC-98DO+"
87         #define CONFIG_NAME             "pc98do+"
88         #define HAS_V33A
89         #define CPU_CLOCKS              15974496
90         #define PIT_CLOCK_8MHZ
91 //      #define CPU_CLOCKS              7987248
92 //      #define PIT_CLOCK_8MHZ
93         #define USE_CPU_TYPE            2
94 #elif defined(_PC9801VX) || defined(_PC98XL)
95         #if defined(_PC9801VX)
96                 #define DEVICE_NAME     "NEC PC-9801VX"
97                 #define CONFIG_NAME     "pc9801vx"
98         #elif defined(_PC98XL)
99                 #define DEVICE_NAME     "NEC PC-98XL"
100                 #define CONFIG_NAME     "pc98xl"
101         #endif
102         #define HAS_I286
103         #define CPU_CLOCKS              9984060
104         #define PIT_CLOCK_5MHZ
105 //      #define CPU_CLOCKS              7987248
106 //      #define PIT_CLOCK_8MHZ
107         #define USE_CPU_TYPE            2
108 #elif defined(_PC98XA)
109         #define DEVICE_NAME             "NEC PC-98XA"
110         #define CONFIG_NAME             "pc98xa"
111         #define HAS_I286
112         #define CPU_CLOCKS              7987248
113         #define PIT_CLOCK_8MHZ
114 #elif defined(_PC9801RA) || defined(_PC98RL)
115         #if defined(_PC9801RA)
116                 #define DEVICE_NAME     "NEC PC-9801RA"
117                 #define CONFIG_NAME     "pc9801ra"
118         #elif defined(_PC98RL)
119                 #define DEVICE_NAME     "NEC PC-98RL"
120                 #define CONFIG_NAME     "pc98rl"
121         #endif
122         #define HAS_I386
123         #define CPU_CLOCKS              19968120
124         #define PIT_CLOCK_5MHZ
125 //      #define CPU_CLOCKS              15974496
126 //      #define PIT_CLOCK_8MHZ
127         #define USE_CPU_TYPE            2
128 #else
129         // unknown machines
130 #endif
131
132 #if defined(_PC9801) || defined(_PC9801E)
133         #define SUPPORT_CMT_IF
134         #define SUPPORT_2HD_FDD_IF
135         #define SUPPORT_2DD_FDD_IF
136         #define SUPPORT_320KB_FDD_IF
137         #define SUPPORT_OLD_BUZZER
138 #elif defined(_PC9801VF) || defined(_PC9801U)
139         #define SUPPORT_2DD_FDD_IF
140 #else
141         #define SUPPORT_2HD_2DD_FDD_IF
142 #endif
143
144 #if defined(_PC98XA) || defined(_PC98XL) || defined(_PC98RL)
145         #define SUPPORT_HIRESO
146 #endif
147 #if !(defined(_PC9801) || defined(_PC9801U) || defined(SUPPORT_HIRESO))
148         #define SUPPORT_2ND_VRAM
149 #endif
150 #if !(defined(_PC9801) || defined(_PC9801E))
151         #define SUPPORT_16_COLORS
152         #define SUPPORT_GRCG
153 #endif
154 #if !(defined(HAS_I86) || defined(HAS_V30))
155         #if !defined(_PC98XA) && !defined(_PC98XL)
156                 #define SUPPORT_ITF_ROM
157         #endif
158         #if !defined(_PC98XA)
159                 #define SUPPORT_EGC
160                 #define HAS_UPD4990A
161         #endif
162         #if !defined(SUPPORT_HIRESO)
163                 #define SUPPORT_NEC_EMS
164         #endif
165         #define SUPPORT_SASI_IF
166 #endif
167
168 #if defined(HAS_I286)
169         #define SUPPORT_24BIT_ADDRESS
170 #elif defined(HAS_I386) || defined(HAS_I486)
171         #define SUPPORT_32BIT_ADDRESS
172         #if !defined(SUPPORT_HIRESO)
173                 #define SUPPORT_BIOS_RAM
174         #endif
175 #endif
176 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
177         #define MEMORY_ADDR_MAX         0x1000000       // 16MB
178 #else
179         #define MEMORY_ADDR_MAX         0x100000        // 1MB
180 #endif
181 //#if defined(SUPPORT_32BIT_ADDRESS)
182 //      #define SUPPORT_SYSTEM_16MB
183 //#endif
184 #define MEMORY_BANK_SIZE                0x800
185 #define IO_ADDR_MAX                     0x10000
186
187 // PC-9801-86
188 //#define SUPPORT_PC98_OPNA
189
190 #if defined(_PC98DO) || defined(_PC98DOPLUS)
191         #define MODE_PC98       0
192         #define MODE_PC88_V1S   1
193         #define MODE_PC88_V1H   2
194         #define MODE_PC88_V2    3
195         #define MODE_PC88_N     4
196         //#define SUPPORT_PC88_DICTIONARY
197         #define SUPPORT_PC88_HIGH_CLOCK
198         //#define SUPPORT_PC88_JOYSTICK
199         #define PC88_EXRAM_BANKS        4
200 #endif
201 #if defined(_PC98DOPLUS)
202         #define SUPPORT_PC88_OPNA
203         #define SUPPORT_PC88_SB2
204 #endif
205
206 // device informations for virtual machine
207 #if !defined(SUPPORT_HIRESO)
208         #define FRAMES_PER_SEC          56.42
209         #define LINES_PER_FRAME         440
210         #define SCREEN_WIDTH            640
211         #define SCREEN_HEIGHT           400
212         #define WINDOW_HEIGHT_ASPECT    480
213 #else
214         #define FRAMES_PER_SEC          79.09
215         #define LINES_PER_FRAME         784
216         #define SCREEN_WIDTH            1120
217         #define SCREEN_HEIGHT           750
218         #define WINDOW_HEIGHT_ASPECT    840
219 #endif
220 #define MAX_DRIVE               2
221 #define UPD765A_NO_ST1_EN_OR_FOR_RESULT7
222 #if defined(_PC98DO) || defined(_PC98DOPLUS)
223 #define PC80S31K_NO_WAIT
224 #endif
225 #define UPD7220_MSB_FIRST
226 #define UPD7220_HORIZ_FREQ      24830
227 #if defined(_PC98DO) || defined(_PC98DOPLUS)
228 #define Z80_MEMORY_WAIT
229 #endif
230 #if defined(SUPPORT_PC98_OPNA) || defined(SUPPORT_PC88_OPNA)
231 #define HAS_YM2608
232 #endif
233 #define I8259_MAX_CHIPS         2
234 #define SINGLE_MODE_DMA
235 #define OVERRIDE_SOUND_FREQ_48000HZ     55467
236 #define SUPPORT_VARIABLE_TIMING
237
238 // device informations for win32
239 #if defined(_PC9801) || defined(_PC9801E)
240 #define USE_FLOPPY_DISK         6
241 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
242 #define USE_BOOT_MODE           5
243 #define USE_DIPSWITCH
244 #define USE_FLOPPY_DISK         4
245 #else
246 #define USE_FLOPPY_DISK         2
247 #endif
248 #if defined(SUPPORT_SASI_IF) || defined(SUPPORT_SCSI_IF) || defined(SUPPORT_IDE_IF)
249 #define USE_HARD_DISK           2
250 #endif
251 #if defined(SUPPORT_CMT_IF) || defined(_PC98DO) || defined(_PC98DOPLUS)
252 #define USE_TAPE                1
253 #define TAPE_BINARY_ONLY
254 #endif
255 #define NOTIFY_KEY_DOWN
256 #define USE_KEY_LOCKED
257 #define USE_SHIFT_NUMPAD_KEY
258 #define USE_ALT_F10_KEY
259 #if defined(_PC98DO) || defined(_PC98DOPLUS)
260 // slow enough for N88-\93ú\96{\8cêBASIC
261 #define USE_AUTO_KEY            8
262 #define USE_AUTO_KEY_RELEASE    10
263 #else
264 #define USE_AUTO_KEY            5
265 #define USE_AUTO_KEY_RELEASE    6
266 #endif
267 #define USE_AUTO_KEY_NUMPAD
268 #define USE_MONITOR_TYPE        2
269 #define USE_SCANLINE
270 #define USE_SCREEN_FILTER
271 #define USE_SOUND_TYPE          5
272 #if defined(_PC98DO) || defined(_PC98DOPLUS)
273 #if    defined(SUPPORT_PC98_OPNA) &&  defined(SUPPORT_PC88_OPNA)
274 #define USE_SOUND_VOLUME        (4 + 1 + 1 + 4 + 1 + 1)
275 #elif  defined(SUPPORT_PC98_OPNA) && !defined(SUPPORT_PC88_OPNA)
276 #define USE_SOUND_VOLUME        (4 + 1 + 1 + 2 + 1 + 1)
277 #elif !defined(SUPPORT_PC98_OPNA) &&  defined(SUPPORT_PC88_OPNA)
278 #define USE_SOUND_VOLUME        (2 + 1 + 1 + 4 + 1 + 1)
279 #elif !defined(SUPPORT_PC98_OPNA) && !defined(SUPPORT_PC88_OPNA)
280 #define USE_SOUND_VOLUME        (2 + 1 + 1 + 2 + 1 + 1)
281 #endif
282 #else
283 #if defined(SUPPORT_PC98_OPNA)
284 #define USE_SOUND_VOLUME        (4 + 1 + 1 + 1)
285 #else
286 #define USE_SOUND_VOLUME        (2 + 1 + 1 + 1)
287 #endif
288 #endif
289 #define USE_JOYSTICK
290 #define USE_MOUSE
291 #define USE_PRINTER
292 #define USE_PRINTER_TYPE        3
293 #define USE_DEBUGGER
294 #define USE_STATE
295 #if defined(HAS_I86) || defined(HAS_V30)
296 #define USE_CPU_I286
297 #elif defined(HAS_I386) || defined(HAS_I486)
298 #define USE_CPU_I386
299 #else
300 #define USE_CPU_I286
301 #endif
302 #if defined(SUPPORT_320KB_FDD_IF) || defined(_PC98DO) || defined(_PC98DOPLUS)
303 #define USE_CPU_Z80
304 #endif
305
306 #include "../../common.h"
307 #include "../../fileio.h"
308 #include "../vm_template.h"
309
310 #ifdef USE_SOUND_VOLUME
311 static const _TCHAR *sound_device_caption[] = {
312 #if defined(SUPPORT_PC98_OPNA)
313         _T("PC-9801-86 (FM)"), _T("PC-9801-86 (PSG)"), _T("PC-9801-86 (ADPCM)"), _T("PC-9801-86 (Rhythm)"),
314 #else
315         _T("PC-9801-26 (FM)"), _T("PC-9801-26 (PSG)"),
316 #endif
317         _T("PC-9801-14"), _T("Beep"),
318 #if defined(_PC98DO) || defined(_PC98DOPLUS)
319 #if defined(SUPPORT_PC88_OPNA)
320         _T("PC-88 OPNA (FM)"), _T("PC-88 OPNA (PSG)"), _T("PC-88 OPNA (ADPCM)"), _T("PC-88 OPNA (Rhythm)"),
321 #else
322         _T("PC-88 OPN (FM)"), _T("PC-88 OPN (PSG)"),
323 #endif
324         _T("PC-88 Beep"), 
325 #endif
326         _T("Noise (FDD)"),
327 };
328 #endif
329
330 class csp_state_utils;
331
332 class EMU;
333 class DEVICE;
334 class EVENT;
335
336 #if defined(SUPPORT_OLD_BUZZER)
337 class BEEP;
338 #endif
339 class DISK;
340 #if defined(USE_HARD_DISK)
341 class HARDDISK;
342 #endif
343 class I8237;
344 class I8251;
345 class I8253;
346 class I8255;
347 class I8259;
348 #if defined(HAS_I86) || defined(HAS_V30)
349 class I286;
350 #elif defined(HAS_I386) || defined(HAS_I486)
351 class I386;
352 #else
353 class I286;
354 #endif
355 class IO;
356 class LS244;
357 //class MEMORY;
358 class NOISE;
359 class NOT;
360 #if !defined(SUPPORT_OLD_BUZZER)
361 class PCM1BIT;
362 #endif
363 #if defined(SUPPORT_SASI_IF)
364 class SASI_HDD;
365 class SCSI_HOST;
366 #define SCSI_HOST_AUTO_ACK
367 #elif defined(SUPPORT_SCSI_IF)
368 class SCSI_HDD;
369 class SCSI_HOST;
370 #define SCSI_HOST_AUTO_ACK
371 #endif
372 class TMS3631;
373 class UPD1990A;
374 class UPD7220;
375 class UPD765A;
376 class YM2203;
377
378 #if defined(SUPPORT_CMT_IF)
379 class CMT;
380 #endif
381 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
382 class CPUREG;
383 #endif
384 class DISPLAY;
385 class DMAREG;
386 class FLOPPY;
387 class FMSOUND;
388 class JOYSTICK;
389 class KEYBOARD;
390 class MEMBUS;
391 class MOUSE;
392 #if defined(SUPPORT_SASI_IF)
393 class SASI;
394 #endif
395 #if defined(SUPPORT_SCSI_IF)
396 class SCSI;
397 #endif
398 #if defined(SUPPORT_IDE_IF)
399 class IDE;
400 #endif
401
402 #if defined(SUPPORT_320KB_FDD_IF)
403 // 320kb fdd drives
404 class PC80S31K;
405 class Z80;
406 #endif
407
408 #if defined(_PC98DO) || defined(_PC98DOPLUS)
409 class PC80S31K;
410 class PC88;
411 class Z80;
412 #endif
413
414 class VM : public VM_TEMPLATE
415 {
416 protected:
417         //EMU* emu;
418         //csp_state_utils* state_entry;
419         
420         // devices
421         //EVENT* event;
422         
423 #if defined(SUPPORT_OLD_BUZZER)
424         BEEP* beep;
425 #else
426         PCM1BIT* beep;
427 #endif
428         DEVICE* printer;
429         I8237* dma;
430 #if defined(SUPPORT_CMT_IF)
431         I8251* sio_cmt;
432 #endif
433         I8251* sio_rs;
434         I8251* sio_kbd;
435         I8253* pit;
436 #if defined(SUPPORT_320KB_FDD_IF)
437         I8255* pio_fdd;
438 #endif
439         I8255* pio_mouse;
440         I8255* pio_sys;
441         I8255* pio_prn;
442         I8259* pic;
443 #if defined(HAS_I386) || defined(HAS_I486)
444         I386* cpu;
445 #elif defined(HAS_I86) || defined(HAS_V30)
446         I286 *cpu;
447 #else
448         I286* cpu;
449 #endif
450         IO* io;
451         LS244* rtcreg;
452         //MEMORY* memory;
453         NOT* not_busy;
454 #if defined(HAS_I86) || defined(HAS_V30)
455         NOT* not_prn;
456 #endif
457 #if defined(SUPPORT_SASI_IF)
458         SASI_HDD* sasi_hdd;
459         SCSI_HOST* sasi_host;
460 #endif
461 #if defined(SUPPORT_SCSI_IF)
462         SCSI_HDD* scsi_hdd[2];
463         SCSI_HOST* scsi_host;
464 #endif
465         UPD1990A* rtc;
466 #if defined(SUPPORT_2HD_FDD_IF)
467         UPD765A* fdc_2hd;
468 #endif
469 #if defined(SUPPORT_2DD_FDD_IF)
470         UPD765A* fdc_2dd;
471 #endif
472 #if defined(SUPPORT_2HD_2DD_FDD_IF)
473         UPD765A* fdc;
474 #endif
475         NOISE* noise_seek;
476         NOISE* noise_head_down;
477         NOISE* noise_head_up;
478         UPD7220* gdc_chr;
479         UPD7220* gdc_gfx;
480         YM2203* opn;
481         
482 #if defined(SUPPORT_CMT_IF)
483         CMT* cmt;
484 #endif
485 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
486         CPUREG* cpureg;
487 #endif
488         DISPLAY* display;
489         DMAREG* dmareg;
490         FLOPPY* floppy;
491         FMSOUND* fmsound;
492         JOYSTICK* joystick;
493         KEYBOARD* keyboard;
494         MEMBUS* memory;
495         MOUSE* mouse;
496 #if defined(SUPPORT_SASI_IF)
497         SASI* sasi;
498 #endif
499 #if defined(SUPPORT_SCSI_IF)
500         SCSI* scsi;
501 #endif
502 #if defined(SUPPORT_IDE_IF)
503         IDE* ide;
504 #endif
505         
506         // PC-9801-14
507         TMS3631* tms3631;
508         I8253* pit_14;
509         I8255* pio_14;
510         LS244* maskreg_14;
511         
512 #if defined(SUPPORT_320KB_FDD_IF)
513         // 320kb fdd drives
514         I8255* pio_sub;
515         PC80S31K *pc80s31k;
516         UPD765A* fdc_sub;
517         Z80* cpu_sub;
518 #endif
519         
520         // misc
521         bool pit_clock_8mhz;
522         int sound_type;
523         
524 #if defined(_PC98DO) || defined(_PC98DOPLUS)
525         EVENT* pc88event;
526         
527         PC88* pc88;
528         DEVICE* pc88prn;
529         I8251* pc88sio;
530         I8255* pc88pio;
531         PCM1BIT* pc88pcm;
532         UPD1990A* pc88rtc;
533         YM2203* pc88opn;
534         Z80* pc88cpu;
535         
536         PC80S31K* pc88sub;
537         I8255* pc88pio_sub;
538         UPD765A* pc88fdc_sub;
539         NOISE* pc88noise_seek;
540         NOISE* pc88noise_head_down;
541         NOISE* pc88noise_head_up;
542         Z80* pc88cpu_sub;
543         
544         int boot_mode;
545 #endif
546         
547         // drives
548         UPD765A *get_floppy_disk_controller(int drv);
549         DISK *get_floppy_disk_handler(int drv);
550         
551 public:
552         // ----------------------------------------
553         // initialize
554         // ----------------------------------------
555         
556         VM(EMU* parent_emu);
557         ~VM();
558         
559         // ----------------------------------------
560         // for emulation class
561         // ----------------------------------------
562         
563         // drive virtual machine
564         void reset();
565         void run();
566         double get_frame_rate();
567         
568 #ifdef USE_DEBUGGER
569         // debugger
570         DEVICE *get_cpu(int index);
571 #endif
572         
573         // draw screen
574         void draw_screen();
575         
576         // sound generation
577         void initialize_sound(int rate, int samples);
578         uint16_t* create_sound(int* extra_frames);
579         int get_sound_buffer_ptr();
580 #ifdef USE_SOUND_VOLUME
581         void set_sound_device_volume(int ch, int decibel_l, int decibel_r);
582 #endif
583         
584         // notify key
585         void key_down(int code, bool repeat);
586         void key_up(int code);
587         bool get_caps_locked();
588         bool get_kana_locked();
589         
590         // user interface
591         void open_floppy_disk(int drv, const _TCHAR* file_path, int bank);
592         void close_floppy_disk(int drv);
593         bool is_floppy_disk_inserted(int drv);
594         void is_floppy_disk_protected(int drv, bool value);
595         bool is_floppy_disk_protected(int drv);
596         uint32_t is_floppy_disk_accessed();
597 #if defined(USE_HARD_DISK)
598         void open_hard_disk(int drv, const _TCHAR* file_path);
599         void close_hard_disk(int drv);
600         bool is_hard_disk_inserted(int drv);
601         uint32_t is_hard_disk_accessed();
602 #endif
603 #if defined(USE_TAPE)
604         void play_tape(int drv, const _TCHAR* file_path);
605         void rec_tape(int drv, const _TCHAR* file_path);
606         void close_tape(int drv);
607         bool is_tape_inserted(int drv);
608 #endif
609         bool is_frame_skippable();
610         
611         void update_config();
612         bool process_state(FILEIO* state_fio, bool loading);
613         
614         // ----------------------------------------
615         // for each device
616         // ----------------------------------------
617         
618         // devices
619         DEVICE* get_device(int id);
620         //DEVICE* dummy;
621         //DEVICE* first_device;
622         //DEVICE* last_device;
623 };
624
625 #endif