OSDN Git Service

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