From b0e2b401b7d0314516392eb13bc8fe188800330b Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Tue, 3 Mar 2020 12:50:15 +0100 Subject: [PATCH] LodeRunner: move sprites and background tiles to SDRAM --- .../LodeRunner_MiST/LodeRunner_MiST.qsf | 12 +- .../LodeRunner_MiST/meta/Lode Runner.mra | 110 +++++++++++++++ .../LodeRunner_MiST/rtl/Graphics.VHD | 2 +- .../LodeRunner_MiST/rtl/LodeRunner_MiST.sv | 49 +++++-- .../LodeRunner_MiST/rtl/pace.vhd | 22 ++- .../LodeRunner_MiST/rtl/platform.vhd | 127 +++++++++--------- .../LodeRunner_MiST/rtl/sdram.sv | 53 +++++--- .../LodeRunner_MiST/rtl/sprite_array.vhd | 21 ++- .../LodeRunner_MiST/rtl/spritectl.vhd | 44 +++--- .../LodeRunner_MiST/rtl/target_top.vhd | 12 +- 10 files changed, 318 insertions(+), 134 deletions(-) create mode 100644 Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/meta/Lode Runner.mra diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/LodeRunner_MiST.qsf b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/LodeRunner_MiST.qsf index 317e418d..47576d27 100644 --- a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/LodeRunner_MiST.qsf +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/LodeRunner_MiST.qsf @@ -41,7 +41,7 @@ # ======================== set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL -set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26" set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" set_global_assignment -name SMART_RECOMPILE ON set_global_assignment -name SYSTEMVERILOG_FILE rtl/LodeRunner_MiST.sv @@ -77,7 +77,6 @@ set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd set_global_assignment -name VHDL_FILE rtl/cpu68.vhd set_global_assignment -name SYSTEMVERILOG_FILE rtl/YM2149.sv set_global_assignment -name VHDL_FILE rtl/Sound_Board.vhd -set_global_assignment -name VHDL_FILE rtl/roms/ldrun/snd_prg.vhd set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip set_global_assignment -name VHDL_FILE ../../../common/CPU/T80/Z80.vhd @@ -153,7 +152,6 @@ set_location_assignment PIN_66 -to SDRAM_nWE set_location_assignment PIN_59 -to SDRAM_nCS set_location_assignment PIN_33 -to SDRAM_CKE set_location_assignment PIN_43 -to SDRAM_CLK -set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component" # Classic Timing Assignments # ========================== @@ -204,7 +202,7 @@ set_global_assignment -name USE_CONFIGURATION_DEVICE OFF # SignalTap II Assignments # ======================== set_global_assignment -name ENABLE_SIGNALTAP OFF -set_global_assignment -name USE_SIGNALTAP_FILE output_files/mcr3.stp +set_global_assignment -name USE_SIGNALTAP_FILE output_files/sp.stp # Power Estimation Assignments # ============================ @@ -266,10 +264,12 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top - set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top # end DESIGN_PARTITION(Top) # ------------------------- # end ENTITY(LodeRunner_MiST) -# --------------------------- \ No newline at end of file +# --------------------------- +set_global_assignment -name SIGNALTAP_FILE output_files/sp.stp +set_location_assignment PLL_1 -to pll|altpll_component|auto_generated|pll1 +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/meta/Lode Runner.mra b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/meta/Lode Runner.mra new file mode 100644 index 00000000..b961fac9 --- /dev/null +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/meta/Lode Runner.mra @@ -0,0 +1,110 @@ + + Lode Runner + 0216 + ldrun + Irem + iremm62 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FF + + + + + + + + + + + + + FF + + + + + + diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/Graphics.VHD b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/Graphics.VHD index 772c00d1..0f8ce71a 100644 --- a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/Graphics.VHD +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/Graphics.VHD @@ -22,7 +22,7 @@ entity Graphics is sprite_ctl_i : in to_SPRITE_CTL_t; sprite_ctl_o : out from_SPRITE_CTL_t; spr0_hit : out std_logic; - + graphics_i : in to_GRAPHICS_t; graphics_o : out from_GRAPHICS_t; diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/LodeRunner_MiST.sv b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/LodeRunner_MiST.sv index 8ddc3feb..7e15985d 100644 --- a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/LodeRunner_MiST.sv +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/LodeRunner_MiST.sv @@ -30,8 +30,10 @@ module LodeRunner_MiST( `include "rtl/build_id.v" +`define CORE_NAME "LDRUN" + localparam CONF_STR = { - "LDRUNNER;ROM;", + `CORE_NAME,";;", "O2,Rotate Controls,Off,On;", "O34,Scanlines,Off,25%,50%,75%;", "O5,Blending,Off,On;", @@ -98,14 +100,29 @@ user_io( wire [14:0] rom_addr; wire [15:0] rom_do; -wire [16:0] snd_addr; +wire [17:0] snd_addr; wire [13:0] snd_rom_addr; wire [15:0] snd_do; wire snd_vma; +wire [14:0] chr1_addr; +wire [31:0] chr1_do; wire [14:0] sp_addr; wire [31:0] sp_do; +/* ROM structure +00000-1FFFF CPU1 128k +20000-2FFFF CPU2 64k +30000-4FFFF GFX1 128k +50000-8FFFF GFX2 256k + +90000-9FFFF GFX3 64k +A0000-A02FF spr_color_proms 3*256b +A0300-A05FF chr_color_proms 3*256b +A0600-A08FF fg_color_proms 3*256b +A0900-A091F spr_height_prom 32b +*/ + wire ioctl_downl; wire [7:0] ioctl_index; wire ioctl_wr; @@ -124,7 +141,7 @@ data_io data_io( .ioctl_dout ( ioctl_dout ) ); -wire [24:0] sp_ioctl_addr = ioctl_addr - 17'h10000; //todo +wire [24:0] sp_ioctl_addr = ioctl_addr - 20'h30000; reg port1_req, port2_req; sdram sdram( @@ -141,22 +158,24 @@ sdram sdram( .port1_d ( {ioctl_dout, ioctl_dout} ), .port1_q ( ), - .cpu1_addr ( ioctl_downl ? 16'hffff : {2'b00, rom_addr[14:1]} ), + .cpu1_addr ( ioctl_downl ? 17'h1ffff : {3'b000, rom_addr[14:1]} ), .cpu1_q ( rom_do ), - .cpu2_addr ( ioctl_downl ? 16'hffff : snd_addr[16:1] ), + .cpu2_addr ( ioctl_downl ? 17'h1ffff : snd_addr[17:1] ), .cpu2_q ( snd_do ), // port2 for sprite graphics .port2_req ( port2_req ), .port2_ack ( ), - .port2_a ( {sp_ioctl_addr[23:16], sp_ioctl_addr[13:0], sp_ioctl_addr[15]} ), // merge sprite roms to 32-bit wide words - .port2_ds ( {sp_ioctl_addr[14], ~sp_ioctl_addr[14]} ), + .port2_a ( {sp_ioctl_addr[23:15], sp_ioctl_addr[12:0], sp_ioctl_addr[14]} ), // merge sprite roms to 32-bit wide words + .port2_ds ( {sp_ioctl_addr[13], ~sp_ioctl_addr[13]} ), .port2_we ( ioctl_downl ), .port2_d ( {ioctl_dout, ioctl_dout} ), .port2_q ( ), - .sp_addr ( ioctl_downl ? 15'h7fff : sp_addr ), - .sp_q ( sp_do ) + .chr1_addr ( chr1_addr ), + .chr1_q ( chr1_do ), + .sp_addr ( 16'h8000 + sp_addr ), + .sp_q ( sp_do ) ); // ROM download controller @@ -168,13 +187,13 @@ always @(posedge clk_sys) begin if (ioctl_downl) begin if (~ioctl_wr_last && ioctl_wr) begin port1_req <= ~port1_req; - port2_req <= ~port2_req; + if (ioctl_addr >= 20'h30000) port2_req <= ~port2_req; end end - // clock domain crossing here (clk_snd -> clk_sys) + // async clock domain crossing here (clk_snd -> clk_sys) snd_vma_r <= snd_vma; snd_vma_r2 <= snd_vma_r; - if (snd_vma_r2) snd_addr <= snd_rom_addr + 16'h8000; + if (snd_vma_r2) snd_addr <= snd_rom_addr + 18'h20000; end // reset signal generation @@ -230,7 +249,11 @@ target_top target_top( .cpu_rom_do( rom_addr[0] ? rom_do[15:8] : rom_do[7:0] ), .snd_rom_addr(snd_rom_addr), .snd_rom_do(snd_rom_addr[0] ? snd_do[15:8] : snd_do[7:0]), - .snd_vma(snd_vma) + .snd_vma(snd_vma), + .gfx1_addr(chr1_addr), + .gfx1_do(chr1_do), + .gfx2_addr(sp_addr), + .gfx2_do(sp_do) ); mist_video #(.COLOR_DEPTH(4), .SD_HCNT_WIDTH(10)) mist_video( diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/pace.vhd b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/pace.vhd index 5fe723f1..8d42326b 100644 --- a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/pace.vhd +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/pace.vhd @@ -34,7 +34,11 @@ entity PACE is platform_i : in from_PLATFORM_IO_t; platform_o : out to_PLATFORM_IO_t; cpu_rom_addr : out std_logic_vector(14 downto 0); - cpu_rom_do : in std_logic_vector(7 downto 0) + cpu_rom_do : in std_logic_vector(7 downto 0); + gfx1_addr : out std_logic_vector(17 downto 2); + gfx1_do : in std_logic_vector(31 downto 0); + gfx2_addr : out std_logic_vector(17 downto 2); + gfx2_do : in std_logic_vector(31 downto 0) ); end entity PACE; @@ -53,6 +57,7 @@ architecture SYN of PACE is signal to_sprite_reg : to_SPRITE_REG_t; signal to_sprite_ctl : to_SPRITE_CTL_t; + signal to_sprite_ctl2 : to_SPRITE_CTL_t; signal from_sprite_ctl : from_SPRITE_CTL_t; signal spr0_hit : std_logic; @@ -117,8 +122,12 @@ begin platform_i => platform_i, platform_o => platform_o, - cpu_rom_addr => cpu_rom_addr, - cpu_rom_do => cpu_rom_do + cpu_rom_addr => cpu_rom_addr, + cpu_rom_do => cpu_rom_do, + gfx1_addr => gfx1_addr, + gfx1_do => gfx1_do, + gfx2_addr => gfx2_addr, + gfx2_do => gfx2_do ); graphics_inst : entity work.Graphics @@ -137,10 +146,9 @@ begin graphics_i => to_graphics, graphics_o => from_graphics, - - -- video (incl. clk) - video_i => video_i, - video_o => video_o + -- video (incl. clk) + video_i => video_i, + video_o => video_o ); end SYN; diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/platform.vhd b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/platform.vhd index f21c5a5d..fda568b2 100644 --- a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/platform.vhd +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/platform.vhd @@ -53,7 +53,11 @@ entity platform is platform_i : in from_PLATFORM_IO_t; platform_o : out to_PLATFORM_IO_t; cpu_rom_addr : out std_logic_vector(14 downto 0); - cpu_rom_do : in std_logic_vector(7 downto 0) + cpu_rom_do : in std_logic_vector(7 downto 0); + gfx1_addr : out std_logic_vector(17 downto 2); + gfx1_do : in std_logic_vector(31 downto 0); + gfx2_addr : out std_logic_vector(17 downto 2); + gfx2_do : in std_logic_vector(31 downto 0) ); end platform; @@ -331,72 +335,71 @@ begin type gfx_rom_d_a is array(M62_CHAR_ROM'range) of std_logic_vector(7 downto 0); signal chr_rom_d : gfx_rom_d_a; type spr_rom_d_a is array(0 to 11) of std_logic_vector(7 downto 0); - signal spr_rom_left : spr_rom_d_a; - signal spr_rom_right : spr_rom_d_a; + signal spr_rom : spr_rom_d_a; begin - - GEN_CHAR_ROMS : for i in M62_CHAR_ROM'range generate - char_rom_inst : entity work.sprom - generic map - ( - init_file => "./roms/" & - M62_CHAR_ROM(i) & ".hex", - widthad_a => 13 - ) - port map - ( - clock => clk_video, - address => tilemap_i(1).tile_a(12 downto 0), - q => chr_rom_d(i) - ); - end generate GEN_CHAR_ROMS; - tilemap_o(1).tile_d(23 downto 0) <= chr_rom_d(0) & chr_rom_d(1) & chr_rom_d(2); + -- external background ROMs + gfx1_addr <= "000"&tilemap_i(1).tile_a(12 downto 0); + tilemap_o(1).tile_d(23 downto 0) <= gfx1_do(7 downto 0) & gfx1_do(15 downto 8) & gfx1_do(23 downto 16); --- chr_rom_addr <= tilemap_i(1).tile_a(12 downto 0); - --tilemap_o(1).tile_d(23 downto 0) <= chr_rom_do; - - - GEN_SPRITE_ROMS : for i in M62_SPRITE_ROM'range generate - sprite_rom_inst : entity work.dprom_2r - generic map - ( - init_file => "./roms/" & - M62_SPRITE_ROM(i) & ".hex", - widthad_a => 13, - widthad_b => 13 - ) - port map - ( - clock => clk_video, - address_a(12 downto 5) => sprite_i.a(12 downto 5), - address_a(4) => '0', - address_a(3 downto 0) => sprite_i.a(3 downto 0), - q_a => spr_rom_left(i), - address_b(12 downto 5) => sprite_i.a(12 downto 5), - address_b(4) => '1', - address_b(3 downto 0) => sprite_i.a(3 downto 0), - q_b => spr_rom_right(i) - ); - end generate GEN_SPRITE_ROMS; + -- internal background ROMs +-- GEN_CHAR_ROMS : for i in M62_CHAR_ROM'range generate +-- char_rom_inst : entity work.sprom +-- generic map +-- ( +-- init_file => "./roms/" & +-- M62_CHAR_ROM(i) & ".hex", +-- widthad_a => 13 +-- ) +-- port map +-- ( +-- clock => clk_video, +-- address => tilemap_i(1).tile_a(12 downto 0), +-- q => chr_rom_d(i) +-- ); +-- end generate GEN_CHAR_ROMS; +-- +-- tilemap_o(1).tile_d(23 downto 0) <= chr_rom_d(0) & chr_rom_d(1) & chr_rom_d(2); - sprite_o.d(sprite_o.d'left downto 48) <= (others => '0'); - sprite_o.d(47 downto 0) <= spr_rom_left(0) & spr_rom_right(0) & - spr_rom_left(1) & spr_rom_right(1) & - spr_rom_left(2) & spr_rom_right(2) - when sprite_i.a(14 downto 13) = "00" else - spr_rom_left(3) & spr_rom_right(3) & - spr_rom_left(4) & spr_rom_right(4) & - spr_rom_left(5) & spr_rom_right(5) - when sprite_i.a(14 downto 13) = "01" else - spr_rom_left(6) & spr_rom_right(6) & - spr_rom_left(7) & spr_rom_right(7) & - spr_rom_left(8) & spr_rom_right(8) - when sprite_i.a(14 downto 13) = "10" else - spr_rom_left(9) & spr_rom_right(9) & - spr_rom_left(10) & spr_rom_right(10) & - spr_rom_left(11) & spr_rom_right(11); + -- external sprite ROMs + gfx2_addr <= '0' & sprite_i.a(14 downto 0); + sprite_o.d(23 downto 0) <= gfx2_do(7 downto 0) & gfx2_do(15 downto 8) & gfx2_do(23 downto 16); + + -- internal sprite ROMs +-- GEN_SPRITE_ROMS : for i in M62_SPRITE_ROM'range generate +-- sprite_rom_inst : entity work.sprom +-- generic map +-- ( +-- init_file => "./roms/" & +-- M62_SPRITE_ROM(i) & ".hex", +-- widthad_a => 13 +-- ) +-- port map +-- ( +-- clock => clk_video, +-- address(12 downto 5) => sprite_i.a(12 downto 5), +-- address(4 downto 0) => sprite_i.a(4 downto 0), +-- q => spr_rom(i) +-- ); +-- end generate GEN_SPRITE_ROMS; +-- +-- sprite_o.d(sprite_o.d'left downto 24) <= (others => '0'); +-- sprite_o.d(23 downto 0) <= spr_rom(0) & +-- spr_rom(1) & +-- spr_rom(2) +-- when sprite_i.a(14 downto 13) = "00" else +-- spr_rom(3) & +-- spr_rom(4) & +-- spr_rom(5) +-- when sprite_i.a(14 downto 13) = "01" else +-- spr_rom(6) & +-- spr_rom(7) & +-- spr_rom(8) +-- when sprite_i.a(14 downto 13) = "10" else +-- spr_rom(9) & +-- spr_rom(10) & +-- spr_rom(11); end block BLK_GFX_ROMS; diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/sdram.sv b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/sdram.sv index 41f5b7a8..267f2759 100644 --- a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/sdram.sv +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/sdram.sv @@ -46,9 +46,9 @@ module sdram ( input [15:0] port1_d, output reg [15:0] port1_q, - input [16:1] cpu1_addr, + input [17:1] cpu1_addr, output reg [15:0] cpu1_q, - input [16:1] cpu2_addr, + input [17:1] cpu2_addr, output reg [15:0] cpu2_q, input port2_req, @@ -59,7 +59,9 @@ module sdram ( input [15:0] port2_d, output reg [31:0] port2_q, - input [16:2] sp_addr, + input [19:2] chr1_addr, + output reg [31:0] chr1_q, + input [19:2] sp_addr, output reg [31:0] sp_q ); @@ -83,24 +85,25 @@ localparam RFRSH_CYCLES = 10'd842; SDRAM state machine for 2 bank interleaved access 1 word burst, CL2 cmd issued registered - 0 RAS0 cas1 - data0 read burst terminated - 1 ras0 + 0 RAS0 + 1 ras0 - data1 returned 2 data1 returned - 3 CAS0 data1 returned + 3 CAS0 4 RAS1 cas0 5 ras1 6 CAS1 data0 returned + 7 cas1 - data0 read burst terminated */ localparam STATE_RAS0 = 3'd0; // first state in cycle localparam STATE_RAS1 = 3'd4; // Second ACTIVE command after RAS0 + tRRD (15ns) localparam STATE_CAS0 = STATE_RAS0 + RASCAS_DELAY + 1'd1; // CAS phase - 3 localparam STATE_CAS1 = STATE_RAS1 + RASCAS_DELAY; // CAS phase - 6 -localparam STATE_READ0 = 3'd0;// STATE_CAS0 + CAS_LATENCY + 2'd2; // 7 -localparam STATE_READ1 = 3'd3; -localparam STATE_DS1b = 3'd0; -localparam STATE_READ1b = 3'd4; -localparam STATE_LAST = 3'd6; +localparam STATE_READ0 = STATE_CAS0 + CAS_LATENCY + 2'd2; // 7 +localparam STATE_READ1 = 3'd2; +localparam STATE_DS1b = 3'd7; +localparam STATE_READ1b = 3'd3; +localparam STATE_LAST = 3'd7; reg [2:0] t; @@ -152,8 +155,8 @@ assign SDRAM_nWE = sd_cmd[0]; reg [24:1] addr_latch[2]; reg [24:1] addr_latch_next[2]; -reg [16:1] addr_last[2]; -reg [16:2] addr_last2[2]; +reg [17:1] addr_last[2]; +reg [19:2] addr_last2[2]; reg [15:0] din_latch[2]; reg [1:0] oe_latch; reg [1:0] we_latch; @@ -166,6 +169,7 @@ localparam PORT_NONE = 2'd0; localparam PORT_CPU1 = 2'd1; localparam PORT_CPU2 = 2'd2; localparam PORT_SP = 2'd1; +localparam PORT_CHR1 = 2'd2; localparam PORT_REQ = 2'd3; reg [1:0] next_port[2]; @@ -185,10 +189,10 @@ always @(*) begin addr_latch_next[0] = { 1'b0, port1_a }; end else if (cpu1_addr != addr_last[PORT_CPU1]) begin next_port[0] = PORT_CPU1; - addr_latch_next[0] = { 8'd0, cpu1_addr }; + addr_latch_next[0] = { 7'd0, cpu1_addr }; end else if (cpu2_addr != addr_last[PORT_CPU2]) begin next_port[0] = PORT_CPU2; - addr_latch_next[0] = { 8'd0, cpu2_addr }; + addr_latch_next[0] = { 7'd0, cpu2_addr }; end else begin next_port[0] = PORT_NONE; addr_latch_next[0] = addr_latch[0]; @@ -202,7 +206,10 @@ always @(*) begin addr_latch_next[1] = { 1'b1, port2_a }; end else if (sp_addr != addr_last2[PORT_SP]) begin next_port[1] = PORT_SP; - addr_latch_next[1] = { 1'b1, 7'd0, sp_addr, 1'b0 }; + addr_latch_next[1] = { 1'b1, 4'd0, sp_addr, 1'b0 }; + end else if (chr1_addr != addr_last2[PORT_CHR1]) begin + next_port[1] = PORT_CHR1; + addr_latch_next[1] = { 1'b1, 4'd0, chr1_addr, 1'b0 }; end else begin next_port[1] = PORT_NONE; addr_latch_next[1] = addr_latch[1]; @@ -249,7 +256,7 @@ always @(posedge clk) begin sd_cmd <= CMD_ACTIVE; SDRAM_A <= addr_latch_next[0][22:10]; SDRAM_BA <= addr_latch_next[0][24:23]; - addr_last[next_port[0]] <= addr_latch_next[0][16:1]; + addr_last[next_port[0]] <= addr_latch_next[0][17:1]; if (next_port[0] == PORT_REQ) begin { oe_latch[0], we_latch[0] } <= { ~port1_we, port1_we }; ds[0] <= port1_ds; @@ -273,7 +280,7 @@ always @(posedge clk) begin sd_cmd <= CMD_ACTIVE; SDRAM_A <= addr_latch_next[1][22:10]; SDRAM_BA <= addr_latch_next[1][24:23]; - addr_last2[next_port[1]] <= addr_latch_next[1][16:2]; + addr_last2[next_port[1]] <= addr_latch_next[1][19:2]; if (next_port[1] == PORT_REQ) begin { oe_latch[1], we_latch[1] } <= { ~port1_we, port1_we }; ds[1] <= port2_ds; @@ -327,8 +334,9 @@ always @(posedge clk) begin if(t == STATE_READ1 && oe_latch[1]) begin case(port[1]) - PORT_REQ: port2_q[15:0] <= sd_din; - PORT_SP : sp_q[15:0] <= sd_din; + PORT_REQ : port2_q[15:0] <= sd_din; + PORT_SP : sp_q[15:0] <= sd_din; + PORT_CHR1: chr1_q[15:0] <= sd_din; default: ; endcase; end @@ -337,8 +345,9 @@ always @(posedge clk) begin if(t == STATE_READ1b && oe_latch[1]) begin case(port[1]) - PORT_REQ: begin port2_q[31:16] <= sd_din; port2_ack <= port2_req; end - PORT_SP : begin sp_q[31:16] <= sd_din; end + PORT_REQ : begin port2_q[31:16] <= sd_din; port2_ack <= port2_req; end + PORT_SP : begin sp_q[31:16] <= sd_din; end + PORT_CHR1 : begin chr1_q[31:16] <= sd_din; end default: ; endcase; end diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/sprite_array.vhd b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/sprite_array.vhd index 1209e0f0..cafb9866 100644 --- a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/sprite_array.vhd +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/sprite_array.vhd @@ -55,7 +55,7 @@ architecture SYN of sprite_array is signal ctl_o : ctl_o_a_t(0 to N_SPRITES-1); signal ld_r : std_logic_vector(N_SPRITES-1 downto 0); - + signal ld_ena : std_logic; begin -- Sprite Data Load Arbiter @@ -68,17 +68,28 @@ begin -- enable must be 1 clock behind address to latch data after fetch --ld_r <= (N_SPRITES-1 => '1', others => '0'); -- make ISE 9.2.03i happy... + ld_ena <= '1'; ld_r(ld_r'left) <= '1'; ld_r(ld_r'left-1 downto 0) <= (others => '0'); i := 0; elsif rising_edge(clk) and clk_ena = '1' then - ld_r <= ld_r(ld_r'left-1 downto 0) & ld_r(ld_r'left); - if i = N_SPRITES-1 then + if video_ctl.hblank = '0' then + ld_ena <= '1'; i := 0; + ld_r(ld_r'left) <= '1'; + ld_r(ld_r'left-1 downto 0) <= (others => '0'); else - i := i + 1; + ld_ena <= not ld_ena; + if ld_ena = '1' then + ld_r <= ld_r(ld_r'left-1 downto 0) & ld_r(ld_r'left); + if i = N_SPRITES-1 then + i := 0; + else + i := i + 1; + end if; + row_a <= ctl_o(i).a; + end if; end if; - row_a <= ctl_o(i).a; end if; end process; diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/spritectl.vhd b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/spritectl.vhd index 2a44677b..0e236a67 100644 --- a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/spritectl.vhd +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/spritectl.vhd @@ -40,16 +40,15 @@ architecture SYN of spritectl is signal flipData : std_logic_vector(47 downto 0); -- flipped row data alias rgb : RGB_t is ctl_o.rgb; - + signal ld_r : std_logic; + signal left_d : std_logic; + signal rowStore : std_logic_vector(47 downto 0); -- saved row of spt to show during visibile period + begin - flipData(47 downto 32) <= flip_1 (ctl_i.d(47 downto 32), reg_i.xflip); - flipData(31 downto 16) <= flip_1 (ctl_i.d(31 downto 16), reg_i.xflip); - flipData(15 downto 0) <= flip_1 (ctl_i.d(15 downto 0), reg_i.xflip); - - process (clk, clk_ena) + process (clk, clk_ena, left_d, reg_i) - variable rowStore : std_logic_vector(47 downto 0); -- saved row of spt to show during visibile period +-- variable rowStore : std_logic_vector(47 downto 0); -- saved row of spt to show during visibile period variable pel : std_logic_vector(2 downto 0); variable x : unsigned(video_ctl.x'range); variable y : unsigned(video_ctl.y'range); @@ -77,6 +76,7 @@ begin if rising_edge(clk) then if clk_ena = '1' then + ld_r <= ctl_i.ld; if video_ctl.hblank = '1' then x := unsigned(reg_i.x) - M62_VIDEO_H_OFFSET + PACE_VIDEO_PIPELINE_DELAY - 3; @@ -131,16 +131,28 @@ begin if y = 0 then yMat := false; end if; - + -- sprites not visible before row 16 - if ctl_i.ld = '1' then + if ld_r = '0' and ctl_i.ld = '1' then + left_d <= not left_d; -- switch sprite half if yMat then - rowStore := flipData; -- load sprite data + if left_d = '0' then + -- store first half of the sprite line data + flipData(39 downto 32) <= ctl_i.d(23 downto 16); + flipData(23 downto 16) <= ctl_i.d(15 downto 8); + flipData(7 downto 0) <= ctl_i.d(7 downto 0); + else + -- load sprite data + rowStore(47 downto 32) <= flip_1(flipData(39 downto 32) & ctl_i.d(23 downto 16), reg_i.xflip); + rowStore(31 downto 16) <= flip_1(flipData(23 downto 16) & ctl_i.d(15 downto 8), reg_i.xflip); + rowStore(15 downto 0) <= flip_1(flipData( 7 downto 0) & ctl_i.d( 7 downto 0), reg_i.xflip); + end if; else - rowStore := (others => '0'); + rowStore <= (others => '0'); end if; end if; - + else + left_d <= '0'; end if; -- hblank='1' if video_ctl.stb = '1' then @@ -157,9 +169,9 @@ begin if xMat then -- shift in next pixel pel := rowStore(rowStore'left-32) & rowStore(rowStore'left-16) & rowStore(rowStore'left); - rowStore(47 downto 32) := rowStore(46 downto 32) & '0'; - rowStore(31 downto 16) := rowStore(30 downto 16) & '0'; - rowStore(15 downto 0) := rowStore(14 downto 0) & '0'; + rowStore(47 downto 32) <= rowStore(46 downto 32) & '0'; + rowStore(31 downto 16) <= rowStore(30 downto 16) & '0'; + rowStore(15 downto 0) <= rowStore(14 downto 0) & '0'; end if; end if; @@ -190,7 +202,7 @@ begin -- generate sprite data address ctl_o.a(15) <= '0'; -- unused ctl_o.a(14 downto 5) <= code; - ctl_o.a(4) <= '0'; -- dual-port RAM + ctl_o.a(4) <= left_d; if reg_i.yflip = '0' then ctl_o.a(3 downto 0) <= std_logic_vector(row(3 downto 0)); else diff --git a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/target_top.vhd b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/target_top.vhd index 41ee2a1b..72be4eaf 100644 --- a/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/target_top.vhd +++ b/Arcade_MiST/IremM62 Hardware/LodeRunner_MiST/rtl/target_top.vhd @@ -42,7 +42,11 @@ entity target_top is port( cpu_rom_do : in std_logic_vector(7 downto 0); snd_rom_addr : out std_logic_vector(13 downto 0); snd_rom_do : in std_logic_vector(7 downto 0); - snd_vma : out std_logic + snd_vma : out std_logic; + gfx1_addr : out std_logic_vector(17 downto 2); + gfx1_do : in std_logic_vector(31 downto 0); + gfx2_addr : out std_logic_vector(17 downto 2); + gfx2_do : in std_logic_vector(31 downto 0) ); end target_top; @@ -111,7 +115,11 @@ pace_inst : entity work.pace platform_i => platform_i, platform_o => platform_o, cpu_rom_addr => cpu_rom_addr, - cpu_rom_do => cpu_rom_do + cpu_rom_do => cpu_rom_do, + gfx1_addr => gfx1_addr, + gfx1_do => gfx1_do, + gfx2_addr => gfx2_addr, + gfx2_do => gfx2_do ); inputs_i.jamma_n.coin(1) <= not usr_coin1;