atimach64gx: Implement hardware cursor.

This commit is contained in:
joevt 2024-02-28 15:51:56 -08:00 committed by dingusdev
parent 81f3b95914
commit fe21108f08
2 changed files with 80 additions and 0 deletions

View File

@ -668,6 +668,81 @@ void AtiMach64Gx::crtc_update()
this->crtc_on = true;
}
void AtiMach64Gx::draw_hw_cursor(uint8_t *dst_buf, int dst_pitch) {
uint8_t *src_buf, *src_row, *dst_row, px4;
int vert_offset = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_OFF], ATI_CUR_VERT_OFF, ATI_CUR_VERT_OFF_size);
//int horz_offset = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_OFF], ATI_CUR_HORZ_OFF, ATI_CUR_HORZ_OFF_size);
src_buf = &this->vram_ptr[this->regs[ATI_CUR_OFFSET] * 8];
int cur_height = 64 - vert_offset;
uint32_t color0 = this->regs[ATI_CUR_CLR0] | 0x000000FFUL;
uint32_t color1 = this->regs[ATI_CUR_CLR1] | 0x000000FFUL;
for (int h = 0; h < cur_height; h++) {
dst_row = &dst_buf[h * dst_pitch];
src_row = &src_buf[h * 16];
for (int x = 0; x < 16; x++) {
px4 = src_row[x];
for (int p = 0; p < 4; p++, px4 >>= 2, dst_row += 4) {
switch(px4 & 3) {
case 0: // cursor color 0
WRITE_DWORD_BE_A(dst_row, color0);
break;
case 1: // cursor color 1
WRITE_DWORD_BE_A(dst_row, color1);
break;
case 2: // transparent
WRITE_DWORD_BE_A(dst_row, 0);
break;
case 3: // 1's complement of display pixel
break;
}
}
}
}
}
void AtiMach64Gx::get_cursor_position(int& x, int& y) {
x = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_POSN], ATI_CUR_HORZ_POSN, ATI_CUR_HORZ_POSN_size);
y = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_POSN], ATI_CUR_VERT_POSN, ATI_CUR_VERT_POSN_size);
}
int AtiMach64Gx::device_postinit()
{
this->vbl_cb = [this](uint8_t irq_line_state) {
insert_bits<uint32_t>(this->regs[ATI_CRTC_INT_CNTL], irq_line_state, ATI_CRTC_VBLANK, 1);
if (irq_line_state) {
set_bit(this->regs[ATI_CRTC_INT_CNTL], ATI_CRTC_VBLANK_INT);
set_bit(this->regs[ATI_CRTC_INT_CNTL], ATI_CRTC_VLINE_INT);
#if 1
#else
set_bit(this->regs[ATI_CRTC_GEN_CNTL], ATI_CRTC_VSYNC_INT);
#endif
}
bool do_interrupt =
bit_set(this->regs[ATI_CRTC_INT_CNTL], ATI_CRTC_VBLANK_INT_EN) ||
bit_set(this->regs[ATI_CRTC_INT_CNTL], ATI_CRTC_VLINE_INT_EN) ||
#if 1
#else
bit_set(this->regs[ATI_CRTC_GEN_CNTL], ATI_CRTC_VSYNC_INT_EN) ||
#endif
0;
LOG_F(WARNING, "%s: irq_line_state:%d do_interrupt:%d CRTC_INT_CNTL:%08x", this->name.c_str(), irq_line_state, do_interrupt, this->regs[ATI_CRTC_INT_CNTL]);
if (do_interrupt) {
this->pci_interrupt(irq_line_state);
}
};
return 0;
}
// ========================== IBM RGB514 related code ==========================
void AtiMach64Gx::rgb514_write_reg(uint8_t reg_addr, uint8_t value)
{

View File

@ -49,6 +49,9 @@ public:
bool pci_io_read(uint32_t offset, uint32_t size, uint32_t* res);
bool pci_io_write(uint32_t offset, uint32_t value, uint32_t size);
// HWComponent methods
int device_postinit();
// MMIODevice methods
uint32_t read(uint32_t rgn_start, uint32_t offset, int size);
void write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size);
@ -64,6 +67,8 @@ protected:
void rgb514_write_reg(uint8_t reg_addr, uint8_t value);
void rgb514_write_ind_reg(uint8_t reg_addr, uint8_t value);
void verbose_pixel_format(int crtc_index);
void draw_hw_cursor(uint8_t *dst_buf, int dst_pitch);
void get_cursor_position(int& x, int& y);
private:
void change_one_bar(uint32_t &aperture, uint32_t aperture_size, uint32_t aperture_new, int bar_num);