OSDN Git Service

[VM] Add PC-8001/mk2/8801/mk2.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc8801 / pc88.h
1 /*
2         NEC PC-8001 Emulator 'ePC-8001'
3         NEC PC-8001mkII Emulator 'ePC-8001mkII'
4         NEC PC-8001mkIISR Emulator 'ePC-8001mkIISR'
5         NEC PC-8801 Emulator 'ePC-8801'
6         NEC PC-8801mkII Emulator 'ePC-8801mkII'
7         NEC PC-8801MA Emulator 'ePC-8801MA'
8         NEC PC-98DO Emulator 'ePC-98DO'
9
10         Author : Takeda.Toshiya
11         Date   : 2011.12.29-
12
13         [ PC-8801 ]
14 */
15
16 #ifndef _PC88_H_
17 #define _PC88_H_
18
19 #include "../vm.h"
20 #include "../../emu.h"
21 #include "../device.h"
22
23 #define SIG_PC88_USART_IRQ      0
24 #ifdef SUPPORT_PC88_OPN1
25 #define SIG_PC88_OPN1_IRQ       1
26 #endif
27 #ifdef SUPPORT_PC88_OPN2
28 #define SIG_PC88_OPN2_IRQ       2
29 #endif
30 #ifdef SUPPORT_PC88_CDROM
31 #define SIG_PC88_SCSI_DRQ       3
32 #endif
33 #define SIG_PC88_USART_OUT      4
34
35 #define CMT_BUFFER_SIZE         0x40000
36
37 #if defined(PC8801_VARIANT)
38 #define NIPPY_PATCH
39 #endif
40
41 #if defined(SUPPORT_PC88_OPN1) || defined(SUPPORT_PC88_OPN2)
42 class YM2203;
43 #endif
44 class Z80;
45 #ifdef SUPPORT_PC88_CDROM
46 class SCSI_HOST;
47 class SCSI_CDROM;
48 #endif
49
50 namespace PC88DEV {
51 typedef struct {
52         struct {
53                 int rate, counter;
54                 uint8_t cursor, attrib;
55         } blink;
56         struct {
57                 int type, mode;
58                 int x, y;
59         } cursor;
60         struct {
61                 uint8_t data;
62                 int num;
63                 uint8_t expand[200][80];
64         } attrib;
65         struct {
66                 uint8_t expand[200][80];
67         } text;
68         int width, height;
69         int char_height;
70         bool skip_line;
71         int vretrace;
72         bool timing_changed;
73         uint8_t buffer[120 * 200];
74         int buffer_ptr;
75         uint8_t cmd;
76         int cmd_ptr;
77         uint8_t mode, reverse, intr_mask, status;
78         bool vblank;
79         
80         void reset(bool hireso);
81         void write_cmd(uint8_t data);
82         void write_param(uint8_t data);
83         uint32_t read_param();
84         uint32_t read_status();
85         void start();
86         void finish();
87         void write_buffer(uint8_t data);
88         uint8_t read_buffer(int ofs);
89         void update_blink();
90         void expand_buffer(bool hireso, bool line400);
91         void set_attrib(uint8_t code);
92 } pc88_crtc_t;
93
94 typedef struct {
95         struct {
96                 pair32_t addr, count;
97                 uint8_t mode;
98                 int nbytes;
99                 DEVICE *io;
100                 bool running;
101         } ch[4];
102         uint8_t mode, status;
103         bool high_low;
104         DEVICE *mem;
105         
106         void write_io8(uint32_t addr, uint32_t data);
107         uint32_t read_io8(uint32_t addr);
108         void start(int c);
109         void run(int c, int nbytes);
110         void finish(int c);
111 } pc88_dmac_t;
112
113 class PC88 : public DEVICE
114 {
115 private:
116 #ifdef SUPPORT_PC88_OPN1
117         YM2203 *d_opn1;
118 #endif
119 #ifdef SUPPORT_PC88_OPN2
120         YM2203 *d_opn2;
121 #endif
122         Z80 *d_cpu;
123         DEVICE *d_pcm, *d_pio, *d_prn, *d_rtc, *d_sio;
124 #ifdef SUPPORT_PC88_CDROM
125         SCSI_HOST* d_scsi_host;
126         SCSI_CDROM* d_scsi_cdrom;
127 #endif
128 #ifdef SUPPORT_PC88_HMB20
129         DEVICE *d_opm;
130 #endif
131 #ifdef SUPPORT_PC88_PCG8100
132         DEVICE *d_pcg_pit, *d_pcg_pcm0, *d_pcg_pcm1, *d_pcg_pcm2;
133 #endif
134         
135         uint8_t* rbank[16];
136         uint8_t* wbank[16];
137         uint8_t wdmy[0x1000];
138         uint8_t rdmy[0x1000];
139         
140         uint8_t ram[0x10000];
141 #if defined(PC88_EXRAM_BANKS)
142         uint8_t exram[0x8000 * PC88_EXRAM_BANKS];
143 #endif
144         uint8_t gvram[0xc000];
145         uint8_t gvram_null[0x4000];
146 #if defined(PC8801SR_VARIANT)
147         uint8_t tvram[0x1000];
148 #endif
149 #if defined(PC8001_VARIANT)
150         uint8_t n80rom[0x8000];
151 #if defined(_PC8001SR)
152         uint8_t n80srrom[0xa000];
153 #endif
154 #else
155         uint8_t n88rom[0x8000];
156         uint8_t n88exrom[0x8000];
157         uint8_t n80rom[0x8000];
158 #endif
159 //#ifdef SUPPORT_PC88_KANJI1
160         uint8_t kanji1[0x20000];
161 //#endif
162 #ifdef SUPPORT_PC88_KANJI2
163         uint8_t kanji2[0x20000];
164 #endif
165 #ifdef SUPPORT_PC88_DICTIONARY
166         uint8_t dicrom[0x80000];
167 #endif
168 #ifdef SUPPORT_PC88_CDROM
169         uint8_t cdbios[0x10000];
170         bool cdbios_loaded;
171 #endif
172         
173         // i/o port
174         uint8_t port[256];
175         
176         pc88_crtc_t crtc;
177         pc88_dmac_t dmac;
178         
179         // memory mapper
180 #if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
181         uint8_t alu_reg[3];
182 #endif
183         uint8_t gvram_plane, gvram_sel;
184         
185         void update_timing();
186         int get_m1_wait(bool addr_f000);
187         int get_main_wait(bool read);
188 #if defined(PC8801SR_VARIANT)
189         int get_tvram_wait(bool read);
190 #endif
191         int get_gvram_wait(bool read);
192         void update_gvram_wait();
193         void update_gvram_sel();
194 #if defined(PC8001_VARIANT)
195         void update_n80_write();
196         void update_n80_read();
197 #else
198         void update_low_write();
199         void update_low_read();
200 #if defined(PC8801SR_VARIANT)
201         void update_tvram_memmap();
202 #endif
203 #endif
204         
205         // cpu
206         bool cpu_clock_low;
207 #if defined(SUPPORT_PC88_HIGH_CLOCK)
208         bool cpu_clock_high_fe2;
209 #endif
210         bool mem_wait_on;
211         int m1_wait_clocks;
212         int f000_m1_wait_clocks;
213         int mem_wait_clocks_r, mem_wait_clocks_w;
214 #if defined(PC8801SR_VARIANT)
215         int tvram_wait_clocks_r, tvram_wait_clocks_w;
216 #endif
217         int gvram_wait_clocks_r, gvram_wait_clocks_w;
218         int busreq_clocks;
219         
220         // screen
221         typedef struct palette_s {
222                 uint8_t b, r, g;
223         } palette_t;
224         palette_t palette[10]; // 8 = digital back color, 9 = analog back color
225         bool update_palette;
226         bool hireso;
227         
228         uint8_t sg_pattern[0x800];
229         uint8_t text[200][640];
230         uint8_t text_color[200][80];
231         bool text_reverse[200][80];
232         uint8_t graph[400][640];
233         
234         palette_t palette_digital[9];
235         palette_t palette_analog [9];
236         palette_t palette_line_digital[400][9];
237         palette_t palette_line_analog [400][9];
238         bool palette_line_changed[400];
239 #if defined(SUPPORT_PC88_VAB)
240         scrntype_t palette_vab_pc[0x10000];
241 #endif
242         
243         void draw_text();
244 #if defined(PC8001_VARIANT)
245 #if defined(_PC8001SR)
246         bool draw_320x200_color_graph();
247 #endif
248         bool draw_320x200_4color_graph();
249         void draw_320x200_attrib_graph();
250 #endif
251         bool draw_640x200_color_graph();
252         void draw_640x200_mono_graph();
253         void draw_640x200_attrib_graph();
254 #if defined(PC8801SR_VARIANT)
255         void draw_640x400_mono_graph();
256         void draw_640x400_attrib_graph();
257 #endif
258         
259         // misc
260         bool usart_dcd;
261         bool opn_busy;
262         
263         // keyboard
264         uint8_t key_status[256];
265         uint8_t key_caps, key_kana;
266         
267 #ifdef SUPPORT_PC88_JOYSTICK
268         // joystick & mouse
269         const uint32_t *joystick_status;
270         const int32_t* mouse_status;
271         uint32_t mouse_strobe_clock;
272         uint32_t mouse_strobe_clock_lim;
273         int mouse_phase;
274         int mouse_dx, mouse_dy;
275         int mouse_lx, mouse_ly;
276 #endif
277         
278         // intterrupt
279         uint8_t intr_req;
280 #ifdef SUPPORT_PC88_OPN1
281         bool intr_req_opn1;
282 #endif
283 #ifdef SUPPORT_PC88_OPN2
284         bool intr_req_opn2;
285 #endif
286         uint8_t intr_mask1, intr_mask2;
287         void request_intr(int level, bool status);
288         void update_intr();
289         
290         // data recorder
291         FILEIO *cmt_fio;
292         bool cmt_play, cmt_rec;
293         _TCHAR rec_file_path[_MAX_PATH];
294         int cmt_bufptr, cmt_bufcnt;
295         uint8_t cmt_buffer[CMT_BUFFER_SIZE];
296         int cmt_data_carrier[1024], cmt_data_carrier_cnt;
297         int cmt_register_id;
298         
299         void release_tape();
300         bool check_data_carrier();
301         
302         // beep/sing
303         bool beep_on, beep_signal, sing_signal;
304         
305 #ifdef SUPPORT_PC88_PCG8100
306         // pcg
307         uint16_t pcg_addr;
308         uint8_t pcg_data, pcg_ctrl;
309         uint8_t pcg_pattern[0x800];
310 #endif
311         
312 #ifdef SUPPORT_PC88_CDROM
313         int cdda_register_id;
314         double cdda_volume;
315 #endif
316         
317 #ifdef NIPPY_PATCH
318         // dirty patch for NIPPY
319         bool nippy_patch;
320 #endif
321 public:
322         PC88(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
323         {
324 #if defined(PC8001_VARIANT)
325                 set_device_name(_T("PC-8001 Core"));
326 #else
327                 set_device_name(_T("PC-8801 Core"));
328 #endif
329         }
330         ~PC88() {}
331         
332         // common functions
333         void initialize();
334         void release();
335         void reset();
336         
337         void write_data8w(uint32_t addr, uint32_t data, int* wait);
338         uint32_t read_data8w(uint32_t addr, int* wait);
339         uint32_t fetch_op(uint32_t addr, int *wait);
340         void write_io8(uint32_t addr, uint32_t data);
341         uint32_t read_io8(uint32_t addr);
342 #ifdef _IO_DEBUG_LOG
343         uint32_t read_io8_debug(uint32_t addr);
344 #endif
345         
346         uint32_t read_dma_data8(uint32_t addr);
347         void write_dma_data8(uint32_t addr, uint32_t data);
348         void write_dma_io8(uint32_t addr, uint32_t data);
349         
350         void write_signal(int id, uint32_t data, uint32_t mask);
351         void event_callback(int event_id, int err);
352         void event_frame();
353         void event_vline(int v, int clock);
354         uint32_t get_intr_ack();
355         void notify_intr_ei();
356         bool process_state(FILEIO* state_fio, bool loading);
357         
358         // unique functions
359 #ifdef PC8801SR_VARIANT
360         bool is_sr_mr()
361         {
362                 return (n88rom[0x79d7] < 0x38);
363         }
364 #endif
365         void set_context_cpu(Z80* device)
366         {
367                 d_cpu = device;
368         }
369 #ifdef SUPPORT_PC88_OPN1
370         void set_context_opn1(YM2203* device)
371         {
372                 d_opn1 = device;
373         }
374 #endif
375 #ifdef SUPPORT_PC88_OPN2
376         void set_context_opn2(YM2203* device)
377         {
378                 d_opn2 = device;
379         }
380 #endif
381         void set_context_pcm(DEVICE* device)
382         {
383                 d_pcm = device;
384         }
385         void set_context_pio(DEVICE* device)
386         {
387                 d_pio = device;
388         }
389         void set_context_prn(DEVICE* device)
390         {
391                 d_prn = device;
392         }
393         void set_context_rtc(DEVICE* device)
394         {
395                 d_rtc = device;
396         }
397         void set_context_sio(DEVICE* device)
398         {
399                 d_sio = device;
400         }
401 #ifdef SUPPORT_PC88_CDROM
402         void set_context_scsi_host(SCSI_HOST* device)
403         {
404                 d_scsi_host = device;
405         }
406         void set_context_scsi_cdrom(SCSI_CDROM* device)
407         {
408                 d_scsi_cdrom = device;
409         }
410 #endif
411 #ifdef SUPPORT_PC88_HMB20
412         void set_context_opm(DEVICE* device)
413         {
414                 d_opm = device;
415         }
416 #endif
417 #ifdef SUPPORT_PC88_PCG8100
418         void set_context_pcg_pit(DEVICE* device)
419         {
420                 d_pcg_pit = device;
421         }
422         void set_context_pcg_pcm0(DEVICE* device)
423         {
424                 d_pcg_pcm0 = device;
425         }
426         void set_context_pcg_pcm1(DEVICE* device)
427         {
428                 d_pcg_pcm1 = device;
429         }
430         void set_context_pcg_pcm2(DEVICE* device)
431         {
432                 d_pcg_pcm2 = device;
433         }
434 #endif
435         void key_down(int code, bool repeat);
436         bool get_caps_locked()
437         {
438                 return (key_caps != 0);
439         }
440         bool get_kana_locked()
441         {
442                 return (key_kana != 0);
443         }
444         
445         void play_tape(const _TCHAR* file_path);
446         void rec_tape(const _TCHAR* file_path);
447         void close_tape();
448         bool is_tape_inserted()
449         {
450                 return (cmt_play || cmt_rec);
451         }
452         bool is_frame_skippable();
453         
454         void draw_screen();
455 };
456
457 }
458 #endif
459