OSDN Git Service

[VM][FM77AV][MB61VH010] Fix incorrect drawing line.
[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                         if((command_reg & 0x40) != 0) return do_compare(addr);
369                         break;
370         }
371         return 0xff;
372 }
373
374 void MB61VH010::do_line(void)
375 {
376         int x_begin = line_xbegin.w.l;
377         int x_end = line_xend.w.l;
378         int y_begin = line_ybegin.w.l;
379         int y_end = line_yend.w.l;
380         int cpx_t = x_begin;
381         int cpy_t = y_begin;
382         int ax = x_end - x_begin;
383         int ay = y_end - 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         //printf("Line: (%d,%d) - (%d,%d) CMD=%02x\n", x_begin, y_begin, x_end, y_end, command_reg);  
392         double usec;
393         bool lastflag = false;
394         
395         //is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false;
396         planes = target->read_signal(SIG_DISPLAY_PLANES) & 0x07;
397         screen_width = target->read_signal(SIG_DISPLAY_X_WIDTH) * 8;
398         screen_height = target->read_signal(SIG_DISPLAY_Y_HEIGHT);
399
400         //if((command_reg & 0x80) == 0) return;
401         oldaddr = 0xffffffff;
402         //alu_addr = 0xffffffff;
403
404         
405         line_style = line_pattern;
406         busy_flag = true;
407         total_bytes = 1;
408         
409         mask_reg = 0xff;
410         if((line_style.b.h & 0x80) != 0) {
411                 mask_reg &= ~vmask[cpx_t & 7];
412         }
413         tmp8a = (line_style.w.l & 0x8000) >> 15;
414         line_style.w.l = (line_style.w.l << 1) | tmp8a;
415    
416         xcount = abs(ax);
417         ycount = abs(ay);
418         lastflag = put_dot(x_begin, y_begin);
419         if(ycount == 0) {
420                 if(xcount != 0) {
421                         if(ax > 0) {
422                                 for(; cpx_t <= x_end; cpx_t++) {
423                                         lastflag = put_dot(cpx_t, cpy_t);
424                                 }
425                         } else {
426                                 for(; cpx_t >= x_end; cpx_t--) {
427                                         lastflag = put_dot(cpx_t, cpy_t);
428                                 }
429                         }
430                         //lastflag = true;
431                 }
432         } else if(xcount == 0) {
433                 if(ay > 0) {
434                         for(; cpy_t <= y_end; cpy_t++) {
435                                 lastflag = put_dot(cpx_t, cpy_t);
436                         }
437                 } else {
438                         for(; cpy_t  >= y_end; cpy_t--) {
439                                 lastflag = put_dot(cpx_t, cpy_t);
440                         }
441                 }
442                 //lastflag = true;
443         } else if(xcount >= ycount) {
444                 //xcount++;
445                 //diff = ((ycount + 1) * 32768) / xcount;
446                 diff = (ycount * 32768) / xcount;
447                 for(; xcount >= 0; xcount-- ) {
448                         lastflag = put_dot(cpx_t, cpy_t);
449                         count += diff;
450                         if(count > 16384) {
451                                 if(ay < 0) {
452                                         if(cpy_t > y_end) cpy_t--;
453                                 } else {
454                                         if(cpy_t < y_end) cpy_t++;
455                                 }
456                                 count -= 32768;
457                                 //lastflag = put_dot(cpx_t, cpy_t);
458                         }
459                         if(ax > 0) {
460                                 cpx_t++;
461                         } else if(ax < 0) {
462                                 cpx_t--;
463                         }
464                 }
465         } else { // (abs(ax) <= abs(ay)
466                 //diff = ((xcount + 1) * 32768) / ycount;
467                 diff = (xcount  * 32768) / ycount;
468                 for(; ycount >= 0; ycount--) {
469                         lastflag = put_dot(cpx_t, cpy_t);
470                         count += diff;
471                         if(count > 16384) {
472                                 if(ax < 0) {
473                                         if(cpx_t > x_end) cpx_t--;
474                                 } else if(ax > 0) {
475                                         if(cpx_t < x_end) cpx_t++;
476                                 }
477                                 count -= 32768;
478                                 //lastflag = put_dot(cpx_t, cpy_t);
479                         }
480                         if(ay > 0) {
481                                 cpy_t++;
482                         } else {
483                                 cpy_t--;
484                         }
485                         //total_bytes++;
486                 }
487         }
488         lastflag = put_dot(x_end, y_end);
489         if(!lastflag) total_bytes++;
490         do_alucmds(alu_addr);
491
492         //if(total_bytes > 8) { // Over 0.5us
493         usec = (double)total_bytes / 16.0;
494         if(eventid_busy >= 0) cancel_event(this, eventid_busy) ;
495         register_event(this, EVENT_MB61VH010_BUSY_OFF, usec, false, &eventid_busy) ;
496         mask_reg = mask_bak;
497 }
498
499 bool MB61VH010::put_dot(int x, int y)
500 {
501         uint8 vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
502         uint16 tmp8a;
503         bool flag = false;
504         
505         if((x < 0) || (y < 0)) return flag;
506         if((x >= screen_width) || (y >= screen_height)) return flag;
507         if((command_reg & 0x80) == 0) return flag;
508         
509         alu_addr = ((y * screen_width) >> 3) + (x >> 3);
510         alu_addr = alu_addr + (line_addr_offset.w.l << 1);
511         alu_addr = alu_addr & 0x7fff;
512         if(!is_400line) alu_addr = alu_addr & 0x3fff;
513         
514         if(oldaddr != alu_addr) {
515                 if(oldaddr == 0xffffffff) oldaddr = alu_addr;
516                 do_alucmds(oldaddr);
517                 mask_reg = 0xff;
518                 oldaddr = alu_addr;
519                 flag = true;
520                 total_bytes++;
521         }
522         
523         if((line_style.b.h & 0x80) != 0) {
524                 mask_reg &= ~vmask[x & 7];
525         }
526         tmp8a = (line_style.w.l & 0x8000) >> 15;
527         line_style.w.l = (line_style.w.l << 1) | tmp8a;
528         return flag;
529 }
530
531 void MB61VH010::write_data8(uint32 id, uint32 data)
532 {
533         //printf("ALU: ADDR=%02x DATA=%02x\n", id, data);
534         if(id == ALU_CMDREG) {
535                 command_reg = data;
536                 return;
537         }
538         switch(id) {
539                 case ALU_LOGICAL_COLOR:
540                         color_reg = data;
541                         break;
542                 case ALU_WRITE_MASKREG:
543                         mask_reg = data;
544                         break;
545                 case ALU_BANK_DISABLE:
546                         bank_disable_reg = data;
547                         break;
548                 case ALU_TILEPAINT_B:
549                         tile_reg[0] = data;
550                         break;
551                 case ALU_TILEPAINT_R:
552                         tile_reg[1] = data;
553                         break;
554                 case ALU_TILEPAINT_G:
555                         tile_reg[2] = data;
556                         break;
557                 case ALU_TILEPAINT_L:
558                         tile_reg[3] = data;
559                         break;
560                 case ALU_OFFSET_REG_HIGH:
561                         line_addr_offset.b.h = data;
562                         break;
563                 case ALU_OFFSET_REG_LO:
564                         line_addr_offset.b.l = data;
565                         break;
566                 case ALU_LINEPATTERN_REG_HIGH:
567                         line_pattern.b.h = data;
568                         break;
569                 case ALU_LINEPATTERN_REG_LO:
570                         line_pattern.b.l = data;
571                         break;
572                 case ALU_LINEPOS_START_X_HIGH:
573                         line_xbegin.b.h = data;
574                         break;
575                 case ALU_LINEPOS_START_X_LOW:  
576                         line_xbegin.b.l = data;
577                         break;
578                 case ALU_LINEPOS_START_Y_HIGH:
579                         line_ybegin.b.h = data;
580                         break;
581                 case ALU_LINEPOS_START_Y_LOW:  
582                         line_ybegin.b.l = data;
583                         break;
584                 case ALU_LINEPOS_END_X_HIGH:
585                         line_xend.b.h = data;
586                         break;
587                 case ALU_LINEPOS_END_X_LOW:  
588                         line_xend.b.l = data;
589                         break;
590                 case ALU_LINEPOS_END_Y_HIGH:
591                         line_yend.b.h = data;
592                         break;
593                 case ALU_LINEPOS_END_Y_LOW:
594                         line_yend.b.l = data;
595                         do_line();
596                         break;
597                 default:
598                         if((id >= (ALU_CMPDATA_REG + 0)) && (id < (ALU_CMPDATA_REG + 8))) {
599                                 cmp_color_data[id - ALU_CMPDATA_REG] = data;
600                         } else  if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0x18000))) {
601                                 uint32 raddr = id - ALU_WRITE_PROXY;
602                                 if(is_400line) {
603                                         raddr = raddr & 0x7fff;
604                                 } else {
605                                         raddr = raddr & 0x3fff;
606                                 }
607                                 do_alucmds_dmyread(raddr);
608                         }
609                         break;
610         }
611 }
612
613 uint32 MB61VH010::read_data8(uint32 id)
614 {
615         uint32 raddr;  
616         switch(id) {
617                 case ALU_CMDREG:
618                         return (uint32)command_reg;
619                         break;
620                 case ALU_LOGICAL_COLOR:
621                         return (uint32)color_reg;
622                         break;
623                 case ALU_WRITE_MASKREG:
624                         return (uint32)mask_reg;
625                         break;
626                 case ALU_CMP_STATUS_REG:
627                         return (uint32)cmp_status_reg;
628                         break;
629                 case ALU_BANK_DISABLE:
630                         return (uint32)bank_disable_reg;
631                         break;
632                 default:
633                         if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0x18000))) {
634                                 uint32 dmydata;
635                                 raddr = id - ALU_WRITE_PROXY;
636                                 //is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false;
637                                 if(is_400line) {
638                                         raddr = raddr & 0x7fff;
639                                 } else {
640                                         raddr = raddr & 0x3fff;
641                                 }
642                                 //dmydata = target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS);
643                                 do_alucmds_dmyread(raddr);
644                                 dmydata = target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS);
645                                 return dmydata;
646                         }
647                         return 0xffffffff;
648                         break;
649         }
650 }
651
652 uint32 MB61VH010::read_signal(int id)
653 {
654         uint32 val = 0x00000000;
655         switch(id) {
656                 case SIG_ALU_BUSYSTAT:
657                         if(busy_flag) val = 0xffffffff;
658                         break;
659         }
660         return val;
661 }
662
663 void MB61VH010::write_signal(int id, uint32 data, uint32 mask)
664 {
665         bool flag = ((data & mask) != 0);
666         switch(id) {
667                 case SIG_ALU_400LINE:
668                         is_400line = flag;
669                         break;
670                 case SIG_ALU_MULTIPAGE:
671                         multi_page = (data & mask) & 0x07;
672                         break;
673         }
674 }
675
676 void MB61VH010::event_callback(int event_id, int err)
677 {
678         switch(event_id) {
679                 case EVENT_MB61VH010_BUSY_ON:
680                         busy_flag = true;
681                         if(eventid_busy >= 0) cancel_event(this, eventid_busy);
682                         eventid_busy = -1;
683                         break;
684                 case EVENT_MB61VH010_BUSY_OFF:
685                         busy_flag = false;
686                         eventid_busy = -1;
687                         break;
688         }
689 }
690
691 void MB61VH010::initialize(void)
692 {
693         busy_flag = false;
694         is_400line = false;
695         eventid_busy = -1;
696         multi_page = 0x00;
697 }
698
699 void MB61VH010::reset(void)
700 {
701         int i;
702         busy_flag = false;
703         if(eventid_busy >= 0) cancel_event(this, eventid_busy);
704         eventid_busy = -1;
705         
706         command_reg = 0;        // D410 (RW)
707         color_reg = 0;          // D411 (RW)
708         mask_reg = 0;           // D412 (RW)
709         cmp_status_reg = 0;     // D413 (RO)
710         for(i = 0; i < 8; i++) cmp_color_data[i] = 0x80; // D413-D41A (WO)
711         bank_disable_reg = 0;   // D41B (RW)
712         for(i = 0; i < 4; i++) tile_reg[i] = 0;        // D41C-D41F (WO)
713         
714         line_addr_offset.d = 0; // D420-D421 (WO)
715         line_pattern.d = 0;     // D422-D423 (WO)
716         line_xbegin.d = 0;      // D424-D425 (WO)
717         line_ybegin.d = 0;      // D426-D427 (WO)
718         line_xend.d = 0;        // D428-D429 (WO)
719         line_yend.d = 0;        // D42A-D42B (WO)
720
721         oldaddr = 0xffffffff;
722         
723         planes = target->read_signal(SIG_DISPLAY_PLANES) & 0x07;
724         if(planes >= 4) planes = 4;
725         //is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false;
726         
727         screen_width = target->read_signal(SIG_DISPLAY_X_WIDTH) * 8;
728         screen_height = target->read_signal(SIG_DISPLAY_Y_HEIGHT);
729 }