OSDN Git Service

[VM][FMTOWNS][PLANEVRAM] Make registers accessing related to Tsugaru.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / planevram.cpp
1
2 #include "./planevram.h"
3 #include "./vram.h"
4
5 #include "./crtc.h"
6 #include "./sprite.h"
7
8 #include "../../fileio.h"
9
10 namespace FMTOWNS {
11
12 void PLANEVRAM::initialize()
13 {
14         DEVICE::initialize();
15 }
16
17 void PLANEVRAM::reset()
18 {
19         mix_reg = 0xff;
20         r50_readplane = 0x0; // OK?
21         r50_ramsel = 0xf; // OK?
22         r50_gvramsel = 0x00000000; // OK?
23 }
24
25 void PLANEVRAM::write_io8(uint32_t addr, uint32_t data)
26 {
27         switch(addr) {
28         case 0xff80:
29                 mix_reg = data | (~(0x28)); // 20231008 K.O related from manual.
30                 break;
31         case 0xff81:
32 //              out_debug_log(_T("0xCFF81=%02X"), data & 0xff);
33                 r50_readplane = (data & 0xc0) >> 6;
34                 r50_ramsel = data & 0x0f;
35                 break;
36         case 0xff82:
37                 __LIKELY_IF(d_crtc != NULL) {
38                         d_crtc->write_signal(SIG_TOWNS_CRTC_MMIO_CFF82H, data, 0xffffffff);
39 //                      out_debug_log(_T("WRITE CFF82h <- %02X"), data);
40                 }
41                 break;
42         case 0xff83:
43 //              out_debug_log(_T("0xCFF83=%02X"), data & 0xff);
44                 r50_gvramsel = ((data & 0x10) != 0) ? 0x20000 : 0x00000;
45                 break;
46         case 0xff86:
47                 break;
48         case 0xffa0:
49                 break;
50         default:
51                 __LIKELY_IF(d_sprite != NULL) {
52                         d_sprite->write_data8(addr & 0x7fff, data);
53                 }
54                 break;
55         }
56 }
57
58 uint32_t PLANEVRAM::read_io8(uint32_t addr)
59 {
60         switch(addr) {
61         case 0xff80:
62                 return mix_reg;
63                 break;
64         case 0xff81:
65                 return ((r50_readplane << 6) | r50_ramsel);
66                 break;
67         case 0xff82:
68                 //__LIKELY_IF(d_crtc != NULL) {
69                 //      return d_crtc->read_signal(SIG_TOWNS_CRTC_MMIO_CFF82H);
70                 //}
71                 break;
72         case 0xff83:
73                 return ((r50_gvramsel != 0x00000) ? 0x10 : 0x00) | 0xe7;
74                 break;
75         case 0xff84:
76                 return 0x00; // Reserve.FIRQ
77                 //return 0x7f; // Reserve.FIRQ
78                 break;
79         case 0xff86:
80                 __LIKELY_IF(d_crtc != NULL) {
81                         return d_crtc->read_signal(SIG_TOWNS_CRTC_MMIO_CFF86H);
82                 }
83                 break;
84         case 0xffa0:
85                 {
86                         uint8_t val;
87                         val = 0xff;
88                         val = val & 0x7f;
89                         return val;
90                 }
91                 break;
92         default:
93                 __LIKELY_IF(d_sprite != NULL) {
94                         return d_sprite->read_data8(addr & 0x7fff);
95                 }
96                 break;
97         }
98         return 0xff;
99 }
100
101 uint32_t PLANEVRAM::read_memory_mapped_io8(uint32_t addr)
102 {
103         // Plane Access
104         uint32_t x_addr = r50_gvramsel;
105         // ToDo: Writing plane.
106         addr = (addr & 0x7fff) << 2;
107         __UNLIKELY_IF(d_vram == NULL) return 0xff;
108
109         pair32_t dat;
110         __DECL_ALIGNED(8) uint8_t cache[4];
111         dat.d = d_vram->read_memory_mapped_io32(x_addr + addr);
112         dat.write_4bytes_le_to(cache);
113 //      p = &(p[x_addr + addr]);
114
115         // 8bit -> 32bit
116         uint8_t val = 0;
117         const uint8_t lmask = 1 << (r50_readplane & 3);
118         const uint8_t hmask = lmask << 4;
119
120         __DECL_ALIGNED(8) uint8_t extra_p[8];
121         __DECL_ALIGNED(8) uint8_t extra_mask[8];
122         const uint8_t extra_value[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
123         __DECL_ALIGNED(8) uint8_t extra_bool[8];
124
125 __DECL_VECTORIZED_LOOP
126         for(int i = 0, j = 0; i < 8; i += 2, j++) {
127                 extra_p[i    ] = cache[j];
128                 extra_p[i + 1] = cache[j];
129         }
130 __DECL_VECTORIZED_LOOP
131         for(int i = 0; i < 8; i += 2) {
132                 extra_mask[i    ] = hmask;
133                 extra_mask[i + 1] = lmask;
134         }
135
136 __DECL_VECTORIZED_LOOP
137         for(int i = 0; i < 8; i++) {
138                 extra_bool[i] = ((extra_mask[i] & extra_p[i]) != 0) ? 0xff : 0x00;
139         }
140
141 __DECL_VECTORIZED_LOOP
142         for(int i = 0; i < 8; i++) {
143                 extra_bool[i] &= extra_value[i];
144         }
145 __DECL_VECTORIZED_LOOP
146         for(int i = 0; i < 8; i++) {
147                 val |= extra_bool[i];
148         }
149
150         return val;
151 }
152
153
154 void PLANEVRAM::write_memory_mapped_io8(uint32_t addr, uint32_t data)
155 {
156         // Plane Access
157         uint32_t x_addr = r50_gvramsel;
158
159         // ToDo: Writing plane.
160         addr = (addr & 0x7fff) << 2;
161
162         __UNLIKELY_IF(d_vram == NULL) return;
163
164         pair32_t dat;
165         dat.d = d_vram->read_memory_mapped_io32(x_addr + addr);
166
167         // 8bit -> 32bit
168         uint32_t tmp = 0;
169         uint32_t tmp_d = data;
170         uint8_t ntmp = r50_ramsel/* & 0x0f*/;
171 #ifdef __LITTLE_ENDIAN__
172 //      uint32_t tmp_m1 = 0xf0000000/* & write_plane_mask*/;
173 //      uint32_t tmp_m2 = 0x0f000000/* & write_plane_mask*/;
174         const uint32_t tmp_m1 = (((uint32_t)ntmp) << 28);
175         const uint32_t tmp_m2 = (((uint32_t)ntmp) << 24);
176 #else
177 //      uint32_t tmp_m1 = 0x0000000f/* & write_plane_mask*/;
178 //      uint32_t tmp_m2 = 0x000000f0/* & write_plane_mask*/;
179         const uint32_t tmp_m1 = (((uint32_t)ntmp) << 0);
180         const uint32_t tmp_m2 = (((uint32_t)ntmp) << 4);
181 #endif
182         pair32_t tmp_r1;
183         //uint32_t tmp_r2;
184         uint32_t mask = 0;
185
186 __DECL_VECTORIZED_LOOP
187         for(int i = 0; i < 4; i++) {
188 #ifdef __LITTLE_ENDIAN__
189                 tmp = tmp >> 8;
190                 mask = mask >> 8;
191 #else
192                 tmp = tmp << 8;
193                 mask = mask << 8;
194 #endif
195                 tmp = tmp | (((tmp_d & 0x80) != 0) ? tmp_m2 : 0x00);
196                 tmp = tmp | (((tmp_d & 0x40) != 0) ? tmp_m1 : 0x00);
197                 mask = mask | (tmp_m1 | tmp_m2);
198                 tmp_d <<= 2;
199         }
200         tmp_r1.d = dat.d;
201         tmp_r1.d &= ~mask;
202         tmp_r1.d |= tmp;
203
204         d_vram->write_memory_mapped_io32(x_addr + addr, tmp_r1.d);
205 }
206
207 uint32_t PLANEVRAM::read_dma_data8w(uint32_t addr, int* wait)
208 {
209         uint32_t val = read_memory_mapped_io8(addr); // OK?
210         __LIKELY_IF(wait != NULL) {
211                 *wait = 0; // Discard WAIT VALUE(s) for DMA transfer.
212         }
213         return val;
214 }
215
216 void PLANEVRAM::write_dma_data8w(uint32_t addr, uint32_t data, int* wait)
217 {
218         write_memory_mapped_io8(addr, data); // OK?
219         __LIKELY_IF(wait != NULL) {
220                 *wait = 0; // Discard WAIT VALUE(s) for DMA transfer.
221         }
222 }
223
224 #define STATE_VERSION   2
225
226 bool PLANEVRAM::process_state(FILEIO* state_fio, bool loading)
227 {
228         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
229                 return false;
230         }
231
232         if(!state_fio->StateCheckInt32(this_device_id)) {
233                 return false;
234         }
235
236         state_fio->StateValue(mix_reg);
237         state_fio->StateValue(r50_readplane);
238         state_fio->StateValue(r50_ramsel);
239         state_fio->StateValue(r50_gvramsel);
240
241         return true;
242 }
243
244 }