OSDN Git Service

[VM][PC9801][DISPLAY] EGC: Add write protect register (03h).
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / display.h
1 /*
2         NEC PC-9801 Emulator 'ePC-9801'
3         NEC PC-9801E/F/M Emulator 'ePC-9801E'
4         NEC PC-9801U Emulator 'ePC-9801U'
5         NEC PC-9801VF Emulator 'ePC-9801VF'
6         NEC PC-9801VM Emulator 'ePC-9801VM'
7         NEC PC-9801VX Emulator 'ePC-9801VX'
8         NEC PC-9801RA Emulator 'ePC-9801RA'
9         NEC PC-98XA Emulator 'ePC-98XA'
10         NEC PC-98XL Emulator 'ePC-98XL'
11         NEC PC-98RL Emulator 'ePC-98RL'
12         NEC PC-98DO Emulator 'ePC-98DO'
13
14         Author : Takeda.Toshiya
15         Date   : 2010.09.16-
16
17         [ display ]
18 */
19
20 #ifndef _DISPLAY_H_
21 #define _DISPLAY_H_
22
23 #include "../vm.h"
24 #include "../../emu.h"
25 #include "../device.h"
26
27 #define SIG_DISPLAY98_SET_PAGE_80 1
28 #define SIG_DISPLAY98_SET_PAGE_A0 2
29 #define SIG_DISPLAY98_SET_BANK    3
30
31 class UPD7220;
32
33 namespace PC9801 {
34
35 class DISPLAY : public DEVICE
36 {
37 private:
38         DEVICE *d_pic;
39         DEVICE *d_pio_sys;
40         DEVICE *d_pio_prn;
41         outputs_t output_gdc_freq;
42         
43         UPD7220 *d_gdc_chr, *d_gdc_gfx;
44         uint8_t *ra_chr;
45         uint8_t *ra_gfx, *cs_gfx;
46         
47         uint8_t tvram[0x4000];
48         uint32_t vram_bank;
49 #if !defined(SUPPORT_HIRESO)
50 #if defined(SUPPORT_2ND_VRAM)
51         __DECL_ALIGNED(4) uint8_t vram[0x40000];
52 #else
53         __DECL_ALIGNED(4) uint8_t vram[0x20000];
54 #endif
55 #else
56         __DECL_ALIGNED(4) uint8_t vram[0x80000];
57 #endif
58         
59 #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
60         uint8_t vram_disp_sel;
61         uint8_t vram_draw_sel;
62 #endif
63         uint8_t *vram_disp_b;
64         uint8_t *vram_disp_r;
65         uint8_t *vram_disp_g;
66 #if defined(SUPPORT_16_COLORS)
67         uint8_t *vram_disp_e;
68 #endif
69         uint8_t *vram_draw;
70         
71         scrntype_t palette_chr[8];
72         scrntype_t palette_gfx8[8];
73         uint8_t digipal[4];
74 #if defined(SUPPORT_16_COLORS)
75         scrntype_t palette_gfx16[16];
76         uint8_t anapal[16][3], anapal_sel;
77 #endif
78         
79         uint8_t crtv;
80         uint8_t scroll[6];
81         uint8_t modereg1[8];
82         uint8_t border; // ToDo; OVER SCAN.
83 #if defined(SUPPORT_16_COLORS)
84         uint8_t modereg2[128];
85         bool is_use_egc;
86         bool enable_egc;
87 #endif
88 #if defined(SUPPORT_GRCG)
89         uint8_t grcg_mode, grcg_tile_ptr, grcg_tile[4];
90         __DECL_ALIGNED(8) uint16_t grcg_tile_word[4];
91         __DECL_ALIGNED(8) bool grcg_plane_enabled[4];
92         bool grcg_cg_mode, grcg_rw_mode;
93 #endif
94 #if defined(SUPPORT_EGC)
95         typedef union {
96                 uint8_t b[2];
97                 uint16_t w;
98         } egcword_t;
99         typedef union {
100                 uint8_t b[4][2];
101                 uint16_t w[4];
102                 uint32_t d[2];
103                 uint64_t q;
104         } egcquad_t;
105         
106         uint16_t egc_access;
107         uint16_t egc_fgbg;
108         uint16_t egc_ope;
109         uint16_t egc_fg;
110         __DECL_ALIGNED(16) egcword_t egc_mask;
111         uint16_t egc_bg;
112         uint16_t egc_sft;
113         uint16_t egc_leng;
114         __DECL_ALIGNED(16) egcquad_t egc_lastvram;
115         __DECL_ALIGNED(16) egcquad_t egc_patreg;
116         __DECL_ALIGNED(16) egcquad_t egc_fgc;
117         __DECL_ALIGNED(16) egcquad_t egc_bgc;
118         int egc_func;
119         uint32_t egc_remain;
120         uint32_t egc_stack;
121         uint8_t* egc_inptr;
122         uint8_t* egc_outptr;
123
124         int tmp_inptr_ofs;
125         int tmp_outptr_ofs;
126         
127         __DECL_ALIGNED(16) egcword_t egc_mask2;
128         __DECL_ALIGNED(16) egcword_t egc_srcmask;
129         uint8_t egc_srcbit;
130         uint8_t egc_dstbit;
131         uint8_t egc_sft8bitl;
132         uint8_t egc_sft8bitr;
133         __DECL_ALIGNED(16) uint8_t egc_buf[528];        /* 4096/8 + 4*4 */
134         __DECL_ALIGNED(16) egcquad_t egc_vram_src;
135         __DECL_ALIGNED(16) egcquad_t egc_vram_data;
136
137         __DECL_ALIGNED(16) static const uint8_t  egc_bytemask_u0[64];
138         __DECL_ALIGNED(16) static const uint8_t  egc_bytemask_u1[8];
139         __DECL_ALIGNED(16) static const uint8_t  egc_bytemask_d0[64];
140         __DECL_ALIGNED(16) static const uint8_t  egc_bytemask_d1[8];
141         __DECL_ALIGNED(16) static const uint16_t egc_maskword[16][4];
142 #endif
143         
144 #if !defined(SUPPORT_HIRESO)
145         #define FONT_SIZE       16
146         #define FONT_WIDTH      8
147         #define FONT_HEIGHT     16
148 #else
149         #define FONT_SIZE       48
150         #define FONT_WIDTH      14
151         #define FONT_HEIGHT     24
152 #endif
153         #define KANJI_2ND_OFS   (FONT_SIZE * 0x80)
154         #define KANJI_FONT_SIZE (FONT_SIZE * 2)
155         #define ANK_FONT_OFS    (KANJI_FONT_SIZE * 0x4000)
156         
157         uint8_t font[ANK_FONT_OFS + FONT_SIZE * 0x400];
158         uint16_t font_code;
159         uint8_t font_line;
160 //      uint16_t font_lr;
161         bool b_gfx_ff;
162         
163         uint8_t screen_chr[SCREEN_HEIGHT][SCREEN_WIDTH + 1];
164         uint8_t screen_gfx[SCREEN_HEIGHT][SCREEN_WIDTH];
165
166         uint32_t bank_table[0x10];
167
168         
169 #if !defined(SUPPORT_HIRESO)
170         void kanji_copy(uint8_t *dst, uint8_t *src, int from, int to);
171 #else
172         void ank_copy(int code, uint8_t *pattern);
173         void kanji_copy(int first, int second, uint8_t *pattern);
174 #endif
175 #if defined(SUPPORT_GRCG)
176         void grcg_writeb(uint32_t addr1, uint32_t data);
177         void grcg_writew(uint32_t addr1, uint32_t data);
178         uint32_t grcg_readb(uint32_t addr1);
179         uint32_t grcg_readw(uint32_t addr1);
180 #endif
181 #if defined(SUPPORT_EGC)
182         inline void egc_shift();
183         inline void egc_sftb_upn_sub(uint32_t ext);
184         inline void egc_sftb_dnn_sub(uint32_t ext);
185         inline void egc_sftb_upr_sub(uint32_t ext);
186         inline void egc_sftb_dnr_sub(uint32_t ext);
187         inline void egc_sftb_upl_sub(uint32_t ext);
188         inline void egc_sftb_dnl_sub(uint32_t ext);
189         void egc_sftb_upn0(uint32_t ext);
190         void egc_sftw_upn0();
191         void egc_sftb_dnn0(uint32_t ext);
192         void egc_sftw_dnn0();
193         void egc_sftb_upr0(uint32_t ext);
194         void egc_sftw_upr0();
195         void egc_sftb_dnr0(uint32_t ext);
196         void egc_sftw_dnr0();
197         void egc_sftb_upl0(uint32_t ext);
198         void egc_sftw_upl0();
199         void egc_sftb_dnl0(uint32_t ext);
200         void egc_sftw_dnl0();
201         void egc_sftb(int func, uint32_t ext);
202         void egc_sftw(int func);
203         void egc_shiftinput_byte(uint32_t ext);
204         void egc_shiftinput_incw();
205         void egc_shiftinput_decw();
206         uint64_t egc_ope_00(uint8_t ope, uint32_t addr);
207         uint64_t egc_ope_0f(uint8_t ope, uint32_t addr);
208         uint64_t egc_ope_c0(uint8_t ope, uint32_t addr);
209         uint64_t egc_ope_f0(uint8_t ope, uint32_t addr);
210         uint64_t egc_ope_fc(uint8_t ope, uint32_t addr);
211         uint64_t egc_ope_ff(uint8_t ope, uint32_t addr);
212         uint64_t egc_ope_nd(uint8_t ope, uint32_t addr);
213         uint64_t egc_ope_np(uint8_t ope, uint32_t addr);
214         uint64_t egc_ope_xx(uint8_t ope, uint32_t addr);
215         uint64_t egc_opefn(uint32_t func, uint8_t ope, uint32_t addr);
216         uint64_t egc_opeb(uint32_t addr, uint8_t value);
217         uint64_t egc_opew(uint32_t addr, uint16_t value);
218         uint32_t egc_readb(uint32_t addr1);
219         uint32_t egc_readw(uint32_t addr1);
220         void egc_writeb(uint32_t addr1, uint8_t value);
221         void egc_writew(uint32_t addr1, uint16_t value);
222 #endif
223         void draw_chr_screen();
224         void draw_gfx_screen();
225         void init_memsw();
226         void save_memsw();
227 public:
228         DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
229         {
230                 initialize_output_signals(&output_gdc_freq);
231                 memset(tvram, 0, sizeof(tvram));
232                 set_device_name(_T("Display"));
233         }
234         ~DISPLAY() {}
235         
236         // common functions
237         void initialize();
238         void release();
239         void reset();
240         void event_frame();
241         void write_io8(uint32_t addr, uint32_t data);
242         uint32_t read_io8(uint32_t addr);
243         void write_memory_mapped_io8(uint32_t addr, uint32_t data);
244         void write_memory_mapped_io16(uint32_t addr, uint32_t data);
245         uint32_t read_memory_mapped_io8(uint32_t addr);
246         uint32_t read_memory_mapped_io16(uint32_t addr);
247         void write_dma_io8(uint32_t addr, uint32_t data);
248         void write_dma_io16(uint32_t addr, uint32_t data);
249         uint32_t read_dma_io8(uint32_t addr);
250         uint32_t read_dma_io16(uint32_t addr);
251         void write_signal(int ch, uint32_t data, uint32_t mask);
252         bool process_state(FILEIO* state_fio, bool loading);
253         
254         // unique functions
255         void set_context_pic(DEVICE *device)
256         {
257                 d_pic = device;
258         }
259         void set_context_gdc_chr(UPD7220 *device, uint8_t *ra)
260         {
261                 d_gdc_chr = device;
262                 ra_chr = ra;
263         }
264         void set_context_gdc_freq(DEVICE *device, int id, int mask)
265         {
266                 register_output_signal(&output_gdc_freq, device, id, mask);
267         }
268         void set_context_gdc_gfx(UPD7220 *device, uint8_t *ra, uint8_t *cs)
269         {
270                 d_gdc_gfx = device;
271                 ra_gfx = ra; cs_gfx = cs;
272         }
273         void set_context_pio_sys(DEVICE* device)
274         {
275                 d_pio_sys = device;
276         }
277         void set_context_pio_prn(DEVICE* device)
278         {
279                 d_pio_prn = device;
280         }
281         void sound_bios_ok()
282         {
283                 tvram[0x3fee] = 8;
284         }
285         void draw_screen();
286 };
287
288 #if defined(SUPPORT_EGC)
289
290 inline void DISPLAY::egc_shift()
291 {
292         uint8_t src8, dst8;
293         
294         egc_remain = (egc_leng & 0xfff) + 1;
295         egc_func = (egc_sft >> 12) & 1;
296         if(!egc_func) {
297                 egc_inptr = egc_buf;
298                 egc_outptr = egc_buf;
299         } else {
300                 egc_inptr = egc_buf + 4096 / 8 + 3;
301                 egc_outptr = egc_buf + 4096 / 8 + 3;
302         }
303         egc_srcbit = egc_sft & 0x0f;
304         egc_dstbit = (egc_sft >> 4) & 0x0f;
305         
306         src8 = egc_srcbit & 0x07;
307         dst8 = egc_dstbit & 0x07;
308         if(src8 < dst8) {
309                 egc_func += 2;
310                 egc_sft8bitr = dst8 - src8;
311                 egc_sft8bitl = 8 - egc_sft8bitr;
312         }
313         else if(src8 > dst8) {
314                 egc_func += 4;
315                 egc_sft8bitl = src8 - dst8;
316                 egc_sft8bitr = 8 - egc_sft8bitl;
317         }
318         egc_stack = 0;
319 }
320
321 inline void DISPLAY::egc_sftb_upn_sub(uint32_t ext)
322 {
323         if(egc_dstbit >= 8) {
324                 egc_dstbit -= 8;
325                 egc_srcmask.b[ext] = 0;
326                 return;
327         }
328         if(egc_dstbit) {
329                 if((egc_dstbit + egc_remain) >= 8) {
330                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (7 * 8)];
331                         egc_remain -= (8 - egc_dstbit);
332                         egc_dstbit = 0;
333                 } else {
334                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (egc_remain - 1) * 8];
335                         egc_remain = 0;
336                         egc_dstbit = 0;
337                 }
338         } else {
339                 if(egc_remain >= 8) {
340                         egc_remain -= 8;
341                 } else {
342                         egc_srcmask.b[ext] = egc_bytemask_u1[egc_remain - 1];
343                         egc_remain = 0;
344                 }
345         }
346         egc_vram_src.b[0][ext] = egc_outptr[0];
347         egc_vram_src.b[1][ext] = egc_outptr[4];
348         egc_vram_src.b[2][ext] = egc_outptr[8];
349         egc_vram_src.b[3][ext] = egc_outptr[12];
350         egc_outptr++;
351 }
352
353 inline void DISPLAY::egc_sftb_dnn_sub(uint32_t ext)
354 {
355         if(egc_dstbit >= 8) {
356                 egc_dstbit -= 8;
357                 egc_srcmask.b[ext] = 0;
358                 return;
359         }
360         if(egc_dstbit) {
361                 if((egc_dstbit + egc_remain) >= 8) {
362                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (7 * 8)];
363                         egc_remain -= (8 - egc_dstbit);
364                         egc_dstbit = 0;
365                 } else {
366                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (egc_remain - 1) * 8];
367                         egc_remain = 0;
368                         egc_dstbit = 0;
369                 }
370         } else {
371                 if(egc_remain >= 8) {
372                         egc_remain -= 8;
373                 } else {
374                         egc_srcmask.b[ext] = egc_bytemask_d1[egc_remain - 1];
375                         egc_remain = 0;
376                 }
377         }
378         egc_vram_src.b[0][ext] = egc_outptr[0];
379         egc_vram_src.b[1][ext] = egc_outptr[4];
380         egc_vram_src.b[2][ext] = egc_outptr[8];
381         egc_vram_src.b[3][ext] = egc_outptr[12];
382         egc_outptr--;
383 }
384
385 inline void DISPLAY::egc_sftb_upr_sub(uint32_t ext)
386 {
387         if(egc_dstbit >= 8) {
388                 egc_dstbit -= 8;
389                 egc_srcmask.b[ext] = 0;
390                 return;
391         }
392         if(egc_dstbit) {
393                 if((egc_dstbit + egc_remain) >= 8) {
394                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (7 * 8)];
395                         egc_remain -= (8 - egc_dstbit);
396                 } else {
397                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (egc_remain - 1) * 8];
398                         egc_remain = 0;
399                 }
400                 egc_dstbit = 0;
401                 egc_vram_src.b[0][ext] = (egc_outptr[0] >> egc_sft8bitr);
402                 egc_vram_src.b[1][ext] = (egc_outptr[4] >> egc_sft8bitr);
403                 egc_vram_src.b[2][ext] = (egc_outptr[8] >> egc_sft8bitr);
404                 egc_vram_src.b[3][ext] = (egc_outptr[12] >> egc_sft8bitr);
405         } else {
406                 if(egc_remain >= 8) {
407                         egc_remain -= 8;
408                 } else {
409                         egc_srcmask.b[ext] = egc_bytemask_u1[egc_remain - 1];
410                         egc_remain = 0;
411                 }
412                 egc_vram_src.b[0][ext] = (egc_outptr[0] << egc_sft8bitl) | (egc_outptr[1] >> egc_sft8bitr);
413                 egc_vram_src.b[1][ext] = (egc_outptr[4] << egc_sft8bitl) | (egc_outptr[5] >> egc_sft8bitr);
414                 egc_vram_src.b[2][ext] = (egc_outptr[8] << egc_sft8bitl) | (egc_outptr[9] >> egc_sft8bitr);
415                 egc_vram_src.b[3][ext] = (egc_outptr[12] << egc_sft8bitl) | (egc_outptr[13] >> egc_sft8bitr);
416                 egc_outptr++;
417         }
418 }
419
420 inline void DISPLAY::egc_sftb_dnr_sub(uint32_t ext)
421 {
422         if(egc_dstbit >= 8) {
423                 egc_dstbit -= 8;
424                 egc_srcmask.b[ext] = 0;
425                 return;
426         }
427         if(egc_dstbit) {
428                 if((egc_dstbit + egc_remain) >= 8) {
429                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (7 * 8)];
430                         egc_remain -= (8 - egc_dstbit);
431                 } else {
432                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (egc_remain - 1) * 8];
433                         egc_remain = 0;
434                 }
435                 egc_dstbit = 0;
436                 egc_vram_src.b[0][ext] = (egc_outptr[0] << egc_sft8bitr);
437                 egc_vram_src.b[1][ext] = (egc_outptr[4] << egc_sft8bitr);
438                 egc_vram_src.b[2][ext] = (egc_outptr[8] << egc_sft8bitr);
439                 egc_vram_src.b[3][ext] = (egc_outptr[12] << egc_sft8bitr);
440         } else {
441                 if(egc_remain >= 8) {
442                         egc_remain -= 8;
443                 } else {
444                         egc_srcmask.b[ext] = egc_bytemask_d1[egc_remain - 1];
445                         egc_remain = 0;
446                 }
447                 egc_outptr--;
448                 egc_vram_src.b[0][ext] = (egc_outptr[1] >> egc_sft8bitl) | (egc_outptr[0] << egc_sft8bitr);
449                 egc_vram_src.b[1][ext] = (egc_outptr[5] >> egc_sft8bitl) | (egc_outptr[4] << egc_sft8bitr);
450                 egc_vram_src.b[2][ext] = (egc_outptr[9] >> egc_sft8bitl) | (egc_outptr[8] << egc_sft8bitr);
451                 egc_vram_src.b[3][ext] = (egc_outptr[13] >> egc_sft8bitl) | (egc_outptr[12] << egc_sft8bitr);
452         }
453 }
454
455 inline void DISPLAY::egc_sftb_upl_sub(uint32_t ext)
456 {
457         if(egc_dstbit >= 8) {
458                 egc_dstbit -= 8;
459                 egc_srcmask.b[ext] = 0;
460                 return;
461         }
462         if(egc_dstbit) {
463                 if((egc_dstbit + egc_remain) >= 8) {
464                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (7 * 8)];
465                         egc_remain -= (8 - egc_dstbit);
466                         egc_dstbit = 0;
467                 } else {
468                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (egc_remain - 1) * 8];
469                         egc_remain = 0;
470                         egc_dstbit = 0;
471                 }
472         } else {
473                 if(egc_remain >= 8) {
474                         egc_remain -= 8;
475                 } else {
476                         egc_srcmask.b[ext] = egc_bytemask_u1[egc_remain - 1];
477                         egc_remain = 0;
478                 }
479         }
480         egc_vram_src.b[0][ext] = (egc_outptr[0] << egc_sft8bitl) | (egc_outptr[1] >> egc_sft8bitr);
481         egc_vram_src.b[1][ext] = (egc_outptr[4] << egc_sft8bitl) | (egc_outptr[5] >> egc_sft8bitr);
482         egc_vram_src.b[2][ext] = (egc_outptr[8] << egc_sft8bitl) | (egc_outptr[9] >> egc_sft8bitr);
483         egc_vram_src.b[3][ext] = (egc_outptr[12] << egc_sft8bitl) | (egc_outptr[13] >> egc_sft8bitr);
484         egc_outptr++;
485 }
486
487 inline void DISPLAY::egc_sftb_dnl_sub(uint32_t ext)
488 {
489         if(egc_dstbit >= 8) {
490                 egc_dstbit -= 8;
491                 egc_srcmask.b[ext] = 0;
492                 return;
493         }
494         if(egc_dstbit) {
495                 if((egc_dstbit + egc_remain) >= 8) {
496                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (7 * 8)];
497                         egc_remain -= (8 - egc_dstbit);
498                         egc_dstbit = 0;
499                 } else {
500                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (egc_remain - 1) * 8];
501                         egc_remain = 0;
502                         egc_dstbit = 0;
503                 }
504         } else {
505                 if(egc_remain >= 8) {
506                         egc_remain -= 8;
507                 } else {
508                         egc_srcmask.b[ext] = egc_bytemask_d1[egc_remain - 1];
509                         egc_remain = 0;
510                 }
511         }
512         egc_outptr--;
513         egc_vram_src.b[0][ext] = (egc_outptr[1] >> egc_sft8bitl) | (egc_outptr[0] << egc_sft8bitr);
514         egc_vram_src.b[1][ext] = (egc_outptr[5] >> egc_sft8bitl) | (egc_outptr[4] << egc_sft8bitr);
515         egc_vram_src.b[2][ext] = (egc_outptr[9] >> egc_sft8bitl) | (egc_outptr[8] << egc_sft8bitr);
516         egc_vram_src.b[3][ext] = (egc_outptr[13] >> egc_sft8bitl) | (egc_outptr[12] << egc_sft8bitr);
517 }
518 #endif  
519 }
520 #endif
521