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:
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user