From 6f616c6b50f5059c243797667bb258fa727e8015 Mon Sep 17 00:00:00 2001 From: harbaum Date: Sun, 5 May 2013 17:57:01 +0000 Subject: [PATCH] Bus error adjustments --- cores/mist/TG68K.vhd | 17 +++++++---- cores/mist/acia.v | 60 ++++++++++++++++++++++++++++---------- cores/mist/mist_top.v | 67 ++++++++++++++++++++++++------------------- 3 files changed, 93 insertions(+), 51 deletions(-) diff --git a/cores/mist/TG68K.vhd b/cores/mist/TG68K.vhd index c42d0f2..2518ab0 100644 --- a/cores/mist/TG68K.vhd +++ b/cores/mist/TG68K.vhd @@ -62,7 +62,8 @@ entity TG68K is skipFetch : out std_logic; cpuDMA : buffer std_logic; ramlds : out std_logic; - ramuds : out std_logic + ramuds : out std_logic; + turbo : in std_logic:='0' ); end TG68K; @@ -164,8 +165,8 @@ BEGIN -- sel_fast <= '1' when cpuaddr(23 downto 21)="001" OR cpuaddr(23 downto 21)="010" ELSE '0'; --$200000 - $5FFFFF -- sel_fast <= '1' when cpuaddr(23 downto 19)="11111" ELSE '0'; --$F800000;-- - sel_fast <= '0'; -- off --- sel_fast <= '1' when cpuaddr(23 downto 22)="00" AND state/="01" ELSE '0'; --$000000 - $3fffff +-- sel_fast <= '0'; -- off + sel_fast <= '1' when turbo='1' AND cpuaddr(23 downto 22)="00" AND state/="01" ELSE '0'; --$000000 - $3fffff -- sel_fast <= '1' when (cpuaddr(23 downto 22)="00" OR cpuaddr(23 downto 17)="1111110" OR cpuaddr(23 downto 16)="11111110" OR cpuaddr(23 downto 17)="1111101" OR cpuaddr(23 downto 18)="111000") AND state/="01" ELSE '0'; --$000000 - $3fffff ramcs <= (NOT sel_fast) or slower(0);-- OR (state(0) AND NOT state(1)); @@ -295,9 +296,13 @@ PROCESS (clk, reset, state, as_s, as_e, rw_s, rw_e, uds_s, uds_e, lds_s, lds_e) lds <= '1'; ELSE as <= (as_s AND as_e) OR sel_fast; - rw <= rw_s AND rw_e; - uds <= uds_s AND uds_e; - lds <= lds_s AND lds_e; +-- rw <= rw_s AND rw_e; +-- uds <= uds_s AND uds_e; +-- lds <= lds_s AND lds_e; +-- as <= as_s OR sel_fast; + rw <= rw_s; + uds <= uds_s; + lds <= lds_s; END IF; IF reset='0' THEN S_state <= "00"; diff --git a/cores/mist/acia.v b/cores/mist/acia.v index 49cd3b6..1e8c30c 100644 --- a/cores/mist/acia.v +++ b/cores/mist/acia.v @@ -9,6 +9,9 @@ module acia ( input rw, output reg [7:0] dout, output irq, + + output midi_out, + input midi_in, // data from io controller to acia input ikbd_strobe_in, @@ -45,7 +48,7 @@ always @(negedge clk) begin ikbd_strobe_inD <= ikbd_strobe_in; ikbd_strobe_inD2 <= ikbd_strobe_inD; - // read on kbd data register + // read on ikbd data register if(sel && ~ds && rw && (addr == 2'd1)) data_read <= 1'b1; else @@ -57,21 +60,21 @@ always @(negedge clk) begin writePin <= 4'd0; end else begin if(ikbd_strobe_inD && !ikbd_strobe_inD2) begin - // store data in fifo - fifoIn[writePin] <= ikbd_data_in; - writePin <= writePin + 4'd1; + // store data in fifo + fifoIn[writePin] <= ikbd_data_in; + writePin <= writePin + 4'd1; end if(data_read && dataInAvail) begin - readPin <= readPin + 4'd1; + readPin <= readPin + 4'd1; - // 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; - end - end + // 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; + end + end end // ------------------ cpu interface -------------------- @@ -100,7 +103,7 @@ always @(posedge clk) begin readPout <= readPout + 4'd1; end -always @(sel, ds, rw, addr, dataInAvail, rxd) begin +always @(sel, ds, rw, addr, dataInAvail, rxd, midi_tx_empty) begin dout = 8'h00; if(sel && ~ds && rw) begin @@ -109,20 +112,47 @@ always @(sel, ds, rw, addr, dataInAvail, rxd) begin if(addr == 2'd1) dout = rxd; // data // midi acia read - if(addr == 2'd2) dout = 8'h02; // status + if(addr == 2'd2) dout = { 6'b000000, midi_tx_empty, 1'b0} ; // status if(addr == 2'd3) dout = 8'h00; // data end end + +// midi transmitter +assign midi_out = midi_tx_empty ? 1'b1: midi_tx_cnt[0]; +wire midi_tx_empty = (midi_tx_cnt == 4'd0); +reg [7:0] midi_clk; +reg [3:0] midi_tx_cnt; +reg [9:0] midi_tx_data; +// 8MHz/256 = 31250Hz -> MIDI bit rate +always @(posedge clk) + midi_clk <= midi_clk + 8'd1; + always @(negedge clk) begin + if(midi_clk == 8'd0) begin + // shift down one bit, fill with 1 bits + midi_tx_data <= { 1'b1, midi_tx_data[9:1] }; + + // decreae transmit counter + if(midi_tx_cnt != 4'd0) + midi_tx_cnt <= midi_tx_cnt - 4'd1; + end + if(reset) begin - writePout <= 0; + writePout <= 4'd0; + midi_tx_cnt <= 4'd0; end else begin // keyboard acia data register writes into buffer if(sel && ~ds && ~rw && addr == 2'd1) begin fifoOut[writePout] <= din; writePout <= writePout + 4'd1; end + + // write to midi data register + if(sel && ~ds && ~rw && addr == 2'd1) begin + midi_tx_data <= { 1'b1, din, 1'b0 }; // 8N1, lsb first + midi_tx_cnt <= 4'd10; // 10 bits to go + end end end diff --git a/cores/mist/mist_top.v b/cores/mist/mist_top.v index e0c2e9d..c5e728a 100644 --- a/cores/mist/mist_top.v +++ b/cores/mist/mist_top.v @@ -59,11 +59,11 @@ wire io_dtack = vreg_sel || mmu_sel || mfp_sel || mfp_iack || // required to properly detect that a blitter is not present. // a bus error is now generated once no dtack is seen for 63 clock cycles. wire tg68_clr_berr; -wire tg68_berr = (dtack_timeout == 5'd31); // || cpu_write_illegal; +wire tg68_berr = (dtack_timeout == 3'd7); // || cpu_write_illegal; // count bus errors for debugging purposes. we can thus trigger for a // certain bus error -reg [3:0] berr_cnt_out; +reg [3:0] berr_cnt_out /* synthesis noprune */; reg [3:0] berr_cnt; reg berrD; always @(posedge clk_8) begin @@ -81,9 +81,9 @@ always @(posedge clk_8) begin end // the following is just to prevent optimization -assign UART_TX = (berr_cnt_out == 4'd0); +//assign UART_TX = (berr_cnt_out == 4'd0); -wire cpu_write = cpu_cycle && cpu2io && data_strobe && !tg68_rw; +wire cpu_write = cpu_cycle && cpu2io && address_strobe && !tg68_rw; // it's illegal to write to certain memory areas // TODO: Still the write itself would succeed. That must not happen @@ -91,23 +91,25 @@ wire cpu_write_illegal = cpu_write && (tg68_adr[23:3] === 21'd0); // the first two long words $0 and $4 -reg [4:0] dtack_timeout; +reg [2:0] dtack_timeout; always @(posedge clk_8) begin if(reset) begin - dtack_timeout <= 5'd0; + dtack_timeout <= 3'd0; end else begin - // timeout only when cpu owns the bus and when - // neither dtack nor fast ram are active - if(dtack_timeout != 5'd31) begin - if(!tg68_dtack || br || tg68_cpuena) - dtack_timeout <= 5'd0; - else - dtack_timeout <= dtack_timeout + 5'd1; - end else - // leave bus error when next instruction is read + if(cpu_cycle) begin + // timeout only when cpu owns the bus and when + // neither dtack nor fast ram are active + if(dtack_timeout != 3'd7) begin + if(!tg68_dtack || br || tg68_cpuena || tg68_as) + dtack_timeout <= 3'd0; + else + dtack_timeout <= dtack_timeout + 3'd1; + end else + // leave bus error when next instruction is read // if(!tg68_dtack && (tg68_cpustate[1:0] == 2'd3)) - if(tg68_clr_berr) - dtack_timeout <= 1'b0; + if(tg68_clr_berr) + dtack_timeout <= 3'd0; + end end end @@ -118,7 +120,7 @@ wire dma_br; // request interrupt ack from mfp for IPL == 6 wire mfp_iack; -assign mfp_iack = cpu_cycle && cpu2iack && data_strobe && (tg68_adr[3:1] == 3'b110); +assign mfp_iack = cpu_cycle && cpu2iack && address_strobe && (tg68_adr[3:1] == 3'b110); // the tg68k core with the wrapper of the minimig doesn't support non-autovector // interrupts. Also the existing support for them inside the tg68 kernel is/was broken. @@ -126,7 +128,7 @@ assign mfp_iack = cpu_cycle && cpu2iack && data_strobe && (tg68_adr[3:1] == 3'b1 // entirely to non-autovector interrupts. This means that i now have to provide // the vectors for those interrupts that oin the ST are autovector ones. This needs // to be done for IPL2 (hbi) and IPL4 (vbi) -wire auto_iack = cpu_cycle && cpu2iack && data_strobe && +wire auto_iack = cpu_cycle && cpu2iack && address_strobe && ((tg68_adr[3:1] == 3'b100) || (tg68_adr[3:1] == 3'b010)); wire [7:0] auto_vector_vbi = (auto_iack && (tg68_adr[3:1] == 3'b100))?8'h1c:8'h00; wire [7:0] auto_vector_hbi = (auto_iack && (tg68_adr[3:1] == 3'b010))?8'h1a:8'h00; @@ -142,7 +144,7 @@ wire [7:0] auto_vector = auto_vector_vbi | auto_vector_hbi; // $fffffa40 - $fffffa7f - FPU // $fffffc20 - $fffffc3f - RTC -wire io_sel = cpu_cycle && cpu2io && data_strobe ; +wire io_sel = cpu_cycle && cpu2io && address_strobe ; // mmu 8 bit interface at $ff8000 - $ff8801 wire mmu_sel = io_sel && ({tg68_adr[15:1], 1'd0} == 16'h8000); @@ -264,6 +266,10 @@ acia acia ( .dout (acia_data_out), .irq (acia_irq ), + // MIDI interface + .midi_out (UART_TX ), + .midi_in (UART_RX ), + // ikbd interface .ikbd_data_out_available (ikbd_data_from_acia_available), .ikbd_strobe_out (ikbd_strobe_from_acia), @@ -439,7 +445,7 @@ assign reset = system_ctrl[0]; // ------------- generate VBI (IPL = 4) -------------- wire vbi_ack; -assign vbi_ack = cpu2iack && data_strobe && (tg68_adr[3:1] == 3'b100); +assign vbi_ack = cpu2iack && address_strobe && (tg68_adr[3:1] == 3'b100); reg vsD, vsD2, vsI, vbi; always @(negedge clk_8) @@ -457,7 +463,7 @@ end // ------------- generate HBI (IPL = 2) -------------- wire hbi_ack; -assign hbi_ack = cpu2iack && data_strobe && (tg68_adr[3:1] == 3'b010); +assign hbi_ack = cpu2iack && address_strobe && (tg68_adr[3:1] == 3'b010); reg hsD, hsD2, hsI, hbi; always @(negedge clk_8) @@ -522,7 +528,8 @@ TG68K tg68k ( .skipFetch ( ), .cpuDMA (tg68_cdma ), .ramlds (tg68_clds ), - .ramuds (tg68_cuds ) + .ramuds (tg68_cuds ), + .turbo (system_ctrl[18] ) ); // @@ -579,19 +586,19 @@ wire cpu2io = (tg68_adr[23:16] == 8'b11111111); wire cpu2iack = (tg68_adr[23:4] == 20'hfffff); // data strobe! -// wire data_strobe = ~tg68_uds || ~tg68_lds; -reg data_strobe; +// wire address_strobe = ~tg68_uds || ~tg68_lds; +reg address_strobe; always @(posedge clk_8) - data_strobe <= (video_cycle) && (~tg68_uds || ~tg68_lds); + address_strobe <= (video_cycle) && ~tg68_as; // generate dtack (for st ram only and rom), TODO: no dtack for rom write -// assign tg68_dtack = ~(((cpu2mem && data_strobe && cpu_cycle) || io_dtack ) && !br); -assign tg68_dtack = ~(((cpu2mem && data_strobe) || io_dtack ) && !br); +// assign tg68_dtack = ~(((cpu2mem && address_strobe && cpu_cycle) || io_dtack ) && !br); +assign tg68_dtack = ~(((cpu2mem && address_strobe) || io_dtack ) && !br); wire ram_oe = video_cycle?~video_read: - (cpu_cycle?~(data_strobe && tg68_rw && cpu2mem):1'b1); + (cpu_cycle?~(address_strobe && tg68_rw && cpu2mem):1'b1); -wire ram_wr = cpu_cycle?~(data_strobe && ~tg68_rw && cpu2ram):1'b1; +wire ram_wr = cpu_cycle?~(address_strobe && ~tg68_rw && cpu2ram):1'b1; // data strobe wire ram_uds = video_cycle?1'b0:tg68_uds;