mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-02-12 18:47:03 +00:00
Minor ikbd, mfp and acia fixes ...
This commit is contained in:
@@ -278,7 +278,7 @@ pf68K_Kernel_inst: TG68KdotC_Kernel
|
||||
END IF;
|
||||
IF rising_edge(clk) THEN
|
||||
IF clkena='1' THEN
|
||||
slower <= "0111";
|
||||
slower <= "1111";
|
||||
ELSE
|
||||
slower(3 downto 0) <= '0'&slower(3 downto 1); -- enaWRreg&slower(3 downto 1);
|
||||
-- slower(0) <= NOT slower(3) AND NOT slower(2);
|
||||
|
||||
@@ -26,10 +26,11 @@ module acia (
|
||||
localparam FIFO_ADDR_BITS = 4;
|
||||
localparam FIFO_DEPTH = (1 << FIFO_ADDR_BITS);
|
||||
|
||||
// input FIFO to store ikbd bytes received from IO controller
|
||||
reg [7:0] fifoIn [FIFO_DEPTH-1:0];
|
||||
reg [FIFO_ADDR_BITS-1:0] writePin, readPin;
|
||||
|
||||
//
|
||||
// output FIFO to store ikbd bytes to be sent to IO controller
|
||||
reg [7:0] fifoOut [FIFO_DEPTH-1:0];
|
||||
reg [FIFO_ADDR_BITS-1:0] writePout, readPout;
|
||||
|
||||
@@ -44,10 +45,13 @@ reg midi_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)
|
||||
if(reset) begin
|
||||
readTimer <= 14'd0;
|
||||
else
|
||||
ikbd_rx_counter <= 16'd0;
|
||||
end else
|
||||
if(readTimer > 0)
|
||||
readTimer <= readTimer - 14'd1;
|
||||
|
||||
@@ -55,22 +59,30 @@ always @(negedge clk) begin
|
||||
ikbd_strobe_inD2 <= ikbd_strobe_inD;
|
||||
|
||||
// read on ikbd data register
|
||||
if(sel && ~ds && rw && (addr == 2'd1))
|
||||
ikbd_cpu_data_read <= 1'b0;
|
||||
if(sel && ~ds && rw && (addr == 2'd1)) begin
|
||||
ikbd_cpu_data_read <= 1'b1;
|
||||
else
|
||||
ikbd_cpu_data_read <= 1'b0;
|
||||
ikbd_rx_counter <= ikbd_rx_counter + 16'd1;
|
||||
end
|
||||
|
||||
// read on midi data register
|
||||
// read on midi data register
|
||||
midi_cpu_data_read <= 1'b0;
|
||||
if(sel && ~ds && rw && (addr == 2'd3))
|
||||
midi_cpu_data_read <= 1'b1;
|
||||
else
|
||||
midi_cpu_data_read <= 1'b0;
|
||||
|
||||
if(reset) begin
|
||||
// reset read and write counters
|
||||
readPin <= 4'd0;
|
||||
writePin <= 4'd0;
|
||||
end else begin
|
||||
|
||||
// ikbd acia master reset
|
||||
if(ikbd_cr[1:0] == 2'b11) begin
|
||||
readPin <= 4'd0;
|
||||
writePin <= 4'd0;
|
||||
end
|
||||
|
||||
// store bytes received from IO controller via SPI
|
||||
if(ikbd_strobe_inD && !ikbd_strobe_inD2) begin
|
||||
// store data in fifo
|
||||
fifoIn[writePin] <= ikbd_data_in;
|
||||
@@ -98,6 +110,8 @@ wire [7:0] ikbd_rx_data = fifoIn[readPin];
|
||||
wire ikbd_rx_data_available;
|
||||
assign ikbd_rx_data_available = (readPin != writePin) && (readTimer == 0);
|
||||
|
||||
// in a real ST the irqs are active low open collector outputs and are simply wired
|
||||
// tegether ("wired or")
|
||||
assign irq = ikbd_irq || midi_irq;
|
||||
|
||||
assign ikbd_data_out_available = (readPout != writePout);
|
||||
@@ -115,7 +129,7 @@ always @(posedge clk) begin
|
||||
if(ikbd_strobe_outD && !ikbd_strobe_outD2)
|
||||
readPout <= readPout + 4'd1;
|
||||
end
|
||||
|
||||
|
||||
always @(sel, ds, rw, addr, ikbd_rx_data_available, ikbd_rx_data, ikbd_irq,
|
||||
midi_rx_data, midi_rx_data_available, midi_tx_empty, midi_irq) begin
|
||||
dout = 8'h00;
|
||||
@@ -134,7 +148,6 @@ end
|
||||
// ------------------------------ MIDI UART ---------------------------------
|
||||
wire midi_irq = (midi_cr[7] && midi_rx_data_available) || // rx irq
|
||||
((midi_cr[6:5] == 2'b01) && midi_tx_empty); // tx irq
|
||||
// midi_tx_irq;
|
||||
|
||||
// MIDI runs at 31250bit/s which is exactly 1/256 of the 8Mhz system clock
|
||||
|
||||
@@ -144,7 +157,7 @@ always @(posedge clk)
|
||||
midi_clk <= midi_clk + 8'd1;
|
||||
|
||||
// --------------------------- midi receiver -----------------------------
|
||||
reg [7:0] midi_rx_cnt; // bit + sub-bit cointer
|
||||
reg [7:0] midi_rx_cnt; // bit + sub-bit counter
|
||||
reg [9: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
|
||||
@@ -160,6 +173,13 @@ always @(negedge clk) begin
|
||||
if(midi_cpu_data_read)
|
||||
midi_rx_data_available <= 1'b0; // read on midi data clears rx status
|
||||
|
||||
// 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;
|
||||
end
|
||||
|
||||
// 1/16 system clock == 16 times midi clock
|
||||
if(midi_clk[3:0] == 4'd0) begin
|
||||
midi_rx_filter <= { midi_rx_filter[2:0], midi_in};
|
||||
@@ -228,17 +248,14 @@ always @(negedge clk) begin
|
||||
midi_tx_data_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if(reset) begin
|
||||
|
||||
if(reset) begin
|
||||
midi_reg_data_cnt <= 8'd0;
|
||||
midi_reg_ctrl_cnt <= 8'd0;
|
||||
|
||||
writePout <= 4'd0;
|
||||
midi_tx_cnt <= 8'd0;
|
||||
midi_tx_data_valid <= 1'b0;
|
||||
|
||||
ikbd_cr <= 8'h00;
|
||||
midi_cr <= 8'h00;
|
||||
end else begin
|
||||
if(sel && ~ds && ~rw) begin
|
||||
|
||||
|
||||
@@ -143,13 +143,11 @@ reg [7:0] vr;
|
||||
assign irq = ((ipr & imr) != 16'h0000) && (highest_irq_active == highest_irq_pending);
|
||||
|
||||
// handle pending and in service irqs
|
||||
wire [15:0] irq_active_map;
|
||||
assign irq_active_map = (ipr | isr) & imr;
|
||||
wire [15:0] irq_active_map = (ipr | isr) & imr;
|
||||
|
||||
// (i am pretty sure this can be done much more elegant ...)
|
||||
// check the number of the highest active irq
|
||||
wire [3:0] highest_irq_active;
|
||||
assign highest_irq_active=
|
||||
wire [3:0] highest_irq_active=
|
||||
( irq_active_map[15] == 1'b1)?4'd15:
|
||||
((irq_active_map[15:14] == 2'b01)?4'd14:
|
||||
((irq_active_map[15:13] == 3'b001)?4'd13:
|
||||
@@ -168,12 +166,10 @@ assign highest_irq_active=
|
||||
((irq_active_map[15:0] == 16'b000000000000001)?4'd0:
|
||||
4'd0)))))))))))))));
|
||||
|
||||
wire [15:0] irq_pending_map;
|
||||
assign irq_pending_map = ipr & imr;
|
||||
wire [15:0] irq_pending_map = ipr & imr;
|
||||
|
||||
// check the number of the highest pending irq
|
||||
wire [3:0] highest_irq_pending;
|
||||
assign highest_irq_pending =
|
||||
wire [3:0] highest_irq_pending =
|
||||
( irq_pending_map[15] == 1'b1)?4'd15:
|
||||
((irq_pending_map[15:14] == 2'b01)?4'd14:
|
||||
((irq_pending_map[15:13] == 3'b001)?4'd13:
|
||||
@@ -198,9 +194,8 @@ assign highest_irq_pending =
|
||||
wire [7:0] gpip_in;
|
||||
assign gpip_in = { mono_detect, 1'b0, !dma_irq, !acia_irq, !blitter_irq, 3'b000 };
|
||||
|
||||
// gpip as output to the cpu
|
||||
wire [7:0] gpip_cpu_out;
|
||||
assign gpip_cpu_out = (gpip_in & ~ddr) | (gpip & ddr);
|
||||
// gpip as output to the cpu (ddr bit == 1 -> gpip pin is output)
|
||||
wire [7:0] gpip_cpu_out = (gpip_in & ~ddr) | (gpip & ddr);
|
||||
|
||||
// cpu read interface
|
||||
always @(iack, sel, ds, rw, addr, gpip_cpu_out, aer, ddr, ier, ipr, isr, imr,
|
||||
@@ -250,31 +245,35 @@ reg acia_irqD, acia_irqD2;
|
||||
|
||||
reg [7:0] irq_vec;
|
||||
|
||||
reg iackD;
|
||||
always @(posedge clk) begin
|
||||
dma_irqD <= dma_irq;
|
||||
blitter_irqD <= blitter_irq;
|
||||
|
||||
`ifndef CUBHACK
|
||||
acia_irqD <= acia_irq;
|
||||
`endif
|
||||
|
||||
iackD <= iack;
|
||||
|
||||
// the polarity of the irq is negated over a real st.
|
||||
// if(aer[7]) dma_irqD <= dma_irq;
|
||||
// else dma_irqD <= !dma_irq;
|
||||
|
||||
// if(aer[6]) acia_irqD <= acia_irq;
|
||||
// else acia_irqD <= !acia_irq;
|
||||
|
||||
// the pending irq changes in the middle of an iack
|
||||
// phase, so we latch the current vector to keep is stable
|
||||
// phase, so we latch the current vector to keep ist stable
|
||||
// during the entire cpu read
|
||||
irq_vec <= { vr[7:4], highest_irq_pending };
|
||||
end
|
||||
|
||||
reg iackD;
|
||||
always @(negedge clk) begin
|
||||
// ST default for most aer bits is 0 (except I2/CTS)
|
||||
// since the irq polarity is inverted over normal ST
|
||||
// interrupts we'll invert the irq signal if a aer bit
|
||||
// is 1
|
||||
|
||||
if(aer[3]) blitter_irqD <= !blitter_irq;
|
||||
else blitter_irqD <= blitter_irq;
|
||||
|
||||
`ifndef CUBHACK
|
||||
if(aer[4]) acia_irqD <= !acia_irq;
|
||||
else acia_irqD <= acia_irq;
|
||||
`endif
|
||||
|
||||
// the polarity of the irq is negated over a real st.
|
||||
if(aer[5]) dma_irqD <= !dma_irq;
|
||||
else dma_irqD <= dma_irq;
|
||||
|
||||
|
||||
dma_irqD2 <= dma_irqD;
|
||||
blitter_irqD2 <= blitter_irqD;
|
||||
|
||||
@@ -319,14 +318,12 @@ always @(negedge clk) begin
|
||||
`endif
|
||||
|
||||
// ... dma ...
|
||||
if(dma_irqD && !dma_irqD2) begin
|
||||
if(ier[7]) ipr[7] <= 1'b1;
|
||||
end
|
||||
if(dma_irqD && !dma_irqD2 && ier[7])
|
||||
ipr[7] <= 1'b1;
|
||||
|
||||
// ... and blitter
|
||||
if(blitter_irqD && !blitter_irqD2) begin
|
||||
if(ier[3]) ipr[3] <= 1'b1;
|
||||
end
|
||||
if(blitter_irqD && !blitter_irqD2 && ier[3])
|
||||
ipr[3] <= 1'b1;
|
||||
|
||||
if(sel && ~ds && ~rw) begin
|
||||
if(addr == 5'h00) gpip <= din;
|
||||
@@ -335,7 +332,7 @@ always @(negedge clk) begin
|
||||
|
||||
if(addr == 5'h03) begin
|
||||
ier[15:8] <= din;
|
||||
ipr[15:8]<= ipr[15:8] & din; // clear pending interrupts
|
||||
ipr[15:8] <= ipr[15:8] & din; // clear pending interrupts
|
||||
end
|
||||
|
||||
if(addr == 5'h05) ipr[15:8] <= ipr[15:8] & din;
|
||||
|
||||
@@ -464,7 +464,7 @@ wire [2:0] host_state;
|
||||
wire [22:0] host_addr;
|
||||
wire [15:0] host_dataWR;
|
||||
wire [15:0] host_dataRD;
|
||||
|
||||
|
||||
// tg68
|
||||
wire [ 16-1:0] tg68_dat_in;
|
||||
wire [ 16-1:0] tg68_dat_out;
|
||||
@@ -486,8 +486,7 @@ wire tg68_cdma;
|
||||
wire tg68_clds;
|
||||
wire tg68_cuds;
|
||||
|
||||
wire reset;
|
||||
assign reset = system_ctrl[0];
|
||||
wire reset = system_ctrl[0];
|
||||
|
||||
// ------------- generate VBI (IPL = 4) --------------
|
||||
wire vbi_ack;
|
||||
|
||||
@@ -17,7 +17,7 @@ module user_io(
|
||||
// serial data from mfp to io controller
|
||||
output reg serial_strobe_out,
|
||||
input serial_data_out_available,
|
||||
input [7:0] serial_data_out,
|
||||
input [7:0] serial_data_out,
|
||||
|
||||
output [1:0] BUTTONS,
|
||||
output [1:0] SWITCHES
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// http://martin.hinner.info/vga/timing.html
|
||||
// http://www.epanorama.net/faq/vga2rgb/calc.html
|
||||
|
||||
// original atari video timing
|
||||
// original atari video timing
|
||||
// mono color
|
||||
// pclk 32MHz 16/8MHz
|
||||
// hfreq 35.7kHz 15.75kHz
|
||||
@@ -224,39 +224,37 @@ reg [2:0] palette_r[15:0];
|
||||
reg [2:0] palette_g[15:0];
|
||||
reg [2:0] palette_b[15:0];
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// --------------------------- CPU register read -------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
always @(reg_sel, reg_rw, reg_uds, reg_lds, reg_addr, _v_bas_ad, shmode, vaddr, syncmode) begin
|
||||
reg_dout = 16'h0000;
|
||||
|
||||
// read registers
|
||||
if(reg_sel && reg_rw) begin
|
||||
|
||||
if(reg_addr == 6'h00 && ~reg_lds)
|
||||
reg_dout = { 8'h00, _v_bas_ad[22:15]};
|
||||
|
||||
if(reg_addr == 6'h01 && ~reg_lds)
|
||||
reg_dout = { 8'h00, _v_bas_ad[14:7]};
|
||||
|
||||
if(reg_addr == 6'h02 && ~reg_lds)
|
||||
reg_dout = { 8'h00, vaddr[22:15]};
|
||||
// video base register (r/w)
|
||||
if(reg_addr == 6'h00) reg_dout <= { 8'h00, _v_bas_ad[22:15] };
|
||||
if(reg_addr == 6'h01) reg_dout <= { 8'h00, _v_bas_ad[14: 7] };
|
||||
|
||||
if(reg_addr == 6'h03 && ~reg_lds)
|
||||
reg_dout = { 8'h00, vaddr[14:7]};
|
||||
// video address counter (ro on ST)
|
||||
if(reg_addr == 6'h02) reg_dout <= { 8'h00, vaddr[22:15] };
|
||||
if(reg_addr == 6'h03) reg_dout <= { 8'h00, vaddr[14:7 ] };
|
||||
if(reg_addr == 6'h04) reg_dout <= { 8'h00, vaddr[6:0], 1'b0 };
|
||||
|
||||
if(reg_addr == 6'h04 && ~reg_lds)
|
||||
reg_dout = { 8'h00, vaddr[6:0], 1'b0 };
|
||||
|
||||
if(reg_addr == 6'h05 && ~reg_uds)
|
||||
reg_dout = { 6'h00, syncmode, 8'h00};
|
||||
// syncmode register
|
||||
if(reg_addr == 6'h05) reg_dout <= { 6'h00, syncmode, 8'h00 };
|
||||
|
||||
// the color palette registers
|
||||
if(reg_addr >= 6'h20 && reg_addr < 6'h30 ) begin
|
||||
reg_dout[2:0] = palette_b[reg_addr[3:0]];
|
||||
reg_dout[6:4] = palette_g[reg_addr[3:0]];
|
||||
reg_dout[10:8] = palette_r[reg_addr[3:0]];
|
||||
reg_dout[2:0] <= palette_b[reg_addr[3:0]];
|
||||
reg_dout[6:4] <= palette_g[reg_addr[3:0]];
|
||||
reg_dout[10:8] <= palette_r[reg_addr[3:0]];
|
||||
end
|
||||
|
||||
if(reg_addr == 6'h30 && ~reg_uds)
|
||||
reg_dout = { 6'h00, shmode, 8'h00};
|
||||
// shift mode register
|
||||
if(reg_addr == 6'h30) reg_dout <= { 6'h00, shmode, 8'h00 };
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user