OSDN Git Service

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