BitBLT work

This commit is contained in:
Cacodemon345
2024-01-31 16:34:34 +06:00
parent 2b0a494ede
commit a9b3fdd945

View File

@@ -36,10 +36,55 @@
#include <86box/vid_ddc.h> #include <86box/vid_ddc.h>
#include <assert.h> #include <assert.h>
#pragma pack(push, 1)
typedef struct chips_69000_bitblt_t
{
/* BR00 - Source and Destination Span Register. */
uint16_t source_span;
uint16_t destination_span;
/* BR01 - Pattern/Source Expansion Background Color & Transparency Key Register. */
uint32_t pattern_source_key_bg;
/* BR02 - Pattern/Source Expansion Foreground Color Register. */
uint32_t pattern_source_key_fg;
/* BR03 - Monochrome Source Control Register. */
uint8_t monochrome_source_left_clip;
uint8_t monochrome_source_right_clip;
uint8_t monochrome_source_initial_discard;
uint8_t monochrome_source_alignment : 3;
uint8_t monochrome_source_expansion_color_reg_select : 1;
uint8_t dummy_8 : 4;
/* BR04 - BitBLT Control Register. */
uint32_t bitblt_control;
/* BR05 - Pattern Address Register. */
uint32_t pat_addr;
/* BR06 - Source Address Register. */
uint32_t source_addr;
/* BR07 - Destination Address Register. */
uint32_t destination_addr;
/* BR08 - Destination Width & Height Register. */
uint16_t destination_width;
uint16_t destination_height;
/* BR09 - Source Expansion Background Color & Transparency Key Register. */
uint32_t source_key_bg;
/* BR0A - Source Expansion Foreground Color Register. */
uint32_t source_key_fg;
};
#pragma pack(pop)
typedef struct chips_69000_t { typedef struct chips_69000_t {
svga_t svga; svga_t svga;
uint8_t pci_conf_status; uint8_t pci_conf_status;
uint8_t slot; uint8_t slot, irq_state;
uint8_t pci_line_interrupt; uint8_t pci_line_interrupt;
uint8_t pci_rom_enable; uint8_t pci_rom_enable;
uint8_t read_write_bank; uint8_t read_write_bank;
@@ -65,11 +110,21 @@ typedef struct chips_69000_t {
uint8_t mem_regs_b[4 * 4]; uint8_t mem_regs_b[4 * 4];
}; };
union { union {
uint32_t bitblt_regs[16]; uint32_t bitblt_regs[11];
uint16_t bitblt_regs_w[16 * 2]; uint16_t bitblt_regs_w[11 * 2];
uint8_t bitblt_regs_b[16 * 4]; uint8_t bitblt_regs_b[11 * 4];
struct chips_69000_bitblt_t bitblt;
}; };
struct
{
struct chips_69000_bitblt_t bitblt;
uint32_t actual_source_height;
uint32_t actual_destination_height;
uint8_t bytes_per_pixel;
} bitblt_running;
union { union {
uint16_t subsys_vid; uint16_t subsys_vid;
uint8_t subsys_vid_b[2]; uint8_t subsys_vid_b[2];
@@ -145,6 +200,20 @@ chips_69000_write_flat_panel(chips_69000_t* chips, uint8_t val)
chips->flat_panel_regs[chips->flat_panel_index] = val; chips->flat_panel_regs[chips->flat_panel_index] = val;
} }
void
chips_69000_interrupt(chips_69000_t* chips)
{
pci_irq(chips->slot, PCI_INTA, 0, !!((chips->mem_regs[0] & chips->mem_regs[1]) & 0x80004040), &chips->irq_state);
}
void
chips_69000_bitblt_interrupt(chips_69000_t* chips)
{
chips->mem_regs[1] |= 1 << 31;
chips_69000_interrupt(chips);
}
void void
chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop)
{ {
@@ -199,63 +268,6 @@ chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop)
} }
} }
void
chips_69000_do_rop_15bpp(uint16_t *dst, uint16_t src, uint8_t rop)
{
uint16_t orig_dst = *dst & 0x8000;
switch (rop) {
case 0x00:
*dst = 0;
break;
case 0x11:
*dst = ~(*dst) & ~src;
break;
case 0x22:
*dst &= ~src;
break;
case 0x33:
*dst = ~src;
break;
case 0x44:
*dst = src & ~(*dst);
break;
case 0x55:
*dst = ~*dst;
break;
case 0x66:
*dst ^= src;
break;
case 0x77:
*dst = ~src | ~(*dst);
break;
case 0x88:
*dst &= src;
break;
case 0x99:
*dst ^= ~src;
break;
case 0xAA:
break; /* No-op. */
case 0xBB:
*dst |= ~src;
break;
case 0xCC:
*dst = src;
break;
case 0xDD:
*dst = src | ~(*dst);
break;
case 0xEE:
*dst |= src;
break;
case 0xFF:
*dst = ~0;
break;
}
*dst &= 0x7FFF;
*dst |= orig_dst;
}
void void
chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop)
{ {
@@ -424,66 +436,6 @@ chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t src, uint8_t nonpattern_
} }
} }
void
chips_69000_do_rop_15bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop)
{
uint16_t orig_dst = *dst & 0x8000;
switch (rop) {
case 0x00:
*dst = 0;
break;
case 0x05:
*dst = ~(*dst) & ~src;
break;
case 0x0A:
*dst &= ~src;
break;
case 0x0F:
*dst = ~src;
break;
case 0x50:
*dst = src & ~(*dst);
break;
case 0x55:
*dst = ~*dst;
break;
case 0x5A:
*dst ^= src;
break;
case 0x5F:
*dst = ~src | ~(*dst);
break;
case 0xB8:
*dst = (((src ^ *dst) & nonpattern_src) ^ src);
break;
case 0xA0:
*dst &= src;
break;
case 0xA5:
*dst ^= ~src;
break;
case 0xAA:
break; /* No-op. */
case 0xAF:
*dst |= ~src;
break;
case 0xF0:
*dst = src;
break;
case 0xF5:
*dst = src | ~(*dst);
break;
case 0xFA:
*dst |= src;
break;
case 0xFF:
*dst = 0xFF;
break;
}
*dst &= 0x7FFF;
*dst |= orig_dst;
}
void void
chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop) chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t src, uint8_t nonpattern_src, uint8_t rop)
{ {
@@ -703,6 +655,24 @@ chips_69000_recalc_banking(chips_69000_t *chips)
}*/ }*/
} }
void
chips_69000_setup_bitblt(chips_69000_t* chips)
{
chips->engine_active = 1;
chips->bitblt_running.bitblt = chips->bitblt;
chips->bitblt_running.actual_source_height = chips->bitblt.destination_height;
chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height;
if (!chips->bitblt_running.actual_destination_height) {
chips->bitblt_running.actual_destination_height = 1;
}
/*Stubbed!*/
chips->engine_active = 0;
chips_69000_bitblt_interrupt(chips);
}
uint8_t uint8_t
chips_69000_read_ext_reg(chips_69000_t* chips) chips_69000_read_ext_reg(chips_69000_t* chips)
{ {
@@ -736,6 +706,11 @@ chips_69000_read_ext_reg(chips_69000_t* chips)
case 0x0A: case 0x0A:
val = chips->ext_regs[index] & 0x37; val = chips->ext_regs[index] & 0x37;
break; break;
case 0x20:
val &= ~1;
val |= !!(chips->bitblt.bitblt_control & (1 << 31));
/* TODO: Handle BitBLT reset, if required. */
break;
case 0x63: case 0x63:
{ {
val = chips->ext_regs[index]; val = chips->ext_regs[index];
@@ -983,7 +958,6 @@ chips_69000_in(uint16_t addr, void *p)
if (svga->adv_flags & FLAG_RAMDAC_SHIFT) if (svga->adv_flags & FLAG_RAMDAC_SHIFT)
temp >>= 2; temp >>= 2;
break; break;
#if 1
case 0x3D0: case 0x3D0:
return chips->flat_panel_index; return chips->flat_panel_index;
case 0x3D1: case 0x3D1:
@@ -992,7 +966,6 @@ chips_69000_in(uint16_t addr, void *p)
return chips->mm_index; return chips->mm_index;
case 0x3D3: case 0x3D3:
return chips_69000_read_multimedia(chips); return chips_69000_read_multimedia(chips);
#endif
case 0x3D4: case 0x3D4:
temp = svga->crtcreg; temp = svga->crtcreg;
break; break;
@@ -1146,6 +1119,7 @@ chips_69000_pci_write(int func, int addr, uint8_t val, void *p)
uint8_t uint8_t
chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips)
{ {
addr &= 0xFFF;
switch (addr & 0xFFF) { switch (addr & 0xFFF) {
case 0x00 ... 0x28: case 0x00 ... 0x28:
return chips->bitblt_regs_b[addr & 0xFF]; return chips->bitblt_regs_b[addr & 0xFF];
@@ -1208,6 +1182,7 @@ chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips)
uint16_t uint16_t
chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips) chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips)
{ {
addr &= 0xFFF;
switch (addr & 0xFFF) { switch (addr & 0xFFF) {
default: default:
return chips_69000_readb_mmio(addr, chips) | (chips_69000_readb_mmio(addr + 1, chips) << 8); return chips_69000_readb_mmio(addr, chips) | (chips_69000_readb_mmio(addr + 1, chips) << 8);
@@ -1218,6 +1193,7 @@ chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips)
uint32_t uint32_t
chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips)
{ {
addr &= 0xFFF;
switch (addr & 0xFFF) { switch (addr & 0xFFF) {
default: default:
return chips_69000_readw_mmio(addr, chips) | (chips_69000_readw_mmio(addr + 2, chips) << 16); return chips_69000_readw_mmio(addr, chips) | (chips_69000_readw_mmio(addr + 2, chips) << 16);
@@ -1228,13 +1204,44 @@ chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips)
void void
chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips)
{ {
addr &= 0xFFF;
switch (addr & 0xFFF) { switch (addr & 0xFFF) {
case 0x00 ... 0x28: case 0x00 ... 0x28:
chips->bitblt_regs_b[addr & 0xFF] = val; chips->bitblt_regs_b[addr & 0xFF] = val;
if ((addr & 0xFFF) == 0x023) if ((addr & 0xFFF) == 0x023) {
pclog("BitBLT/Draw operation\n"); uint8_t cntr = 0;
pclog("BitBLT/Draw operation %hd\n", (uint8_t)cntr++);
chips_69000_setup_bitblt(chips);
}
break; break;
case 0x600 ... 0x60F: case 0x600 ... 0x60F:
switch (addr & 0xFFF)
{
case 0x600 ... 0x603:
{
chips->mem_regs_b[addr & 0xF] = val;
chips->mem_regs[addr >> 2] &= 0x80004040;
if (addr == 0x605 || addr == 0x607)
chips_69000_interrupt(chips);
break;
}
case 0x604 ... 0x607:
{
chips->mem_regs_b[addr & 0xF] &= ~val;
chips->mem_regs[addr >> 2] &= 0x80004040;
if (addr == 0x605 || addr == 0x607)
chips_69000_interrupt(chips);
break;
}
case 0x60c ... 0x60f:
{
chips->mem_regs_b[addr & 0xF] = val;
break;
}
}
chips->mem_regs_b[addr & 0xF] = val; chips->mem_regs_b[addr & 0xF] = val;
break; break;
case 0x768: case 0x768:
@@ -1293,6 +1300,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips)
void void
chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips)
{ {
addr &= 0xFFF;
switch (addr & 0xFFF) { switch (addr & 0xFFF) {
default: default:
chips_69000_writeb_mmio(addr, val, chips); chips_69000_writeb_mmio(addr, val, chips);
@@ -1304,6 +1312,7 @@ chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips)
void void
chips_69000_writel_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) chips_69000_writel_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips)
{ {
addr &= 0xFFF;
switch (addr & 0xFFF) { switch (addr & 0xFFF) {
default: default:
chips_69000_writew_mmio(addr, val, chips); chips_69000_writew_mmio(addr, val, chips);
@@ -1384,19 +1393,13 @@ chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p)
svga_writel_linear(addr & 0x1FFFFF, val, p); svga_writel_linear(addr & 0x1FFFFF, val, p);
} }
void
chips_69000_vsync_start(svga_t *svga)
{
/* TODO: PCI interrupts for this. */
chips_69000_t *chips = (chips_69000_t *) svga->priv;
}
void void
chips_69000_vblank_start(svga_t *svga) chips_69000_vblank_start(svga_t *svga)
{ {
chips_69000_t *chips = (chips_69000_t *) svga->priv; chips_69000_t *chips = (chips_69000_t *) svga->priv;
/* Needed? */ chips->mem_regs[1] |= 1 << 14;
chips_69000_interrupt(chips);
} }
static void * static void *
@@ -1425,7 +1428,6 @@ chips_69000_init(const device_t *info)
chips->svga.bpp = 8; chips->svga.bpp = 8;
chips->svga.miscout = 1; chips->svga.miscout = 1;
chips->svga.recalctimings_ex = chips_69000_recalctimings; chips->svga.recalctimings_ex = chips_69000_recalctimings;
chips->svga.vsync_callback = chips_69000_vsync_start;
chips->svga.vblank_start = chips_69000_vblank_start; chips->svga.vblank_start = chips_69000_vblank_start;
mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips);
@@ -1444,7 +1446,7 @@ chips_69000_init(const device_t *info)
chips->flat_panel_regs[0x01] = 1; chips->flat_panel_regs[0x01] = 1;
sizeof(chips->bitblt_regs); sizeof(struct chips_69000_bitblt_t);
return chips; return chips;
} }