1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-01-26 20:01:48 +00:00

Blitter works

This commit is contained in:
harbaum
2013-08-22 14:38:07 +00:00
parent 8729df11c1
commit fc86678739

View File

@@ -103,10 +103,7 @@ always @(sel, rw, addr, src_y_inc, src_x_inc, src_addr, endmask1, endmask2, endm
end
end
// source read takes place in state 1 (normal source read) and 4 (fxsr)
assign bm_addr = ((state == 1)||(state == 4))?src_addr:dst_addr;
reg [2:0] state;
reg [2:0] state /* synthesis noprune */;
reg [7:0] dummy /* synthesis noprune */;
always @(negedge clk) begin
@@ -160,7 +157,7 @@ always @(negedge clk) begin
if(din[15] && (y_count != 0)) begin
busy <= 1'b1;
state <= 3'd0;
end
end
end
if((addr == 5'h1e) && ~lds) begin
@@ -172,54 +169,63 @@ always @(negedge clk) begin
end
// --------- blitter state machine -------------
// the state machine runs through most states for every word it processes
// state 0: Blitter has just been started, wait 1 bus cycle before updating counters
// state 1: normal source read cycle
// state 2: destination read cycle
// state 3: destination write cycle
// state 4: extra source read cycle (fxsr)
br <= busy; // hog mode: grab bus immediately as long as we need it
// busy is written by the cpu and anly becomes active if y_count != 0
// busy->br is written by the cpu and anly becomes active if y_count != 0
if(br && (bus_cycle == 2'd0)) begin
if(state == 3'd3) begin
if(last_word_in_row && fxsr)
state <= 3'd4; // extra state 4, then 1, 2 ...
else
state <= 3'd1; // cycle through states 1, 2 and 3
end else if(state == 3'd4)
// init/setup state
if(state == 3'd0) begin
if(fxsr) begin
state <= 3'd4;
// op <= 4'd15; // all black for testing
end
else state <= 3'd1;
end
// first extra source read (fxsr)
if(state == 3'd4) begin
if(src_x_inc[15] == 1'b0) src <= { src[15:0], bm_data_in};
else src <= { bm_data_in, src[31:16]};
src_addr <= src_addr + { {8{src_x_inc[15]}}, src_x_inc };
state <= 3'd1;
else if(state == 3'd0 && fxsr)
state <= 3'd4;
else
state <= state + 3'd1;
if((state == 3'd1) || (state == 3'd4)) begin
end
if(state == 3'd1) begin
// don't do the read of the last word in a row if nfsr is set
if(!((state == 3'd1) && nfsr && last_word_in_row)) begin
if(src_x_inc[15] == 1'b0) src[15:0] <= bm_data_in;
else src[31:16] <= bm_data_in;
if(nfsr && last_word_in_row) begin
// no final source read, but shifting anyway
if(src_x_inc[15] == 1'b0) src[31:16] <= src[15:0];
else src[15:0] <= src[31:16];
src_addr <= src_addr + { {8{src_y_inc[15]}}, src_y_inc } - { {8{src_x_inc[15]}}, src_x_inc };
// in noral read state (not due to fxsr) we shift
if(state == 3'd1) begin
if(src_x_inc[15] == 1'b0) src[31:16] <= src[15:0];
else src[15:0] <= src[31:16];
end
end else begin
if(src_x_inc[15] == 1'b0) src <= { src[15:0], bm_data_in};
else src <= { bm_data_in, src[31:16]};
// if(src_x_inc[15] == 1'b0) src <= { src[15:0], bm_data_in};
// else src <= { bm_data_in, src[31:16]};
// process src pointer
if(x_count != 1) // do signed add by sign expanding XXX_x_inc
src_addr <= src_addr + { {8{src_x_inc[15]}}, src_x_inc };
else // we are at the end of a line
src_addr <= src_addr + { {8{src_y_inc[15]}}, src_y_inc };
end else begin
// no source read, but shifting anyway
if(src_x_inc[15] == 1'b0) src[31:16] <= src[15:0];
else src[15:0] <= src[31:16];
// TODO: do the dest read here if nfsr and skip state 2
end
state <= 3'd2;
end
if(state == 3'd2) begin
dest <= bm_data_in;
state <= 3'd3;
end
// don't update counters and adresses if still in setup phase
@@ -235,7 +241,6 @@ always @(negedge clk) begin
dst_addr <= dst_addr + { {8{dst_x_inc[15]}}, dst_x_inc };
x_count <= x_count - 8'd1;
end else begin
// we are at the end of a line but not finished yet
@@ -251,17 +256,24 @@ always @(negedge clk) begin
// y_count reached zero -> end of blitter operation
busy <= 1'b0;
end
if(last_word_in_row && fxsr)
state <= 3'd4; // extra state 4
else
state <= 3'd1; // normal source read state
end
end
end
// source read takes place in state 1 (normal source read) and 4 (fxsr)
assign bm_addr = ((state == 1)||(state == 4))?src_addr:dst_addr;
// ----------------- blitter busmaster engine -------------------
always @(posedge clk) begin
bm_read <= 1'b0;
bm_write <= 1'b0;
if(br && (y_count != 0) && (bus_cycle == 2'd0)) begin
// drive write
if(state == 3'd1) bm_read <= 1'b1;
else if(state == 3'd2) bm_read <= 1'b1;
else if(state == 3'd3) bm_write <= 1'b1;
@@ -269,8 +281,6 @@ always @(posedge clk) begin
end
end
// wire io = (bus_cycle[3:2] == 1); // blitter does io in cycle 1 which is the same one the cpu uses
// internal registers
reg [31:0] src; // 32 bit source read buffer
reg [15:0] dest; // 16 bit destination read buffer
@@ -300,11 +310,6 @@ halftone_op halftone_op (
.out (src_halftoned)
);
// todo: clean this
reg [15:0] dummy_reg /* synthesis noprune */;
always @(posedge clk) begin
dummy_reg <= src_skewed;
end
// apply blitter operation
blitter_op blitter_op (
@@ -354,7 +359,7 @@ module blitter_op (
always @(op, in0, in1) begin
case(op)
0: out = 8'h00;
0: out = 16'h0000;
1: out = in0 & in1;
2: out = in0 & ~in1;
3: out = in0;
@@ -364,12 +369,12 @@ always @(op, in0, in1) begin
7: out = in0 | in1;
8: out = ~in0 & ~in1;
9: out = ~in0 ^ in1;
10: out = ~in1;
10: out = ~in1;
11: out = in0 | ~in1;
12: out = ~in0;
13: out = ~in0 | in1;
14: out = ~in0 | ~in1;
15: out = 8'hff;
15: out = 16'hffff;
endcase; // case (op)
end