-- -- -- v9938.vhd -- -- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity v9938 is port( pSltClk21 : IN std_logic; pSltClk : IN std_logic; pSltRst_n : IN std_logic; pSltSltsl_n : IN std_logic; pSltIorq_n : IN std_logic; pSltRd_n : IN std_logic; pSltWr_n : IN std_logic; pSltAdr : IN std_logic_vector(15 downto 0); pSltDat : INOUT std_logic_vector(7 downto 0); pSltBdir_n : OUT std_logic; pSltCs1 : IN std_logic; pSltCs2 : IN std_logic; pSltCs12 : IN std_logic; pSltRfsh_n : IN std_logic; pSltWait_n : IN std_logic; pSltInt_n : IN std_logic; pSltM1_n : IN std_logic; pSltMerq_n : IN std_logic; -- pSltClk2 : IN std_logic; pSltRsv5 : OUT std_logic; pSltRsv16 : OUT std_logic; pRamCeX_n : OUT std_logic; pRamOeX_n : OUT std_logic; pRamWeX_n : OUT std_logic; pRamAdrX : OUT std_logic_vector(18 downto 0); pRamDatX : INOUT std_logic_vector(7 downto 0); pRamCeY_n : OUT std_logic; pRamOeY_n : OUT std_logic; pRamWeY_n : OUT std_logic; pRamAdrY : OUT std_logic_vector(18 downto 0); pRamDatY : INOUT std_logic_vector(7 downto 0); -- Vide Output 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 ); end v9938; architecture RTL of v9938 is signal pSltClk_n : std_logic; -- H counter signal h_counter : std_logic_vector(10 downto 0); -- V counter signal v_counter : std_logic_vector(10 downto 0); -- 画面表示開始位置(adjust=(0,0)時) constant OFFSET_X : std_logic_vector := "111011"; -- = 236/4; constant OFFSET_Y : std_logic_vector := "010011"; -- = 76/4; signal adjust_x : std_logic_vector( 5 downto 0); signal adjust_y : std_logic_vector( 5 downto 0); -- dot state register  signal dotState : std_logic_vector( 1 downto 0);  signal dotResetState : std_logic_vector( 1 downto 0); signal field : std_logic; -- sync state register signal sstate : std_logic_vector( 1 downto 0); constant sstate_A : std_logic_vector := "00"; constant sstate_B : std_logic_vector := "01"; constant sstate_C : std_logic_vector := "10"; constant sstate_D : std_logic_vector := "11"; signal VideoHS_n : std_logic; signal VideoVS_n : std_logic; -- グラフィック表示エリア検出用 signal window_x :std_logic; signal window_y :std_logic; signal window :std_logic; signal pwindow_x :std_logic; signal pwindow_y :std_logic; signal pwindow :std_logic; signal spwindow_x :std_logic; -- 周辺枠エリア検出用 signal bwindow_x :std_logic; signal bwindow_y :std_logic; signal bwindow :std_logic; -- dot counter signal dotCounter_x : std_logic_vector( 8 downto 0); signal dotCounter_y : std_logic_vector( 8 downto 0); -- dot counter - 8 ( fifo addr ) signal pdotCounter_x : std_logic_vector( 8 downto 0); signal pdotCounter_y : std_logic_vector( 8 downto 0); signal VramReadFreeFlag : std_logic; -- 3.58MHz generator signal cpuClockCounter :std_logic_vector( 2 downto 0); -- slot control signal IopAcs : std_logic; signal IopAcs0 : std_logic; signal IopAcs1 : std_logic; -- VDP register access signal VdpIs1stByte : std_logic; signal VdpP0Data : std_logic_vector( 7 downto 0); signal VdpP1Data : std_logic_vector( 7 downto 0); signal VdpRegPtr : std_logic_vector( 5 downto 0); signal VdpRegWrPulse : std_logic; signal VdpVramAccessAddr : std_logic_vector( 16 downto 0); signal VdpVramAccessData : std_logic_vector( 7 downto 0); signal VdpVramAccessAddrTmp : std_logic_vector( 16 downto 0); signal VdpVramAddrSetReq : std_logic; signal VdpVramAddrSetAck : std_logic; signal VdpVramAccessRw : std_logic; signal VdpVramWrReq : std_logic; signal VdpVramWrAck : std_logic; signal VdpVramAccessing : std_logic; signal VdpR0DispNum : std_logic_vector(3 downto 1); signal VdpR1DispMode : std_logic_vector(1 downto 0); signal VdpR1SpSize : std_logic; signal VdpR11R5SpAttrTblBaseAddr : std_logic_vector( 6 downto 0); signal VdpR6SpPtnGeneTblBaseAddr : std_logic_vector( 5 downto 0); signal VdpR9InterraceMode : std_logic; signal VdpR9TwoPageMode : std_logic; signal VdpR17RegNum : std_logic_vector( 5 downto 0); signal VdpR17IncRegNum : std_logic; -- sprite signal SpPreReadState : std_logic_vector( 2 downto 0); constant spstate_idle : std_logic_vector := "000"; constant spstate_yread : std_logic_vector := "001"; constant spstate_xread : std_logic_vector := "010"; constant spstate_ptnnumread : std_logic_vector := "011"; constant spstate_ptnread1 : std_logic_vector := "111"; constant spstate_ptnread2 : std_logic_vector := "110"; constant spstate_colorread : std_logic_vector := "100"; signal SpMode2 : std_logic; signal SpPreReadCounter : std_logic_vector( 4 downto 0); signal SpPreReadCounter2 : std_logic_vector( 3 downto 0); signal SpPreReadPtnNum : std_logic_vector( 7 downto 0); signal SpY : std_logic_vector( 7 downto 0); signal SpPreReadY : std_logic_vector( 7 downto 0); signal spColorCode : std_logic_vector( 3 downto 0); signal SpPattern0 : std_logic_vector( 16 downto 0); signal SpPattern1 : std_logic_vector( 16 downto 0); signal SpPattern2 : std_logic_vector( 16 downto 0); signal SpPattern3 : std_logic_vector( 16 downto 0); signal SpX0 : std_logic_vector( 7 downto 0); signal SpX1 : std_logic_vector( 7 downto 0); signal SpX2 : std_logic_vector( 7 downto 0); signal SpX3 : std_logic_vector( 7 downto 0); signal SpColor0 : std_logic_vector( 3 downto 0); signal SpColor1 : std_logic_vector( 3 downto 0); signal SpColor2 : std_logic_vector( 3 downto 0); signal SpColor3 : std_logic_vector( 3 downto 0); signal SpCC0 : std_logic; signal SpCC1 : std_logic; signal SpCC2 : std_logic; signal SpCC3 : std_logic; signal SpEC0 : std_logic; signal SpEC1 : std_logic; signal SpEC2 : std_logic; signal SpEC3 : std_logic; signal SpIC0 : std_logic; signal SpIC1 : std_logic; signal SpIC2 : std_logic; signal SpIC3 : std_logic; -- Color Code signal colorCode : std_logic_vector( 7 downto 0); 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; signal fifoAddr : std_logic_vector( 7 downto 0); signal fifoAddr_in : std_logic_vector( 2 downto 0); signal fifoAddr_out : std_logic_vector( 2 downto 0); signal fifoWe : std_logic; signal fifoIn : std_logic; signal fifoOut : std_logic; signal fifoData_in : std_logic_vector( 7 downto 0); signal fifoData_out : std_logic_vector( 7 downto 0); begin ---------------------------------------------------------------- -- 8byte FIFO control ---------------------------------------------------------------- fifoAddr <= ( "00000" & fifoAddr_out ) when (fifoOut = '1') else ( "00000" & fifoAddr_in ); fifoData_in <= pRamDatX; fifoWe <= '1' when fifoIn = '1' else '0'; fifoMem : Ram port map(fifoAddr, pSltClk21, fifoWe, fifoData_in, fifoData_out); ---------------------------------------------------------------- -- Dummy pin ---------------------------------------------------------------- pSltClk_n <= not pSltClk; pVideoCS_n <= not (VideoHS_n xor VideoVS_n); pVideoHS_n <= VideoHS_n; pVideoVS_n <= VideoVS_n; -- to CXA1645 pVideoSYNC <= not (VideoHS_n xor VideoVS_n); pVideoSC <= cpuClockCounter(2); -- adjust adjust_x <= OFFSET_X; adjust_y <= OFFSET_Y; process( pSltClk21, pSltRst_n ) begin if (pSltRst_n = '0') then h_counter <= (others => '0'); v_counter <= (others => '0'); VideoHS_n <= '1'; VideoVS_n <= '1'; cpuClockCounter <= (others => '0'); elsif (pSltClk21'event and pSltClk21 = '1') then -- 3.58MHz generator, 6分周回路 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; 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 ライン * 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 = 525) and VdpR9InterraceMode = '1') or ((v_counter = 526) and VdpR9InterraceMode = '0') or ((v_counter = 537) and VdpR9InterraceMode = '1') or ((v_counter = 538) and VdpR9InterraceMode = '0') )then sstate <= sstate_A; elsif( (v_counter = 6) or ((v_counter = 531) and VdpR9InterraceMode = '1') or ((v_counter = 532) and VdpR9InterraceMode = '0') )then sstate <= sstate_B; elsif( (v_counter = 18) or ((v_counter = 543) and VdpR9InterraceMode = '1') or ((v_counter = 544) and VdpR9InterraceMode = '0') )then sstate <= sstate_C; end if; -- field 信号生成 if( v_counter = 525 ) then field <= '1'; elsif( v_counter = 0 ) then field <= '0'; end if; -- H syncパルス発生 if( sstate = sstate_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( sstate = sstate_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( sstate = sstate_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; -- V syncパルス発生 if( sstate = sstate_B ) then VideoVS_n <= '0'; else VideoVS_n <= '1'; end if; end if; end process; -- pwindow, window 信号生成 pwindow <= (pwindow_x and pwindow_y); window <= (window_x and window_y); process( pSltClk21, pSltRst_n ) begin if (pSltRst_n = '0') then dotCounter_x <= (others =>'0'); dotCounter_y <= (others =>'0'); window_x <= '0'; window_y <= '0'; pwindow_x <= '0'; pwindow_y <= '0'; bwindow <= '0'; bwindow_x <= '0'; bwindow_y <= '0'; spwindow_x <= '0'; VramReadFreeFlag <= '0'; elsif (pSltClk21'event and pSltClk21 = '1') then if( h_counter = ("000" & ( adjust_x - 24) & "10" ) ) then spwindow_x <= '1'; elsif( (h_counter( 1 downto 0) = "10") and ( pdotCounter_x = 255 ) ) then spwindow_x <= '0'; end if; -- 32回に一かい vram アクセス用に vramバスを開放 if( h_counter = ("000" & adjust_x & "10") ) then pdotCounter_x <= (others =>'0'); VramReadFreeFlag <= '0'; if( v_counter = ("000" & adjust_y & "00") ) then dotCounter_y <= (others =>'0'); elsif( v_counter = ("000" & adjust_y & "00")+526 ) then dotCounter_y <= (others =>'0'); else dotCounter_y <= dotCounter_y + 1; end if; elsif( (h_counter( 1 downto 0) = "10") and (VramReadFreeFlag = '0') ) then pdotCounter_x <= pdotCounter_x + 1; if( pdotCounter_x( 4 downto 0 ) = "11111" ) then VramReadFreeFlag <= '1'; end if; elsif( (h_counter( 1 downto 0) = "10") and (VramReadFreeFlag = '1') ) then VramReadFreeFlag <= '0'; end if; if( h_counter = ("000" & adjust_x & "10" ) ) then pwindow_x <= '1'; elsif( (h_counter( 1 downto 0) = "10") and ( pdotCounter_x = 255 ) ) then pwindow_x <= '0'; end if; if( (v_counter = ("000" & adjust_y & "10") ) or (v_counter = 526+("000" & adjust_y & "10")) ) then pwindow_y <= '1'; window_y <= '1'; elsif( (v_counter = ("000" & adjust_y & "10")+212*2) or (v_counter = 526+("000" & adjust_y & "10")+212*2) ) then pwindow_y <= '0'; window_y <= '0'; end if; if( (h_counter( 1 downto 0) = "10") and ( pdotCounter_x = 7 ) ) then dotCounter_x <= ( others => '0' ); elsif( h_counter( 1 downto 0) = "10") then dotCounter_x <= dotCounter_x + 1; end if; if( (h_counter( 1 downto 0) = "10") and ( pdotCounter_x = 7 ) ) then window_x <= '1'; elsif( (h_counter( 1 downto 0) = "10") and ( pdotCounter_x = 255 ) ) then window_x <= '0'; end if; -- bwindow 信号生成 if( h_counter = 200-1 ) then bwindow_x <= '1'; elsif( h_counter = 1363-1 ) then bwindow_x <= '0'; end if; if( (v_counter = 10*2-1) or (v_counter = 525+10*2-1) ) then bwindow_y <= '1'; elsif( (v_counter = 524-1) or (v_counter = 525+524-1) ) then bwindow_y <= '0'; end if; if( (bwindow_x = '1') and (bwindow_y = '1') )then bwindow <= '1'; else bwindow <= '0'; end if; end if; end process; -- color generator process( SpColor0, SpColor1, SpColor2, SpColor3, SpPattern0, SpPattern1, SpPattern2, SpPattern3, SpCC0, SpCC1, SpCC2, SpCC3 ) begin for i in 0 to 3 loop spColorCode(i) <= ( (SpColor0(i) and SpPattern0(16)) or (SpColor1(i) and SpPattern1(16) and SpCC1 ) or (SpColor2(i) and SpPattern2(16) and SpCC1 and SpCC2 ) or (SpColor3(i) and SpPattern3(16) and SpCC1 and SpCC2 and SpCC3 ) ) or ( ( not SpPattern0(16) and not SpCC1 ) and ( (SpColor1(i) and SpPattern1(16) ) or (SpColor2(i) and SpPattern2(16) and SpCC2 ) or (SpColor3(i) and SpPattern3(16) and SpCC2 and SpCC3 ) ) ) or ( ( not SpPattern0(16) and not SpPattern1(16) and not SpCC2 ) and ( (SpColor2(i) and SpPattern2(16) ) or (SpColor3(i) and SpPattern3(16) and SpCC3 ) ) ) or ( ( not SpPattern0(16) and not SpPattern1(16) and not SpPattern2(16) and not SpCC3 ) and ( SpColor3(i) and SpPattern3(16) ) ); end loop; end process; process( pSltClk21, pSltRst_n ) begin if (pSltRst_n = '0') then dotState <= (others => '0' ); pVideoR <= "000000"; pVideoG <= "000000"; pVideoB <= "000000"; VdpVramWrAck <= '0'; pRamDatY <= (others => 'Z'); pRamDatX <= (others => 'Z'); VdpVramAccessing <= '0'; elsif (pSltClk21'event and pSltClk21 = '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; case dotState is when "10" => pRamCeX_n <= '0'; pRamCeY_n <= '1'; pRamOeY_n <= '1'; if( (pWindow = '1') and (VramReadFreeFlag = '0' ) ) then pRamAdrX <= ("000" & dotCounter_y( 7 downto 0) & pdotCounter_x( 7 downto 0)); pRamDatX <= (others => 'Z' ); pRamOeX_n <= '0'; pRamWeX_n <= '1'; elsif( (SpPreReadState /= spstate_idle) and (VramReadFreeFlag = '0' ) )then case SpPreReadState is when spstate_yread => pRamAdrX <= ("00" & VdpR11R5SpAttrTblBaseAddr & '1' & not SpMode2 & '0' & SpPreReadCounter & "00"); when spstate_xread => pRamAdrX <= ("00" & VdpR11R5SpAttrTblBaseAddr & '1' & not SpMode2 & '0' & SpPreReadCounter & "01"); when spstate_ptnnumread => pRamAdrX <= ("00" & VdpR11R5SpAttrTblBaseAddr & '1' & not SpMode2 & '0' & SpPreReadCounter & "10"); when spstate_colorread => if( SpMode2 = '0' ) then pRamAdrX <= ("00" & VdpR11R5SpAttrTblBaseAddr & '1' & not SpMode2 & '0' & SpPreReadCounter & "11"); else pRamAdrX <= ("00" & VdpR11R5SpAttrTblBaseAddr & "0" & SpPreReadCounter & SpPreReadY( 3 downto 0)); end if; when spstate_ptnread1 => if( VdpR1SpSize = '0' ) then -- 8x8 mode pRamAdrX <= ("00" & VdpR6SpPtnGeneTblBaseAddr & SpPreReadPtnNum( 7 downto 0) & SpPreReadY( 2 downto 0) ); else -- 16x16 mode pRamAdrX <= ("00" & VdpR6SpPtnGeneTblBaseAddr & SpPreReadPtnNum( 7 downto 2) & '0' & SpPreReadY( 3 downto 0) ); end if; when spstate_ptnread2 => if( VdpR1SpSize = '0' ) then -- 8x8 mode null; else -- 16x16 mode pRamAdrX <= ("00" & VdpR6SpPtnGeneTblBaseAddr & SpPreReadPtnNum( 7 downto 2) & '1' & SpPreReadY( 3 downto 0) ); end if; when others => null; end case; pRamDatX <= (others => 'Z' ); pRamOeX_n <= '0'; pRamWeX_n <= '1'; elsif( VdpVramWrReq /= VdpVramWrAck ) then VdpVramAccessing <= '1'; -- elsif( VdpVramRdReq /= VdpVramRdAck ) then -- pRamAdrX <= "00" & VdpVramAccessAddrTmp(16 downto 0); end if; if( window = '1' ) then fifoOut <= '1'; else fifoOut <= '0'; end if; if( bwindow = '1' ) then pVideoR <= '0' & colorCode( 4 downto 2 ) & "00"; pVideoG <= '0' & colorCode( 7 downto 5 ) & "00"; pVideoB <= '0' & colorCode( 1 downto 0 ) & "000"; else pVideoR <= (others => '0'); pVideoG <= (others => '0'); pVideoB <= (others => '0'); pVideoB <= (others => '0'); end if; when "00" => if( VdpVramAccessing = '1' ) then pRamAdrX <= ("00" & VdpVramAccessAddr(16 downto 0)); if( VdpVramAccessRw = '0' ) then pRamDatX <= VdpVramAccessData; pRamOeX_n <= '1'; pRamWeX_n <= '0'; else pRamDatX <= (others => 'Z' ); pRamOeX_n <= '0'; pRamWeX_n <= '1'; end if; end if; if( window = '1' ) then if( (SpPattern0(16) = '1') or (SpPattern1(16) = '1') or (SpPattern2(16) = '1') or (SpPattern3(16) = '1') ) then colorCode <= spColorCode & "0000"; else colorCode <= fifoData_out; end if; fifoAddr_out <= fifoAddr_out + 1; else colorCode <= "00000011"; end if; if( (pWindow = '1') and (VramReadFreeFlag = '0' ) ) then fifoIn <= '1'; end if; when "01" => if( (pWindow = '1') and (VramReadFreeFlag = '0' ) ) then fifoIn <= '0'; end if; when "11" => pRamWeX_n <= '1'; pRamWeY_n <= '1'; pRamOeX_n <= '1'; pRamOeY_n <= '1'; pRamDatX <= (others => 'Z' ); pRamDatY <= (others => 'Z' ); if( (pWindow = '1') and (VramReadFreeFlag = '0' ) ) then fifoAddr_in <= fifoAddr_in + 1; end if; if( VdpVramAccessing = '1' ) then VdpVramAccessing <= '0'; VdpVramWrAck <= not VdpVramWrAck; end if; when others => null; end case; case dotState is when "10" => if( pDotCounter_x = 255 ) then SpPreReadCounter <= (others => '0'); SpPreReadCounter2 <= (others => '0'); SpY <= dotCounter_y( 7 downto 0); end if; when "00" => null; when "01" => if( (SpPreReadState /= spstate_idle) and (VramReadFreeFlag = '0' ) ) then case SpPreReadState is when spstate_yread => SpPreReadY <= SpY - pRamDatX; when spstate_xread => case SpPreReadCounter2 is when "0000" => SpX0 <= pRamDatX; when "0001" => SpX1 <= pRamDatX; when "0010" => SpX2 <= pRamDatX; when "0011" => SpX3 <= pRamDatX; when others => null; end case; when spstate_ptnnumread => SpPreReadPtnNum <= pRamDatX; when spstate_colorread => case SpPreReadCounter2 is when "0000" => SpColor0 <= pRamDatX( 3 downto 0); SpEC0 <= pRamDatX(7); SpCC0 <= pRamDatX(6); SpIC0 <= pRamDatX(5); when "0001" => SpColor1 <= pRamDatX( 3 downto 0); SpEC1 <= pRamDatX(7); SpCC1 <= pRamDatX(6); SpIC1 <= pRamDatX(5); when "0010" => SpColor2 <= pRamDatX( 3 downto 0); SpEC2 <= pRamDatX(7); SpCC2 <= pRamDatX(6); SpIC2 <= pRamDatX(5); when "0011" => SpColor3 <= pRamDatX( 3 downto 0); SpEC3 <= pRamDatX(7); SpCC3 <= pRamDatX(6); SpIC3 <= pRamDatX(5); when others => null; end case; when spstate_ptnread1 => case SpPreReadCounter2 is when "0000" => SpPattern0(16 downto 8) <= '0' & pRamDatX; when "0001" => SpPattern1(16 downto 8) <= '0' & pRamDatX; when "0010" => SpPattern2(16 downto 8) <= '0' & pRamDatX; when "0011" => SpPattern3(16 downto 8) <= '0' & pRamDatX; when others => null; end case; when spstate_ptnread2 => if( VdpR1SpSize = '0' ) then -- 8x8 mode case SpPreReadCounter2 is when "0000" => SpPattern0(7 downto 0) <= (others =>'0'); when "0001" => SpPattern1(7 downto 0) <= (others =>'0'); when "0010" => SpPattern2(7 downto 0) <= (others =>'0'); when "0011" => SpPattern3(7 downto 0) <= (others =>'0'); when others => null; end case; else -- 16x16 mode case SpPreReadCounter2 is when "0000" => SpPattern0(7 downto 0) <= pRamDatX; when "0001" => SpPattern1(7 downto 0) <= pRamDatX; when "0010" => SpPattern2(7 downto 0) <= pRamDatX; when "0011" => SpPattern3(7 downto 0) <= pRamDatX; when others => null; end case; end if; when others => null; end case; end if; when "11" => if( (SpPreReadState /= spstate_idle) and (VramReadFreeFlag = '0' ) )then case SpPreReadState is when spstate_idle => if( SpPreReadCounter = "00000" ) then SpPreReadState <= spstate_yread; end if; when spstate_yread => if( (SpPreReadY( 7 downto 3) = "00000") and (VdpR1SpSize = '0' ) )then SpPreReadState <= spstate_xread; elsif( (SpPreReadY( 7 downto 4) = "0000") and (VdpR1SpSize = '1' ) )then SpPreReadState <= spstate_xread; else if( SpPreReadCounter = "11111" ) then SpPreReadState <= spstate_idle; else SpPreReadState <= spstate_yread; SpPreReadCounter <= SpPreReadCounter + 1; end if; end if; when spstate_xread => SpPreReadState <= spstate_ptnnumread; when spstate_ptnnumread => SpPreReadState <= spstate_colorread; when spstate_colorread => SpPreReadState <= spstate_ptnread1; when spstate_ptnread1 => SpPreReadState <= spstate_ptnread2; when spstate_ptnread2 => SpPreReadCounter <= SpPreReadCounter + 1; SpPreReadCounter2 <= SpPreReadCounter2 + 1; if( SpPreReadCounter2 = "0011" ) then -- 横4つ分のスプライトを読んだ SpPreReadState <= spstate_idle; else SpPreReadState <= spstate_yread; end if; when others => null; end case; end if; if( SpX0 = "00000000") then SpPattern0 <= SpPattern0(15 downto 0) & '0'; end if; if( SpX1 = "00000000") then SpPattern1 <= SpPattern1(15 downto 0) & '0'; end if; if( SpX2 = "00000000") then SpPattern2 <= SpPattern2(15 downto 0) & '0'; end if; if( SpX3 = "00000000") then SpPattern3 <= SpPattern3(15 downto 0) & '0'; end if; if( window_x = '1' ) then if( SpX0 /= "00000000" ) then SpX0 <= SpX0 - 1; end if; if( SpX1 /= "00000000" ) then SpX1 <= SpX1 - 1; end if; if( SpX2 /= "00000000" ) then SpX2 <= SpX2 - 1; end if; if( SpX3 /= "00000000" ) then SpX3 <= SpX3 - 1; end if; elsif( spwindow_x = '1' ) then if( (SpEC0='1') and (SpX0 /= "00000000") ) then SpX0 <= SpX0 - 1; end if; if( (SpEC1='1') and (SpX1 /= "00000000") ) then SpX1 <= SpX1 - 1; end if; if( (SpEC2='1') and (SpX2 /= "00000000") ) then SpX2 <= SpX2 - 1; end if; if( (SpEC3='1') and (SpX3 /= "00000000") ) then SpX3 <= SpX3 - 1; end if; end if; when others => null; end case; end if; end process; pSltRsv5 <= '1'; pSltRsv16 <= '1'; pSltBdir_n <= '0' when pSltSltsl_n = '0' and pSltRd_n = '0' else '1'; pSltDat <= (others => 'Z'); -- MSX slot access IopAcs <= '1' when IopAcs0 = '1' and IopAcs1 = '0' else '0'; IopAcs0 <= '1' when pSltIorq_n = '0' and (pSltRd_n = '0' or pSltWr_n = '0') else '0'; process(pSltClk, pSltRst_n) begin if (pSltRst_n = '0') then IopAcs1 <= '0'; elsif (pSltClk'event and pSltClk = '1') then IopAcs1 <= IopAcs0; end if; end process; -- VDP register access process( pSltClk, pSltRst_n ) begin if (pSltRst_n = '0') then VdpIs1stByte <= '1'; VdpRegWrPulse <= '0'; VdpVramAddrSetReq <= '0'; VdpVramWrReq <= '0'; VdpVramAddrSetAck <= '0'; VdpVramAccessRw <= '0'; VdpVramAccessAddr <= (others => '0'); VdpVramAccessAddrTmp <= (others => '0'); VdpR11R5SpAttrTblBaseAddr <= (others => '0'); VdpR6SpPtnGeneTblBaseAddr <= (others => '0'); VdpR9TwoPageMode <= '0'; VdpR9InterraceMode <= '0'; elsif (pSltClk'event and pSltClk = '1') then if( IopAcs = '1' and pSltWr_n = '0' and pSltAdr(7 downto 0) = "10011000") then -- port#0 write ( 0x88 for MSX1 アダプタ, 0x98 for MSX2 ) VdpVramWrReq <= not VdpVramWrAck; -- VdpP0Data <= pSltDat( 7 downto 0); VdpVramAccessData <= pSltDat( 7 downto 0); if( VdpVramAddrSetReq /= VdpVramAddrSetAck ) then VdpVramAccessAddr <= VdpVramAccessAddrTmp; VdpVramAddrSetAck <= not VdpVramAddrSetAck; else VdpVramAccessAddr <= VdpVramAccessAddr + 1; end if; elsif( IopAcs = '1' and pSltRd_n = '0' and pSltAdr(7 downto 0) = "10011000") then -- port#0 read null; elsif( IopAcs = '1' and pSltWr_n = '0' and pSltAdr(7 downto 0) = "10011001") then -- port#1 write case VdpIs1stByte is when '1' => VdpP1Data <= pSltDat( 7 downto 0); VdpIs1stByte <= '0'; when '0' => case pSltDat( 7 downto 6 ) is when "01" => -- set vram access address(write) VdpVramAccessAddrTmp( 7 downto 0 ) <= VdpP1Data( 7 downto 0); VdpVramAccessAddrTmp(13 downto 8 ) <= pSltDat( 5 downto 0); VdpVramAddrSetReq <= not VdpVramAddrSetAck; VdpVramAccessRw <= '0'; when "00" => -- set vram access address(read) VdpVramAccessAddrTmp( 7 downto 0 ) <= VdpP1Data( 7 downto 0); VdpVramAccessAddrTmp(13 downto 8 ) <= pSltDat( 5 downto 0); VdpVramAddrSetReq <= not VdpVramAddrSetAck; VdpVramAccessRw <= '1'; when "10" => -- chokusetsu register shitei VdpRegPtr <= pSltDat( 5 downto 0); VdpRegWrPulse <= '1'; when others => null; end case; VdpIs1stByte <= '1'; when others => null; end case; elsif( IopAcs = '1' and pSltRd_n = '0' and pSltAdr(7 downto 0) = "10011001") then --- port#1 read VdpIs1stByte <= '1'; elsif( IopAcs = '1' and pSltWr_n = '0' and pSltAdr(7 downto 0) = "10011010") then --- port#2 write null; elsif( IopAcs = '1' and pSltRd_n = '0' and pSltAdr(7 downto 0) = "10011010") then --- port#2 read null; elsif( IopAcs = '1' and pSltWr_n = '0' and pSltAdr(7 downto 0) = "10011011") then --- port#3 write VdpRegWrPulse <= '1'; VdpP1Data <= pSltDat( 7 downto 0); VdpRegPtr <= VdpR17RegNum; if( VdpR17IncRegNum = '1' ) then VdpR17RegNum <= VdpR17RegNum + 1; end if; elsif( IopAcs = '1' and pSltRd_n = '0' and pSltAdr(7 downto 0) = "10011011") then --- port#3 read null; elsif( VdpRegWrPulse = '1' ) then -- register write VdpRegWrPulse <= '0'; case VdpRegPtr is when "000000" => -- #00 VdpR0DispNum <= VdpP1Data(3 downto 1); if( (VdpR1DispMode = "00") and (VdpP1Data( 3 downto 1 ) /= "000") and (VdpP1Data( 3 downto 1 ) /= "001" ) ) then SpMode2 <= '1'; else SpMode2 <= '0'; end if; when "000001" => -- #01 VdpR1SpSize <= VdpP1Data(1); VdpR1DispMode <= VdpP1Data(4 downto 3); if( (VdpP1Data(4 downto 3) = "00") and (VdpR0DispNum /= "000") and (VdpR0DispNum /= "001" ) ) then SpMode2 <= '1'; else SpMode2 <= '0'; end if; when "000101" => -- #05 VdpR11R5SpAttrTblBaseAddr( 4 downto 0) <= VdpP1Data( 7 downto 3); when "000110" => -- #06 VdpR6SpPtnGeneTblBaseAddr <= VdpP1Data( 5 downto 0); when "001001" => -- #09 VdpR9TwoPageMode <= VdpP1Data(2); VdpR9InterraceMode <= VdpP1Data(3); when "001011" => -- #11 VdpR11R5SpAttrTblBaseAddr( 6 downto 5) <= VdpP1Data( 1 downto 0); when "001110" => -- #14 VdpVramAccessAddrTmp( 16 downto 14 ) <= VdpP1Data( 2 downto 0); VdpVramAddrSetReq <= not VdpVramAddrSetAck; when "010001" => -- #17 VdpR17RegNum <= VdpP1Data( 5 downto 0 ); VdpR17IncRegNum <= not VdpP1Data(7); when others => null; end case; end if; end if; end process; end RTL;