1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-01-26 20:01:48 +00:00

Bus error adjustments

This commit is contained in:
harbaum
2013-05-05 17:57:01 +00:00
parent 3a326af786
commit 6f616c6b50
3 changed files with 93 additions and 51 deletions

View File

@@ -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";

View File

@@ -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

View File

@@ -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;