mirror of
https://github.com/86Box/86Box.git
synced 2026-02-25 12:55:32 -07:00
Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
@@ -401,7 +401,7 @@ ati28800_recalctimings(svga_t *svga)
|
||||
case 0x09: svga->clock = (cpuclock * (double)(1ull << 32)) / 32000000.0; break;
|
||||
case 0x0A: svga->clock = (cpuclock * (double)(1ull << 32)) / 37500000.0; break;
|
||||
case 0x0B: svga->clock = (cpuclock * (double)(1ull << 32)) / 39000000.0; break;
|
||||
case 0x0C: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break;
|
||||
case 0x0C: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break;
|
||||
case 0x0D: svga->clock = (cpuclock * (double)(1ull << 32)) / 56644000.0; break;
|
||||
case 0x0E: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break;
|
||||
case 0x0F: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break;
|
||||
@@ -423,14 +423,6 @@ ati28800_recalctimings(svga_t *svga)
|
||||
svga->rowoffset <<= 1;
|
||||
}
|
||||
|
||||
if (svga->crtc[0x17] & 4) {
|
||||
svga->vtotal <<= 1;
|
||||
svga->dispend <<= 1;
|
||||
svga->vsyncstart <<= 1;
|
||||
svga->split <<= 1;
|
||||
svga->vblankstart <<= 1;
|
||||
}
|
||||
|
||||
if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) { /* Extended 256 colour modes */
|
||||
switch (svga->bpp) {
|
||||
case 8:
|
||||
|
||||
@@ -123,7 +123,7 @@ cga_waitstates(void *p)
|
||||
int ws;
|
||||
|
||||
ws = ws_array[cycles & 0xf];
|
||||
sub_cycles(ws);
|
||||
cycles -= ws;
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -100,7 +100,7 @@ void colorplus_write(uint32_t addr, uint8_t val, void *p)
|
||||
colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff];
|
||||
}
|
||||
egawrites++;
|
||||
sub_cycles(4);
|
||||
cycles -= 4;
|
||||
}
|
||||
|
||||
uint8_t colorplus_read(uint32_t addr, void *p)
|
||||
@@ -117,7 +117,7 @@ uint8_t colorplus_read(uint32_t addr, void *p)
|
||||
{
|
||||
addr &= 0x3FFF;
|
||||
}
|
||||
sub_cycles(4);
|
||||
cycles -= 4;
|
||||
if (colorplus->cga.snow_enabled)
|
||||
{
|
||||
int offset = ((timer_get_remaining_u64(&colorplus->cga.timer) / CGACONST) * 2) & 0xfc;
|
||||
|
||||
@@ -732,7 +732,7 @@ ega_write(uint32_t addr, uint8_t val, void *p)
|
||||
int writemask2 = ega->writemask;
|
||||
|
||||
egawrites++;
|
||||
sub_cycles(video_timing_write_b);
|
||||
cycles -= video_timing_write_b;
|
||||
|
||||
if (addr >= 0xB0000) addr &= 0x7fff;
|
||||
else addr &= 0xffff;
|
||||
@@ -859,7 +859,7 @@ ega_read(uint32_t addr, void *p)
|
||||
int readplane = ega->readplane;
|
||||
|
||||
egareads++;
|
||||
sub_cycles(video_timing_read_b);
|
||||
cycles -= video_timing_read_b;
|
||||
if (addr >= 0xb0000) addr &= 0x7fff;
|
||||
else addr &= 0xffff;
|
||||
|
||||
|
||||
@@ -245,6 +245,15 @@ et4000_out(uint16_t addr, uint8_t val, void *priv)
|
||||
svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000;
|
||||
} else
|
||||
svga->write_bank = svga->read_bank = 0;
|
||||
|
||||
old = svga->gdcreg[6];
|
||||
svga_out(addr, val, svga);
|
||||
if ((old & 0xc) != 0 && (val & 0xc) == 0)
|
||||
{
|
||||
/*override mask - ET4000 supports linear 128k at A0000*/
|
||||
svga->banked_mask = 0x1ffff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -454,7 +454,7 @@ void et4000w32p_recalcmapping(et4000w32p_t *et4000)
|
||||
case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/
|
||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
||||
mem_mapping_disable(&et4000->mmu_mapping);
|
||||
svga->banked_mask = 0xffff;
|
||||
svga->banked_mask = 0x1ffff;
|
||||
break;
|
||||
case 0x1: /*64k at A0000*/
|
||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||
|
||||
@@ -253,7 +253,7 @@ genius_waitstates(void)
|
||||
int ws;
|
||||
|
||||
ws = ws_array[cycles & 0xf];
|
||||
sub_cycles(ws);
|
||||
cycles -= ws;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ hercules_waitstates(void *p)
|
||||
int ws;
|
||||
|
||||
ws = ws_array[cycles & 0xf];
|
||||
sub_cycles(ws);
|
||||
cycles -= ws;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -729,7 +729,7 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
|
||||
svga_t *svga = &ht216->svga;
|
||||
uint8_t bit_mask = 0, rop_select = 0;
|
||||
|
||||
sub_cycles(video_timing_write_b);
|
||||
cycles -= video_timing_write_b;
|
||||
|
||||
egawrites++;
|
||||
|
||||
@@ -911,7 +911,7 @@ ht216_read_common(ht216_t *ht216, uint32_t addr)
|
||||
|
||||
addr &= 0xfffff;
|
||||
|
||||
sub_cycles(video_timing_read_b);
|
||||
cycles -= video_timing_read_b;
|
||||
|
||||
egareads++;
|
||||
|
||||
|
||||
@@ -2132,7 +2132,7 @@ mystique_readb_linear(uint32_t addr, void *p)
|
||||
|
||||
egareads++;
|
||||
|
||||
sub_cycles(video_timing_read_b);
|
||||
cycles -= video_timing_read_b;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
@@ -2149,7 +2149,7 @@ mystique_readw_linear(uint32_t addr, void *p)
|
||||
|
||||
egareads += 2;
|
||||
|
||||
sub_cycles(video_timing_read_w);
|
||||
cycles -= video_timing_read_w;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
@@ -2166,7 +2166,7 @@ mystique_readl_linear(uint32_t addr, void *p)
|
||||
|
||||
egareads += 4;
|
||||
|
||||
sub_cycles(video_timing_read_l);
|
||||
cycles -= video_timing_read_l;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
@@ -2183,7 +2183,7 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *p)
|
||||
|
||||
egawrites++;
|
||||
|
||||
sub_cycles(video_timing_write_b);
|
||||
cycles -= video_timing_write_b;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
@@ -2201,7 +2201,7 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *p)
|
||||
|
||||
egawrites += 2;
|
||||
|
||||
sub_cycles(video_timing_write_w);
|
||||
cycles -= video_timing_write_w;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
@@ -2219,7 +2219,7 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *p)
|
||||
|
||||
egawrites += 4;
|
||||
|
||||
sub_cycles(video_timing_write_l);
|
||||
cycles -= video_timing_write_l;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
|
||||
@@ -2697,7 +2697,7 @@ s3_accel_in(uint16_t port, void *p)
|
||||
if (FIFO_FULL && s3->chip >= S3_VISION964)
|
||||
temp |= 0xf8; /*FIFO full*/
|
||||
} else {
|
||||
if (s3->busy || s3->force_busy) {
|
||||
if (s3->force_busy) {
|
||||
temp |= 0x02; /*Hardware busy*/
|
||||
}
|
||||
s3->force_busy = 0;
|
||||
@@ -3343,10 +3343,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
||||
dstbase >>= 2;
|
||||
}
|
||||
|
||||
if (((s3_cpu_src(s3) || s3_cpu_dest(s3))) && (s3->chip >= S3_86C928 && s3->chip < S3_TRIO64V)) {
|
||||
s3->busy = 1;
|
||||
}
|
||||
|
||||
if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || s3_cpu_dest(s3)) && !cpu_input) {
|
||||
s3->force_busy = 1;
|
||||
}
|
||||
@@ -3439,7 +3435,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
||||
if (s3->bpp == 0) cpu_dat >>= 8;
|
||||
else cpu_dat >>= 16;
|
||||
if (!s3->accel.sy) {
|
||||
s3->busy = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3510,7 +3505,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
||||
else cpu_dat >>= 16;
|
||||
|
||||
if (!s3->accel.sy) {
|
||||
s3->busy = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3682,10 +3676,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
||||
s3->accel.dest = dstbase + s3->accel.cy * s3->width;
|
||||
s3->accel.sy--;
|
||||
|
||||
if (s3->accel.sy < 0) {
|
||||
s3->busy = 0;
|
||||
}
|
||||
|
||||
if (cpu_input) {
|
||||
if (s3_cpu_dest(s3))
|
||||
s3->data_available = 1;
|
||||
@@ -3766,7 +3756,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
||||
s3->accel.sy--;
|
||||
|
||||
if (s3->accel.sy < 0) {
|
||||
s3->busy = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3854,9 +3843,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
||||
|
||||
s3->accel.sy--;
|
||||
|
||||
if (s3->accel.sy < 0)
|
||||
s3->busy = 0;
|
||||
|
||||
if (cpu_input)
|
||||
return;
|
||||
|
||||
@@ -3979,9 +3965,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
||||
|
||||
s3->accel.sy--;
|
||||
|
||||
if (s3->accel.sy < 0)
|
||||
s3->busy = 0;
|
||||
|
||||
if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return;
|
||||
if (s3->accel.sy < 0)
|
||||
return;
|
||||
@@ -4061,7 +4044,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
||||
s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff;
|
||||
s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff;
|
||||
}
|
||||
s3->busy = 0;
|
||||
break;
|
||||
|
||||
case 11: /*Polygon Fill Pattern (Trio64 only)*/
|
||||
@@ -4150,7 +4132,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
|
||||
s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff;
|
||||
s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff;
|
||||
}
|
||||
s3->busy = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +344,7 @@ sigma_write(uint32_t addr, uint8_t val, void *p)
|
||||
|
||||
sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)] = val;
|
||||
egawrites++;
|
||||
sub_cycles(4);
|
||||
cycles -= 4;
|
||||
}
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ sigma_read(uint32_t addr, void *p)
|
||||
{
|
||||
sigma_t *sigma = (sigma_t *)p;
|
||||
|
||||
sub_cycles(4);
|
||||
cycles -= 4;
|
||||
egareads++;
|
||||
return sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)];
|
||||
}
|
||||
|
||||
@@ -1015,7 +1015,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
|
||||
egawrites++;
|
||||
|
||||
sub_cycles(video_timing_write_b);
|
||||
cycles -= video_timing_write_b;
|
||||
|
||||
if (!linear) {
|
||||
addr = svga_decode_addr(svga, addr, 1);
|
||||
@@ -1057,14 +1057,21 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
if (svga->adv_flags & FLAG_LATCH8)
|
||||
count = 8;
|
||||
|
||||
/* Undocumented Cirrus Logic behavior: The datasheet says that, with EXT_WRITE and FLAG_ADDR_BY8, the write mask only
|
||||
changes meaning in write modes 4 and 5, as well as write mode 1. In reality, however, all other write modes are also
|
||||
affected, as proven by the Windows 3.1 CL-GD 5422/4 drivers in 8bpp modes. */
|
||||
switch (svga->writemode) {
|
||||
case 0:
|
||||
if (svga->gdcreg[3] & 7)
|
||||
val = svga_rotate[svga->gdcreg[3] & 7][val];
|
||||
val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7))));
|
||||
if ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = val;
|
||||
if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) {
|
||||
if (writemask2 & (0x80 >> i))
|
||||
svga->vram[addr | i] = val;
|
||||
} else {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = val;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
@@ -1078,8 +1085,13 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
break;
|
||||
case 1:
|
||||
for (i = 0; i < count; i++) {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = svga->latch.b[i];
|
||||
if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) {
|
||||
if (writemask2 & (0x80 >> i))
|
||||
svga->vram[addr | i] = svga->latch.b[i];
|
||||
} else {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = svga->latch.b[i];
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 2:
|
||||
@@ -1088,15 +1100,19 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
|
||||
if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]);
|
||||
if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) {
|
||||
if (writemask2 & (0x80 >> i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]);
|
||||
} else {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (svga->gdcreg[3] & 7)
|
||||
val = svga_rotate[svga->gdcreg[3] & 7][val];
|
||||
val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7))));
|
||||
wm = svga->gdcreg[8];
|
||||
svga->gdcreg[8] &= val;
|
||||
|
||||
@@ -1114,26 +1130,46 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
switch (svga->gdcreg[3] & 0x18) {
|
||||
case 0x00: /* Set */
|
||||
for (i = 0; i < count; i++) {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]);
|
||||
if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) {
|
||||
if (writemask2 & (0x80 >> i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]);
|
||||
} else {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x08: /* AND */
|
||||
for (i = 0; i < count; i++) {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i];
|
||||
if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) {
|
||||
if (writemask2 & (0x80 >> i))
|
||||
svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i];
|
||||
} else {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x10: /* OR */
|
||||
for (i = 0; i < count; i++) {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i];
|
||||
if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) {
|
||||
if (writemask2 & (0x80 >> i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i];
|
||||
} else {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x18: /* XOR */
|
||||
for (i = 0; i < count; i++) {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i];
|
||||
if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) {
|
||||
if (writemask2 & (0x80 >> i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i];
|
||||
} else {
|
||||
if (writemask2 & (1 << i))
|
||||
svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1156,7 +1192,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
readplane = svga->gdcreg[4] & 7;
|
||||
|
||||
sub_cycles(video_timing_read_b);
|
||||
cycles -= video_timing_read_b;
|
||||
|
||||
egareads++;
|
||||
|
||||
@@ -1182,6 +1218,9 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
addr = svga->translate_address(addr, p);
|
||||
if (addr >= svga->vram_max)
|
||||
return 0xff;
|
||||
latch_addr = (addr & svga->vram_mask) & ~3;
|
||||
for (i = 0; i < count; i++)
|
||||
svga->latch.b[i] = svga->vram[latch_addr | i];
|
||||
return svga->vram[addr & svga->vram_mask];
|
||||
} else if (svga->chain2_read) {
|
||||
readplane = (readplane & 2) | (addr & 1);
|
||||
@@ -1381,7 +1420,7 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p)
|
||||
|
||||
egawrites += 2;
|
||||
|
||||
sub_cycles(video_timing_write_w);
|
||||
cycles -= video_timing_write_w;
|
||||
|
||||
if (!linear) {
|
||||
addr = svga_decode_addr(svga, addr, 1);
|
||||
@@ -1442,7 +1481,7 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p)
|
||||
|
||||
egawrites += 4;
|
||||
|
||||
sub_cycles(video_timing_write_l);
|
||||
cycles -= video_timing_write_l;
|
||||
|
||||
if (!linear) {
|
||||
addr = svga_decode_addr(svga, addr, 1);
|
||||
@@ -1526,7 +1565,7 @@ svga_readw_common(uint32_t addr, uint8_t linear, void *p)
|
||||
|
||||
egareads += 2;
|
||||
|
||||
sub_cycles(video_timing_read_w);
|
||||
cycles -= video_timing_read_w;
|
||||
|
||||
if (!linear) {
|
||||
addr = svga_decode_addr(svga, addr, 0);
|
||||
@@ -1579,7 +1618,7 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *p)
|
||||
|
||||
egareads += 4;
|
||||
|
||||
sub_cycles(video_timing_read_l);
|
||||
cycles -= video_timing_read_l;
|
||||
|
||||
if (!linear) {
|
||||
addr = svga_decode_addr(svga, addr, 0);
|
||||
|
||||
@@ -71,9 +71,7 @@ video_cards[] = {
|
||||
{ "cl_gd5401_isa", &gd5401_isa_device },
|
||||
{ "cl_gd5402_isa", &gd5402_isa_device },
|
||||
{ "cl_gd5420_isa", &gd5420_isa_device },
|
||||
#if defined(DEV_BRANCH) && defined(USE_CL5422)
|
||||
{ "cl_gd5422_isa", &gd5422_isa_device },
|
||||
#endif
|
||||
{ "cl_gd5428_isa", &gd5428_isa_device },
|
||||
{ "cl_gd5429_isa", &gd5429_isa_device },
|
||||
{ "cl_gd5434_isa", &gd5434_isa_device },
|
||||
@@ -154,9 +152,7 @@ video_cards[] = {
|
||||
{ "voodoo3_3k_pci", &voodoo_3_3000_device },
|
||||
{ "mach64gx_vlb", &mach64gx_vlb_device },
|
||||
{ "et4000w32p_vlb", &et4000w32p_cardex_vlb_device },
|
||||
#if defined(DEV_BRANCH) && defined(USE_CL5422)
|
||||
{ "cl_gd5424_vlb", &gd5424_vlb_device },
|
||||
#endif
|
||||
{ "cl_gd5428_vlb", &gd5428_vlb_device },
|
||||
{ "cl_gd5429_vlb", &gd5429_vlb_device },
|
||||
{ "cl_gd5434_vlb", &gd5434_vlb_device },
|
||||
|
||||
@@ -798,7 +798,7 @@ static uint8_t tgui_ext_linear_read(uint32_t addr, void *p)
|
||||
tgui_t *tgui = (tgui_t *)svga->p;
|
||||
int c;
|
||||
|
||||
sub_cycles(video_timing_read_b);
|
||||
cycles -= video_timing_read_b;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
@@ -829,7 +829,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||
uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]};
|
||||
uint8_t mask = tgui->ext_gdc_regs[7];
|
||||
|
||||
sub_cycles(video_timing_write_b);
|
||||
cycles -= video_timing_write_b;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
@@ -898,7 +898,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||
uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]};
|
||||
uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8];
|
||||
|
||||
sub_cycles(video_timing_write_w);
|
||||
cycles -= video_timing_write_w;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
|
||||
@@ -127,6 +127,15 @@ void tvga_out(uint16_t addr, uint8_t val, void *p)
|
||||
case 0x3CF:
|
||||
switch (svga->gdcaddr & 15)
|
||||
{
|
||||
case 0x6:
|
||||
old = svga->gdcreg[6];
|
||||
svga_out(addr, val, svga);
|
||||
if ((old & 0xc) != 0 && (val & 0xc) == 0)
|
||||
{
|
||||
/*override mask - TVGA supports linear 128k at A0000*/
|
||||
svga->banked_mask = 0x1ffff;
|
||||
}
|
||||
return;
|
||||
case 0xE:
|
||||
svga->gdcreg[0xe] = val ^ 2;
|
||||
tvga->tvga_3d9 = svga->gdcreg[0xe] & 0xf;
|
||||
|
||||
@@ -151,7 +151,7 @@ static uint16_t voodoo_readw(uint32_t addr, void *p)
|
||||
|
||||
addr &= 0xffffff;
|
||||
|
||||
sub_cycles(voodoo->read_time);
|
||||
cycles -= voodoo->read_time;
|
||||
|
||||
if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/
|
||||
{
|
||||
@@ -190,7 +190,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p)
|
||||
voodoo->rd_count++;
|
||||
addr &= 0xffffff;
|
||||
|
||||
sub_cycles(voodoo->read_time);
|
||||
cycles -= voodoo->read_time;
|
||||
|
||||
if (addr & 0x800000) /*Texture*/
|
||||
{
|
||||
@@ -390,7 +390,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p)
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("voodoo_readl : bad addr %08X\n", addr);
|
||||
voodoo_log("voodoo_readl : bad addr %08X\n", addr);
|
||||
temp = 0xffffffff;
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ static void voodoo_writew(uint32_t addr, uint16_t val, void *p)
|
||||
voodoo->wr_count++;
|
||||
addr &= 0xffffff;
|
||||
|
||||
sub_cycles(voodoo->write_time);
|
||||
cycles -= voodoo->write_time;
|
||||
|
||||
if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/
|
||||
voodoo_queue_command(voodoo, addr | FIFO_WRITEW_FB, val);
|
||||
@@ -418,9 +418,9 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
|
||||
addr &= 0xffffff;
|
||||
|
||||
if (addr == voodoo->last_write_addr+4)
|
||||
sub_cycles(voodoo->burst_time);
|
||||
cycles -= voodoo->burst_time;
|
||||
else
|
||||
sub_cycles(voodoo->write_time);
|
||||
cycles -= voodoo->write_time;
|
||||
voodoo->last_write_addr = addr;
|
||||
|
||||
if (addr & 0x800000) /*Texture*/
|
||||
|
||||
@@ -181,6 +181,8 @@ enum
|
||||
#define VIDPROCCFG_CURSOR_MODE (1 << 1)
|
||||
#define VIDPROCCFG_HALF_MODE (1 << 4)
|
||||
#define VIDPROCCFG_OVERLAY_ENABLE (1 << 8)
|
||||
#define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11)
|
||||
#define VIDPROCCFG_OVERLAY_CLUT_SEL (1 << 13)
|
||||
#define VIDPROCCFG_H_SCALE_ENABLE (1 << 14)
|
||||
#define VIDPROCCFG_V_SCALE_ENABLE (1 << 15)
|
||||
#define VIDPROCCFG_FILTER_MODE_MASK (3 << 16)
|
||||
@@ -658,7 +660,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
|
||||
|
||||
case Video_hwCurPatAddr:
|
||||
banshee->hwCurPatAddr = val;
|
||||
svga->hwcursor.addr = val & 0xfffff0;
|
||||
svga->hwcursor.addr = (val & 0xfffff0) + (svga->hwcursor.yoff * 16);
|
||||
break;
|
||||
case Video_hwCurLoc:
|
||||
banshee->hwCurLoc = val;
|
||||
@@ -671,6 +673,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
|
||||
}
|
||||
else
|
||||
svga->hwcursor.yoff = 0;
|
||||
svga->hwcursor.addr = (banshee->hwCurPatAddr & 0xfffff0) + (svga->hwcursor.yoff * 16);
|
||||
svga->hwcursor.xsize = 64;
|
||||
svga->hwcursor.ysize = 64;
|
||||
// banshee_log("hwCurLoc %08x %i\n", val, svga->hwcursor.y);
|
||||
@@ -832,7 +835,7 @@ static uint32_t banshee_ext_inl(uint16_t addr, void *p)
|
||||
svga_t *svga = &banshee->svga;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
sub_cycles(voodoo->read_time);
|
||||
cycles -= voodoo->read_time;
|
||||
|
||||
switch (addr & 0xff)
|
||||
{
|
||||
@@ -1023,7 +1026,7 @@ static uint32_t banshee_reg_readl(uint32_t addr, void *p)
|
||||
voodoo_t *voodoo = banshee->voodoo;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
sub_cycles(voodoo->read_time);
|
||||
cycles -= voodoo->read_time;
|
||||
|
||||
switch (addr & 0x1f00000)
|
||||
{
|
||||
@@ -1154,7 +1157,7 @@ static uint32_t banshee_reg_readl(uint32_t addr, void *p)
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("banshee_reg_readl: 3D addr=%08x\n", addr);
|
||||
banshee_log("banshee_reg_readl: 3D addr=%08x\n", addr);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1175,7 +1178,7 @@ static void banshee_reg_writew(uint32_t addr, uint16_t val, void *p)
|
||||
banshee_t *banshee = (banshee_t *)p;
|
||||
voodoo_t *voodoo = banshee->voodoo;
|
||||
|
||||
sub_cycles(voodoo->write_time);
|
||||
cycles -= voodoo->write_time;
|
||||
|
||||
// banshee_log("banshee_reg_writew: addr=%08x val=%04x\n", addr, val);
|
||||
switch (addr & 0x1f00000)
|
||||
@@ -1205,6 +1208,8 @@ static void banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val)
|
||||
voodoo->cmdfifo_size = val;
|
||||
voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12);
|
||||
voodoo->cmdfifo_enabled = val & 0x100;
|
||||
if (!voodoo->cmdfifo_enabled)
|
||||
voodoo->cmdfifo_in_sub = 0; /*Not sure exactly when this should be reset*/
|
||||
// banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end);
|
||||
break;
|
||||
|
||||
@@ -1248,9 +1253,9 @@ static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p)
|
||||
voodoo_t *voodoo = banshee->voodoo;
|
||||
|
||||
if (addr == voodoo->last_write_addr+4)
|
||||
sub_cycles(voodoo->burst_time);
|
||||
cycles -= voodoo->burst_time;
|
||||
else
|
||||
sub_cycles(voodoo->write_time);
|
||||
cycles -= voodoo->write_time;
|
||||
voodoo->last_write_addr = addr;
|
||||
|
||||
// banshee_log("banshee_reg_writel: addr=%08x val=%08x\n", addr, val);
|
||||
@@ -1346,7 +1351,7 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p)
|
||||
voodoo_t *voodoo = banshee->voodoo;
|
||||
svga_t *svga = &banshee->svga;
|
||||
|
||||
sub_cycles(voodoo->read_time);
|
||||
cycles -= voodoo->read_time;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= voodoo->tile_base)
|
||||
@@ -1364,7 +1369,7 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p)
|
||||
return 0xff;
|
||||
|
||||
egareads++;
|
||||
sub_cycles(video_timing_read_b);
|
||||
cycles -= video_timing_read_b;
|
||||
|
||||
// banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
|
||||
|
||||
@@ -1377,8 +1382,10 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p)
|
||||
voodoo_t *voodoo = banshee->voodoo;
|
||||
svga_t *svga = &banshee->svga;
|
||||
|
||||
sub_cycles(voodoo->read_time);
|
||||
|
||||
if (addr & 1)
|
||||
return banshee_read_linear(addr, p) | (banshee_read_linear(addr+1, p) << 8);
|
||||
|
||||
cycles -= voodoo->read_time;
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= voodoo->tile_base)
|
||||
{
|
||||
@@ -1395,7 +1402,7 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p)
|
||||
return 0xff;
|
||||
|
||||
egareads++;
|
||||
sub_cycles(video_timing_read_w);
|
||||
cycles -= video_timing_read_w;
|
||||
|
||||
// banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
|
||||
|
||||
@@ -1408,7 +1415,10 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p)
|
||||
voodoo_t *voodoo = banshee->voodoo;
|
||||
svga_t *svga = &banshee->svga;
|
||||
|
||||
sub_cycles(voodoo->read_time);
|
||||
if (addr & 3)
|
||||
return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr+2, p) << 16);
|
||||
|
||||
cycles -= voodoo->read_time;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= voodoo->tile_base)
|
||||
@@ -1426,7 +1436,7 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p)
|
||||
return 0xff;
|
||||
|
||||
egareads++;
|
||||
sub_cycles(video_timing_read_l);
|
||||
cycles -= video_timing_read_l;
|
||||
|
||||
// banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
|
||||
|
||||
@@ -1439,7 +1449,7 @@ static void banshee_write_linear(uint32_t addr, uint8_t val, void *p)
|
||||
voodoo_t *voodoo = banshee->voodoo;
|
||||
svga_t *svga = &banshee->svga;
|
||||
|
||||
sub_cycles(voodoo->write_time);
|
||||
cycles -= voodoo->write_time;
|
||||
|
||||
// banshee_log("write_linear: addr=%08x val=%02x\n", addr, val);
|
||||
addr &= svga->decode_mask;
|
||||
@@ -1459,7 +1469,7 @@ static void banshee_write_linear(uint32_t addr, uint8_t val, void *p)
|
||||
|
||||
egawrites++;
|
||||
|
||||
sub_cycles(video_timing_write_b);
|
||||
cycles -= video_timing_write_b;
|
||||
|
||||
svga->changedvram[addr >> 12] = changeframecount;
|
||||
svga->vram[addr & svga->vram_mask] = val;
|
||||
@@ -1471,8 +1481,14 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p)
|
||||
voodoo_t *voodoo = banshee->voodoo;
|
||||
svga_t *svga = &banshee->svga;
|
||||
|
||||
sub_cycles(voodoo->write_time);
|
||||
|
||||
if (addr & 1)
|
||||
{
|
||||
banshee_write_linear(addr, val, p);
|
||||
banshee_write_linear(addr + 1, val >> 8, p);
|
||||
return;
|
||||
}
|
||||
|
||||
cycles -= voodoo->write_time;
|
||||
// banshee_log("write_linear: addr=%08x val=%02x\n", addr, val);
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= voodoo->tile_base)
|
||||
@@ -1491,7 +1507,7 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p)
|
||||
|
||||
egawrites++;
|
||||
|
||||
sub_cycles(video_timing_write_w);
|
||||
cycles -= video_timing_write_w;
|
||||
|
||||
svga->changedvram[addr >> 12] = changeframecount;
|
||||
*(uint16_t *)&svga->vram[addr & svga->vram_mask] = val;
|
||||
@@ -1504,11 +1520,18 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p)
|
||||
svga_t *svga = &banshee->svga;
|
||||
int timing;
|
||||
|
||||
if (addr & 3)
|
||||
{
|
||||
banshee_write_linear_w(addr, val, p);
|
||||
banshee_write_linear_w(addr + 2, val >> 16, p);
|
||||
return;
|
||||
}
|
||||
|
||||
if (addr == voodoo->last_write_addr+4)
|
||||
timing = voodoo->burst_time;
|
||||
else
|
||||
timing = voodoo->write_time;
|
||||
sub_cycles(timing);
|
||||
cycles -= timing;
|
||||
voodoo->last_write_addr = addr;
|
||||
|
||||
// /*if (val) */banshee_log("write_linear_l: addr=%08x val=%08x %08x\n", addr, val, voodoo->tile_base);
|
||||
@@ -1530,7 +1553,7 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p)
|
||||
|
||||
egawrites += 4;
|
||||
|
||||
sub_cycles(video_timing_write_l);
|
||||
cycles -= video_timing_write_l;
|
||||
|
||||
svga->changedvram[addr >> 12] = changeframecount;
|
||||
*(uint32_t *)&svga->vram[addr & svga->vram_mask] = val;
|
||||
@@ -1670,7 +1693,12 @@ void banshee_hwcursor_draw(svga_t *svga, int displine)
|
||||
int g = (data >> 5) & 0x3f; \
|
||||
int b = data >> 11; \
|
||||
\
|
||||
buf[wp++] = (r << 3) | (g << 10) | (b << 19); \
|
||||
if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \
|
||||
buf[wp++] = (r << 3) | (g << 10) | (b << 19); \
|
||||
else \
|
||||
buf[wp++] = (clut[r << 3] & 0x0000ff) | \
|
||||
(clut[g << 2] & 0x00ff00) | \
|
||||
(clut[b << 3] & 0xff0000); \
|
||||
src += 2; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -1680,7 +1708,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine)
|
||||
{ \
|
||||
int c; \
|
||||
int wp = 0; \
|
||||
uint32_t base_addr = buf ? src_addr2 : src_addr; \
|
||||
uint32_t base_addr = (buf == banshee->overlay_buffer[1]) ? src_addr2 : src_addr; \
|
||||
\
|
||||
for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \
|
||||
{ \
|
||||
@@ -1689,7 +1717,12 @@ void banshee_hwcursor_draw(svga_t *svga, int displine)
|
||||
int g = (data >> 5) & 0x3f; \
|
||||
int b = data >> 11; \
|
||||
\
|
||||
buf[wp++] = (r << 3) | (g << 10) | (b << 19); \
|
||||
if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \
|
||||
buf[wp++] = (r << 3) | (g << 10) | (b << 19); \
|
||||
else \
|
||||
buf[wp++] = (clut[r << 3] & 0x0000ff) | \
|
||||
(clut[g << 2] & 0x00ff00) | \
|
||||
(clut[b << 3] & 0xff0000); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -1957,6 +1990,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine)
|
||||
uint32_t src_x = 0;
|
||||
unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4;
|
||||
int skip_filtering;
|
||||
uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0];
|
||||
|
||||
if (svga->render == svga_render_null &&
|
||||
!svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] &&
|
||||
@@ -2323,11 +2357,11 @@ static uint8_t banshee_pci_read(int func, int addr, void *p)
|
||||
case 0x1a: ret = 0x00; break;
|
||||
case 0x1b: ret = 0x00; break;
|
||||
|
||||
/*Undocumented, but Voodoo 3 BIOS checks this*/
|
||||
case 0x2c: ret = 0x1a; break;
|
||||
case 0x2d: ret = 0x12; break;
|
||||
case 0x2e: ret = (banshee->type == TYPE_V3_3000) ? 0x3a : 0x30; break;
|
||||
case 0x2f: ret = 0x00; break;
|
||||
/*Subsystem vendor ID*/
|
||||
case 0x2c: ret = banshee->pci_regs[0x2c]; break;
|
||||
case 0x2d: ret = banshee->pci_regs[0x2d]; break;
|
||||
case 0x2e: ret = banshee->pci_regs[0x2e]; break;
|
||||
case 0x2f: ret = banshee->pci_regs[0x2f]; break;
|
||||
|
||||
case 0x30: ret = banshee->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/
|
||||
case 0x31: ret = 0x00; break;
|
||||
@@ -2633,6 +2667,37 @@ static void *banshee_init_common(const device_t *info, wchar_t *fn, int has_sgra
|
||||
banshee->i2c_ddc = i2c_gpio_init("ddc_voodoo_banshee");
|
||||
banshee->ddc = ddc_init(i2c_gpio_get_bus(banshee->i2c_ddc));
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_BANSHEE:
|
||||
if (has_sgram) {
|
||||
banshee->pci_regs[0x2c] = 0x1a;
|
||||
banshee->pci_regs[0x2d] = 0x12;
|
||||
banshee->pci_regs[0x2e] = 0x04;
|
||||
banshee->pci_regs[0x2f] = 0x00;
|
||||
} else {
|
||||
banshee->pci_regs[0x2c] = 0x02;
|
||||
banshee->pci_regs[0x2d] = 0x11;
|
||||
banshee->pci_regs[0x2e] = 0x17;
|
||||
banshee->pci_regs[0x2f] = 0x10;
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_V3_2000:
|
||||
banshee->pci_regs[0x2c] = 0x1a;
|
||||
banshee->pci_regs[0x2d] = 0x12;
|
||||
banshee->pci_regs[0x2e] = 0x30;
|
||||
banshee->pci_regs[0x2f] = 0x00;
|
||||
break;
|
||||
|
||||
case TYPE_V3_3000:
|
||||
banshee->pci_regs[0x2c] = 0x1a;
|
||||
banshee->pci_regs[0x2d] = 0x12;
|
||||
banshee->pci_regs[0x2e] = 0x3a;
|
||||
banshee->pci_regs[0x2f] = 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_banshee);
|
||||
|
||||
return banshee;
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#define COMMAND_INITIATE (1 << 8)
|
||||
#define COMMAND_INC_X_START (1 << 10)
|
||||
#define COMMAND_INC_Y_START (1 << 11)
|
||||
#define COMMAND_STIPPLE_LINE (1 << 12)
|
||||
#define COMMAND_PATTERN_MONO (1 << 13)
|
||||
#define COMMAND_DX (1 << 14)
|
||||
#define COMMAND_DY (1 << 15)
|
||||
@@ -246,6 +247,50 @@ static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t p
|
||||
}
|
||||
}
|
||||
|
||||
static void PLOT_LINE(voodoo_t *voodoo, int x, int y, uint8_t rop, uint32_t pattern, int src_colorkey)
|
||||
{
|
||||
switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK)
|
||||
{
|
||||
case DST_FORMAT_COL_8_BPP:
|
||||
{
|
||||
uint32_t addr = get_addr(voodoo, x, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t dest = voodoo->vram[addr];
|
||||
|
||||
voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_8);
|
||||
voodoo->changedvram[addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
case DST_FORMAT_COL_16_BPP:
|
||||
{
|
||||
uint32_t addr = get_addr(voodoo, x*2, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t dest = *(uint16_t *)&voodoo->vram[addr];
|
||||
|
||||
*(uint16_t *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_16);
|
||||
voodoo->changedvram[addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
case DST_FORMAT_COL_24_BPP:
|
||||
{
|
||||
uint32_t addr = get_addr(voodoo, x*3, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t dest = *(uint32_t *)&voodoo->vram[addr];
|
||||
|
||||
*(uint32_t *)&voodoo->vram[addr] = (MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000);
|
||||
voodoo->changedvram[addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
case DST_FORMAT_COL_32_BPP:
|
||||
{
|
||||
uint32_t addr = get_addr(voodoo, x*4, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t dest = *(uint32_t *)&voodoo->vram[addr];
|
||||
|
||||
*(uint32_t *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32);
|
||||
voodoo->changedvram[addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void update_src_stride(voodoo_t *voodoo)
|
||||
{
|
||||
int bpp;
|
||||
@@ -858,14 +903,24 @@ static void banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, u
|
||||
}
|
||||
}
|
||||
|
||||
static void banshee_do_line(voodoo_t *voodoo)
|
||||
static void step_line(voodoo_t *voodoo)
|
||||
{
|
||||
if (voodoo->banshee_blt.line_pix_pos == voodoo->banshee_blt.line_rep_cnt)
|
||||
{
|
||||
voodoo->banshee_blt.line_pix_pos = 0;
|
||||
if (voodoo->banshee_blt.line_bit_pos == voodoo->banshee_blt.line_bit_mask_size)
|
||||
voodoo->banshee_blt.line_bit_pos = 0;
|
||||
else
|
||||
voodoo->banshee_blt.line_bit_pos++;
|
||||
}
|
||||
else
|
||||
voodoo->banshee_blt.line_pix_pos++;
|
||||
}
|
||||
|
||||
|
||||
static void banshee_do_line(voodoo_t *voodoo, int draw_last_pixel)
|
||||
{
|
||||
clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
|
||||
uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern;
|
||||
int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.srcY);
|
||||
int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.srcX;
|
||||
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) ==
|
||||
(COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
|
||||
uint8_t rop = voodoo->banshee_blt.command >> 24;
|
||||
int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX);
|
||||
int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY);
|
||||
@@ -874,27 +929,28 @@ static void banshee_do_line(voodoo_t *voodoo)
|
||||
int x = voodoo->banshee_blt.srcX;
|
||||
int y = voodoo->banshee_blt.srcY;
|
||||
int error;
|
||||
uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ?
|
||||
voodoo->banshee_blt.lineStipple : ~0;
|
||||
|
||||
if (dx > dy) /*X major*/
|
||||
{
|
||||
error = dx/2;
|
||||
while (x != voodoo->banshee_blt.dstX)
|
||||
{
|
||||
uint8_t pattern_mask = pattern_mono[pat_y & 7];
|
||||
int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1;
|
||||
int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos);
|
||||
int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1;
|
||||
|
||||
if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans)
|
||||
PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32);
|
||||
PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32);
|
||||
|
||||
error -= dy;
|
||||
if (error < 0)
|
||||
{
|
||||
error += dx;
|
||||
y += y_inc;
|
||||
pat_y += y_inc;
|
||||
}
|
||||
x += x_inc;
|
||||
pat_x += x_inc;
|
||||
step_line(voodoo);
|
||||
}
|
||||
}
|
||||
else /*Y major*/
|
||||
@@ -902,24 +958,32 @@ static void banshee_do_line(voodoo_t *voodoo)
|
||||
error = dy/2;
|
||||
while (y != voodoo->banshee_blt.dstY)
|
||||
{
|
||||
uint8_t pattern_mask = pattern_mono[pat_y & 7];
|
||||
int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1;
|
||||
int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos);
|
||||
int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1;
|
||||
|
||||
if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans)
|
||||
PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32);
|
||||
PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32);
|
||||
|
||||
error -= dx;
|
||||
if (error < 0)
|
||||
{
|
||||
error += dy;
|
||||
x += x_inc;
|
||||
pat_x += x_inc;
|
||||
}
|
||||
y += y_inc;
|
||||
pat_y += y_inc;
|
||||
step_line(voodoo);
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_last_pixel)
|
||||
{
|
||||
int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos);
|
||||
int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1;
|
||||
|
||||
if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans)
|
||||
PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32);
|
||||
}
|
||||
|
||||
voodoo->banshee_blt.srcXY = (x & 0xffff) | (y << 16);
|
||||
voodoo->banshee_blt.srcX = x;
|
||||
voodoo->banshee_blt.srcY = y;
|
||||
@@ -1057,8 +1121,12 @@ static void banshee_do_2d_blit(voodoo_t *voodoo, int count, uint32_t data)
|
||||
banshee_do_rectfill(voodoo);
|
||||
break;
|
||||
|
||||
case COMMAND_CMD_LINE:
|
||||
banshee_do_line(voodoo, 1);
|
||||
break;
|
||||
|
||||
case COMMAND_CMD_POLYLINE:
|
||||
banshee_do_line(voodoo);
|
||||
banshee_do_line(voodoo, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1141,6 +1209,16 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val)
|
||||
case 0x38:
|
||||
voodoo->banshee_blt.commandExtra = val;
|
||||
// bansheeblt_log("commandExtra=%08x\n", val);
|
||||
break;
|
||||
case 0x3c:
|
||||
voodoo->banshee_blt.lineStipple = val;
|
||||
break;
|
||||
case 0x40:
|
||||
voodoo->banshee_blt.lineStyle = val;
|
||||
voodoo->banshee_blt.line_rep_cnt = val & 0xff;
|
||||
voodoo->banshee_blt.line_bit_mask_size = (val >> 8) & 0x1f;
|
||||
voodoo->banshee_blt.line_pix_pos = (val >> 16) & 0xff;
|
||||
voodoo->banshee_blt.line_bit_pos = (val >> 24) & 0x1f;
|
||||
break;
|
||||
case 0x44:
|
||||
voodoo->banshee_blt.colorPattern[0] = val;
|
||||
@@ -1321,18 +1399,18 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val)
|
||||
banshee_do_rectfill(voodoo);
|
||||
break;
|
||||
|
||||
/* case COMMAND_CMD_LINE:
|
||||
case COMMAND_CMD_LINE:
|
||||
voodoo->banshee_blt.dstXY = val;
|
||||
voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19;
|
||||
voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19;
|
||||
banshee_do_line(voodoo);
|
||||
break;*/
|
||||
banshee_do_line(voodoo, 1);
|
||||
break;
|
||||
|
||||
case COMMAND_CMD_POLYLINE:
|
||||
voodoo->banshee_blt.dstXY = val;
|
||||
voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19;
|
||||
voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19;
|
||||
banshee_do_line(voodoo);
|
||||
banshee_do_line(voodoo, 0);
|
||||
break;
|
||||
|
||||
case COMMAND_CMD_POLYFILL:
|
||||
|
||||
@@ -155,16 +155,19 @@ void voodoo_wait_for_swap_complete(voodoo_t *voodoo)
|
||||
static uint32_t cmdfifo_get(voodoo_t *voodoo)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr)
|
||||
{
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
}
|
||||
|
||||
if (!voodoo->cmdfifo_in_sub) {
|
||||
while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr)
|
||||
{
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
}
|
||||
}
|
||||
|
||||
val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask];
|
||||
|
||||
voodoo->cmdfifo_depth_rd++;
|
||||
if (!voodoo->cmdfifo_in_sub)
|
||||
voodoo->cmdfifo_depth_rd++;
|
||||
voodoo->cmdfifo_rp += 4;
|
||||
|
||||
// voodoo_fifo_log(" CMDFIFO get %08x\n", val);
|
||||
@@ -285,7 +288,7 @@ void voodoo_fifo_thread(void *param)
|
||||
voodoo->time += end_time - start_time;
|
||||
}
|
||||
|
||||
while (voodoo->cmdfifo_enabled && voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr)
|
||||
while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub))
|
||||
{
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
@@ -308,6 +311,18 @@ void voodoo_fifo_thread(void *param)
|
||||
case 0: /*NOP*/
|
||||
break;
|
||||
|
||||
case 1: /*JSR*/
|
||||
// voodoo_fifo_log("JSR %08x\n", (header >> 4) & 0xfffffc);
|
||||
voodoo->cmdfifo_ret_addr = voodoo->cmdfifo_rp;
|
||||
voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc;
|
||||
voodoo->cmdfifo_in_sub = 1;
|
||||
break;
|
||||
|
||||
case 2: /*RET*/
|
||||
voodoo->cmdfifo_rp = voodoo->cmdfifo_ret_addr;
|
||||
voodoo->cmdfifo_in_sub = 0;
|
||||
break;
|
||||
|
||||
case 3: /*JMP local frame buffer*/
|
||||
voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc;
|
||||
// voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header);
|
||||
|
||||
@@ -36,6 +36,24 @@
|
||||
#include <86box/vid_voodoo_render.h>
|
||||
#include <86box/vid_voodoo_setup.h>
|
||||
|
||||
#ifdef ENABLE_VOODOO_SETUP_LOG
|
||||
int voodoo_setup_do_log = ENABLE_VOODOO_SETUP_LOG;
|
||||
|
||||
static void
|
||||
voodoo_setup_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (voodoo_setup_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define voodoo_setup_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void voodoo_triangle_setup(voodoo_t *voodoo)
|
||||
{
|
||||
@@ -152,8 +170,10 @@ void voodoo_triangle_setup(voodoo_t *voodoo)
|
||||
voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(verts[vc].sVx * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff);
|
||||
|
||||
if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy)
|
||||
fatal("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy);
|
||||
if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) {
|
||||
voodoo_setup_log("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy);
|
||||
return;
|
||||
}
|
||||
|
||||
if (voodoo->sSetupMode & SETUPMODE_RGB)
|
||||
{
|
||||
|
||||
@@ -336,7 +336,7 @@ static png_infop info_ptr;
|
||||
|
||||
|
||||
static void
|
||||
video_take_screenshot(const wchar_t *fn, int startx, int starty, int w, int h)
|
||||
video_take_screenshot(const wchar_t *fn, int startx, int starty, int y1, int y2, int w, int h)
|
||||
{
|
||||
int i, x, y;
|
||||
png_bytep *b_rgb = NULL;
|
||||
@@ -382,7 +382,7 @@ video_take_screenshot(const wchar_t *fn, int startx, int starty, int w, int h)
|
||||
for (y = 0; y < h; ++y) {
|
||||
b_rgb[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr));
|
||||
for (x = 0; x < w; ++x) {
|
||||
temp = render_buffer->line[y + starty][x + startx];
|
||||
temp = render_buffer->dat[(y * w) + x];
|
||||
|
||||
b_rgb[y][(x) * 3 + 0] = (temp >> 16) & 0xff;
|
||||
b_rgb[y][(x) * 3 + 1] = (temp >> 8) & 0xff;
|
||||
@@ -407,7 +407,7 @@ video_take_screenshot(const wchar_t *fn, int startx, int starty, int w, int h)
|
||||
|
||||
|
||||
static void
|
||||
video_screenshot(int x, int y, int w, int h)
|
||||
video_screenshot(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
wchar_t path[1024], fn[128];
|
||||
|
||||
@@ -426,7 +426,7 @@ video_screenshot(int x, int y, int w, int h)
|
||||
|
||||
video_log("taking screenshot to: %S\n", path);
|
||||
|
||||
video_take_screenshot((const wchar_t *) path, x, y, w, h);
|
||||
video_take_screenshot((const wchar_t *) path, x, y, y1, y2, w, h);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
}
|
||||
|
||||
@@ -449,20 +449,20 @@ video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
int yy;
|
||||
|
||||
if ((w > 0) && (h > 0)) {
|
||||
for (yy = 0; yy < h; yy++) {
|
||||
if (y2 > 0) {
|
||||
for (yy = y1; yy < y2; yy++) {
|
||||
if (((y + yy) >= 0) && ((y + yy) < buffer32->h)) {
|
||||
if (video_grayscale || invert_display)
|
||||
video_transform_copy(&(render_buffer->line[y + yy][x]), &(buffer32->line[y + yy][x]), w);
|
||||
video_transform_copy(&(render_buffer->dat)[yy * w], &(buffer32->line[y + yy][x]), w);
|
||||
else
|
||||
memcpy(&(render_buffer->line[y + yy][x]), &(buffer32->line[y + yy][x]), w << 2);
|
||||
memcpy(&(render_buffer->dat)[yy * w], &(buffer32->line[y + yy][x]), w << 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screenshots) {
|
||||
if (render_buffer != NULL)
|
||||
video_screenshot(x, y, w, h);
|
||||
video_screenshot(x, y, y1, y2, w, h);
|
||||
screenshots--;
|
||||
video_log("screenshot taken, %i left\n", screenshots);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user