OSDN Git Service

[VM][FMTOWNS] Hardware abstract.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / towns_vram.h
1 /*
2         Skelton for retropc emulator
3
4         Author : Kyuma Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2016.12.28 -
6
7         [ FM-Towns VRAM ]
8         History: 2016.12.28 Initial.
9 */
10
11 #ifndef _TOWNS_VRAM_H_
12 #define _TOWNS_VRAM_H_
13
14 #include "../vm.h"
15 #include "../emu.h"
16 #include "device.h"
17 #if defined(_USE_QT)
18 #include <QMutex>
19 #endif
20
21 // Older Towns.
22 #define TOWNS_VRAM_ADDR_MASK 0x7ffff
23 // VRAM DIRECT ACCESS: For Sprite. You should access with 16bit
24 // You can write raw data, drawing with colorkey is automatically.
25 #define SIG_TOWNS_TRANSFER_SPRITE_DATA 0x100000
26 #define SIG_TOWNS_SET_SPRITE_BANK      0x140000
27 #define SIG_TOWNS_CLEAR_SPRITE_BUFFER  0x140001
28 // Do render with any mode. You should set vline to arg.
29 #define SIG_TOWNS_RENDER_RASTER    0x01
30 #define SIG_TOWNS_RENDER_FULL      0x02
31 #define SIG_TOWNS_VRAM_VSTART      0x03
32 #define SIG_TOWNS_VRAM_VBLANK      0x04
33 #define SIG_TOWNS_VRAM_VSYNC       0x05
34 #define SIG_TOWNS_VRAM_HSYNC       0x06
35 #define SIG_TOWNS_VRAM_SET_VLINE   0x07
36 #define SIG_TOWNS_RENDER_FLAG      0x08
37
38 namespace FMTOWNS {
39 class TOWNS_VRAM : public DEVICE
40 {
41 protected:
42         uint32_t page_modes[4];
43         bool line_rendered[2][TOWNS_CRTC_MAX_LINES];
44         
45         scrntype_t *framebuffer0[2]; // Frame Buffer Layer 0. Not saved.
46         scrntype_t *framebuffer1[2]; // Frame Buffer Layer 1. Not saved.
47
48         int framebuffer_width[2][2]; // [Bank][Layer]
49         int framebuffer_height[2][2];
50         int framebuffer_stride[2][2];
51         int framebuffer_size[2][2];
52
53         uint16_t *vram_ptr[2];   // Layer [01] address.
54         uint32_t vram_size[2];   // Layer [01] size [bytes].
55         uint32_t vram_offset[2]; // Layer [01] address offset.
56 #if defined(_USE_QT)
57         // If you use other framework, place mutex lock.
58         QMutex vram_lock[2][2]; // [bank][layer];
59 #endif
60         
61         __DECL_ALIGNED(sizeof(scrntype_t) * 4) scrntype_t table_32768c[65536];
62         __DECL_ALIGNED(sizeof(scrntype_t) * 4) scrntype_t alpha_32768c[65536];
63         __DECL_ALIGNED(sizeof(uint16_t) * 8)   uint16_t   mask_32768c[65536];
64         
65         __DECL_ALIGNED(sizeof(scrntype_t) * 4) scrntype_t alpha_16c[8 * 8 * 2];
66         __DECL_ALIGNED(sizeof(uint16_t) * 8)   uint16_t   mask_16c[8 * 8];
67         
68         uint32_t layer_virtual_width[2];
69         uint32_t layer_virtual_height[2];
70         uint32_t layer_display_width[2];
71         uint32_t layer_display_height[2];
72
73         bool access_page1;
74         uint32_t write_plane_mask; // for plane-access.
75         uint8_t packed_access_mask_lo;
76         uint8_t packed_access_mask_hi;
77
78         bool dirty_flag[0x80000 >> 3]; // Per 8bytes : 16pixels(16colors) / 8pixels(256) / 4pixels(32768)
79
80         scrntype_t alpha_buffer_32768[0x80000 >> 1];
81         scrntype_t alpha_buffer_16[0x80000 << 1];
82
83         uint16_t mask_buffer_32768[0x80000 >> 1];
84         uint16_t mask_buffer_32768_neg[0x80000 >> 1];
85         uint8_t  mask_buffer_16[0x80000];
86         uint8_t  mask_buffer_16_neg[0x80000];
87         
88         
89         uint16_t vram[0x80000 / 2]; // Related by machine.
90         
91         
92         // FMR50 Compatible registers. They are mostly dummy.
93         // Digital paletts. I/O FD98H - FD9FH.
94         uint8_t r50_digital_palette[8];
95         bool layer_display_flags[2]; // I/O FDA0H (WO) : bit3-2 (Layer1) or bit1-0 (Layer0).Not 0 is true.
96         
97         bool r50_dpalette_updated;   // I/O 044CH (RO) : bit7
98         
99         bool sprite_busy;            // I/O 044CH (RO) : bit1. Must update from write_signal().
100         bool splite_disp_page;       // I/O 044CH (RO) : bit0. Must update from write_signal().
101         
102         // Around Analog palette.
103         uint8_t apalette_code; // I/O FD90H (RW). 16 or 256 colors.
104         uint8_t apalette_b;    // I/O FD92H (RW).
105         uint8_t apalette_r;    // I/O FD94H (RW).
106         uint8_t apalette_g;    // I/O FD96H (RW).
107         uint16_t   apalette_16_rgb[2][16];   // R * 256 + G * 16 + B
108         scrntype_t apalette_16_pixel[2][16]; // Not saved. Must be calculated.
109         uint32_t   apalette_256_rgb[256];    // R * 65536 + G * 256 + B
110         scrntype_t apalette_256_pixel[256];  // Not saved. Must be calculated.
111         // Accessing VRAM. Will be separated.
112         // Memory description:
113         // All of accessing must be little endian.
114         // 000C:00000 - 000C:07fff : Plane accessing window(->FM-R50 features?). Access to Layer #0 (8000:00000).
115         // 000C:08000 - 000C:0ffff : I/O CVRAM
116         // 000D:00000 - 000E:0ffff : Reserved (Window for KANJI, DIC etc).
117         // 8000:00000 - 8000:3ffff : Plane accessing Layer #0.
118         // 8000:40000 - 8000:7ffff : Plane accessing Layer #1.
119         // 8010:00000 - 8010:7ffff : Plane accessing with one layer.
120         // 8100:00000 - 8100:1ffff : Sprite (and text vram).
121         // I/O 0458H (RW) : VRAM ACCESS CONTROLLER reg address.
122         // I/O 045AH (RW) : VRAM ACCESS CONTROLLER reg data (LOW).
123         // I/O 045BH (RW) : VRAM ACCESS CONTROLLER reg data (HIGH).
124         pair_t packed_pixel_mask_reg; // '1' = Write. I/O 0458H - 045BH.
125         //uint8_t *vram_addr;
126         uint32_t vram_bytes;
127         uint32_t layer_offset[4];
128         uint8_t text_vram[4096]; // 4096bytes
129         uint8_t kanji_vram[4096]; // 4096bytes
130         // End.
131
132         // Flags related by host renderer. Not saved.
133         bool has_hardware_rendering;
134         bool has_hardware_blending;
135         // End.
136
137         void lock_framebuffer(int layer, int bank)
138         {
139 #if defined(_USE_QT)
140                 vram_lock[bank][layer].lock();
141 #endif
142         }
143         void unlock_framebuffer(int layer, int bank)
144         {
145 #if defined(_USE_QT)
146                 vram_lock[bank][layer].unlock();
147 #endif
148         }
149
150         
151 public:
152         TOWNS_VRAM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
153         {
154                 memset(vram, 0x00, sizeof(vram));
155                 for(int bank = 0; bank < 2; bank++) {
156                         for(int layer = 0; layer < 2; layer++) {
157                                 framebuffer_width[bank][layer] = 640;
158                                 framebuffer_height[bank][layer] = 480;
159                                 framebuffer_stride[bank][layer] = 640 * sizeof(scrntype_t);
160                                 framebuffer_size[bank][layer] = 640 * 480 * sizeof(scrntype_t);
161                                 if(layer == 0) {
162                                         framebuffer0[bank] = NULL;
163                                 } else {
164                                         framebuffer1[bank] = NULL;
165                                 }
166                         }
167                 }
168                 page_modes[0] = page_modes[1] = page_modes[2] = page_modes[3] = 0;
169                 packed_access_mask_hi = packed_access_mask_lo = 0xff;
170                 write_plane_mask = 0xffffffff;
171         }
172         ~TOWNS_VRAM() {}
173         
174         uint32_t read_data8(uint32_t addr);
175         uint32_t read_data16(uint32_t addr);
176         uint32_t read_data32(uint32_t addr);
177         void write_data8(uint32_t addr, uint32_t data);
178         void write_data16(uint32_t addr, uint32_t data);
179         void write_data32(uint32_t addr, uint32_t data);
180
181         uint32_t read_io8(uint32_t addr);
182         void write_io8(uint32_t addr, uint32_t data);
183         void draw_screen();
184         void write_signal(int id, uint32_t data, uint32_t mask); // Do render
185
186         // Unique Functions
187         uint32_t read_plane_data8(uint32_t addr);
188         uint32_t read_plane_data16(uint32_t addr);
189         uint32_t read_plane_data32(uint32_t addr);
190         // New APIs?
191         void write_plane_data8(uint32_t addr, uint32_t data);
192         void write_plane_data16(uint32_t addr, uint32_t data);
193         void write_plane_data32(uint32_t addr, uint32_t data);
194
195         void set_frame_buffer(int layer, bool buffer1, scrntype_t *framebuffer, int width, int height);
196         scrntype_t *get_frame_buffer_ptr(int layer);
197         int  get_frame_buffer_width(int layer);
198         int  get_frame_buffer_height(int layer);
199         bool is_display(int layer);
200         bool is_updated(int layer, int line_num);
201         void lock_frame_buffer(int layer);
202         void unlock_frame_buffer(int layer);
203         void set_render_features(bool blending_from_buffer, bool rendering_framebuffer);
204         // End.
205         
206         void set_context_renderbuffer(scrntype_t *p, int layer, int bank, uint32_t width, uint32_t height, uint32_t stride){
207                 if((layer > 1) || (layer < 0)) return;
208                 if((bank > 1) || (bank < 0)) return;
209                 lock_framebuffer(layer, bank);
210                 framebuffer_width[bank][layer] = width;
211                 framebuffer_height[bank][layer] = height;
212                 framebuffer_stride[bank][layer] = stride * sizeof(scrntype_t);
213                 framebuffer_size[bank][layer] = stride * height * sizeof(scrntype_t);
214                 if(layer == 0) {
215                         framebuffer0[bank] = p;
216                 } else {
217                         framebuffer1[bank] = p;
218                 }
219                 unlock_framebuffer(layer, bank);
220         
221         };
222 };
223
224 }
225 #endif