diff --git a/cores/mist/TG68K.vhd b/cores/mist/TG68K.vhd index dd2949d..30869f4 100644 --- a/cores/mist/TG68K.vhd +++ b/cores/mist/TG68K.vhd @@ -136,9 +136,6 @@ COMPONENT TG68KdotC_Kernel SIGNAL sync_state3 : std_logic; SIGNAL eind : std_logic; SIGNAL eindd : std_logic; - SIGNAL sel_autoconfig: std_logic; - SIGNAL autoconfig_out: std_logic; - SIGNAL autoconfig_data: std_logic_vector(3 downto 0); SIGNAL sel_fast: std_logic; SIGNAL slower : std_logic_vector(3 downto 0); @@ -156,15 +153,17 @@ BEGIN addr <= cpuaddr;-- WHEN addr_akt_e='1' ELSE t_addr WHEN addr_akt_s='1' ELSE "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; -- data <= data_write WHEN data_akt_e='1' ELSE t_data WHEN data_akt_s='1' ELSE "ZZZZZZZZZZZZZZZZ"; -- datatg68 <= fromram WHEN sel_fast='1' ELSE r_data; - datatg68 <= fromram WHEN sel_fast='1' ELSE r_data WHEN sel_autoconfig='0' ELSE autoconfig_data&r_data(11 downto 0); + datatg68 <= fromram WHEN sel_fast='1' ELSE r_data; -- WHEN sel_autoconfig='0' ELSE autoconfig_data&r_data(11 downto 0); -- toram <= data_write; - sel_autoconfig <= '1' when cpuaddr(23 downto 19)="11101" AND autoconfig_out='1' ELSE '0'; --$E80000 - $EFFFFF --TH sel_fast <= '1' when state/="01" AND (cpuaddr(23 downto 21)="001" OR cpuaddr(23 downto 21)="010" OR cpuaddr(23 downto 21)="011" OR cpuaddr(23 downto 21)="100") ELSE '0'; --$200000 - $9FFFFF -- 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'; --$200000 - $9FFFFF --- sel_fast <= '1' when cpuaddr(24)='1' AND state/="01" ELSE '0'; --$1000000 - $1FFFFFF +-- 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 <= '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)); -- cpuDMA <= NOT ramcs; cpuDMA <= sel_fast; @@ -174,9 +173,9 @@ BEGIN -- ramaddr(23 downto 0) <= cpuaddr(23 downto 0); -- ramaddr(24) <= sel_fast; -- ramaddr(31 downto 25) <= cpuaddr(31 downto 25); - ramaddr(23 downto 0) <= cpuaddr(23) & sel_fast & cpuaddr(21 downto 0); - ramaddr(31 downto 24) <= cpuaddr(31 downto 24); - +--TH ramaddr(23 downto 0) <= cpuaddr(23) & sel_fast & cpuaddr(21 downto 0); +--TH ramaddr(31 downto 24) <= cpuaddr(31 downto 24); + ramaddr <= cpuaddr; pf68K_Kernel_inst: TG68KdotC_Kernel generic map( @@ -208,37 +207,6 @@ pf68K_Kernel_inst: TG68KdotC_Kernel skipFetch => skipFetch -- : out std_logic ); - PROCESS (clk) - BEGIN - autoconfig_data <= "1111"; - IF memcfg(5 downto 4)/="00" THEN - CASE cpuaddr(6 downto 1) IS - WHEN "000000" => autoconfig_data <= "1110"; --normal card, add mem, no ROM - WHEN "000001" => - CASE memcfg(5 downto 4) IS - WHEN "01" => autoconfig_data <= "0110"; --2MB - WHEN "10" => autoconfig_data <= "0111"; --4MB --- WHEN OTHERS => autoconfig_data <= "0000"; --8MB - WHEN OTHERS => autoconfig_data <= "0111"; --4MB - END CASE; - WHEN "001000" => autoconfig_data <= "1110"; --4626=icomp - WHEN "001001" => autoconfig_data <= "1101"; - WHEN "001010" => autoconfig_data <= "1110"; - WHEN "001011" => autoconfig_data <= "1101"; - WHEN "010011" => autoconfig_data <= "1110"; --serial=1 - WHEN OTHERS => null; - END CASE; - END IF; - IF rising_edge(clk) THEN - IF reset='0' THEN - autoconfig_out <= '1'; --autoconfig on - ELSIF enaWRreg='1' THEN - IF sel_autoconfig='1' AND state="11"AND uds_in='0' AND cpuaddr(6 downto 1)="100100" THEN - autoconfig_out <= '0'; --autoconfig off - END IF; - END IF; - END IF; - END PROCESS; PROCESS (clk) BEGIN diff --git a/cores/mist/data_io.v b/cores/mist/data_io.v index ebbfac8..a7a0aee 100644 --- a/cores/mist/data_io.v +++ b/cores/mist/data_io.v @@ -16,6 +16,7 @@ module data_io ( output [4:0] dma_idx, input [7:0] dma_data, output reg dma_ack, + output reg dma_nak, // ram interface output reg [2:0] state, // state bits required to drive the sdram host @@ -45,10 +46,11 @@ assign addr = addrR[22:0] - ((cmd == 2)?23'b1:23'b0); // generate state signals required to control the sdram host interface always @(posedge clk_8) begin - // start io transfers after! bus_cycle 3 and 0 (after the video cycle) - writeD <= write && ((bus_cycle == 3) || writeD); + // start io transfers clock cycles after bus_cycle 0 + // (after the cpu cycle) + writeD <= write && ((bus_cycle == 0) || writeD); writeD2 <= writeD; - readD <= read && ((bus_cycle == 3) || readD); + readD <= read && ((bus_cycle == 0) || readD); readD2 <= readD; if(reset) @@ -91,8 +93,10 @@ always@(posedge sck, posedge ss) begin write <= 1'b0; read <= 1'b0; dma_ack <= 1'b0; + dma_nak <= 1'b0; end else begin dma_ack <= 1'b0; + dma_nak <= 1'b0; sbuf <= { sbuf[13:0], sdi}; // 0:7 is command, 8:15 and 16:23 is payload bytes @@ -112,6 +116,10 @@ always@(posedge sck, posedge ss) begin if({sbuf[6:0], sdi } == 8'd6) dma_ack <= 1'b1; + // send nak + if({sbuf[6:0], sdi } == 8'd7) + dma_nak <= 1'b1; + // if we can see a read coming initiate sdram read transfer asap if({sbuf[6:0], sdi } == 8'd3) read <= 1; diff --git a/cores/mist/dma.v b/cores/mist/dma.v index 276269e..a8a2d3a 100644 --- a/cores/mist/dma.v +++ b/cores/mist/dma.v @@ -22,6 +22,7 @@ module dma ( input [4:0] dio_idx, output reg [7:0] dio_data, input dio_ack, + input dio_nak, // input from psg input drv_side, @@ -155,8 +156,11 @@ reg acsi_irq; wire acsi_status_read = sel && rw && (mode[4:3] == 2'b01); reg dio_ackD, dio_ackD2; -always @(posedge clk) +reg dio_nakD, dio_nakD2; +always @(posedge clk) begin dio_ackD <= dio_ack; + dio_nakD <= dio_nak; +end always @(negedge clk) begin if(reset) begin @@ -178,6 +182,10 @@ always @(negedge clk) begin end else begin // acknowledge comes from io controller // rising edge on ack -> clear busy flag + dio_nakD2 <= dio_nakD; + if(dio_nakD && !dio_nakD2) + br <= 1'b0; // release bus + dio_ackD2 <= dio_ackD; if(dio_ackD && !dio_ackD2) begin br <= 1'b0; // release bus diff --git a/cores/mist/mist_top.v b/cores/mist/mist_top.v index 3b6896b..1a2d593 100644 --- a/cores/mist/mist_top.v +++ b/cores/mist/mist_top.v @@ -59,7 +59,7 @@ 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_berr = (dtack_timeout == 5'd31); // || cpu_write_illegal; - + // count bus errors for debugging purposes. we can thus trigger for a // certain bus error reg [3:0] berr_cnt_out; @@ -92,7 +92,9 @@ always @(posedge clk_8) begin if(reset) begin dtack_timeout <= 5'd0; end else begin - if(!tg68_dtack || br) + // timeout only when cpu owns the bus and when + // neither dtack nor fast ram are active + if(!tg68_dtack || br || tg68_cpuena) dtack_timeout <= 5'd0; else if(dtack_timeout != 5'd31) dtack_timeout <= dtack_timeout + 5'd1; @@ -311,9 +313,9 @@ YM2149 ym2149 ( .CLK ( sclk[1] ) // 2 MHz ); -wire dma_dio_ack; +wire dma_dio_ack, dma_dio_nak; wire [4:0] dma_dio_idx; -wire [7:0 ]dma_dio_data; +wire [7:0] dma_dio_data; // floppy_sel is active low wire wr_prot = (floppy_sel == 2'b01)?system_ctrl[7]:system_ctrl[6]; @@ -341,6 +343,7 @@ dma dma ( .dio_idx (dma_dio_idx ), .dio_data (dma_dio_data), .dio_ack (dma_dio_ack ), + .dio_nak (dma_dio_nak ), // floppy interface .drv_sel (floppy_sel ), @@ -516,13 +519,13 @@ wire [15:0] cpu_data_in; assign cpu_data_in = cpu2mem?ram_data:io_data_out; // cpu/video stram multiplexing -wire video_cycle; -wire cpu_cycle; wire [22:0] ram_address; wire [15:0] ram_data; -assign video_cycle = (bus_cycle[3:2] == 0); // 1 is host/spi cycle -assign cpu_cycle = (bus_cycle[3:2] == 2); +wire video_cycle = (bus_cycle[3:2] == 0); +wire cpu_cycle = (bus_cycle[3:2] == 1); +wire io_cycle = (bus_cycle[3:2] == 2); + assign ram_address = video_cycle?video_address:tg68_adr[23:1]; assign video_data = ram_data; @@ -535,57 +538,49 @@ wire MEM8M = (system_ctrl[3:1] == 3'd4); wire MEM14M = (system_ctrl[3:1] == 3'd5); // ram from 0x000000 to 0x400000 -wire cpu2ram; -assign cpu2ram = (tg68_adr[23:22] == 2'b00) || // ordinary 4MB +wire cpu2ram = (tg68_adr[23:22] == 2'b00) || // ordinary 4MB ((MEM14M || MEM8M) && (tg68_adr[23:22] == 2'b01)) || // MiST special 8MB (MEM14M && ((tg68_adr[23:22] == 2'b10) | (tg68_adr[23:21] == 3'b110))); // MiST special 14MB // 256k tos from 0xe00000 to 0xe40000 -wire cpu2tos256k; -assign cpu2tos256k = (tg68_adr[23:18] == 6'b111000); +wire cpu2tos256k = (tg68_adr[23:18] == 6'b111000); // 192k tos from 0xfc0000 to 0xff0000 -wire cpu2tos192k; -assign cpu2tos192k = (tg68_adr[23:17] == 7'b1111110) || - (tg68_adr[23:16] == 8'b11111110); +wire cpu2tos192k = (tg68_adr[23:17] == 7'b1111110) || + (tg68_adr[23:16] == 8'b11111110); // 128k cartridge from 0xfa0000 to 0xfc0000 -wire cpu2cart; -assign cpu2cart = (tg68_adr[23:17] == 7'b1111101); +wire cpu2cart = (tg68_adr[23:17] == 7'b1111101); // cpu to any type of mem (rw on ram, read on rom) -wire cpu2mem; -assign cpu2mem = cpu2ram || (tg68_rw && (cpu2tos192k || cpu2tos256k || cpu2cart)); +wire cpu2mem = cpu2ram || (tg68_rw && (cpu2tos192k || cpu2tos256k || cpu2cart)); // io from 0xff0000 -wire cpu2io; -assign cpu2io = (tg68_adr[23:16] == 8'b11111111); +wire cpu2io = (tg68_adr[23:16] == 8'b11111111); // irq ack happens on 0xfffffX -wire cpu2iack; -assign cpu2iack = (tg68_adr[23:4] == 20'hfffff); +wire cpu2iack = (tg68_adr[23:4] == 20'hfffff); -wire data_strobe; -assign data_strobe = ~tg68_uds || ~tg68_lds; +// data strobe! +// wire data_strobe = ~tg68_uds || ~tg68_lds; +reg data_strobe; +always @(posedge clk_8) + data_strobe <= (video_cycle) && (~tg68_uds || ~tg68_lds); // 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 && cpu_cycle) || io_dtack ) && !br); +assign tg68_dtack = ~(((cpu2mem && data_strobe) || io_dtack ) && !br); -wire ram_oe; -assign ram_oe = video_cycle?~video_read: +wire ram_oe = video_cycle?~video_read: (cpu_cycle?~(data_strobe && tg68_rw && cpu2mem):1'b1); -wire ram_wr; -assign ram_wr = cpu_cycle?~(data_strobe && ~tg68_rw && cpu2ram):1'b1; +wire ram_wr = cpu_cycle?~(data_strobe && ~tg68_rw && cpu2ram):1'b1; // data strobe -wire ram_uds; -assign ram_uds = video_cycle?1'b0:tg68_uds; - -wire ram_lds; -assign ram_lds = video_cycle?1'b0:tg68_lds; - +wire ram_uds = video_cycle?1'b0:tg68_uds; +wire ram_lds = video_cycle?1'b0:tg68_lds; + //// sdram //// sdram sdram ( .sdata (SDRAM_DQ ), @@ -612,7 +607,7 @@ sdram sdram ( .cpuAddr (tg68_cad[24:1] ), .cpuU (tg68_cuds ), .cpuL (tg68_clds ), - .cpustate (tg68_cpustate ), // 6'b100101 + .cpustate (tg68_cpustate ), .cpu_dma (tg68_cdma ), .cpuRD (tg68_cout ), .cpuena (tg68_cpuena ), @@ -699,6 +694,7 @@ data_io data_io ( .dma_idx (dma_dio_idx ), .dma_data (dma_dio_data ), .dma_ack (dma_dio_ack ), + .dma_nak (dma_dio_nak ), // ram interface .state (host_state ), diff --git a/cores/mist/video.v b/cores/mist/video.v index 845da9b..66cbf74 100644 --- a/cores/mist/video.v +++ b/cores/mist/video.v @@ -301,7 +301,7 @@ wire [9:0] v_offset = mono?10'd0:10'd2; wire de = (hcnt >= H_PRE) && (hcnt < H_ACT+H_PRE) && (vcnt >= v_offset && vcnt < V_ACT+v_offset); // a fake de signal for timer a for color modes with half the hsync frequency -wire deC = (((hcnt >= H_PRE) && !vcnt[0]) || ((hcnt < H_ACT+H_PRE-10'd128) && vcnt[0])) && +wire deC = (((hcnt >= H_PRE) && !vcnt[0]) || ((hcnt < H_ACT+H_PRE-10'd160) && vcnt[0])) && (vcnt >= (v_offset-10'd0) && vcnt < (V_ACT+v_offset-10'd0)); // a fake hsync pulse for the scan doubled color modes @@ -434,9 +434,6 @@ always@(posedge sck, posedge ss) begin end end -// output to video controller -wire osd_oe; // the current pixel overwritten by the OSD - // input from video controller // vcnt (0..399) / hcnt (0..639) @@ -449,16 +446,24 @@ localparam OSD_HEIGHT = 10'd128; // pixels are doubled vertically localparam OSD_POS_X = (H_ACT-OSD_WIDTH)>>1; localparam OSD_POS_Y = (V_ACT-OSD_HEIGHT)>>1; -assign osd_oe = osd_enable && ( +localparam OSD_BORDER = 10'd2; + +wire osd_oe = osd_enable && ( + (hcnt >= OSD_POS_X-OSD_BORDER) && + (hcnt < (OSD_POS_X + OSD_WIDTH + OSD_BORDER)) && + (vcnt >= OSD_POS_Y - OSD_BORDER) && + (vcnt < (OSD_POS_Y + OSD_HEIGHT + OSD_BORDER))); + +wire osd_content_area = (hcnt >= OSD_POS_X) && (hcnt < (OSD_POS_X + OSD_WIDTH)) && (vcnt >= OSD_POS_Y) && - (vcnt < (OSD_POS_Y + OSD_HEIGHT))); + (vcnt < (OSD_POS_Y + OSD_HEIGHT)); wire [7:0] osd_hcnt = hcnt - OSD_POS_X + 7'd1; // one pixel offset for osd_byte register wire [6:0] osd_vcnt = vcnt - OSD_POS_Y; -wire osd_pixel = osd_byte[osd_vcnt[3:1]]; +wire osd_pixel = osd_content_area?osd_byte[osd_vcnt[3:1]]:1'b0; reg [7:0] osd_byte; always @(posedge clk)