X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=source%2Fsrc%2Fvm%2Ffm7%2Fmb61vh010.cpp;h=744e8e455027aa25e5e73a57526833673ab62365;hb=941a6ad9e4fed618caca320f9177153f42d49ac4;hp=4524b8a4212c405b9d4920843b4588eebcd8d648;hpb=4e8405a01acba9e0c82eac40455e3a615123f107;p=csp-qt%2Fcommon_source_project-fm7.git diff --git a/source/src/vm/fm7/mb61vh010.cpp b/source/src/vm/fm7/mb61vh010.cpp index 4524b8a42..744e8e455 100644 --- a/source/src/vm/fm7/mb61vh010.cpp +++ b/source/src/vm/fm7/mb61vh010.cpp @@ -16,26 +16,23 @@ MB61VH010::MB61VH010(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_ { p_emu = parent_emu; p_vm = parent_vm; + target = NULL; } MB61VH010::~MB61VH010() { } -uint8 MB61VH010::do_read(uint32 addr, uint32 bank) +uint8_t MB61VH010::do_read(uint32_t addr, uint32_t bank) { - uint32 raddr; - uint32 offset; - - if(((1 << bank) & read_signal(SIG_DISPLAY_MULTIPAGE)) != 0) return 0xff; - //if(is_400line) offset = 0x8000; + uint32_t raddr; + if(((1 << bank) & multi_page) != 0) return 0xff; if(is_400line) { if((addr & 0xffff) < 0x8000) { - raddr = (addr & 0x7fff) | (0x8000 * bank); + raddr = (addr & 0x7fff) | (0x8000 * bank); return target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS); } - return 0xff; } else { raddr = (addr & 0x3fff) | (0x4000 * bank); return target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS); @@ -43,24 +40,23 @@ uint8 MB61VH010::do_read(uint32 addr, uint32 bank) return 0xff; } -uint8 MB61VH010::do_write(uint32 addr, uint32 bank, uint8 data) +uint8_t MB61VH010::do_write(uint32_t addr, uint32_t bank, uint8_t data) { - uint32 raddr; - uint8 readdata; + uint32_t raddr; + uint8_t readdata; - if(((1 << bank) & read_signal(SIG_DISPLAY_MULTIPAGE)) != 0) return 0xff; + if(((1 << bank) & multi_page) != 0) return 0xff; if((command_reg & 0x40) != 0) { // Calculate before writing readdata = do_read(addr, bank); //readdata = data; if((command_reg & 0x20) != 0) { // NAND readdata = readdata & cmp_status_reg; - data = data & ~cmp_status_reg; - readdata = readdata | data; + data = data & (~cmp_status_reg); } else { // AND - readdata = readdata & ~cmp_status_reg; + readdata = readdata & (~cmp_status_reg); data = data & cmp_status_reg; - readdata = readdata | data; } + readdata = readdata | data; } else { readdata = data; } @@ -77,18 +73,17 @@ uint8 MB61VH010::do_write(uint32 addr, uint32 bank, uint8 data) } -uint8 MB61VH010::do_pset(uint32 addr) +uint8_t MB61VH010::do_pset(uint32_t addr) { - uint32 i; - uint32 raddr = addr; // Use banked ram. - uint8 bitmask; - uint8 srcdata; + int i; + uint32_t raddr = addr; // Use banked ram. + uint8_t bitmask; + uint8_t srcdata; int planes_b = planes; - if(planes_b >= 4) planes_b = 4; for(i = 0; i < planes_b; i++) { if((bank_disable_reg & (1 << i)) != 0) { - continue; + continue; } if((color_reg & (1 << i)) == 0) { bitmask = 0x00; @@ -97,7 +92,7 @@ uint8 MB61VH010::do_pset(uint32 addr) } srcdata = do_read(addr, i); - bitmask = bitmask & ~mask_reg; + bitmask = bitmask & (~mask_reg); srcdata = srcdata & mask_reg; srcdata = srcdata | bitmask; do_write(addr, i, srcdata); @@ -105,10 +100,10 @@ uint8 MB61VH010::do_pset(uint32 addr) return 0xff; } -uint8 MB61VH010::do_blank(uint32 addr) +uint8_t MB61VH010::do_blank(uint32_t addr) { - uint32 i; - uint8 srcdata; + uint32_t i; + uint8_t srcdata; if(planes >= 4) planes = 4; for(i = 0; i < planes; i++) { @@ -122,11 +117,11 @@ uint8 MB61VH010::do_blank(uint32 addr) return 0xff; } -uint8 MB61VH010::do_or(uint32 addr) +uint8_t MB61VH010::do_or(uint32_t addr) { - uint32 i; - uint8 bitmask; - uint8 srcdata; + uint32_t i; + uint8_t bitmask; + uint8_t srcdata; if(planes >= 4) planes = 4; for(i = 0; i < planes; i++) { @@ -146,11 +141,11 @@ uint8 MB61VH010::do_or(uint32 addr) return 0xff; } -uint8 MB61VH010::do_and(uint32 addr) +uint8_t MB61VH010::do_and(uint32_t addr) { - uint32 i; - uint8 bitmask; - uint8 srcdata; + uint32_t i; + uint8_t bitmask; + uint8_t srcdata; if(planes >= 4) planes = 4; for(i = 0; i < planes; i++) { @@ -170,11 +165,11 @@ uint8 MB61VH010::do_and(uint32 addr) return 0xff; } -uint8 MB61VH010::do_xor(uint32 addr) +uint8_t MB61VH010::do_xor(uint32_t addr) { - uint32 i; - uint8 bitmask; - uint8 srcdata; + uint32_t i; + uint8_t bitmask; + uint8_t srcdata; if(planes >= 4) planes = 4; for(i = 0; i < planes; i++) { @@ -194,11 +189,11 @@ uint8 MB61VH010::do_xor(uint32 addr) return 0xff; } -uint8 MB61VH010::do_not(uint32 addr) +uint8_t MB61VH010::do_not(uint32_t addr) { - uint32 i; - uint8 bitmask; - uint8 srcdata; + uint32_t i; + uint8_t bitmask; + uint8_t srcdata; if(planes >= 4) planes = 4; for(i = 0; i < planes; i++) { @@ -216,72 +211,75 @@ uint8 MB61VH010::do_not(uint32 addr) } -uint8 MB61VH010::do_tilepaint(uint32 addr) +uint8_t MB61VH010::do_tilepaint(uint32_t addr) { - uint32 i; - uint8 bitmask; - uint8 srcdata; - //printf("Tilepaint CMD=%02x, ADDR=%04x Planes=%d, tile_reg=(%02x %02x %02x %02x)\n", - // command_reg, addr, planes, tile_reg[0], tile_reg[1], tile_reg[2], tile_reg[3]); - if(planes >= 4) planes = 4; + uint32_t i; + uint8_t bitmask; + uint8_t srcdata; + + if(planes > 4) planes = 4; for(i = 0; i < planes; i++) { if((bank_disable_reg & (1 << i)) != 0) { continue; } srcdata = do_read(addr, i); - bitmask = tile_reg[i] & ~mask_reg; + bitmask = tile_reg[i] & (~mask_reg); srcdata = (srcdata & mask_reg) | bitmask; do_write(addr, i, srcdata); } return 0xff; } -uint8 MB61VH010::do_compare(uint32 addr) +uint8_t MB61VH010::do_compare(uint32_t addr) { - uint32 offset = 0x4000; - uint8 r, g, b, t; - uint8 disables = ~bank_disable_reg; - uint8 tmpcol; - uint8 tmp_stat = 0; + uint32_t offset = 0x4000; + uint8_t r, g, b; + uint8_t disables = ~bank_disable_reg; + + uint8_t tmpcol; + uint8_t tmp_stat = 0; + uint8_t cmp_reg_bak[8]; + int k; int i; int j; - //printf("Compare CMD=%02x, ADDR=%04x\n", command_reg, addr); + + disables = disables & 0x07; + k = 0; + for(j = 0; j < 8; j++) { + if((cmp_color_data[j] & 0x80) == 0) { + cmp_reg_bak[k] = cmp_color_data[j] & disables; + k++; + } + } + cmp_status_reg = 0x00; + if(k <= 0) return 0xff; b = do_read(addr, 0); r = do_read(addr, 1); g = do_read(addr, 2); - if(planes >= 4) { - t = do_read(addr, 3); - disables = disables & 0x0f; - } else { - t = 0; - disables = disables & 0x07; - } - for(i = 7; i >= 0; i--) { - tmpcol = ((b & 0x80) != 0) ? 1 : 0; - tmpcol |= ((r & 0x80) != 0) ? 2 : 0; - tmpcol |= ((g & 0x80) != 0) ? 4 : 0; - tmpcol |= ((t & 0x80) != 0) ? 8 : 0; + for(i = 0; i < 8; i++) { + tmp_stat <<= 1; + tmpcol = (b & 0x80) >> 7; + tmpcol = tmpcol | ((r & 0x80) >> 6); + tmpcol = tmpcol | ((g & 0x80) >> 5); + //tmpcol |= ((t & 0x80) != 0) ? 8 : 0; tmpcol = tmpcol & disables; - for(j = 0; j < 8; j++) { - if((cmp_color_data[j] & 0x80) == 0) { - if((cmp_color_data[j] & disables) == tmpcol) { - tmp_stat = tmp_stat | (1 << i); - break; - } + for(j = 0; j < k; j++) { + if(cmp_reg_bak[j] == tmpcol) { + tmp_stat = tmp_stat | 0x01; + goto _l0; } } +_l0: b <<= 1; r <<= 1; g <<= 1; - t <<= 1; } cmp_status_reg = tmp_stat; return 0xff; } -void MB61VH010::do_alucmds_dmyread(uint32 addr) +void MB61VH010::do_alucmds_dmyread(uint32_t addr) { - int i; if(!is_400line) { addr = addr & 0x3fff; } else { @@ -291,13 +289,12 @@ void MB61VH010::do_alucmds_dmyread(uint32 addr) } addr = addr & 0x7fff; } - printf("ALU DMYREAD: CMD %02x ADDR=%04x CMP[]=", command_reg, addr); - for(i = 0; i < 8; i++) printf("[%02x]", cmp_color_data[i]); if((command_reg & 0x80) == 0) { - printf("\n"); return; } - if(((command_reg & 0x40) != 0) && ((command_reg & 0x07) != 7)) do_compare(addr); + //busy_flag = true; + //cmp_status_reg = 0x00; + if((command_reg & 0x40) != 0) do_compare(addr); switch(command_reg & 0x07) { case 0: do_pset(addr); @@ -324,10 +321,12 @@ void MB61VH010::do_alucmds_dmyread(uint32 addr) do_compare(addr); break; } - printf(" CMP STATUS=%02x\n", cmp_status_reg); + //p_emu->out_debug_log("ALU DMYREAD ADDR=%04x, CMD=%02x CMP STATUS=%02x\n", addr, command_reg, cmp_status_reg); + //if(eventid_busy >= 0) cancel_event(this, eventid_busy) ; + //register_event(this, EVENT_MB61VH010_BUSY_OFF, 1.0 / 16.0, false, &eventid_busy) ; } -uint8 MB61VH010::do_alucmds(uint32 addr) +uint8_t MB61VH010::do_alucmds(uint32_t addr) { if(!is_400line) { addr = addr & 0x3fff; @@ -338,8 +337,8 @@ uint8 MB61VH010::do_alucmds(uint32 addr) } addr = addr & 0x7fff; } - if((command_reg & 0x07) != 0x00) printf("ALU: CMD %02x ADDR=%08x\n", command_reg, addr); - if(((command_reg & 0x40) != 0) && ((command_reg & 0x07) != 7)) do_compare(addr); + //cmp_status_reg = 0x00; + if((command_reg & 0x40) != 0) do_compare(addr); switch(command_reg & 0x07) { case 0: return do_pset(addr); @@ -371,149 +370,187 @@ uint8 MB61VH010::do_alucmds(uint32 addr) void MB61VH010::do_line(void) { - int x_begin = line_xbegin.w.l; - int x_end = line_xend.w.l; - int y_begin = line_ybegin.w.l; - int y_end = line_yend.w.l; - uint32 addr; - int cpx_t = x_begin; - int cpy_t = y_begin; - int ax = x_end - x_begin; - int ay = y_end - y_begin; - int diff; + uint32_t x_begin = line_xbegin.w.l; + uint32_t x_end = line_xend.w.l; + uint32_t y_begin = line_ybegin.w.l; + uint32_t y_end = line_yend.w.l; + int cpx_t = (int)x_begin; + int cpy_t = (int)y_begin; + int ax = (int)x_end - (int)x_begin; + int ay = (int)y_end - (int)y_begin; + int diff = 0; int count = 0; - uint8 mask_bak = mask_reg; - //printf("Line: (%d,%d) - (%d,%d) CMD=%02x\n", x_begin, y_begin, x_end, y_end, command_reg); + int xcount; + int ycount; + //uint8_t mask_bak = mask_reg; + uint16_t tmp8a; + uint8_t vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; double usec; bool lastflag = false; + - is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false; - planes = target->read_signal(SIG_DISPLAY_PLANES) & 0x07; - screen_width = target->read_signal(SIG_DISPLAY_X_WIDTH) * 8; - screen_height = target->read_signal(SIG_DISPLAY_Y_HEIGHT); - - //if((command_reg & 0x80) == 0) return; oldaddr = 0xffffffff; alu_addr = 0xffffffff; - - + //if ((x_begin >= screen_width) && (x_end >= screen_width)) return; + //if ((y_begin >= screen_height) && (y_end >= screen_height)) return; line_style = line_pattern; - oldaddr = 0xffff; busy_flag = true; - total_bytes = 1; + total_bytes = 0; - //mask_reg = 0xff & ~vmask[x_begin & 7]; mask_reg = 0xff; - // Got from HD63484.cpp . - if(abs(ax) >= abs(ay)) { - if(ax != 0) { - diff = ((abs(ay) + 1) * 1024) / abs(ax); - for(; cpx_t != x_end; ) { + if ((line_style.b.h & 0x80) != 0) { + mask_reg &= ~vmask[cpx_t & 7]; + } + tmp8a = ((line_style.b.h & 0x80) >> 7) & 0x01; + line_style.w.l = (line_style.w.l << 1) | tmp8a; + + xcount = abs(ax); + ycount = abs(ay); + //p_emu->out_debug_log("LINE: (%d,%d)-(%d,%d)\n", x_begin, y_begin, x_end , y_end); + if(ycount == 0) { + if(ax > 0) { + if((cpx_t & 0x07) != 7) total_bytes = 1; + //if((x_end >= screen_width) && (x_begin < screen_width)) x_end = screen_width - 1; + for(; cpx_t <= (int)x_end; cpx_t++) { + if(cpy_t >= screen_width) break; lastflag = put_dot(cpx_t, cpy_t); - count += diff; - if(count >= 1024) { - if(ax > 0) { - lastflag = put_dot(cpx_t + 1, cpy_t); - } else if(ax < 0) { - lastflag = put_dot(cpx_t - 1, cpy_t); - } - if(ay < 0) { - cpy_t--; - } else { - cpy_t++; - } - count -= 1024; - } - if(ax > 0) { - cpx_t++; - } else if(ax < 0) { - cpx_t--; - } + if((cpx_t & 0x07) == 7) total_bytes++; } + } else { + if((cpx_t & 0x07) != 0) total_bytes = 1; + for(; cpx_t >= (int)x_end; cpx_t--) { + if(cpy_t < 0) break; + if((cpx_t & 0x07) == 0) total_bytes++; + lastflag = put_dot(cpx_t, cpy_t); + } + } + } else if(xcount == 0) { + if(ay > 0) { + for(; cpy_t <= (int)y_end; cpy_t++) { + if(cpy_t >= screen_height) break; + lastflag = put_dot(cpx_t, cpy_t); + total_bytes++; + } + } else { + for(; cpy_t >= (int)y_end; cpy_t--) { + if(cpy_t < 0) break; + lastflag = put_dot(cpx_t, cpy_t); + total_bytes++; + } + } + } else if(xcount >= ycount) { + diff = (ycount * 32768) / xcount; + if(ax < 0) { + //if(x_end == 0) xcount = x_begin; + if((cpx_t & 0x07) != 0) total_bytes = 1; + } else { + if(x_end >= screen_width) xcount = (int)screen_width - (int)x_begin - 1; + if((cpx_t & 0x07) == 0) total_bytes = 1; + } + for(; xcount >= 0; xcount-- ) { lastflag = put_dot(cpx_t, cpy_t); - } else { // ax = ay = 0 - lastflag = put_dot(cpx_t, cpy_t); - total_bytes++; + count += diff; + if(count > 16384) { + if(ay < 0) { + cpy_t--; + if(cpy_t < 0) break; + } else { + cpy_t++; + if(cpy_t >= screen_height) break; + } + total_bytes++; + count -= 32768; + } + if(ax > 0) { + cpx_t++; + if((cpx_t & 0x07) == 0) total_bytes++; + if(cpx_t >= screen_width) break; + } else if(ax < 0) { + if((cpx_t & 0x07) == 0) total_bytes++; + cpx_t--; + if(cpx_t < 0) break; + } + } + } else { // (abs(ax) <= abs(ay) + diff = (xcount * 32768) / ycount; + if(ay < 0) { + //if(y_end < 0) ycount = y_begin; + } else { + if(y_end >= screen_height) ycount = screen_height - y_begin - 1; } - } else { // (abs(ax) < abs(ay) - diff = ((abs(ax) + 1) * 1024) / abs(ay); - for(; cpy_t != y_end; ) { + for(; ycount >= 0; ycount--) { lastflag = put_dot(cpx_t, cpy_t); count += diff; - if(count >= 1024) { - if(ay > 0) { - lastflag = put_dot(cpx_t, cpy_t + 1); - } else if(ay < 0) { - lastflag = put_dot(cpx_t, cpy_t - 1); - } + if(count > 16384) { if(ax < 0) { cpx_t--; + if(cpx_t < 0) break; } else if(ax > 0) { cpx_t++; + if(cpx_t > screen_width) break; } - count -= 1024; + count -= 32768; } + total_bytes++; if(ay > 0) { cpy_t++; + if(cpy_t >= screen_height) break; } else { cpy_t--; + if(cpy_t < 0) break; } } - lastflag = put_dot(cpx_t, cpy_t); } - do_alucmds(alu_addr); - + //if(!lastflag) total_bytes++; + if(alu_addr < 0x8000) do_alucmds(alu_addr); + + //if(total_bytes > 16) { // Over 1.0us usec = (double)total_bytes / 16.0; - //if(usec >= 1.0) { // 1MHz + if(eventid_busy >= 0) cancel_event(this, eventid_busy) ; register_event(this, EVENT_MB61VH010_BUSY_OFF, usec, false, &eventid_busy) ; - //} else { - //busy_flag = false; - //} - mask_reg = mask_bak; - line_pattern = line_style; + //} else { + // busy_flag = false; + //} } bool MB61VH010::put_dot(int x, int y) { - uint8 vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; - uint16 tmp8a; - uint8 mask; + uint8_t vmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; + uint16_t tmp8a; bool flag = false; - if((x < 0) || (y < 0)) return flag; - if((x >= screen_width) || (y >= screen_height)) return flag; - if((command_reg & 0x80) == 0) return flag; + if((x < 0) || (y < 0)) return false; + if(y >= (int)screen_height) return false; + if((command_reg & 0x80) == 0) return false; - alu_addr = ((y * screen_width) >> 3) + (x >> 3); - alu_addr = alu_addr + (line_addr_offset.w.l << 1); + alu_addr = (y * screen_width + x) >> 3; + alu_addr = alu_addr + line_addr_offset.w.l; alu_addr = alu_addr & 0x7fff; if(!is_400line) alu_addr = alu_addr & 0x3fff; - if(oldaddr == 0xffffffff) oldaddr = alu_addr; if(oldaddr != alu_addr) { + if(oldaddr == 0xffffffff) oldaddr = alu_addr; do_alucmds(oldaddr); mask_reg = 0xff; oldaddr = alu_addr; flag = true; - total_bytes++; + //total_bytes++; } - if((line_style.b.h & 0x80) != 0) { mask_reg &= ~vmask[x & 7]; - } - tmp8a = (line_style.w.l & 0x8000) >> 15; + } + tmp8a = ((line_style.b.h & 0x80) >> 7) & 0x01; line_style.w.l = (line_style.w.l << 1) | tmp8a; return flag; } -void MB61VH010::write_data8(uint32 id, uint32 data) +void MB61VH010::write_data8(uint32_t id, uint32_t data) { - //printf("ALU: ADDR=%02x DATA=%02x\n", id, data); + //p_emu->out_debug_log("ALU: ADDR=%02x DATA=%02x\n", id, data); if(id == ALU_CMDREG) { command_reg = data; return; } - //if((command_reg & 0x80) == 0) return; switch(id) { case ALU_LOGICAL_COLOR: color_reg = data; @@ -537,10 +574,13 @@ void MB61VH010::write_data8(uint32 id, uint32 data) tile_reg[3] = data; break; case ALU_OFFSET_REG_HIGH: - line_addr_offset.b.h = data; + line_addr_offset.b.h &= 0x01; + line_addr_offset.b.h = line_addr_offset.b.h | ((data << 1) & 0x3e); break; case ALU_OFFSET_REG_LO: - line_addr_offset.b.l = data; + line_addr_offset.b.l = data << 1; + line_addr_offset.b.h &= 0xfe; + line_addr_offset.b.h = line_addr_offset.b.h | ((data >> 7) & 0x01); break; case ALU_LINEPATTERN_REG_HIGH: line_pattern.b.h = data; @@ -549,25 +589,25 @@ void MB61VH010::write_data8(uint32 id, uint32 data) line_pattern.b.l = data; break; case ALU_LINEPOS_START_X_HIGH: - line_xbegin.b.h = data; + line_xbegin.b.h = data & 0x03; break; case ALU_LINEPOS_START_X_LOW: line_xbegin.b.l = data; break; case ALU_LINEPOS_START_Y_HIGH: - line_ybegin.b.h = data; + line_ybegin.b.h = data & 0x01; break; case ALU_LINEPOS_START_Y_LOW: line_ybegin.b.l = data; break; case ALU_LINEPOS_END_X_HIGH: - line_xend.b.h = data; + line_xend.b.h = data & 0x03; break; case ALU_LINEPOS_END_X_LOW: line_xend.b.l = data; break; case ALU_LINEPOS_END_Y_HIGH: - line_yend.b.h = data; + line_yend.b.h = data & 0x01; break; case ALU_LINEPOS_END_Y_LOW: line_yend.b.l = data; @@ -576,54 +616,95 @@ void MB61VH010::write_data8(uint32 id, uint32 data) default: if((id >= (ALU_CMPDATA_REG + 0)) && (id < (ALU_CMPDATA_REG + 8))) { cmp_color_data[id - ALU_CMPDATA_REG] = data; - } else if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0x18000))) { - is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false; - do_alucmds_dmyread(id - ALU_WRITE_PROXY); + } else if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0xc000))) { + uint32_t raddr = id - ALU_WRITE_PROXY; + if(is_400line) { + if(raddr >= 0x8000) return; + } else { + raddr = raddr & 0x3fff; + } + do_alucmds_dmyread(raddr); } break; } } -uint32 MB61VH010::read_data8(uint32 id) +uint32_t MB61VH010::read_data8(uint32_t id) { - + uint32_t raddr; switch(id) { case ALU_CMDREG: - return (uint32)command_reg; + return (uint32_t)command_reg; break; case ALU_LOGICAL_COLOR: - return (uint32)color_reg; + return (uint32_t)color_reg; break; case ALU_WRITE_MASKREG: - return (uint32)mask_reg; + return (uint32_t)mask_reg; break; case ALU_CMP_STATUS_REG: - return (uint32)cmp_status_reg; + return (uint32_t)cmp_status_reg; break; case ALU_BANK_DISABLE: - return (uint32)bank_disable_reg; + return (uint32_t)bank_disable_reg; break; default: - if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0x18000))) { - is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false; - do_alucmds_dmyread(id - ALU_WRITE_PROXY); + if((id >= ALU_WRITE_PROXY) && (id < (ALU_WRITE_PROXY + 0xc000))) { + uint32_t dmydata; + raddr = id - ALU_WRITE_PROXY; + if(is_400line) { + if(raddr >= 0x8000) return 0xffffffff; + } else { + raddr = raddr & 0x3fff; + } + //dmydata = target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS); + do_alucmds_dmyread(raddr); + raddr = (id - ALU_WRITE_PROXY) % 0xc000; + dmydata = target->read_data8(raddr + DISPLAY_VRAM_DIRECT_ACCESS); + return dmydata; } return 0xffffffff; break; } } -uint32 MB61VH010::read_signal(int id) +uint32_t MB61VH010::read_signal(int id) { - uint32 val = 0x00000000; + uint32_t val = 0x00000000; switch(id) { case SIG_ALU_BUSYSTAT: if(busy_flag) val = 0xffffffff; break; + case SIG_ALU_ENABLED: + val = ((command_reg & 0x80) != 0) ? 0xffffffff : 0; + break; } return val; } +void MB61VH010::write_signal(int id, uint32_t data, uint32_t mask) +{ + bool flag = ((data & mask) != 0); + switch(id) { + case SIG_ALU_400LINE: + is_400line = flag; + break; + case SIG_ALU_MULTIPAGE: + multi_page = (data & mask) & 0x07; + break; + case SIG_ALU_PLANES: + planes = (data & mask) & 0x07; + if(planes >= 4) planes = 4; + break; + case SIG_ALU_X_WIDTH: + screen_width = (data << 3) & 0x3ff; + break; + case SIG_ALU_Y_HEIGHT: + screen_height = data & 0x3ff; + break; + } +} + void MB61VH010::event_callback(int event_id, int err) { switch(event_id) { @@ -641,8 +722,30 @@ void MB61VH010::event_callback(int event_id, int err) void MB61VH010::initialize(void) { + int i; busy_flag = false; + is_400line = false; eventid_busy = -1; + multi_page = 0x00; + planes = 3; + screen_width = 640; + screen_height = 200; +#if 1 + command_reg = 0; // D410 (RW) + color_reg = 0; // D411 (RW) + mask_reg = 0; // D412 (RW) + cmp_status_reg = 0; // D413 (RO) + for(i = 0; i < 8; i++) cmp_color_data[i] = 0x80; // D413-D41A (WO) + bank_disable_reg = 0; // D41B (RW) + for(i = 0; i < 4; i++) tile_reg[i] = 0; // D41C-D41F (WO) + + line_addr_offset.d = 0; // D420-D421 (WO) + line_pattern.d = 0; // D422-D423 (WO) + line_xbegin.d = 0; // D424-D425 (WO) + line_ybegin.d = 0; // D426-D427 (WO) + line_xend.d = 0; // D428-D429 (WO) + line_yend.d = 0; // D42A-D42B (WO) +#endif } void MB61VH010::reset(void) @@ -651,7 +754,7 @@ void MB61VH010::reset(void) busy_flag = false; if(eventid_busy >= 0) cancel_event(this, eventid_busy); eventid_busy = -1; - +#if 1 command_reg = 0; // D410 (RW) color_reg = 0; // D411 (RW) mask_reg = 0; // D412 (RW) @@ -666,12 +769,98 @@ void MB61VH010::reset(void) line_ybegin.d = 0; // D426-D427 (WO) line_xend.d = 0; // D428-D429 (WO) line_yend.d = 0; // D42A-D42B (WO) - +#endif oldaddr = 0xffffffff; - planes = target->read_signal(SIG_DISPLAY_PLANES) & 0x07; - is_400line = (target->read_signal(SIG_DISPLAY_MODE_IS_400LINE) != 0) ? true : false; - - screen_width = target->read_signal(SIG_DISPLAY_X_WIDTH) * 8; - screen_height = target->read_signal(SIG_DISPLAY_Y_HEIGHT); + if(planes >= 4) planes = 4; +} + +#define STATE_VERSION 1 +void MB61VH010::save_state(FILEIO *state_fio) +{ + int i; + state_fio->FputUint32(STATE_VERSION); + state_fio->FputInt32(this_device_id); + p_emu->out_debug_log("Save State: MB61VH010 : id=%d ver=%d\n", this_device_id, STATE_VERSION); + + { // V1 + state_fio->FputUint8(command_reg); + state_fio->FputUint8(color_reg); + state_fio->FputUint8(mask_reg); + state_fio->FputUint8(cmp_status_reg); + for(i = 0; i < 8; i++) state_fio->FputUint8(cmp_color_data[i]); + state_fio->FputUint8(bank_disable_reg); + for(i = 0; i < 4; i++) state_fio->FputUint8(tile_reg[i]); + state_fio->FputUint8(multi_page); + + state_fio->FputUint32_BE(line_addr_offset.d); + state_fio->FputUint16_BE(line_pattern.w.l); + state_fio->FputUint16_BE(line_xbegin.w.l); + state_fio->FputUint16_BE(line_ybegin.w.l); + state_fio->FputUint16_BE(line_xend.w.l); + state_fio->FputUint16_BE(line_yend.w.l); + + state_fio->FputBool(busy_flag); + state_fio->FputInt32_BE(eventid_busy); + + state_fio->FputUint32_BE(total_bytes); + state_fio->FputUint32_BE(oldaddr); + state_fio->FputUint32_BE(alu_addr); + + state_fio->FputUint32_BE(planes); + state_fio->FputBool(is_400line); + state_fio->FputUint32_BE(screen_width); + state_fio->FputUint32_BE(screen_height); + + state_fio->FputUint16_BE(line_style.w.l); + } + +} + +bool MB61VH010::load_state(FILEIO *state_fio) +{ + uint32_t version = state_fio->FgetUint32(); + int i; + p_emu->out_debug_log("Load State: MB61VH010 : id=%d ver=%d\n", this_device_id, version); + if(this_device_id != state_fio->FgetInt32()) return false; + if(version >= 1) { + command_reg = state_fio->FgetUint8(); + color_reg = state_fio->FgetUint8(); + mask_reg = state_fio->FgetUint8(); + cmp_status_reg = state_fio->FgetUint8(); + for(i = 0; i < 8; i++) cmp_color_data[i] = state_fio->FgetUint8(); + bank_disable_reg = state_fio->FgetUint8(); + for(i = 0; i < 4; i++) tile_reg[i] = state_fio->FgetUint8(); + multi_page = state_fio->FgetUint8(); + + line_addr_offset.d = state_fio->FgetUint32_BE(); + line_pattern.d = 0; + line_xbegin.d = 0; + line_ybegin.d = 0; + line_xend.d = 0; + line_yend.d = 0; + + line_pattern.w.l = state_fio->FgetUint16_BE(); + line_xbegin.w.l = state_fio->FgetUint16_BE(); + line_ybegin.w.l = state_fio->FgetUint16_BE(); + line_xend.w.l = state_fio->FgetUint16_BE(); + line_yend.w.l = state_fio->FgetUint16_BE(); + + busy_flag = state_fio->FgetBool(); + eventid_busy = state_fio->FgetInt32_BE(); + + total_bytes = state_fio->FgetUint32_BE(); + oldaddr = state_fio->FgetUint32_BE(); + alu_addr = state_fio->FgetUint32_BE(); + + planes = state_fio->FgetUint32_BE(); + is_400line = state_fio->FgetBool(); + screen_width = state_fio->FgetUint32_BE(); + screen_height = state_fio->FgetUint32_BE(); + + line_style.d = 0; + line_style.w.l = state_fio->FgetUint16_BE(); + } + if(version != STATE_VERSION) return false; + return true; }