OSDN Git Service

[Build][FM7][VM] Reduce warnig when compiling (with VC2013).
[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) & read_signal(SIG_DISPLAY_MULTIPAGE)) != 0) return 0xff;
30         //if(is_400line) offset = 0x8000;
31         
32         if(is_400line) {
33                 if((addr & 0xffff) < 0x8000) {
34                         //raddr = ((addr + (line_addr_offset.w.l << 1)) & 0x7fff) | (0x8000 * bank);
35                         raddr = (addr  & 0x7fff) | (0x8000 * bank);
36                         return target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS);
37                 }
38                 return 0xff;
39         } else {
40                 //raddr = ((addr + (line_addr_offset.w.l << 1)) & 0x3fff) | (0x4000 * bank);
41                 raddr = (addr & 0x3fff) | (0x4000 * bank);
42                 return target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS);
43         }
44         return 0xff;
45 }
46
47 uint8 MB61VH010::do_write(uint32 addr, uint32 bank, uint8 data)
48 {
49         uint32 raddr;
50         uint8 readdata;
51
52         if(((1 << bank) & read_signal(SIG_DISPLAY_MULTIPAGE)) != 0) return 0xff;
53         if((command_reg & 0x40) != 0) { // Calculate before writing
54                 readdata = do_read(addr, bank);
55                 //readdata = data;
56                 if((command_reg & 0x20) != 0) { // NAND
57                         readdata = readdata & cmp_status_reg;
58                         data = data & (~cmp_status_reg);
59                         readdata = readdata | data;
60                 } else { // AND
61                         readdata = readdata & (~cmp_status_reg);
62                         data = data & cmp_status_reg;
63                         readdata = readdata | data;
64                 }
65         } else {
66                 readdata = data;
67         }
68         if(is_400line) {
69                 if((addr & 0xffff) < 0x8000) {
70                         //raddr = ((addr + (line_addr_offset.w.l << 1)) & 0x7fff) | (0x8000 * bank);
71                         raddr = (addr & 0x7fff) | (0x8000 * bank);
72                         target->write_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS, readdata);
73                 }
74         } else {
75                 //raddr = ((addr + (line_addr_offset.w.l << 1)) & 0x3fff) | (0x4000 * bank);
76                 raddr = (addr & 0x3fff) | (0x4000 * bank);
77                 target->write_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS, readdata);
78         }
79         return readdata;
80 }
81
82
83 uint8 MB61VH010::do_pset(uint32 addr)
84 {
85         int i;
86         uint32 raddr = addr;  // Use banked ram.
87         uint8 bitmask;
88         uint8 srcdata;
89         int planes_b = planes;
90
91         if(planes_b >= 4) planes_b = 4;
92         for(i = 0; i < planes_b; i++) {
93                 if((bank_disable_reg & (1 << i)) != 0) {
94                                 continue;
95                 }
96                 if((color_reg & (1 << i)) == 0) {
97                         bitmask = 0x00;
98                 } else {
99                         bitmask = 0xff;
100                 }
101                 
102                 srcdata = do_read(addr, i);
103                 bitmask = bitmask & (~mask_reg);
104                 srcdata = srcdata & mask_reg;
105                 srcdata = srcdata | bitmask;
106                 do_write(addr, i, srcdata);
107         }
108         return 0xff;
109 }
110
111 uint8 MB61VH010::do_blank(uint32 addr)
112 {
113         uint32 i;
114         uint8 srcdata;
115
116         if(planes >= 4) planes = 4;
117         for(i = 0; i < planes; i++) {
118                 if((bank_disable_reg & (1 << i)) != 0) {
119                         continue;
120                 }
121                 srcdata = do_read(addr, i);
122                 srcdata = srcdata & mask_reg;
123                 do_write(addr, i, srcdata);
124         }
125         return 0xff;
126 }
127
128 uint8 MB61VH010::do_or(uint32 addr)
129 {
130         uint32 i;
131         uint8 bitmask;
132         uint8 srcdata;
133         
134         if(planes >= 4) planes = 4;
135         for(i = 0; i < planes; i++) {
136                 if((bank_disable_reg & (1 << i)) != 0) {
137                         continue;
138                 }
139                 srcdata = do_read(addr, i);
140                 if((color_reg & (1 << i)) == 0) {
141                         bitmask = srcdata; // srcdata | 0x00
142                 } else {
143                         bitmask = 0xff; // srcdata | 0xff
144                 }
145                 bitmask = bitmask & ~mask_reg;
146                 srcdata = (srcdata & mask_reg) | bitmask;
147                 do_write(addr, i, srcdata);
148         }
149         return 0xff;
150 }
151
152 uint8 MB61VH010::do_and(uint32 addr)
153 {
154         uint32 i;
155         uint8 bitmask;
156         uint8 srcdata;
157
158         if(planes >= 4) planes = 4;
159         for(i = 0; i < planes; i++) {
160                 if((bank_disable_reg & (1 << i)) != 0) {
161                         continue;
162                 }
163                 srcdata = do_read(addr, i);
164                 if((color_reg & (1 << i)) == 0) {
165                         bitmask = 0x00; // srcdata & 0x00
166                 } else {
167                         bitmask = srcdata; // srcdata & 0xff;
168                 }
169                 bitmask = bitmask & ~mask_reg;
170                 srcdata = (srcdata & mask_reg) | bitmask;
171                 do_write(addr, i, srcdata);
172         }
173         return 0xff;
174 }
175
176 uint8 MB61VH010::do_xor(uint32 addr)
177 {
178         uint32 i;
179         uint8 bitmask;
180         uint8 srcdata;
181
182         if(planes >= 4) planes = 4;
183         for(i = 0; i < planes; i++) {
184                 if((bank_disable_reg & (1 << i)) != 0) {
185                         continue;
186                 }
187                 srcdata = do_read(addr, i);
188                 if((color_reg & (1 << i)) == 0) {
189                         bitmask = srcdata ^ 0x00;
190                 } else {
191                         bitmask = srcdata ^ 0xff;
192                 }
193                 bitmask = bitmask & ~mask_reg;
194                 srcdata = (srcdata & mask_reg) | bitmask;
195                 do_write(addr, i, srcdata);
196         }
197         return 0xff;
198 }
199
200 uint8 MB61VH010::do_not(uint32 addr)
201 {
202         uint32 i;
203         uint8 bitmask;
204         uint8 srcdata;
205
206         if(planes >= 4) planes = 4;
207         for(i = 0; i < planes; i++) {
208                 if((bank_disable_reg & (1 << i)) != 0) {
209                         continue;
210                 }
211                 srcdata = do_read(addr, i);
212                 bitmask = ~srcdata;
213                 
214                 bitmask = bitmask & ~mask_reg;
215                 srcdata = (srcdata & mask_reg) | bitmask;
216                 do_write(addr, i, srcdata);
217         }
218         return 0xff;
219 }
220
221
222 uint8 MB61VH010::do_tilepaint(uint32 addr)
223 {
224         uint32 i;
225         uint8 bitmask;
226         uint8 srcdata;
227         //printf("Tilepaint CMD=%02x, ADDR=%04x Planes=%d, disable=%d, tile_reg=(%02x %02x %02x %02x)\n",
228         //      command_reg, addr, planes, bank_disable_reg, tile_reg[0], tile_reg[1], tile_reg[2], tile_reg[3]);
229         if(planes > 4) planes = 4;
230         for(i = 0; i < planes; i++) {
231                 if((bank_disable_reg & (1 << i)) != 0) {
232                         continue;
233                 }
234                 srcdata = do_read(addr, i);
235                 bitmask = tile_reg[i] & (~mask_reg);
236                 srcdata = (srcdata & mask_reg) | bitmask;
237                 do_write(addr, i, srcdata);
238         }
239         return 0xff;
240 }
241
242 uint8 MB61VH010::do_compare(uint32 addr)
243 {
244         uint32 offset = 0x4000;
245         uint8 r, g, b, t;
246         uint8 disables = ~bank_disable_reg;
247         uint8 tmpcol;
248         uint8 tmp_stat = 0;
249         int i;
250         int j;
251         //printf("Compare CMD=%02x, ADDR=%04x", command_reg, addr);
252         b = do_read(addr, 0);
253         r = do_read(addr, 1);
254         g = do_read(addr, 2);
255         //if(planes >= 4) {
256         //      t = do_read(addr, 3);
257         //      disables = disables & 0x0f;
258         //} else {
259                 t = 0;
260                 disables = disables & 0x07;
261         //}
262         for(i = 0; i < 8; i++) {
263                 tmp_stat <<= 1;
264                 tmpcol  = (b & 0x80) >> 7;
265                 tmpcol |= ((r & 0x80) >> 6);
266                 tmpcol |= ((g & 0x80) >> 5);
267                 //tmpcol |= ((t & 0x80) != 0) ? 8 : 0;
268                 tmpcol = tmpcol & disables;
269                 for(j = 0; j < 8; j++) {
270                         if((cmp_color_data[j] & 0x80) == 0) {
271                                 if((cmp_color_data[j] & disables) == tmpcol) {
272                                         tmp_stat = tmp_stat | 0x01;
273                                         goto _l0;
274                                 }
275                         }
276                 }
277 _l0:       
278                 b <<= 1;
279                 r <<= 1;
280                 g <<= 1;
281         }
282         cmp_status_reg = tmp_stat;
283         //printf(",Status=%02x\n", cmp_status_reg);
284         return 0xff;
285 }
286
287 void MB61VH010::do_alucmds_dmyread(uint32 addr)
288 {
289         if(!is_400line) {
290                 addr = addr & 0x3fff;
291         } else {
292                 if(addr >= 0x8000) {
293                         mask_reg = 0xff;
294                         return;
295                 }
296                 addr = addr & 0x7fff;
297         }
298         //printf("ALU DMYREAD: CMD %02x ADDR=%04x CMP[]=", command_reg, addr);
299         //for(i = 0; i < 8; i++) printf("[%02x]", cmp_color_data[i]);
300         if((command_reg & 0x80) == 0) {
301           //printf("\n");
302                 return;
303         }
304         if(((command_reg & 0x40) != 0) && ((command_reg & 0x07) != 7)) do_compare(addr);
305         switch(command_reg & 0x07) {
306                 case 0:
307                         do_pset(addr);
308                         break;
309                 case 1:
310                         do_blank(addr);
311                         break;
312                 case 2:
313                         do_or(addr);
314                         break;
315                 case 3:
316                         do_and(addr);
317                         break;
318                 case 4:
319                         do_xor(addr);
320                         break;
321                 case 5:
322                         do_not(addr);
323                         break;
324                 case 6:
325                         do_tilepaint(addr);
326                         break;
327                 case 7:
328                         do_compare(addr);
329                         break;
330         }
331         //printf("ALU DMYREAD ADDR=%04x, CMD=%02x CMP STATUS=%02x\n", addr, command_reg, cmp_status_reg);
332 }  
333
334 uint8 MB61VH010::do_alucmds(uint32 addr)
335 {
336         if(!is_400line) {
337                 addr = addr & 0x3fff;
338         } else {
339                 if(addr >= 0x8000) {
340                         mask_reg = 0xff;
341                         return 0xff;
342                 }
343                 addr = addr & 0x7fff;
344         }
345         //if((command_reg & 0x07) != 0x00) printf("ALU: CMD %02x ADDR=%08x\n", command_reg, addr);
346         if(((command_reg & 0x40) != 0) && ((command_reg & 0x07) != 7)) do_compare(addr);
347         //printf("ALU ADDR=%04x, CMD=%02x CMP STATUS=%02x\n", addr, command_reg, cmp_status_reg);
348         switch(command_reg & 0x07) {
349                 case 0:
350                         return do_pset(addr);
351                         break;
352                 case 1:
353                         return do_blank(addr);
354                         break;
355                 case 2:
356                         return do_or(addr);
357                         break;
358                 case 3:
359                         return do_and(addr);
360                         break;
361                 case 4:
362                         return do_xor(addr);
363                         break;
364                 case 5:
365                         return do_not(addr);
366                         break;
367                 case 6:
368                         return do_tilepaint(addr);
369                         break;
370                 case 7:
371                         return do_compare(addr);
372                         break;
373         }
374         return 0xff;
375 }
376
377 void MB61VH010::do_line(void)
378 {
379         int x_begin = line_xbegin.w.l;
380         int x_end = line_xend.w.l;
381         int y_begin = line_ybegin.w.l;
382         int y_end = line_yend.w.l;
383         int cpx_t = x_begin;
384         int cpy_t = y_begin;
385         int ax = x_end - x_begin;
386         int ay = y_end - y_begin;
387         int diff = 0;
388         int count = 0;
389         int xcount;
390         int ycount;
391         uint8 mask_bak = mask_reg;
392         uint16 tmp8a;
393         uint8 vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
394         //printf("Line: (%d,%d) - (%d,%d) CMD=%02x\n", x_begin, y_begin, x_end, y_end, command_reg);  
395         double usec;
396         bool lastflag = false;
397         
398         is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false;
399         planes = target->read_signal(SIG_DISPLAY_PLANES) & 0x07;
400         screen_width = target->read_signal(SIG_DISPLAY_X_WIDTH) * 8;
401         screen_height = target->read_signal(SIG_DISPLAY_Y_HEIGHT);
402
403         //if((command_reg & 0x80) == 0) return;
404         oldaddr = 0xffffffff;
405         alu_addr = 0xffffffff;
406
407         
408         line_style = line_pattern;
409         busy_flag = true;
410         total_bytes = 1;
411         
412         //mask_reg = 0xff & ~vmask[x_begin & 7];
413         mask_reg = 0xff;
414         if((line_style.b.h & 0x80) != 0) {
415                 mask_reg &= ~vmask[cpx_t & 7];
416         }
417         tmp8a = (line_style.w.l & 0x8000) >> 15;
418         line_style.w.l = (line_style.w.l << 1) | tmp8a;
419         xcount = abs(ax);
420         ycount = abs(ay);
421         if(xcount >= ycount) {
422                 if(xcount != 0) {
423                         //if(ycount != 0) {
424                                 diff = ((ycount  + 1) * 1024) / xcount;
425                         //}
426                         for(; xcount >= 0; xcount-- ) {
427                                 lastflag = put_dot(cpx_t, cpy_t);
428                                 count += diff;
429                                 if(count > 1024) {
430                                         if(ay > 0) {
431                                                 lastflag = put_dot(cpx_t, cpy_t + 1);
432                                         } else if(ax < 0) {
433                                                 lastflag = put_dot(cpx_t, cpy_t - 1);
434                                         }
435                                         if(ay < 0) {
436                                                 cpy_t--;
437                                         } else {
438                                                 cpy_t++;
439                                         }
440                                         count -= 1024;
441                                 }
442                                 if(ax > 0) {
443                                         cpx_t++;
444                                 } else if(ax < 0) {
445                                         cpx_t--;
446                                 }
447                         }
448                 } else { // ax = ay = 0
449                         lastflag = put_dot(cpx_t, cpy_t);
450                         total_bytes++;
451                 }
452         } else { // (abs(ax) < abs(ay)
453                 //if(xcount != 0) {
454                         diff = ((xcount + 1) * 1024) / ycount;
455                 //}
456                 for(; ycount >= 0; ycount--) {
457                         lastflag = put_dot(cpx_t, cpy_t);
458                         count += diff;
459                         if(count > 1024) {
460                                 if(ax > 0) {
461                                         lastflag = put_dot(cpx_t + 1, cpy_t);
462                                 } else if(ay < 0) {
463                                         lastflag = put_dot(cpx_t - 1, cpy_t);
464                                 }                                 
465                                 if(ax < 0) {
466                                         cpx_t--;
467                                 } else if(ax > 0) {
468                                         cpx_t++;
469                                 }
470                                 count -= 1024;
471                                 total_bytes++;
472                         }
473                         if(ay > 0) {
474                                 cpy_t++;
475                         } else {
476                                 cpy_t--;
477                         }
478                         total_bytes++;
479                 }
480         }
481
482         if(!lastflag) total_bytes++;
483         do_alucmds(alu_addr);
484
485         if(total_bytes > 8) { // Over 0.5us
486                 usec = (double)total_bytes / 16.0;
487                 register_event(this, EVENT_MB61VH010_BUSY_OFF, usec, false, &eventid_busy) ;
488         } else {
489                 busy_flag = false;
490         }
491         //mask_reg = mask_bak;
492         //line_pattern = line_style;
493 }
494
495 bool MB61VH010::put_dot(int x, int y)
496 {
497         uint8 vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
498         uint16 tmp8a;
499         bool flag = false;
500         
501         if((x < 0) || (y < 0)) return flag;
502         if((x >= screen_width) || (y >= screen_height)) return flag;
503         if((command_reg & 0x80) == 0) return flag;
504         
505         alu_addr = ((y * screen_width) >> 3) + (x >> 3);
506         alu_addr = alu_addr + (line_addr_offset.w.l << 1);
507         alu_addr = alu_addr & 0x7fff;
508         if(!is_400line) alu_addr = alu_addr & 0x3fff;
509         if(oldaddr == 0xffffffff) oldaddr = alu_addr;
510         
511         if(oldaddr != alu_addr) {
512                 do_alucmds(oldaddr);
513                 mask_reg = 0xff;
514                 oldaddr = alu_addr;
515                 flag = true;
516                 total_bytes++;
517         }
518         
519         if((line_style.b.h & 0x80) != 0) {
520                 mask_reg &= ~vmask[x & 7];
521         }
522         tmp8a = (line_style.w.l & 0x8000) >> 15;
523         line_style.w.l = (line_style.w.l << 1) | tmp8a;
524         return flag;
525 }
526
527 void MB61VH010::write_data8(uint32 id, uint32 data)
528 {
529         //printf("ALU: ADDR=%02x DATA=%02x\n", id, data);
530         if(id == ALU_CMDREG) {
531                 command_reg = data;
532                 return;
533         }
534         //if((command_reg & 0x80) == 0) return;
535         switch(id) {
536                 case ALU_LOGICAL_COLOR:
537                         color_reg = data;
538                         break;
539                 case ALU_WRITE_MASKREG:
540                         mask_reg = data;
541                         break;
542                 case ALU_BANK_DISABLE:
543                         bank_disable_reg = data;
544                         break;
545                 case ALU_TILEPAINT_B:
546                         tile_reg[0] = data;
547                         break;
548                 case ALU_TILEPAINT_R:
549                         tile_reg[1] = data;
550                         break;
551                 case ALU_TILEPAINT_G:
552                         tile_reg[2] = data;
553                         break;
554                 case ALU_TILEPAINT_L:
555                         tile_reg[3] = data;
556                         break;
557                 case ALU_OFFSET_REG_HIGH:
558                         line_addr_offset.b.h = data;
559                         break;
560                 case ALU_OFFSET_REG_LO:
561                         line_addr_offset.b.l = data;
562                         break;
563                 case ALU_LINEPATTERN_REG_HIGH:
564                         line_pattern.b.h = data;
565                         break;
566                 case ALU_LINEPATTERN_REG_LO:
567                         line_pattern.b.l = data;
568                         break;
569                 case ALU_LINEPOS_START_X_HIGH:
570                         line_xbegin.b.h = data;
571                         break;
572                 case ALU_LINEPOS_START_X_LOW:  
573                         line_xbegin.b.l = data;
574                         break;
575                 case ALU_LINEPOS_START_Y_HIGH:
576                         line_ybegin.b.h = data;
577                         break;
578                 case ALU_LINEPOS_START_Y_LOW:  
579                         line_ybegin.b.l = data;
580                         break;
581                 case ALU_LINEPOS_END_X_HIGH:
582                         line_xend.b.h = data;
583                         break;
584                 case ALU_LINEPOS_END_X_LOW:  
585                         line_xend.b.l = data;
586                         break;
587                 case ALU_LINEPOS_END_Y_HIGH:
588                         line_yend.b.h = data;
589                         break;
590                 case ALU_LINEPOS_END_Y_LOW:
591                         line_yend.b.l = data;
592                         do_line();
593                         break;
594                 default:
595                         if((id >= (ALU_CMPDATA_REG + 0)) && (id < (ALU_CMPDATA_REG + 8))) {
596                                 cmp_color_data[id - ALU_CMPDATA_REG] = data;
597                         } else  if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0x18000))) {
598                                 is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false;
599                                 do_alucmds_dmyread(id - ALU_WRITE_PROXY);
600                         }
601                         break;
602         }
603 }
604
605 uint32 MB61VH010::read_data8(uint32 id)
606 {
607         uint32 raddr;  
608         switch(id) {
609                 case ALU_CMDREG:
610                         return (uint32)command_reg;
611                         break;
612                 case ALU_LOGICAL_COLOR:
613                         return (uint32)color_reg;
614                         break;
615                 case ALU_WRITE_MASKREG:
616                         return (uint32)mask_reg;
617                         break;
618                 case ALU_CMP_STATUS_REG:
619                         return (uint32)cmp_status_reg;
620                         break;
621                 case ALU_BANK_DISABLE:
622                         return (uint32)bank_disable_reg;
623                         break;
624                 default:
625                         if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0x18000))) {
626                                 raddr = (id - ALU_WRITE_PROXY) & 0xbfff;
627                                 is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false;
628                                 do_alucmds_dmyread(id - ALU_WRITE_PROXY);
629                                 if(is_400line) raddr = raddr & 0x7fff;
630                                 return target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS);
631                         }
632                         return 0xffffffff;
633                         break;
634         }
635 }
636
637 uint32 MB61VH010::read_signal(int id)
638 {
639         uint32 val = 0x00000000;
640         switch(id) {
641                 case SIG_ALU_BUSYSTAT:
642                         if(busy_flag) val = 0xffffffff;
643                         break;
644         }
645         return val;
646 }
647
648 void MB61VH010::event_callback(int event_id, int err)
649 {
650         switch(event_id) {
651                 case EVENT_MB61VH010_BUSY_ON:
652                         busy_flag = true;
653                         if(eventid_busy >= 0) cancel_event(this, eventid_busy);
654                         eventid_busy = -1;
655                         break;
656                 case EVENT_MB61VH010_BUSY_OFF:
657                         busy_flag = false;
658                         eventid_busy = -1;
659                         break;
660         }
661 }
662
663 void MB61VH010::initialize(void)
664 {
665         busy_flag = false;
666         eventid_busy = -1;
667 }
668
669 void MB61VH010::reset(void)
670 {
671         int i;
672         busy_flag = false;
673         if(eventid_busy >= 0) cancel_event(this, eventid_busy);
674         eventid_busy = -1;
675         
676         command_reg = 0;        // D410 (RW)
677         color_reg = 0;          // D411 (RW)
678         mask_reg = 0;           // D412 (RW)
679         cmp_status_reg = 0;     // D413 (RO)
680         for(i = 0; i < 8; i++) cmp_color_data[i] = 0x80; // D413-D41A (WO)
681         bank_disable_reg = 0;   // D41B (RW)
682         for(i = 0; i < 4; i++) tile_reg[i] = 0;        // D41C-D41F (WO)
683         
684         line_addr_offset.d = 0; // D420-D421 (WO)
685         line_pattern.d = 0;     // D422-D423 (WO)
686         line_xbegin.d = 0;      // D424-D425 (WO)
687         line_ybegin.d = 0;      // D426-D427 (WO)
688         line_xend.d = 0;        // D428-D429 (WO)
689         line_yend.d = 0;        // D42A-D42B (WO)
690
691         oldaddr = 0xffffffff;
692         
693         planes = target->read_signal(SIG_DISPLAY_PLANES) & 0x07;
694         if(planes >= 4) planes = 4;
695         is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false;
696         
697         screen_width = target->read_signal(SIG_DISPLAY_X_WIDTH) * 8;
698         screen_height = target->read_signal(SIG_DISPLAY_Y_HEIGHT);
699 }