mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-01-27 12:21:44 +00:00
ATari ST DMA rewritten
This commit is contained in:
@@ -97,30 +97,23 @@ reg ikbd_cpu_data_read;
|
||||
reg [7:0] ikbd_cr;
|
||||
reg [7:0] midi_cr;
|
||||
|
||||
reg [15:0] ikbd_rx_counter /* synthesis noprune */;
|
||||
|
||||
always @(negedge clk) begin
|
||||
if(reset) begin
|
||||
readTimer <= 14'd0;
|
||||
ikbd_rx_counter <= 16'd0;
|
||||
end else begin
|
||||
if(readTimer > 0)
|
||||
readTimer <= readTimer - 14'd1;
|
||||
|
||||
// read on ikbd data register
|
||||
ikbd_cpu_data_read <= 1'b0;
|
||||
if(sel && ~ds && rw && (addr == 2'd1)) begin
|
||||
if(sel && ~ds && rw && (addr == 2'd1))
|
||||
ikbd_cpu_data_read <= 1'b1;
|
||||
ikbd_rx_counter <= ikbd_rx_counter + 16'd1;
|
||||
end
|
||||
|
||||
|
||||
if(ikbd_cpu_data_read && ikbd_rx_data_available) begin
|
||||
// Some programs (e.g. bolo) need a pause between two ikbd bytes.
|
||||
// The ikbd runs at 7812.5 bit/s 1 start + 8 data + 1 stop bit.
|
||||
// One byte is 1/718.25 seconds. A pause of ~1ms is thus required
|
||||
// 8000000/718.25 = 11138.18
|
||||
// readTimer <= 14'd11138;
|
||||
readTimer <= 14'd15000;
|
||||
end
|
||||
end
|
||||
@@ -128,6 +121,7 @@ end
|
||||
|
||||
// ------------------ cpu interface --------------------
|
||||
|
||||
wire [7:0] ikbd_status = { ikbd_irq, 6'b000001, cpu_ikbd_rx_data_available};
|
||||
wire [7:0] ikbd_rx_data;
|
||||
wire ikbd_rx_data_available;
|
||||
|
||||
@@ -149,11 +143,11 @@ always @(sel, ds, rw, addr, ikbd_rx_data_available, ikbd_rx_data, ikbd_irq,
|
||||
|
||||
if(sel && ~ds && rw) begin
|
||||
// keyboard acia read
|
||||
if(addr == 2'd0) dout = { ikbd_irq, 6'b000001, cpu_ikbd_rx_data_available};
|
||||
if(addr == 2'd0) dout = ikbd_status;
|
||||
if(addr == 2'd1) dout = ikbd_rx_data;
|
||||
|
||||
// midi acia read
|
||||
if(addr == 2'd2) dout = { midi_irq, 5'b00000, midi_tx_empty, midi_rx_data_available};
|
||||
if(addr == 2'd2) dout = midi_status;
|
||||
if(addr == 2'd3) dout = midi_rx_data;
|
||||
end
|
||||
end
|
||||
@@ -162,6 +156,9 @@ end
|
||||
wire midi_irq = (midi_cr[7] && midi_rx_data_available) || // rx irq
|
||||
((midi_cr[6:5] == 2'b01) && midi_tx_empty); // tx irq
|
||||
|
||||
wire [7:0] midi_status = { midi_irq, 1'b0 /* parity err */, midi_rx_overrun, midi_rx_frame_error,
|
||||
2'b00 /* CTS & DCD */, midi_tx_empty, midi_rx_data_available};
|
||||
|
||||
// MIDI runs at 31250bit/s which is exactly 1/256 of the 8Mhz system clock
|
||||
|
||||
// 8MHz/256 = 31250Hz -> MIDI bit rate
|
||||
@@ -171,10 +168,11 @@ always @(posedge clk)
|
||||
|
||||
// --------------------------- midi receiver -----------------------------
|
||||
reg [7:0] midi_rx_cnt; // bit + sub-bit counter
|
||||
reg [8:0] midi_rx_shift_reg; // shift register used during reception
|
||||
reg [7:0] midi_rx_shift_reg; // shift register used during reception
|
||||
reg [7:0] midi_rx_data;
|
||||
reg [3:0] midi_rx_filter; // filter to reduce noise
|
||||
reg midi_rx_frame_error;
|
||||
reg midi_rx_overrun;
|
||||
reg midi_rx_data_available;
|
||||
reg midi_in_filtered;
|
||||
|
||||
@@ -183,17 +181,23 @@ always @(negedge clk) begin
|
||||
midi_rx_cnt <= 8'd0;
|
||||
midi_rx_data_available <= 1'b0;
|
||||
midi_rx_filter <= 4'b1111;
|
||||
midi_rx_overrun <= 1'b0;
|
||||
midi_rx_frame_error <= 1'b0;
|
||||
end else begin
|
||||
|
||||
// read on midi data register
|
||||
if(sel && ~ds && rw && (addr == 2'd3))
|
||||
if(sel && ~ds && rw && (addr == 2'd3)) begin
|
||||
midi_rx_data_available <= 1'b0; // read on midi data clears rx status
|
||||
midi_rx_overrun <= 1'b0;
|
||||
end
|
||||
|
||||
// midi acia master reset
|
||||
if(midi_cr[1:0] == 2'b11) begin
|
||||
midi_rx_cnt <= 8'd0;
|
||||
midi_rx_data_available <= 1'b0;
|
||||
midi_rx_filter <= 4'b1111;
|
||||
midi_rx_overrun <= 1'b0;
|
||||
midi_rx_frame_error <= 1'b0;
|
||||
end
|
||||
|
||||
// 1/16 system clock == 16 times midi clock
|
||||
@@ -218,20 +222,24 @@ always @(negedge clk) begin
|
||||
// received a bit
|
||||
if(midi_rx_cnt[3:0] == 4'd0) begin
|
||||
// in the middle of the bit -> shift new bit into msb
|
||||
midi_rx_shift_reg <= { midi_in_filtered, midi_rx_shift_reg[8:1] };
|
||||
midi_rx_shift_reg <= { midi_in_filtered, midi_rx_shift_reg[7:1] };
|
||||
end
|
||||
|
||||
// receiving last (stop) bit
|
||||
if(midi_rx_cnt[7:0] == 8'd1) begin
|
||||
if(midi_in_filtered == 1'b1) begin
|
||||
// copy data into rx register
|
||||
midi_rx_data <= midi_rx_shift_reg[8:1]; // pure data w/o start and stop bits
|
||||
midi_rx_data <= midi_rx_shift_reg; // pure data w/o start and stop bits
|
||||
midi_rx_data_available <= 1'b1;
|
||||
midi_rx_frame_error <= 1'b0;
|
||||
end else
|
||||
// report frame error via status register
|
||||
midi_rx_frame_error <= 1'b1;
|
||||
|
||||
|
||||
// data hasn't been read yet? -> overrun
|
||||
if(midi_rx_data_available)
|
||||
midi_rx_overrun <= 1'b1;
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
120
cores/mist/acsi.v
Normal file
120
cores/mist/acsi.v
Normal file
@@ -0,0 +1,120 @@
|
||||
// acsi.v
|
||||
//
|
||||
// Atari ST ACSI implementation for the MIST baord
|
||||
// http://code.google.com/p/mist-board/
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// 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 acsi (
|
||||
// clocks and system interface
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input [7:0] enable,
|
||||
|
||||
input dma_ack, // IO controller answers request
|
||||
input dma_nak, // IO controller rejects request
|
||||
input [7:0] dma_status,
|
||||
|
||||
|
||||
input [2:0] status_sel,
|
||||
output [7:0] status_byte,
|
||||
|
||||
// cpu interface
|
||||
input [1:0] cpu_addr,
|
||||
input cpu_sel,
|
||||
input cpu_rw,
|
||||
input [7:0] cpu_din,
|
||||
output [7:0] cpu_dout,
|
||||
|
||||
output reg irq
|
||||
);
|
||||
|
||||
// acsi always returns dma status on cpu_read
|
||||
assign cpu_dout = dma_status;
|
||||
|
||||
reg [2:0] target;
|
||||
reg [4:0] cmd;
|
||||
reg [2:0] byte_counter;
|
||||
reg [7:0] cmd_parms [4:0];
|
||||
reg busy;
|
||||
|
||||
// acsi status as reported to the io controller
|
||||
assign status_byte =
|
||||
(status_sel == 0)?{ target, cmd }:
|
||||
(status_sel == 1)?cmd_parms[0]:
|
||||
(status_sel == 2)?cmd_parms[1]:
|
||||
(status_sel == 3)?cmd_parms[2]:
|
||||
(status_sel == 4)?cmd_parms[3]:
|
||||
(status_sel == 5)?cmd_parms[4]:
|
||||
(status_sel == 6)?{ 7'b0000000, busy }:
|
||||
8'h00;
|
||||
|
||||
// CPU write interface
|
||||
always @(negedge clk) begin
|
||||
if(reset) begin
|
||||
target <= 3'd0;
|
||||
cmd <= 5'd0;
|
||||
irq <= 1'b0;
|
||||
busy <= 1'b0;
|
||||
end else begin
|
||||
|
||||
// DMA transfer has been ack'd by io controller
|
||||
if(dma_ack && busy) begin
|
||||
irq <= 1'b1; // set acsi irq
|
||||
busy <= 1'd0;
|
||||
end
|
||||
|
||||
// DMA transfer has been rejected by io controller (no such device)
|
||||
if(dma_nak)
|
||||
busy <= 1'd0;
|
||||
|
||||
// cpu is accessing acsi bus -> clear acsi irq
|
||||
// status itself is returned by the io controller with the dma_ack.
|
||||
if(cpu_sel)
|
||||
irq <= 1'b0;
|
||||
|
||||
// acsi register access
|
||||
if(cpu_sel && !cpu_rw) begin
|
||||
if(!cpu_addr[0]) begin
|
||||
// a0 == 0 -> first command byte
|
||||
target <= cpu_din[7:5];
|
||||
cmd <= cpu_din[4:0];
|
||||
byte_counter <= 3'd0;
|
||||
|
||||
// check if this acsi device is enabled
|
||||
if(enable[cpu_din[7:5]] == 1'b1)
|
||||
irq <= 1'b1;
|
||||
end else begin
|
||||
// further bytes
|
||||
cmd_parms[byte_counter] <= cpu_din[7:0];
|
||||
byte_counter <= byte_counter + 3'd1;
|
||||
|
||||
// check if this acsi device is enabled
|
||||
if(enable[target] == 1'b1) begin
|
||||
// auto-ack first 5 bytes
|
||||
if(byte_counter < 4)
|
||||
irq <= 1'b1;
|
||||
else
|
||||
busy <= 1'b1; // request io cntroller
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // acsi
|
||||
@@ -1,199 +0,0 @@
|
||||
// SPI data client (rom, floppy, harddisk io)
|
||||
|
||||
module data_io (
|
||||
// clocks
|
||||
input clk_8,
|
||||
input reset,
|
||||
input [1:0] bus_cycle,
|
||||
output reg [31:0] ctrl_out,
|
||||
|
||||
// spi interface
|
||||
input sdi,
|
||||
input sck,
|
||||
input ss,
|
||||
output sdo,
|
||||
|
||||
// dma status interface
|
||||
output [4:0] dma_idx,
|
||||
input [7:0] dma_data,
|
||||
output reg dma_ack,
|
||||
output reg br,
|
||||
|
||||
// horizontal and vertical screen adjustments
|
||||
output reg [15:0] video_adj,
|
||||
|
||||
// ram interface
|
||||
output reg read,
|
||||
output reg write,
|
||||
output [22:0] addr,
|
||||
output reg [15:0] data_out, // write data register
|
||||
input [15:0] data_in
|
||||
);
|
||||
|
||||
assign dma_idx = bcnt;
|
||||
|
||||
reg [4:0] cnt; // bit counter (counting spi bits, rolling from 23 to 8)
|
||||
reg [4:0] bcnt; // payload byte counter
|
||||
reg [14:0] sbuf; // receive buffer (buffer used to assemble spi bytes/words)
|
||||
reg [7:0] cmd; // command byte (first byte of spi transmission)
|
||||
reg [30:0] addrR;// address register (word address for memory transfers)
|
||||
reg writeCmd; // write request received via SPI
|
||||
reg writeD; // write synchonized to 8Mhz clock
|
||||
reg writeD2; // synchronized write delayed by one 8Mhz clock
|
||||
reg readCmd; // read request received via SPI
|
||||
reg readD; // read synchonized to 8Mhz clock
|
||||
reg readD2; // synchronized read delayed by one 8Mhz clock
|
||||
reg [15:0] ram_data; // latch for incoming ram data
|
||||
reg brI; // signals to bring br into local clock domain
|
||||
|
||||
// during write the address needs to be decremented by one as the
|
||||
// address auto increment takes place at the beginning of each transfer
|
||||
assign addr = (cmd==2)?(addrR[22:0]-23'd1):addrR[22:0];
|
||||
|
||||
// latch bus cycle to have it stable at the end of the cycle (rising edge of clk8)
|
||||
reg [1:0] bus_cycle_L;
|
||||
always @(negedge clk_8) begin
|
||||
bus_cycle_L <= bus_cycle;
|
||||
|
||||
if(bus_cycle == 0)
|
||||
br <= brI;
|
||||
end
|
||||
|
||||
// generate state signals required to control the sdram host interface
|
||||
always @(posedge clk_8) begin
|
||||
// start io transfers clock cycles after bus_cycle 0
|
||||
// (after the cpu cycle)
|
||||
writeD <= writeCmd && ((bus_cycle_L == 3) || writeD);
|
||||
writeD2 <= writeD;
|
||||
readD <= readCmd && ((bus_cycle_L == 3) || readD);
|
||||
readD2 <= readD;
|
||||
|
||||
// at the end of a read cycle latch the incoming ram data for later spi transmission
|
||||
if(read) ram_data <= data_in;
|
||||
|
||||
if(reset) begin
|
||||
read <= 1'b0;
|
||||
write <= 1'b0;
|
||||
end else begin
|
||||
if(writeD && ~writeD2) begin
|
||||
write <= 1'b1;
|
||||
read <= 1'b0;
|
||||
end else if(readD && ~readD2) begin
|
||||
write <= 1'b0;
|
||||
read <= 1'b1;
|
||||
end else begin
|
||||
write <= 1'b0;
|
||||
read <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [15:0] txData;
|
||||
assign sdo = txData[15];
|
||||
|
||||
always@(negedge sck) begin
|
||||
// memory read
|
||||
if(cmd == 3) begin
|
||||
if(cnt == 8)
|
||||
txData <= ram_data;
|
||||
else
|
||||
txData[15:1] <= txData[14:0];
|
||||
end
|
||||
|
||||
// dma status read
|
||||
if(cmd == 5) begin
|
||||
if((cnt == 8) || (cnt == 16))
|
||||
txData[15:8] <= dma_data;
|
||||
else
|
||||
txData[15:1] <= txData[14:0];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always@(posedge sck, posedge ss) begin
|
||||
if(ss == 1'b1) begin
|
||||
cnt <= 5'd0;
|
||||
bcnt <= 4'd0;
|
||||
writeCmd <= 1'b0;
|
||||
readCmd <= 1'b0;
|
||||
dma_ack <= 1'b0;
|
||||
end else begin
|
||||
dma_ack <= 1'b0;
|
||||
sbuf <= { sbuf[13:0], sdi};
|
||||
|
||||
// 0:7 is command, 8:15 and 16:23 is payload bytes
|
||||
if(cnt < 5'd23)
|
||||
cnt <= cnt + 5'd1;
|
||||
else
|
||||
cnt <= 5'd8;
|
||||
|
||||
// count payload bytes
|
||||
if((cnt == 15) || (cnt == 23))
|
||||
bcnt <= bcnt + 4'd1;
|
||||
|
||||
if(cnt == 5'd7) begin
|
||||
cmd <= {sbuf[6:0], sdi};
|
||||
|
||||
// send ack
|
||||
if({sbuf[6:0], sdi } == 8'd6)
|
||||
dma_ack <= 1'b1;
|
||||
|
||||
// request bus
|
||||
if({sbuf[6:0], sdi } == 8'd7)
|
||||
brI <= 1'b1;
|
||||
|
||||
// release bus
|
||||
if({sbuf[6:0], sdi } == 8'd8)
|
||||
brI <= 1'b0;
|
||||
|
||||
// if we can see a read coming initiate sdram read transfer asap
|
||||
if({sbuf[6:0], sdi } == 8'd3)
|
||||
readCmd <= 1;
|
||||
end
|
||||
|
||||
// handle "payload"
|
||||
if(cnt >= 8) begin
|
||||
|
||||
// set address
|
||||
if(cmd == 1)
|
||||
addrR <= { addrR[29:0], sdi};
|
||||
|
||||
// write ram
|
||||
if(cmd == 2) begin
|
||||
if(cnt == 5'd16)
|
||||
writeCmd <= 1'b0;
|
||||
|
||||
if(cnt == 5'd23) begin
|
||||
data_out <= { sbuf, sdi };
|
||||
addrR <= addrR + 31'b1;
|
||||
writeCmd <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// read ram
|
||||
if(cmd == 3) begin
|
||||
if(cnt == 16)
|
||||
readCmd <= 0;
|
||||
|
||||
if(cnt == 23) begin
|
||||
addrR <= addrR + 31'b1;
|
||||
readCmd <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
// set control register (32 bits written in 2 * 16 bits)
|
||||
if((cmd == 4) && (cnt == 5'd23)) begin
|
||||
if(bcnt < 2)
|
||||
ctrl_out[31:16] <= { sbuf, sdi };
|
||||
else
|
||||
ctrl_out[15:0] <= { sbuf, sdi };
|
||||
end
|
||||
|
||||
// set video offsets
|
||||
if((cmd == 9) && (cnt == 5'd23))
|
||||
video_adj <= { sbuf, sdi };
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
1063
cores/mist/dma.v
1063
cores/mist/dma.v
File diff suppressed because it is too large
Load Diff
271
cores/mist/fdc.v
Normal file
271
cores/mist/fdc.v
Normal file
@@ -0,0 +1,271 @@
|
||||
// fdc.v
|
||||
//
|
||||
// Atari ST floppy implementation for the MIST baord
|
||||
// http://code.google.com/p/mist-board/
|
||||
//
|
||||
// Copyright (c) 2014 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// 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 fdc (
|
||||
// clocks and system interface
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
// write protection of currently selected floppy
|
||||
input [1:0] drv_sel,
|
||||
input drv_side,
|
||||
input wr_prot,
|
||||
|
||||
input dma_ack,
|
||||
input [2:0] status_sel,
|
||||
output [7:0] status_byte,
|
||||
|
||||
// cpu interface
|
||||
input [1:0] cpu_addr,
|
||||
input cpu_sel,
|
||||
input cpu_rw,
|
||||
input [7:0] cpu_din,
|
||||
output reg [7:0] cpu_dout,
|
||||
|
||||
output reg irq
|
||||
);
|
||||
|
||||
// fdc_busy is a counter. counts down from 2 to 0. stays at 3 since that
|
||||
// means that the fdc is waiting for the arm io controller
|
||||
localparam STATE_IDLE = 2'd0;
|
||||
localparam STATE_IRQ = 2'd1;
|
||||
localparam STATE_INT_WAIT = 2'd2;
|
||||
localparam STATE_IO_WAIT = 2'd3;
|
||||
|
||||
reg [1:0] state; // fdc busy state
|
||||
|
||||
// the fdc registers
|
||||
reg [7:0] cmd; // write only
|
||||
reg [7:0] track;
|
||||
reg [7:0] sector;
|
||||
reg [7:0] data;
|
||||
|
||||
// fdc status as reported to the io controller
|
||||
assign status_byte =
|
||||
(status_sel == 0)?cmd:
|
||||
(status_sel == 1)?track:
|
||||
(status_sel == 2)?sector:
|
||||
(status_sel == 3)?data:
|
||||
(status_sel == 4)?{ 4'b0000, drv_sel, drv_side, state == STATE_IO_WAIT }:
|
||||
8'h00;
|
||||
|
||||
reg step_dir;
|
||||
|
||||
reg [31:0] delay;
|
||||
|
||||
wire cmd_type_1 = (cmd[7] == 1'b0);
|
||||
wire cmd_type_2 = (cmd[7:6] == 2'b10);
|
||||
|
||||
// ---------------- floppy motor simulation -------------
|
||||
|
||||
// timer to simulate motor-on. This runs for x/8000000 seconds after each command
|
||||
reg motor_start;
|
||||
reg [31:0] motor_on_counter;
|
||||
wire motor_on = (motor_on_counter != 0);
|
||||
|
||||
// motor_on_counter > 16000000 means the motor is spinning up
|
||||
wire motor_spin_up_done = motor_on && (motor_on_counter <= 16000000);
|
||||
|
||||
always @(posedge clk or posedge motor_start) begin
|
||||
if(motor_start)
|
||||
// motor runs for 2 seconds if it was already on. it rus for one
|
||||
// more second if if wasn't on yet (spin up)
|
||||
motor_on_counter <= motor_on?32'd16000000:32'd24000000;
|
||||
else begin
|
||||
// let "motor" run
|
||||
if(motor_on_counter != 0)
|
||||
motor_on_counter <= motor_on_counter - 32'd1;
|
||||
end
|
||||
end
|
||||
|
||||
// -------------- index pulse generation ----------------
|
||||
|
||||
// floppy rotates at 300rpm = 5rps -> generate 5 index pulses per second
|
||||
wire index_pulse = index_pulse_cnt > 32'd1500000; // 1/16 rotation
|
||||
reg [31:0] index_pulse_cnt;
|
||||
always @(posedge clk) begin
|
||||
if(!motor_on)
|
||||
index_pulse_cnt <= 32'd0;
|
||||
else begin
|
||||
if(index_pulse_cnt != 0)
|
||||
index_pulse_cnt <= index_pulse_cnt - 32'd1;
|
||||
else
|
||||
index_pulse_cnt <= 32'd1600000; // 8000000/5
|
||||
end
|
||||
end
|
||||
|
||||
// status byte returned by the fdc when reading register 0
|
||||
wire [7:0] status = {
|
||||
motor_on,
|
||||
wr_prot,
|
||||
cmd_type_1?motor_spin_up_done:1'b0,
|
||||
2'b00 /* track not found/crc err */,
|
||||
cmd_type_1?(track == 0):1'b0,
|
||||
cmd_type_1?index_pulse:(state!=STATE_IDLE),
|
||||
state != STATE_IDLE
|
||||
};
|
||||
|
||||
// CPU register read
|
||||
always @(cpu_sel, cpu_addr, cpu_rw) begin
|
||||
cpu_dout = 8'h00;
|
||||
|
||||
if(cpu_sel && cpu_rw) begin
|
||||
case(cpu_addr)
|
||||
0: cpu_dout = status;
|
||||
1: cpu_dout = track;
|
||||
2: cpu_dout = sector;
|
||||
3: cpu_dout = data;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// CPU register write
|
||||
always @(negedge clk or posedge reset) begin
|
||||
if(reset) begin
|
||||
// clear internal registers
|
||||
cmd <= 8'h00;
|
||||
track <= 8'h00;
|
||||
sector <= 8'h00;
|
||||
data <= 8'h00;
|
||||
|
||||
// reset state machines and counters
|
||||
state <= STATE_IDLE;
|
||||
irq <= 1'b0;
|
||||
motor_start <= 1'b0;
|
||||
delay <= 32'd0;
|
||||
|
||||
end else begin
|
||||
motor_start <= 1'b0;
|
||||
|
||||
// DMA transfer has been ack'd by io controller
|
||||
if(dma_ack) begin
|
||||
// fdc waiting for io controller
|
||||
if(state == STATE_IO_WAIT)
|
||||
state <= STATE_IRQ; // jump to end of busy phase
|
||||
end
|
||||
|
||||
// fdc may be waiting internally (e.g. for step completion)
|
||||
if(state == STATE_INT_WAIT) begin
|
||||
// count down and go into irq state if done
|
||||
if(delay != 0)
|
||||
delay <= delay - 32'd1;
|
||||
else
|
||||
state <= STATE_IRQ;
|
||||
end
|
||||
|
||||
// fdc is ending busy phase
|
||||
if(state == STATE_IRQ) begin
|
||||
irq <= 1'b1;
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
|
||||
// cpu is reading status register or writing command register -> clear fdc irq
|
||||
if(cpu_sel && (cpu_addr == 0))
|
||||
irq <= 1'b0;
|
||||
|
||||
if(cpu_sel && !cpu_rw) begin
|
||||
// fdc register write
|
||||
if(cpu_addr == 0) begin // command register
|
||||
cmd <= cpu_din;
|
||||
state <= STATE_INT_WAIT;
|
||||
delay <= 31'd0;
|
||||
|
||||
// all TYPE I and TYPE II commands start the motor
|
||||
if((cpu_din[7] == 1'b0) || (cpu_din[7:6] == 2'b10))
|
||||
motor_start <= 1'b1;
|
||||
|
||||
// ------------- TYPE I commands -------------
|
||||
if(cpu_din[7:4] == 4'b0000) begin // RESTORE
|
||||
track <= 8'd0;
|
||||
delay <= 31'd2000000; // 250ms delay
|
||||
end
|
||||
|
||||
if(cpu_din[7:4] == 4'b0001) begin // SEEK
|
||||
track <= data;
|
||||
delay <= 31'd200000; // 25ms delay
|
||||
end
|
||||
|
||||
if(cpu_din[7:3] == 3'b001) begin // STEP
|
||||
delay <= 31'd20000; // 2.5ms delay
|
||||
if(cpu_din[4]) // update flag
|
||||
track <= (step_dir == 1)?(track + 8'd1):(track - 8'd1);
|
||||
end
|
||||
|
||||
if(cpu_din[7:5] == 3'b010) begin // STEP-IN
|
||||
delay <= 31'd20000; // 2.5ms delay
|
||||
step_dir <= 1'b1;
|
||||
if(cpu_din[4]) // update flag
|
||||
track <= track + 8'd1;
|
||||
end
|
||||
|
||||
if(cpu_din[7:5] == 3'b011) begin // STEP-OUT
|
||||
delay <= 31'd20000; // 2.5ms delay
|
||||
step_dir <= 1'b0;
|
||||
if(cpu_din[4]) // update flag
|
||||
track <= track - 8'd1;
|
||||
end
|
||||
|
||||
// ------------- TYPE II commands -------------
|
||||
if(cpu_din[7:5] == 3'b100) begin // read sector
|
||||
state <= STATE_IO_WAIT;
|
||||
end
|
||||
|
||||
if(cpu_din[7:5] == 3'b101) // write sector
|
||||
if(!wr_prot)
|
||||
state <= STATE_IO_WAIT;
|
||||
|
||||
// ------------- TYPE III commands ------------
|
||||
|
||||
if(cpu_din[7:4] == 4'b1100) // read address
|
||||
state <= STATE_IO_WAIT;
|
||||
|
||||
if(cpu_din[7:4] == 4'b1110) // read track
|
||||
state <= STATE_IO_WAIT;
|
||||
|
||||
if(cpu_din[7:4] == 4'b1111) // write track
|
||||
if(!wr_prot)
|
||||
state <= STATE_IO_WAIT;
|
||||
|
||||
// ------------- TYPE IV commands -------------
|
||||
if(cpu_din[7:4] == 4'b1101) begin // force intrerupt
|
||||
if(cpu_din[3:0] == 4'b0000)
|
||||
state <= STATE_IDLE; // immediately
|
||||
else
|
||||
state <= STATE_IRQ; // with irq
|
||||
end
|
||||
end // if (cpu_addr == 0)
|
||||
|
||||
if(cpu_addr == 1) // track register
|
||||
track <= cpu_din;
|
||||
|
||||
if(cpu_addr == 2) // sector register
|
||||
sector <= cpu_din;
|
||||
|
||||
if(cpu_addr == 3) // data register
|
||||
data <= cpu_din;
|
||||
|
||||
end // if (cpu_sel && !cpu_rw)
|
||||
end // else: !if(reset)
|
||||
end // always @ (negedge clk or posedge reset)
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// TODO: Make this truly async
|
||||
// http://www.asic-world.com/examples/verilog/asyn_fifo.html
|
||||
|
||||
module io_fifo #(
|
||||
parameter DATA_WIDTH = 8,
|
||||
parameter DEPTH = 4
|
||||
|
||||
@@ -90,8 +90,10 @@ always @(negedge CLK) begin
|
||||
// then write the data to the appropriate register.
|
||||
if(DAT_WE) begin
|
||||
data <= DAT_I;
|
||||
down_counter <= DAT_I;
|
||||
end
|
||||
// the counter itself is only loaded here if it's stopped
|
||||
if(!started)
|
||||
down_counter <= DAT_I;
|
||||
end
|
||||
|
||||
if(CTRL_WE) begin
|
||||
control <= CTRL_I[3:0];
|
||||
|
||||
@@ -327,7 +327,8 @@ 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 fdc.v
|
||||
set_global_assignment -name VERILOG_FILE acsi.v
|
||||
set_global_assignment -name VERILOG_FILE mfp.v
|
||||
set_global_assignment -name VERILOG_FILE dma.v
|
||||
set_global_assignment -name VERILOG_FILE sigma_delta_dac.v
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/********************************************/
|
||||
/* */
|
||||
/********************************************/
|
||||
|
||||
|
||||
module mist_top (
|
||||
// clock inputsxque
|
||||
input wire [ 2-1:0] CLOCK_27, // 27 MHz
|
||||
@@ -130,8 +130,8 @@ always @(posedge clk_32 or posedge berr_reset) begin
|
||||
end
|
||||
|
||||
// no tristate busses exist inside the FPGA. so bus request doesn't do
|
||||
// much more than halting the cpu by suppressing dtack
|
||||
wire br = data_io_br || blitter_br; // dma/blitter are only other bus masters
|
||||
// much more than halting the cpu by suppressing
|
||||
wire br = dma_br || blitter_br; // dma/blitter are only other bus masters
|
||||
|
||||
// request interrupt ack from mfp for IPL == 6. This must not be done by
|
||||
// combinatorics as it must be glitch free since the mfp does things on the
|
||||
@@ -172,8 +172,11 @@ wire rom_sel_all = ethernec_present && cpu_cycle && tg68_as && tg68_rw && ({tg68
|
||||
wire [1:0] rom_sel = { rom_sel_all && tg68_adr[16], rom_sel_all && !tg68_adr[16] };
|
||||
wire [15:0] rom_data_out;
|
||||
|
||||
// mmu 8 bit interface at $ff8000 - $ff8001
|
||||
wire mmu_sel = io_sel && ({tg68_adr[15:1], 1'd0} == 16'h8000);
|
||||
// mmu 8 bit interface at $ff8000 - $ff800d
|
||||
wire mmu_sel = io_sel &&
|
||||
(({tg68_adr[15:3], 3'd0} == 16'h8000) || // ff8000-ff8007
|
||||
({tg68_adr[15:2], 2'd0} == 16'h8008) || // ff8008-ff800b
|
||||
({tg68_adr[15:1], 1'd0} == 16'h800c)); // ff800c-ff800d
|
||||
wire [7:0] mmu_data_out;
|
||||
|
||||
// mega ste cache controller 8 bit interface at $ff8e20 - $ff8e21
|
||||
@@ -185,8 +188,14 @@ wire [7:0] mste_ctrl_data_out;
|
||||
// (requierd to enable Mega STE cpu speed/cache control)
|
||||
wire vme_sel = !steroids && mste && io_sel && ({tg68_adr[15:4], 4'd0} == 16'h8e00);
|
||||
|
||||
// video controller 16 bit interface at $ff8200 - $ff827f
|
||||
wire vreg_sel = io_sel && ({tg68_adr[15:7], 7'd0} == 16'h8200);
|
||||
// shifter 16 bit interface at $ff8200 - $ff820d and $ff8240 - $ff827f
|
||||
// STE shifter also has registers at ff820f and ff8265
|
||||
wire vreg_sel = io_sel && (
|
||||
({tg68_adr[15:3], 3'd0} == 16'h8200) || // ff8200-ff8207
|
||||
({tg68_adr[15:2], 2'd0} == 16'h8208) || // ff8208-ff820b
|
||||
({tg68_adr[15:1], 1'd0} == 16'h820c) || // ff820c-ff820d
|
||||
(({tg68_adr[15:1], 1'd0} == 16'h820e) && ste) || // ff820e-ff820f (STE)
|
||||
({tg68_adr[15:6], 6'd0} == 16'h8240)); // ff8240-ff827f
|
||||
wire [15:0] vreg_data_out;
|
||||
|
||||
// ste joystick 16 bit interface at $ff9200 - $ff923f
|
||||
@@ -197,24 +206,29 @@ wire [15:0] ste_joy_data_out;
|
||||
wire ste_dma_snd_sel = ste && io_sel && ({tg68_adr[15:6], 6'd0} == 16'h8900);
|
||||
wire [15:0] ste_dma_snd_data_out;
|
||||
|
||||
// mfp 8 bit interface at $fffa00 - $fffa3f
|
||||
wire mfp_sel = io_sel && ({tg68_adr[15:6], 6'd0} == 16'hfa00);
|
||||
// mfp 8 bit interface at $fffa00 - $fffa3f, odd byte and word only
|
||||
wire mfp_sel = io_sel && (tg68_lds == 1'd0) && ({tg68_adr[15:6], 6'd0} == 16'hfa00);
|
||||
wire [7:0] mfp_data_out;
|
||||
|
||||
// acia 8 bit interface at $fffc00 - $fffc07
|
||||
wire acia_sel = io_sel && ({tg68_adr[15:8], 8'd0} == 16'hfc00);
|
||||
// acia 8 bit interface at $fffc00 - $fffdff
|
||||
wire acia_sel = io_sel && ({tg68_adr[15:9], 9'd0} == 16'hfc00); // fffc00-fffdff
|
||||
wire [7:0] acia_data_out;
|
||||
|
||||
// blitter 16 bit interface at $ff8a00 - $ff8a3f, STE always has a blitter
|
||||
wire blitter_sel = (system_ctrl[19] || ste) && io_sel && ({tg68_adr[15:8], 8'd0} == 16'h8a00);
|
||||
wire blitter_sel = (system_ctrl[19] || ste) && io_sel && ({tg68_adr[15:6], 6'd0} == 16'h8a00);
|
||||
wire [15:0] blitter_data_out;
|
||||
|
||||
// psg 8 bit interface at $ff8800 - $ff8803
|
||||
// psg 8 bit interface at $ff8800 - $ff88ff
|
||||
wire psg_sel = io_sel && ({tg68_adr[15:8], 8'd0} == 16'h8800);
|
||||
wire [7:0] psg_data_out;
|
||||
|
||||
// dma 16 bit interface at $ff8600 - $ff860f
|
||||
wire dma_sel = io_sel && ({tg68_adr[15:4], 4'd0} == 16'h8600);
|
||||
// dma 16 bit interface at $ff8604 - $ff8607 (word only) and $ff8606 - $ff860d (STE - ff860f)
|
||||
wire word_access = (tg68_uds == 1'd0) && (tg68_lds == 1'd0);
|
||||
wire dma_sel = io_sel && (
|
||||
(({tg68_adr[15:2], 2'd0} == 16'h8604) && word_access) || // ff8604-ff8607 word only
|
||||
({tg68_adr[15:2], 2'd0} == 16'h8608) || // ff8608-ff860b
|
||||
({tg68_adr[15:1], 1'd0} == 16'h860c) || // ff860c-ff860d
|
||||
(({tg68_adr[15:1], 1'd0} == 16'h860e) && ste)); // ff860e-ff860f (hdmode, STE)
|
||||
wire [15:0] dma_data_out;
|
||||
|
||||
// de-multiplex the various io data output ports into one
|
||||
@@ -288,7 +302,6 @@ wire [5:0] shifter_r, shifter_g, shifter_b;
|
||||
|
||||
video video (
|
||||
.clk (clk_32 ),
|
||||
.clk27 (CLOCK_27[0]),
|
||||
.bus_cycle (bus_cycle ),
|
||||
|
||||
// spi for OSD
|
||||
@@ -464,7 +477,7 @@ blitter blitter (
|
||||
.bm_read (blitter_master_read),
|
||||
.bm_data_in (ram_data_out),
|
||||
|
||||
.br_in (data_io_br ),
|
||||
.br_in (dma_br ),
|
||||
.br_out (blitter_br ),
|
||||
.bg (blitter_bg ),
|
||||
.irq (blitter_irq ),
|
||||
@@ -636,39 +649,53 @@ YM2149 ym2149 (
|
||||
.CLK8 ( clk_8 ) // 8 MHz CPU bus clock
|
||||
);
|
||||
|
||||
wire dma_dio_ack;
|
||||
wire [4:0] dma_dio_idx;
|
||||
wire [7:0] dma_dio_data;
|
||||
|
||||
// floppy_sel is active low
|
||||
wire wr_prot = (floppy_sel == 2'b01)?system_ctrl[7]:system_ctrl[6];
|
||||
wire [22:0] dma_addr;
|
||||
wire [15:0] dma_dout;
|
||||
wire dma_write, dma_read;
|
||||
wire dma_br;
|
||||
|
||||
dma dma (
|
||||
// system interface
|
||||
.clk (clk_8 ),
|
||||
.reset (reset ),
|
||||
.bus_cycle (bus_cycle ),
|
||||
.irq (dma_irq ),
|
||||
.turbo (1'b0 ),
|
||||
|
||||
.ctrl_out (system_ctrl ),
|
||||
.video_adj (video_adj ),
|
||||
|
||||
// spi
|
||||
.sdi (SPI_DI ),
|
||||
.sck (SPI_SCK ),
|
||||
.ss (SPI_SS2 ),
|
||||
.sdo (dma_sdo ),
|
||||
|
||||
// cpu interface
|
||||
.clk (clk_8 ),
|
||||
.reset (reset ),
|
||||
.din (tg68_dat_out[15:0]),
|
||||
.sel (dma_sel ),
|
||||
.addr (tg68_adr[3:1]),
|
||||
.uds (tg68_uds ),
|
||||
.lds (tg68_lds ),
|
||||
.rw (tg68_rw ),
|
||||
.dout (dma_data_out),
|
||||
.cpu_din (tg68_dat_out[15:0]),
|
||||
.cpu_sel (dma_sel ),
|
||||
.cpu_addr (tg68_adr[3:1]),
|
||||
.cpu_uds (tg68_uds ),
|
||||
.cpu_lds (tg68_lds ),
|
||||
.cpu_rw (tg68_rw ),
|
||||
.cpu_dout (dma_data_out),
|
||||
|
||||
.irq (dma_irq ),
|
||||
|
||||
// system control interface
|
||||
// additional signals for floppy/acsi interface
|
||||
.fdc_wr_prot (wr_prot),
|
||||
.acsi_enable (system_ctrl[17:10]),
|
||||
|
||||
// data_io (arm controller imterface)
|
||||
.dio_idx (dma_dio_idx ),
|
||||
.dio_data (dma_dio_data),
|
||||
.dio_ack (dma_dio_ack ),
|
||||
|
||||
// floppy interface
|
||||
.drv_sel (floppy_sel ),
|
||||
.drv_side (floppy_side )
|
||||
.drv_side (floppy_side ),
|
||||
.acsi_enable (system_ctrl[17:10]),
|
||||
|
||||
|
||||
// ram interface
|
||||
.ram_br (dma_br ),
|
||||
.ram_read (dma_read ),
|
||||
.ram_write (dma_write ),
|
||||
.ram_addr (dma_addr ),
|
||||
.ram_dout (dma_dout ),
|
||||
.ram_din (ram_data_out )
|
||||
);
|
||||
|
||||
wire [1:0] floppy_sel;
|
||||
@@ -681,7 +708,7 @@ wire clk_8;
|
||||
wire clk_32;
|
||||
wire clk_128;
|
||||
wire clk_mfp;
|
||||
|
||||
|
||||
// use pll
|
||||
clock clock (
|
||||
.areset (1'b0 ), // async reset input
|
||||
@@ -694,23 +721,9 @@ clock clock (
|
||||
);
|
||||
|
||||
//// 8MHz clock ////
|
||||
reg [3:0] clk_cnt;
|
||||
reg [1:0] clk_cnt;
|
||||
reg [1:0] bus_cycle;
|
||||
|
||||
always @ (posedge clk_32, negedge pll_locked) begin
|
||||
if (!pll_locked) begin
|
||||
clk_cnt <= #1 4'b0010;
|
||||
bus_cycle <= 2'd0;
|
||||
end else begin
|
||||
clk_cnt <= #1 clk_cnt + 4'd1;
|
||||
if(clk_cnt[1:0] == 2'd1) begin
|
||||
bus_cycle <= bus_cycle + 2'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign clk_8 = clk_cnt[1];
|
||||
|
||||
// MFP clock
|
||||
// required: 2.4576 MHz
|
||||
// derived from 27MHZ: 27*74/824 = 2.457525 MHz => 0.003% error
|
||||
@@ -722,6 +735,19 @@ pll_mfp1 pll_mfp1 (
|
||||
.c0 (clk_mfp ) // output clock c0 (2.457627MHz)
|
||||
);
|
||||
|
||||
always @ (posedge clk_32, negedge pll_locked) begin
|
||||
if (!pll_locked) begin
|
||||
clk_cnt <= 2'd2;
|
||||
bus_cycle <= 2'd0;
|
||||
end else begin
|
||||
clk_cnt <= clk_cnt + 2'd1;
|
||||
if(clk_cnt == 2'd1)
|
||||
bus_cycle <= bus_cycle + 2'd1;
|
||||
end
|
||||
end
|
||||
|
||||
assign clk_8 = clk_cnt[1];
|
||||
|
||||
// bus cycle counter for debugging
|
||||
reg [31:0] cycle_counter /* synthesis noprune */;
|
||||
always @ (posedge clk_8) begin
|
||||
@@ -838,14 +864,19 @@ always @(posedge clk_32)
|
||||
|
||||
// the TG68 core works on the rising clock edge. We thus prepare everything
|
||||
// on the falling clock edge
|
||||
reg brD;
|
||||
always @(negedge clk_32) begin
|
||||
brD <= br; // delay bus request by one cycle. This only has an effect in
|
||||
// STEroids mode as otherwise br changes in those cycles not used by
|
||||
// CPU
|
||||
|
||||
// default: cpu does not run
|
||||
clkena <= 1'b0;
|
||||
iCacheStore <= 1'b0;
|
||||
dCacheStore <= 1'b0;
|
||||
cacheUpdate <= 1'b0;
|
||||
|
||||
if(br || reset)
|
||||
if(br || brD || reset)
|
||||
tg68_as <= 1'b0;
|
||||
else begin
|
||||
// run cpu if it owns the bus
|
||||
@@ -1059,7 +1090,7 @@ wire cpu2io = (tg68_adr[23:16] == 8'hff);
|
||||
|
||||
// irq ack happens
|
||||
wire cpu2iack = (tg68_fc == 3'b111);
|
||||
|
||||
|
||||
// generate dtack (for st ram and rom on read, no dtack for rom write)
|
||||
assign tg68_dtack = ((cpu2mem && cpu_cycle && tg68_as) || io_dtack ) && !br;
|
||||
|
||||
@@ -1067,6 +1098,9 @@ assign tg68_dtack = ((cpu2mem && cpu_cycle && tg68_as) || io_dtack ) && !br;
|
||||
/* ------------------------------- bus multiplexer ------------------------------ */
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
|
||||
wire dma_has_bus = dma_br;
|
||||
wire blitter_has_bus = blitter_br;
|
||||
|
||||
// singnal indicating if cpu should use a second cpu slot for 16Mhz like operation
|
||||
// steroids (STEroid) always runs at max speed
|
||||
wire second_cpu_slot = (mste && enable_16mhz) || steroids;
|
||||
@@ -1079,27 +1113,27 @@ 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] cpu_cycle_addr = dma_has_bus?dma_addr:(blitter_has_bus?blitter_master_addr:tg68_adr[23:1]);
|
||||
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 cpu_cycle_oe = dma_has_bus?dma_read:(blitter_has_bus?blitter_master_read:(cpu_cycle && tg68_as && tg68_rw && cpu2mem));
|
||||
wire ram_oe = viking_cycle?viking_read:(video_cycle?video_cycle_oe:(cpu_cycle?cpu_cycle_oe:1'b0));
|
||||
|
||||
// ----------------- RAM write -----------------
|
||||
wire cpu_cycle_wr = data_io_br?data_io_write:(blitter_br?blitter_master_write:(cpu_cycle && tg68_as && ~tg68_rw && cpu2ram));
|
||||
wire cpu_cycle_wr = dma_has_bus?dma_write:(blitter_has_bus?blitter_master_write:(cpu_cycle && tg68_as && ~tg68_rw && cpu2ram));
|
||||
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;
|
||||
wire [15:0] ram_data_in = data_io_br?data_io_dout:(blitter_br?blitter_master_data_out:tg68_dat_out);
|
||||
wire [15:0] ram_data_in = dma_has_bus?dma_dout:(blitter_has_bus?blitter_master_data_out:tg68_dat_out);
|
||||
|
||||
// data strobe
|
||||
wire ram_uds = video_cycle?1'b1:((blitter_br||data_io_br)?1'b1:~tg68_uds);
|
||||
wire ram_lds = video_cycle?1'b1:((blitter_br||data_io_br)?1'b1:~tg68_lds);
|
||||
wire ram_uds = video_cycle?1'b1:((br && brD)?1'b1:~tg68_uds);
|
||||
wire ram_lds = video_cycle?1'b1:((br && brD)?1'b1:~tg68_lds);
|
||||
|
||||
// sdram controller has 64 bit output
|
||||
wire [63:0] ram_data_out_64;
|
||||
@@ -1143,11 +1177,11 @@ sdram sdram (
|
||||
// multiplex spi_do, drive it from user_io if that's selected, drive
|
||||
// it from minimig if it's selected and leave it open else (also
|
||||
// to be able to monitor sd card data directly)
|
||||
wire data_io_sdo;
|
||||
wire dma_sdo;
|
||||
wire user_io_sdo;
|
||||
|
||||
assign SPI_DO = (CONF_DATA0 == 1'b0)?user_io_sdo:
|
||||
((SPI_SS2 == 1'b0)?data_io_sdo:1'bZ);
|
||||
((SPI_SS2 == 1'b0)?dma_sdo:1'bZ);
|
||||
|
||||
wire [31:0] system_ctrl;
|
||||
|
||||
@@ -1241,40 +1275,6 @@ user_io user_io(
|
||||
.CORE_TYPE (8'ha3) // mist core id
|
||||
);
|
||||
|
||||
wire [22:0] data_io_addr;
|
||||
wire [15:0] data_io_dout;
|
||||
wire data_io_write, data_io_read;
|
||||
wire data_io_br;
|
||||
|
||||
data_io data_io (
|
||||
// system control
|
||||
.clk_8 (clk_8 ),
|
||||
.reset (init ),
|
||||
.bus_cycle (bus_cycle ),
|
||||
.ctrl_out (system_ctrl ),
|
||||
|
||||
// spi
|
||||
.sdi (SPI_DI ),
|
||||
.sck (SPI_SCK ),
|
||||
.ss (SPI_SS2 ),
|
||||
.sdo (data_io_sdo ),
|
||||
|
||||
.video_adj (video_adj ),
|
||||
|
||||
// dma status interface
|
||||
.dma_idx (dma_dio_idx ),
|
||||
.dma_data (dma_dio_data ),
|
||||
.dma_ack (dma_dio_ack ),
|
||||
.br (data_io_br ),
|
||||
|
||||
// ram interface
|
||||
.read (data_io_read ),
|
||||
.write (data_io_write ),
|
||||
.addr (data_io_addr ),
|
||||
.data_out (data_io_dout ),
|
||||
.data_in (ram_data_out )
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// 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
|
||||
|
||||
@@ -61,19 +61,19 @@ module user_io(
|
||||
wire [7:0] spi_sck_D = { spi_sck_D[6:0], SPI_CLK } /* synthesis keep */;
|
||||
wire spi_sck = (spi_sck && spi_sck_D != 8'h00) || (!spi_sck && spi_sck_D == 8'hff);
|
||||
|
||||
reg [1:0] byte_cnt;
|
||||
reg [6:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [3:0] bit_cnt; // 0..15
|
||||
reg [3:0] but_sw;
|
||||
reg [1:0] byte_cnt;
|
||||
reg [6:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [3:0] bit_cnt; // 0..15
|
||||
reg [3:0] but_sw;
|
||||
|
||||
// counter runs 0..7,8..15,8..15,8..15
|
||||
wire [2:0] tx_bit = ~(bit_cnt[2:0]);
|
||||
// counter runs 0..7,8..15,8..15,8..15
|
||||
wire [2:0] tx_bit = ~(bit_cnt[2:0]);
|
||||
|
||||
assign BUTTONS = but_sw[1:0];
|
||||
assign SWITCHES = but_sw[3:2];
|
||||
assign BUTTONS = but_sw[1:0];
|
||||
assign SWITCHES = but_sw[3:2];
|
||||
|
||||
always@(negedge spi_sck) begin
|
||||
always@(negedge spi_sck) begin
|
||||
if(bit_cnt <= 7)
|
||||
SPI_MISO <= CORE_TYPE[7-bit_cnt];
|
||||
else begin
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
module video (
|
||||
// system interface
|
||||
input clk, // 31.875 MHz
|
||||
input clk27, // 27.000 Mhz
|
||||
input [1:0] bus_cycle, // bus-cycle for sync
|
||||
|
||||
// SPI interface for OSD
|
||||
|
||||
Reference in New Issue
Block a user