-- -- VHDL source of Graphic Piece Controller (GPC) -- -- (C)2000,2001, Kunihiko OHNAKA. All rights resereved. -- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity gpc is port( -- Video Engine Clock pVideoClk : in std_logic; pCpuClk : in std_logic; pCpuReset_n : in std_logic; pCpuIrq_n : out std_logic; pCpuAddr : in std_logic_vector( 7 downto 0 ); -- pCpuData_in : in std_logic_vector( 15 downto 0 ); -- pCpuData_out : out std_logic_vector( 15 downto 0 ); pCpuData_in : in std_logic_vector( 7 downto 0 ); pCpuData_out : out std_logic_vector( 7 downto 0 ); pCpuWait_n : out std_logic; plsCpuWr : in std_logic; plsCpuRd : in std_logic; pRamAddr : OUT std_logic_vector(18 downto 0); pRamCeX_n : OUT std_logic; pRamOeX_n : OUT std_logic; pRamWeX_n : OUT std_logic; pRamDataX : INOUT std_logic_vector(7 downto 0); pRamCeY_n : OUT std_logic; pRamOeY_n : OUT std_logic; pRamWeY_n : OUT std_logic; pRamDataY : INOUT std_logic_vector(7 downto 0); -- Vide Output -- Video DAC(MB40988) clock pVDACClk : OUT std_logic; pVideoR : OUT std_logic_vector( 5 downto 0); pVideoG : OUT std_logic_vector( 5 downto 0); pVideoB : OUT std_logic_vector( 5 downto 0); pVideoHS_n : OUT std_logic; pVideoVS_n : OUT std_logic; pVideoCS_n : OUT std_logic; -- CXA1645 signal pVideoSC : OUT std_logic; pVideoSYNC : OUT std_logic; -- Test Pins pTest0 : OUT std_logic; pTest1 : OUT std_logic ); end gpc; architecture RTL of gpc is component Ram port( address : IN std_logic_vector(7 downto 0); inclock : IN std_logic; we : IN std_logic; data : IN std_logic_vector(7 downto 0); q : OUT std_logic_vector(7 downto 0) ); end component; -- test counter -- signal test_counter : std_logic_vector( 7 downto 0); -- display start position -- constant OFFSET_X : std_logic_vector := "0110110"; -- = 220/4; -- constant OFFSET_Y : std_logic_vector := "0101110"; -- = 3+3+13+26+1 = 46 -- constant OFFSET_Y_212 : std_logic_vector := "0100100"; -- = 3+3+13+16+1 = 36 -- constant OFFSET_X : std_logic_vector := "0110000"; -- = 196/4; constant OFFSET_X : std_logic_vector := "0110110"; -- = 220/4; constant OFFSET_Y : std_logic_vector := "0100100"; -- NTSC sync state register signal ntscState : std_logic_vector( 1 downto 0); constant ntscState_A : std_logic_vector := "00"; constant ntscState_B : std_logic_vector := "01"; constant ntscState_C : std_logic_vector := "10"; constant ntscState_D : std_logic_vector := "11"; signal VideoHS_n : std_logic; signal VideoVS_n : std_logic; signal vramWrReq : std_logic; signal vramWrReq_D : std_logic; signal vramWrAck : std_logic; signal vramAccessAddr : std_logic_vector( 19 downto 0); -- signal vramAccessAddr_tmp : std_logic_vector( 19 downto 0); signal vramAccessAddr_setFlag : std_logic; -- signal vramAccessData : std_logic_vector( 15 downto 0); signal vramAccessData : std_logic_vector( 7 downto 0); -- signal vramAccessing : std_logic; signal registerHighByte : std_logic_vector( 7 downto 0); -- Color Code for plane 0 signal colorCode0even : std_logic_vector( 7 downto 0); signal colorCode0odd : std_logic_vector( 7 downto 0); signal transparent_flag : std_logic; signal colorR0 : std_logic_vector( 5 downto 0); signal colorG0 : std_logic_vector( 5 downto 0); signal colorB0 : std_logic_vector( 5 downto 0); -- Color Code for plane 1 signal latestColorCode0 : std_logic_vector( 7 downto 0); signal colorCode1even : std_logic_vector( 7 downto 0); signal colorCode1odd : std_logic_vector( 7 downto 0); signal colorR1 : std_logic_vector( 5 downto 0); signal colorG1 : std_logic_vector( 5 downto 0); signal colorB1 : std_logic_vector( 5 downto 0); -- NTSC timing counter -- H counter signal h_counter : std_logic_vector(10 downto 0); -- V counter signal v_counter : std_logic_vector(10 downto 0); -- dot state register signal dotState : std_logic_vector( 1 downto 0); -- dot counter signal dotCounter_x : std_logic_vector( 8 downto 0); signal dotCounter_y : std_logic_vector( 8 downto 0); signal preDotCounter_x : std_logic_vector( 8 downto 0); signal preDotCounter_y : std_logic_vector( 8 downto 0); signal window : std_logic; signal window_x : std_logic; signal window_y : std_logic; signal preWindow : std_logic; signal preWindow_x : std_logic; signal preWindow_y : std_logic; -- 3.58MHz generator signal cpuClockCounter :std_logic_vector( 2 downto 0); -- mode registers signal gpcReg0plane0disp: std_logic; signal gpcReg0plane1disp : std_logic; signal gpcReg0transparent : std_logic; signal gpcReg0vsync : std_logic; -- palette registers signal paletteAddr : std_logic_vector( 7 downto 0); signal paletteAddr_out : std_logic_vector( 7 downto 0); signal paletteWeR : std_logic; signal paletteWeG : std_logic; signal paletteWeB : std_logic; signal paletteIn : std_logic; signal paletteData_in : std_logic_vector( 7 downto 0); signal paletteDataR_out : std_logic_vector( 7 downto 0); signal paletteDataG_out : std_logic_vector( 7 downto 0); signal paletteDataB_out : std_logic_vector( 7 downto 0); signal paletteWrReq : std_logic; signal paletteWrReq_D : std_logic; signal paletteWrAck : std_logic; signal paletteWrData_R : std_logic_vector( 7 downto 0); signal paletteWrData_G : std_logic_vector( 7 downto 0); signal paletteWrData_B : std_logic_vector( 7 downto 0); signal paletteWrNum : std_logic_vector( 7 downto 0); signal paletteWrNum_tmp : std_logic_vector( 7 downto 0); -- window registers signal wflag00 : std_logic; signal wflag00_x : std_logic; signal wflag00_y : std_logic; signal wflag01 : std_logic; signal wflag01_x : std_logic; signal wflag01_y : std_logic; signal wflag02 : std_logic; signal wflag02_x : std_logic; signal wflag02_y : std_logic; -- for plane 0 signal p0dispx : std_logic_vector(8 downto 0); signal p0dispy : std_logic_vector(8 downto 0); -- for plane 1 signal p1dispx : std_logic_vector(8 downto 0); signal p1dispy : std_logic_vector(8 downto 0); -- for window 0 signal w0x0 : std_logic_vector(8 downto 0); signal w0y0 : std_logic_vector(8 downto 0); signal w0x1 : std_logic_vector(8 downto 0); signal w0y1 : std_logic_vector(8 downto 0); signal w0dispx : std_logic_vector(8 downto 0); signal w0dispy : std_logic_vector(8 downto 0); -- for window 1 signal w1x0 : std_logic_vector(8 downto 0); signal w1y0 : std_logic_vector(8 downto 0); signal w1x1 : std_logic_vector(8 downto 0); signal w1y1 : std_logic_vector(8 downto 0); signal w1dispx : std_logic_vector(8 downto 0); signal w1dispy : std_logic_vector(8 downto 0); -- for window 2 signal w2x0 : std_logic_vector(8 downto 0); signal w2y0 : std_logic_vector(8 downto 0); signal w2x1 : std_logic_vector(8 downto 0); signal w2y1 : std_logic_vector(8 downto 0); signal w2dispx : std_logic_vector(8 downto 0); signal w2dispy : std_logic_vector(8 downto 0); begin -- RGB Sync Signals pVideoCS_n <= not (VideoHS_n xor VideoVS_n); pVideoHS_n <= VideoHS_n; pVideoVS_n <= VideoVS_n; -- CXA1645 NTSC Encoder Signals pVideoSYNC <= not (VideoHS_n xor VideoVS_n); pVideoSC <= cpuClockCounter(2); -- Video DAC(MB40988) Clock -- dotState changes as 00->01->11->10 -- dotState(0) xor dotState(1) 0-> 1-> 0-> 1 -- pVideoR(G,B) <======><====> pVDACClk <= dotState(0) xor dotState(1); ---------------------------------------------------------------- -- Palette Register control ---------------------------------------------------------------- paletteAddr <= ( paletteWrNum ) when ( paletteIn = '1' ) else ( paletteAddr_out ); paletteWeR <= '1' when paletteIn = '1' else '0'; paletteWeG <= '1' when paletteIn = '1' else '0'; paletteWeB <= '1' when paletteIn = '1' else '0'; paletteMemR : Ram port map(paletteAddr, pVideoClk, paletteWeR, paletteWrData_R, paletteDataR_out); paletteMemG : Ram port map(paletteAddr, pVideoClk, paletteWeG, paletteWrData_G, paletteDataG_out); paletteMemB : Ram port map(paletteAddr, pVideoClk, paletteWeB, paletteWrData_B, paletteDataB_out); ---------------------------------------------------------------- -- 3.58 MHz Generator ---------------------------------------------------------------- process( pVideoClk, pCpuReset_n ) begin if (pCpuReset_n = '0') then cpuClockCounter <= (others => '0'); elsif (pVideoClk'event and pVideoClk = '1') then case cpuClockCounter is when "000" => cpuClockCounter <= "001"; when "001" => cpuClockCounter <= "011"; when "011" => cpuClockCounter <= "111"; when "111" => cpuClockCounter <= "110"; when "110" => cpuClockCounter <= "100"; when "100" => cpuClockCounter <= "000"; when others => cpuClockCounter <= "000"; end case; end if; end process; pTest0 <= plsCpuWr; pTest1 <= plsCpuRd; -- pTest <= test_counter(7); -- process( pVideoClk, pCpuReset_n ) -- begin -- if (pCpuReset_n = '0') then -- test_counter <= (others => '0'); -- elsif (pVideoClk'event and pVideoClk = '1') then -- test_counter <= test_counter + 1; -- end if; -- end process; ---------------------------------------------------------------- -- NTSC Timing Generator ---------------------------------------------------------------- process( pVideoClk, pCpuReset_n ) begin if (pCpuReset_n = '0') then ntscState <= (others => '0' ); VideoHS_n <= '1'; VideoVS_n <= '1'; h_counter <= (others => '0'); v_counter <= (others => '0'); pCpuIrq_n <= '1'; elsif (pVideoClk'event and pVideoClk = '1') then if( h_counter = 1363 ) then h_counter <= (others => '0' ); else h_counter <= h_counter + 1; end if; if( (h_counter = 681) or (h_counter = 1363) ) then -- 525 lines * 2 = 1050 if( v_counter = 1049 ) then if(h_counter = 1363) then v_counter <= (others => '0'); end if; else v_counter <= v_counter + 1; end if; end if; if( (v_counter = 0) or (v_counter = 12) or (v_counter = 526) or (v_counter = 538) ) then ntscState <= ntscState_A; elsif( (v_counter = 6) or (v_counter = 532) ) then ntscState <= ntscState_B; elsif( (v_counter = 18) or (v_counter = 544) ) then ntscState <= ntscState_C; end if; -- generate H sync pulse if( ntscState = ntscState_A ) then if( (h_counter = 1) or (h_counter = 1+682) ) then VideoHS_n <= '0'; -- pulse on elsif( (h_counter = 51) or (h_counter = 51+682) ) then VideoHS_n <= '1'; -- pulse off end if; elsif( ntscState = ntscState_B ) then if( (h_counter = 1364-100+1) or (h_counter = 682-100+1) ) then VideoHS_n <= '0'; -- pulse on elsif( (h_counter = 1) or (h_counter = 1+682) ) then VideoHS_n <= '1'; -- pulse off end if; elsif( ntscState = ntscState_C ) then if( h_counter = 1 ) then VideoHS_n <= '0'; -- pulse on elsif( h_counter = 101 ) then VideoHS_n <= '1'; -- pulse off end if; end if; -- generate V sync pulse and V sync interrupt if( ntscState = ntscState_B ) then VideoVS_n <= '0'; else VideoVS_n <= '1'; end if; if( gpcReg0vsync = '1' ) then pCpuIrq_n <= preWindow_y; -- pCpuIrq_n <= VideoVS_n; else pCpuIrq_n <= '1'; end if; end if; end process; ---------------------------------------------------------------- -- Dot Counters, window signals ---------------------------------------------------------------- -- generate pwindow, window, g123window, spwindow preWindow <= (preWindow_x and preWindow_y); window <= (window_x and window_y); process( pVideoClk, pCpuReset_n ) begin if (pCpuReset_n = '0') then dotCounter_x <= (others =>'0'); dotCounter_y <= (others =>'0'); preDotCounter_x <= (others =>'0'); preDotCounter_y <= (others =>'0'); window_x <= '0'; window_y <= '0'; preWindow_x <= '0'; preWindow_y <= '0'; elsif (pVideoClk'event and pVideoClk = '1') then if( h_counter = ("00" & OFFSET_X & "10" ) ) then preWindow_x <= '1'; elsif( (h_counter( 1 downto 0) = "10") and ( preDotCounter_x = "011111111" ) ) then preWindow_x <= '0'; end if; if( (v_counter = ("0000" & (OFFSET_Y+1) & '0') ) or (v_counter = 526+("0000" & (OFFSET_Y+1) & '0')) ) then preWindow_y <= '1'; window_y <= '1'; elsif( (v_counter = ("0000" & (OFFSET_Y+1) & '0')+220*2) or (v_counter = 526+("0000" & (OFFSET_Y+1) & '0')+220*2) ) then preWindow_y <= '0'; window_y <= '0'; end if; -- main window if( (h_counter( 1 downto 0) = "10") and ( dotCounter_x = "111111111" ) ) then -- when dotCounter_x = -1 window_x <= '1'; elsif( (h_counter( 1 downto 0) = "10") and ( dotCounter_x ="011111111" ) ) then -- when dotCounter_x = 255 window_x <= '0'; end if; if( h_counter = ("00" & (OFFSET_X-1) & "10") ) then preDotCounter_x <= "111111111"; -- -1 dotCounter_x <= "111111101"; -- -3 if( v_counter = ("000" & OFFSET_Y & '0') ) then -- dotCounter_y <= (VdpR23VStartLine - 1); dotCounter_y <= (others => '1'); elsif( v_counter = ("000" & OFFSET_Y & '0')+526 ) then -- dotCounter_y <= (VdpR23VStartLine - 1); dotCounter_y <= (others => '1'); else dotCounter_y <= dotCounter_y + 1; end if; elsif( h_counter( 1 downto 0) = "10") then preDotCounter_x <= preDotCounter_x + 1; dotCounter_x <= dotCounter_x + 1; end if; if( h_counter = 1363 ) then if( v_counter = ("0000" & OFFSET_Y & '1') ) then -- preDotCounter_y <= VdpR23VStartLine; preDotCounter_y <= (others => '0'); elsif( v_counter = ("0000" & OFFSET_Y & '1')+526 ) then -- preDotCounter_y <= VdpR23VStartLine; preDotCounter_y <= (others => '0'); else preDotCounter_y <= preDotCounter_y + 1; end if; end if; end if; end process; ---------------------------------------------------------------- -- float window ---------------------------------------------------------------- wflag00 <= wflag00_x and wflag00_y; wflag01 <= wflag01_x and wflag01_y; wflag02 <= wflag02_x and wflag02_y; process( pVideoClk, pCpuReset_n ) begin if (pCpuReset_n = '0') then wflag00_x <= '0'; wflag00_y <= '0'; wflag01_x <= '0'; wflag01_y <= '0'; wflag02_x <= '0'; wflag02_y <= '0'; elsif (pVideoClk'event and pVideoClk = '1') then if( h_counter = 0 ) then wflag00_x <= '0'; wflag01_x <= '0'; wflag02_x <= '0'; elsif( dotState = "11" ) then if( preDotCounter_x = (w0x0-1) ) then wflag00_x <= '1'; elsif( preDotCounter_x = w0x1 ) then wflag00_x <= '0'; end if; if( preDotCounter_x = (w1x0-1) ) then wflag01_x <= '1'; elsif( preDotCounter_x = w1x1 ) then wflag01_x <= '0'; end if; if( preDotCounter_x = (w2x0-1) ) then wflag02_x <= '1'; elsif( preDotCounter_x = w2x1 ) then wflag02_x <= '0'; end if; end if; if( v_counter = 0 ) then wflag00_y <= '0'; wflag01_y <= '0'; wflag02_y <= '0'; elsif( h_counter = 0 ) then if( preDotCounter_y = w0y0 ) then wflag00_y <= '1'; elsif( preDotCounter_y = w0y1 ) then wflag00_y <= '0'; end if; if( preDotCounter_y = w1y0 ) then wflag01_y <= '1'; elsif( preDotCounter_y = w1y1 ) then wflag01_y <= '0'; end if; if( preDotCounter_y = w2y0 ) then wflag02_y <= '1'; elsif( preDotCounter_y = w2y1 ) then wflag02_y <= '0'; end if; end if; end if; end process; ---------------------------------------------------------------- -- Main State Counter ---------------------------------------------------------------- process( pVideoClk, pCpuReset_n ) begin if (pCpuReset_n = '0') then dotState <= (others => '0' ); elsif (pVideoClk'event and pVideoClk = '1') then if( h_counter = 1363) then dotState <= "00"; else case dotState is when "00" => dotState <= "01"; when "01" => dotState <= "11"; when "11" => dotState <= "10"; when "10" => dotState <= "00"; when others => null; end case; end if; end if; end process; ---------------------------------------------------------------- -- Main State (Palette, Color Generation ) ---------------------------------------------------------------- process( pVideoClk, pCpuReset_n ) begin if (pCpuReset_n = '0') then pRamAddr <= (others => '0' ); pRamDataX <= (others => 'Z' ); pRamDataY <= (others => 'Z' ); pRamCeX_n <= '1'; pRamCeY_n <= '1'; pRamOeX_n <= '1'; pRamOeY_n <= '1'; pRamWeX_n <= '1'; pRamWeY_n <= '1'; pVideoR <= (others => '0' ); pVideoG <= (others => '0' ); pVideoB <= (others => '0' ); paletteAddr_out <= (others => '0'); paletteWrAck <= '0'; paletteWrReq_D <= '0'; paletteIn <= '0'; vramWrReq_D <= '0'; vramWrAck <= '0'; latestColorCode0 <= (others => '0'); colorCode0even <= (others => '0'); colorCode0odd <= (others => '0'); colorCode1even <= (others => '0'); colorCode1odd <= (others => '0'); transparent_flag <= '0'; colorR0 <= (others => '0'); colorG0 <= (others => '0'); colorB0 <= (others => '0'); colorR1 <= (others => '0'); colorG1 <= (others => '0'); colorB1 <= (others => '0'); elsif (pVideoClk'event and pVideoClk = '1') then paletteWrReq_D <= paletteWrReq; vramWrReq_D <= vramWrReq; pRamCeX_n <= '0'; pRamCeY_n <= '0'; case dotState is when "10" => pRamDataX <= (others => 'Z' ); pRamDataY <= (others => 'Z' ); if( preWindow = '1' ) then pRamOeX_n <= '0'; pRamOeY_n <= '0'; if( preDotCounter_x(0) = '0' ) then -- priority check and address generation (field 0) -- -- 000-00000000-00000000 -- Y YYYYYYYY XXXXXXXX -- if( wflag00='1' ) then pRamAddr <= "00" & ( preDotCounter_y-w0y0 + w0dispy) & ( preDotCounter_x(8 downto 1)-w0x0(8 downto 1) + w0dispx(8 downto 1)); elsif( wflag00='0' and wflag01='1' ) then pRamAddr <= "00" & ( preDotCounter_y-w1y0 + w1dispy) & ( preDotCounter_x(8 downto 1)-w1x0(8 downto 1) + w1dispx(8 downto 1)); elsif( wflag00='0' and wflag01='0' and wflag02='1' ) then pRamAddr <= "00" & ( preDotCounter_y-w2y0 + w2dispy) & ( preDotCounter_x(8 downto 1)-w2x0(8 downto 1) + w2dispx(8 downto 1)); else pRamAddr <= "00" &( preDotCounter_y + p0dispy) & ( preDotCounter_x(8 downto 1)+p0dispx(8 downto 1)); end if; else -- address generation (field 1) pRamAddr <= "10" & ( preDotCounter_y + p1dispy) & ( preDotCounter_x( 8 downto 1)+p1dispx(8 downto 1)); end if; end if; -- Palette decoding and palette setting if( preWindow = '1' ) then if( dotCounter_x(0) = '0' ) then paletteAddr_out <= colorCode0odd; latestColorCode0 <= colorCode0odd; else paletteAddr_out <= colorCode0even; latestColorCode0 <= colorCode0even; end if; else if( paletteWrReq_D = not paletteWrAck ) then paletteWrAck <= not paletteWrAck; paletteIn <= '1'; end if; end if; -- final color output if( window = '1' ) then if( gpcReg0transparent = '1' and transparent_flag = '1' ) then -- transparental mixing pVideoR <= (('0' & colorR0(5 downto 1)) + ('0' & colorR1(5 downto 1))); pVideoG <= (('0' & colorG0(5 downto 1)) + ('0' & colorG1(5 downto 1))); pVideoB <= (('0' & colorB0(5 downto 1)) + ('0' & colorB1(5 downto 1))); else if( latestColorCode0 = "00000000" ) then pVideoR <= colorR1; pVideoG <= colorG1; pVideoB <= colorB1; else pVideoR <= colorR0; pVideoG <= colorG0; pVideoB <= colorB0; end if; end if; else pVideoR <= (others => '0'); pVideoG <= (others => '0'); pVideoB <= (others => '0'); end if; when "00" => paletteIn <= '0'; colorR1 <= paletteDataR_out(5 downto 0); colorG1 <= paletteDataG_out(5 downto 0); colorB1 <= paletteDataB_out(5 downto 0); when "01" => if( preWindow = '1' ) then if( preDotCounter_x(0) = '0' ) then if( gpcReg0plane0disp = '1' ) then colorCode0even <= pRamDataX; colorCode0odd <= pRamDataY; else colorCode0even <= (others => '0'); colorCode0odd <= (others => '0'); end if; else if( gpcReg0plane1disp = '1' ) then colorCode1even <= pRamDataX; colorCode1odd <= pRamDataY; -- colorCode1odd <= (others => '0'); else colorCode1even <= (others => '0'); colorCode1odd <= (others => '0'); end if; end if; end if; -- Palette decoding if( dotCounter_x(0) = '0' ) then paletteAddr_out <= colorCode1odd; else -- paletteAddr_out <= colorCode1even; if( gpcReg0plane1disp = '1' ) then paletteAddr_out <= pRamDataX; else paletteAddr_out <= (others => '0'); end if; end if; if( vramWrReq_D = not vramWrAck ) then -- vram writing pRamAddr <= vramAccessAddr( 19 downto 1); vramWrAck <= not vramWrAck; if( vramAccessAddr(0) = '0' ) then -- even address pRamDataX <= vramAccessData; pRamOeX_n <= '1'; pRamWeX_n <= '0'; else -- odd address pRamDataY <= vramAccessData; pRamOeY_n <= '1'; pRamWeY_n <= '0'; end if; else pRamOeX_n <= '1'; pRamOeY_n <= '1'; end if; when "11" => pRamWeX_n <='1'; pRamWeY_n <='1'; transparent_flag <= paletteDataR_out(7); -- colorR0 <= "011000"; colorR0 <= paletteDataR_out(5 downto 0); colorG0 <= paletteDataG_out(5 downto 0); colorB0 <= paletteDataB_out(5 downto 0); when others => null; end case; end if; end process; ---------------------------------------------------------------- -- CPU Interface ---------------------------------------------------------------- process( pCpuClk, pCpuReset_n ) begin if (pCpuReset_n = '0') then pCpuData_out <= (others => 'Z'); pCpuWait_n <= '1'; gpcReg0plane0disp <= '1'; gpcReg0plane1disp <= '1'; gpcReg0transparent <= '0'; gpcReg0vsync <= '0'; vramWrReq <= '0'; vramAccessAddr <= (others => '0'); vramAccessAddr_setFlag <= '0'; -- vramAccessAddr_tmp <= (others => '0'); vramAccessData <= (others => '0'); paletteWrNum <= (others => '0'); paletteWrReq <= '0'; paletteWrData_R <= (others => '0'); paletteWrData_G <= (others => '0'); paletteWrData_B <= (others => '0'); w0x0 <= (others => '0'); w0y0 <= (others => '0'); w0x1 <= (others => '0'); w0y1 <= (others => '0'); w0dispx <= (others => '0'); w0dispy <= (others => '0'); w1x0 <= (others => '0'); w1y0 <= (others => '0'); w1x1 <= (others => '0'); w1y1 <= (others => '0'); w1dispx <= (others => '0'); w1dispy <= (others => '0'); w2x0 <= (others => '0'); w2y0 <= (others => '0'); w2x1 <= (others => '0'); w2y1 <= (others => '0'); w2dispx <= (others => '0'); w2dispy <= (others => '0'); p0dispx <= (others => '0'); p0dispy <= (others => '0'); p1dispx <= (others => '0'); p1dispy <= (others => '0'); registerHighByte <= (others => '0'); elsif (pCpuClk'event and pCpuClk = '1') then if( plsCpuWr = '1' ) then -- register write case pCpuAddr(5 downto 0) is when "000000" => gpcReg0plane0disp <= pCpuData_in(0); gpcReg0plane1disp <= pCpuData_in(1); gpcReg0transparent <= pCpuData_in(4); gpcReg0vsync <= pCpuData_in(5); when "000001" => -- vram write vramWrReq <= not vramWrAck; vramAccessData <= pCpuData_in; if( vramAccessAddr_setFlag = '0' ) then vramAccessAddr <= vramAccessAddr + 1; else vramAccessAddr_setFlag <= '0'; end if; when "000010" => registerHighByte <= pCpuData_in; -- vram access address registers when "000100" => vramAccessAddr(7 downto 0) <= pCpuData_in; vramAccessAddr_setFlag <= '1'; when "000101" => vramAccessAddr(15 downto 8) <= pCpuData_in; vramAccessAddr_setFlag <= '1'; when "000110" => vramAccessAddr(19 downto 16) <= pCpuData_in( 3 downto 0); vramAccessAddr_setFlag <= '1'; -- palette registers when "001000" => paletteWrData_R <= pCpuData_in( 7 downto 0); when "001001" => paletteWrData_G <= pCpuData_in( 7 downto 0); when "001010" => paletteWrData_B <= pCpuData_in( 7 downto 0); when "001011" => paletteWrReq <= not paletteWrAck; paletteWrNum <= pCpuData_in( 7 downto 0); -- window 0 registers when "100000" => -- 0x20 w0x0 <= registerHighByte(0) & pCpuData_in; when "100001" => -- 0x21 w0y0 <= registerHighByte(0) & pCpuData_in; when "100010" => -- 0x22 w0x1 <= registerHighByte(0) & pCpuData_in; when "100011" => -- 0x23 w0y1 <= registerHighByte(0) & pCpuData_in; when "100100" => -- 0x24 w0dispx <= registerHighByte(0) & pCpuData_in; when "100101" => -- 0x25 w0dispy <= registerHighByte(0) & pCpuData_in; -- window 1 registers when "100110" => -- 0x26 w1x0 <= registerHighByte(0) & pCpuData_in; when "100111" => -- 0x27 w1y0 <= registerHighByte(0) & pCpuData_in; when "101000" => -- 0x28 w1x1 <= registerHighByte(0) & pCpuData_in; when "101001" => -- 0x29 w1y1 <= registerHighByte(0) & pCpuData_in; when "101010" => -- 0x2a w1dispx <= registerHighByte(0) & pCpuData_in; when "101011" => -- 0x2b w1dispy <= registerHighByte(0) & pCpuData_in; -- window 2 registers when "101100" => -- 0x2c w2x0 <= registerHighByte(0) & pCpuData_in; when "101101" => -- 0x2d w2y0 <= registerHighByte(0) & pCpuData_in; when "101110" => -- 0x2e w2x1 <= registerHighByte(0) & pCpuData_in; when "101111" => -- 0x2f w2y1 <= registerHighByte(0) & pCpuData_in; when "110000" => -- 0x30 w2dispx <= registerHighByte(0) & pCpuData_in; when "110001" => -- 0x31 w2dispy <= registerHighByte(0) & pCpuData_in; -- plane 0 registers when "110010" => -- 0x32 p0dispx <= registerHighByte(0) & pCpuData_in; when "110011" => -- 0x33 p0dispy <= registerHighByte(0) & pCpuData_in; -- plane 1 registers when "110100" => -- 0x34 p1dispx <= registerHighByte(0) & pCpuData_in; when "110101" => -- 0x35 p1dispy <= registerHighByte(0) & pCpuData_in; when others => null; end case; elsif( plsCpuRd = '0' ) then -- register read case pCpuAddr(5 downto 0) is when "000000" => pCpuData_out <= "00" & gpcReg0vsync & gpcReg0transparent & "00" & gpcReg0plane0disp & gpcReg0plane1disp; when "001000" => -- status register pCpuData_out <= "0000000" & preWindow_y; when others => pCpuData_out <= (others => '0'); end case; else pCpuData_out <= (others => 'Z'); end if; end if; end process; end RTL;