OSDN Git Service

[VM][FM77AV][MB61VH010] Remove warnings.
[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 MB61VH010::MB61VH010(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
16 {
17         p_emu = parent_emu;
18         p_vm = parent_vm;
19 }
20
21 MB61VH010::~MB61VH010()
22 {
23 }
24
25 uint8 MB61VH010::do_read(uint32 addr, uint32 bank)
26 {
27         uint32 raddr;
28         
29         if(((1 << bank) & multi_page) != 0) return 0xff;
30         if(is_400line) {
31                 if((addr & 0xffff) < 0x8000) {
32                         raddr = (addr  & 0x7fff) | (0x8000 * bank);
33                         return target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS);
34                 }
35         } else {
36                 raddr = (addr & 0x3fff) | (0x4000 * bank);
37                 return target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS);
38         }
39         return 0xff;
40 }
41
42 uint8 MB61VH010::do_write(uint32 addr, uint32 bank, uint8 data)
43 {
44         uint32 raddr;
45         uint8 readdata;
46
47         if(((1 << bank) & multi_page) != 0) return 0xff;
48         if((command_reg & 0x40) != 0) { // Calculate before writing
49                 readdata = do_read(addr, bank);
50                 //readdata = data;
51                 if((command_reg & 0x20) != 0) { // NAND
52                         readdata = readdata & cmp_status_reg;
53                         data = data & (~cmp_status_reg);
54                 } else { // AND
55                         readdata = readdata & (~cmp_status_reg);
56                         data = data & cmp_status_reg;
57                 }
58                 readdata = readdata | data;
59         } else {
60                 readdata = data;
61         }
62         if(is_400line) {
63                 if((addr & 0xffff) < 0x8000) {
64                         //raddr = ((addr + (line_addr_offset.w.l << 1)) & 0x7fff) | (0x8000 * bank);
65                         raddr = (addr & 0x7fff) | (0x8000 * bank);
66                         target->write_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS, readdata);
67                 }
68         } else {
69                 //raddr = ((addr + (line_addr_offset.w.l << 1)) & 0x3fff) | (0x4000 * bank);
70                 raddr = (addr & 0x3fff) | (0x4000 * bank);
71                 target->write_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS, readdata);
72         }
73         return readdata;
74 }
75
76
77 uint8 MB61VH010::do_pset(uint32 addr)
78 {
79         int i;
80         uint32 raddr = addr;  // Use banked ram.
81         uint8 bitmask;
82         uint8 srcdata;
83         int planes_b = planes;
84         if(planes_b >= 4) planes_b = 4;
85         for(i = 0; i < planes_b; i++) {
86                 if((bank_disable_reg & (1 << i)) != 0) {
87                         continue;
88                 }
89                 if((color_reg & (1 << i)) == 0) {
90                         bitmask = 0x00;
91                 } else {
92                         bitmask = 0xff;
93                 }
94                 
95                 srcdata = do_read(addr, i);
96                 bitmask = bitmask & (~mask_reg);
97                 srcdata = srcdata & mask_reg;
98                 srcdata = srcdata | bitmask;
99                 do_write(addr, i, srcdata);
100         }
101         return 0xff;
102 }
103
104 uint8 MB61VH010::do_blank(uint32 addr)
105 {
106         uint32 i;
107         uint8 srcdata;
108
109         if(planes >= 4) planes = 4;
110         for(i = 0; i < planes; i++) {
111                 if((bank_disable_reg & (1 << i)) != 0) {
112                         continue;
113                 }
114                 srcdata = do_read(addr, i);
115                 srcdata = srcdata & mask_reg;
116                 do_write(addr, i, srcdata);
117         }
118         return 0xff;
119 }
120
121 uint8 MB61VH010::do_or(uint32 addr)
122 {
123         uint32 i;
124         uint8 bitmask;
125         uint8 srcdata;
126         
127         if(planes >= 4) planes = 4;
128         for(i = 0; i < planes; i++) {
129                 if((bank_disable_reg & (1 << i)) != 0) {
130                         continue;
131                 }
132                 srcdata = do_read(addr, i);
133                 if((color_reg & (1 << i)) == 0) {
134                         bitmask = srcdata; // srcdata | 0x00
135                 } else {
136                         bitmask = 0xff; // srcdata | 0xff
137                 }
138                 bitmask = bitmask & ~mask_reg;
139                 srcdata = (srcdata & mask_reg) | bitmask;
140                 do_write(addr, i, srcdata);
141         }
142         return 0xff;
143 }
144
145 uint8 MB61VH010::do_and(uint32 addr)
146 {
147         uint32 i;
148         uint8 bitmask;
149         uint8 srcdata;
150
151         if(planes >= 4) planes = 4;
152         for(i = 0; i < planes; i++) {
153                 if((bank_disable_reg & (1 << i)) != 0) {
154                         continue;
155                 }
156                 srcdata = do_read(addr, i);
157                 if((color_reg & (1 << i)) == 0) {
158                         bitmask = 0x00; // srcdata & 0x00
159                 } else {
160                         bitmask = srcdata; // srcdata & 0xff;
161                 }
162                 bitmask = bitmask & ~mask_reg;
163                 srcdata = (srcdata & mask_reg) | bitmask;
164                 do_write(addr, i, srcdata);
165         }
166         return 0xff;
167 }
168
169 uint8 MB61VH010::do_xor(uint32 addr)
170 {
171         uint32 i;
172         uint8 bitmask;
173         uint8 srcdata;
174
175         if(planes >= 4) planes = 4;
176         for(i = 0; i < planes; i++) {
177                 if((bank_disable_reg & (1 << i)) != 0) {
178                         continue;
179                 }
180                 srcdata = do_read(addr, i);
181                 if((color_reg & (1 << i)) == 0) {
182                         bitmask = srcdata ^ 0x00;
183                 } else {
184                         bitmask = srcdata ^ 0xff;
185                 }
186                 bitmask = bitmask & ~mask_reg;
187                 srcdata = (srcdata & mask_reg) | bitmask;
188                 do_write(addr, i, srcdata);
189         }
190         return 0xff;
191 }
192
193 uint8 MB61VH010::do_not(uint32 addr)
194 {
195         uint32 i;
196         uint8 bitmask;
197         uint8 srcdata;
198
199         if(planes >= 4) planes = 4;
200         for(i = 0; i < planes; i++) {
201                 if((bank_disable_reg & (1 << i)) != 0) {
202                         continue;
203                 }
204                 srcdata = do_read(addr, i);
205                 bitmask = ~srcdata;
206                 
207                 bitmask = bitmask & ~mask_reg;
208                 srcdata = (srcdata & mask_reg) | bitmask;
209                 do_write(addr, i, srcdata);
210         }
211         return 0xff;
212 }
213
214
215 uint8 MB61VH010::do_tilepaint(uint32 addr)
216 {
217         uint32 i;
218         uint8 bitmask;
219         uint8 srcdata;
220         //printf("Tilepaint CMD=%02x, ADDR=%04x Planes=%d, disable=%d, tile_reg=(%02x %02x %02x %02x)\n",
221         //      command_reg, addr, planes, bank_disable_reg, tile_reg[0], tile_reg[1], tile_reg[2], tile_reg[3]);
222         if(planes > 4) planes = 4;
223         for(i = 0; i < planes; i++) {
224                 if((bank_disable_reg & (1 << i)) != 0) {
225                         continue;
226                 }
227                 srcdata = do_read(addr, i);
228                 bitmask = tile_reg[i] & (~mask_reg);
229                 srcdata = (srcdata & mask_reg) | bitmask;
230                 do_write(addr, i, srcdata);
231         }
232         return 0xff;
233 }
234
235 uint8 MB61VH010::do_compare(uint32 addr)
236 {
237         uint32 offset = 0x4000;
238         uint8 r, g, b;
239         uint8 disables = ~bank_disable_reg;
240         //uint8 disables = bank_disable_reg;
241         uint8 tmpcol;
242         uint8 tmp_stat = 0;
243         uint8 cmp_reg_bak[8];
244         int k;
245         int i;
246         int j;
247         
248         disables = disables & 0x07;
249         k = 0;
250         for(j = 0; j < 8; j++) {
251                 if((cmp_color_data[j] & 0x80) == 0) {
252                         cmp_reg_bak[k] = cmp_color_data[j] & disables;
253                         k++;
254                 }
255         }
256         cmp_status_reg = 0x00;
257         if(k <= 0) return 0xff;
258         b = r = g = 0;
259         b = do_read(addr, 0);
260         r = do_read(addr, 1);
261         g = do_read(addr, 2);
262         for(i = 0; i < 8; i++) {
263                 tmp_stat <<= 1;
264                 tmpcol  = (b & 0x80) >> 7;
265                 tmpcol  = tmpcol | ((r & 0x80) >> 6);
266                 tmpcol  = tmpcol | ((g & 0x80) >> 5);
267                 //tmpcol |= ((t & 0x80) != 0) ? 8 : 0;
268                 tmpcol = tmpcol & disables;
269                 for(j = 0; j < k; j++) {
270                         if(cmp_reg_bak[j] == tmpcol) {
271                                 tmp_stat = tmp_stat | 0x01;
272                                 goto _l0;
273                         }
274                 }
275 _l0:       
276                 b <<= 1;
277                 r <<= 1;
278                 g <<= 1;
279         }
280         cmp_status_reg = tmp_stat;
281         return 0xff;
282 }
283
284 void MB61VH010::do_alucmds_dmyread(uint32 addr)
285 {
286         if(!is_400line) {
287                 addr = addr & 0x3fff;
288         } else {
289                 if(addr >= 0x8000) {
290                         mask_reg = 0xff;
291                         return;
292                 }
293                 addr = addr & 0x7fff;
294         }
295         if((command_reg & 0x80) == 0) {
296                 return;
297         }
298         //busy_flag = true;
299         cmp_status_reg = 0x00;
300         if((command_reg & 0x40) != 0) do_compare(addr);
301         switch(command_reg & 0x07) {
302                 case 0:
303                         do_pset(addr);
304                         break;
305                 case 1:
306                         do_blank(addr);
307                         break;
308                 case 2:
309                         do_or(addr);
310                         break;
311                 case 3:
312                         do_and(addr);
313                         break;
314                 case 4:
315                         do_xor(addr);
316                         break;
317                 case 5:
318                         do_not(addr);
319                         break;
320                 case 6:
321                         do_tilepaint(addr);
322                         break;
323                 case 7:
324                         do_compare(addr);
325                         break;
326         }
327         //printf("ALU DMYREAD ADDR=%04x, CMD=%02x CMP STATUS=%02x\n", addr, command_reg, cmp_status_reg);
328         //if(eventid_busy >= 0) cancel_event(this, eventid_busy) ;
329         //register_event(this, EVENT_MB61VH010_BUSY_OFF, 1.0 / 16.0, false, &eventid_busy) ;
330 }  
331
332 uint8 MB61VH010::do_alucmds(uint32 addr)
333 {
334         if(!is_400line) {
335                 addr = addr & 0x3fff;
336         } else {
337                 if(addr >= 0x8000) {
338                         mask_reg = 0xff;
339                         return 0xff;
340                 }
341                 addr = addr & 0x7fff;
342         }
343         cmp_status_reg = 0x00;
344         if((command_reg & 0x40) != 0) do_compare(addr);
345         switch(command_reg & 0x07) {
346                 case 0:
347                         return do_pset(addr);
348                         break;
349                 case 1:
350                         return do_blank(addr);
351                         break;
352                 case 2:
353                         return do_or(addr);
354                         break;
355                 case 3:
356                         return do_and(addr);
357                         break;
358                 case 4:
359                         return do_xor(addr);
360                         break;
361                 case 5:
362                         return do_not(addr);
363                         break;
364                 case 6:
365                         return do_tilepaint(addr);
366                         break;
367                 case 7:
368                         return do_compare(addr);
369                         break;
370         }
371         return 0xff;
372 }
373
374 void MB61VH010::do_line(void)
375 {
376         uint32 x_begin = line_xbegin.w.l;
377         uint32 x_end = line_xend.w.l;
378         uint32 y_begin = line_ybegin.w.l;
379         uint32 y_end = line_yend.w.l;
380         int cpx_t = (int)x_begin;
381         int cpy_t = (int)y_begin;
382         int ax = (int)x_end - (int)x_begin;
383         int ay = (int)y_end - (int)y_begin;
384         int diff = 0;
385         int count = 0;
386         int xcount;
387         int ycount;
388         uint8 mask_bak = mask_reg;
389         uint16 tmp8a;
390         uint8 vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
391         double usec;
392         bool lastflag = false;
393         
394
395         oldaddr = 0xffffffff;
396         if ((x_begin >= screen_width) && (x_end >= screen_width)) return;
397         if ((y_begin >= screen_height) && (y_end >= screen_height)) return;
398
399         line_style = line_pattern;
400         busy_flag = true;
401         total_bytes = 0;
402         
403         mask_reg = 0xff;
404         if ((line_style.b.h & 0x80) != 0) {
405                 mask_reg &= ~vmask[cpx_t & 7];
406         }
407         tmp8a = ((line_style.b.h & 0x80) >> 7) & 0x01;
408         line_style.w.l = (line_style.w.l << 1) | tmp8a;
409    
410         xcount = abs(ax);
411         ycount = abs(ay);
412         //lastflag = put_dot(x_begin, y_begin);
413         if(ycount == 0) {
414                 if(ax > 0) {
415                         if(x_end >= screen_width) x_end = screen_width - 1;
416                         for(; cpx_t <= (int)x_end; cpx_t++) {
417                                 lastflag = put_dot(cpx_t, cpy_t);
418                         }
419                 } else {
420                         if(x_end < 0) x_end = 0;
421                         for(; cpx_t >= (int)x_end; cpx_t--) {
422                                 lastflag = put_dot(cpx_t, cpy_t);
423                         }
424                 }
425         } else if(xcount == 0) {
426                 if(ay > 0) {
427                         if(y_end >= screen_height) y_end = screen_height - 1;
428                         for(; cpy_t <= (int)y_end; cpy_t++) {
429                                 lastflag = put_dot(cpx_t, cpy_t);
430                         }
431                 } else {
432                         //if(y_end < 0) y_end = 0;
433                         for(; cpy_t  >= (int)y_end; cpy_t--) {
434                                 lastflag = put_dot(cpx_t, cpy_t);
435                         }
436                 }
437         } else if(xcount >= ycount) {
438                 diff = (ycount * 32768) / xcount;
439                 if(ax < 0) {
440                         if(x_end < 0) xcount = x_begin;
441                 } else {
442                         //if(x_end >= screen_width) xcount = screen_width - x_begin - 1;
443                         if(x_end >= screen_width) xcount = (int)screen_width - (int)x_begin;
444                 }
445                 for(; xcount >= 0; xcount-- ) {
446                         lastflag = put_dot(cpx_t, cpy_t);
447                         count += diff;
448                         if(count > 16384) {
449                                 if(ay < 0) {
450                                         if(cpy_t > (int)y_end) cpy_t--;
451                                 } else {
452                                         if(cpy_t < (int)y_end) cpy_t++;
453                                 }
454                                 count -= 32768;
455                         }
456                         if(ax > 0) {
457                                 cpx_t++;
458                         } else if(ax < 0) {
459                                 cpx_t--;
460                         }
461                 }
462         } else if(xcount == ycount) {
463                 //xcount++;
464                 if(ax < 0) {
465                         xcount = x_begin;
466                 } else {
467                         //if(x_end >= screen_width) xcount = (int)(screen_width - x_begin) - 1;
468                         if (x_end >= screen_width) xcount = (int)screen_width - (int)x_begin;
469                 }
470                 for(; xcount >= 0; xcount-- ) {
471                         lastflag = put_dot(cpx_t, cpy_t);
472                         if(ay > 0) {
473                                 cpy_t++;
474                         } else {
475                                 cpy_t--;
476                         }
477                         if(ax > 0) {
478                                 cpx_t++;
479                         } else if(ax < 0) {
480                                 cpx_t--;
481                         }
482                         //total_bytes++;
483                 }
484         } else { // (abs(ax) <= abs(ay)
485                 diff = (xcount  * 32768) / ycount;
486                 if(ay < 0) {
487                         if(y_end < 0) ycount = y_begin;
488                 } else {
489                         if(y_end >= screen_height) ycount = screen_height - y_begin - 1;
490                 }
491                 for(; ycount >= 0; ycount--) {
492                         lastflag = put_dot(cpx_t, cpy_t);
493                         count += diff;
494                         if(count > 16384) {
495                                 if(ax < 0) {
496                                         if(cpx_t > (int)x_end) cpx_t--;
497                                 } else if(ax > 0) {
498                                         if(cpx_t < (int)x_end) cpx_t++;
499                                 }
500                                 count -= 32768;
501                         }
502                         if(ay > 0) {
503                                 cpy_t++;
504                         } else {
505                                 cpy_t--;
506                         }
507                         //total_bytes++;
508                 }
509         }
510         //lastflag = put_dot(x_end, y_end);
511         if(!lastflag) total_bytes++;
512         do_alucmds(alu_addr);
513    
514         if(total_bytes > 0) { // Over 0.5us
515                 usec = (double)total_bytes / 16.0;
516                 if(eventid_busy >= 0) cancel_event(this, eventid_busy) ;
517                 register_event(this, EVENT_MB61VH010_BUSY_OFF, usec, false, &eventid_busy) ;
518         } else {
519                 busy_flag = false;
520         }
521         mask_reg = mask_bak;
522 }
523
524 bool MB61VH010::put_dot(int x, int y)
525 {
526         uint8 vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
527         uint16 tmp8a;
528         bool flag = false;
529         
530         if((x < 0) || (y < 0)) return flag;
531         if((x >= (int)screen_width) || (y >= (int)screen_height)) return flag;
532         if((command_reg & 0x80) == 0) return flag;
533         
534         alu_addr = ((y * screen_width) >> 3) + (x >> 3);
535         alu_addr = alu_addr + ((line_addr_offset.w.l << 1) & 0x3ffe);
536         alu_addr = alu_addr & 0x7fff;
537         if(!is_400line) alu_addr = alu_addr & 0x3fff;
538         //if(oldaddr == 0xffffffff) oldaddr = alu_addr;
539         
540         if(oldaddr != alu_addr) {
541                 if(oldaddr == 0xffffffff) oldaddr = alu_addr;
542                 //printf("** %d %d %04x %04x %02x\n", x, y, line_addr_offset.w, alu_addr, command_reg );
543                 do_alucmds(oldaddr);
544                 mask_reg = 0xff;
545                 oldaddr = alu_addr;
546                 flag = true;
547                 total_bytes++;
548         }
549         //printf("** %d %d %04x %04x %02x\n", x, y, line_addr_offset.w, alu_addr, command_reg );
550         
551         if((line_style.b.h & 0x80) != 0) {
552                 mask_reg &= ~vmask[x & 7];
553         }
554         //tmp8a = (line_style.w.l & 0x8000) >> 15;
555         tmp8a = ((line_style.b.h & 0x80) >> 7) & 0x01;
556         line_style.w.l = (line_style.w.l << 1) | tmp8a;
557         return flag;
558 }
559
560 void MB61VH010::write_data8(uint32 id, uint32 data)
561 {
562         //printf("ALU: ADDR=%02x DATA=%02x\n", id, data);
563         if(id == ALU_CMDREG) {
564                 command_reg = data;
565                 return;
566         }
567         switch(id) {
568                 case ALU_LOGICAL_COLOR:
569                         color_reg = data;
570                         break;
571                 case ALU_WRITE_MASKREG:
572                         mask_reg = data;
573                         break;
574                 case ALU_BANK_DISABLE:
575                         bank_disable_reg = data;
576                         break;
577                 case ALU_TILEPAINT_B:
578                         tile_reg[0] = data;
579                         break;
580                 case ALU_TILEPAINT_R:
581                         tile_reg[1] = data;
582                         break;
583                 case ALU_TILEPAINT_G:
584                         tile_reg[2] = data;
585                         break;
586                 case ALU_TILEPAINT_L:
587                         tile_reg[3] = data;
588                         break;
589                 case ALU_OFFSET_REG_HIGH:
590                         line_addr_offset.b.h = data;
591                         break;
592                 case ALU_OFFSET_REG_LO:
593                         line_addr_offset.b.l = data;
594                         break;
595                 case ALU_LINEPATTERN_REG_HIGH:
596                         line_pattern.b.h = data;
597                         break;
598                 case ALU_LINEPATTERN_REG_LO:
599                         line_pattern.b.l = data;
600                         break;
601                 case ALU_LINEPOS_START_X_HIGH:
602                         line_xbegin.b.h = data;
603                         break;
604                 case ALU_LINEPOS_START_X_LOW:  
605                         line_xbegin.b.l = data;
606                         break;
607                 case ALU_LINEPOS_START_Y_HIGH:
608                         line_ybegin.b.h = data;
609                         break;
610                 case ALU_LINEPOS_START_Y_LOW:  
611                         line_ybegin.b.l = data;
612                         break;
613                 case ALU_LINEPOS_END_X_HIGH:
614                         line_xend.b.h = data;
615                         break;
616                 case ALU_LINEPOS_END_X_LOW:  
617                         line_xend.b.l = data;
618                         break;
619                 case ALU_LINEPOS_END_Y_HIGH:
620                         line_yend.b.h = data;
621                         break;
622                 case ALU_LINEPOS_END_Y_LOW:
623                         line_yend.b.l = data;
624                         do_line();
625                         break;
626                 default:
627                         if((id >= (ALU_CMPDATA_REG + 0)) && (id < (ALU_CMPDATA_REG + 8))) {
628                                 cmp_color_data[id - ALU_CMPDATA_REG] = data;
629                         } else  if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0x18000))) {
630                                 uint32 raddr = id - ALU_WRITE_PROXY;
631                                 //if(is_400line) {
632                                 //      raddr = raddr & 0x7fff;
633                                 //} else {
634                                 //      raddr = raddr & 0x3fff;
635                                 //}
636                                 do_alucmds_dmyread(raddr);
637                         }
638                         break;
639         }
640 }
641
642 uint32 MB61VH010::read_data8(uint32 id)
643 {
644         uint32 raddr;  
645         switch(id) {
646                 case ALU_CMDREG:
647                         return (uint32)command_reg;
648                         break;
649                 case ALU_LOGICAL_COLOR:
650                         return (uint32)color_reg;
651                         break;
652                 case ALU_WRITE_MASKREG:
653                         return (uint32)mask_reg;
654                         break;
655                 case ALU_CMP_STATUS_REG:
656                         return (uint32)cmp_status_reg;
657                         break;
658                 case ALU_BANK_DISABLE:
659                         return (uint32)bank_disable_reg;
660                         break;
661                 default:
662                         if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0x18000))) {
663                                 uint32 dmydata;
664                                 raddr = id - ALU_WRITE_PROXY;
665                                 if(is_400line) {
666                                         raddr = raddr & 0x7fff;
667                                 } else {
668                                         raddr = raddr & 0x3fff;
669                                 }
670                                 //dmydata = target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS);
671                                 do_alucmds_dmyread(raddr);
672                                 raddr = (id - ALU_WRITE_PROXY) & 0xbfff;
673                                 dmydata = target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS);
674                                 return dmydata;
675                         }
676                         return 0xffffffff;
677                         break;
678         }
679 }
680
681 uint32 MB61VH010::read_signal(int id)
682 {
683         uint32 val = 0x00000000;
684         switch(id) {
685                 case SIG_ALU_BUSYSTAT:
686                         if(busy_flag) val = 0xffffffff;
687                         break;
688         }
689         return val;
690 }
691
692 void MB61VH010::write_signal(int id, uint32 data, uint32 mask)
693 {
694         bool flag = ((data & mask) != 0);
695         switch(id) {
696                 case SIG_ALU_400LINE:
697                         is_400line = flag;
698                         break;
699                 case SIG_ALU_MULTIPAGE:
700                         multi_page = (data & mask) & 0x07;
701                         break;
702                 case SIG_ALU_PLANES:
703                         planes = (data & mask) & 0x07;
704                         if(planes >= 4) planes = 4;
705                         break;
706                 case SIG_ALU_X_WIDTH:
707                         screen_width = (data << 3) & 0x3ff;
708                         break;
709                 case SIG_ALU_Y_HEIGHT:
710                         screen_height = data & 0x3ff;
711                         break;
712         }
713 }
714
715 void MB61VH010::event_callback(int event_id, int err)
716 {
717         switch(event_id) {
718                 case EVENT_MB61VH010_BUSY_ON:
719                         busy_flag = true;
720                         if(eventid_busy >= 0) cancel_event(this, eventid_busy);
721                         eventid_busy = -1;
722                         break;
723                 case EVENT_MB61VH010_BUSY_OFF:
724                         busy_flag = false;
725                         eventid_busy = -1;
726                         break;
727         }
728 }
729
730 void MB61VH010::initialize(void)
731 {
732         busy_flag = false;
733         is_400line = false;
734         eventid_busy = -1;
735         multi_page = 0x00;
736         planes = 3;
737         screen_width = 640;
738         screen_height = 200;
739 }
740
741 void MB61VH010::reset(void)
742 {
743         int i;
744         busy_flag = false;
745         if(eventid_busy >= 0) cancel_event(this, eventid_busy);
746         eventid_busy = -1;
747         
748         command_reg = 0;        // D410 (RW)
749         color_reg = 0;          // D411 (RW)
750         mask_reg = 0;           // D412 (RW)
751         cmp_status_reg = 0;     // D413 (RO)
752         for(i = 0; i < 8; i++) cmp_color_data[i] = 0x80; // D413-D41A (WO)
753         bank_disable_reg = 0;   // D41B (RW)
754         for(i = 0; i < 4; i++) tile_reg[i] = 0;        // D41C-D41F (WO)
755         
756         line_addr_offset.d = 0; // D420-D421 (WO)
757         line_pattern.d = 0;     // D422-D423 (WO)
758         line_xbegin.d = 0;      // D424-D425 (WO)
759         line_ybegin.d = 0;      // D426-D427 (WO)
760         line_xend.d = 0;        // D428-D429 (WO)
761         line_yend.d = 0;        // D42A-D42B (WO)
762         oldaddr = 0xffffffff;
763         
764         if(planes >= 4) planes = 4;
765 }
766
767 #define STATE_VERSION 1
768 void MB61VH010::save_state(FILEIO *state_fio)
769 {
770         int i;
771         state_fio->FputUint32(STATE_VERSION);
772         state_fio->FputInt32(this_device_id);
773
774         { // V1
775                 state_fio->FputUint8(command_reg);
776                 state_fio->FputUint8(color_reg);
777                 state_fio->FputUint8(mask_reg);
778                 state_fio->FputUint8(cmp_status_reg);
779                 for(i = 0; i < 8; i++)  state_fio->FputUint8(cmp_color_data[i]);
780                 state_fio->FputUint8(bank_disable_reg);
781                 for(i = 0; i < 4; i++)  state_fio->FputUint8(tile_reg[i]);
782                 state_fio->FputUint8(multi_page);
783                 
784                 state_fio->FputUint32_BE(line_addr_offset.d);
785                 state_fio->FputUint16_BE(line_pattern.w.l);
786                 state_fio->FputUint16_BE(line_xbegin.w.l);
787                 state_fio->FputUint16_BE(line_ybegin.w.l);
788                 state_fio->FputUint16_BE(line_xend.w.l);
789                 state_fio->FputUint16_BE(line_yend.w.l);
790                 
791                 state_fio->FputBool(busy_flag);
792                 state_fio->FputInt32_BE(eventid_busy);
793
794                 state_fio->FputUint32_BE(total_bytes);
795                 state_fio->FputUint32_BE(oldaddr);
796                 state_fio->FputUint32_BE(alu_addr);
797
798                 state_fio->FputUint32_BE(planes);
799                 state_fio->FputBool(is_400line);
800                 state_fio->FputUint32_BE(screen_width);
801                 state_fio->FputUint32_BE(screen_height);
802
803                 state_fio->FputUint16_BE(line_style.w.l);
804         }
805    
806 }
807
808 bool MB61VH010::load_state(FILEIO *state_fio)
809 {
810         uint32 version = state_fio->FgetUint32();
811         int i;
812    
813         if(this_device_id != state_fio->FgetInt32()) return false;
814         if(version >= 1) {
815                 command_reg = state_fio->FgetUint8();
816                 color_reg = state_fio->FgetUint8();
817                 mask_reg = state_fio->FgetUint8();
818                 cmp_status_reg = state_fio->FgetUint8();
819                 for(i = 0; i < 8; i++)  cmp_color_data[i] = state_fio->FgetUint8();
820                 bank_disable_reg = state_fio->FgetUint8();
821                 for(i = 0; i < 4; i++)  tile_reg[i] = state_fio->FgetUint8();
822                 multi_page = state_fio->FgetUint8();
823
824                 line_addr_offset.d = state_fio->FgetUint32_BE();
825                 line_pattern.d = 0;
826                 line_xbegin.d = 0;
827                 line_ybegin.d = 0;
828                 line_xend.d = 0;
829                 line_yend.d = 0;
830            
831                 line_pattern.w.l = state_fio->FgetUint16_BE();
832                 line_xbegin.w.l = state_fio->FgetUint16_BE();
833                 line_ybegin.w.l = state_fio->FgetUint16_BE();
834                 line_xend.w.l = state_fio->FgetUint16_BE();
835                 line_yend.w.l = state_fio->FgetUint16_BE();
836
837                 busy_flag = state_fio->FgetBool();
838                 eventid_busy = state_fio->FgetInt32_BE();
839                 
840                 total_bytes = state_fio->FgetUint32_BE();
841                 oldaddr = state_fio->FgetUint32_BE();
842                 alu_addr = state_fio->FgetUint32_BE();
843
844                 planes = state_fio->FgetUint32_BE();
845                 is_400line = state_fio->FgetBool();
846                 screen_width = state_fio->FgetUint32_BE();
847                 screen_height = state_fio->FgetUint32_BE();
848
849                 line_style.d = 0;
850                 line_style.w.l = state_fio->FgetUint16_BE();
851         }
852         return true;
853 }