📄 userio.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 user IO module// joystick signals are _joy[5:0]=[fire2,fire,up,down,left,right];//// 16-10-2005 -started coding// 17-10-2005 -added proper reset for mouse buttons/counters// -improved mouse startup timing// 22-11-2005 -added joystick 1// 05-02-2006 -unused buttons of joystick port 2 are now high// 06-02-2006 -cleaned up code// -added user output// 27-12-2006 -added joystick port 1 and automatic joystick/mouse switch// -started coding osd display// 28-12-2006 -more osd display work done// 29-12-2006 -fixed some bugs in osd module// 30-12-2006 -cleaned up osd module, added osdctrl input//-----------------------------------------------------------------------------//JB:// 2008-06-17 - added osd control by joy2// - spi8 rewritten to use spi clock// - added highlight (inversion) of selected osd line// - added user reset and reset to bootloader// - added memory and interpolation filters configuration
// 2008-07-28 - added JOYTEST register to make it compatible with ALPHA1/SIRIAX intro/trainermodule userio( input clk, //bus clock input reset, //reset input sol, //start of video line input sof, //start of video frame input [8:1] regaddress, //register adress inputs input [15:0]datain, //bus data in output reg [15:0]dataout, //bus data out inout ps2mdat, //mouse PS/2 data inout ps2mclk, //mouse PS/2 clk output _fire0, //joystick 0 fire output (to CIA) output _fire1, //joystick 1 fire output (to CIA) output [2:0]user, //user menu control [fire,up,down] (to Paula) input [5:0]_joy1, //joystick 1 in (default mouse port) input [5:0]_joy2, //joystick 2 in (default joystick port) input [3:0]osdctrl, //OSD control (minimig->host, [menu,select,down,up]) input _den, //SPI enable input din, //SPI data in output dout, //SPI data out input dclk, //SPI clock output osdblank, //osd overlay, normal video blank output output osdpixel, //osd video pixel output [1:0]lr_filter, output [1:0]hr_filter, output [1:0]memcfg, output usrrst, //user reset from osd module output bootrst //user reset to bootloader);//local signals reg [5:0]_sjoy1; //synchronized joystick 1 signalsreg [5:0]_xjoy2; //synchronized joystick 2 signalswire [5:0]_sjoy2; //synchronized joystick 2 signalswire [15:0]mouse0dat; //mouse counterswire _mleft,_mthird,_mright; //mouse buttonsreg joy1enable; //joystick 1 enable (mouse/joy switch)reg joy2enable; //joystick 2 enable when no osdwire osdenable; //osd enablewire [3:0]xosdctrl; //JB: osd control lineswire test_load; //load test value to mouse counter wire [15:0]test_data; //mouse counter test value//register names and adresses parameter JOY0DAT=9'h00a;parameter JOY1DAT=9'h00c;parameter POTINP=9'h016;parameter JOYTEST=9'h036;//--------------------------------------------------------------------------------------//-------------------------------------------------------------------------------------- //input synchronization of external signalsalways @(posedge clk) _sjoy1[5:0]<=_joy1[5:0]; always @(posedge clk) _xjoy2[5:0]<=_joy2[5:0]; //port 2 joystick disable in osdalways @(posedge clk) if (osdenable) joy2enable <= 0; else if (_xjoy2[5:0] == 6'b11_1111) joy2enable <= 1;assign _sjoy2[5:0] = joy2enable ? _xjoy2[5:0] : 6'b11_1111;assign xosdctrl[3] = osdctrl[3] | (~_xjoy2[2] & ~_xjoy2[3]);assign xosdctrl[2] = osdctrl[2] | (~_xjoy2[4] & ~joy2enable);assign xosdctrl[1] = osdctrl[1] | (~_xjoy2[2] & _xjoy2[3] & ~joy2enable);assign xosdctrl[0] = osdctrl[0] | (~_xjoy2[3] & _xjoy2[2] & ~joy2enable);//port 1 automatic mouse/joystick switchalways @(posedge clk) if(!_mleft || reset)//when left mouse button pushed, switch to mouse (default) joy1enable=0; else if(!_sjoy1[4])//when joystick 1 fire pushed, switch to joystick joy1enable=1;//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//data output multiplexeralways @(regaddress or joy1enable or _sjoy1 or mouse0dat or _sjoy2 or _mright or _mthird) if((regaddress[8:1]==JOY0DAT[8:1]) && joy1enable)//read port 1 joystick dataout[15:0]={6'b000000,~_sjoy1[1],_sjoy1[3]^_sjoy1[1],6'b000000,~_sjoy1[0],_sjoy1[2]^_sjoy1[0]}; else if(regaddress[8:1]==JOY0DAT[8:1])//read port 1 mouse dataout[15:0]=mouse0dat[15:0]; else if(regaddress[8:1]==JOY1DAT[8:1])//read port 2 joystick dataout[15:0]={6'b000000,~_sjoy2[1],_sjoy2[3]^_sjoy2[1],6'b000000,~_sjoy2[0],_sjoy2[2]^_sjoy2[0]}; else if(regaddress[8:1]==POTINP[8:1])//read mouse and joysticks extra buttons dataout[15:0]={1'b0,_sjoy2[5],3'b010,_mright&_sjoy1[5],1'b0,_mthird,8'b00000000}; else dataout[15:0]=16'h0000;//assign fire outputs to cia Aassign _fire1=_sjoy2[4];assign _fire0=_sjoy1[4]&_mleft;//assign user interface control signalsassign user[2:0]=~_sjoy2[4:2];//JB: some trainers writes to JOYTEST register to reset current mouse counterassign test_load = regaddress[8:1]==JOYTEST[8:1] ? 1 : 0;assign test_data = datain[15:0];//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//instantiate mouse controllerps2mouse pm1( .clk(clk), .reset(reset), .ps2mdat(ps2mdat), .ps2mclk(ps2mclk), .ycount(mouse0dat[15:8]), .xcount(mouse0dat[7:0]), ._mleft(_mleft), ._mthird(_mthird), ._mright(_mright), .test_load(test_load), .test_data(test_data));//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//instantiate osd controllerosd osd1( .clk(clk), .reset(reset), .sol(sol), .sof(sof), .osdctrl(xosdctrl), ._den(_den), .din(din), .dout(dout), .dclk(dclk), .osdblank(osdblank), .osdpixel(osdpixel), .osdenable(osdenable), .lr_filter(lr_filter), .hr_filter(hr_filter), .memcfg(memcfg), .usrrst(usrrst), .bootrst(bootrst));//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------endmodule//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//on screen display controllermodule osd( input clk, //pixel clock input reset, //reset input sol, //start of video line input sof, //start of video frame input [3:0]osdctrl, //OSD control (minimig->host, [menu,select,down,up]) input _den, //SPI enable input din, //SPI data in output dout, //SPI data out input dclk, //SPI clock output osdblank, //osd overlay, normal video blank output output osdpixel, //osd video pixel output osdenable, //osd enable output reg [1:0]lr_filter, output reg [1:0]hr_filter, output reg [1:0]memcfg, output usrrst, output bootrst);//local signalsreg [8:0]horbeam; //horizontal beamcounterreg [8:0]verbeam; //vertical beamcounterreg [7:0]osdbuf[1023:0]; //osd video bufferwire osdframe; //true if beamcounters within osd framereg [7:0]bufout; //osd buffer read datareg osdenable1; //osd display enable 1reg osdenable2; //osd display enable 2 (synchronized to start of frame)reg [9:0]wraddr; //osd buffer write addresswire [7:0]wrdat; //osd buffer write datawire wren; //osd buffer write enablereg [3:0]highlight; //highlighted line numberreg invert; //invertion of highlighted line//--------------------------------------------------------------------------------------//OSD video generator//--------------------------------------------------------------------------------------//osd local horizontal beamcounteralways @(posedge clk) if (sol) horbeam <= 0; else horbeam <= horbeam + 1;//osd local vertical beamcounteralways @(posedge clk) if (sof) verbeam<=0; else if (sol) verbeam <= verbeam + 1;//--------------------------------------------------------------------------------------//generate osd video framereg hframe,vframe;//horizontal part..always @(posedge clk) if (horbeam[8]) hframe <= 0; else if (horbeam[7]) hframe <= 1;//vertical part..always @(posedge clk) if (verbeam[7] && ~verbeam[6]) vframe <= 1; else if (verbeam[0]) vframe <= 0;//combine..assign osdframe = vframe & hframe & osdenable2;always @(posedge clk) if (~highlight[3] && verbeam[5:3]==highlight[2:0] && ~verbeam[6]) invert <= 1; else if (verbeam[0]) invert <= 0;//--------------------------------------------------------------------------------------//assign osd blank and pixel outputsassign osdpixel = invert ^ bufout[verbeam[2:0]];assign osdblank = osdframe;//--------------------------------------------------------------------------------------//video buffer//--------------------------------------------------------------------------------------//dual ported osd video buffer//video buffer is 1024*8//this buffer should be a single blockramalways @(posedge clk)//input part if (wren) osdbuf[wraddr[9:0]] <= wrdat[7:0]; always @(posedge clk)//output part bufout[7:0] <= osdbuf[{verbeam[5:3],horbeam[6:0]}];//--------------------------------------------------------------------------------------//interface to host//--------------------------------------------------------------------------------------wire rx;wire cmd;reg [2:0]spicmd; //spi command//instantiate spi interfacespi8 spi0( .clk(clk), .scs(~_den), .sdi(din), .sdo(dout), .sck(dclk), .in({4'b0000,osdctrl[3:0]}), .out(wrdat[7:0]), .rx(rx), .cmd(cmd));//command latch// commands are://// 8'b00000000 nop// 8'b00100NNN write data to osd buffer line <NNN>// 8'b01000000 disable displaying of osd// 8'b01100000 enable displaying of osd// 8'b10000000 reset Minimig// 8'b10100000 read osdctrl (controls for osd)// 8'b1110HHLL set interpolation filter status// 8'b111100MM set memory configurationalways @(posedge clk) if (rx && cmd) spicmd <= wrdat[7:5];//filter configurationalways @(posedge clk) if (rx && cmd && wrdat[7:4]==4'b1110) {hr_filter[1:0],lr_filter[1:0]} <= wrdat[3:0];//memory configurationalways @(posedge clk) if (rx && cmd && wrdat[7:4]==4'b1111) memcfg[1:0] <= wrdat[1:0];//address counter and buffer write control (write line <NNN> command)always @(posedge clk)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -