OSDN Git Service

[VM][General] Merge upstream 2016-03-01. (Pahse 1).
[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 #define SIG_PC88_USART_OUT      3
25 #define SIG_PC88_DATAREC_MIX    4
26 #define SIG_PC88_DATAREC_VOLUME 5
27
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
42 typedef struct {
43         struct {
44                 int rate, counter;
45                 uint8_t cursor, attrib;
46         } blink;
47         struct {
48                 int type, mode;
49                 int x, y;
50         } cursor;
51         struct {
52                 uint8_t data, mask;
53                 int num;
54                 uint8_t expand[200][80];
55         } attrib;
56         struct {
57                 uint8_t expand[200][80];
58         } text;
59         int width, height;
60         int char_height;
61         bool skip_line;
62         int vretrace;
63         bool timing_changed;
64         uint8_t buffer[120 * 200];
65         int buffer_ptr;
66         uint8_t cmd;
67         int cmd_ptr;
68         uint8_t mode, reverse, intr_mask, status;
69         bool vblank;
70         
71         void reset(bool hireso);
72         void write_cmd(uint8_t data);
73         void write_param(uint8_t data);
74         uint32_t read_param();
75         uint32_t read_status();
76         void start();
77         void finish();
78         void write_buffer(uint8_t data);
79         uint8_t read_buffer(int ofs);
80         void update_blink();
81         void expand_buffer(bool hireso, bool line400);
82         void set_attrib(uint8_t code);
83 } pc88_crtc_t;
84
85 typedef struct {
86         struct {
87                 pair_t addr, count;
88                 uint8_t mode;
89                 int nbytes;
90                 DEVICE *io;
91                 bool running;
92         } ch[4];
93         uint8_t mode, status;
94         bool high_low;
95         DEVICE *mem;
96         
97         void write_io8(uint32_t addr, uint32_t data);
98         uint32_t read_io8(uint32_t addr);
99         void start(int c);
100         void run(int c, int nbytes);
101         void finish(int c);
102 } pc88_dmac_t;
103
104 class PC88 : public DEVICE
105 {
106 private:
107         YM2203 *d_opn;
108 #ifdef SUPPORT_PC88_SB2
109         YM2203 *d_sb2;
110 #endif
111         Z80 *d_cpu;
112         DEVICE *d_pcm, *d_pio, *d_prn, *d_rtc, *d_sio;
113 #ifdef SUPPORT_PC88_PCG8100
114         DEVICE *d_pcg_pit, *d_pcg_pcm0, *d_pcg_pcm1, *d_pcg_pcm2;
115 #endif
116         
117         uint8_t* rbank[16];
118         uint8_t* wbank[16];
119         uint8_t wdmy[0x1000];
120         uint8_t rdmy[0x1000];
121         
122         uint8_t ram[0x10000];
123 #if defined(PC88_EXRAM_BANKS)
124         uint8_t exram[0x8000 * PC88_EXRAM_BANKS];
125 #endif
126         uint8_t gvram[0xc000];
127         uint8_t gvram_null[0x4000];
128         uint8_t tvram[0x1000];
129 #if defined(_PC8001SR)
130         uint8_t n80mk2rom[0x8000];
131         uint8_t n80mk2srrom[0xa000];
132 #else
133         uint8_t n88rom[0x8000];
134         uint8_t n88exrom[0x8000];
135         uint8_t n80rom[0x8000];
136 #endif
137         uint8_t kanji1[0x20000];
138         uint8_t kanji2[0x20000];
139 #ifdef SUPPORT_PC88_DICTIONARY
140         uint8_t dicrom[0x80000];
141 #endif
142         
143         // i/o port
144         uint8_t port[256];
145         
146         pc88_crtc_t crtc;
147         pc88_dmac_t dmac;
148         
149         // memory mapper
150         uint8_t alu_reg[3];
151         uint8_t gvram_plane, gvram_sel;
152         
153         void update_timing();
154         int get_m1_wait(bool addr_f000);
155         int get_main_wait(bool read);
156         int get_tvram_wait(bool read);
157         int get_gvram_wait(bool read);
158         void update_gvram_wait();
159         void update_gvram_sel();
160 #if defined(_PC8001SR)
161         void update_n80_write();
162         void update_n80_read();
163 #else
164         void update_low_memmap();
165         void update_tvram_memmap();
166 #endif
167         
168         // cpu
169         bool cpu_clock_low;
170 #if defined(SUPPORT_PC88_HIGH_CLOCK)
171         bool cpu_clock_high_fe2;
172 #endif
173         bool mem_wait_on;
174         int m1_wait_clocks;
175         int f000_m1_wait_clocks;
176         int mem_wait_clocks_r, mem_wait_clocks_w;
177         int tvram_wait_clocks_r, tvram_wait_clocks_w;
178         int gvram_wait_clocks_r, gvram_wait_clocks_w;
179         int busreq_clocks;
180         
181         // screen
182         struct {
183                 uint8_t b, r, g;
184         } palette[9];
185         bool update_palette;
186         bool hireso;
187         
188         uint8_t sg_pattern[0x800];
189         uint8_t text[200][640];
190         uint8_t graph[400][640];
191         scrntype_t palette_text_pc[9];  // 0 = back color for attrib mode, 8 = black
192         scrntype_t palette_graph_pc[8];
193         
194         void draw_text();
195 #if defined(_PC8001SR)
196         bool draw_320x200_color_graph();
197         bool draw_320x200_4color_graph();
198         void draw_320x200_attrib_graph();
199 #endif
200         bool draw_640x200_color_graph();
201         void draw_640x200_mono_graph();
202 #if defined(_PC8001SR)
203         void draw_640x200_attrib_graph();
204 #else
205         void draw_640x400_attrib_graph();
206 #endif
207         
208         // misc
209         bool usart_dcd;
210         bool opn_busy;
211         
212         // keyboard
213         uint8_t key_status[256];
214         uint8_t key_caps, key_kana;
215         
216 #ifdef SUPPORT_PC88_JOYSTICK
217         // joystick & mouse
218         const uint32_t *joystick_status;
219         const int32_t* mouse_status;
220         uint32_t mouse_strobe_clock;
221         uint32_t mouse_strobe_clock_lim;
222         int mouse_phase;
223         int mouse_dx, mouse_dy;
224         int mouse_lx, mouse_ly;
225 #endif
226         
227         // intterrupt
228         uint8_t intr_req;
229         bool intr_req_sound;
230 #ifdef SUPPORT_PC88_SB2
231         bool intr_req_sb2;
232 #endif
233         uint8_t intr_mask1, intr_mask2;
234         void request_intr(int level, bool status);
235         void update_intr();
236         
237         // data recorder
238         FILEIO *cmt_fio;
239         bool cmt_play, cmt_rec;
240         _TCHAR rec_file_path[_MAX_PATH];
241         int cmt_bufptr, cmt_bufcnt;
242         uint8_t cmt_buffer[CMT_BUFFER_SIZE];
243         int cmt_data_carrier[1024], cmt_data_carrier_cnt;
244         int cmt_register_id;
245         
246         void release_tape();
247         bool check_data_carrier();
248         
249         // beep/sing
250         bool beep_on, beep_signal, sing_signal;
251 #ifdef SUPPORT_PC88_PCG8100
252         // pcg
253         uint16_t pcg_addr;
254         uint8_t pcg_data, pcg_ctrl;
255         uint8_t pcg_pattern[0x800];
256 #endif
257         
258 #ifdef NIPPY_PATCH
259         // dirty patch for NIPPY
260         bool nippy_patch;
261 #endif
262         
263 public:
264         PC88(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {}
265         ~PC88() {}
266         
267         // common functions
268         void initialize();
269         void release();
270         void reset();
271         
272         void write_data8w(uint32_t addr, uint32_t data, int* wait);
273         uint32_t read_data8w(uint32_t addr, int* wait);
274         uint32_t fetch_op(uint32_t addr, int *wait);
275         void write_io8(uint32_t addr, uint32_t data);
276         uint32_t read_io8(uint32_t addr);
277 #ifdef _IO_DEBUG_LOG
278         uint32_t read_io8_debug(uint32_t addr);
279 #endif
280         
281         uint32_t read_dma_data8(uint32_t addr);
282         void write_dma_io8(uint32_t addr, uint32_t data);
283         
284         void write_signal(int id, uint32_t data, uint32_t mask);
285         void event_callback(int event_id, int err);
286         void event_frame();
287         void event_vline(int v, int clock);
288         uint32_t get_intr_ack();
289         void notify_intr_ei();
290         void save_state(FILEIO* state_fio);
291         bool load_state(FILEIO* state_fio);
292         
293         // unique functions
294         bool is_sr_mr()
295         {
296 #if !defined(_PC8001SR)
297                 return (n88rom[0x79d7] < 0x38);
298 #else
299                 return true;
300 #endif
301         }
302         void set_context_cpu(Z80* device)
303         {
304                 d_cpu = device;
305         }
306         void set_context_opn(YM2203* device)
307         {
308                 d_opn = device;
309         }
310 #ifdef SUPPORT_PC88_SB2
311         void set_context_sb2(YM2203* device)
312         {
313                 d_sb2 = device;
314         }
315 #endif
316         void set_context_pcm(DEVICE* device)
317         {
318                 d_pcm = device;
319         }
320         void set_context_pio(DEVICE* device)
321         {
322                 d_pio = device;
323         }
324         void set_context_prn(DEVICE* device)
325         {
326                 d_prn = device;
327         }
328         void set_context_rtc(DEVICE* device)
329         {
330                 d_rtc = device;
331         }
332         void set_context_sio(DEVICE* device)
333         {
334                 d_sio = device;
335         }
336 #ifdef SUPPORT_PC88_PCG8100
337         void set_context_pcg_pit(DEVICE* device)
338         {
339                 d_pcg_pit = device;
340         }
341         void set_context_pcg_pcm0(DEVICE* device)
342         {
343                 d_pcg_pcm0 = device;
344         }
345         void set_context_pcg_pcm1(DEVICE* device)
346         {
347                 d_pcg_pcm1 = device;
348         }
349         void set_context_pcg_pcm2(DEVICE* device)
350         {
351                 d_pcg_pcm2 = device;
352         }
353 #endif
354         void key_down(int code, bool repeat);
355         
356         void play_tape(const _TCHAR* file_path);
357         void rec_tape(const _TCHAR* file_path);
358         void close_tape();
359         bool is_tape_inserted()
360         {
361                 return (cmt_play || cmt_rec);
362         }
363         bool is_frame_skippable();
364         
365         void draw_screen();
366 };
367
368 #endif
369