Merge pull request #3218 from 86Box/tc1995

ET4000w32/i (and non-i): More fixes, see below.
This commit is contained in:
Miran Grča
2023-03-22 20:43:55 +01:00
committed by GitHub

View File

@@ -96,12 +96,12 @@ typedef struct et4000w32p_t {
uint8_t suspend_terminate, osr; uint8_t suspend_terminate, osr;
uint8_t status; uint8_t status;
uint16_t x_count, y_count; uint16_t x_count, y_count;
uint16_t cpu_x_cnt, cpu_x_cnt_back, cpu_y_cnt;
int pattern_x, source_x, pattern_x_back, source_x_back, int pattern_x, source_x, pattern_x_back, source_x_back,
pattern_y, source_y, cpu_dat_pos, pix_pos, pattern_y, source_y, cpu_dat_pos, pix_pos,
cpu_input_num, fifo_queue; cpu_input_num, fifo_queue;
int pattern_x_diff, pattern_y_diff, pattern_x_diff2, pattern_y_diff2; int mmu_start;
int patcnt, mmu_start;
uint32_t pattern_addr, source_addr, dest_addr, mix_addr, uint32_t pattern_addr, source_addr, dest_addr, mix_addr,
pattern_back, source_back, dest_back, mix_back, pattern_back, source_back, dest_back, mix_back,
@@ -121,7 +121,7 @@ typedef struct et4000w32p_t {
static int et4000w32_vbus[4] = { 1, 2, 4, 4 }; static int et4000w32_vbus[4] = { 1, 2, 4, 4 };
static int et4000w32_max_x[8] = { 0, 0, 4, 8, 0x10, 0x20, 0x40, 0x70000000 }; static int et4000w32_max_x[8] = { 0, 0, 4, 8, 0x10, 0x20, 0x40, 0x70000000 };
static int et4000w32_wrap_x[8] = { 0, 0, 3, 7, 0x0F, 0x1F, 0x3F, ~0 }; static int et4000w32_wrap_x[8] = { 0, 0, 3, 7, 0x0f, 0x1f, 0x3f, ~0 };
static int et4000w32_wrap_y[8] = { 1, 2, 4, 8, ~0, ~0, ~0, ~0 }; static int et4000w32_wrap_y[8] = { 1, 2, 4, 8, ~0, ~0, ~0, ~0 };
static video_timings_t timing_et4000w32_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; static video_timings_t timing_et4000w32_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 };
@@ -272,14 +272,20 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p)
case 0x216b: case 0x216b:
case 0x217b: case 0x217b:
et4000->regs[et4000->index] = val; et4000->regs[et4000->index] = val;
svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || (et4000->type == ET4000W32)) ? 128 : 64;
svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8);
svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8);
svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80); svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80);
svga->hwcursor.xoff = et4000->regs[0xE2]; svga->hwcursor.xoff = et4000->regs[0xE2];
svga->hwcursor.yoff = et4000->regs[0xE6]; svga->hwcursor.yoff = et4000->regs[0xE6];
svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->type == ET4000W32) && et4000->regs[0xe2] && et4000->regs[0xe6])) ? 128 : 64;
if (et4000->type == ET4000W32) { if (et4000->type == ET4000W32) {
if ((svga->bpp == 15) || (svga->bpp == 16)) {
svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 128;
}
}
if (((et4000->type == ET4000W32) && (svga->hwcursor.cur_xsize == 128))) {
switch (svga->bpp) { switch (svga->bpp) {
case 8: case 8:
svga->hwcursor.xoff += 32; svga->hwcursor.xoff += 32;
@@ -297,7 +303,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p)
} }
} else { } else {
if (et4000->type > ET4000W32P_REVC) { if (et4000->type > ET4000W32P_REVC) {
if (svga->bpp == 24 && et4000->adjust_cursor) { if ((svga->bpp == 24) && et4000->adjust_cursor) {
et4000->adjust_cursor = 0; et4000->adjust_cursor = 0;
} }
} }
@@ -674,40 +680,46 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val)
et4000->acl.fifo_queue++; et4000->acl.fifo_queue++;
switch (addr & 0xff) { switch (addr & 0xff) {
case 0x80: case 0x80:
et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3fff00) | val; et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xffffff00) | val;
break; break;
case 0x81: case 0x81:
et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3f00ff) | (val << 8); et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xffff00ff) | (val << 8);
break; break;
case 0x82: case 0x82:
et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00ffff) | ((val & 0x3f) << 16); et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xff00ffff) | (val << 16);
break;
case 0x83:
et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00ffffff) | (val << 24);
break; break;
case 0x84: case 0x84:
et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3fff00) | val; et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xffffff00) | val;
break; break;
case 0x85: case 0x85:
et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3f00ff) | (val << 8); et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xffff00ff) | (val << 8);
break; break;
case 0x86: case 0x86:
et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00ffff) | ((val & 0x3f) << 16); et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xff00ffff) | (val << 16);
break;
case 0x87:
et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00ffffff) | (val << 24);
break; break;
case 0x88: case 0x88:
et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x0f00) | val; et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0xff00) | val;
break; break;
case 0x89: case 0x89:
et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00ff) | ((val & 0x0f) << 8); et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00ff) | (val << 8);
break; break;
case 0x8a: case 0x8a:
et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x0f00) | val; et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0xff00) | val;
break; break;
case 0x8b: case 0x8b:
et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00ff) | ((val & 0x0f) << 8); et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00ff) | (val << 8);
break; break;
case 0x8c: case 0x8c:
et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x0f00) | val; et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0xff00) | val;
break; break;
case 0x8d: case 0x8d:
et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00ff) | ((val & 0x0f) << 8); et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00ff) | (val << 8);
break; break;
case 0x8e: case 0x8e:
if (et4000->type >= ET4000W32P_REVC) if (et4000->type >= ET4000W32P_REVC)
@@ -728,16 +740,16 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val)
et4000->acl.queued.source_wrap = val & 0x77; et4000->acl.queued.source_wrap = val & 0x77;
break; break;
case 0x98: case 0x98:
et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x0f00) | val; et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0xff00) | val;
break; break;
case 0x99: case 0x99:
et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00ff) | ((val & 0x0f) << 8); et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00ff) | (val << 8);
break; break;
case 0x9a: case 0x9a:
et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x0f00) | val; et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0xff00) | val;
break; break;
case 0x9b: case 0x9b:
et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00ff) | ((val & 0x0f) << 8); et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00ff) | (val << 8);
break; break;
case 0x9c: case 0x9c:
if (et4000->type >= ET4000W32P_REVC) if (et4000->type >= ET4000W32P_REVC)
@@ -755,15 +767,16 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val)
et4000->acl.queued.rop_fg = val; et4000->acl.queued.rop_fg = val;
break; break;
case 0xa0: case 0xa0:
et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3fff00) | val; et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xffffff00) | val;
break; break;
case 0xa1: case 0xa1:
et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3f00ff) | (val << 8); et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xffff00ff) | (val << 8);
break; break;
case 0xa2: case 0xa2:
et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00ffff) | ((val & 0x3f) << 16); et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xff00ffff) | (val << 16);
break; break;
case 0xa3: case 0xa3:
et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00ffffff) | (val << 24);
et4000->acl.internal = et4000->acl.queued; et4000->acl.internal = et4000->acl.queued;
if (et4000->type >= ET4000W32P_REVC) { if (et4000->type >= ET4000W32P_REVC) {
et4000w32p_blit_start(et4000); et4000w32p_blit_start(et4000);
@@ -778,9 +791,10 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val)
et4000w32_blit_start(et4000); et4000w32_blit_start(et4000);
et4000->acl.cpu_input_num = 0; et4000->acl.cpu_input_num = 0;
if (!(et4000->acl.queued.ctrl_routing & 0x37)) { if (!(et4000->acl.queued.ctrl_routing & 0x37)) {
et4000->acl.mmu_start = 0; et4000->acl.mmu_start = 1;
et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); et4000w32_blit(-1, 0, 0, 0xffffffff, et4000);
} } else
et4000->acl.mmu_start = 0;
} }
break; break;
case 0xa4: case 0xa4:
@@ -843,11 +857,13 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uin
et4000->acl.queued.dest_addr = ((addr & 0x1fff) + et4000->mmu.base[bank]); et4000->acl.queued.dest_addr = ((addr & 0x1fff) + et4000->mmu.base[bank]);
et4000->acl.internal = et4000->acl.queued; et4000->acl.internal = et4000->acl.queued;
et4000w32_blit_start(et4000); et4000w32_blit_start(et4000);
et4000w32_log("ET4000W32 Accelerated MMU aperture start XY Block (Implicit): bank = %i, patx = %i, paty = %i, wrap y = %i\n", et4000->bank, et4000->acl.pattern_x, et4000->acl.pattern_y, et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]); et4000w32_log("ET4000W32 Accelerated MMU aperture start XY Block (Implicit): bank = %i, patx = %i, paty = %i, wrap x = %i, wrap y = %i\n", et4000->bank, et4000->acl.pattern_x, et4000->acl.pattern_y, et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7], et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]);
et4000->acl.cpu_input_num = 0; et4000->acl.cpu_input_num = 0;
if (!(et4000->acl.queued.ctrl_routing & 0x37)) { if (!(et4000->acl.queued.ctrl_routing & 0x37)) {
et4000->acl.mmu_start = 1; et4000->acl.mmu_start = 1;
et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); et4000w32_blit(-1, 0, 0, 0xffffffff, et4000);
} else {
et4000->acl.mmu_start = 0;
} }
} }
@@ -865,10 +881,19 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uin
et4000->acl.cpu_input_num = 0; et4000->acl.cpu_input_num = 0;
} }
if ((et4000->acl.internal.ctrl_routing & 7) == 4) /*CPU data is X Count*/ if (et4000w32_vbus[et4000->acl.internal.vbus] == 1) {
et4000w32_blit(val | (et4000->acl.queued.count_x << 8), 0, 0, 0xffffffff, et4000); if ((et4000->acl.internal.ctrl_routing & 7) == 4) { /*CPU data is X Count*/
if ((et4000->acl.internal.ctrl_routing & 7) == 5) /*CPU data is Y Count*/ et4000w32_log("ET4000W32 Accelerated MMU aperture routing = %02x: val = %02x, cx = %02x.\n", et4000->acl.internal.ctrl_routing, val, et4000->acl.internal.count_x);
et4000w32_blit(val | (et4000->acl.queued.count_y << 8), 0, 0, 0xffffffff, et4000); et4000->acl.cpu_x_cnt = val + 1;
et4000->acl.cpu_x_cnt |= ((et4000->acl.queued.count_x >> 8) << 8);
et4000w32_blit(et4000->acl.cpu_x_cnt, 3, 0, 0xffffffff, et4000);
} else if ((et4000->acl.internal.ctrl_routing & 7) == 5) { /*CPU data is Y Count*/
et4000w32_log("ET4000W32 Accelerated MMU aperture routing = %02x: val = %02x, cy = %02x.\n", et4000->acl.internal.ctrl_routing, val, et4000->acl.internal.count_y);
et4000->acl.cpu_y_cnt = val + 1;
et4000->acl.cpu_y_cnt |= ((et4000->acl.queued.count_y >> 8) << 8);
et4000w32_blit(et4000->acl.cpu_y_cnt, 4, 0, 0xffffffff, et4000);
}
}
} }
} }
} }
@@ -899,31 +924,40 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
} else { } else {
switch (addr & 0xff) { switch (addr & 0xff) {
case 0x00: case 0x00:
et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3fff00) | val; et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xffffff00) | val;
break; break;
case 0x01: case 0x01:
et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3f00ff) | (val << 8); et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xffff00ff) | (val << 8);
break; break;
case 0x02: case 0x02:
et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00ffff) | ((val & 0x3f) << 16); et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xff00ffff) | (val << 16);
break;
case 0x03:
et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00ffffff) | (val << 24);
break; break;
case 0x04: case 0x04:
et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3fff00) | val; et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xffffff00) | val;
break; break;
case 0x05: case 0x05:
et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3f00ff) | (val << 8); et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xffff00ff) | (val << 8);
break; break;
case 0x06: case 0x06:
et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00ffff) | ((val & 0x3f) << 16); et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xff00ffff) | (val << 16);
break;
case 0x07:
et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00ffffff) | (val << 24);
break; break;
case 0x08: case 0x08:
et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3fff00) | val; et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xffffff00) | val;
break; break;
case 0x09: case 0x09:
et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3f00ff) | (val << 8); et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xffff00ff) | (val << 8);
break; break;
case 0x0a: case 0x0a:
et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00ffff) | ((val & 0x3f) << 16); et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xff00ffff) | (val << 16);
break;
case 0x0b:
et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00ffffff) | (val << 24);
break; break;
case 0x13: case 0x13:
et4000->mmu.ctrl = val; et4000->mmu.ctrl = val;
@@ -1127,6 +1161,26 @@ et4000w32_blit_start(et4000w32p_t *et4000)
et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1);
} }
et4000->acl.source_x_back = et4000->acl.source_x; et4000->acl.source_x_back = et4000->acl.source_x;
if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] == 7) && !(et4000->acl.internal.ctrl_routing & 0x37) && (et4000->acl.internal.rop_fg == 0x5a)) {
if ((et4000->acl.internal.count_y > 0) && (et4000->acl.pattern_y > 0)) {
if (et4000->acl.pattern_addr == et4000->acl.pattern_back)
et4000->acl.pattern_y = 0;
else {
et4000->acl.pattern_y = (et4000->acl.pattern_addr - et4000->acl.pattern_back) & 0x70;
et4000->acl.pattern_y >>= 4;
}
}
} else if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] == 15) && !(et4000->acl.internal.ctrl_routing & 0x37) && (et4000->acl.internal.rop_fg == 0x5a)) {
if ((et4000->acl.internal.count_y > 0) && (et4000->acl.pattern_y > 0)) {
if (et4000->acl.pattern_addr == et4000->acl.pattern_back)
et4000->acl.pattern_y = 0;
else {
et4000->acl.pattern_y = (et4000->acl.pattern_addr - et4000->acl.pattern_back) & 0xf0;
et4000->acl.pattern_y >>= 5;
}
}
}
} }
static void static void
@@ -1137,6 +1191,7 @@ et4000w32p_blit_start(et4000w32p_t *et4000)
if (!(et4000->acl.queued.xy_dir & 0x20)) if (!(et4000->acl.queued.xy_dir & 0x20))
et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; et4000->acl.internal.error = et4000->acl.internal.dmaj / 2;
et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr;
et4000->acl.source_addr = et4000->acl.internal.source_addr; et4000->acl.source_addr = et4000->acl.internal.source_addr;
et4000->acl.mix_addr = et4000->acl.internal.mix_addr; et4000->acl.mix_addr = et4000->acl.internal.mix_addr;
@@ -1236,12 +1291,12 @@ et4000w32_decy(et4000w32p_t *et4000)
et4000->acl.mix_addr -= et4000->acl.internal.mix_off + 1; et4000->acl.mix_addr -= et4000->acl.internal.mix_off + 1;
et4000->acl.dest_addr -= et4000->acl.internal.dest_off + 1; et4000->acl.dest_addr -= et4000->acl.internal.dest_off + 1;
et4000->acl.pattern_y--; et4000->acl.pattern_y--;
if (et4000->acl.pattern_y < 0 && !(et4000->acl.internal.pattern_wrap & 0x40)) { if ((et4000->acl.pattern_y < 0) && !(et4000->acl.internal.pattern_wrap & 0x40)) {
et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1;
et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1));
} }
et4000->acl.source_y--; et4000->acl.source_y--;
if (et4000->acl.source_y < 0 && !(et4000->acl.internal.source_wrap & 0x40)) { if ((et4000->acl.source_y < 0) && !(et4000->acl.internal.source_wrap & 0x40)) {
et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1;
et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1));
} }
@@ -2030,99 +2085,168 @@ et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4
uint8_t out; uint8_t out;
int mixmap; int mixmap;
while (count-- && et4000->acl.y_count >= 0) { if (!(et4000->acl.status & ACL_XYST) && !et4000->acl.mmu_start) {
pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; et4000w32_log("XY Block not started\n");
return;
}
if (cpu_input == 1) { if (cpu_input == 3) {
source = src_dat & 0xff; while (1) {
src_dat >>= 8; pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask];
} else /*The source data is from the display memory if the Control Routing register is not set to 1*/
source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask];
dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask];
mixmap = mix_dat & 1; mixmap = mix_dat & 1;
/*Now determine the Raster Operation*/ rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg;
rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; mix_dat >>= 1;
mix_dat >>= 1; mix_dat |= 0x80000000;
mix_dat |= 0x80000000;
ROPMIX(rop, dest, pattern, source, out); ROPMIX(rop, dest, pattern, source, out);
/*Write the data*/ /*Write the data*/
svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out;
svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount;
if (et4000->acl.internal.xy_dir & 1) { if (et4000->acl.internal.xy_dir & 1)
et4000->acl.dest_addr--; et4000w32_decx(1, et4000);
et4000->acl.pattern_x--; else
et4000->acl.source_x--; et4000w32_incx(1, et4000);
if (et4000->acl.pattern_x < 0)
et4000->acl.pattern_x += (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); count--;
if (et4000->acl.source_x < 0) if (!count) {
et4000->acl.source_x += (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); count = et4000->acl.cpu_x_cnt;
} else {
et4000->acl.dest_addr++; if (et4000->acl.internal.xy_dir & 2) {
et4000->acl.pattern_x++; et4000w32_decy(et4000);
et4000->acl.source_x++; et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1);
if (et4000->acl.pattern_x >= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) } else {
et4000->acl.pattern_x -= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); et4000w32_incy(et4000);
if (et4000->acl.source_x >= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1;
et4000->acl.source_x -= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); }
et4000->acl.pattern_x = et4000->acl.pattern_x_back;
et4000->acl.source_x = et4000->acl.source_x_back;
et4000->acl.y_count--;
if (et4000->acl.y_count == 0xffff) {
et4000->acl.status &= ~ACL_XYST;
if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) {
et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count);
et4000->acl.status &= ~ACL_SSO;
}
return;
}
}
} }
} else if (cpu_input == 4) {
while (1) {
pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask];
source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask];
et4000->acl.x_count--; dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask];
if (et4000->acl.x_count == 0xffff) { mixmap = mix_dat & 1;
et4000->acl.x_count = et4000->acl.internal.count_x;
if (et4000->acl.internal.xy_dir & 2) { rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg;
et4000->acl.pattern_addr -= (et4000->acl.internal.pattern_off + 1); mix_dat >>= 1;
et4000->acl.source_addr -= (et4000->acl.internal.source_off + 1); mix_dat |= 0x80000000;
et4000->acl.dest_addr -= (et4000->acl.internal.dest_off + 1);
et4000->acl.pattern_y--; ROPMIX(rop, dest, pattern, source, out);
if ((et4000->acl.pattern_y < 0) && !(et4000->acl.internal.pattern_wrap & 0x40)) {
et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; /*Write the data*/
et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out;
svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount;
if (et4000->acl.internal.xy_dir & 1)
et4000w32_decx(1, et4000);
else
et4000w32_incx(1, et4000);
et4000->acl.x_count--;
if (et4000->acl.x_count == 0xffff) {
et4000->acl.x_count = et4000->acl.internal.count_x;
if (et4000->acl.internal.xy_dir & 2) {
et4000w32_decy(et4000);
et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1);
} else {
et4000w32_incy(et4000);
et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1;
} }
et4000->acl.source_y--;
if ((et4000->acl.source_y < 0) && !(et4000->acl.internal.source_wrap & 0x40)) { et4000->acl.pattern_x = et4000->acl.pattern_x_back;
et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; et4000->acl.source_x = et4000->acl.source_x_back;
et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1));
count--;
if (!count) {
et4000->acl.status &= ~ACL_XYST;
if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) {
et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count);
et4000->acl.status &= ~ACL_SSO;
}
return;
} }
et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1);
} else {
et4000->acl.pattern_addr += (et4000->acl.internal.pattern_off + 1);
et4000->acl.source_addr += (et4000->acl.internal.source_off + 1);
et4000->acl.dest_addr += (et4000->acl.internal.dest_off + 1);
et4000->acl.pattern_y++;
if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) {
et4000->acl.pattern_y = 0;
et4000->acl.pattern_addr = et4000->acl.pattern_back;
}
et4000->acl.source_y++;
if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) {
et4000->acl.source_y = 0;
et4000->acl.source_addr = et4000->acl.source_back;
}
et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + (et4000->acl.internal.dest_off + 1);
} }
}
} else {
while (count-- && (et4000->acl.y_count >= 0)) {
pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask];
et4000->acl.pattern_x = et4000->acl.pattern_x_back; if (cpu_input == 1) {
et4000->acl.source_x = et4000->acl.source_x_back; source = src_dat & 0xff;
src_dat >>= 8;
} else /*The source data is from the display memory if the Control Routing register is not set to 1*/
source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask];
et4000->acl.y_count--; dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask];
if (et4000->acl.y_count == 0xffff) { mixmap = mix_dat & 1;
et4000->acl.status &= ~ACL_XYST;
if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) { /*Now determine the Raster Operation*/
et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count); rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg;
et4000->acl.status &= ~ACL_SSO; mix_dat >>= 1;
mix_dat |= 0x80000000;
ROPMIX(rop, dest, pattern, source, out);
/*Write the data*/
svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out;
svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount;
if (et4000->acl.internal.xy_dir & 1)
et4000w32_decx(1, et4000);
else
et4000w32_incx(1, et4000);
et4000->acl.x_count--;
if (et4000->acl.x_count == 0xffff) {
et4000->acl.x_count = et4000->acl.internal.count_x;
if (et4000->acl.internal.xy_dir & 2) {
et4000w32_decy(et4000);
et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1);
} else {
et4000w32_incy(et4000);
et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1;
} }
et4000->acl.cpu_input_num = 0;
return;
}
if (cpu_input) et4000->acl.pattern_x = et4000->acl.pattern_x_back;
return; et4000->acl.source_x = et4000->acl.source_x_back;
et4000->acl.y_count--;
if (et4000->acl.y_count == 0xffff) {
et4000->acl.status &= ~ACL_XYST;
if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) {
et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count);
et4000->acl.status &= ~ACL_SSO;
}
et4000->acl.cpu_input_num = 0;
return;
}
if (cpu_input) {
return;
}
}
} }
} }
} }
@@ -2334,7 +2458,7 @@ et4000w32p_hwcursor_draw(svga_t *svga, int displine)
uint8_t dat; uint8_t dat;
offset = svga->hwcursor_latch.xoff; offset = svga->hwcursor_latch.xoff;
if (et4000->type == ET4000W32) { if ((et4000->type == ET4000W32) && (pitch == 32)) {
switch (svga->bpp) { switch (svga->bpp) {
case 8: case 8:
minus_width = 0; minus_width = 0;