OSDN Git Service

[General] Completely merge upstream 2019-01-11.
[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         // PC-9801-86
176         #define SUPPORT_PC98_OPNA
177 #endif
178 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
179         #define MEMORY_ADDR_MAX         0x1000000       // 16MB
180 #else
181         #define MEMORY_ADDR_MAX         0x100000        // 1MB
182 #endif
183 //#if defined(SUPPORT_32BIT_ADDRESS)
184 //      #define SUPPORT_SYSTEM_16MB
185 //#endif
186 #define MEMORY_BANK_SIZE                0x800
187 #define IO_ADDR_MAX                     0x10000
188
189 #if defined(_PC98DO) || defined(_PC98DOPLUS)
190         #define PC8801_VARIANT
191         #define PC8801SR_VARIANT
192         #define MODE_PC98       0
193         #define MODE_PC88_V1S   1
194         #define MODE_PC88_V1H   2
195         #define MODE_PC88_V2    3
196         #define MODE_PC88_N     4
197         #define SUPPORT_PC88_KANJI1
198         #define SUPPORT_PC88_KANJI2
199         //#define SUPPORT_PC88_DICTIONARY
200         #define SUPPORT_PC88_HIGH_CLOCK
201         //#define SUPPORT_PC88_JOYSTICK
202         #define PC88_EXRAM_BANKS        4
203         #define SUPPORT_PC88_OPN1
204 #if defined(_PC98DOPLUS)
205         #define SUPPORT_PC88_OPNA
206 #endif
207 #endif
208
209 // device informations for virtual machine
210 #if !defined(SUPPORT_HIRESO)
211         #define FRAMES_PER_SEC          56.42
212         #define LINES_PER_FRAME         440
213         #define SCREEN_WIDTH            640
214         #define SCREEN_HEIGHT           400
215         #define WINDOW_HEIGHT_ASPECT    480
216 #else
217         #define FRAMES_PER_SEC          79.09
218         #define LINES_PER_FRAME         784
219         #define SCREEN_WIDTH            1120
220         #define SCREEN_HEIGHT           750
221         #define WINDOW_HEIGHT_ASPECT    840
222 #endif
223 #define MAX_DRIVE               2
224 #define UPD765A_NO_ST1_EN_OR_FOR_RESULT7
225 #if defined(_PC98DO) || defined(_PC98DOPLUS)
226 #define PC80S31K_NO_WAIT
227 #endif
228 #define UPD7220_MSB_FIRST
229 #define UPD7220_HORIZ_FREQ      24830
230 #if defined(_PC98DO) || defined(_PC98DOPLUS)
231 #define Z80_MEMORY_WAIT
232 #endif
233 #define I8259_MAX_CHIPS         2
234 #define SINGLE_MODE_DMA
235 #define OVERRIDE_SOUND_FREQ_48000HZ     55467
236
237 // device informations for win32
238 #if defined(_PC9801) || defined(_PC9801E)
239 #define USE_FLOPPY_DISK         6
240 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
241 #define USE_BOOT_MODE           5
242 #define USE_DIPSWITCH
243 #define USE_FLOPPY_DISK         4
244 #else
245 #define USE_FLOPPY_DISK         2
246 #endif
247 #if defined(SUPPORT_SASI_IF) || defined(SUPPORT_SCSI_IF) || defined(SUPPORT_IDE_IF)
248 #define USE_HARD_DISK           2
249         #if defined(HAS_I286)
250         #define I86_PSEUDO_BIOS
251         #else
252         #define I386_PSEUDO_BIOS
253         #endif
254 #endif
255 #if defined(SUPPORT_CMT_IF) || defined(_PC98DO) || defined(_PC98DOPLUS)
256 #define USE_TAPE                1
257 #define TAPE_BINARY_ONLY
258 #endif
259 #define USE_KEY_LOCKED
260 #if defined(_PC98DO) || defined(_PC98DOPLUS)
261 // slow enough for N88-\93ú\96{\8cêBASIC
262 #define USE_AUTO_KEY            8
263 #define USE_AUTO_KEY_RELEASE    10
264 #else
265 #define USE_AUTO_KEY            5
266 #define USE_AUTO_KEY_RELEASE    6
267 #endif
268 #define USE_AUTO_KEY_NUMPAD
269 #define USE_MONITOR_TYPE        2
270 #define USE_SCANLINE
271 #define USE_SCREEN_FILTER
272 #define USE_SOUND_TYPE          5
273 #if defined(_PC98DO) || defined(_PC98DOPLUS)
274 #if    defined(SUPPORT_PC98_OPNA) &&  defined(SUPPORT_PC88_OPNA)
275 #define USE_SOUND_VOLUME        (4 + 1 + 1 + 4 + 1 + 1)
276 #elif  defined(SUPPORT_PC98_OPNA) && !defined(SUPPORT_PC88_OPNA)
277 #define USE_SOUND_VOLUME        (4 + 1 + 1 + 2 + 1 + 1)
278 #elif !defined(SUPPORT_PC98_OPNA) &&  defined(SUPPORT_PC88_OPNA)
279 #define USE_SOUND_VOLUME        (2 + 1 + 1 + 4 + 1 + 1)
280 #elif !defined(SUPPORT_PC98_OPNA) && !defined(SUPPORT_PC88_OPNA)
281 #define USE_SOUND_VOLUME        (2 + 1 + 1 + 2 + 1 + 1)
282 #endif
283 #else
284 #if defined(SUPPORT_PC98_OPNA)
285 #define USE_SOUND_VOLUME        (4 + 1 + 1 + 1)
286 #else
287 #define USE_SOUND_VOLUME        (2 + 1 + 1 + 1)
288 #endif
289 #endif
290 #define USE_JOYSTICK
291 #define USE_MOUSE
292 #define USE_PRINTER
293 #define USE_PRINTER_TYPE        3
294 #define USE_DEBUGGER
295 #define USE_STATE
296 #if defined(HAS_I86) || defined(HAS_V30)
297 #define USE_CPU_I286
298 #elif defined(HAS_I386) || defined(HAS_I486)
299 #define USE_CPU_I386
300 #else
301 #define USE_CPU_I286
302 #endif
303 #if defined(SUPPORT_320KB_FDD_IF) || defined(_PC98DO) || defined(_PC98DOPLUS)
304 #define USE_CPU_Z80
305 #endif
306
307 #include "../../common.h"
308 #include "../../fileio.h"
309 #include "../vm_template.h"
310
311 #ifdef USE_SOUND_VOLUME
312 static const _TCHAR *sound_device_caption[] = {
313 #if defined(SUPPORT_PC98_OPNA)
314         _T("OPNA (FM)"), _T("OPNA (PSG)"), _T("OPNA (ADPCM)"), _T("OPNA (Rhythm)"),
315 #else
316         _T("OPN (FM)"), _T("OPN (PSG)"),
317 #endif
318         _T("PC-9801-14"), _T("Beep"),
319 #if defined(_PC98DO) || defined(_PC98DOPLUS)
320 #if defined(SUPPORT_PC88_OPNA)
321         _T("PC-88 (FM)"), _T("PC-88 (PSG)"), _T("PC-88 (ADPCM)"), _T("PC-88 (Rhythm)"),
322 #else
323         _T("PC-88 (FM)"), _T("PC-88 (PSG)"),
324 #endif
325         _T("PC-88 (Beep)"), 
326 #endif
327         _T("Noise (FDD)"),
328 };
329 #endif
330
331 class EMU;
332 class DEVICE;
333 class EVENT;
334
335 #if defined(SUPPORT_OLD_BUZZER)
336 class BEEP;
337 #endif
338 class DISK;
339 #if defined(USE_HARD_DISK)
340 class HARDDISK;
341 #endif
342 class I8237;
343 class I8251;
344 class I8253;
345 class I8255;
346 class I8259;
347 #if defined(HAS_I86) || defined(HAS_V30)
348 class I286;
349 #elif defined(HAS_I386) || defined(HAS_I486)
350 class I386;
351 #else
352 class I286;
353 #endif
354 class IO;
355 class LS244;
356 //class MEMORY;
357 class NOISE;
358 class NOT;
359 #if !defined(SUPPORT_OLD_BUZZER)
360 class PCM1BIT;
361 #endif
362 #if defined(SUPPORT_SASI_IF)
363 class SASI_HDD;
364 class SCSI_HOST;
365 #define SCSI_HOST_AUTO_ACK
366 #elif defined(SUPPORT_SCSI_IF)
367 class SCSI_HDD;
368 class SCSI_HOST;
369 #define SCSI_HOST_AUTO_ACK
370 #endif
371 class TMS3631;
372 class UPD1990A;
373 class UPD7220;
374 class UPD765A;
375 class YM2203;
376
377 namespace PC9801 {
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         class BIOS;
395 #endif
396 #if defined(SUPPORT_SCSI_IF)
397         class SCSI;
398 #endif
399 #if defined(SUPPORT_IDE_IF)
400         class IDE;
401 #endif
402 }
403
404 #if defined(SUPPORT_320KB_FDD_IF)
405 // 320kb fdd drives
406 class PC80S31K;
407 class Z80;
408 #endif
409
410 #if defined(_PC98DO) || defined(_PC98DOPLUS)
411 class PC80S31K;
412 namespace PC88DEV {
413         class PC88;
414 }
415 class Z80;
416 #endif
417
418 class VM : public VM_TEMPLATE
419 {
420 protected:
421         //EMU* emu;
422         //csp_state_utils* state_entry;
423         
424         // devices
425         //EVENT* event;
426         
427 #if defined(SUPPORT_OLD_BUZZER)
428         BEEP* beep;
429 #else
430         PCM1BIT* beep;
431 #endif
432         DEVICE* printer;
433         I8237* dma;
434 #if defined(SUPPORT_CMT_IF)
435         I8251* sio_cmt;
436 #endif
437         I8251* sio_rs;
438         I8251* sio_kbd;
439         I8253* pit;
440 #if defined(SUPPORT_320KB_FDD_IF)
441         I8255* pio_fdd;
442 #endif
443         I8255* pio_mouse;
444         I8255* pio_sys;
445         I8255* pio_prn;
446         I8259* pic;
447 #if defined(HAS_I386) || defined(HAS_I486)
448         I386* cpu;
449 #elif defined(HAS_I86) || defined(HAS_V30)
450         I286 *cpu;
451 #else
452         I286* cpu;
453 #endif
454         IO* io;
455         LS244* rtcreg;
456         //MEMORY* memory;
457         NOT* not_busy;
458 #if defined(HAS_I86) || defined(HAS_V30)
459         NOT* not_prn;
460 #endif
461 #if defined(SUPPORT_SASI_IF)
462         SASI_HDD* sasi_hdd;
463         SCSI_HOST* sasi_host;
464 #endif
465 #if defined(SUPPORT_SCSI_IF)
466         SCSI_HDD* scsi_hdd[2];
467         SCSI_HOST* scsi_host;
468 #endif
469         UPD1990A* rtc;
470 #if defined(SUPPORT_2HD_FDD_IF)
471         UPD765A* fdc_2hd;
472 #endif
473 #if defined(SUPPORT_2DD_FDD_IF)
474         UPD765A* fdc_2dd;
475 #endif
476 #if defined(SUPPORT_2HD_2DD_FDD_IF)
477         UPD765A* fdc;
478 #endif
479         NOISE* noise_seek;
480         NOISE* noise_head_down;
481         NOISE* noise_head_up;
482         UPD7220* gdc_chr;
483         UPD7220* gdc_gfx;
484         YM2203* opn;
485         
486 #if defined(SUPPORT_CMT_IF)
487         PC9801::CMT* cmt;
488 #endif
489 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
490         PC9801::CPUREG* cpureg;
491 #endif
492         PC9801::DISPLAY* display;
493         PC9801::DMAREG* dmareg;
494         PC9801::FLOPPY* floppy;
495         PC9801::FMSOUND* fmsound;
496         PC9801::JOYSTICK* joystick;
497         PC9801::KEYBOARD* keyboard;
498         PC9801::MEMBUS* memory;
499         PC9801::MOUSE* mouse;
500 #if defined(SUPPORT_SASI_IF)
501         PC9801::SASI* sasi;
502         PC9801::BIOS *sasi_bios;
503 #endif
504 #if defined(SUPPORT_SCSI_IF)
505         PC9801::SCSI* scsi;
506 #endif
507 #if defined(SUPPORT_IDE_IF)
508         PC9801::IDE* ide;
509 #endif
510         
511         // PC-9801-14
512         TMS3631* tms3631;
513         I8253* pit_14;
514         I8255* pio_14;
515         LS244* maskreg_14;
516         
517 #if defined(SUPPORT_320KB_FDD_IF)
518         // 320kb fdd drives
519         I8255* pio_sub;
520         PC80S31K *pc80s31k;
521         UPD765A* fdc_sub;
522         Z80* cpu_sub;
523 #endif
524         
525         // misc
526         bool pit_clock_8mhz;
527         int sound_type;
528         
529 #if defined(_PC98DO) || defined(_PC98DOPLUS)
530         EVENT* pc88event;
531         
532         PC88DEV::PC88* pc88;
533         DEVICE* pc88prn;
534         I8251* pc88sio;
535         I8255* pc88pio;
536         PCM1BIT* pc88pcm;
537         UPD1990A* pc88rtc;
538         YM2203* pc88opn1;
539         Z80* pc88cpu;
540         
541         PC80S31K* pc88sub;
542         I8255* pc88pio_sub;
543         UPD765A* pc88fdc_sub;
544         NOISE* pc88noise_seek;
545         NOISE* pc88noise_head_down;
546         NOISE* pc88noise_head_up;
547         Z80* pc88cpu_sub;
548         
549         int boot_mode;
550 #endif
551         
552         // drives
553         UPD765A *get_floppy_disk_controller(int drv);
554         DISK *get_floppy_disk_handler(int drv);
555         
556 public:
557         // ----------------------------------------
558         // initialize
559         // ----------------------------------------
560         
561         VM(EMU* parent_emu);
562         ~VM();
563         
564         // ----------------------------------------
565         // for emulation class
566         // ----------------------------------------
567         
568         // drive virtual machine
569         void reset();
570         void run();
571         double get_frame_rate();
572         
573 #ifdef USE_DEBUGGER
574         // debugger
575         DEVICE *get_cpu(int index);
576 #endif
577         
578         // draw screen
579         void draw_screen();
580         
581         // sound generation
582         void initialize_sound(int rate, int samples);
583         uint16_t* create_sound(int* extra_frames);
584         int get_sound_buffer_ptr();
585 #ifdef USE_SOUND_VOLUME
586         void set_sound_device_volume(int ch, int decibel_l, int decibel_r);
587 #endif
588         
589         // notify key
590         void key_down(int code, bool repeat);
591         void key_up(int code);
592         bool get_caps_locked();
593         bool get_kana_locked();
594         
595         // user interface
596         void open_floppy_disk(int drv, const _TCHAR* file_path, int bank);
597         void close_floppy_disk(int drv);
598         bool is_floppy_disk_inserted(int drv);
599         void is_floppy_disk_protected(int drv, bool value);
600         bool is_floppy_disk_protected(int drv);
601         uint32_t is_floppy_disk_accessed();
602 #if defined(USE_HARD_DISK)
603         void open_hard_disk(int drv, const _TCHAR* file_path);
604         void close_hard_disk(int drv);
605         bool is_hard_disk_inserted(int drv);
606         uint32_t is_hard_disk_accessed();
607 #endif
608 #if defined(USE_TAPE)
609         void play_tape(int drv, const _TCHAR* file_path);
610         void rec_tape(int drv, const _TCHAR* file_path);
611         void close_tape(int drv);
612         bool is_tape_inserted(int drv);
613 #endif
614         bool is_frame_skippable();
615         
616         void update_config();
617         bool process_state(FILEIO* state_fio, bool loading);
618         
619         // ----------------------------------------
620         // for each device
621         // ----------------------------------------
622         
623         // devices
624         DEVICE* get_device(int id);
625         //DEVICE* dummy;
626         //DEVICE* first_device;
627         //DEVICE* last_device;
628 };
629
630 #endif