mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-01-13 15:17:39 +00:00
Viking/SM194 support
This commit is contained in:
parent
5ddcb6fc37
commit
0f686abc5a
93
cores/mist/io_fifo.v
Normal file
93
cores/mist/io_fifo.v
Normal file
@ -0,0 +1,93 @@
|
||||
//
|
||||
// io_fifo.v
|
||||
//
|
||||
// Atari ST(E) io controller FIFO for the MiST board
|
||||
// http://code.google.com/p/mist-board/
|
||||
//
|
||||
// Copyright (c) 2013 Till Harbaum <till@harbaum.org>
|
||||
// Modified by Juan Carlos González Amestoy.
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module io_fifo #(
|
||||
parameter DATA_WIDTH = 8,
|
||||
parameter DEPTH = 4
|
||||
)(
|
||||
input reset,
|
||||
|
||||
input [DATA_WIDTH-1:0] in,
|
||||
input in_clk,
|
||||
input in_strobe,
|
||||
input in_enable,
|
||||
|
||||
input out_clk,
|
||||
output [DATA_WIDTH-1:0] out,
|
||||
input out_strobe,
|
||||
input out_enable,
|
||||
|
||||
output empty,
|
||||
output data_available,
|
||||
output full
|
||||
);
|
||||
|
||||
localparam FIFO_ADDR_BITS = DEPTH;
|
||||
localparam FIFO_DEPTH = (1 << FIFO_ADDR_BITS);
|
||||
|
||||
reg [DATA_WIDTH-1:0] fifo [FIFO_DEPTH-1:0];
|
||||
reg [FIFO_ADDR_BITS-1:0] writeP, readP;
|
||||
|
||||
assign full = (readP == (writeP + 1));
|
||||
assign empty = (readP == writeP);
|
||||
assign data_available = (readP != writeP);
|
||||
|
||||
// the strobes may not be in the right clock domain, so bring them into the
|
||||
// local clock domain
|
||||
reg in_strobeD, in_strobeD2;
|
||||
reg out_strobeD, out_strobeD2;
|
||||
|
||||
// present current value. If fifo is empty show last value
|
||||
assign out = data_available?fifo[readP]:fifo[readP-1];
|
||||
|
||||
always @(posedge out_clk) begin
|
||||
// bring strobes in local clock domain
|
||||
out_strobeD <= out_strobe;
|
||||
out_strobeD2 <= out_strobeD;
|
||||
|
||||
if(reset)
|
||||
readP <= 0;
|
||||
else begin
|
||||
// rising edge on fifo read strobe from io controller
|
||||
if((out_strobeD && !out_strobeD2) || out_enable)
|
||||
readP <= readP + 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge in_clk) begin
|
||||
// bring strobes in local clock domain
|
||||
in_strobeD <= in_strobe;
|
||||
in_strobeD2 <= in_strobeD;
|
||||
|
||||
if(reset)
|
||||
writeP <= 0;
|
||||
else begin
|
||||
// rising edge on strobe signal causes write
|
||||
// or in_enable being true
|
||||
if((in_strobeD && !in_strobeD2) || in_enable) begin
|
||||
fifo[writeP] <= in;
|
||||
writeP <= writeP + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@ -323,7 +323,9 @@ set_global_assignment -name VERILOG_FILE clock.v
|
||||
set_global_assignment -name VERILOG_FILE mist_top.v
|
||||
set_global_assignment -name VERILOG_FILE user_io.v
|
||||
set_global_assignment -name VERILOG_FILE video.v
|
||||
set_global_assignment -name VERILOG_FILE viking.v
|
||||
set_global_assignment -name VERILOG_FILE video_modes.v
|
||||
set_global_assignment -name VERILOG_FILE io_fifo.v
|
||||
set_global_assignment -name VERILOG_FILE osd.v
|
||||
set_global_assignment -name VERILOG_FILE data_io.v
|
||||
set_global_assignment -name VERILOG_FILE mfp.v
|
||||
|
||||
@ -46,6 +46,8 @@ wire ste = system_ctrl[23] || system_ctrl[24];
|
||||
wire mste = system_ctrl[24];
|
||||
wire steroids = system_ctrl[23] && system_ctrl[24]; // a STE on steroids
|
||||
|
||||
// ethernec is enabled by the io controller whenever a USB
|
||||
// ethernet interface is detected
|
||||
wire ethernec_present = system_ctrl[25];
|
||||
|
||||
// usb target port on io controller is used for redirection of
|
||||
@ -213,6 +215,60 @@ wire [15:0] io_data_out = vreg_data_out | dma_data_out | blitter_data_out |
|
||||
|
||||
wire init = ~pll_locked;
|
||||
|
||||
/* -------------------------- Viking video card -------------------- */
|
||||
|
||||
// viking/sm194 is enabled and max 8MB memory may be enabled
|
||||
wire viking_mem_ok = MEM512K || MEM1M || MEM2M || MEM4M || MEM8M;
|
||||
wire viking_enable = system_ctrl[28] && viking_mem_ok;
|
||||
|
||||
// check for cpu access to 0xcxxxxx with viking enabled to switch video
|
||||
// output once the driver loads
|
||||
reg viking_in_use;
|
||||
always @(negedge clk_128) begin
|
||||
if(reset)
|
||||
viking_in_use <= 1'b0;
|
||||
else
|
||||
if(clkena && viking_enable && (tg68_adr[23:18] == 6'b110000))
|
||||
viking_in_use <= 1'b1;
|
||||
end
|
||||
|
||||
// video output multiplexer to switch between shifter and viking
|
||||
wire viking_active = viking_in_use && !osd_enable;
|
||||
assign VGA_HS = viking_active?viking_hs:shifter_hs;
|
||||
assign VGA_VS = viking_active?viking_vs:shifter_vs;
|
||||
assign VGA_R = viking_active?viking_r:shifter_r;
|
||||
assign VGA_G = viking_active?viking_g:shifter_g;
|
||||
assign VGA_B = viking_active?viking_b:shifter_b;
|
||||
|
||||
wire viking_hs, viking_vs;
|
||||
wire [5:0] viking_r, viking_g, viking_b;
|
||||
|
||||
wire [22:0] viking_address;
|
||||
wire viking_read;
|
||||
|
||||
viking viking (
|
||||
.reset (reset ),
|
||||
.pclk (clk_128 ), // pixel
|
||||
.bus_cycle (bus_cycle ),
|
||||
|
||||
// memory interface
|
||||
.bclk (clk_8 ), // system bus clock = 8Mhz
|
||||
.addr (viking_address ),
|
||||
.data (ram_data_out_64),
|
||||
.read (viking_read ),
|
||||
|
||||
// video output
|
||||
.hs (viking_hs ),
|
||||
.vs (viking_vs ),
|
||||
.r (viking_r ),
|
||||
.g (viking_g ),
|
||||
.b (viking_b )
|
||||
);
|
||||
|
||||
wire osd_enable;
|
||||
wire shifter_hs, shifter_vs;
|
||||
wire [5:0] shifter_r, shifter_g, shifter_b;
|
||||
|
||||
video video (
|
||||
.clk (clk_32 ),
|
||||
.clk27 (CLOCK_27[0]),
|
||||
@ -222,6 +278,7 @@ video video (
|
||||
.sdi (SPI_DI ),
|
||||
.sck (SPI_SCK ),
|
||||
.ss (SPI_SS3 ),
|
||||
.osd_enable (osd_enable ),
|
||||
|
||||
// cpu register interface
|
||||
.reg_clk (clk_8 ),
|
||||
@ -238,11 +295,11 @@ video video (
|
||||
.data (ram_data_out_64),
|
||||
.read (video_read ),
|
||||
|
||||
.hs (VGA_HS ),
|
||||
.vs (VGA_VS ),
|
||||
.video_r (VGA_R ),
|
||||
.video_g (VGA_G ),
|
||||
.video_b (VGA_B ),
|
||||
.hs (shifter_hs ),
|
||||
.vs (shifter_vs ),
|
||||
.video_r (shifter_r ),
|
||||
.video_g (shifter_g ),
|
||||
.video_b (shifter_b ),
|
||||
|
||||
// configuration signals
|
||||
.adjust (video_adj ),
|
||||
@ -955,14 +1012,16 @@ wire MEM14M = (system_ctrl[3:1] == 3'd5);
|
||||
|
||||
// rom is also at 0x000000 to 0x000007
|
||||
wire cpu2lowrom = (tg68_adr[23:3] == 21'd0);
|
||||
|
||||
|
||||
// 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
|
||||
(steroids && (tg68_adr[23:19] == 5'b11101))); // 512k at $e80000 for STEroids
|
||||
(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
|
||||
(viking_enable && (tg68_adr[23:18] == 6'b110000)) // 256k at 0xc00000 for viking card
|
||||
);
|
||||
|
||||
// 256k tos from 0xe00000 to 0xe40000
|
||||
wire cpu2tos256k = (tg68_adr[23:18] == 6'b111000);
|
||||
@ -1001,23 +1060,23 @@ wire second_cpu_slot = (mste && enable_16mhz) || steroids;
|
||||
// cpu, DMA and Blitter. A third is optionally being used for faster CPU
|
||||
wire video_cycle = (bus_cycle == 0);
|
||||
wire cpu_cycle = (bus_cycle == 1) || (second_cpu_slot && (bus_cycle == 3));
|
||||
wire viking_cycle = (bus_cycle == 2);
|
||||
|
||||
// ----------------- RAM address --------------
|
||||
wire [22:0] video_cycle_addr = (st_hs && ste)?ste_dma_snd_addr:video_address;
|
||||
wire [22:0] cpu_cycle_addr = data_io_br?data_io_addr:(blitter_br?blitter_master_addr:tg68_adr[23:1]);
|
||||
wire [22:0] ram_address = video_cycle?video_cycle_addr:cpu_cycle_addr;
|
||||
wire [22:0] ram_address = viking_cycle?viking_address:(video_cycle?video_cycle_addr:cpu_cycle_addr);
|
||||
|
||||
// ----------------- RAM read -----------------
|
||||
// memory access during the video cycle is shared between video and ste_dma_snd
|
||||
wire video_cycle_oe = (st_hs && ste)?ste_dma_snd_read:video_read;
|
||||
// memory access during the cpu cycle is shared between blitter and cpu
|
||||
wire cpu_cycle_oe = data_io_br?data_io_read:(blitter_br?blitter_master_read:(cpu_cycle && tg68_as && tg68_rw && cpu2mem));
|
||||
wire ram_oe = video_cycle?video_cycle_oe:(cpu_cycle?cpu_cycle_oe:1'b0);
|
||||
wire ram_oe = viking_cycle?viking_read:(video_cycle?video_cycle_oe:(cpu_cycle?cpu_cycle_oe:1'b0));
|
||||
|
||||
// ----------------- RAM write -----------------
|
||||
wire video_cycle_wr = 1'b0;
|
||||
wire cpu_cycle_wr = data_io_br?data_io_write:(blitter_br?blitter_master_write:(cpu_cycle && tg68_as && ~tg68_rw && cpu2ram));
|
||||
wire ram_wr = video_cycle?video_cycle_wr:(cpu_cycle?cpu_cycle_wr:1'b0);
|
||||
wire ram_wr = (viking_cycle||video_cycle)?1'b0:(cpu_cycle?cpu_cycle_wr:1'b0);
|
||||
|
||||
wire [15:0] ram_data_out;
|
||||
wire [15:0] system_data_out = cpu2mem?ram_data_out:io_data_out;
|
||||
|
||||
@ -28,6 +28,8 @@ module osd (
|
||||
input ss,
|
||||
input sdi,
|
||||
|
||||
output reg osd_enable,
|
||||
|
||||
// current video beam position
|
||||
input [9:0] hcnt,
|
||||
input [9:0] vcnt,
|
||||
@ -57,7 +59,6 @@ reg [7:0] cmd;
|
||||
reg [4:0] cnt;
|
||||
reg [10:0] bcnt;
|
||||
|
||||
reg osd_enable;
|
||||
reg [7:0] osd_buffer [2047:0]; // the OSD buffer itself
|
||||
|
||||
// the OSD has its own SPI interface to the io controller
|
||||
|
||||
@ -59,7 +59,8 @@ module video (
|
||||
input [1:0] scanlines, // scanlines (00-none 01-25% 10-50% 11-100%)
|
||||
input [15:0] adjust, // hor/ver video adjust
|
||||
input ste, // enable STE featurss
|
||||
|
||||
output osd_enable,
|
||||
|
||||
// signals not affected by scan doubler for internal use like irqs
|
||||
output st_de,
|
||||
output reg st_vs,
|
||||
@ -374,6 +375,8 @@ osd osd (
|
||||
.sdi (sdi ),
|
||||
.sck (sck ),
|
||||
.ss (ss ),
|
||||
|
||||
.osd_enable (osd_enable ),
|
||||
|
||||
// feed ST video signal into OSD
|
||||
.clk (clk ),
|
||||
|
||||
155
cores/mist/viking.v
Normal file
155
cores/mist/viking.v
Normal file
@ -0,0 +1,155 @@
|
||||
//
|
||||
// viking.v
|
||||
//
|
||||
// Atari ST(E) Viking/SM194
|
||||
// http://code.google.com/p/mist-board/
|
||||
//
|
||||
// Copyright (c) 2013 Till Harbaum <till@harbaum.org>
|
||||
// Modified by Juan Carlos González Amestoy.
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// The viking card does not have its own CPU interface as it is not
|
||||
// configurable in any way. It just etches data from ram and displays
|
||||
// it on screen.
|
||||
|
||||
module viking (
|
||||
input reset,
|
||||
input pclk, // 128 MHz pixel clock
|
||||
|
||||
// memory interface
|
||||
input bclk, // 8 MHz bus clock
|
||||
input [1:0] bus_cycle, // bus-cycle for bus access sync
|
||||
output reg [22:0] addr, // video word address
|
||||
output read, // video read cycle
|
||||
input [63:0] data, // video data read
|
||||
|
||||
// VGA output (multiplexed with sm124 output in top level)
|
||||
output hs,
|
||||
output vs,
|
||||
output [5:0] r,
|
||||
output [5:0] g,
|
||||
output [5:0] b
|
||||
);
|
||||
|
||||
localparam BASE = 23'h600000; // c00000
|
||||
|
||||
// total width must be multiple of 64, so video runs synchronous
|
||||
// to main bus
|
||||
|
||||
// Horizontal timing
|
||||
// HBP1 | H | HFP | HS | HBP2
|
||||
// -----|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|-----|____|-----
|
||||
// HBP1 is used for prefetch
|
||||
|
||||
// 1280x
|
||||
localparam H = 1280;
|
||||
localparam HFP = 88;
|
||||
localparam HS = 136;
|
||||
localparam HBP1 = 32;
|
||||
localparam HBP2 = 192;
|
||||
|
||||
// Vertical timing
|
||||
// V | VFP | VS | VBP
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|-----|____|-----
|
||||
|
||||
// x1024
|
||||
localparam V = 1024;
|
||||
localparam VFP = 9;
|
||||
localparam VS = 4;
|
||||
localparam VBP = 9;
|
||||
|
||||
assign read = (bus_cycle == 2) && me; // memory enable can directly be used as a ram read signal
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// --------------------------- internal state counter ------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
reg [3:0] t /* synthesis noprune */;
|
||||
always @(posedge pclk) begin
|
||||
// 128 Mhz counter synchronous to 8 Mhz clock
|
||||
// force counter to pass state 0 exactly after the rising edge of clk_reg (8Mhz)
|
||||
if(((t == 4'd15) && ( bclk == 0)) ||
|
||||
((t == 4'd0) && ( bclk == 1)) ||
|
||||
((t != 4'd15) && (t != 4'd0)))
|
||||
t <= t + 4'd1;
|
||||
end
|
||||
|
||||
// create internal bus_cycle signal which is stable on the positive clock
|
||||
// edge and extends the previous state by half a 128 Mhz clock cycle
|
||||
reg [5:0] bus_cycle_L /* synthesis noprune */ ;
|
||||
always @(negedge pclk)
|
||||
bus_cycle_L <= { bus_cycle, t };
|
||||
|
||||
|
||||
// --------------- horizontal timing -------------
|
||||
reg[10:0] h_cnt; // 0..2047
|
||||
assign hs = ((h_cnt >= HBP1+H+HFP) && (h_cnt < HBP1+H+HFP+HS))?0:1;
|
||||
always@(posedge pclk) begin
|
||||
if(h_cnt==HBP1+H+HFP+HS+HBP2-1) begin
|
||||
// make sure a line starts with the "viking" bus cyle (2)
|
||||
// shifter has cycle 0, cpu has cycles 1 and 3
|
||||
if(bus_cycle_L == { 2'd1, 4'd15 })
|
||||
h_cnt<=0;
|
||||
end else
|
||||
h_cnt <= h_cnt + 1;
|
||||
end
|
||||
|
||||
// --------------- vertical timing -------------
|
||||
reg[10:0] v_cnt; // 0..2047
|
||||
assign vs = ((v_cnt >= V+VFP) && (v_cnt < V+VFP+VS))?0:1;
|
||||
always@(posedge pclk) begin
|
||||
if(h_cnt==HBP1+H+HFP+HS+HBP2-1) begin
|
||||
if(v_cnt==V+VFP+VS+VBP-1) v_cnt <= 0;
|
||||
else v_cnt <= v_cnt+1;
|
||||
end
|
||||
end
|
||||
|
||||
// reorder words 1:2:3:4 -> 4:3:2:1
|
||||
wire [63:0] data_reorder = { data[15:0], data[31:16], data[47:32], data[63:48] };
|
||||
|
||||
reg [63:0] input_latch;
|
||||
reg [63:0] shift_register;
|
||||
|
||||
// ---------------- memory timing ----------------
|
||||
always@(posedge pclk) begin
|
||||
// last line on screen
|
||||
if(v_cnt == V+VFP+VS+VBP-2)
|
||||
addr <= BASE;
|
||||
else if(me && bus_cycle_L == 6'h30) // directly after read
|
||||
addr <= addr + 23'd4; // advance 4 words (64 bits)
|
||||
|
||||
if(me && (bus_cycle_L == 6'h2f))
|
||||
input_latch <= data_reorder;
|
||||
|
||||
if(bus_cycle_L == 6'h3f)
|
||||
shift_register <= input_latch;
|
||||
else
|
||||
shift_register[63:1] <= shift_register[62:0];
|
||||
end
|
||||
|
||||
// memory enable (data is being read from memory)
|
||||
wire me = (v_cnt < V)&&(h_cnt < H) /* synthesis keep */;
|
||||
// display enable (data is being displayed)
|
||||
wire de = (v_cnt < V)&&(h_cnt >= HBP1)&&(h_cnt < HBP1+H) /* synthesis keep */;
|
||||
|
||||
wire pix = de?(!shift_register[63]):1'b0;
|
||||
|
||||
// drive all 18 rgb bits from the data bit
|
||||
wire [5:0] pix6 = { pix, pix, pix, pix, pix, pix };
|
||||
assign r = pix6;
|
||||
assign g = pix6;
|
||||
assign b = pix6;
|
||||
|
||||
endmodule
|
||||
BIN
tools/mist_vhi.st
Normal file
BIN
tools/mist_vhi.st
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user