Browse Source

Sprite doubling and graphic acceleration stuff

Hardware sprite now scales with video output, courtesy of mntmn! Some fixes and changes to mouse cursor position when scaled, plus some graphics acceleration changes to make it easier to use.
tags/1.7.0-beta2
Bjorn Astrom 2 months ago
parent
commit
d61315e451
3 changed files with 60 additions and 60 deletions
  1. +8
    -28
      ZZ9000_proto.sdk/ZZ9000OS/src/gfx.c
  2. +32
    -28
      ZZ9000_proto.sdk/ZZ9000OS/src/main.c
  3. +20
    -4
      video_formatter.v

+ 8
- 28
ZZ9000_proto.sdk/ZZ9000OS/src/gfx.c View File

@@ -944,26 +944,22 @@ void template_fill_rect(uint32_t color_format, uint16_t rect_x1, uint16_t rect_y
}

// Generic graphics acceleration functionality
void acc_clear_buffer(uint32_t addr, uint16_t w, uint16_t h, uint16_t pitch_, uint32_t fg_color, uint32_t color_format)
void acc_clear_buffer(uint32_t addr, uint16_t w, uint16_t h, uint16_t pitch_, uint32_t fg_color, uint32_t color_format_)
{
if (!w || !h || !addr)
return;

uint16_t pitch = pitch_;
uint16_t pitch = pitch_ * color_format_;
uint8_t* dp = (uint8_t*)((uint32_t)addr);
uint8_t u8_fg = fg_color >> 24;

if (pitch == 0) {
switch (color_format) {
case MNTVA_COLOR_8BIT: pitch = w; break;
case MNTVA_COLOR_16BIT565: pitch = w * 2; break;
case MNTVA_COLOR_32BIT: pitch = w * 4; break;
default: return; break;
}
uint8_t color_format = 0;
if (color_format_ == 2) {
color_format = MNTVA_COLOR_16BIT565;
} else if (color_format == 4) {
color_format = MNTVA_COLOR_32BIT;
}

//printf("Clearing %dx%d pixels, %d bytes (%d).\n", w, h, h * pitch, pitch);

switch(color_format) {
case MNTVA_COLOR_8BIT:
memset(dp, u8_fg, h * pitch);
@@ -992,27 +988,11 @@ void acc_flip_to_fb(uint32_t src, uint32_t dest, uint16_t w, uint16_t h, uint16_
if (!w || !h || !src || !dest)
return;

uint16_t pitch = pitch_;
uint16_t pitch = pitch_ * color_format;
uint8_t* sp = (uint8_t*)((uint32_t)src);
uint8_t* dp = (uint8_t *)((uint32_t)dest);
//uint8_t* dp = (uint8_t*)((uint32_t)(framebuffer + framebuffer_pan_offset + 0x10000));

if (pitch == 0) {
switch (color_format) {
case MNTVA_COLOR_8BIT: pitch = w; break;
case MNTVA_COLOR_16BIT565: pitch = w * 2; break;
case MNTVA_COLOR_32BIT: pitch = w * 4; break;
default: return; break;
}
}

/*for (int i = 0; i < h; i++) {
memcpy(dp, sp, pitch);
sp += pitch;
dp += pitch;
}*/
memcpy (dp, sp, h * pitch);
//printf("Flipping %dx%d pixels, %d bytes (%d).\n", w, h, h * pitch, pitch);
}

void acc_blit_rect(uint32_t src, uint32_t dest, uint16_t dx, uint16_t dy, uint16_t w, uint16_t h, uint16_t src_pitch, uint16_t dest_pitch, uint8_t draw_mode, uint8_t mask_color)


+ 32
- 28
ZZ9000_proto.sdk/ZZ9000OS/src/main.c View File

@@ -70,6 +70,8 @@ int hdmi_ctrl_write_byte(u8 addr, u8 value) {
buffer[1] = value;
int status;

malloc(50);

while (XIicPs_BusIsBusy(&Iic)) {
};
usleep(I2C_PAUSE);
@@ -449,13 +451,13 @@ void pixelclock_init(int mhz) {
//XClk_Wiz_WriteReg(XPAR_CLK_WIZ_0_BASEADDR, 0x25C, 0x00000001);

phase = XClk_Wiz_ReadReg(XPAR_CLK_WIZ_0_BASEADDR, 0x20C);
printf("CLK phase: %lu\n", phase);
//printf("CLK phase: %lu\n", phase);
duty = XClk_Wiz_ReadReg(XPAR_CLK_WIZ_0_BASEADDR, 0x210);
printf("CLK duty: %lu\n", duty);
//printf("CLK duty: %lu\n", duty);
divide = XClk_Wiz_ReadReg(XPAR_CLK_WIZ_0_BASEADDR, 0x208);
printf("CLK divide: %lu\n", divide);
//printf("CLK divide: %lu\n", divide);
muldiv = XClk_Wiz_ReadReg(XPAR_CLK_WIZ_0_BASEADDR, 0x200);
printf("CLK muldiv: %lu\n", muldiv);
//printf("CLK muldiv: %lu\n", muldiv);
}

void pixelclock_init_2(struct zz_video_mode *mode) {
@@ -479,13 +481,13 @@ void pixelclock_init_2(struct zz_video_mode *mode) {
//XClk_Wiz_WriteReg(XPAR_CLK_WIZ_0_BASEADDR, 0x25C, 0x00000001);

phase = XClk_Wiz_ReadReg(XPAR_CLK_WIZ_0_BASEADDR, 0x20C);
printf("CLK phase: %lu\n", phase);
//printf("CLK phase: %lu\n", phase);
duty = XClk_Wiz_ReadReg(XPAR_CLK_WIZ_0_BASEADDR, 0x210);
printf("CLK duty: %lu\n", duty);
//printf("CLK duty: %lu\n", duty);
divide = XClk_Wiz_ReadReg(XPAR_CLK_WIZ_0_BASEADDR, 0x208);
printf("CLK divide: %lu\n", divide);
//printf("CLK divide: %lu\n", divide);
muldiv = XClk_Wiz_ReadReg(XPAR_CLK_WIZ_0_BASEADDR, 0x200);
printf("CLK muldiv: %lu\n", muldiv);
//printf("CLK muldiv: %lu\n", muldiv);
}

// FIXME!
@@ -564,19 +566,19 @@ void video_system_init(int hres, int vres, int htotal, int vtotal, int mhz,
printf("VSI: %d x %d [%d x %d] %d MHz %d Hz, hdiv: %d vdiv: %d\n", hres,
vres, htotal, vtotal, mhz, vhz, hdiv, vdiv);

printf("pixelclock_init()...\n");
//printf("pixelclock_init()...\n");
pixelclock_init(mhz);
printf("...done.\n");
//printf("...done.\n");

printf("hdmi_set_video_mode()...\n");
//printf("hdmi_set_video_mode()...\n");
//hdmi_set_video_mode(hres, vres, mhz, vhz, hdmi);

printf("hdmi_ctrl_init()...\n");
//printf("hdmi_ctrl_init()...\n");
hdmi_ctrl_init();

printf("init_vdma()...\n");
//printf("init_vdma()...\n");
init_vdma(hres, vres, hdiv, vdiv);
printf("...done.\n");
//printf("...done.\n");

//dump_vdma_status(&vdma);
}
@@ -586,19 +588,19 @@ void video_system_init_2(struct zz_video_mode *mode, int hdiv, int vdiv) {
printf("VSI: %d x %d [%d x %d] %d MHz %d Hz, hdiv: %d vdiv: %d\n", mode->hres,
mode->vres, mode->hmax, mode->vmax, mode->mhz, mode->vhz, hdiv, vdiv);

printf("pixelclock_init()...\n");
//printf("pixelclock_init()...\n");
pixelclock_init_2(mode);
printf("...done.\n");
//printf("...done.\n");

printf("hdmi_set_video_mode()...\n");
//printf("hdmi_set_video_mode()...\n");
//hdmi_set_video_mode(hres, vres, mhz, vhz, hdmi);

printf("hdmi_ctrl_init()...\n");
//printf("hdmi_ctrl_init()...\n");
hdmi_ctrl_init();

printf("init_vdma()...\n");
//printf("init_vdma()...\n");
init_vdma(mode->hres, mode->vres, hdiv, vdiv);
printf("...done.\n");
//printf("...done.\n");

//dump_vdma_status(&vdma);
}
@@ -707,15 +709,19 @@ void sprite_reset() {
}

void update_hw_sprite_pos(int16_t x, int16_t y) {
sprite_x = x + sprite_x_offset + 3;
sprite_x = x + sprite_x_offset + 1;
// horizontally doubled mode
if (scalemode & 1) sprite_x *=2;
sprite_x_adj = sprite_x;
if (scalemode & 1)
sprite_x_adj = (sprite_x * 2) + 1;
else
sprite_x_adj = sprite_x + 2;

sprite_y = y + sprite_y_offset + 1;
// vertically doubled mode
if (scalemode & 2) sprite_y *= 2;
sprite_y_adj = sprite_y;
if (scalemode & 2)
sprite_y_adj = sprite_y *= 2;
else
sprite_y_adj = sprite_y;

if (sprite_x < 0 || sprite_y < 0) {
if (sprite_clip_x != sprite_x || sprite_clip_y != sprite_y) {
@@ -1329,7 +1335,6 @@ int main() {
SWAP32(data->offset[0]);
data->offset[0] += ADDR_ADJ;

//printf("clearbuf: %.8X, %dx%d, %d size: %d\n", data->offset[0], data->x[0], data->y[0], data->pitch[0], sizeof(struct GFXData));
acc_clear_buffer(data->offset[0], data->x[0], data->y[0], data->pitch[0], data->rgb[0], data->u8_user[GFXDATA_U8_COLORMODE]);
break;
}
@@ -1343,7 +1348,6 @@ int main() {
data->offset[0] += ADDR_ADJ;
data->offset[1] += ADDR_ADJ;

//printf("flipbuf: %.8X to %.8X %dx%d, %d\n", data->offset[0], data->offset[1], data->x[0], data->y[0], data->pitch[0]);
acc_flip_to_fb(data->offset[0], data->offset[1], data->x[0], data->y[0], data->pitch[0], data->u8_user[GFXDATA_U8_COLORMODE]);
break;
case ACC_OP_BLIT_RECT:
@@ -1384,7 +1388,7 @@ int main() {
break;
}

printf ("Allocating %dx%d surface, %d bytes per pixel, %d bytes.\n", data->x[0], data->y[0], cf_bpp[data->u8_user[GFXDATA_U8_COLORMODE]], sfc_size);
printf ("Allocating %dx%d surface, %d bytes per pixel, %d bytes.\n", data->x[0], data->y[0], data->u8_user[GFXDATA_U8_COLORMODE], sfc_size);
uint8_t *p = calloc(1, sfc_size);
printf ("Surface allocated at offset %p, or %p on the Amiga side.\n", p, p - ADDR_ADJ);
data->offset[0] = (uint32_t)(p - ADDR_ADJ);


+ 20
- 4
video_formatter.v View File

@@ -53,6 +53,7 @@ localparam OP_UNUSED1=12;
localparam OP_SPRITEXY=13;
localparam OP_SPRITE_ADDR=14;
localparam OP_SPRITE_DATA=15;
localparam OP_VIDEOCAP=16; // we ignore this here, it's snooped by MNTZorro

localparam CMODE_8BIT=0;
localparam CMODE_16BIT=1;
@@ -112,9 +113,14 @@ reg [23:0] sprite_buffer[SPRITE_SIZE-1:0];
reg [11:0] sprite_addr_in;
reg [11:0] sprite_x;
reg [11:0] sprite_y;
reg sprite_dbl;
reg vga_sprite_dbl; // vga_domain
reg [11:0] vga_sprite_x; // vga domain
reg [11:0] vga_sprite_y; // vga domain
reg [11:0] vga_sprite_x2; // vga domain
reg [11:0] vga_sprite_y2; // vga domain
reg [11:0] sprite_px; // vga domain
reg [11:0] sprite_py; // vga domain
reg [23:0] sprite_pix; // vga domain
reg sprite_on; // vga domain

@@ -216,6 +222,7 @@ begin
OP_SCALE: begin
scale_x <= control_data_in[0];
scale_y <= control_data_in[1];
sprite_dbl <= control_data_in[1];
end
OP_COLORMODE: colormode <= control_data_in[1:0]; // FIXME
OP_VSYNC: vsync_request <= 1; //control_data[0];
@@ -313,6 +320,9 @@ always @(posedge dvi_clk) begin
vga_sprite_x <= sprite_x;
vga_sprite_y <= sprite_y;
end
vga_sprite_x2 <= vga_sprite_x+(SPRITE_W<<sprite_dbl);
vga_sprite_y2 <= vga_sprite_y+(SPRITE_H<<sprite_dbl);
vga_sprite_dbl <= sprite_dbl;
// FIXME there is some non-determinism in the relationship
// between this process and the fetching process
@@ -395,11 +405,16 @@ always @(posedge dvi_clk) begin
CMODE_32BIT: pixout <= pixout32_dly2;
endcase
sprite_pix <= sprite_buffer[sprite_px];
if (counter_y >= vga_sprite_y && counter_y < (vga_sprite_y+SPRITE_H)
&& counter_x >= vga_sprite_x && counter_x < (vga_sprite_x+SPRITE_W)) begin
sprite_pix <= sprite_buffer[((sprite_py>>sprite_dbl)<<5)+(sprite_px>>sprite_dbl)];
if (counter_y >= vga_sprite_y && counter_y < vga_sprite_y2
&& counter_x >= vga_sprite_x && counter_x < vga_sprite_x2) begin
sprite_on <= 1;
sprite_px <= sprite_px + 1;
if (sprite_px < (SPRITE_W<<sprite_dbl)-1'b1)
sprite_px <= sprite_px + 1'b1;
else begin
sprite_px <= 0;
sprite_py <= sprite_py + 1'b1;
end
end else begin
sprite_on <= 0;
end
@@ -411,6 +426,7 @@ always @(posedge dvi_clk) begin
if (counter_y > vga_v_max) begin
counter_y <= 0;
sprite_px <= 0;
sprite_py <= 0;
end else begin
counter_y <= counter_y + 1'b1;
end


Loading…
Cancel
Save