#define MEMDEBUGMASK 0x7fffff
#define MEMDEBUGTEST 0x3fc000
#define MEMDEBUGCLEAR 0
+#define SPCDEBUG 0
#define PICASSOIV_DEBUG_IO 0
#if MEMLOGR
uae_u8 er_type;
struct gfxboard_func *func;
device_t *pcemdev;
+ uae_u8 er_flags;
};
#define ISP4() (gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z2 || gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z3)
_T("CyberVision 64 Zorro III"), _T("Phase 5"), _T("CV64_Z3"),
8512, 34, 0,
0x00000000, 0x00200000, 0x00400000, 0x20000000, 0, 3, 2, false,
- 0, 0, NULL, &s3_cybervision_trio64_device
+ 0, 0, NULL, &s3_cybervision_trio64_device, 0x40
},
{
GFXBOARD_ID_CV643D_Z2,
_T("CyberVision 64/3D Zorro II"), _T("Phase 5"), _T("CV643D_Z2"),
8512, 67, 0,
0x00000000, 0x00400000, 0x00400000, 0x00400000, 0, 2, 2, false,
- 0, 0, NULL, &s3_virge_device
+ 0, 0, NULL, &s3_virge_device, 0xc0
},
{
GFXBOARD_ID_CV643D_Z3,
_T("CyberVision 64/3D Zorro III"), _T("Phase 5"), _T("CV643D_Z3"),
8512, 67, 0,
0x00000000, 0x00400000, 0x00400000, 0x10000000, 0, 3, 2, false,
- 0, 0, NULL, &s3_virge_device
+ 0, 0, NULL, &s3_virge_device, 0x40
},
{
GFXBOARD_ID_PICASSO2,
int bank;
uae_u8 z2_flags, z3_flags, type;
struct uae_prefs *p = aci->prefs;
+ uae_u8 flags = 0;
gfxboard_init (aci, gb);
}
}
if (gb->board->configtype == 3) {
- type = 0x80 | z3_flags | (gb->board->model_registers ? 0x08 : 0x00);
- ew (gb, 0x08, 0x10 | 0x20);
+ type = 0x80 | z3_flags;
+ flags |= 0x10 | 0x20;
} else {
- type = z2_flags | 0x08 | 0xc0;
+ type = z2_flags | 0xc0;
}
- ew (gb, 0x04, gb->board->model_memory);
- ew (gb, 0x10, gb->board->manufacturer >> 8);
- ew (gb, 0x14, gb->board->manufacturer);
+ type |= gb->board->model_registers ? 0x08 : 0x00;
+ flags |= gb->board->er_flags;
+
+ ew(gb, 0x04, gb->board->model_memory);
+ ew(gb, 0x10, gb->board->manufacturer >> 8);
+ ew(gb, 0x14, gb->board->manufacturer);
uae_u32 ser = gb->board->serial;
- ew (gb, 0x18, ser >> 24); /* ser.no. Byte 0 */
- ew (gb, 0x1c, ser >> 16); /* ser.no. Byte 1 */
- ew (gb, 0x20, ser >> 8); /* ser.no. Byte 2 */
- ew (gb, 0x24, ser >> 0); /* ser.no. Byte 3 */
+ ew(gb, 0x18, ser >> 24); /* ser.no. Byte 0 */
+ ew(gb, 0x1c, ser >> 16); /* ser.no. Byte 1 */
+ ew(gb, 0x20, ser >> 8); /* ser.no. Byte 2 */
+ ew(gb, 0x24, ser >> 0); /* ser.no. Byte 3 */
- ew (gb, 0x00, type);
+ ew(gb, 0x00, type);
+ ew(gb, 0x08, flags);
if (ISP4()) {
int roms[] = { 91, -1 };
struct rtggfxboard *gb = getgfxboard(addr);
int boardnum = gb->rbc->rtgmem_type;
+#if SPCDEBUG
// if ((addr & 0xfffff) != 0x40021)
-// write_log(_T("PCEM SPECIAL PUT %08x %08x %d\n"), addr, v, size);
+ write_log(_T("PCEM SPECIAL PUT %08x %08x %d PC=%08x\n"), addr, v, size, M68K_GETPC);
+#endif
if (boardnum == GFXBOARD_ID_CV643D_Z2) {
+
uaecptr addr2 = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
uaecptr addrd = addr2 + gb->gfxboardmem_start;
if (gb->pcem_pci_configured) {
if (addr2 >= 0x3c0000 && addr2 < 0x3d0000) {
addrd &= 0x3fff;
if (size == 1) {
- v = do_byteswap_16(v);
+ addrd ^= 2;
} else {
addrd ^= 3;
}
} else if (addr2 == 0x3a0000 + 8) {
// Z2 endian select
gb->pcem_data[1] = v;
- gb->pcem_vram_offset = (v & 0x40) ? 0 : 0x800000;
+ gb->pcem_vram_offset = (v & 0xc0) << 16;
return;
} else if (addr2 == 0x3a0000 + 0) {
if (size == 1) {
return;
}
}
- if (addr2 >= 0x3e8000 && addr2 < 0x3f0000) {
+ if (addr2 >= 0x3c8000 && addr2 < 0x3d0000) {
+ if (size == 0)
+ gfxboard_bput_mmio_pcem(addrd, v);
+ else if (size == 1)
+ gfxboard_wput_mmio_pcem(addrd, v);
+ else
+ gfxboard_lput_mmio_pcem(addrd, v);
+ } else if (addr2 >= 0x3e8000 && addr2 < 0x3f0000) {
if (size == 0)
gfxboard_bput_mmio_pcem(addrd, v);
else if (size == 1)
else
gfxboard_lput_mmio_pcem(addrd, v);
} else if (addr2 >= 0x3e0000 && addr2 < 0x3e8000) {
- int em = (gb->pcem_data[1] >> 7) & 1;
- switch (em)
- {
- case 0:
- if (size == 0)
- gfxboard_bput_mmio_pcem(addrd, v);
- else if (size == 1)
- gfxboard_wput_mmio_pcem(addrd, v);
- else
- gfxboard_lput_mmio_pcem(addrd, v);
- break;
- case 1:
- if (size == 0)
- gfxboard_bput_mmio_wbs_pcem(addrd, v);
- else if (size == 1)
- gfxboard_wput_mmio_wbs_pcem(addrd, v);
- else
- gfxboard_lput_mmio_wbs_pcem(addrd, v);
- break;
- }
+ if (size == 0)
+ gfxboard_bput_mmio_wbs_pcem(addrd, v);
+ else if (size == 1)
+ gfxboard_wput_mmio_wbs_pcem(addrd, v);
+ else
+ gfxboard_lput_mmio_wbs_pcem(addrd, v);
}
} else if (boardnum == GFXBOARD_ID_CV64_Z3) {
int boardnum = gb->rbc->rtgmem_type;
uae_u32 v = 0;
+#if SPCDEBUG
// if ((addr & 0xfffff) != 0x40021)
-// write_log(_T("PCEM SPECIAL GET %08x %d\n"), addr, size);
+ write_log(_T("PCEM SPECIAL GET %08x %d PC=%08x\n"), addr, size, M68K_GETPC);
+#endif
if (boardnum == GFXBOARD_ID_CV643D_Z2) {
uaecptr addr2 = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
addrd &= 0x3fff;
if (size == 0) {
addrd ^= 3;
+ } else if (size == 1) {
+ addrd ^= 2;
}
v = get_io_pcem(addrd, size);
- if (size == 1) {
- v = do_byteswap_16(v);
- }
}
} else {
if (addr2 >= 0x3c0000 && addr2 < 0x3c8000) {
v = gfxboard_lget_pci_pcem(addrd);
}
}
- if (addr2 >= 0x3e8000 && addr2 < 0x3f0000) {
+ if (addr2 >= 0x3c8000 && addr2 < 0x3d0000) {
+ if (size == 0)
+ v = gfxboard_bget_mmio_pcem(addrd);
+ else if (size == 1)
+ v = gfxboard_wget_mmio_pcem(addrd);
+ else
+ v = gfxboard_lget_mmio_pcem(addrd);
+ } else if (addr2 >= 0x3e8000 && addr2 < 0x3f0000) {
if (size == 0)
v = gfxboard_bget_mmio_pcem(addrd);
else if (size == 1)
else
v = gfxboard_lget_mmio_pcem(addrd);
} else if (addr2 >= 0x3e0000 && addr2 < 0x3e8000) {
- int em = (gb->pcem_data[1] >> 7) & 1;
- switch (em)
- {
- case 0:
- if (size == 0)
- v = gfxboard_bget_mmio_pcem(addrd);
- else if (size == 1)
- v = gfxboard_wget_mmio_pcem(addrd);
- else
- v = gfxboard_lget_mmio_pcem(addrd);
- break;
- case 1:
- if (size == 0)
- v = gfxboard_bget_mmio_wbs_pcem(addrd);
- else if (size == 1)
- v = gfxboard_wget_mmio_wbs_pcem(addrd);
- else
- v = gfxboard_lget_mmio_wbs_pcem(addrd);
- break;
- }
+ if (size == 0)
+ v = gfxboard_bget_mmio_wbs_pcem(addrd);
+ else if (size == 1)
+ v = gfxboard_wget_mmio_wbs_pcem(addrd);
+ else
+ v = gfxboard_lget_mmio_wbs_pcem(addrd);
}
} else if (boardnum == GFXBOARD_ID_CV64_Z3) {
static void ibm_gd5428_mapping_update(gd5429_t *gd5429);
-static int s3_vga_vsync_enabled(gd5429_t *gd5429)
+static int gd5429_interrupt_enabled(gd5429_t* gd5429)
{
- if (!(gd5429->svga.crtc[0x11] & 0x20) && (gd5429->svga.crtc[0x11] & 0x10) && (gd5429->type < PCI || (gd5429->svga.gdcreg[0x17] & 4)))
+ return !PCI || (gd5429->svga.gdcreg[0x17] & 4);
+}
+
+static int gd5429_vga_vsync_enabled(gd5429_t *gd5429)
+{
+ if (!(gd5429->svga.crtc[0x11] & 0x20) && (gd5429->svga.crtc[0x11] & 0x10) && gd5429_interrupt_enabled(gd5429))
return 1;
return 0;
}
static void gd5429_update_irqs(gd5429_t *gd5429)
{
- if (gd5429->vblank_irq > 0 && s3_vga_vsync_enabled(gd5429))
+ if (gd5429->vblank_irq > 0 && gd5429_vga_vsync_enabled(gd5429))
pci_set_irq(NULL, PCI_INTA);
else
pci_clear_irq(NULL, PCI_INTA);
static void gd5429_overlay_draw(svga_t *svga, int displine)
{
gd5429_t *gd5429 = (gd5429_t*)svga->p;
+ int shift = gd5429->type >= CL_TYPE_GD5446 ? 2 : 0;
int h_acc = svga->overlay_latch.h_acc;
int r[8], g[8], b[8], ck[8];
int x_read = 4, x_write = 4;
int x;
uint32_t *p;
- uint8_t *src = &svga->vram[svga->overlay_latch.addr & svga->vram_mask];
+ uint8_t *src = &svga->vram[(svga->overlay_latch.addr << shift) & svga->vram_mask];
int bpp = svga->bpp;
int bytesperpix = (bpp + 7) / 8;
uint8_t *src2 = &svga->vram[(svga->ma - (svga->hdisp * bytesperpix)) & svga->vram_display_mask];
if (svga->overlay_latch.v_acc >= 256)
{
svga->overlay_latch.v_acc -= 256;
- svga->overlay_latch.addr += svga->overlay.pitch;
+ svga->overlay_latch.addr += svga->overlay.pitch << 1;
}
}
case 0x3c:
svga->overlay.addr &= ~0x0f0000;
svga->overlay.addr |= (val << 16) & 0x0f0000;
- svga->overlay.pitch &= ~(1 << 11);
- svga->overlay.pitch |= ((val >> 5) & 1) << 11;
+ svga->overlay.pitch &= ~0x100;
+ svga->overlay.pitch |= (val & 0x20) << 3;
gd5429_update_overlay(gd5429);
break;
case 0x3d:
- svga->overlay.pitch &= ~(0xff << 3);
- svga->overlay.pitch |= val << 3;
+ svga->overlay.pitch &= ~0xff;
+ svga->overlay.pitch |= val;
gd5429_update_overlay(gd5429);
break;
case 0x3e:
}
count--;
}
- dst = svga->vram[gd5429->blt.dst_addr & svga->vram_mask];
- svga->changedvram[(gd5429->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount;
+ dst = svga->vram[(gd5429->blt.dst_addr + bplcnt) & svga->vram_mask];
+ svga->changedvram[((gd5429->blt.dst_addr + bplcnt) & svga->vram_mask) >> 12] = changeframecount;
//pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X\n", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst);
switch (gd5429->blt.rop)
uint64_t status_time;
uint8_t subsys_cntl, subsys_stat;
+ int vblank_irq;
uint32_t hwc_fg_col, hwc_bg_col;
int hwc_col_stack_pos;
static int s3_vga_vsync_enabled(s3_t *s3)
{
- if (!(s3->svga.crtc[0x11] & 0x20) && (s3->svga.crtc[0x11] & 0x10) && (s3->svga.crtc[0x32] & 0x10))
+ if ((s3->svga.crtc[0x32] & 0x10) && !(s3->svga.crtc[0x11] & 0x20) && s3->vblank_irq > 0)
return 1;
return 0;
}
static void s3_update_irqs(s3_t *s3)
{
int enabled = s3_vga_vsync_enabled(s3);
- if ((s3->subsys_cntl & s3->subsys_stat & INT_MASK) || (enabled && (s3->subsys_stat & INT_VSY)))
+ if (((s3->subsys_cntl & s3->subsys_stat & INT_MASK) && (s3->svga.crtc[0x32] & 0x10)) || (enabled && (s3->subsys_stat & INT_VSY)))
pci_set_irq(s3->card, PCI_INTA);
else
pci_clear_irq(s3->card, PCI_INTA);
}
}
+static void s3_update_irqs_thread(s3_t* s3, int mask)
+{
+ if ((s3->subsys_cntl & s3->subsys_stat & mask) && (s3->svga.crtc[0x32] & 0x10))
+ pci_set_irq(s3->card, PCI_INTA);
+}
+
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3);
#define WRITE8(addr, var, val) switch ((addr) & 3) \
}
s3->blitter_busy = 0;
s3->subsys_stat |= INT_FIFO_EMP;
- s3_update_irqs(s3);
+ s3_update_irqs_thread(s3, INT_FIFO_EMP);
}
s3->fifo_thread_state = 0;
}
static void s3_vblank_start(svga_t *svga)
{
s3_t *s3 = (s3_t *)svga->p;
+ if (s3->vblank_irq >= 0) {
+ s3->vblank_irq = 1;
+ }
if ((s3->subsys_cntl & INT_VSY) || s3_vga_vsync_enabled(s3)) {
s3->subsys_stat |= INT_VSY;
s3_update_irqs(s3);
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
- if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) return;
+ if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48)
+ return;
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
switch (svga->crtcreg)
{
case 0x11:
- if (!(val & 0x10))
- s3->subsys_stat &= ~INT_VSY;
+ if (!(val & 0x10)) {
+ if (s3->vblank_irq > 0)
+ s3->vblank_irq = -1;
+ } else if (s3->vblank_irq < 0) {
+ s3->vblank_irq = 0;
+ }
s3_update_irqs(s3);
if ((val & ~0x30) == (old & ~0x30))
old = val;
case 0x3c2:
ret = svga_in(addr, svga);
ret |= (s3->subsys_stat & INT_VSY) ? 0x80 : 0x00;
+ ret |= s3->vblank_irq > 0 ? 0x80 : 0x00;
return ret;
case 0x3c5:
#define INT_3DF_EMP (1 << 6)
#define INT_MASK 0xff
-static int is_interrupt_active(virge_t *virge)
+static int virge_vga_vsync_enabled(virge_t *virge)
{
- if ((virge->svga.crtc[0x32] & 0x10) && ((!(virge->svga.crtc[0x11] & 0x20) && virge->vblank_irq > 0) || (virge->subsys_stat & virge->subsys_cntl & INT_MASK)))
+ if ((virge->svga.crtc[0x32] & 0x10) && !(virge->svga.crtc[0x11] & 0x20) && virge->vblank_irq > 0)
return 1;
return 0;
}
static void s3_virge_update_irqs(virge_t *virge)
{
- if (is_interrupt_active(virge))
+ if (((virge->subsys_stat & virge->subsys_cntl & INT_MASK) && virge->svga.crtc[0x32] & 0x10) || virge_vga_vsync_enabled(virge))
pci_set_irq(virge->card, PCI_INTA);
else
pci_clear_irq(virge->card, PCI_INTA);
}
+static void s3_virge_update_irqs_thread(virge_t* virge, int mask)
+{
+ if ((virge->subsys_stat & virge->subsys_cntl & INT_MASK & mask) && virge->svga.crtc[0x32] & 0x10)
+ pci_set_irq(virge->card, PCI_INTA);
+}
+
+
static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
{
virge_t *virge = (virge_t *)p;
svga->crtcreg = val;// & 0x7f;
return;
case 0x3d5:
- //pclog("Write CRTC R%02X %02X %04x(%08x):%08x\n", svga->crtcreg, val, CS, cs, pc);
+ //pclog("Write CRTC R%02X %02X %04x(%08x):%08x\n", svga->crtcreg, val, CS, cs, 0);
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
- if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48)
+ if (svga->crtcreg >= 0x2d && svga->crtcreg <= 0x3f && svga->crtcreg != 0x38 && svga->crtcreg != 0x39 && (svga->crtc[0x38] & 0xcc) != 0x48)
+ return;
+ if (svga->crtcreg >= 0x40 && (svga->crtc[0x39] & 0xe0) != 0xa0)
+ return;
+ if ((svga->crtcreg == 0x36 || svga->crtcreg == 0x37 || svga->crtcreg == 0x68) && (svga->crtc[0x39] & 0xe5) != 0xa5)
return;
if (svga->crtcreg >= 0x80)
return;
}
virge->virge_busy = 0;
virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP;
- s3_virge_update_irqs(virge);
+ s3_virge_update_irqs_thread(virge, INT_FIFO_EMP | INT_3DF_EMP);
}
virge->fifo_thread_state = 0;
}
}
virge->s3d_busy = 0;
virge->subsys_stat |= INT_S3D_DONE;
- s3_virge_update_irqs(virge);
+ s3_virge_update_irqs_thread(virge, INT_S3D_DONE);
}
virge->render_thread_state = 0;
}