From c523161f492943cedce8ee3c90a29a05d8f8270d Mon Sep 17 00:00:00 2001 From: harbaum Date: Mon, 9 Sep 2013 18:17:52 +0000 Subject: [PATCH] Minor ikbd, mfp and acia fixes ... --- cores/mist/TG68K.vhd | 2 +- cores/mist/acia.v | 51 ++++++++++++++++++++++----------- cores/mist/mfp.v | 65 +++++++++++++++++++++---------------------- cores/mist/mist_top.v | 5 ++-- cores/mist/user_io.v | 2 +- cores/mist/video.v | 40 +++++++++++++------------- 6 files changed, 88 insertions(+), 77 deletions(-) diff --git a/cores/mist/TG68K.vhd b/cores/mist/TG68K.vhd index b5dacda..37ea9e9 100644 --- a/cores/mist/TG68K.vhd +++ b/cores/mist/TG68K.vhd @@ -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); diff --git a/cores/mist/acia.v b/cores/mist/acia.v index 515be2f..7cf60eb 100644 --- a/cores/mist/acia.v +++ b/cores/mist/acia.v @@ -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 diff --git a/cores/mist/mfp.v b/cores/mist/mfp.v index 5a2ae99..79a7d7f 100644 --- a/cores/mist/mfp.v +++ b/cores/mist/mfp.v @@ -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; diff --git a/cores/mist/mist_top.v b/cores/mist/mist_top.v index bbc3bde..4aab94a 100644 --- a/cores/mist/mist_top.v +++ b/cores/mist/mist_top.v @@ -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; diff --git a/cores/mist/user_io.v b/cores/mist/user_io.v index d31b893..37e27ed 100644 --- a/cores/mist/user_io.v +++ b/cores/mist/user_io.v @@ -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 diff --git a/cores/mist/video.v b/cores/mist/video.v index f647982..b51dfb0 100644 --- a/cores/mist/video.v +++ b/cores/mist/video.v @@ -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