Author Topic: FPGA VGA Controller for 8-bit computer  (Read 426624 times)

0 Members and 8 Guests are viewing this topic.

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #725 on: December 13, 2019, 09:04:52 pm »
Hmm.. okay, so I've downloaded the project, compiled and flashed it to the FPGA and downloaded and loaded the binaries into RS232_debugger.  This is what I'm getting:

(Attachment Link)

I'm able to move it around, resize the overlay window etc. but I can't get a sensible image out of the overlay.  I haven't changed anything, I've just copied the project into a new folder and compiled it in Quantus Prime.  :-//  Also, it seems both quick binaries for the RS232_debugger are identical?
Did you program a paint software to draw in there?
Do you have the ram for a 256x256 pixel, 8 bit image?

Your looking at the existing ram contents being fed through the palette.
Play with the controls I listed...

Ok, maybe, first, you should add the the MAGGIE support for different bitplane sizes.  This way, in 1 bit color, you could render the font in memory into the sprite if you made it 8 pixels wide with a 1 byte width setting for the graphics.

Looking at the code I sent you, and knowing where the pixels / bits setting is stored, show me how you would modify my MAGGIE code to recognizes the different bitplane modes horizontal sizes.


Yes, both quick binaries are identical.
« Last Edit: December 13, 2019, 09:27:48 pm by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #726 on: December 13, 2019, 09:57:20 pm »
Grrr, line 141 in bart.v reads:
               if (x_in[3])

Take a look at line 215...  You know what is should be...

also, lines 142 & 144 are backwards....

                   pixel_out[3:0] <= ram_byte_in[3:0];

                  pixel_out[3:0] <= ram_byte_in[7:4];

See lines 216 & 218...
« Last Edit: December 13, 2019, 10:08:29 pm by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #727 on: December 13, 2019, 10:07:19 pm »
Here are 2 different quick save files for when you get the MAGGIE to respond to the 'color depth'.

This time, they are both different.

You only need to modify 1 key line in the MAGGIE to get the pixels / bits setting to work.
I also recommend making a new wire called 'pixel_per_byte[1:0]' and assign it to the right place.
« Last Edit: December 13, 2019, 10:10:47 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #728 on: December 14, 2019, 11:15:34 am »
Hmm.. okay, so I've downloaded the project, compiled and flashed it to the FPGA and downloaded and loaded the binaries into RS232_debugger.  This is what I'm getting:

(Attachment Link)

I'm able to move it around, resize the overlay window etc. but I can't get a sensible image out of the overlay.  I haven't changed anything, I've just copied the project into a new folder and compiled it in Quantus Prime.  :-//  Also, it seems both quick binaries for the RS232_debugger are identical?
Did you program a paint software to draw in there?

Not yet... I'd just assumed that there would be something meaningful in there as I could see a pattern of sorts, it was just out of phase.

Do you have the ram for a 256x256 pixel, 8 bit image?

No - I've only got 33KB to play with in total on this Cyclone IV EP4CE6 FPGA.

I'm considering designing and building a dev board for the Lattice LFE5U FPGA as there doesn't seem to be many cheap ones about (or many about at all - I found one that doesn't look great) - it would be a good practice run before starting on the GPU card build and if I slap an ADV7125 in there, I could have 24-bit VGA output to test with too.  Does anyone know of or have schematics with basic circuits to support an LFE5U FPGA?  Might start another thread on that question.  Obviously, a head start before I dive into the datasheets would speed up development.

Ok, maybe, first, you should add the the MAGGIE support for different bitplane sizes.  This way, in 1 bit color, you could render the font in memory into the sprite if you made it 8 pixels wide with a 1 byte width setting for the graphics.

Looking at the code I sent you, and knowing where the pixels / bits setting is stored, show me how you would modify my MAGGIE code to recognizes the different bitplane modes horizontal sizes.

Let me get back to you on this one.  Busy day today and I'm going to need a clear block of time to look at the code and concentrate.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #729 on: December 14, 2019, 11:42:50 am »
Is this line right?

Code: [Select]
wire [1:0]  pixel_per_byte;

assign pixel_per_byte = BP2RAST_cmd[1:0]; // bitplane setting equates to pixels per byte (0 = 1, 1 = 2, 2 = 4, or 3 = 8)
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #730 on: December 14, 2019, 03:41:11 pm »
Yes.  Now make the address generator count at the right speed according to the setting.
Study my code carefully how I assigned the wiring around of the counters and how I am accumulating the address position.

It's 1 line to edit with only a 1 new term to get it working.

You will know it's working if 1 of the new quick save file generates a meaningful image.
« Last Edit: December 14, 2019, 03:43:45 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #731 on: December 14, 2019, 06:54:15 pm »
Okay, I've had 10 minutes to look at this, so don't be too critical.  This is what I've come up with:

Code: [Select]
assign pixel_per_byte = BP2RAST_cmd[1:0]; // bitplane setting equates to pixels per byte (0 = 1, 1 = 2, 2 = 4, or 3 = 8)

So now pixel_per_byte relates directly to the current mode.  Further down, in the always @(posedge clk) block, I've tweaked the ram_read_pointer_x increment to be sensitive to the current mode:

Code: [Select]
if (run_x) begin

width <= width - 1;
ram_read_pointer_x <= ram_read_pointer_x + 2**pixel_per_byte;

end

So ram_read_pointer_x is incremented by 1 bit in mode 0, 2 bits in mode 1, 4 bits in mode 2 and a byte in mode 3, instead of just being incremented by a byte each time previously.  This results in the following output based on the two binaries you supplied:

889630-0

Looking good so far.  8)

889634-1

Oh shazbut.  |O

Not sure what I'm doing wrong, I thought I'd got it in the bag...  :-[
« Last Edit: December 14, 2019, 06:57:33 pm by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #732 on: December 14, 2019, 09:21:42 pm »
Nope, you did great.  I also would have accepted:
ram_read_pointer_x <= ram_read_pointer_x + ( 1 << pixel_per_byte );

So, you truly need me to prepare graphics...
Maybe on Sunday.

Next, X - Zoom, or scale.  Also known as X period or horizontal period.
The setting is stored in ' period_x[3:0] '.
The goal, when 'period_x[3:0]' = '0', the picture you get should be the same.
When 'period_x[3:0]' = '1' then the picture should be twice as wide, or, every X pixel is repeated twice.
When 'period_x[3:0]' = '2' then the picture should be 3 times as wide, or, every X pixel is repeated 3 times.
When 'period_x[3:0]' = '3' then the picture should be 4 times as wide, or, every X pixel is repeated 4 times.
......
When 'period_x[3:0]' = '7' then the picture should be 8 times as wide, or, every X pixel is repeated 8 times.

You get the idea.

Around 3 controls left, then some fancy manipulation to get the text working.

Now you understand the text you saw was only a sprite set to 8 pixels wide, 1 bit color, 1 byte per line and 32 lines tall pointing to the letter 'A' in the GPU ram's current font.  You could play with the base address to vertically shift the image to a new letter, or, increased the size of the window to show more letters as the font is stored vertically, all 256 characters in 1 straight line.

You also could adjust the bg_ & fg_ color to your liking, or, try 4 color mode messing up the graphic, but you would recognize a font squeezed half-width as 2 bits now generate 1 4 colour pixel.  Also, now, the bg_color now would select which 4 colors in the palette would be used for those 4 possible colors.


« Last Edit: December 14, 2019, 09:48:45 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #733 on: December 15, 2019, 12:43:56 pm »
Nope, you did great.  I also would have accepted:
ram_read_pointer_x <= ram_read_pointer_x + ( 1 << pixel_per_byte );

Ah of course - didn't think about bit-shifting.  :)  I guess the hardware output would be the same and there's no performance penalty for squaring instead of bit-shifting?

Next, X - Zoom, or scale.  Also known as X period or horizontal period.
The setting is stored in ' period_x[3:0] '.
The goal, when 'period_x[3:0]' = '0', the picture you get should be the same.
When 'period_x[3:0]' = '1' then the picture should be twice as wide, or, every X pixel is repeated twice.
When 'period_x[3:0]' = '2' then the picture should be 3 times as wide, or, every X pixel is repeated 3 times.
When 'period_x[3:0]' = '3' then the picture should be 4 times as wide, or, every X pixel is repeated 4 times.
......
When 'period_x[3:0]' = '7' then the picture should be 8 times as wide, or, every X pixel is repeated 8 times.

You get the idea.

Okay, not such a simple solution for X-scaling.  I'm sure it's not the most efficient way of doing it, but here's my solution:

Code: [Select]
wire [7:0]  width_count;   <----- new wire

if (run_x) begin

if (period_x[3:0] == width_count) begin
width <= width - 1;
width_count <= 0;
ram_read_pointer_x <= ram_read_pointer_x + 2**pixel_per_byte;
end
else begin
width_count <= width_count + 1;
ram_read_pointer_x <= ram_read_pointer_x;
end

end

width_count is zeroed in the xy_rst, x_rst and h_rst if... blocks as well.  Full project attached below.

Here's a screenshot of a pixel scaled to 8x width:

« Last Edit: December 15, 2019, 01:59:56 pm by nockieboy »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #734 on: December 15, 2019, 02:18:44 pm »
Okay, so I've pushed on a little further and implemented the Y-scale function as well.  :-/O

890086-0

Nice 8x8 scaling on the original sprite.  ^-^

Again, don't know if I'm using the optimal method to scale the sprite, but I've attached the updated MAGGIE code.  :-+
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #735 on: December 15, 2019, 04:42:06 pm »
Have you tried moving the text around inside a zoomed box with and without the original 'Y' code, taking care of the source read address, you will see a little problem...

Are you sure your width and height is correct ad 1x and 2x zooms?
Is the right read address getting through?

Change the base memory address to 0x0B10 & 0x0B00.  Move it up and down 1 or 2 at different Y zoom levels 0 & 1.  Something is off.

Your top line of the font is off by 1 byte as 0x0B0F renders the beginning of the character properly.  And when zoomed, vertically to 1, you are also 1 line short at the bottom of the image.  In fact, at all zoom levels above 0, you are missing 1 line at the bottom.

(I counted using the test vertical bar cursor at address 0x3F03)
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #736 on: December 15, 2019, 06:01:40 pm »
Have you tried moving the text around inside a zoomed box with and without the original 'Y' code, taking care of the source read address, you will see a little problem...

Are you sure your width and height is correct ad 1x and 2x zooms?
Is the right read address getting through?

Change the base memory address to 0x0B10 & 0x0B00.  Move it up and down 1 or 2 at different Y zoom levels 0 & 1.  Something is off.

Your top line of the font is off by 1 byte as 0x0B0F renders the beginning of the character properly.  And when zoomed, vertically to 1, you are also 1 line short at the bottom of the image.  In fact, at all zoom levels above 0, you are missing 1 line at the bottom.

(I counted using the test vertical bar cursor at address 0x3F03)

Thought I was doing too well.  :-\

I've been staring at the code for the last 30 minutes and, short of randomly moving stuff about to test the results, I don't think I'm likely to spot the problem any time soon.  :-//

One thing I've found is that it's missing the first line even without the Y-scale code changes.

Is it because width[] and height[] are registers, and thus are a clock behind? 
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #737 on: December 15, 2019, 06:55:55 pm »
Have you tried moving the text around inside a zoomed box with and without the original 'Y' code, taking care of the source read address, you will see a little problem...

Are you sure your width and height is correct ad 1x and 2x zooms?
Is the right read address getting through?

Change the base memory address to 0x0B10 & 0x0B00.  Move it up and down 1 or 2 at different Y zoom levels 0 & 1.  Something is off.

Your top line of the font is off by 1 byte as 0x0B0F renders the beginning of the character properly.  And when zoomed, vertically to 1, you are also 1 line short at the bottom of the image.  In fact, at all zoom levels above 0, you are missing 1 line at the bottom.

(I counted using the test vertical bar cursor at address 0x3F03)

Thought I was doing too well.  :-\

I've been staring at the code for the last 30 minutes and, short of randomly moving stuff about to test the results, I don't think I'm likely to spot the problem any time soon.  :-//

One thing I've found is that it's missing the first line even without the Y-scale code changes.

Is it because width[] and height[] are registers, and thus are a clock behind?

Ok, lets see if I can help you out of this one...
Read my attached code carefully and compare the changes I made compared to yours.
Also read the comments I added.

Code: [Select]
// **************************************************************
// *                                                            *
// *  Multiple Address Generator & Graphics Instruction Engine  *
// *                                                            *
// **************************************************************

module maggie (

//inputs
input wire clk,
input wire [3:0]  pc_ena_in,
input wire [7:0]  hw_regs[0:(2**HW_REGS-1)],
input wire [47:0] HV_trig,
input wire [31:0] cmd_in,
input wire [15:0] ram_din,

//outputs (all wires as we will embed the connected registers inside the module)
output wire [19:0] read_addr,
output wire [31:0] cmd_out,
output wire [23:0] bp_2_rast_cmd

);

// parameters
parameter HW_REGS = 8;
parameter HW_REG_BASE = 96;
parameter H_RESET_TRIG = 8;
parameter H_POS_TRIG = 10;
parameter RAM_READ_CYCLES = 3;

// local parameters
localparam V_RESET_TRIG = H_RESET_TRIG +  1;
localparam V_POS_TRIG = H_POS_TRIG +  1;
localparam BP2RAST_cmd = HW_REG_BASE +  0; // Transfers the video mode setting to the new bitplane_2_raster module
localparam BP2RAST_bgc = HW_REG_BASE +  1; // Transfers the bg_colour setting to the new bitplane_2_raster module
localparam BP2RAST_fgc = HW_REG_BASE +  2; // Transfers the fg_colour setting to the new bitplane_2_raster module
localparam RST_ADDR_H = HW_REG_BASE +  3; // MSB bits of 24 bit base read address
localparam RST_ADDR_M = HW_REG_BASE +  4; // MID bits of 24 bit base read address
localparam RST_ADDR_L = HW_REG_BASE +  5; // LSB bits of 24 bit base read address
localparam YINC_ADDR_H = HW_REG_BASE +  6; // MSB bits of 16 bit Y-Line increment for read address
localparam YINC_ADDR_L = HW_REG_BASE +  7; // LSB bits of 16 bit Y-Line increment for read address
localparam X_SIZE_H = HW_REG_BASE +  8; // MSB bits of 16 bit display width screen pixels
localparam X_SIZE_L = HW_REG_BASE +  9; // LSB bits of 16 bit display width screen pixels
localparam Y_SIZE_H = HW_REG_BASE + 10; // MSB bits of 16 bit display height screen y lines
localparam Y_SIZE_L = HW_REG_BASE + 11; // LSB bits of 16 bit display height screen y lines
localparam X_SCALE = HW_REG_BASE + 12; // Compound of two 4 bit words. Upper 4 bits controls the X increment every period, lower 4 bits is a pixel period counter to define the number of pixels until the upper 4 bits are added to the address-pointer.
localparam Y_SCALE = HW_REG_BASE + 13; // Compound of two 4 bit words. Upper 4 bits reserved for text tile mode Y size while the lower lower 4 bits is a line period counter to define the number of lines until YINC_ADDR is added to the address-pointer
localparam X_START_SUB = HW_REG_BASE + 14; // An 8 bit word which defines an odd pixel start position within the period counter and X position within a bitplane's X coordinate position
localparam Y_START_SUB = HW_REG_BASE + 15; // An 8 bit word which defines an odd line start within within the period counter and Y coordinates inside a font.

// registers
reg [19:0] ram_read_pointer_y;
reg [23:0] ram_read_pointer_x;
reg [4:0] period_x;
reg [4:0] period_y;
reg [7:0] h_trig_delay;
reg [11:0] width;
reg [11:0] height;
wire run_x;
wire run_y;
assign run_x = width[11];
assign run_y = height[11];

// wires
wire h_rst, x_rst, xy_rst;
wire h_trig, v_trig;
wire window_enable;
wire [23:0] reset_addr;
wire [15:0] inc_addr_x;
wire [15:0] inc_addr_y;
wire [3:0]  period_x_rst;
wire [3:0]  period_y_rst;
wire [11:0] x_size;
wire [11:0] y_size;
wire [1:0]  pixel_per_byte;
wire [7:0]  width_count;
wire [7:0]  height_count;

// assignments
assign bp_2_rast_cmd[23:0] = { hw_regs[BP2RAST_fgc] , hw_regs[BP2RAST_bgc] , hw_regs[BP2RAST_cmd] };
assign text_mode_master = hw_regs[BP2RAST_cmd][7];

assign x_rst = HV_trig[H_RESET_TRIG];
assign xy_rst = HV_trig[V_RESET_TRIG] && x_rst;

assign v_trig = HV_trig[V_POS_TRIG];
assign h_trig = HV_trig[H_POS_TRIG];
assign h_rst = text_mode_master ? h_trig_delay[0] : h_trig_delay[RAM_READ_CYCLES-1];  // When in text mode, push the window left by 'RAM_READ_CYCLES' as it takes a second memory read to get the font image

assign window_enable = run_x && run_y;
assign cmd_out[7] = window_enable; // commands the pixel/by/pixel window enable for the bitplane_2_raster module
assign cmd_out[6] = 1'b0; // for now, disables the 2 byte colour mode

assign reset_addr[23:0] = { hw_regs[RST_ADDR_H] , hw_regs[RST_ADDR_M] , hw_regs[RST_ADDR_L]  };
assign inc_addr_y[15:0] = { hw_regs[YINC_ADDR_H] , hw_regs[YINC_ADDR_L] };
assign inc_addr_x[3:0] = hw_regs[X_SCALE][7:4];

assign read_addr[19:0] = ram_read_pointer_x[22:3];
assign cmd_out[2:0] = ram_read_pointer_x[2:0]; // commands the sub pixel X position for the bitplane_2_raster module

assign period_x[3:0] = hw_regs[X_SCALE][3:0];
assign period_y[3:0] = hw_regs[Y_SCALE][3:0];

assign period_x_rst[3:0] = hw_regs[X_START_SUB][3:0];
assign period_y_rst[3:0] = hw_regs[Y_START_SUB][3:0];

assign x_size[11:0] = { hw_regs[X_SIZE_H][3:0], hw_regs[X_SIZE_L][7:0] };
assign y_size[11:0] = { hw_regs[Y_SIZE_H][3:0], hw_regs[Y_SIZE_L][7:0] };

assign pixel_per_byte = BP2RAST_cmd[1:0]; // bitplane setting equates to pixels per byte (0 = 1, 1 = 2, 2 = 4, or 3 = 8)

always @(posedge clk) begin

   if (pc_ena_in[3:0] == 0) begin

      h_trig_delay[7:1] <= h_trig_delay[6:0];
h_trig_delay[0] <= h_trig;

      if (xy_rst) begin // equivalent to a vertical sync/reset

height             <= 0;
width_count <= 0;
height_count <= 0;

end
else if (x_rst) begin // equivalent to a horizontal sync/increment

width <= 0;
width_count <= 0;

if (v_trig) begin              // V_TRIG is high for the entire first line of video to be displayed.  This is the point in place and time where the read address must be equal to the setting in the reset_addr.
height[11]   <= 1;      // set run_y bit active
height[10:0] <= y_size[10:0];
height_count <= 0;     // * must reset as well.

ram_read_pointer_y <= reset_addr << 3;  // V_TRIG is high during the first active line of video, set the read pointer, both
ram_read_pointer_x <= reset_addr << 3;  // the backup and currrent display address to the exact reset base address during this line.
end // V_TRIG
else begin  // ~V_TRIG

if (run_y) begin                // after the first line, do these functions.
if (period_y[3:0] == height_count) begin   // If the vertical scale period count has reached it's end
height <= height - 1;                  // count down the visible window size
height_count <= 0;                     // reset the vertical period
ram_read_pointer_y <= ram_read_pointer_y + (inc_addr_y[15:0] << 3);  // vertical increment display position in backup buffer
ram_read_pointer_x <= ram_read_pointer_y + (inc_addr_y[15:0] << 3);  // vertical increment display position in current display address
end // (period_y[3:0] == height_count
else begin                                // if the period count hasn't reached it's end,
height_count <= height_count + 1;  // increment the period count
ram_read_pointer_x <= ram_read_pointer_y; // restore the memory read address to the previous backup buffer address
end

end // ~V_TRIG
end

      end
else begin


if (h_rst) begin

width[11]   <= 1;       // set run_x bit active
width[10:0] <= x_size[10:0];
width_count <= 0;

end

if (run_x) begin

if (period_x[3:0] == width_count) begin
width <= width - 1;
width_count <= 0;
ram_read_pointer_x <= ram_read_pointer_x + 2**pixel_per_byte;
end
else begin
width_count <= width_count + 1;
end

end

         //-------------------------------
         //snap to it....
         //-------------------------------

      end // ~x_rst

   end // if (pc_ena_in[3:0] == 0)

end //@(posedge clk)

endmodule

« Last Edit: December 15, 2019, 07:04:40 pm by BrianHG »
 
The following users thanked this post: nockieboy

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #738 on: December 15, 2019, 07:02:38 pm »
Next, we want to shift the horizontal position within the sprite/window by a sub-bitplane-pixel.

This means shift the text image in the window to the left by 1 pixel at a time.
This figure is stored inside the 'period_x_rst'

Please do not touch the 'period_y_rst' as this has specifically to do with rendering tiles/fonts on the 'Y' axis.  We have 2 other variables to do first, then we need to gut the old OSD text and wire in the new MAGGIE in it's place before you can edit this last variable of the MAGGIE.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #739 on: December 15, 2019, 08:57:14 pm »
I cannot find a .pal or .act file of the VGA palette which I need to properly convert some bitmap files using photoshop.

If I convert an image using a different palette, you will need to edit the 565.mif file to see the image properly.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #740 on: December 16, 2019, 01:28:38 am »
Okay, I've had 10 minutes to look at this, so don't be too critical.  This is what I've come up with:

Code: [Select]
assign pixel_per_byte = BP2RAST_cmd[1:0]; // bitplane setting equates to pixels per byte (0 = 1, 1 = 2, 2 = 4, or 3 = 8)

So now pixel_per_byte relates directly to the current mode.  Further down, in the always @(posedge clk) block, I've tweaked the ram_read_pointer_x increment to be sensitive to the current mode:
Another mistake, this line should read:
Code: [Select]
assign pixel_per_byte = bp_2_rast_cmd[1:0]; // bitplane setting equates to pixels per byte (0 = 1, 1 = 2, 2 = 4, or 3 = 8)

Fix it up....
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #741 on: December 16, 2019, 03:12:31 am »
Another mistake in BART.v module.

Lines 141 and 215 currently read:

if (x_in[2])

When they should actually read:

if (~x_in[2])

Now that you fixed the issues in my last 2 posts, load these attached test graphics files.

I deliberately left them a binary files you need to load into spare empty memory.  I recommend $1200 i.e. 0x1200.  This will place a bit of the graphics into the end of your text buffer, but there is no other space as they will go all they way up to address $3EFF.

The 4 files are:
z80_360x256x1.bin
pac_208x204x4.bin
z80_192x120x16.bin
z80_120x96x256.bin

I tested them all ok, so I expect proper screen shots.  You will need to figure out the MAGGIE settings for the X&Y resolution by # of colors.
« Last Edit: December 16, 2019, 03:24:53 am by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #742 on: December 16, 2019, 09:29:36 am »
The 4 files are:
z80_360x256x1.bin
pac_208x204x4.bin
z80_192x120x16.bin
z80_120x96x256.bin

I tested them all ok, so I expect proper screen shots.  You will need to figure out the MAGGIE settings for the X&Y resolution by # of colors.

Here's what I've got - the palette is out mostly, but I think I can decipher the images:  ;)

z80_360x256x1.bin:
890526-0

pac_208x204x4.bin:
890530-1

z80_192x120x16.bin:
890534-2

z80_120x96x256.bin: (I moved the sprite down out of the way of the garbage text above it)
890538-3

The images are appearing BEHIND the text though - is there a setting I'm missing somewhere?
« Last Edit: December 16, 2019, 09:31:47 am by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #743 on: December 16, 2019, 09:53:02 am »
The 4 files are:
z80_360x256x1.bin
pac_208x204x4.bin
z80_192x120x16.bin
z80_120x96x256.bin

I tested them all ok, so I expect proper screen shots.  You will need to figure out the MAGGIE settings for the X&Y resolution by # of colors.

Here's what I've got - the palette is out mostly, but I think I can decipher the images:  ;)

z80_360x256x1.bin:
(Attachment Link)
You couldn't choose a better set of colors, like White and Black?
Remmeber, bg_color anf FG_color...
What about turning off the text layer?
Remember, the old bitplane_to_raster controls...
Quote
pac_208x204x4.bin:
(Attachment Link)
Ok, I was limited here.  You could only get the right image by editing the palette.  So for this one, I forgive you.
Quote

z80_192x120x16.bin:
(Attachment Link)
You couldn't choose an alternate palette base number from bg_color?
You would be surprised...
Quote

z80_120x96x256.bin: (I moved the sprite down out of the way of the garbage text above it)
(Attachment Link)
Ok, unless you want to change the entire palette, this is the best I could do...
Quote

The images are appearing BEHIND the text though - is there a setting I'm missing somewhere?
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #744 on: December 16, 2019, 10:31:05 am »
You couldn't choose a better set of colors, like White and Black?
Remmeber, bg_color anf FG_color...
What about turning off the text layer?
Remember, the old bitplane_to_raster controls...

I was just interested in getting the images to show, and to make the text overlapping the sprites visible.  I know I can turn the text off, just wondered if the 'z-order' of the drawing was correct and intended, that's all?

890562-0
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #745 on: December 16, 2019, 10:43:40 am »
You couldn't choose a better set of colors, like White and Black?
Remmeber, bg_color anf FG_color...
What about turning off the text layer?
Remember, the old bitplane_to_raster controls...

I was just interested in getting the images to show, and to make the text overlapping the sprites visible.  I know I can turn the text off, just wondered if the 'z-order' of the drawing was correct and intended, that's all?

(Attachment Link)
When all 15 sprites/layers are in place, the z-order priority goes from top sprite to bottom sprite.

Ok, now, go back to the Yellow/Blue AB text test, make this function work:
https://www.eevblog.com/forum/fpga/fpga-vga-controller-for-8-bit-computer/msg2830598/#msg2830598

We then have 16 bit addressing, Y font/tile scale/size, MAGGIE Font-slave-addressing mode, replace old OSD Font algorithm with 5x MAGGIE with new font capabilities, update palette to 5 port ram function to receive 5 MAGGIE, switch 5 port rams to 15 port rams on GPU ram palette, fix up Z80 bridge to cope with 16bit GPU ram, and then you have finished your GPU V1.0 core.


« Last Edit: December 16, 2019, 10:45:22 am by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #746 on: December 16, 2019, 02:59:42 pm »
Well, that got weird fast...  :o

I had a think about how best to implement horizontal scrolling as you've stated:

890616-0

Being more of someone who learns by experimentation, I cracked on and started writing code to get the sprite going horizontally, tweaking and adding bits to get the desired output.  I decided to stop when I realised I hadn't a clue what I was doing anymore and the sprite wasn't scrolling horizontally properly for every height it could have.  :-//

Code: [Select]
ram_read_pointer_x <= ram_read_pointer_x + (x_size * y_size) + x_size*((1 << y_size[7:4]) - 1) + 1 + y_size[7:4];

Can't be good when it starts to get that complicated and it still doesn't cover sizes of Y above 0x20.

Full code for MAGGIE attached so you can see what a convoluted mess I've made with my attempt.  ::)
« Last Edit: December 16, 2019, 03:29:26 pm by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #747 on: December 16, 2019, 06:31:40 pm »
Well, that got weird fast...  :o

I had a think about how best to implement horizontal scrolling as you've stated:

(Attachment Link)

Being more of someone who learns by experimentation, I cracked on and started writing code to get the sprite going horizontally, tweaking and adding bits to get the desired output.  I decided to stop when I realised I hadn't a clue what I was doing anymore and the sprite wasn't scrolling horizontally properly for every height it could have.  :-//

Code: [Select]
ram_read_pointer_x <= ram_read_pointer_x + (x_size * y_size) + x_size*((1 << y_size[7:4]) - 1) + 1 + y_size[7:4];

Can't be good when it starts to get that complicated and it still doesn't cover sizes of Y above 0x20.

Full code for MAGGIE attached so you can see what a convoluted mess I've made with my attempt.  ::)
You only needed 8 pixels.  Your Z80 fills in the reset address.  This is all you should have written:
Lines 137 & 138: (undo your other changes)
ram_read_pointer_y <= (reset_addr << 3) + period_x_rst;  // V_TRIG is high during the first active line of video, set the read pointer, both
ram_read_pointer_x <= (reset_addr << 3) + period_x_rst;  // the backup and current display address to the exact reset base address during this line.

This allows byte/bitplane sub-pixel horizontal alignment along the X-axis when the sprite begins it's first pixel.  If you like, there is the potential to add 1 other thing to make this add always = to 1 pixel when dealing with 4 color and 16 bit color.  It's useless with 256 color at the base address increments as 1 for moving the image 1 pixel.

Next, the really weird 16 bit pixel mode.  Add this assign:
assign pixel_16_bit         = bp_2_rast_cmd[2];  // setting goes high when we expect 16 bit, 2 byte pixels.

Now, what this setting does is when set to 1, every time the 'X' read address increases, it will need to increase by 2, not 1 as it currently does.  If you truly figure the really simple way to get this one to work right, you will get a prize...   Remember, that 'Increment by 2' doe not affect the lower 3 bits which horizontally position the bitplane sub-pixel positioning.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #748 on: December 16, 2019, 07:05:22 pm »
You only needed 8 pixels.  Your Z80 fills in the reset address.  This is all you should have written:
Lines 137 & 138: (undo your other changes)
ram_read_pointer_y <= (reset_addr << 3) + period_x_rst;  // V_TRIG is high during the first active line of video, set the read pointer, both
ram_read_pointer_x <= (reset_addr << 3) + period_x_rst;  // the backup and current display address to the exact reset base address during this line.

This allows byte/bitplane sub-pixel horizontal alignment along the X-axis when the sprite begins it's first pixel.  If you like, there is the potential to add 1 other thing to make this add always = to 1 pixel when dealing with 4 color and 16 bit color.  It's useless with 256 color at the base address increments as 1 for moving the image 1 pixel.

... but that doesn't do what I thought you wanted?  I had in mind, for example for an 8x16 sprite, it would show the letter 'A' and when you scroll it, it would scroll to the left and show the letter 'B' coming in from the right, stopping one pixel short of showing the full tile (for the Z80 to re-set the start address and show the next char completely)?  :-\

Also, the 'new' tile scrolling in from the right is moved up a line?  Is that intended?

Next, the really weird 16 bit pixel mode.  Add this assign:
assign pixel_16_bit         = bp_2_rast_cmd[2];  // setting goes high when we expect 16 bit, 2 byte pixels.

Now, what this setting does is when set to 1, every time the 'X' read address increases, it will need to increase by 2, not 1 as it currently does.  If you truly figure the really simple way to get this one to work right, you will get a prize...   Remember, that 'Increment by 2' doe not affect the lower 3 bits which horizontally position the bitplane sub-pixel positioning.

Erm... well, I'd change lines 151 and 152 to this:

Code: [Select]
ram_read_pointer_y <= ram_read_pointer_y + (inc_addr_y[15:0] << (3 + pixel_16_bit));  // vertical increment display position in backup buffer
ram_read_pointer_x <= ram_read_pointer_y + (inc_addr_y[15:0] << (3 + pixel_16_bit));  // vertical increment display position in current display address

Latest MAGGIE code attached.
« Last Edit: December 16, 2019, 07:12:53 pm by nockieboy »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #749 on: December 16, 2019, 07:33:01 pm »
You only needed 8 pixels.  Your Z80 fills in the reset address.  This is all you should have written:
Lines 137 & 138: (undo your other changes)
ram_read_pointer_y <= (reset_addr << 3) + period_x_rst;  // V_TRIG is high during the first active line of video, set the read pointer, both
ram_read_pointer_x <= (reset_addr << 3) + period_x_rst;  // the backup and current display address to the exact reset base address during this line.

This allows byte/bitplane sub-pixel horizontal alignment along the X-axis when the sprite begins it's first pixel.  If you like, there is the potential to add 1 other thing to make this add always = to 1 pixel when dealing with 4 color and 16 bit color.  It's useless with 256 color at the base address increments as 1 for moving the image 1 pixel.

... but that doesn't do what I thought you wanted?  I had in mind, for example for an 8x16 sprite, it would show the letter 'A' and when you scroll it, it would scroll to the left and show the letter 'B' coming in from the right, stopping one pixel short of showing the full tile (for the Z80 to re-set the start address and show the next char completely)?  :-\

Also, the 'new' tile scrolling in from the right is moved up a line?  Is that intended?
I you are showing 1 pixel less, then you may want to shrike the horizontal width of the window so you don't see the extra junk on the right hand side.  Remember, the text font is 1 byte wide.  Try playing with the 1bit color, B&W graphic I gave you which is multiple bytes wide.  Shifting it to the left 1 pixel at a time will not make the right hand side vertically jump except all the way on the right hand side of the window.  Increase the read reset address by 1 and the image will shift 8 pixels to the left.  Increase the base address by the width byte setting and the image will vertically shift by 1 line.  We have not yet touched tiles/fonts.  You are missing a chunk of code which defines the current vertical location within a tile since you cannot add the current 'Y' address every line at the same character memory needs to be re-read every line while a sub-Y position is needed to compute where to read the font memory a second time around passing through the GPU ram again bases on the contents of the prior read character ram.

I'm curious, have you ever programmed direct HW registers for a video display on an Atari 800, or Amiga?  Did you not know this is how their internal video processors work the same way.  Or are you just used to library calls with do this control 'bit' manipulation under the hood?

Quote
Next, the really weird 16 bit pixel mode.  Add this assign:
assign pixel_16_bit         = bp_2_rast_cmd[2];  // setting goes high when we expect 16 bit, 2 byte pixels.

Now, what this setting does is when set to 1, every time the 'X' read address increases, it will need to increase by 2, not 1 as it currently does.  If you truly figure the really simple way to get this one to work right, you will get a prize...   Remember, that 'Increment by 2' doe not affect the lower 3 bits which horizontally position the bitplane sub-pixel positioning.

Erm... well, I'd change lines 151 and 152 to this:

Code: [Select]
ram_read_pointer_y <= ram_read_pointer_y + ((inc_addr_y[15:0] << 3) * (1+pixel_16_bit));  // vertical increment display position in backup buffer
ram_read_pointer_x <= ram_read_pointer_y + ((inc_addr_y[15:0] << 3) * (1+pixel_16_bit));  // vertical increment display position in current display address

Latest MAGGIE code attached.

EDIT: Hang on - testing a simpler way to do the 16-bit scroll..
Nope, that's wrong.  Right now, every time the horizontal address needs to increase, every 8, 4, 2 ,or every pixel, it increments by 1 address.  Meaning, 1 byte at a time.  We need to double this addition once every 8, 4, 2, or every pixel.  This has nothing to do with the vertical increment as that setting specifies the number of horizontal bytes you source image is.  So, naturally you would just have the correct number set there by the Z80 defining the number of bytes per line in the source graphic.  This is not what I am asking.  When MAGGIE is drawing the image, as it requests every single pixel, when the 16bit setting is high, it needs to recognize that every pixel is 2 bytes (16 bit) wide, not 1 byte.  How will you adapt MAGGIE to handle this.


Think about it this way, if you want color text.  Now don't go into reading the font yet as the font is still 8 bit.  But your memory has an 8 bit character stored as 1 bit monochrome.  And, the upper 8 bits, being read at the same time, stores the 256 possible colors, 16 foreground and 16 background colors.  Now, our ram is already wired to read 16 bits in 1 shot, but, the upper 8 bits is just the adjacent address according to the opposite LSB address as we wired it that way as a backwards compatibility to 8 bit mode.
« Last Edit: December 16, 2019, 07:41:42 pm by BrianHG »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf