📄 sprites.v
字号:
// Copyright 2006, 2007 Dennis van Weeren//// This file is part of Minimig//// Minimig is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 3 of the License, or// (at your option) any later version.//// Minimig is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program. If not, see <http://www.gnu.org/licenses/>.//////// This is the sprites part of denise // It supports all OCS sprite modes.//// 12-06-2005 -started coding// -first finished version// 21-06-2005 -changed sprite priority logic and nsprite output// 02-10-2005 -sprites are now attached if odd,even or both sprites SPRXCTL bit 7 is set// 17-10-2005 -sprites were displayed one pixel too early, fixed.// JB:// 2008-07-14 - swapped shifta and shiftb in serialized output (fix for Zool2: copper directly writes to SPRxDATx registers)module sprites( input clk, //bus clock input reset, //reset input [8:1]regaddress, //register address input input [8:0]horbeam, //horizontal beam counter input [15:0]datain, //bus data in output [7:0]nsprite, //sprite data valid signals output reg [3:0]sprdata //sprite data out);//register names and adresses parameter SPRPOSCTLBASE=9'h140; //sprite data, position and control register base address//local signalswire selspr0; //select sprite 0wire selspr1; //select sprite 1wire selspr2; //select sprite 2wire selspr3; //select sprite 3wire selspr4; //select sprite 4wire selspr5; //select sprite 5wire selspr6; //select sprite 6wire selspr7; //select sprite 7wire [1:0]sprdat0; //data sprite 0wire [1:0]sprdat1; //data sprite 1wire [1:0]sprdat2; //data sprite 2wire [1:0]sprdat3; //data sprite 3wire [1:0]sprdat4; //data sprite 4wire [1:0]sprdat5; //data sprite 5wire [1:0]sprdat6; //data sprite 6wire [1:0]sprdat7; //data sprite 7wire attach0; //attach sprite 0,1wire attach1; //attach sprite 0,1wire attach2; //attach sprite 2,3wire attach3; //attach sprite 2,3wire attach4; //attach sprite 4,5wire attach5; //attach sprite 4,5wire attach6; //attach sprite 6,7wire attach7; //attach sprite 6,7//--------------------------------------------------------------------------------------//sprite register address decoderwire selsprx;assign selsprx=(SPRPOSCTLBASE[8:6]==regaddress[8:6])?1:0;//base addressassign selspr0=(selsprx&&(regaddress[5:3]==0))?1:0;assign selspr1=(selsprx&&(regaddress[5:3]==1))?1:0;assign selspr2=(selsprx&&(regaddress[5:3]==2))?1:0;assign selspr3=(selsprx&&(regaddress[5:3]==3))?1:0;assign selspr4=(selsprx&&(regaddress[5:3]==4))?1:0;assign selspr5=(selsprx&&(regaddress[5:3]==5))?1:0;assign selspr6=(selsprx&&(regaddress[5:3]==6))?1:0;assign selspr7=(selsprx&&(regaddress[5:3]==7))?1:0;//--------------------------------------------------------------------------------------//instantiate sprite 0sprshift sps0( .clk(clk), .reset(reset), .aen(selspr0), .address(regaddress[2:1]), .horbeam(horbeam), .datain(datain), .sprdata(sprdat0), .attach(attach0));//instantiate sprite 1sprshift sps1( .clk(clk), .reset(reset), .aen(selspr1), .address(regaddress[2:1]), .horbeam(horbeam), .datain(datain), .sprdata(sprdat1), .attach(attach1));//instantiate sprite 2sprshift sps2( .clk(clk), .reset(reset), .aen(selspr2), .address(regaddress[2:1]), .horbeam(horbeam), .datain(datain), .sprdata(sprdat2), .attach(attach2));//instantiate sprite 3sprshift sps3( .clk(clk), .reset(reset), .aen(selspr3), .address(regaddress[2:1]), .horbeam(horbeam), .datain(datain), .sprdata(sprdat3), .attach(attach3));//instantiate sprite 4sprshift sps4( .clk(clk), .reset(reset), .aen(selspr4), .address(regaddress[2:1]), .horbeam(horbeam), .datain(datain), .sprdata(sprdat4), .attach(attach4));//instantiate sprite 5sprshift sps5( .clk(clk), .reset(reset), .aen(selspr5), .address(regaddress[2:1]), .horbeam(horbeam), .datain(datain), .sprdata(sprdat5), .attach(attach5));//instantiate sprite 6sprshift sps6( .clk(clk), .reset(reset), .aen(selspr6), .address(regaddress[2:1]), .horbeam(horbeam), .datain(datain), .sprdata(sprdat6), .attach(attach6));//instantiate sprite 7sprshift sps7( .clk(clk), .reset(reset), .aen(selspr7), .address(regaddress[2:1]), .horbeam(horbeam), .datain(datain), .sprdata(sprdat7), .attach(attach7));//--------------------------------------------------------------------------------------//generate sprite data valid signalsassign nsprite[0]=(sprdat0[1:0]!=2'b00)?1:0;//if any non-zero bit -> valid video dataassign nsprite[1]=(sprdat1[1:0]!=2'b00)?1:0;//if any non-zero bit -> valid video dataassign nsprite[2]=(sprdat2[1:0]!=2'b00)?1:0;//if any non-zero bit -> valid video dataassign nsprite[3]=(sprdat3[1:0]!=2'b00)?1:0;//if any non-zero bit -> valid video dataassign nsprite[4]=(sprdat4[1:0]!=2'b00)?1:0;//if any non-zero bit -> valid video dataassign nsprite[5]=(sprdat5[1:0]!=2'b00)?1:0;//if any non-zero bit -> valid video dataassign nsprite[6]=(sprdat6[1:0]!=2'b00)?1:0;//if any non-zero bit -> valid video dataassign nsprite[7]=(sprdat7[1:0]!=2'b00)?1:0;//if any non-zero bit -> valid video data//--------------------------------------------------------------------------------------//sprite video priority logic and color decoderalways @( attach0 or attach1 or attach2 or attach3 or attach4 or attach5 or attach6 or attach7 or sprdat0 or sprdat1 or sprdat2 or sprdat3 or sprdat4 or sprdat5 or sprdat6 or sprdat7 or nsprite )begin if(nsprite[1:0]!=2'b00)//sprites 0,1 non transparant ? begin if(attach0 || attach1)//sprites are attached -> 15 colors + transparant sprdata[3:0]={sprdat1[1:0],sprdat0[1:0]}; else if(nsprite[0])//output lowered number sprite sprdata[3:0]={2'b00,sprdat0[1:0]}; else//output higher numbered sprite sprdata[3:0]={2'b00,sprdat1[1:0]}; end else if(nsprite[3:2]!=2'b00)//sprites 2,3 non transparant ? begin if(attach2 || attach3)//sprites are attached -> 15 colors + transparant sprdata[3:0]={sprdat3[1:0],sprdat2[1:0]}; else if(nsprite[2])//output lowered number sprite sprdata[3:0]={2'b01,sprdat2[1:0]}; else//output higher numbered sprite sprdata[3:0]={2'b01,sprdat3[1:0]}; end else if(nsprite[5:4]!=2'b00)//sprites 4,5 non transparant ? begin if(attach4 || attach5)//sprites are attached -> 15 colors + transparant sprdata[3:0]={sprdat5[1:0],sprdat4[1:0]}; else if(nsprite[4])//output lowered number sprite sprdata[3:0]={2'b10,sprdat4[1:0]}; else//output higher numbered sprite sprdata[3:0]={2'b10,sprdat5[1:0]}; end else if(nsprite[7:6]!=2'b00)//sprites 6,7 non transparant ? begin if(attach6 || attach7)//sprites are attached -> 15 colors + transparant sprdata[3:0]={sprdat7[1:0],sprdat6[1:0]}; else if(nsprite[6])//output lowered number sprite sprdata[3:0]={2'b11,sprdat6[1:0]}; else//output higher numbered sprite sprdata[3:0]={2'b11,sprdat7[1:0]}; end else//all sprites transparant begin sprdata[3:0]=4'b0000; end end//--------------------------------------------------------------------------------------endmodule//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//this is the sprite parallel to serial converter//clk is 7.09379 MHz (low resolution pixel clock)//the sprdata assign circuitry is constructed differently from the hardware//as described in the amiga hardware reference manual//this is to make sure that the horizontal start position of a sprite//aligns with the bitplane/playfield start positionmodule sprshift
( input clk, //bus clock input reset, //reset input aen, //address enable input [1:0]address, //register address input input [8:0]horbeam, //horizontal beam counter input [15:0]datain, //bus data in output [1:0]sprdata, //serialized sprite data out output reg attach //sprite is attached);
//register names and adresses parameter POS=2'b00; parameter CTL=2'b01; parameter DATA=2'b10; parameter DATB=2'b11; //local signalsreg [15:0]datla; //data register Areg [15:0]datlb; //data register Breg [15:0]shifta; //shift register Areg [15:0]shiftb; //shift register Breg [8:0]hstart; //horizontal start valuereg armed; //sprite "armed" signalwire load; //load shift register signal//--------------------------------------------------------------------------------------//generate armed signalalways @(posedge clk) if(reset)//reset disables sprite armed<=0; else if(aen&&(address==CTL))//writing CTL register disables sprite armed<=0; else if (aen&&(address==DATA))//writing data register A arms sprite armed<=1;//--------------------------------------------------------------------------------------//generate load signalassign load=(armed&&(horbeam[8:0]==hstart[8:0]))?1:0;//--------------------------------------------------------------------------------------//POS registeralways @(posedge clk) if(aen&&(address==POS)) hstart[8:1]<=datain[7:0];//CTL registeralways @(posedge clk) if(aen&&(address==CTL)) {attach,hstart[0]}<={datain[7],datain[0]};//data register Aalways @(posedge clk) if(aen&&(address==DATA)) datla[15:0]<=datain[15:0];//data register Balways @(posedge clk) if(aen&&(address==DATB)) datlb[15:0]<=datain[15:0];//--------------------------------------------------------------------------------------//sprite shift registeralways @(posedge clk) if(load)//load new data into shift register begin shifta[15:0]<=datla[15:0]; shiftb[15:0]<=datlb[15:0]; end else//shift out data begin shifta[15:0]<={shifta[14:0],1'b0}; shiftb[15:0]<={shiftb[14:0],1'b0}; end//assign serialized output dataassign sprdata[1:0] = {shiftb[15],shifta[15]};//--------------------------------------------------------------------------------------endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -