1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-19 17:27:59 +00:00

LodeRunner: move sprites and background tiles to SDRAM

This commit is contained in:
Gyorgy Szombathelyi 2020-03-03 12:50:15 +01:00
parent 1b80f5b041
commit b0e2b401b7
10 changed files with 318 additions and 134 deletions

View File

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

View File

@ -0,0 +1,110 @@
<misterromdescription>
<name>Lode Runner</name>
<mameversion>0216</mameversion>
<setname>ldrun</setname>
<manufacturer>Irem</manufacturer>
<rbf>iremm62</rbf>
<rom index="1"><part>0</part></rom>
<rom index="0" zip="ldrun.zip" md5="9e4c8423a33f0c5bf558d475d89e041a" type="merged|nonmerged">
<!-- CPU1, 128k -->
<part name="lr-a-4e"/>
<part name="lr-a-4d"/>
<part name="lr-a-4b"/>
<part name="lr-a-4a"/>
<part name="lr-a-4e"/>
<part name="lr-a-4d"/>
<part name="lr-a-4b"/>
<part name="lr-a-4a"/>
<part name="lr-a-4e"/>
<part name="lr-a-4d"/>
<part name="lr-a-4b"/>
<part name="lr-a-4a"/>
<part name="lr-a-4e"/>
<part name="lr-a-4d"/>
<part name="lr-a-4b"/>
<part name="lr-a-4a"/>
<!-- SND CPU2, 64k -->
<part name="lr-a-3f"/>
<part name="lr-a-3h"/>
<part name="lr-a-3f"/>
<part name="lr-a-3h"/>
<part name="lr-a-3f"/>
<part name="lr-a-3h"/>
<part name="lr-a-3f"/>
<part name="lr-a-3h"/>
<!-- GFX1, 128k -->
<part name="lr-e-2d"/>
<part name="lr-e-2j"/>
<part name="lr-e-2f"/>
<part name="lr-e-2f"/>
<part name="lr-e-2d"/>
<part name="lr-e-2j"/>
<part name="lr-e-2f"/>
<part name="lr-e-2f"/>
<part name="lr-e-2d"/>
<part name="lr-e-2j"/>
<part name="lr-e-2f"/>
<part name="lr-e-2f"/>
<part name="lr-e-2d"/>
<part name="lr-e-2j"/>
<part name="lr-e-2f"/>
<part name="lr-e-2f"/>
<!-- GFX2, 256k -->
<part name="lr-b-4k"/>
<part name="lr-b-3n"/>
<part name="lr-b-4c"/>
<part name="lr-b-4c"/>
<part name="lr-b-4k"/>
<part name="lr-b-3n"/>
<part name="lr-b-4c"/>
<part name="lr-b-4c"/>
<part name="lr-b-4k"/>
<part name="lr-b-3n"/>
<part name="lr-b-4c"/>
<part name="lr-b-4c"/>
<part name="lr-b-4k"/>
<part name="lr-b-3n"/>
<part name="lr-b-4c"/>
<part name="lr-b-4c"/>
<part name="lr-b-4k"/>
<part name="lr-b-3n"/>
<part name="lr-b-4c"/>
<part name="lr-b-4c"/>
<part name="lr-b-4k"/>
<part name="lr-b-3n"/>
<part name="lr-b-4c"/>
<part name="lr-b-4c"/>
<part name="lr-b-4k"/>
<part name="lr-b-3n"/>
<part name="lr-b-4c"/>
<part name="lr-b-4c"/>
<part name="lr-b-4k"/>
<part name="lr-b-3n"/>
<part name="lr-b-4c"/>
<part name="lr-b-4c"/>
<!-- GFX3, 64k -->
<part repeat="0x10000">FF</part>
<!-- spr_color_proms, 3*256b -->
<part name="lr-b-1m"/>
<part name="lr-b-1n"/>
<part name="lr-b-1l"/>
<!-- chr_color_proms, 3*256b -->
<part name="lr-e-3m"/>
<part name="lr-e-3l"/>
<part name="lr-e-3n"/>
<!-- fg_color_proms, 3*256b -->
<part repeat="0x300">FF</part>
<!-- spr_height_prom -->
<part name="lr-b-5p"/>
</rom>
</misterromdescription>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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