OSDN Git Service

[VM][WIP] Use namespace to devices per VMs.
[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 namespace PC88DEV {
40 typedef struct {
41         struct {
42                 int rate, counter;
43                 uint8_t cursor, attrib;
44         } blink;
45         struct {
46                 int type, mode;
47                 int x, y;
48         } cursor;
49         struct {
50                 uint8_t data;
51                 int num;
52                 uint8_t expand[200][80];
53         } attrib;
54         struct {
55                 uint8_t expand[200][80];
56         } text;
57         int width, height;
58         int char_height;
59         bool skip_line;
60         int vretrace;
61         bool timing_changed;
62         uint8_t buffer[120 * 200];
63         int buffer_ptr;
64         uint8_t cmd;
65         int cmd_ptr;
66         uint8_t mode, reverse, intr_mask, status;
67         bool vblank;
68         
69         void reset(bool hireso);
70         void write_cmd(uint8_t data);
71         void write_param(uint8_t data);
72         uint32_t read_param();
73         uint32_t read_status();
74         void start();
75         void finish();
76         void write_buffer(uint8_t data);
77         uint8_t read_buffer(int ofs);
78         void update_blink();
79         void expand_buffer(bool hireso, bool line400);
80         void set_attrib(uint8_t code);
81 } pc88_crtc_t;
82
83 typedef struct {
84         struct {
85                 pair_t addr, count;
86                 uint8_t mode;
87                 int nbytes;
88                 DEVICE *io;
89                 bool running;
90         } ch[4];
91         uint8_t mode, status;
92         bool high_low;
93         DEVICE *mem;
94         
95         void write_io8(uint32_t addr, uint32_t data);
96         uint32_t read_io8(uint32_t addr);
97         void start(int c);
98         void run(int c, int nbytes);
99         void finish(int c);
100 } pc88_dmac_t;
101
102 class PC88 : public DEVICE
103 {
104 private:
105         YM2203 *d_opn;
106 #ifdef SUPPORT_PC88_SB2
107         YM2203 *d_sb2;
108 #endif
109         Z80 *d_cpu;
110         DEVICE *d_pcm, *d_pio, *d_prn, *d_rtc, *d_sio;
111 #ifdef SUPPORT_PC88_PCG8100
112         DEVICE *d_pcg_pit, *d_pcg_pcm0, *d_pcg_pcm1, *d_pcg_pcm2;
113 #endif
114         
115         uint8_t* rbank[16];
116         uint8_t* wbank[16];
117         uint8_t wdmy[0x1000];
118         uint8_t rdmy[0x1000];
119         
120         uint8_t ram[0x10000];
121 #if defined(PC88_EXRAM_BANKS)
122         uint8_t exram[0x8000 * PC88_EXRAM_BANKS];
123 #endif
124         uint8_t gvram[0xc000];
125         uint8_t gvram_null[0x4000];
126         uint8_t tvram[0x1000];
127 #if defined(_PC8001SR)
128         uint8_t n80mk2rom[0x8000];
129         uint8_t n80mk2srrom[0xa000];
130 #else
131         uint8_t n88rom[0x8000];
132         uint8_t n88exrom[0x8000];
133         uint8_t n80rom[0x8000];
134 #endif
135         uint8_t kanji1[0x20000];
136         uint8_t kanji2[0x20000];
137 #ifdef SUPPORT_PC88_DICTIONARY
138         uint8_t dicrom[0x80000];
139 #endif
140         
141         // i/o port
142         uint8_t port[256];
143         
144         pc88_crtc_t crtc;
145         pc88_dmac_t dmac;
146         
147         // memory mapper
148         uint8_t alu_reg[3];
149         uint8_t gvram_plane, gvram_sel;
150         
151         void update_timing();
152         int get_m1_wait(bool addr_f000);
153         int get_main_wait(bool read);
154         int get_tvram_wait(bool read);
155         int get_gvram_wait(bool read);
156         void update_gvram_wait();
157         void update_gvram_sel();
158 #if defined(_PC8001SR)
159         void update_n80_write();
160         void update_n80_read();
161 #else
162         void update_low_memmap();
163         void update_tvram_memmap();
164 #endif
165         
166         // cpu
167         bool cpu_clock_low;
168 #if defined(SUPPORT_PC88_HIGH_CLOCK)
169         bool cpu_clock_high_fe2;
170 #endif
171         bool mem_wait_on;
172         int m1_wait_clocks;
173         int f000_m1_wait_clocks;
174         int mem_wait_clocks_r, mem_wait_clocks_w;
175         int tvram_wait_clocks_r, tvram_wait_clocks_w;
176         int gvram_wait_clocks_r, gvram_wait_clocks_w;
177         int busreq_clocks;
178         
179         // screen
180         struct {
181                 uint8_t b, r, g;
182         } palette[9];
183         bool update_palette;
184         bool hireso;
185         
186         uint8_t sg_pattern[0x800];
187         uint8_t text[200][640];
188         uint8_t text_color[200][80];
189         bool text_reverse[200][80];
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[9];
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         void draw_640x200_attrib_graph();
203 #if !defined(_PC8001SR)
204         void draw_640x400_mono_graph();
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         
252 #ifdef SUPPORT_PC88_PCG8100
253         // pcg
254         uint16_t pcg_addr;
255         uint8_t pcg_data, pcg_ctrl;
256         uint8_t pcg_pattern[0x800];
257 #endif
258         
259 #ifdef NIPPY_PATCH
260         // dirty patch for NIPPY
261         bool nippy_patch;
262 #endif
263 public:
264         PC88(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
265         {
266 #if defined(_PC8001SR)
267                 set_device_name(_T("PC-8001 Core"));
268 #else
269                 set_device_name(_T("PC-8801 Core"));
270 #endif
271         }
272         ~PC88() {}
273         
274         // common functions
275         void initialize();
276         void release();
277         void reset();
278         
279         void write_data8w(uint32_t addr, uint32_t data, int* wait);
280         uint32_t read_data8w(uint32_t addr, int* wait);
281         uint32_t fetch_op(uint32_t addr, int *wait);
282         void write_io8(uint32_t addr, uint32_t data);
283         uint32_t read_io8(uint32_t addr);
284 #ifdef _IO_DEBUG_LOG
285         uint32_t read_io8_debug(uint32_t addr);
286 #endif
287         
288         uint32_t read_dma_data8(uint32_t addr);
289         void write_dma_io8(uint32_t addr, uint32_t data);
290         
291         void write_signal(int id, uint32_t data, uint32_t mask);
292         void event_callback(int event_id, int err);
293         void event_frame();
294         void event_vline(int v, int clock);
295         uint32_t get_intr_ack();
296         void notify_intr_ei();
297         bool process_state(FILEIO* state_fio, bool loading);
298         
299         // unique functions
300         bool is_sr_mr()
301         {
302 #if !defined(_PC8001SR)
303                 return (n88rom[0x79d7] < 0x38);
304 #else
305                 return true;
306 #endif
307         }
308         void set_context_cpu(Z80* device)
309         {
310                 d_cpu = device;
311         }
312         void set_context_opn(YM2203* device)
313         {
314                 d_opn = device;
315         }
316 #ifdef SUPPORT_PC88_SB2
317         void set_context_sb2(YM2203* device)
318         {
319                 d_sb2 = device;
320         }
321 #endif
322         void set_context_pcm(DEVICE* device)
323         {
324                 d_pcm = device;
325         }
326         void set_context_pio(DEVICE* device)
327         {
328                 d_pio = device;
329         }
330         void set_context_prn(DEVICE* device)
331         {
332                 d_prn = device;
333         }
334         void set_context_rtc(DEVICE* device)
335         {
336                 d_rtc = device;
337         }
338         void set_context_sio(DEVICE* device)
339         {
340                 d_sio = device;
341         }
342 #ifdef SUPPORT_PC88_PCG8100
343         void set_context_pcg_pit(DEVICE* device)
344         {
345                 d_pcg_pit = device;
346         }
347         void set_context_pcg_pcm0(DEVICE* device)
348         {
349                 d_pcg_pcm0 = device;
350         }
351         void set_context_pcg_pcm1(DEVICE* device)
352         {
353                 d_pcg_pcm1 = device;
354         }
355         void set_context_pcg_pcm2(DEVICE* device)
356         {
357                 d_pcg_pcm2 = device;
358         }
359 #endif
360         void key_down(int code, bool repeat);
361         bool get_caps_locked()
362         {
363                 return (key_caps != 0);
364         }
365         bool get_kana_locked()
366         {
367                 return (key_kana != 0);
368         }
369         
370         void play_tape(const _TCHAR* file_path);
371         void rec_tape(const _TCHAR* file_path);
372         void close_tape();
373         bool is_tape_inserted()
374         {
375                 return (cmt_play || cmt_rec);
376         }
377         bool is_frame_skippable();
378         
379         void draw_screen();
380 };
381
382 }
383 #endif
384