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:
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user