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

Blitter+ikbd adjustments for Pacmania STE

This commit is contained in:
harbaum
2014-02-04 14:11:06 +00:00
parent 69c3b0081a
commit 7e8bd85fa1
3 changed files with 104 additions and 92 deletions

View File

@@ -197,14 +197,7 @@ always @(negedge clk) begin
if((addr == 5'h1d) && ~lds) op <= din[3:0];
if((addr == 5'h1e) && ~uds) begin
// HACK: The tg68 does not have atomic read-modify-write cycles
// and may be interrupted by the blitter in between. We thus don't
// accept changes to the line_number register as long as the blitter
// is running since TOS polls the busy flag in the same register
// using bset which in turn can mess up the line_number
if(!busy) line_number <= din[11:8];
line_number <= din[11:8];
smudge <= din[13];
hog <= din[14];
@@ -272,7 +265,7 @@ always @(negedge clk) begin
end
// advance state machine only if bus is owned
if(br_out && !br_in) begin
if(br_out && !br_in && (y_count != 0)) begin
// first extra source read (fxsr)
if(state == 2'd3) begin
if(src_x_inc[15] == 1'b0) src <= { src[15:0], bm_data_in_latch};
@@ -348,6 +341,11 @@ always @(negedge clk) begin
else state <= 2'd0; // normal source read state
end
end
// if(busy && (y_count == 0)) begin
// undo last src inc
// src_addr <= src_addr - { {8{src_x_inc[15]}}, src_x_inc };
// end
end
end

View File

@@ -346,21 +346,12 @@ wire blitter_master_read;
wire blitter_irq;
wire [15:0] blitter_master_data_out;
wire blitter_br = blitter_br_out;
wire blitter_bg = 1'b1;
//wire blitter_bg = blitter_br;
//reg blitter_br;
//always @(posedge clk_128) begin
// if(blitter_br_out && (tg68_busstate == 2'd0))
// blitter_br <= 1'b1;
// else if(!blitter_br_out)
// blitter_br <= 1'b0;
//end
wire blitter_br_out;
// The bg signal works a little different as usual. The blitter
// will only apply br when bg allows it to do so. Forcing bussatte == 0
// make sure that the bus is never transferred in the middle of an
// instruction. This is required since some instructions use d to control
// the blitter are atomic on a real ST
wire blitter_bg = (tg68_busstate == 2'd0);
blitter blitter (
.bus_cycle (bus_cycle ),
@@ -383,7 +374,7 @@ blitter blitter (
.bm_data_in (ram_data_out),
.br_in (data_io_br ),
.br_out (blitter_br_out ),
.br_out (blitter_br ),
.bg (blitter_bg ),
.irq (blitter_irq ),
@@ -904,34 +895,30 @@ wire MEM14M = (system_ctrl[3:1] == 3'd5);
// rom is also at 0x000000 to 0x000007
wire cpu2lowrom = (tg68_adr[23:3] == 21'd0);
// ram from 0x000000 to 0x400000
// ordinary ram from 0x000000 to 0x400000, more if enabled
wire cpu2ram = (!cpu2lowrom) && (
(tg68_adr[23:22] == 2'b00) || // ordinary 4MB
((MEM14M || MEM8M) && (tg68_adr[23:22] == 2'b01)) || // 8MB
(MEM14M && ((tg68_adr[23:22] == 2'b10) || // 12MB
(tg68_adr[23:21] == 3'b110)))); // 14MB
wire cpu2ram14 = (!cpu2lowrom) && (
(tg68_adr[23:22] == 2'b00) || // ordinary 4MB
(tg68_adr[23:22] == 2'b01) || // 8MB
(tg68_adr[23:22] == 2'b10) || // 12MB
(tg68_adr[23:21] == 3'b110)); // 14MB
(tg68_adr[23:22] == 2'b00) || // ordinary 4MB
((MEM14M || MEM8M) && (tg68_adr[23:22] == 2'b01)) || // 8MB
(MEM14M && ((tg68_adr[23:22] == 2'b10) || // 12MB
(tg68_adr[23:21] == 3'b110))) || // 14MB
(steroids && (tg68_adr[23:19] == 5'b11101))); // 512k at $e80000 for STEroids
// 256k tos from 0xe00000 to 0xe40000
wire cpu2tos256k = (tg68_adr[23:18] == 6'b111000) ||
cpu2lowrom;
wire cpu2tos256k = (tg68_adr[23:18] == 6'b111000);
// 192k tos from 0xfc0000 to 0xff0000
wire cpu2tos192k = (tg68_adr[23:17] == 7'b1111110) ||
(tg68_adr[23:16] == 8'b11111110) ||
cpu2lowrom;
(tg68_adr[23:16] == 8'b11111110);
// 128k cartridge from 0xfa0000 to 0xfbffff
wire cpu2cart = (tg68_adr[23:16] == 8'hfa) ||
((tg68_adr[23:16] == 8'hfb) && !dongle_present); // include fb0000 only if no dongle present
// all rom areas
wire cpu2rom = cpu2lowrom || cpu2tos192k || cpu2tos256k || cpu2cart;
// cpu to any type of mem (rw on ram, read on rom)
wire cpu2mem = cpu2ram14 || (tg68_rw && (cpu2tos192k || cpu2tos256k || cpu2cart));
wire cpu2mem = cpu2ram || (tg68_rw && cpu2rom);
// io from 0xff0000
wire cpu2io = (tg68_adr[23:16] == 8'hff);

View File

@@ -194,13 +194,14 @@ wire [9:0] t10_v_border_top = config_string[19:10];
wire [9:0] t11_v_end = config_string[9:0];
// default video mode is monochrome
parameter DEFAULT_MODE = 2'd2;
parameter DEFAULT_MODE = 3'd2;
// shiftmode register
reg [1:0] shmode;
wire mono = (shmode == 2'd2);
wire mid = (shmode == 2'd1);
wire low = (shmode == 2'd0);
reg [2:0] shmode;
wire ttmid = (shmode == 3'd4);
wire mono = (shmode == 3'd2);
wire mid = (shmode == 3'd1);
wire low = (shmode == 3'd0);
// derive number of planes from shiftmode
wire [2:0] planes = mono?3'd1:(mid?3'd2:3'd4);
@@ -225,6 +226,8 @@ reg [7:0] line_offset; // number of words to skip at the end of each
reg [3:0] pixel_offset; // number of pixels to skip at begin of line
reg ste_overscan_enable; // STE has a special 16 bit overscan
wire mistvid = 1'b1; // enable MiST extended video mode(s)
// ---------------------------------------------------------------------------
// ----------------------------- CPU register read ---------------------------
// ---------------------------------------------------------------------------
@@ -269,7 +272,7 @@ always @(reg_sel, reg_rw, reg_uds, reg_lds, reg_addr, _v_bas_ad, shmode, vaddr,
end
// shift mode register
if(reg_addr == 6'h30) reg_dout <= { 6'h00, shmode, 8'h00 };
if(reg_addr == 6'h30) reg_dout <= { 5'h00, shmode, 8'h00 };
end
end
@@ -369,8 +372,9 @@ always @(negedge reg_clk) begin
end
end
end
if(reg_addr == 6'h30 && !reg_uds) shmode <= reg_din[9:8];
// make msb writeable if MiST video modes are enabled
if(reg_addr == 6'h30 && !reg_uds) shmode <= { mistvid?reg_din[10]:1'b0, reg_din[9:8] };
end
end
end
@@ -470,13 +474,19 @@ always @(posedge clk) begin
end
if(!scan_doubler_enable) begin
// hires mode: shift one plane only and reload
// shift_0 register every 16 clocks
if(vga_hcnt[3:0] == 4'hf) shift_0 <= data_latch[0];
else shift_0[15:1] <= shift_0[14:0];
// TODO: Color modes not using scan doubler
// hires mode: shift all planes and reload
// shift registers every 16 clocks
if(vga_hcnt[3:0] == 4'hf) begin
shift_0 <= data_latch[0];
shift_1 <= data_latch[1];
shift_2 <= data_latch[2];
shift_3 <= data_latch[3];
end else begin
shift_0[15:1] <= shift_0[14:0];
shift_1[15:1] <= shift_1[14:0];
shift_2[15:1] <= shift_2[14:0];
shift_3[15:1] <= shift_3[14:0];
end
end
end
@@ -492,38 +502,40 @@ reg last_syncmode;
reg [3:0] bottom_overscan_cnt;
reg [3:0] top_overscan_cnt;
wire bottom_overscan = (bottom_overscan_cnt != 0) /* synthesis keep */;
wire top_overscan = (top_overscan_cnt != 0) /* synthesis keep */;
wire bottom_overscan = (bottom_overscan_cnt != 0);
wire top_overscan = (top_overscan_cnt != 0);
always @(posedge clk) begin
last_syncmode <= syncmode[1]; // delay syncmode to detect changes
if(reg_reset) begin
top_overscan_cnt <= 4'd0;
bottom_overscan_cnt <= 4'd0;
end else begin
last_syncmode <= syncmode[1]; // delay syncmode to detect changes
// this is the magic used to do "overscan".
// the magic actually involves more than writing zero (60hz)
// within line 200. But this is sufficient for our detection
// this is the magic used to do "overscan".
// the magic actually involves more than writing zero (60hz)
// within line 200. But this is sufficient for our detection
// trigger in line 198/199
if((vcnt == { 8'd97, 2'b00} ) && (vga_hcnt == 10'd0) && (bottom_overscan_cnt != 0))
bottom_overscan_cnt <= bottom_overscan_cnt - 4'd1;
// trigger in line 198/199
if((vcnt == { 8'd97, 2'b00} ) && (vga_hcnt == 10'd0) && (bottom_overscan_cnt != 0))
bottom_overscan_cnt <= bottom_overscan_cnt - 4'd1;
if((vcnt[9:2] == 8'd98)||(vcnt[9:2] == 8'd99)||(vcnt[9:2] == 8'd100)) begin
// syncmode has changed from 1 to 0 (50 to 60 hz)
if((syncmode[1] == 1'b0) && (last_syncmode == 1'b1))
bottom_overscan_cnt <= 4'd15;
end
if((vcnt[9:2] == 8'd98)||(vcnt[9:2] == 8'd99)||(vcnt[9:2] == 8'd100)) begin
// syncmode has changed from 1 to 0 (50 to 60 hz)
if((syncmode[1] == 1'b0) && (last_syncmode == 1'b1))
bottom_overscan_cnt <= 4'd15;
end
// trigger in line 284/285
if((vcnt == {8'd133, 2'b00 }) && (vga_hcnt == 10'd0) && (top_overscan_cnt != 0))
top_overscan_cnt <= top_overscan_cnt - 4'd1;
// trigger in line 284/285
if((vcnt == {8'd133, 2'b00 }) && (vga_hcnt == 10'd0) && (top_overscan_cnt != 0))
top_overscan_cnt <= top_overscan_cnt - 4'd1;
if((vcnt[9:2] == 8'd134)||(vcnt[9:2] == 8'd135)||(vcnt[9:2] == 8'd136)) begin
// syncmode has changed from 1 to 0 (50 to 60 hz)
if((syncmode[1] == 1'b0) && (last_syncmode == 1'b1))
top_overscan_cnt <= 4'd15;
end
// top_overscan <= 1'b1;
// bottom_overscan <= 1'b1;
if((vcnt[9:2] == 8'd134)||(vcnt[9:2] == 8'd135)||(vcnt[9:2] == 8'd136)) begin
// syncmode has changed from 1 to 0 (50 to 60 hz)
if((syncmode[1] == 1'b0) && (last_syncmode == 1'b1))
top_overscan_cnt <= 4'd15;
end
end
end
// ---------------------------------------------------------------------------
@@ -725,9 +737,13 @@ always @(posedge clk) begin
// make sure each line starts with plane 0
if(st_hcnt == de_h_start)
plane <= 2'd0;
// according to hatari the video counter is reloaded 3 lines before
// the vbi occurs. This is right after the display has been painted.
// The video address counter is reloaded right after display ends
// The video address counter is reloaded right before display starts
if((vga_hcnt == t3_h_blank_left) && (vcnt == t7_v_blank_bot)) begin
// TODO: -1 and pacmania works ...
if((vga_hcnt == t3_h_blank_left) && (vcnt == (t7_v_blank_bot-de_v_offset+10'd1))) begin
vaddr <= _v_bas_ad;
// copy syncmode
@@ -739,17 +755,28 @@ always @(posedge clk) begin
// read if display enable is active
if(de) begin
// move incoming video data into data latch
if(ttmid) begin
// TT mid compatible part fetches all 4 planes at once
data_latch[0] <= data[15: 0];
data_latch[1] <= data[31:16];
data_latch[2] <= data[47:32];
data_latch[3] <= data[63:48];
vaddr <= vaddr + 23'd4;
end else begin
// ST shifter only uses 16 out of possible 64 bits, so select the right word
case(vaddr[1:0])
2'd0: data_latch[plane] <= data[15: 0];
2'd1: data_latch[plane] <= data[31:16];
2'd2: data_latch[plane] <= data[47:32];
2'd3: data_latch[plane] <= data[63:48];
endcase
// ST shifter only uses 16 out of possible 64 bits, so select the right word
case(vaddr[1:0])
2'd0: data_latch[plane] <= data[15: 0];
2'd1: data_latch[plane] <= data[31:16];
2'd2: data_latch[plane] <= data[47:32];
2'd3: data_latch[plane] <= data[63:48];
endcase
vaddr <= vaddr + 23'd1;
vaddr <= vaddr + 23'd1;
end
end
// advance plane counter