OSDN Git Service

Merge branch 'master' of github.com:Artanejp/common_source_project-fm7
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / mb61vh010.cpp
1 /*
2  * FM77AV/FM16β ALU [mb61vh010.cpp]
3  *  of Fujitsu MB61VH010/011
4  *
5  * Author: K.Ohta <whatisthis.sowhat _at_ gmail.com>
6  * License: GPLv2
7  * History:
8  *   Mar 28, 2015 : Initial
9  *
10  */
11
12 #include "mb61vh010.h"
13
14
15 void MB61VH010::do_pset(uint32_t addr)
16 {
17         int i;
18         uint8_t bitmask[4] = {0};
19         uint8_t srcdata[4] = {0};
20         const uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
21         uint32_t *pbm = (uint32_t *)bitmask;
22         uint32_t *pmp = (uint32_t *)mask_p;
23         uint32_t *psd = (uint32_t *)srcdata;
24         
25         for(i = 0; i < 4; i++) { // planes
26                 //if((bank_disable_reg & (1 << i)) != 0) {
27                 if(disable_flags[i]) continue;
28                 //}
29                 if((color_reg & (1 << i)) == 0) {
30                         bitmask[i] = 0x00;
31                 } else {
32                         bitmask[i] = ~mask_reg;
33                 }
34                 srcdata[i] = do_read(addr, i);
35         }
36         *psd = (*psd & *pmp) | *pbm;
37         //srcdata[0] = (srcdata[0] & mask_p[0]) | bitmask[0];
38         //srcdata[1] = (srcdata[1] & mask_p[1]) | bitmask[1];
39         //srcdata[2] = (srcdata[2] & mask_p[2]) | bitmask[2];
40         //srcdata[3] = (srcdata[3] & mask_p[3]) | bitmask[3];
41
42         for(i = 0; i < 4; i++) {
43                 if(disable_flags[i]) continue;
44                 //if((bank_disable_reg & (1 << i)) != 0) {
45                 //      continue;
46                 //}
47                 do_write(addr, i, srcdata[i]);
48         }
49         return;
50 }
51
52 void MB61VH010::do_blank(uint32_t addr)
53 {
54         uint32_t i;
55         uint8_t srcdata;
56
57         //if(planes >= 4) planes = 4;
58         for(i = 0; i < 4; i++) {
59                 if(disable_flags[i]) continue;
60                 //if((bank_disable_reg & (1 << i)) != 0) {
61                 //      continue;
62                 //}
63                 srcdata = do_read(addr, i);
64                 srcdata = srcdata & mask_reg;
65                 do_write(addr, i, srcdata);
66         }
67         return;
68 }
69
70 void MB61VH010::do_or(uint32_t addr)
71 {
72         uint32_t i;
73         uint8_t bitmask[4] = {0};
74         uint8_t srcdata[4] = {0};
75         const uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
76         const uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
77         uint32_t *pbm = (uint32_t *)bitmask;
78         uint32_t *pmp = (uint32_t *)mask_p;
79         uint32_t *pmn = (uint32_t *)mask_n;
80         uint32_t *psd = (uint32_t *)srcdata;
81         
82         //if(planes >= 4) planes = 4;
83         for(i = 0; i < 4; i++) {
84                 if(disable_flags[i]) continue;
85                 //if((bank_disable_reg & (1 << i)) != 0) {
86                 //      continue;
87                 //}
88                 srcdata[i] = do_read(addr, i);
89                 if((color_reg & (1 << i)) == 0) {
90                         bitmask[i] = srcdata[i]; // srcdata | 0x00
91                 } else {
92                         bitmask[i] = 0xff; // srcdata | 0xff
93                 }
94                 //bitmask = bitmask & ~mask_reg;
95                 //srcdata = (srcdata & mask_reg) | bitmask;
96                 //do_write(addr, i, srcdata);
97         }
98         *psd = (*psd & *pmp) | (*pbm & *pmn);
99         //srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
100         //srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
101         //srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
102         //srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
103         for(i = 0; i < 4; i++) {
104                 if(disable_flags[i]) continue;
105                 //if((bank_disable_reg & (1 << i)) != 0) {
106                 //      continue;
107                 //}
108                 do_write(addr, i, srcdata[i]);
109         }
110         return;
111 }
112
113 void MB61VH010::do_and(uint32_t addr)
114 {
115         uint32_t i;
116         uint8_t bitmask[4] = {0};
117         uint8_t srcdata[4] = {0};
118         const uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
119         const uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
120         uint32_t *pbm = (uint32_t *)bitmask;
121         uint32_t *pmp = (uint32_t *)mask_p;
122         uint32_t *pmn = (uint32_t *)mask_n;
123         uint32_t *psd = (uint32_t *)srcdata;
124
125         //if(planes >= 4) planes = 4;
126         for(i = 0; i < 4; i++) {
127                 if(disable_flags[i]) continue;
128                 //if((bank_disable_reg & (1 << i)) != 0) {
129                 //      continue;
130                 //}
131                 srcdata[i] = do_read(addr, i);
132                 if((color_reg & (1 << i)) == 0) {
133                         bitmask[i] = 0x00; // srcdata & 0x00
134                 } else {
135                         bitmask[i] = srcdata[i]; // srcdata & 0xff;
136                 }
137                 //bitmask = bitmask & ~mask_reg;
138                 //srcdata = (srcdata & mask_reg) | bitmask;
139                 //do_write(addr, i, srcdata);
140         }
141         *psd = (*psd & *pmp) | (*pbm & *pmn);
142         //srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
143         //srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
144         //srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
145         //srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
146         for(i = 0; i < 4; i++) {
147                 if((bank_disable_reg & (1 << i)) != 0) {
148                         continue;
149                 }
150                 do_write(addr, i, srcdata[i]);
151         }
152         return;
153 }
154
155 void MB61VH010::do_xor(uint32_t addr)
156 {
157         uint32_t i;
158         //uint8_t bitmask;
159         //uint8_t srcdata;
160         uint8_t bitmask[4] = {0};
161         uint8_t srcdata[4] = {0};
162         const uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
163         const uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
164         uint32_t *pbm = (uint32_t *)bitmask;
165         uint32_t *pmp = (uint32_t *)mask_p;
166         uint32_t *pmn = (uint32_t *)mask_n;
167         uint32_t *psd = (uint32_t *)srcdata;
168
169         //if(planes >= 4) planes = 4;
170         for(i = 0; i < 4; i++) {
171                 if(disable_flags[i]) continue;
172                 //if((bank_disable_reg & (1 << i)) != 0) {
173                 //      continue;
174                 //}
175                 if((color_reg & (1 << i)) == 0) {
176                         bitmask[i] = 0x00;
177                 } else {
178                         bitmask[i] = 0xff;
179                 }
180                 
181                 srcdata[i] = do_read(addr, i);
182                 //bitmask = bitmask ^ srcdata;
183                 //bitmask = bitmask & (~mask_reg);
184                 //srcdata = srcdata & mask_reg;
185                 //srcdata = srcdata | bitmask;
186                 //do_write(addr, i, srcdata);
187         }
188         *pbm = *pbm ^ *psd;
189         //bitmask[0] = bitmask[0] ^ srcdata[0];
190         //bitmask[1] = bitmask[1] ^ srcdata[1];
191         //bitmask[2] = bitmask[2] ^ srcdata[2];
192         //bitmask[3] = bitmask[3] ^ srcdata[3];
193         
194         *psd = (*psd & *pmp) | (*pbm & *pmn);
195         //srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
196         //srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
197         //srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
198         //srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
199         for(i = 0; i < 4; i++) {
200                 if(disable_flags[i]) continue;
201                 //if((bank_disable_reg & (1 << i)) != 0) {
202                 //      continue;
203                 //}
204                 do_write(addr, i, srcdata[i]);
205         }
206         return;
207 }
208
209 void MB61VH010::do_not(uint32_t addr)
210 {
211         uint32_t i;
212         uint8_t bitmask[4] = {0};
213         uint8_t srcdata[4] = {0};
214         const uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
215         const uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
216         uint32_t *pbm = (uint32_t *)bitmask;
217         uint32_t *pmp = (uint32_t *)mask_p;
218         uint32_t *pmn = (uint32_t *)mask_n;
219         uint32_t *psd = (uint32_t *)srcdata;
220
221         //if(planes >= 4) planes = 4;
222         for(i = 0; i < 4; i++) {
223                 if(disable_flags[i]) continue;
224                 //if((bank_disable_reg & (1 << i)) != 0) {
225                 //      continue;
226                 //}
227                 srcdata[i] = do_read(addr, i);
228                 bitmask[i] = ~srcdata[i];
229                 //bitmask = bitmask & ~mask_reg;
230                 //srcdata = (srcdata & mask_reg) | bitmask;
231                 //do_write(addr, i, srcdata);
232         }
233         *psd = (*psd & *pmp) | (*pbm & *pmn);
234         //srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
235         //srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
236         //srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
237         //srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
238         for(i = 0; i < 4; i++) {
239                 if((bank_disable_reg & (1 << i)) != 0) {
240                         continue;
241                 }
242                 do_write(addr, i, srcdata[i]);
243         }
244         return;
245 }
246
247
248 void MB61VH010::do_tilepaint(uint32_t addr)
249 {
250         uint32_t i;
251         uint8_t bitmask[4] = {0};
252         uint8_t srcdata[4] = {0};
253         const uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
254         const uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
255         uint32_t *pbm = (uint32_t *)bitmask;
256         uint32_t *pmp = (uint32_t *)mask_p;
257         uint32_t *pmn = (uint32_t *)mask_n;
258         uint32_t *psd = (uint32_t *)srcdata;
259
260         //if(planes > 4) planes = 4;
261         for(i = 0; i < 4; i++) {
262                 if(disable_flags[i]) continue;
263                 //if((bank_disable_reg & (1 << i)) != 0) {
264                 //      continue;
265                 //}
266                 srcdata[i] = do_read(addr, i);
267                 bitmask[i] = tile_reg[i];
268                 //bitmask = tile_reg[i] & (~mask_reg);
269                 //srcdata = (srcdata & mask_reg) | bitmask;
270                 //do_write(addr, i, srcdata);
271         }
272         *psd = (*psd & *pmp) | (*pbm & *pmn);
273         //srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
274         //srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
275         //srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
276         //srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
277         for(i = 0; i < 4; i++) {
278                 if(disable_flags[i]) continue;
279                 //if((bank_disable_reg & (1 << i)) != 0) {
280                 //      continue;
281                 //}
282                 do_write(addr, i, srcdata[i]);
283         }
284         return;
285 }
286
287 void MB61VH010::do_compare(uint32_t addr)
288 {
289         uint8_t r, g, b;
290         uint8_t disables = ~bank_disable_reg;
291
292         uint8_t tmpcol;
293         uint8_t tmp_stat = 0;
294         uint8_t cmp_reg_bak[8];
295         int k;
296         int i;
297         int j;
298         
299         disables = disables & 0x07;
300         k = 0;
301         for(j = 0; j < 8; j++) {
302                 if((cmp_color_data[j] & 0x80) == 0) {
303                         cmp_reg_bak[k] = cmp_color_data[j] & disables;
304                         k++;
305                 }
306         }
307         cmp_status_reg = 0x00;
308         if(k <= 0) return;
309         b = do_read(addr, 0);
310         r = do_read(addr, 1);
311         g = do_read(addr, 2);
312         for(i = 0; i < 8; i++) {
313                 tmp_stat <<= 1;
314                 tmpcol  = (b & 0x80) >> 7;
315                 tmpcol  = tmpcol | ((r & 0x80) >> 6);
316                 tmpcol  = tmpcol | ((g & 0x80) >> 5);
317                 tmpcol = tmpcol & disables;
318                 for(j = 0; j < k; j++) {
319                         if(cmp_reg_bak[j] == tmpcol) {
320                                 tmp_stat = tmp_stat | 0x01;
321                                 goto _l0;
322                         }
323                 }
324 _l0:       
325                 b <<= 1;
326                 r <<= 1;
327                 g <<= 1;
328         }
329         cmp_status_reg = tmp_stat;
330         return;
331 }
332
333 void MB61VH010::do_alucmds_dmyread(uint32_t addr)
334 {
335         if(!is_400line) {
336                 addr = addr & 0x3fff;
337         } else {
338                 if(addr >= 0x8000) {
339                         mask_reg = 0xff;
340                         return;
341                 }
342                 addr = addr & 0x7fff;
343         }
344         if((command_reg & 0x80) == 0) {
345                 return;
346         }
347         //busy_flag = true;
348         //cmp_status_reg = 0x00;
349         if((command_reg & 0x40) != 0) do_compare(addr);
350         switch(command_reg & 0x07) {
351                 case 0:
352                         do_pset(addr);
353                         break;
354                 case 1:
355                         do_blank(addr);
356                         break;
357                 case 2:
358                         do_or(addr);
359                         break;
360                 case 3:
361                         do_and(addr);
362                         break;
363                 case 4:
364                         do_xor(addr);
365                         break;
366                 case 5:
367                         do_not(addr);
368                         break;
369                 case 6:
370                         do_tilepaint(addr);
371                         break;
372                 case 7:
373                         do_compare(addr);
374                         break;
375         }
376         //printf("ALU DMYREAD ADDR=%04x, CMD=%02x CMP STATUS=%02x DISABLE=%01x\n", addr, command_reg, cmp_status_reg, bank_disable_reg);
377         //if(eventid_busy >= 0) cancel_event(this, eventid_busy) ;
378         //register_event(this, EVENT_MB61VH010_BUSY_OFF, 1.0 / 16.0, false, &eventid_busy) ;
379 }  
380
381 void MB61VH010::do_alucmds(uint32_t addr)
382 {
383         if(addr >= 0x8000) {
384                 mask_reg = 0xff;
385                 return;
386         }
387
388         //cmp_status_reg = 0xff;
389         if((command_reg & 0x40) != 0) do_compare(addr);
390         switch(command_reg & 0x07) {
391                 case 0:
392                         do_pset(addr);
393                         break;
394                 case 1:
395                         do_blank(addr);
396                         break;
397                 case 2:
398                         do_or(addr);
399                         break;
400                 case 3:
401                         do_and(addr);
402                         break;
403                 case 4:
404                         do_xor(addr);
405                         break;
406                 case 5:
407                         do_not(addr);
408                         break;
409                 case 6:
410                         do_tilepaint(addr);
411                         break;
412                 case 7:
413                         do_compare(addr);
414                         break;
415         }
416         //printf("ALU CMDS ADDR=%04x, CMD=%02x CMP STATUS=%02x\n", addr, command_reg, cmp_status_reg);
417         return;
418 }
419
420 void MB61VH010::do_line(void)
421 {
422         uint32_t x_begin = line_xbegin.w.l;
423         uint32_t x_end = line_xend.w.l;
424         uint32_t y_begin = line_ybegin.w.l;
425         uint32_t y_end = line_yend.w.l;
426         int cpx_t = (int)x_begin;
427         int cpy_t = (int)y_begin;
428         int ax = (int)x_end - (int)x_begin;
429         int ay = (int)y_end - (int)y_begin;
430         int diff = 0;
431         int diff8 = 0;
432         int count = 0;
433         int xcount;
434         int ycount;
435         //bool updated = false;
436         static const uint8_t vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
437         double usec;
438         oldaddr = 0xffffffff;
439         alu_addr = 0xffffffff;
440         line_style = line_pattern;
441         busy_flag = true;
442         total_bytes = 0;
443         
444         mask_reg = 0xff;
445         if ((line_style.b.h & 0x80) != 0) {
446                 mask_reg &= ~vmask[cpx_t & 7];
447         }
448         xcount = abs(ax);
449         ycount = abs(ay);
450         //this->out_debug_log(_T("LINE: (%d,%d)-(%d,%d) CMD=%02x STYLE=%04x, \n"), x_begin, y_begin, x_end , y_end, command_reg, line_style.w.l); 
451         if(ycount == 0) {
452                 if((cpy_t < 0) || (cpy_t >= 512)) goto _finish;
453                 if(xcount == 0) {
454                         put_dot(cpx_t, cpy_t);
455                         goto _finish;
456                 }
457                 if(ax > 0) {
458                         int left = x_end - cpx_t;
459                         if((cpx_t & 0x07) != 7) total_bytes = 1;
460                         for(; cpx_t <= (int)x_end;) {
461                                 if((cpx_t & 7) == 0) {
462                                         if(left >= 8) {
463                                                 put_dot8(cpx_t, cpy_t);
464                                                 cpx_t += 8;
465                                                 left -= 8;
466                                                 total_bytes++;
467                                                 continue;
468                                         }
469                                 }
470                                 {
471                                         put_dot(cpx_t, cpy_t);
472                                         cpx_t++;
473                                         left--;
474                                         if((cpx_t & 0x07) == 7) total_bytes++;
475                                 }
476                         }
477                 } else {
478                         int left = cpx_t - x_end;
479                         if((cpx_t & 0x07) != 0) total_bytes = 1;
480                         for(; cpx_t >= (int)x_end;) {
481                                 if(cpx_t < 0) break; // Comment out for Amnork.
482                                 if((cpx_t & 7) == 7) {
483                                         if(left >= 8) {
484                                                 put_dot8(cpx_t, cpy_t);
485                                                 cpx_t -= 8;
486                                                 left -= 8;
487                                                 total_bytes++;
488                                                 continue;
489                                         }
490                                 }
491                                 {
492                                         if((cpx_t & 7) == 0) total_bytes++;
493                                         put_dot(cpx_t, cpy_t);
494                                         left--;
495                                         cpx_t--;
496                                 }
497                         }
498                 }
499         } else if(xcount == 0) {
500                 //if((cpx_t < 0) || (cpx_t >= screen_width)) goto _finish; // Okay?
501                 if(cpx_t < 0) goto _finish; // Okay?
502                 if(ay > 0) {
503                         for(; cpy_t <= (int)y_end; cpy_t++) {
504                                 if(cpy_t >= 512) break;
505                                 put_dot(cpx_t, cpy_t);
506                                 total_bytes++;
507                         }
508                 } else {
509                         for(; cpy_t  >= (int)y_end; cpy_t--) {
510                                 if(cpy_t < 0) break;
511                                 put_dot(cpx_t, cpy_t);
512                                 total_bytes++;
513                         }
514                 }
515         } else if(xcount > ycount) { // (abs(ax) > abs(ay)
516                 diff = (ycount * 32768) / xcount;
517                 diff8 = diff << 3;
518                 if(ax < 0) {
519                         if((cpx_t & 0x07) != 0) total_bytes = 1;
520                 } else {
521                         if((cpx_t & 0x07) == 0) total_bytes = 1;
522                 }
523                 for(; xcount >= 0; ) {
524                         if((diff8 + count) <= 16384) {
525                                 if(ax > 0) {
526                                         if((cpx_t & 0x07) == 0) {
527                                                 if(xcount >= 8) {
528                                                         put_dot8(cpx_t, cpy_t);
529                                                         total_bytes++;
530                                                         count += diff8;
531                                                         xcount -= 8;
532                                                         cpx_t += 8;
533                                                         continue;
534                                                 }
535                                         }
536                                 } else { // ax < 0
537                                         if((cpx_t & 0x07) == 7) {
538                                                 if(xcount >= 8) {
539                                                         put_dot8(cpx_t, cpy_t);
540                                                         total_bytes++;
541                                                         count += diff8;
542                                                         xcount -= 8;
543                                                         cpx_t -= 8;
544                                                         if(cpx_t < 0) break;
545                                                         continue;
546                                                 }
547                                         }
548                                 }
549                         }
550                         put_dot(cpx_t, cpy_t);
551                         count += diff;
552                         if(count > 16384) {
553                                 if(ay < 0) {
554                                         cpy_t--;
555                                         if(cpy_t < 0) break;
556                                 } else {
557                                         cpy_t++;
558                                         if(cpy_t >= 512) break;
559                                 }
560                                 total_bytes++;
561                                 count -= 32768;
562                         }
563                         if(ax > 0) {
564                                 cpx_t++;
565                                 if((cpx_t & 0x07) == 0) total_bytes++;
566                         } else if(ax < 0) {
567                                 if((cpx_t & 0x07) == 0) total_bytes++;
568                                 cpx_t--;
569                                 if(cpx_t < 0) break; // Comment out for Amnork.
570                         }
571                         xcount--;
572                 }
573         } else if(xcount == ycount) { // (abs(ax) == abs(ay)
574                 diff = (ycount * 32768) / xcount;
575                 if(ax < 0) {
576                         if((cpx_t & 0x07) != 0) total_bytes = 1;
577                 } else {
578                         if((cpx_t & 0x07) == 0) total_bytes = 1;
579                 }
580                 for(; xcount >= 0; xcount-- ) {
581                         put_dot(cpx_t, cpy_t);
582                         if(ay < 0) {
583                                 cpy_t--;
584                                 if(cpy_t < 0) break;
585                         } else {
586                                 cpy_t++;
587                                 if(cpy_t >= 512) break;
588                         }
589                         total_bytes++;
590                         if(ax > 0) {
591                                 cpx_t++;
592                         } else if(ax < 0) {
593                                 cpx_t--;
594                                 if(cpx_t < 0) break; // Comment out for Amnork.
595                         }
596                 }
597         } else { // (abs(ax) < abs(ay)
598                 diff = (xcount  * 32768) / ycount;
599                 for(; ycount >= 0; ycount--) {
600                         put_dot(cpx_t, cpy_t);
601                         total_bytes++;
602                         count += diff;
603                         if(count > 16384) {
604                                 if(ax < 0) {
605                                         cpx_t--;
606                                         if(cpx_t < 0) break; // Comment out for Amnork.
607                                 } else if(ax > 0) {
608                                         cpx_t++;
609                                 }
610                                 count -= 32768;
611                         }
612                         if(ay > 0) {
613                                 cpy_t++;
614                                 if(cpy_t >= 512) {
615                                         break;
616                                 }
617                         } else {
618                                 cpy_t--;
619                                 if(cpy_t < 0) {
620                                         break;
621                                 }
622                         }
623                 }
624         }
625         // last byte
626         do_alucmds(alu_addr);
627         total_bytes++;
628 _finish:   
629         //if(total_bytes == 0) total_bytes = 1;
630         mask_reg = 0xff;
631         //if(total_bytes >= 8) { // Only greater than 8bytes.
632         usec = (double)total_bytes / 16.0;
633         if(usec < 1.0) {
634                 busy_flag = false; // ToDo
635         } else {
636                 if(eventid_busy >= 0) cancel_event(this, eventid_busy) ;
637                 register_event(this, EVENT_MB61VH010_BUSY_OFF, usec, false, &eventid_busy);
638         }
639 }
640
641
642 void MB61VH010::write_data8(uint32_t id, uint32_t data)
643 {
644         //this->out_debug_log(_T("ALU: ADDR=%02x DATA=%02x\n"), id, data);
645         if(id < 0xc000) {
646                 uint32_t raddr = id;
647                 if(is_400line) {
648                         if(raddr >= 0x8000) return;
649                 } else {
650                         raddr = raddr & 0x3fff;
651                 }
652                 do_alucmds_dmyread(raddr);
653         }
654         switch(id) {
655                 case ALU_CMDREG:
656                         command_reg = data;
657                         break;
658                 case ALU_LOGICAL_COLOR:
659                         color_reg = data;
660                         break;
661                 case ALU_WRITE_MASKREG:
662                         mask_reg = data;
663                         break;
664                 case ALU_BANK_DISABLE:
665                         switch(planes) {    // D41B (RW)
666                         case 1:
667                                 data |= 0xfe;
668                                 break;
669                         case 2:
670                                 data |= 0xfc;
671                                 break;
672                         case 3:
673                                 data |= 0xf8;
674                                 break;
675                         case 4:
676                                 data |= 0xf0;
677                                 break;
678                         default:
679                             data |= 0xff;
680                                 break;
681                         }
682                         bank_disable_reg = data;
683                         for(int i = 0; i < 4; i++) {
684                                 disable_flags[i] = ((bank_disable_reg & (1 << i)) != 0) ? true : false;
685                         }
686                         break;
687                 case ALU_TILEPAINT_B:
688                         tile_reg[0] = data;
689                         break;
690                 case ALU_TILEPAINT_R:
691                         tile_reg[1] = data;
692                         break;
693                 case ALU_TILEPAINT_G:
694                         tile_reg[2] = data;
695                         break;
696                 case ALU_TILEPAINT_L:
697                         tile_reg[3] = data;
698                         break;
699                 case ALU_OFFSET_REG_HIGH:
700                         line_addr_offset.b.h &= 0x01;
701                         line_addr_offset.b.h = line_addr_offset.b.h | ((data << 1) & 0x3e);
702                         break;
703                 case ALU_OFFSET_REG_LO:
704                         line_addr_offset.b.l = data << 1;
705                         line_addr_offset.b.h &= 0xfe;
706                         line_addr_offset.b.h = line_addr_offset.b.h | ((data >> 7) & 0x01);
707                         break;
708                 case ALU_LINEPATTERN_REG_HIGH:
709                         line_pattern.b.h = data;
710                         break;
711                 case ALU_LINEPATTERN_REG_LO:
712                         line_pattern.b.l = data;
713                         break;
714                 case ALU_LINEPOS_START_X_HIGH:
715                         line_xbegin.b.h = data & 0x03;
716                         break;
717                 case ALU_LINEPOS_START_X_LOW:  
718                         line_xbegin.b.l = data;
719                         break;
720                 case ALU_LINEPOS_START_Y_HIGH:
721                         line_ybegin.b.h = data & 0x01;
722                         break;
723                 case ALU_LINEPOS_START_Y_LOW:  
724                         line_ybegin.b.l = data;
725                         break;
726                 case ALU_LINEPOS_END_X_HIGH:
727                         line_xend.b.h = data & 0x03;
728                         break;
729                 case ALU_LINEPOS_END_X_LOW:  
730                         line_xend.b.l = data;
731                         break;
732                 case ALU_LINEPOS_END_Y_HIGH:
733                         line_yend.b.h = data & 0x01;
734                         break;
735                 case ALU_LINEPOS_END_Y_LOW:
736                         line_yend.b.l = data;
737                         do_line();
738                         break;
739                 case ALU_CMPDATA_REG + 0:
740                 case ALU_CMPDATA_REG + 1:
741                 case ALU_CMPDATA_REG + 2:
742                 case ALU_CMPDATA_REG + 3:
743                 case ALU_CMPDATA_REG + 4:
744                 case ALU_CMPDATA_REG + 5:
745                 case ALU_CMPDATA_REG + 6:
746                 case ALU_CMPDATA_REG + 7:
747                         cmp_color_data[id - ALU_CMPDATA_REG] = data;
748                         break;
749                 default:
750                         break;
751         }
752 }
753
754 uint32_t MB61VH010::read_data8(uint32_t id)
755 {
756         uint32_t raddr;  
757         if(id < 0xc000) {
758                 uint32_t dmydata;
759                 raddr = id;
760                 if(is_400line) {
761                         if(raddr >= 0x8000) return 0xffffffff;
762                 } else {
763                         raddr = raddr & 0x3fff;
764                 }
765                 do_alucmds_dmyread(raddr);
766                 //raddr = id & 0xffff;
767                 dmydata = target->read_data8(raddr + direct_access_offset);
768                 return dmydata;
769         }
770         switch(id) {
771                 case ALU_CMDREG:
772                         return (uint32_t)command_reg;
773                         break;
774                 case ALU_LOGICAL_COLOR:
775                         return (uint32_t)color_reg;
776                         break;
777                 case ALU_WRITE_MASKREG:
778                         return (uint32_t)mask_reg;
779                         break;
780                 case ALU_CMP_STATUS_REG:
781                         return (uint32_t)cmp_status_reg;
782                         break;
783                 case ALU_BANK_DISABLE:
784                         return (uint32_t)bank_disable_reg;
785                         break;
786                 default:
787 //                      if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0xc000))) {
788                         return 0xffffffff;
789                         break;
790         }
791 }
792
793 uint32_t MB61VH010::read_signal(int id)
794 {
795         uint32_t val = 0x00000000;
796         switch(id) {
797                 case SIG_ALU_BUSYSTAT:
798                         if(busy_flag) val = 0xffffffff;
799                         break;
800                 case SIG_ALU_ENABLED:
801                         if((command_reg & 0x80) != 0) val = 0xffffffff;
802                         break;
803         }
804         return val;
805 }
806
807 void MB61VH010::write_signal(int id, uint32_t data, uint32_t mask)
808 {
809         bool flag = ((data & mask) != 0);
810         switch(id) {
811                 case SIG_ALU_400LINE:
812                         is_400line = flag;
813                         break;
814                 case SIG_ALU_MULTIPAGE:
815                         multi_page = (data & mask) & 0x07;
816                         for(int i = 0; i < 4; i++) {
817                                 multi_flags[i] = (((1 << i) & multi_page) != 0) ? true : false;
818                         }
819                         break;
820                 case SIG_ALU_PLANES:
821                         planes = (data & mask) & 0x07;
822                         if(planes >= 4) planes = 4;
823                         break;
824                 case SIG_ALU_X_WIDTH:
825                         screen_width = (data << 3) & 0x3ff;
826                         break;
827                 case SIG_ALU_Y_HEIGHT:
828                         screen_height = data & 0x3ff;
829                         break;
830         }
831 }
832
833 void MB61VH010::event_callback(int event_id, int err)
834 {
835         switch(event_id) {
836                 case EVENT_MB61VH010_BUSY_ON:
837                         busy_flag = true;
838                         if(eventid_busy >= 0) cancel_event(this, eventid_busy);
839                         eventid_busy = -1;
840                         break;
841                 case EVENT_MB61VH010_BUSY_OFF:
842                         busy_flag = false;
843                         eventid_busy = -1;
844                         break;
845         }
846 }
847
848 void MB61VH010::initialize(void)
849 {
850         int i;
851         busy_flag = false;
852         is_400line = false;
853         eventid_busy = -1;
854         multi_page = 0x00;
855         for(i = 0; i < 4; i++) {
856                 multi_flags[i] = (((1 << i) & multi_page) != 0) ? true : false;
857         }
858         planes = 3;
859         screen_width = 640;
860         screen_height = 200;
861         command_reg = 0;        // D410 (RW)
862         color_reg = 0;          // D411 (RW)
863         mask_reg = 0x00;        // D412 (RW)
864         cmp_status_reg = 0;     // D413 (RO)
865         for(i = 0; i < 8; i++) cmp_color_data[i] = 0x80; // D413-D41A (WO)
866         bank_disable_reg = 0xf8;// D41B (RW)
867         for(i = 0; i < 4; i++) {
868                 disable_flags[i] = ((bank_disable_reg & (1 << i)) != 0) ? true : false;
869         }
870         for(i = 0; i < 4; i++) tile_reg[i] = 0;        // D41C-D41F (WO)
871         
872         line_addr_offset.d = 0; // D420-D421 (WO)
873         line_pattern.d = 0;     // D422-D423 (WO)
874         line_xbegin.d = 0;      // D424-D425 (WO)
875         line_ybegin.d = 0;      // D426-D427 (WO)
876         line_xend.d = 0;        // D428-D429 (WO)
877         line_yend.d = 0;        // D42A-D42B (WO)
878 }
879
880 void MB61VH010::reset(void)
881 {
882         int i;
883         busy_flag = false;
884         if(eventid_busy >= 0) cancel_event(this, eventid_busy);
885         eventid_busy = -1;
886         command_reg = 0;        // D410 (RW)
887         color_reg = 0;          // D411 (RW)
888         mask_reg = 0;           // D412 (RW)
889         cmp_status_reg = 0;     // D413 (RO)
890         for(i = 0; i < 8; i++) cmp_color_data[i] = 0x80; // D413-D41A (WO)
891         for(i = 0; i < 4; i++) tile_reg[i] = 0;        // D41C-D41F (WO)
892         
893         line_addr_offset.d = 0; // D420-D421 (WO)
894         line_pattern.d = 0;     // D422-D423 (WO)
895         line_xbegin.d = 0;      // D424-D425 (WO)
896         line_ybegin.d = 0;      // D426-D427 (WO)
897         line_xend.d = 0;        // D428-D429 (WO)
898         line_yend.d = 0;        // D42A-D42B (WO)
899         oldaddr = 0xffffffff;
900         
901         if(planes >= 4) planes = 4;
902         switch(planes) {    // D41B (RW)
903         case 1:
904                 bank_disable_reg = 0xfe;
905                 break;
906         case 2:
907                 bank_disable_reg = 0xfc;
908                 break;
909         case 3:
910                 bank_disable_reg = 0xf8;
911                 break;
912         case 4:
913                 bank_disable_reg = 0xf0;
914                 break;
915         default:
916                 bank_disable_reg = 0xff;
917                 break;
918         }
919         for(i = 0; i < 4; i++) {
920                 disable_flags[i] = ((bank_disable_reg & (1 << i)) != 0) ? true : false;
921         }
922         for(i = 0; i < 4; i++) {
923                 multi_flags[i] = (((1 << i) & multi_page) != 0) ? true : false;
924         }
925 }
926
927 #define STATE_VERSION 2
928 #include "../../statesub.h"
929
930 void MB61VH010::decl_state(void)
931 {
932         state_entry = new csp_state_utils(STATE_VERSION, this_device_id, _T("MB61VH010"));
933         DECL_STATE_ENTRY_INT(this_device_id);
934         
935         DECL_STATE_ENTRY_UINT8(command_reg);
936         DECL_STATE_ENTRY_UINT8(color_reg);
937         DECL_STATE_ENTRY_UINT8(mask_reg);
938         DECL_STATE_ENTRY_UINT8(cmp_status_reg);
939         DECL_STATE_ENTRY_UINT8(bank_disable_reg);
940         DECL_STATE_ENTRY_UINT8(multi_page);
941         DECL_STATE_ENTRY_UINT32(direct_access_offset);
942         
943         DECL_STATE_ENTRY_UINT8_ARRAY(cmp_color_data, 8);
944         DECL_STATE_ENTRY_UINT8_ARRAY(tile_reg, 4);
945                 
946
947         DECL_STATE_ENTRY_PAIR(line_addr_offset);
948         DECL_STATE_ENTRY_PAIR(line_pattern);
949         DECL_STATE_ENTRY_PAIR(line_xbegin);
950         DECL_STATE_ENTRY_PAIR(line_ybegin);
951         DECL_STATE_ENTRY_PAIR(line_xend);
952         DECL_STATE_ENTRY_PAIR(line_yend);
953                 
954         DECL_STATE_ENTRY_BOOL(busy_flag);
955         DECL_STATE_ENTRY_PAIR(line_style);
956
957         DECL_STATE_ENTRY_UINT32(total_bytes);
958         DECL_STATE_ENTRY_UINT32(oldaddr);
959         DECL_STATE_ENTRY_UINT32(alu_addr);
960
961         DECL_STATE_ENTRY_UINT32(planes);
962         DECL_STATE_ENTRY_BOOL(is_400line);
963         DECL_STATE_ENTRY_UINT32(screen_width);
964         DECL_STATE_ENTRY_UINT32(screen_height);
965
966         DECL_STATE_ENTRY_INT(eventid_busy);
967                 
968 }
969 void MB61VH010::save_state(FILEIO *state_fio)
970 {
971         if(state_entry != NULL) {
972                 state_entry->save_state(state_fio);
973                 out_debug_log(_T("Save State: MB61VH010 : id=%d ver=%d\n"), this_device_id, STATE_VERSION);
974         }
975 }
976
977 bool MB61VH010::load_state(FILEIO *state_fio)
978 {
979         bool mb = false;
980         if(state_entry != NULL) {
981                 mb = state_entry->load_state(state_fio);
982         }
983         out_debug_log(_T("Load State: MB61VH010 : id=%d stat=%s"), this_device_id, (mb) ? _T("OK") : _T("NG"));
984         if(!mb) return false;
985         
986         line_style.w.h = 0;
987         // Update
988         for(int i = 0; i < 4; i++) {
989                 disable_flags[i] = ((bank_disable_reg & (1 << i)) != 0) ? true : false;
990         }
991         for(int i = 0; i < 4; i++) {
992                 multi_flags[i] = (((1 << i) & multi_page) != 0) ? true : false;
993         }
994         return true;
995 }