2 * FM77AV/FM16β ALU [mb61vh010.cpp]
3 * of Fujitsu MB61VH010/011
5 * Author: K.Ohta <whatisthis.sowhat _at_ gmail.com>
8 * Mar 28, 2015 : Initial
12 #include "mb61vh010.h"
14 uint8_t MB61VH010::do_read(uint32_t addr, uint32_t bank)
18 if(((1 << bank) & multi_page) != 0) return 0xff;
20 if((addr & 0xffff) < 0x8000) {
21 raddr = (addr & 0x7fff) | (0x8000 * bank);
22 return target->read_data8(raddr + direct_access_offset);
25 raddr = (addr & 0x3fff) | (0x4000 * bank);
26 return target->read_data8(raddr + direct_access_offset);
31 void MB61VH010::do_write(uint32_t addr, uint32_t bank, uint8_t data)
36 if(((1 << bank) & multi_page) != 0) return;
37 if((command_reg & 0x40) != 0) { // Calculate before writing
38 readdata = do_read(addr, bank);
40 if((command_reg & 0x20) != 0) { // NAND
41 readdata = readdata & cmp_status_reg;
42 data = data & (~cmp_status_reg);
44 readdata = readdata & (~cmp_status_reg);
45 data = data & cmp_status_reg;
47 readdata = readdata | data;
52 if((addr & 0xffff) < 0x8000) {
53 raddr = (addr & 0x7fff) | (0x8000 * bank);
54 target->write_data8(raddr + direct_access_offset, readdata);
57 raddr = (addr & 0x3fff) | (0x4000 * bank);
58 target->write_data8(raddr + direct_access_offset, readdata);
64 void MB61VH010::do_pset(uint32_t addr)
67 uint32_t raddr = addr; // Use banked ram.
68 uint8_t bitmask[4] = {0};
69 uint8_t srcdata[4] = {0};
70 uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
71 int planes_b = planes;
73 if(planes_b >= 4) planes_b = 4;
74 for(i = 0; i < planes_b; i++) {
75 if((bank_disable_reg & (1 << i)) != 0) {
78 if((color_reg & (1 << i)) == 0) {
81 bitmask[i] = ~mask_reg;
83 //srcdata[i] = do_read(addr, i) & mask_reg;
84 srcdata[i] = do_read(addr, i);
86 srcdata[0] = (srcdata[0] & mask_p[0]) | bitmask[0];
87 srcdata[1] = (srcdata[1] & mask_p[1]) | bitmask[1];
88 srcdata[2] = (srcdata[2] & mask_p[2]) | bitmask[2];
89 srcdata[3] = (srcdata[3] & mask_p[3]) | bitmask[3];
91 for(i = 0; i < planes_b; i++) {
92 if((bank_disable_reg & (1 << i)) != 0) {
95 do_write(addr, i, srcdata[i]);
100 void MB61VH010::do_blank(uint32_t addr)
105 if(planes >= 4) planes = 4;
106 for(i = 0; i < planes; i++) {
107 if((bank_disable_reg & (1 << i)) != 0) {
110 srcdata = do_read(addr, i);
111 srcdata = srcdata & mask_reg;
112 do_write(addr, i, srcdata);
117 void MB61VH010::do_or(uint32_t addr)
120 uint8_t bitmask[4] = {0};
121 uint8_t srcdata[4] = {0};
122 uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
123 uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
125 if(planes >= 4) planes = 4;
126 for(i = 0; i < planes; i++) {
127 if((bank_disable_reg & (1 << i)) != 0) {
130 srcdata[i] = do_read(addr, i);
131 if((color_reg & (1 << i)) == 0) {
132 bitmask[i] = srcdata[i]; // srcdata | 0x00
134 bitmask[i] = 0xff; // srcdata | 0xff
136 //bitmask = bitmask & ~mask_reg;
137 //srcdata = (srcdata & mask_reg) | bitmask;
138 //do_write(addr, i, srcdata);
140 srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
141 srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
142 srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
143 srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
144 for(i = 0; i < planes; i++) {
145 if((bank_disable_reg & (1 << i)) != 0) {
148 do_write(addr, i, srcdata[i]);
153 void MB61VH010::do_and(uint32_t addr)
156 uint8_t bitmask[4] = {0};
157 uint8_t srcdata[4] = {0};
158 uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
159 uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
161 if(planes >= 4) planes = 4;
162 for(i = 0; i < planes; i++) {
163 if((bank_disable_reg & (1 << i)) != 0) {
166 srcdata[i] = do_read(addr, i);
167 if((color_reg & (1 << i)) == 0) {
168 bitmask[i] = 0x00; // srcdata & 0x00
170 bitmask[i] = srcdata[i]; // srcdata & 0xff;
172 //bitmask = bitmask & ~mask_reg;
173 //srcdata = (srcdata & mask_reg) | bitmask;
174 //do_write(addr, i, srcdata);
176 srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
177 srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
178 srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
179 srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
180 for(i = 0; i < planes; i++) {
181 if((bank_disable_reg & (1 << i)) != 0) {
184 do_write(addr, i, srcdata[i]);
189 void MB61VH010::do_xor(uint32_t addr)
194 uint8_t bitmask[4] = {0};
195 uint8_t srcdata[4] = {0};
196 uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
197 uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
199 if(planes >= 4) planes = 4;
200 for(i = 0; i < planes; i++) {
201 if((bank_disable_reg & (1 << i)) != 0) {
204 if((color_reg & (1 << i)) == 0) {
210 srcdata[i] = do_read(addr, i);
211 //bitmask = bitmask ^ srcdata;
212 //bitmask = bitmask & (~mask_reg);
213 //srcdata = srcdata & mask_reg;
214 //srcdata = srcdata | bitmask;
215 //do_write(addr, i, srcdata);
217 bitmask[0] = bitmask[0] ^ srcdata[0];
218 bitmask[1] = bitmask[1] ^ srcdata[1];
219 bitmask[2] = bitmask[2] ^ srcdata[2];
220 bitmask[3] = bitmask[3] ^ srcdata[3];
222 srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
223 srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
224 srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
225 srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
226 for(i = 0; i < planes; i++) {
227 if((bank_disable_reg & (1 << i)) != 0) {
230 do_write(addr, i, srcdata[i]);
235 void MB61VH010::do_not(uint32_t addr)
238 uint8_t bitmask[4] = {0};
239 uint8_t srcdata[4] = {0};
240 uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
241 uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
243 if(planes >= 4) planes = 4;
244 for(i = 0; i < planes; i++) {
245 if((bank_disable_reg & (1 << i)) != 0) {
248 srcdata[i] = do_read(addr, i);
249 bitmask[i] = ~srcdata[i];
250 //bitmask = bitmask & ~mask_reg;
251 //srcdata = (srcdata & mask_reg) | bitmask;
252 //do_write(addr, i, srcdata);
254 srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
255 srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
256 srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
257 srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
258 for(i = 0; i < planes; i++) {
259 if((bank_disable_reg & (1 << i)) != 0) {
262 do_write(addr, i, srcdata[i]);
268 void MB61VH010::do_tilepaint(uint32_t addr)
271 uint8_t bitmask[4] = {0};
272 uint8_t srcdata[4] = {0};
273 uint8_t mask_p[4] = {mask_reg, mask_reg, mask_reg, mask_reg};
274 uint8_t mask_n[4] = {(uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg, (uint8_t)~mask_reg};
276 if(planes > 4) planes = 4;
277 for(i = 0; i < planes; i++) {
278 if((bank_disable_reg & (1 << i)) != 0) {
281 srcdata[i] = do_read(addr, i);
282 bitmask[i] = tile_reg[i];
283 //bitmask = tile_reg[i] & (~mask_reg);
284 //srcdata = (srcdata & mask_reg) | bitmask;
285 //do_write(addr, i, srcdata);
287 srcdata[0] = (srcdata[0] & mask_p[0]) | (bitmask[0] & mask_n[0]);
288 srcdata[1] = (srcdata[1] & mask_p[1]) | (bitmask[1] & mask_n[1]);
289 srcdata[2] = (srcdata[2] & mask_p[2]) | (bitmask[2] & mask_n[2]);
290 srcdata[3] = (srcdata[3] & mask_p[3]) | (bitmask[3] & mask_n[3]);
291 for(i = 0; i < planes; i++) {
292 if((bank_disable_reg & (1 << i)) != 0) {
295 do_write(addr, i, srcdata[i]);
300 void MB61VH010::do_compare(uint32_t addr)
302 uint32_t offset = 0x4000;
304 uint8_t disables = ~bank_disable_reg;
307 uint8_t tmp_stat = 0;
308 uint8_t cmp_reg_bak[8];
313 disables = disables & 0x07;
315 for(j = 0; j < 8; j++) {
316 if((cmp_color_data[j] & 0x80) == 0) {
317 cmp_reg_bak[k] = cmp_color_data[j] & disables;
321 cmp_status_reg = 0x00;
323 b = do_read(addr, 0);
324 r = do_read(addr, 1);
325 g = do_read(addr, 2);
326 for(i = 0; i < 8; i++) {
328 tmpcol = (b & 0x80) >> 7;
329 tmpcol = tmpcol | ((r & 0x80) >> 6);
330 tmpcol = tmpcol | ((g & 0x80) >> 5);
331 tmpcol = tmpcol & disables;
332 for(j = 0; j < k; j++) {
333 if(cmp_reg_bak[j] == tmpcol) {
334 tmp_stat = tmp_stat | 0x01;
343 cmp_status_reg = tmp_stat;
347 void MB61VH010::do_alucmds_dmyread(uint32_t addr)
350 addr = addr & 0x3fff;
356 addr = addr & 0x7fff;
358 if((command_reg & 0x80) == 0) {
362 //cmp_status_reg = 0x00;
363 if((command_reg & 0x40) != 0) do_compare(addr);
364 switch(command_reg & 0x07) {
390 //printf("ALU DMYREAD ADDR=%04x, CMD=%02x CMP STATUS=%02x DISABLE=%01x\n", addr, command_reg, cmp_status_reg, bank_disable_reg);
391 //if(eventid_busy >= 0) cancel_event(this, eventid_busy) ;
392 //register_event(this, EVENT_MB61VH010_BUSY_OFF, 1.0 / 16.0, false, &eventid_busy) ;
395 void MB61VH010::do_alucmds(uint32_t addr)
402 //cmp_status_reg = 0xff;
403 if((command_reg & 0x40) != 0) do_compare(addr);
404 switch(command_reg & 0x07) {
430 //printf("ALU CMDS ADDR=%04x, CMD=%02x CMP STATUS=%02x\n", addr, command_reg, cmp_status_reg);
434 void MB61VH010::do_line(void)
436 uint32_t x_begin = line_xbegin.w.l;
437 uint32_t x_end = line_xend.w.l;
438 uint32_t y_begin = line_ybegin.w.l;
439 uint32_t y_end = line_yend.w.l;
440 int cpx_t = (int)x_begin;
441 int cpy_t = (int)y_begin;
442 int ax = (int)x_end - (int)x_begin;
443 int ay = (int)y_end - (int)y_begin;
449 bool updated = false;
451 uint8_t vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
453 oldaddr = 0xffffffff;
454 alu_addr = 0xffffffff;
455 line_style = line_pattern;
460 if ((line_style.b.h & 0x80) != 0) {
461 mask_reg &= ~vmask[cpx_t & 7];
465 //this->out_debug_log("LINE: (%d,%d)-(%d,%d) CMD=%02x STYLE=%04x, \n", x_begin, y_begin, x_end , y_end, command_reg, line_style.w.l);
467 if((cpy_t < 0) || (cpy_t >= 512)) goto _finish;
469 updated = put_dot(cpx_t, cpy_t);
473 int left = x_end - cpx_t;
474 if((cpx_t & 0x07) != 7) total_bytes = 1;
475 for(; cpx_t <= (int)x_end;) {
476 if((cpx_t & 7) == 0) {
478 updated = put_dot8(cpx_t, cpy_t);
486 updated = put_dot(cpx_t, cpy_t);
489 if((cpx_t & 0x07) == 7) total_bytes++;
493 int left = cpx_t - x_end;
494 if((cpx_t & 0x07) != 0) total_bytes = 1;
495 for(; cpx_t >= (int)x_end;) {
496 if(cpx_t < 0) break; // Comment out for Amnork.
497 if((cpx_t & 7) == 7) {
499 updated = put_dot8(cpx_t, cpy_t);
507 if((cpx_t & 7) == 0) total_bytes++;
508 updated = put_dot(cpx_t, cpy_t);
514 } else if(xcount == 0) {
515 //if((cpx_t < 0) || (cpx_t >= screen_width)) goto _finish; // Okay?
516 if(cpx_t < 0) goto _finish; // Okay?
518 for(; cpy_t <= (int)y_end; cpy_t++) {
519 if(cpy_t >= 512) break;
520 updated = put_dot(cpx_t, cpy_t);
524 for(; cpy_t >= (int)y_end; cpy_t--) {
526 updated = put_dot(cpx_t, cpy_t);
530 } else if(xcount > ycount) { // (abs(ax) > abs(ay)
531 diff = (ycount * 32768) / xcount;
534 if((cpx_t & 0x07) != 0) total_bytes = 1;
536 if((cpx_t & 0x07) == 0) total_bytes = 1;
538 for(; xcount >= 0; ) {
539 if((diff8 + count) <= 16384) {
541 if((cpx_t & 0x07) == 0) {
543 updated = put_dot8(cpx_t, cpy_t);
552 if((cpx_t & 0x07) == 7) {
554 updated = put_dot8(cpx_t, cpy_t);
565 updated = put_dot(cpx_t, cpy_t);
573 if(cpy_t >= 512) break;
580 if((cpx_t & 0x07) == 0) total_bytes++;
582 if((cpx_t & 0x07) == 0) total_bytes++;
584 if(cpx_t < 0) break; // Comment out for Amnork.
588 } else if(xcount == ycount) { // (abs(ax) == abs(ay)
589 diff = (ycount * 32768) / xcount;
591 if((cpx_t & 0x07) != 0) total_bytes = 1;
593 if((cpx_t & 0x07) == 0) total_bytes = 1;
595 for(; xcount >= 0; xcount-- ) {
596 updated = put_dot(cpx_t, cpy_t);
602 if(cpy_t >= 512) break;
609 if(cpx_t < 0) break; // Comment out for Amnork.
612 } else { // (abs(ax) < abs(ay)
613 diff = (xcount * 32768) / ycount;
614 for(; ycount >= 0; ycount--) {
615 updated = put_dot(cpx_t, cpy_t);
621 if(cpx_t < 0) break; // Comment out for Amnork.
641 do_alucmds(alu_addr);
644 //if(total_bytes == 0) total_bytes = 1;
646 if(total_bytes >= 8) { // Only greater than 8bytes.
647 usec = (double)total_bytes / 16.0;
648 if(eventid_busy >= 0) cancel_event(this, eventid_busy) ;
649 register_event(this, EVENT_MB61VH010_BUSY_OFF, usec, false, &eventid_busy);
655 inline bool MB61VH010::put_dot(int x, int y)
657 uint8_t vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
664 if((command_reg & 0x80) == 0) return false; // Not compare.
665 if((x < 0) || (y < 0)) {
666 return false; // Lower address
669 //if(y >= (int)screen_height) return; // Workaround of overflow
671 alu_addr = (y * screen_width + x) >> 3;
672 alu_addr = alu_addr + line_addr_offset.w.l;
674 alu_addr = alu_addr & 0x3fff;
676 alu_addr = alu_addr & 0x7fff;
679 mask8 = ~vmask[x & 7];
681 tmp8a = line_style.b.h & 0x80;
683 if(oldaddr != alu_addr) {
684 if(oldaddr == 0xffffffff) {
698 line_style.w.l <<= 1;
699 if(tmp8a != 0) line_style.w.l |= 0x01;
703 inline bool MB61VH010::put_dot8(int x, int y)
705 uint8_t vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
711 if((command_reg & 0x80) == 0) return false; // Not compare.
712 if((x < 0) || (y < 0)) {
713 return false; // Lower address
716 //if(y >= (int)screen_height) return; // Workaround of overflow
718 alu_addr = (y * screen_width + x) >> 3;
719 alu_addr = alu_addr + line_addr_offset.w.l;
721 alu_addr = alu_addr & 0x3fff;
723 alu_addr = alu_addr & 0x7fff;
726 if(oldaddr != alu_addr) {
727 if(oldaddr == 0xffffffff) {
728 if((line_style.b.h & 0x80) != 0) {
729 mask_reg &= ~vmask[x & 7];
738 tmp8a = line_style.b.h;
739 mask_reg = mask_reg & ~tmp8a;
740 tmp8a = line_style.b.l;
741 line_style.b.l = line_style.b.h;
742 line_style.b.h = tmp8a;
746 void MB61VH010::write_data8(uint32_t id, uint32_t data)
748 //this->out_debug_log("ALU: ADDR=%02x DATA=%02x\n", id, data);
749 if(id == ALU_CMDREG) {
754 case ALU_LOGICAL_COLOR:
757 case ALU_WRITE_MASKREG:
760 case ALU_BANK_DISABLE:
761 bank_disable_reg = data;
763 case ALU_TILEPAINT_B:
766 case ALU_TILEPAINT_R:
769 case ALU_TILEPAINT_G:
772 case ALU_TILEPAINT_L:
775 case ALU_OFFSET_REG_HIGH:
776 line_addr_offset.b.h &= 0x01;
777 line_addr_offset.b.h = line_addr_offset.b.h | ((data << 1) & 0x3e);
779 case ALU_OFFSET_REG_LO:
780 line_addr_offset.b.l = data << 1;
781 line_addr_offset.b.h &= 0xfe;
782 line_addr_offset.b.h = line_addr_offset.b.h | ((data >> 7) & 0x01);
784 case ALU_LINEPATTERN_REG_HIGH:
785 line_pattern.b.h = data;
787 case ALU_LINEPATTERN_REG_LO:
788 line_pattern.b.l = data;
790 case ALU_LINEPOS_START_X_HIGH:
791 line_xbegin.b.h = data & 0x03;
793 case ALU_LINEPOS_START_X_LOW:
794 line_xbegin.b.l = data;
796 case ALU_LINEPOS_START_Y_HIGH:
797 line_ybegin.b.h = data & 0x01;
799 case ALU_LINEPOS_START_Y_LOW:
800 line_ybegin.b.l = data;
802 case ALU_LINEPOS_END_X_HIGH:
803 line_xend.b.h = data & 0x03;
805 case ALU_LINEPOS_END_X_LOW:
806 line_xend.b.l = data;
808 case ALU_LINEPOS_END_Y_HIGH:
809 line_yend.b.h = data & 0x01;
811 case ALU_LINEPOS_END_Y_LOW:
812 line_yend.b.l = data;
816 if((id >= (ALU_CMPDATA_REG + 0)) && (id < (ALU_CMPDATA_REG + 8))) {
817 cmp_color_data[id - ALU_CMPDATA_REG] = data;
818 } else if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0xc000))) {
819 uint32_t raddr = id - ALU_WRITE_PROXY;
821 if(raddr >= 0x8000) return;
823 raddr = raddr & 0x3fff;
825 do_alucmds_dmyread(raddr);
831 uint32_t MB61VH010::read_data8(uint32_t id)
836 return (uint32_t)command_reg;
838 case ALU_LOGICAL_COLOR:
839 return (uint32_t)color_reg;
841 case ALU_WRITE_MASKREG:
842 return (uint32_t)mask_reg;
844 case ALU_CMP_STATUS_REG:
845 return (uint32_t)cmp_status_reg;
847 case ALU_BANK_DISABLE:
848 return (uint32_t)bank_disable_reg;
851 if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0xc000))) {
853 raddr = id - ALU_WRITE_PROXY;
855 if(raddr >= 0x8000) return 0xffffffff;
857 raddr = raddr & 0x3fff;
859 do_alucmds_dmyread(raddr);
860 raddr = (id - ALU_WRITE_PROXY) % 0xc000;
861 dmydata = target->read_data8(raddr + direct_access_offset);
869 uint32_t MB61VH010::read_signal(int id)
871 uint32_t val = 0x00000000;
873 case SIG_ALU_BUSYSTAT:
874 if(busy_flag) val = 0xffffffff;
876 case SIG_ALU_ENABLED:
877 if((command_reg & 0x80) != 0) val = 0xffffffff;
883 void MB61VH010::write_signal(int id, uint32_t data, uint32_t mask)
885 bool flag = ((data & mask) != 0);
887 case SIG_ALU_400LINE:
890 case SIG_ALU_MULTIPAGE:
891 multi_page = (data & mask) & 0x07;
894 planes = (data & mask) & 0x07;
895 if(planes >= 4) planes = 4;
897 case SIG_ALU_X_WIDTH:
898 screen_width = (data << 3) & 0x3ff;
900 case SIG_ALU_Y_HEIGHT:
901 screen_height = data & 0x3ff;
906 void MB61VH010::event_callback(int event_id, int err)
909 case EVENT_MB61VH010_BUSY_ON:
911 if(eventid_busy >= 0) cancel_event(this, eventid_busy);
914 case EVENT_MB61VH010_BUSY_OFF:
921 void MB61VH010::initialize(void)
931 command_reg = 0; // D410 (RW)
932 color_reg = 0; // D411 (RW)
933 mask_reg = 0; // D412 (RW)
934 cmp_status_reg = 0; // D413 (RO)
935 for(i = 0; i < 8; i++) cmp_color_data[i] = 0x80; // D413-D41A (WO)
936 bank_disable_reg = 0; // D41B (RW)
937 for(i = 0; i < 4; i++) tile_reg[i] = 0; // D41C-D41F (WO)
939 line_addr_offset.d = 0; // D420-D421 (WO)
940 line_pattern.d = 0; // D422-D423 (WO)
941 line_xbegin.d = 0; // D424-D425 (WO)
942 line_ybegin.d = 0; // D426-D427 (WO)
943 line_xend.d = 0; // D428-D429 (WO)
944 line_yend.d = 0; // D42A-D42B (WO)
947 void MB61VH010::reset(void)
951 if(eventid_busy >= 0) cancel_event(this, eventid_busy);
953 command_reg = 0; // D410 (RW)
954 color_reg = 0; // D411 (RW)
955 mask_reg = 0; // D412 (RW)
956 cmp_status_reg = 0; // D413 (RO)
957 for(i = 0; i < 8; i++) cmp_color_data[i] = 0x80; // D413-D41A (WO)
958 bank_disable_reg = 0; // D41B (RW)
959 for(i = 0; i < 4; i++) tile_reg[i] = 0; // D41C-D41F (WO)
961 line_addr_offset.d = 0; // D420-D421 (WO)
962 line_pattern.d = 0; // D422-D423 (WO)
963 line_xbegin.d = 0; // D424-D425 (WO)
964 line_ybegin.d = 0; // D426-D427 (WO)
965 line_xend.d = 0; // D428-D429 (WO)
966 line_yend.d = 0; // D42A-D42B (WO)
967 oldaddr = 0xffffffff;
969 if(planes >= 4) planes = 4;
972 #define STATE_VERSION 1
973 void MB61VH010::save_state(FILEIO *state_fio)
976 state_fio->FputUint32(STATE_VERSION);
977 state_fio->FputInt32(this_device_id);
978 this->out_debug_log("Save State: MB61VH010 : id=%d ver=%d\n", this_device_id, STATE_VERSION);
981 state_fio->FputUint8(command_reg);
982 state_fio->FputUint8(color_reg);
983 state_fio->FputUint8(mask_reg);
984 state_fio->FputUint8(cmp_status_reg);
985 for(i = 0; i < 8; i++) state_fio->FputUint8(cmp_color_data[i]);
986 state_fio->FputUint8(bank_disable_reg);
987 for(i = 0; i < 4; i++) state_fio->FputUint8(tile_reg[i]);
988 state_fio->FputUint8(multi_page);
990 state_fio->FputUint32_BE(line_addr_offset.d);
991 state_fio->FputUint16_BE(line_pattern.w.l);
992 state_fio->FputUint16_BE(line_xbegin.w.l);
993 state_fio->FputUint16_BE(line_ybegin.w.l);
994 state_fio->FputUint16_BE(line_xend.w.l);
995 state_fio->FputUint16_BE(line_yend.w.l);
997 state_fio->FputBool(busy_flag);
998 state_fio->FputInt32_BE(eventid_busy);
1000 state_fio->FputUint32_BE(total_bytes);
1001 state_fio->FputUint32_BE(oldaddr);
1002 state_fio->FputUint32_BE(alu_addr);
1004 state_fio->FputUint32_BE(planes);
1005 state_fio->FputBool(is_400line);
1006 state_fio->FputUint32_BE(screen_width);
1007 state_fio->FputUint32_BE(screen_height);
1009 state_fio->FputUint16_BE(line_style.w.l);
1014 bool MB61VH010::load_state(FILEIO *state_fio)
1016 uint32_t version = state_fio->FgetUint32();
1018 this->out_debug_log("Load State: MB61VH010 : id=%d ver=%d\n", this_device_id, version);
1019 if(this_device_id != state_fio->FgetInt32()) return false;
1021 command_reg = state_fio->FgetUint8();
1022 color_reg = state_fio->FgetUint8();
1023 mask_reg = state_fio->FgetUint8();
1024 cmp_status_reg = state_fio->FgetUint8();
1025 for(i = 0; i < 8; i++) cmp_color_data[i] = state_fio->FgetUint8();
1026 bank_disable_reg = state_fio->FgetUint8();
1027 for(i = 0; i < 4; i++) tile_reg[i] = state_fio->FgetUint8();
1028 multi_page = state_fio->FgetUint8();
1030 line_addr_offset.d = state_fio->FgetUint32_BE();
1037 line_pattern.w.l = state_fio->FgetUint16_BE();
1038 line_xbegin.w.l = state_fio->FgetUint16_BE();
1039 line_ybegin.w.l = state_fio->FgetUint16_BE();
1040 line_xend.w.l = state_fio->FgetUint16_BE();
1041 line_yend.w.l = state_fio->FgetUint16_BE();
1043 busy_flag = state_fio->FgetBool();
1044 eventid_busy = state_fio->FgetInt32_BE();
1046 total_bytes = state_fio->FgetUint32_BE();
1047 oldaddr = state_fio->FgetUint32_BE();
1048 alu_addr = state_fio->FgetUint32_BE();
1050 planes = state_fio->FgetUint32_BE();
1051 is_400line = state_fio->FgetBool();
1052 screen_width = state_fio->FgetUint32_BE();
1053 screen_height = state_fio->FgetUint32_BE();
1056 line_style.w.l = state_fio->FgetUint16_BE();
1058 if(version != STATE_VERSION) return false;