├── README.md ├── src ├── ram.vhd ├── linebuf.vhd ├── ntsc.vhd ├── doublebuf.vhd ├── vga.vhd ├── vdp_package.vhd ├── kuni_top.vhd └── vdp.vhd └── LICENSE /README.md: -------------------------------------------------------------------------------- 1 | # ESE-VDP (FPGA implementation of YAMAHA V9938) 2 | 3 | It was made for 1-chip MSX when I was in my 20s. I publish this source code for the purpose of my memory. 4 | 5 | # License 6 | 7 | This repository is published under CC BY-NC (Creative Commons Attribution-NonCommercial 4.0 International Public License). 8 | 9 | 本リポジトリはクリエイティブコモンズの CC BY-NC ライセンスの元に公開します。 10 | 11 | # Copyright 12 | 13 | Copyright (C) 2000-2020 Kunihiko Ohnaka All rights reserved. 14 | -------------------------------------------------------------------------------- /src/ram.vhd: -------------------------------------------------------------------------------- 1 | library IEEE; 2 | use IEEE.std_logic_1164.all; 3 | use IEEE.std_logic_unsigned.all; 4 | 5 | entity ram is 6 | port ( 7 | address : in std_logic_vector(7 downto 0); 8 | inclock : in std_logic; 9 | we : in std_logic; 10 | data : in std_logic_vector(7 downto 0); 11 | q : out std_logic_vector(7 downto 0) 12 | ); 13 | end ram; 14 | 15 | architecture RTL of ram is 16 | type Mem is array (255 downto 0) of std_logic_vector(7 downto 0); 17 | signal WaveMem : Mem; 18 | signal iAddress : std_logic_vector(7 downto 0); 19 | 20 | begin 21 | 22 | process (inclock) 23 | begin 24 | if (inclock'event and inclock ='1') then 25 | if (we = '1') then 26 | WaveMem(conv_integer(address)) <= data; 27 | end if; 28 | iAddress <= address; 29 | end if; 30 | end process; 31 | 32 | q <= WaveMem(conv_integer(iAddress)); 33 | 34 | end RTL; 35 | -------------------------------------------------------------------------------- /src/linebuf.vhd: -------------------------------------------------------------------------------- 1 | library IEEE; 2 | use IEEE.std_logic_1164.all; 3 | use IEEE.std_logic_unsigned.all; 4 | 5 | entity linebuf is 6 | port ( 7 | address : in std_logic_vector(9 downto 0); 8 | inclock : in std_logic; 9 | we : in std_logic; 10 | data : in std_logic_vector(5 downto 0); 11 | q : out std_logic_vector(5 downto 0) 12 | ); 13 | end linebuf; 14 | 15 | architecture RTL of linebuf is 16 | -- type Mem is array (639 downto 0) of std_logic_vector(5 downto 0); 17 | type Mem is array (639 downto 0) of std_logic_vector(3 downto 0); 18 | signal iMem : Mem; 19 | signal iAddress : std_logic_vector(9 downto 0); 20 | 21 | begin 22 | 23 | process (inclock) 24 | begin 25 | if (inclock'event and inclock ='1') then 26 | if (we = '1') then 27 | -- iMem(conv_integer(address)) <= data(5 downto 0); 28 | iMem(conv_integer(address)) <= data(5 downto 2); 29 | end if; 30 | iAddress <= address; 31 | end if; 32 | end process; 33 | 34 | -- q <= iMem(conv_integer(iAddress)); 35 | q <= iMem(conv_integer(iAddress)) & "00"; 36 | 37 | end RTL; 38 | -------------------------------------------------------------------------------- /src/ntsc.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- ntsc.vhd 3 | -- VHDL Source of ESE-VDP. 4 | -- 5 | -- Copyright (C)2000-2003 Kunihiko Ohnaka 6 | -- All rights reserved. 7 | -- 8 | -- JP: 日本語のコメント行は JP:を頭に付ける事にする 9 | -- (Japanese comment line starts with "JP:") 10 | -- 11 | -- 13th,Octobre,2003 created by Kunihiko Ohnaka 12 | -- JP: VDPのコアの実装と表示デバイスへの出力を別ソースにした. 13 | 14 | library ieee; 15 | use ieee.std_logic_1164.all; 16 | use ieee.std_logic_unsigned.all; 17 | use work.vdp_package.all; 18 | 19 | entity ntsc is 20 | port( 21 | -- VDP clock ... 21.477MHz 22 | clk21m : in std_logic; 23 | reset : in std_logic; 24 | 25 | -- Video Input 26 | videoRin : in std_logic_vector( 5 downto 0); 27 | videoGin : in std_logic_vector( 5 downto 0); 28 | videoBin : in std_logic_vector( 5 downto 0); 29 | videoHSin_n : in std_logic; 30 | videoVSin_n : in std_logic; 31 | 32 | -- Video Output 33 | videoRout : out std_logic_vector( 5 downto 0); 34 | videoGout : out std_logic_vector( 5 downto 0); 35 | videoBout : out std_logic_vector( 5 downto 0); 36 | videoHSout_n : out std_logic; 37 | videoVSout_n : out std_logic 38 | ); 39 | end ntsc; 40 | 41 | architecture rtl of ntsc is 42 | begin 43 | 44 | videoHSout_n <= videoHSin_n; 45 | videoVSout_n <= videoVSin_n; 46 | 47 | videoRout <= videoRin; 48 | videoGout <= videoGin; 49 | videoBout <= videoBin; 50 | 51 | end rtl; 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/doublebuf.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- doublebuf.vhd 3 | -- Double Buffered Line Memory. 4 | -- 5 | -- Copyright (C)2000-2003 Kunihiko Ohnaka 6 | -- All rights reserved. 7 | -- $Id: linebuf.vhd,v 1.1 2003/03/30 03:43:20 kuni Exp $ 8 | 9 | -- JP: ダブルバッファリング機能付きラインバッファモジュール. 10 | -- JP: xPositionWに X座標を入れ,weを 1にすると書き込みバッファに 11 | -- JP: 書き込まれる.また,xPositionRに X座標を入れると,読み込み 12 | -- JP: バッファから読み出した色コードが qから出力される. 13 | -- JP: evenOdd信号によって,読み込みバッファと書き込みバッファが 14 | -- JP: 切り替わる. 15 | 16 | library IEEE; 17 | use IEEE.std_logic_1164.all; 18 | use IEEE.std_logic_unsigned.all; 19 | use work.vdp_package.all; 20 | 21 | entity doublebuf is 22 | port ( 23 | clk : in std_logic; 24 | xPositionW : in std_logic_vector(9 downto 0); 25 | xPositionR : in std_logic_vector(9 downto 0); 26 | evenOdd : in std_logic; 27 | we : in std_logic; 28 | dataRin : in std_logic_vector(5 downto 0); 29 | dataGin : in std_logic_vector(5 downto 0); 30 | dataBin : in std_logic_vector(5 downto 0); 31 | dataRout : out std_logic_vector(5 downto 0); 32 | dataGout : out std_logic_vector(5 downto 0); 33 | dataBout : out std_logic_vector(5 downto 0) 34 | ); 35 | end doublebuf; 36 | 37 | architecture RTL of doublebuf is 38 | signal we_e : std_logic; 39 | signal we_o : std_logic; 40 | signal addr_e : std_logic_vector(9 downto 0); 41 | signal addr_o : std_logic_vector(9 downto 0); 42 | signal outR_e : std_logic_vector(5 downto 0); 43 | signal outG_e : std_logic_vector(5 downto 0); 44 | signal outB_e : std_logic_vector(5 downto 0); 45 | signal outR_o : std_logic_vector(5 downto 0); 46 | signal outG_o : std_logic_vector(5 downto 0); 47 | signal outB_o : std_logic_vector(5 downto 0); 48 | begin 49 | 50 | bufRe : linebuf port map(addr_e, clk, we_e, dataRin, outR_e); 51 | bufGe : linebuf port map(addr_e, clk, we_e, dataGin, outG_e); 52 | bufBe : linebuf port map(addr_e, clk, we_e, dataBin, outB_e); 53 | 54 | bufRo : linebuf port map(addr_o, clk, we_o, dataRin, outR_o); 55 | bufGo : linebuf port map(addr_o, clk, we_o, dataGin, outG_o); 56 | bufBo : linebuf port map(addr_o, clk, we_o, dataBin, outB_o); 57 | 58 | we_e <= we when evenOdd = '0' else '0'; 59 | we_o <= we when evenOdd = '1' else '0'; 60 | 61 | addr_e <= xPositionW when evenOdd = '0' else xPositionR; 62 | addr_o <= xPositionW when evenOdd = '1' else xPositionR; 63 | 64 | dataRout <= outR_e when evenOdd = '1' else outR_o; 65 | dataGout <= outG_e when evenOdd = '1' else outG_o; 66 | dataBout <= outB_e when evenOdd = '1' else outB_o; 67 | 68 | end RTL; 69 | -------------------------------------------------------------------------------- /src/vga.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- vga.vhd 3 | -- VHDL Source of ESE-VDP. 4 | -- 5 | -- Copyright (C)2000-2003 Kunihiko Ohnaka 6 | -- All rights reserved. 7 | -- 8 | -- JP: 日本語のコメント行は JP:を頭に付ける事にする 9 | -- (Japanese comment line starts with "JP:") 10 | -- 11 | -- 13th,Octobre,2003 created by Kunihiko Ohnaka 12 | -- JP: VDPのコアの実装と表示デバイスへの出力を別ソースにした. 13 | 14 | library ieee; 15 | use ieee.std_logic_1164.all; 16 | use ieee.std_logic_unsigned.all; 17 | use work.vdp_package.all; 18 | 19 | entity vga is 20 | port( 21 | -- VDP clock ... 21.477MHz 22 | clk21m : in std_logic; 23 | reset : in std_logic; 24 | 25 | -- Video Input 26 | videoRin : in std_logic_vector( 5 downto 0); 27 | videoGin : in std_logic_vector( 5 downto 0); 28 | videoBin : in std_logic_vector( 5 downto 0); 29 | hCounterIn : in std_logic_vector(10 downto 0); 30 | vCounterIn : in std_logic_vector(10 downto 0); 31 | 32 | -- Video Output 33 | videoRout : out std_logic_vector( 5 downto 0); 34 | videoGout : out std_logic_vector( 5 downto 0); 35 | videoBout : out std_logic_vector( 5 downto 0); 36 | videoHSout_n : out std_logic; 37 | videoVSout_n : out std_logic 38 | ); 39 | end vga; 40 | 41 | architecture rtl of vga is 42 | -- H counter 43 | signal videoOut : std_logic; 44 | 45 | -- double buffer signal 46 | signal xPositionW : std_logic_vector(9 downto 0); 47 | signal xPositionR : std_logic_vector(9 downto 0); 48 | signal evenOdd : std_logic; 49 | signal we_buf : std_logic; 50 | signal dataRout : std_logic_vector(5 downto 0); 51 | signal dataGout : std_logic_vector(5 downto 0); 52 | signal dataBout : std_logic_vector(5 downto 0); 53 | 54 | -- DISP_START_X + DISP_WIDTH < CLOCKS_PER_LINE/2 = 684 55 | constant DISP_WIDTH : integer := 562; -- 30 + 512 + 20 56 | constant DISP_START_X : integer := 120; 57 | begin 58 | 59 | videoRout <= dataRout when videoOut = '1' else (others => '0'); 60 | videoGout <= dataGout when videoOut = '1' else (others => '0'); 61 | videoBout <= dataBout when videoOut = '1' else (others => '0'); 62 | 63 | dbuf : doublebuf port map(clk21m, xPositionW, xPositionR, evenOdd, we_buf, 64 | videoRin, videoGin, videoBin, 65 | dataRout, dataGout, dataBout); 66 | 67 | xPositionW <= hCounterIn(10 downto 1) - (CLOCKS_PER_LINE/2 - DISP_WIDTH - 10); 68 | evenOdd <= vCounterIn(1); 69 | we_buf <= '1'; 70 | 71 | process( clk21m, reset ) 72 | begin 73 | if (reset = '1') then 74 | videoHSout_n <= '1'; 75 | videoVSout_n <= '1'; 76 | videoOut <= '0'; 77 | xPositionR <= (others => '0'); 78 | elsif (clk21m'event and clk21m = '1') then 79 | 80 | -- JP:垂直同期信号の生成 81 | if( (vCounterIn = 3*2) or (vCounterIn = 525+3*2) )then 82 | videoVSout_n <= '0'; 83 | elsif( (vCounterIn = 6*2) or (vCounterIn = 525+6*2) ) then 84 | videoVSout_n <= '1'; 85 | end if; 86 | 87 | -- JP:水平同期信号の生成 88 | if( (hCounterIn = 0) or (hCounterIn = (CLOCKS_PER_LINE/2)) ) then 89 | videoHSout_n <= '0'; 90 | elsif( (hCounterIn = 40) or (hCounterIn = (CLOCKS_PER_LINE/2) + 40) ) then 91 | videoHSout_n <= '1'; 92 | end if; 93 | 94 | -- JP:映像信号 95 | if( (hCounterIn = DISP_START_X) or 96 | (hCounterIn = DISP_START_X + (CLOCKS_PER_LINE/2)) ) then 97 | videoOut <= '1'; 98 | xPositionR <= (others => '0'); 99 | elsif( (hCounterIn = DISP_START_X+DISP_WIDTH) or 100 | (hCounterIn = DISP_START_X+DISP_WIDTH + (CLOCKS_PER_LINE/2)) ) then 101 | videoOut <= '0'; 102 | else 103 | xPositionR <= xPositionR + 1; 104 | end if; 105 | 106 | end if; 107 | 108 | end process; 109 | end rtl; 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/vdp_package.vhd: -------------------------------------------------------------------------------- 1 | library ieee; 2 | use ieee.std_logic_1164.all; 3 | use ieee.std_logic_unsigned.all; 4 | 5 | package vdp_package is 6 | 7 | -- VDP ID 8 | constant VDP_ID : std_logic_vector(4 downto 0) := "00000"; -- V9938 9 | -- constant VDP_ID : std_logic_vector(4 downto 0) := "00001"; -- unknown 10 | -- constant VDP_ID : std_logic_vector(4 downto 0) := "00010"; -- V9958 11 | 12 | -- switch the default display mode (NTSC or VGA) 13 | -- constant DISPLAY_MODE : std_logic := '0'; -- NTSC 14 | constant DISPLAY_MODE : std_logic := '1'; -- VGA 15 | 16 | constant CLOCKS_PER_LINE : integer := 1368; -- 342x4 17 | 18 | constant ADJUST0_X_NTSC : std_logic_vector( 6 downto 0) := "0110110"; -- = 220/4; 19 | constant ADJUST0_X_VGA : std_logic_vector( 6 downto 0) := "0011011"; -- = 220/4/2; 20 | constant ADJUST0_Y : std_logic_vector( 6 downto 0) := "0101110"; -- = 3+3+13+26+1 = 46 21 | constant ADJUST0_Y_212 : std_logic_vector( 6 downto 0) := "0100100"; -- = 3+3+13+16+1 = 36 22 | 23 | component ram 24 | port( 25 | address : IN std_logic_vector(7 downto 0); 26 | inclock : IN std_logic; 27 | we : IN std_logic; 28 | data : IN std_logic_vector(7 downto 0); 29 | q : OUT std_logic_vector(7 downto 0) 30 | ); 31 | end component; 32 | 33 | component ntsc 34 | port( 35 | -- VDP clock ... 21.477MHz 36 | clk21m : in std_logic; 37 | reset : in std_logic; 38 | 39 | -- Video Input 40 | videoRin : in std_logic_vector( 5 downto 0); 41 | videoGin : in std_logic_vector( 5 downto 0); 42 | videoBin : in std_logic_vector( 5 downto 0); 43 | videoHSin_n : in std_logic; 44 | videoVSin_n : in std_logic; 45 | 46 | -- Video Output 47 | videoRout : out std_logic_vector( 5 downto 0); 48 | videoGout : out std_logic_vector( 5 downto 0); 49 | videoBout : out std_logic_vector( 5 downto 0); 50 | videoHSout_n : out std_logic; 51 | videoVSout_n : out std_logic 52 | ); 53 | end component; 54 | 55 | component vga 56 | port( 57 | -- VDP clock ... 21.477MHz 58 | clk21m : in std_logic; 59 | reset : in std_logic; 60 | 61 | -- Video Input 62 | videoRin : in std_logic_vector( 5 downto 0); 63 | videoGin : in std_logic_vector( 5 downto 0); 64 | videoBin : in std_logic_vector( 5 downto 0); 65 | hCounterIn : in std_logic_vector(10 downto 0); 66 | vCounterIn : in std_logic_vector(10 downto 0); 67 | 68 | -- Video Output 69 | videoRout : out std_logic_vector( 5 downto 0); 70 | videoGout : out std_logic_vector( 5 downto 0); 71 | videoBout : out std_logic_vector( 5 downto 0); 72 | videoHSout_n : out std_logic; 73 | videoVSout_n : out std_logic 74 | ); 75 | end component; 76 | 77 | component doublebuf 78 | port ( 79 | clk : in std_logic; 80 | xPositionW : in std_logic_vector(9 downto 0); 81 | xPositionR : in std_logic_vector(9 downto 0); 82 | evenOdd : in std_logic; 83 | we : in std_logic; 84 | dataRin : in std_logic_vector(5 downto 0); 85 | dataGin : in std_logic_vector(5 downto 0); 86 | dataBin : in std_logic_vector(5 downto 0); 87 | dataRout : out std_logic_vector(5 downto 0); 88 | dataGout : out std_logic_vector(5 downto 0); 89 | dataBout : out std_logic_vector(5 downto 0) 90 | ); 91 | end component; 92 | 93 | component linebuf 94 | port ( 95 | address : in std_logic_vector(9 downto 0); 96 | inclock : in std_logic; 97 | we : in std_logic; 98 | data : in std_logic_vector(5 downto 0); 99 | q : out std_logic_vector(5 downto 0) 100 | ); 101 | end component; 102 | 103 | end vdp_package; 104 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution-NonCommercial 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution-NonCommercial 4.0 International Public 58 | License 59 | 60 | By exercising the Licensed Rights (defined below), You accept and agree 61 | to be bound by the terms and conditions of this Creative Commons 62 | Attribution-NonCommercial 4.0 International Public License ("Public 63 | License"). To the extent this Public License may be interpreted as a 64 | contract, You are granted the Licensed Rights in consideration of Your 65 | acceptance of these terms and conditions, and the Licensor grants You 66 | such rights in consideration of benefits the Licensor receives from 67 | making the Licensed Material available under these terms and 68 | conditions. 69 | 70 | 71 | Section 1 -- Definitions. 72 | 73 | a. Adapted Material means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material 75 | and in which the Licensed Material is translated, altered, 76 | arranged, transformed, or otherwise modified in a manner requiring 77 | permission under the Copyright and Similar Rights held by the 78 | Licensor. For purposes of this Public License, where the Licensed 79 | Material is a musical work, performance, or sound recording, 80 | Adapted Material is always produced where the Licensed Material is 81 | synched in timed relation with a moving image. 82 | 83 | b. Adapter's License means the license You apply to Your Copyright 84 | and Similar Rights in Your contributions to Adapted Material in 85 | accordance with the terms and conditions of this Public License. 86 | 87 | c. Copyright and Similar Rights means copyright and/or similar rights 88 | closely related to copyright including, without limitation, 89 | performance, broadcast, sound recording, and Sui Generis Database 90 | Rights, without regard to how the rights are labeled or 91 | categorized. For purposes of this Public License, the rights 92 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 93 | Rights. 94 | d. Effective Technological Measures means those measures that, in the 95 | absence of proper authority, may not be circumvented under laws 96 | fulfilling obligations under Article 11 of the WIPO Copyright 97 | Treaty adopted on December 20, 1996, and/or similar international 98 | agreements. 99 | 100 | e. Exceptions and Limitations means fair use, fair dealing, and/or 101 | any other exception or limitation to Copyright and Similar Rights 102 | that applies to Your use of the Licensed Material. 103 | 104 | f. Licensed Material means the artistic or literary work, database, 105 | or other material to which the Licensor applied this Public 106 | License. 107 | 108 | g. Licensed Rights means the rights granted to You subject to the 109 | terms and conditions of this Public License, which are limited to 110 | all Copyright and Similar Rights that apply to Your use of the 111 | Licensed Material and that the Licensor has authority to license. 112 | 113 | h. Licensor means the individual(s) or entity(ies) granting rights 114 | under this Public License. 115 | 116 | i. NonCommercial means not primarily intended for or directed towards 117 | commercial advantage or monetary compensation. For purposes of 118 | this Public License, the exchange of the Licensed Material for 119 | other material subject to Copyright and Similar Rights by digital 120 | file-sharing or similar means is NonCommercial provided there is 121 | no payment of monetary compensation in connection with the 122 | exchange. 123 | 124 | j. Share means to provide material to the public by any means or 125 | process that requires permission under the Licensed Rights, such 126 | as reproduction, public display, public performance, distribution, 127 | dissemination, communication, or importation, and to make material 128 | available to the public including in ways that members of the 129 | public may access the material from a place and at a time 130 | individually chosen by them. 131 | 132 | k. Sui Generis Database Rights means rights other than copyright 133 | resulting from Directive 96/9/EC of the European Parliament and of 134 | the Council of 11 March 1996 on the legal protection of databases, 135 | as amended and/or succeeded, as well as other essentially 136 | equivalent rights anywhere in the world. 137 | 138 | l. You means the individual or entity exercising the Licensed Rights 139 | under this Public License. Your has a corresponding meaning. 140 | 141 | 142 | Section 2 -- Scope. 143 | 144 | a. License grant. 145 | 146 | 1. Subject to the terms and conditions of this Public License, 147 | the Licensor hereby grants You a worldwide, royalty-free, 148 | non-sublicensable, non-exclusive, irrevocable license to 149 | exercise the Licensed Rights in the Licensed Material to: 150 | 151 | a. reproduce and Share the Licensed Material, in whole or 152 | in part, for NonCommercial purposes only; and 153 | 154 | b. produce, reproduce, and Share Adapted Material for 155 | NonCommercial purposes only. 156 | 157 | 2. Exceptions and Limitations. For the avoidance of doubt, where 158 | Exceptions and Limitations apply to Your use, this Public 159 | License does not apply, and You do not need to comply with 160 | its terms and conditions. 161 | 162 | 3. Term. The term of this Public License is specified in Section 163 | 6(a). 164 | 165 | 4. Media and formats; technical modifications allowed. The 166 | Licensor authorizes You to exercise the Licensed Rights in 167 | all media and formats whether now known or hereafter created, 168 | and to make technical modifications necessary to do so. The 169 | Licensor waives and/or agrees not to assert any right or 170 | authority to forbid You from making technical modifications 171 | necessary to exercise the Licensed Rights, including 172 | technical modifications necessary to circumvent Effective 173 | Technological Measures. For purposes of this Public License, 174 | simply making modifications authorized by this Section 2(a) 175 | (4) never produces Adapted Material. 176 | 177 | 5. Downstream recipients. 178 | 179 | a. Offer from the Licensor -- Licensed Material. Every 180 | recipient of the Licensed Material automatically 181 | receives an offer from the Licensor to exercise the 182 | Licensed Rights under the terms and conditions of this 183 | Public License. 184 | 185 | b. No downstream restrictions. You may not offer or impose 186 | any additional or different terms or conditions on, or 187 | apply any Effective Technological Measures to, the 188 | Licensed Material if doing so restricts exercise of the 189 | Licensed Rights by any recipient of the Licensed 190 | Material. 191 | 192 | 6. No endorsement. Nothing in this Public License constitutes or 193 | may be construed as permission to assert or imply that You 194 | are, or that Your use of the Licensed Material is, connected 195 | with, or sponsored, endorsed, or granted official status by, 196 | the Licensor or others designated to receive attribution as 197 | provided in Section 3(a)(1)(A)(i). 198 | 199 | b. Other rights. 200 | 201 | 1. Moral rights, such as the right of integrity, are not 202 | licensed under this Public License, nor are publicity, 203 | privacy, and/or other similar personality rights; however, to 204 | the extent possible, the Licensor waives and/or agrees not to 205 | assert any such rights held by the Licensor to the limited 206 | extent necessary to allow You to exercise the Licensed 207 | Rights, but not otherwise. 208 | 209 | 2. Patent and trademark rights are not licensed under this 210 | Public License. 211 | 212 | 3. To the extent possible, the Licensor waives any right to 213 | collect royalties from You for the exercise of the Licensed 214 | Rights, whether directly or through a collecting society 215 | under any voluntary or waivable statutory or compulsory 216 | licensing scheme. In all other cases the Licensor expressly 217 | reserves any right to collect such royalties, including when 218 | the Licensed Material is used other than for NonCommercial 219 | purposes. 220 | 221 | 222 | Section 3 -- License Conditions. 223 | 224 | Your exercise of the Licensed Rights is expressly made subject to the 225 | following conditions. 226 | 227 | a. Attribution. 228 | 229 | 1. If You Share the Licensed Material (including in modified 230 | form), You must: 231 | 232 | a. retain the following if it is supplied by the Licensor 233 | with the Licensed Material: 234 | 235 | i. identification of the creator(s) of the Licensed 236 | Material and any others designated to receive 237 | attribution, in any reasonable manner requested by 238 | the Licensor (including by pseudonym if 239 | designated); 240 | 241 | ii. a copyright notice; 242 | 243 | iii. a notice that refers to this Public License; 244 | 245 | iv. a notice that refers to the disclaimer of 246 | warranties; 247 | 248 | v. a URI or hyperlink to the Licensed Material to the 249 | extent reasonably practicable; 250 | 251 | b. indicate if You modified the Licensed Material and 252 | retain an indication of any previous modifications; and 253 | 254 | c. indicate the Licensed Material is licensed under this 255 | Public License, and include the text of, or the URI or 256 | hyperlink to, this Public License. 257 | 258 | 2. You may satisfy the conditions in Section 3(a)(1) in any 259 | reasonable manner based on the medium, means, and context in 260 | which You Share the Licensed Material. For example, it may be 261 | reasonable to satisfy the conditions by providing a URI or 262 | hyperlink to a resource that includes the required 263 | information. 264 | 265 | 3. If requested by the Licensor, You must remove any of the 266 | information required by Section 3(a)(1)(A) to the extent 267 | reasonably practicable. 268 | 269 | 4. If You Share Adapted Material You produce, the Adapter's 270 | License You apply must not prevent recipients of the Adapted 271 | Material from complying with this Public License. 272 | 273 | 274 | Section 4 -- Sui Generis Database Rights. 275 | 276 | Where the Licensed Rights include Sui Generis Database Rights that 277 | apply to Your use of the Licensed Material: 278 | 279 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 280 | to extract, reuse, reproduce, and Share all or a substantial 281 | portion of the contents of the database for NonCommercial purposes 282 | only; 283 | 284 | b. if You include all or a substantial portion of the database 285 | contents in a database in which You have Sui Generis Database 286 | Rights, then the database in which You have Sui Generis Database 287 | Rights (but not its individual contents) is Adapted Material; and 288 | 289 | c. You must comply with the conditions in Section 3(a) if You Share 290 | all or a substantial portion of the contents of the database. 291 | 292 | For the avoidance of doubt, this Section 4 supplements and does not 293 | replace Your obligations under this Public License where the Licensed 294 | Rights include other Copyright and Similar Rights. 295 | 296 | 297 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 298 | 299 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 300 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 301 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 302 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 303 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 304 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 305 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 306 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 307 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 308 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 309 | 310 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 311 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 312 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 313 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 314 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 315 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 316 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 317 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 318 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 319 | 320 | c. The disclaimer of warranties and limitation of liability provided 321 | above shall be interpreted in a manner that, to the extent 322 | possible, most closely approximates an absolute disclaimer and 323 | waiver of all liability. 324 | 325 | 326 | Section 6 -- Term and Termination. 327 | 328 | a. This Public License applies for the term of the Copyright and 329 | Similar Rights licensed here. However, if You fail to comply with 330 | this Public License, then Your rights under this Public License 331 | terminate automatically. 332 | 333 | b. Where Your right to use the Licensed Material has terminated under 334 | Section 6(a), it reinstates: 335 | 336 | 1. automatically as of the date the violation is cured, provided 337 | it is cured within 30 days of Your discovery of the 338 | violation; or 339 | 340 | 2. upon express reinstatement by the Licensor. 341 | 342 | For the avoidance of doubt, this Section 6(b) does not affect any 343 | right the Licensor may have to seek remedies for Your violations 344 | of this Public License. 345 | 346 | c. For the avoidance of doubt, the Licensor may also offer the 347 | Licensed Material under separate terms or conditions or stop 348 | distributing the Licensed Material at any time; however, doing so 349 | will not terminate this Public License. 350 | 351 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 352 | License. 353 | 354 | 355 | Section 7 -- Other Terms and Conditions. 356 | 357 | a. The Licensor shall not be bound by any additional or different 358 | terms or conditions communicated by You unless expressly agreed. 359 | 360 | b. Any arrangements, understandings, or agreements regarding the 361 | Licensed Material not stated herein are separate from and 362 | independent of the terms and conditions of this Public License. 363 | 364 | 365 | Section 8 -- Interpretation. 366 | 367 | a. For the avoidance of doubt, this Public License does not, and 368 | shall not be interpreted to, reduce, limit, restrict, or impose 369 | conditions on any use of the Licensed Material that could lawfully 370 | be made without permission under this Public License. 371 | 372 | b. To the extent possible, if any provision of this Public License is 373 | deemed unenforceable, it shall be automatically reformed to the 374 | minimum extent necessary to make it enforceable. If the provision 375 | cannot be reformed, it shall be severed from this Public License 376 | without affecting the enforceability of the remaining terms and 377 | conditions. 378 | 379 | c. No term or condition of this Public License will be waived and no 380 | failure to comply consented to unless expressly agreed to by the 381 | Licensor. 382 | 383 | d. Nothing in this Public License constitutes or may be interpreted 384 | as a limitation upon, or waiver of, any privileges and immunities 385 | that apply to the Licensor or You, including from the legal 386 | processes of any jurisdiction or authority. 387 | 388 | ======================================================================= 389 | 390 | Creative Commons is not a party to its public 391 | licenses. Notwithstanding, Creative Commons may elect to apply one of 392 | its public licenses to material it publishes and in those instances 393 | will be considered the “Licensor.” The text of the Creative Commons 394 | public licenses is dedicated to the public domain under the CC0 Public 395 | Domain Dedication. Except for the limited purpose of indicating that 396 | material is shared under a Creative Commons public license or as 397 | otherwise permitted by the Creative Commons policies published at 398 | creativecommons.org/policies, Creative Commons does not authorize the 399 | use of the trademark "Creative Commons" or any other trademark or logo 400 | of Creative Commons without its prior written consent including, 401 | without limitation, in connection with any unauthorized modifications 402 | to any of its public licenses or any other arrangements, 403 | understandings, or agreements concerning use of licensed material. For 404 | the avoidance of doubt, this paragraph does not form part of the 405 | public licenses. 406 | 407 | Creative Commons may be contacted at creativecommons.org. 408 | -------------------------------------------------------------------------------- /src/kuni_top.vhd: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------- 2 | -- Title : msxation.vhd 3 | -- Function : PSG + SCC + RAM(EseSCC/SNATCHER compatible) 4 | -- Date : 4th,January,2003 5 | -- Revision : 3.00 6 | -- Author : Kazuhiro TSUJIKAWA (ESE Artists' factory) 7 | ---------------------------------------------------------------- 8 | library ieee; 9 | use ieee.std_logic_1164.all; 10 | use ieee.std_logic_unsigned.all; 11 | 12 | ---------------------------------------------------------------- 13 | -- CAUTION !!!!!! 14 | -- 15 | -- " --@ " = temporary description (for debugging) 16 | -- 17 | ---------------------------------------------------------------- 18 | 19 | -- slave mode 20 | -- Slot x-0 : none 21 | -- Slot x-1 : ESE-RAM 00000-1FFFF / 20000-3FFFF(BIOS) 22 | -- Slot x-2 : Mapper 40000-5FFFF / 60000-7FFFF(VRAM) 23 | -- Slot x-3 : none 24 | 25 | -- master mode 26 | -- Slot 0-0 : MAINROM 20000-27FFF 27 | -- Slot 0-2 : (SUBROM)+FMBIOS 28000-2FFFF 28 | -- Slot 1 : CONNECTOR 29 | -- Slot 2 : ESE-RAM 00000-1FFFF / 20000-3FFFF(BIOS) 30 | -- Slot 3-0 : Mapper 40000-5FFFF / 60000-7FFFF(VRAM) 31 | -- Slot 3-1 : SUBROM+KANJI 30000-3FFFF 32 | 33 | -- 256kB : 00000-3FFFFh / ESE-SCC 34 | -- 64kB : 40000-4FFFFh / DISK+SUB+MAIN 35 | -- 64kB : 50000-5FFFFh / Mapper 36 | -- 128kB : 60000-7FFFFh / VRAM 37 | 38 | entity kuni_top is 39 | port( 40 | -- VDP clock ... 21.48MHz 41 | pClk21m : in std_logic; 42 | 43 | -- MSX slot signals 44 | pSltClk : in std_logic; 45 | pSltRst_n : in std_logic; 46 | pSltSltsl_n : inout std_logic; 47 | pSltIorq_n : inout std_logic; 48 | pSltRd_n : inout std_logic; 49 | pSltWr_n : inout std_logic; 50 | pSltAdr : inout std_logic_vector(15 downto 0); 51 | pSltDat : inout std_logic_vector(7 downto 0); 52 | pSltBdir_n : out std_logic; 53 | 54 | -- pSltCs1 : inout std_logic; 55 | -- pSltCs2 : inout std_logic; 56 | pSltCs12 : inout std_logic; 57 | pSltRfsh_n : inout std_logic; 58 | pSltWait_n : inout std_logic; 59 | pSltInt_n : inout std_logic; 60 | pSltM1_n : inout std_logic; 61 | pSltMerq_n : inout std_logic; 62 | 63 | -- pSltClk2 : in std_logic; 64 | -- pSltRsv5 : out std_logic; 65 | -- pSltRsv16 : out std_logic; 66 | 67 | -- SRAM signals 68 | pRamCeX : out std_logic; 69 | pRamOeX_n : out std_logic; 70 | pRamWeX_n : out std_logic; 71 | pRamAdrX : out std_logic_vector(18 downto 0); 72 | pRamDatX : inout std_logic_vector(7 downto 0); 73 | 74 | -- pRamCeY_n : out std_logic; 75 | -- pRamOeY_n : out std_logic; 76 | -- pRamWeY_n : out std_logic; 77 | -- pRamAdrY : out std_logic_vector(18 downto 0); 78 | -- pRamDatY : inout std_logic_vector(7 downto 0); 79 | 80 | -- Sound output 81 | pSltSnd_L : inout std_logic_vector( 5 downto 0); -- KuniBoard only 82 | pSltSnd_R : inout std_logic_vector( 5 downto 0); -- KuniBoard only 83 | -- pSltSound : inout std_logic_vector( 5 downto 0); -- KuniBoard only 84 | 85 | pSelf : in std_logic; 86 | pClkEna_n : out std_logic; -- KuniBoard only 87 | pCpuClk : out std_logic; -- KuniBoard only 88 | pBusReq_n : inout std_logic; 89 | pCpuM1_n : inout std_logic; -- KuniBoard only 90 | pCpuRfsh_n : inout std_logic; -- KuniBoard only 91 | 92 | pKeyCaps : out std_logic; -- Kana lamp : 0=ON, Z=OFF 93 | pKeyKana : inout std_logic; -- Kana lamp : 0=ON, Z=OFF 94 | pKeyY : inout std_logic_vector( 9 downto 0); 95 | pKeyX : inout std_logic_vector( 7 downto 0); 96 | pJoyA : inout std_logic_vector( 5 downto 0); 97 | pStrA : out std_logic; 98 | pJoyB : inout std_logic_vector( 5 downto 0); 99 | pStrB : out std_logic; 100 | 101 | -- pVideoClk : out std_logic; -- Video DAC(MB40988) clock 102 | -- pVideoDHClk : out std_logic; -- dot clock high resolution (10.74MHz) 103 | -- pVideoDLClk : out std_logic; -- dot clock low resolution ( 5.37MHz) 104 | 105 | pVideoR : out std_logic_vector( 5 downto 0); -- KuniBoard only 106 | pVideoG : out std_logic_vector( 5 downto 0); -- KuniBoard only 107 | pVideoB : out std_logic_vector( 5 downto 0); -- KuniBoard only 108 | pVideoHS_n : out std_logic; -- KuniBoard only 109 | pVideoVS_n : out std_logic; -- KuniBoard only 110 | -- pVideoCS_n : out std_logic; -- KuniBoard only 111 | pVideoSC : out std_logic; -- KuniBoard only 112 | pVideoSYNC : out std_logic -- KuniBoard only 113 | ); 114 | end kuni_top; 115 | 116 | architecture rtl of kuni_top is 117 | 118 | component t80a 119 | port( 120 | RESET_n : in std_logic; 121 | CLK_n : in std_logic; 122 | WAIT_n : in std_logic; 123 | INT_n : in std_logic; 124 | NMI_n : in std_logic; 125 | BUSRQ_n : in std_logic; 126 | M1_n : out std_logic; 127 | MREQ_n : out std_logic; 128 | IORQ_n : out std_logic; 129 | RD_n : out std_logic; 130 | WR_n : out std_logic; 131 | RFSH_n : out std_logic; 132 | HALT_n : out std_logic; 133 | BUSAK_n : out std_logic; 134 | A : out std_logic_vector(15 downto 0); 135 | D : inout std_logic_vector(7 downto 0) 136 | ); 137 | end component; 138 | 139 | component psg 140 | port( 141 | clk21m : in std_logic; 142 | reset : in std_logic; 143 | clkena : in std_logic; 144 | req : in std_logic; 145 | ack : out std_logic; 146 | wrt : in std_logic; 147 | adr : in std_logic_vector(15 downto 0); 148 | dbi : out std_logic_vector(7 downto 0); 149 | dbo : in std_logic_vector(7 downto 0); 150 | 151 | joya : inout std_logic_vector(5 downto 0); 152 | stra : out std_logic; 153 | joyb : inout std_logic_vector(5 downto 0); 154 | strb : out std_logic; 155 | 156 | kana : out std_logic; 157 | cmtin : in std_logic; 158 | keymode : in std_logic; 159 | 160 | wave : out std_logic_vector(7 downto 0) 161 | ); 162 | end component; 163 | 164 | component rom 165 | port( 166 | clk : in std_logic; 167 | adr : in std_logic_vector(7 downto 0); 168 | dbi : out std_logic_vector(7 downto 0) 169 | ); 170 | end component; 171 | 172 | component esescc 173 | port( 174 | clk21m : in std_logic; 175 | reset : in std_logic; 176 | clkena : in std_logic; 177 | req : in std_logic; 178 | ack : out std_logic; 179 | wrt : in std_logic; 180 | adr : in std_logic_vector(15 downto 0); 181 | dbi : out std_logic_vector(7 downto 0); 182 | dbo : in std_logic_vector(7 downto 0); 183 | 184 | ramreq : out std_logic; 185 | ramwrt : out std_logic; 186 | ramadr : out std_logic_vector(19 downto 0); 187 | ramdbi : in std_logic_vector(7 downto 0); 188 | ramdbo : out std_logic_vector(7 downto 0); 189 | 190 | wavl : out std_logic_vector(7 downto 0); 191 | wavr : out std_logic_vector(7 downto 0) 192 | ); 193 | end component; 194 | 195 | component eseram 196 | port( 197 | clk21m : in std_logic; 198 | reset : in std_logic; 199 | clkena : in std_logic; 200 | req : in std_logic; 201 | ack : out std_logic; 202 | wrt : in std_logic; 203 | adr : in std_logic_vector(15 downto 0); 204 | dbi : out std_logic_vector(7 downto 0); 205 | dbo : in std_logic_vector(7 downto 0); 206 | 207 | ramreq : out std_logic; 208 | ramwrt : out std_logic; 209 | ramadr : out std_logic_vector(19 downto 0); 210 | ramdbi : in std_logic_vector(7 downto 0); 211 | ramdbo : out std_logic_vector(7 downto 0) 212 | ); 213 | end component; 214 | 215 | component mapper 216 | port( 217 | clk21m : in std_logic; 218 | reset : in std_logic; 219 | clkena : in std_logic; 220 | req : in std_logic; 221 | ack : out std_logic; 222 | mem : in std_logic; 223 | wrt : in std_logic; 224 | adr : in std_logic_vector(15 downto 0); 225 | dbi : out std_logic_vector(7 downto 0); 226 | dbo : in std_logic_vector(7 downto 0); 227 | 228 | ramreq : out std_logic; 229 | ramwrt : out std_logic; 230 | ramadr : out std_logic_vector(21 downto 0); 231 | ramdbi : in std_logic_vector(7 downto 0); 232 | ramdbo : out std_logic_vector(7 downto 0) 233 | ); 234 | end component; 235 | 236 | component vdp 237 | port( 238 | -- VDP clock ... 21.477MHz 239 | clk21m : in std_logic; 240 | reset : in std_logic; 241 | req : in std_logic; 242 | ack : out std_logic; 243 | wrt : in std_logic; 244 | adr : in std_logic_vector(15 downto 0); 245 | dbi : out std_logic_vector(7 downto 0); 246 | dbo : in std_logic_vector(7 downto 0); 247 | 248 | int_n : out std_logic; 249 | 250 | pRamOe_n: out std_logic; 251 | pRamWe_n: out std_logic; 252 | pRamAdr : out std_logic_vector(16 downto 0); 253 | pRamDat : inout std_logic_vector(7 downto 0); 254 | 255 | -- Video Output 256 | pVideoR : out std_logic_vector( 5 downto 0); 257 | pVideoG : out std_logic_vector( 5 downto 0); 258 | pVideoB : out std_logic_vector( 5 downto 0); 259 | 260 | pVideoHS_n : out std_logic; 261 | pVideoVS_n : out std_logic; 262 | pVideoCS_n : out std_logic; 263 | 264 | pVideoDHClk : out std_logic; 265 | pVideoDLClk : out std_logic; 266 | 267 | -- CXA1645(RGB->NTSC encoder) signals 268 | pVideoSC : out std_logic; 269 | pVideoSYNC : out std_logic; 270 | 271 | -- Display resolution (0=15kHz, 1=31kHz) 272 | DispReso : in std_logic 273 | ); 274 | end component; 275 | 276 | component rtc 277 | port( 278 | clk21m : in std_logic; 279 | reset : in std_logic; 280 | clkena : in std_logic; 281 | req : in std_logic; 282 | ack : out std_logic; 283 | wrt : in std_logic; 284 | adr : in std_logic_vector(15 downto 0); 285 | dbi : out std_logic_vector(7 downto 0); 286 | dbo : in std_logic_vector(7 downto 0) 287 | ); 288 | end component; 289 | 290 | -- operation mode 291 | signal SelfMode : std_logic; 292 | signal KeyMode : std_logic; 293 | 294 | -- dummy signals 295 | signal CmtIn : std_logic; 296 | --signal JoyA : std_logic_vector(5 downto 0); 297 | --signal StrA : std_logic; 298 | --signal JoyB : std_logic_vector(5 downto 0); 299 | --signal StrB : std_logic; 300 | --signal Kana : std_logic; 301 | signal Caps : std_logic; 302 | 303 | -- MSX slot signals 304 | signal iSltSltsl_n : std_logic; 305 | signal iSltMerq_n : std_logic; 306 | signal iSltIorq_n : std_logic; 307 | signal iSltRd_n : std_logic; 308 | signal iSltWr_n : std_logic; 309 | signal iSltAdr : std_logic_vector(15 downto 0); 310 | signal iSltDat : std_logic_vector(7 downto 0); 311 | signal dlydbi : std_logic_vector(7 downto 0); 312 | 313 | -- internal bus signals (common) 314 | signal clk21m : std_logic; 315 | signal cpuclk : std_logic; 316 | signal reset : std_logic; 317 | signal clkdiv : std_logic_vector(1 downto 0); 318 | signal clkena : std_logic; 319 | signal req : std_logic; 320 | signal ack, iack : std_logic; 321 | signal mem : std_logic; 322 | signal wrt : std_logic; 323 | signal adr : std_logic_vector(15 downto 0); 324 | signal dbi : std_logic_vector(7 downto 0); 325 | signal dbo : std_logic_vector(7 downto 0); 326 | 327 | -- expansion slot signals 328 | signal Dec_FFFF : std_logic; 329 | signal ExpDbi : std_logic_vector(7 downto 0); 330 | signal ExpSlot0 : std_logic_vector(7 downto 0); 331 | signal ExpSlot3 : std_logic_vector(7 downto 0); 332 | signal ExpSlotX : std_logic_vector(7 downto 0); 333 | signal PriSltNum : std_logic_vector(1 downto 0); 334 | signal ExpSltNum0 : std_logic_vector(1 downto 0); 335 | signal ExpSltNum3 : std_logic_vector(1 downto 0); 336 | signal ExpSltNumX : std_logic_vector(1 downto 0); 337 | 338 | -- exernal SRAM signals 339 | signal wex, wey : std_logic; 340 | signal RamReq : std_logic; 341 | signal RamAck : std_logic; 342 | signal RamSel : std_logic; 343 | signal RamDbi : std_logic_vector(7 downto 0); 344 | signal RamAdr : std_logic_vector(18 downto 0); 345 | 346 | -- slot select signals 347 | signal slt_bot : std_logic; 348 | signal slt_scc : std_logic; 349 | signal slt_erm : std_logic; 350 | signal slt_map : std_logic; 351 | signal jslt_scc : std_logic; 352 | signal jslt_mem : std_logic; 353 | signal jslt_mmc : std_logic; 354 | 355 | -- BIOS-ROM signals 356 | signal RomReq : std_logic; 357 | signal rom_main : std_logic; 358 | signal rom_opll : std_logic; 359 | signal rom_extr : std_logic; 360 | 361 | -- PPI(8255) signals 362 | signal PpiReq : std_logic; 363 | signal PpiAck : std_logic; 364 | signal PpiDbi : std_logic_vector(7 downto 0); 365 | signal PpiPortA : std_logic_vector(7 downto 0); 366 | signal PpiPortB : std_logic_vector(7 downto 0); 367 | signal PpiPortC : std_logic_vector(7 downto 0); 368 | 369 | -- PSG signals 370 | signal PsgReq : std_logic; 371 | signal PsgAck : std_logic; 372 | signal PsgDbi : std_logic_vector(7 downto 0); 373 | signal PsgAmp : std_logic_vector(7 downto 0); 374 | 375 | -- SCC signals 376 | signal SccReq : std_logic; 377 | signal SccAck : std_logic; 378 | signal SccDbi : std_logic_vector(7 downto 0); 379 | signal SccRam : std_logic; 380 | signal SccWrt : std_logic; 381 | signal SccAdr : std_logic_vector(19 downto 0); 382 | signal SccDbo : std_logic_vector(7 downto 0); 383 | signal SccAmpL : std_logic_vector(7 downto 0); 384 | signal SccAmpR : std_logic_vector(7 downto 0); 385 | 386 | -- ESE-RAM signals 387 | signal ErmReq : std_logic; 388 | signal ErmAck : std_logic; 389 | signal ErmDbi : std_logic_vector(7 downto 0); 390 | signal ErmRam : std_logic; 391 | signal ErmWrt : std_logic; 392 | signal ErmDbo : std_logic_vector(7 downto 0); 393 | signal ErmAdr : std_logic_vector(19 downto 0); 394 | 395 | -- Mapper RAM signals 396 | signal MapReq : std_logic; 397 | signal MapAck : std_logic; 398 | signal MapDbi : std_logic_vector(7 downto 0); 399 | signal MapRam : std_logic; 400 | signal MapWrt : std_logic; 401 | signal MapDbo : std_logic_vector(7 downto 0); 402 | signal MapAdr : std_logic_vector(21 downto 0); 403 | 404 | -- VDP signals 405 | signal VdpReq : std_logic; 406 | signal VdpAck : std_logic; 407 | signal VdpDbi : std_logic_vector(7 downto 0); 408 | signal VideoSC : std_logic; 409 | signal OeVdp_n : std_logic; 410 | signal WeVdp_n : std_logic; 411 | signal VdpAdr : std_logic_vector(16 downto 0); 412 | signal pVdpInt_n : std_logic; 413 | signal Reso : std_logic; 414 | 415 | -- Sound signals 416 | signal pSltSndL : std_logic_vector(5 downto 0); 417 | signal pSltSndR : std_logic_vector(5 downto 0); 418 | signal pSltSound : std_logic_vector(5 downto 0); 419 | 420 | -- SD/MMC signals 421 | signal MmcReq : std_logic; 422 | signal MMC_CS : std_logic; 423 | signal MMC_CK : std_logic; 424 | signal MMC_DI : std_logic; 425 | signal MMC_DO : std_logic; 426 | signal MmcEna : std_logic; 427 | signal MmcDbo : std_logic_vector(7 downto 0); 428 | signal MmcDbi : std_logic_vector(7 downto 0); 429 | signal MmcSeq : std_logic_vector(4 downto 0); 430 | 431 | -- ROM signals 432 | signal RomDbi : std_logic_vector(7 downto 0); 433 | 434 | -- RTC signals 435 | signal RtcReq : std_logic; 436 | signal RtcAck : std_logic; 437 | signal RtcDbi : std_logic_vector(7 downto 0); 438 | begin 439 | 440 | ---------------------------------------------------------------- 441 | -- dummy pin 442 | ---------------------------------------------------------------- 443 | pClkEna_n <= '0' when SelfMode = '1' else '1'; 444 | pBusReq_n <= 'Z'; 445 | pSltCs12 <= 'Z'; 446 | 447 | pSltM1_n <= pCpuM1_n when SelfMode = '1' else 'Z'; 448 | --pSltM1_n <= 'Z'; 449 | pSltRfsh_n<= pCpuRfsh_n when SelfMode = '1' else 'Z'; 450 | --pSltRfsh_n<= 'Z'; 451 | 452 | --pSltWait_n<= 'Z'; 453 | --pSltInt_n <= pVdpInt_n when SelfMode = '1' else 'Z'; 454 | pSltInt_n <= pVdpInt_n; 455 | 456 | pCpuClk <= CpuClk; 457 | pVideoSC <= VideoSc; 458 | --pVideoDLClk <= VideoDLClk; 459 | --pVideoDHClk <= VideoDHClk; 460 | 461 | pKeyCaps <= 'Z'; 462 | pKeyKana <= 'Z'; 463 | pKeyY <= (others => 'Z'); 464 | pKeyX <= (others => 'Z'); 465 | pJoyA <= (others => 'Z'); 466 | pStrA <= 'Z'; 467 | pJoyB <= (others => 'Z'); 468 | pStrB <= 'Z'; 469 | 470 | 471 | ---------------------------------------------------------------- 472 | -- bus control 473 | ---------------------------------------------------------------- 474 | reset <= not pSltRst_n; 475 | clk21m <= pClk21m; 476 | 477 | ---------------------------------------------------------------- 478 | -- operation mode 479 | ---------------------------------------------------------------- 480 | process(clk21m) 481 | 482 | begin 483 | 484 | if (clk21m'event and clk21m = '1') then 485 | 486 | if (reset = '1') then 487 | --SelfMode <= '0'; -- operation mode : 1=master, 0=slave 488 | SelfMode <= pSelf; 489 | end if; 490 | 491 | end if; 492 | 493 | end process; 494 | 495 | ---------------------------------------------------------------- 496 | -- clock generator 497 | -- pCpuClk should be independent from reset 498 | ---------------------------------------------------------------- 499 | process(clk21m) 500 | 501 | variable jc : std_logic_vector(4 downto 0); 502 | 503 | begin 504 | 505 | if (clk21m'event and clk21m = '1') then 506 | 507 | jc(3) := jc(2); 508 | jc(2) := jc(1); 509 | jc(1) := jc(0); 510 | 511 | if (jc(3 downto 1) = "010" or jc(3 downto 1) = "101") then 512 | jc(0) := jc(3); 513 | else 514 | jc(0) := not jc(3); 515 | end if; 516 | 517 | -- CPUCLK : 3.58MHz = 21.48MHz / 6 518 | if (jc(3 downto 2) = "10") then 519 | clkena <= '1'; 520 | else 521 | clkena <= '0'; 522 | end if; 523 | cpuclk <= jc(3); 524 | 525 | -- prescaler : 21.48MHz / 4 526 | clkdiv <= clkdiv - 1; 527 | 528 | end if; 529 | 530 | end process; 531 | 532 | ---------------------------------------------------------------- 533 | -- Wait control 534 | ---------------------------------------------------------------- 535 | process(pSltClk, reset) 536 | 537 | variable jSltIorq_n : std_logic; 538 | variable kSltIorq_n : std_logic; 539 | 540 | begin 541 | 542 | if (reset = '1') then 543 | jSltIorq_n := '1'; 544 | kSltIorq_n := '1'; 545 | pSltWait_n <= 'Z'; 546 | elsif (pSltClk'event and pSltClk = '1') then 547 | if (SelfMode = '0') then 548 | pSltWait_n <= 'Z'; 549 | elsif (jSltIorq_n = '0' and kSltIorq_n = '1' and adr(6 downto 2) = "00110") then 550 | pSltWait_n <= '0'; 551 | -- pSltWait_n <= 'Z'; 552 | else 553 | pSltWait_n <= 'Z'; 554 | end if; 555 | kSltIorq_n := jSltIorq_n; 556 | jSltIorq_n := pSltIorq_n; 557 | 558 | end if; 559 | 560 | end process; 561 | 562 | ---------------------------------------------------------------- 563 | -- MSX slot access control 564 | ---------------------------------------------------------------- 565 | process(clk21m, reset) 566 | 567 | begin 568 | 569 | if (reset = '1') then 570 | 571 | iSltSltsl_n <= '1'; 572 | iSltMerq_n <= '1'; 573 | iSltIorq_n <= '1'; 574 | iSltRd_n <= '1'; 575 | iSltWr_n <= '1'; 576 | iSltAdr <= (others => '1'); 577 | iSltDat <= (others => '1'); 578 | 579 | iack <= '0'; 580 | 581 | Dec_FFFF <= '0'; 582 | dlydbi <= (others => '1'); 583 | 584 | elsif (clk21m'event and clk21m = '1') then 585 | 586 | -- MSX slot signals 587 | if (SelfMode = '0') then 588 | iSltSltsl_n <= pSltSltsl_n; 589 | else 590 | iSltSltsl_n <= '1'; 591 | end if; 592 | iSltMerq_n <= pSltMerq_n; 593 | iSltIorq_n <= pSltIorq_n; 594 | iSltRd_n <= pSltRd_n; 595 | iSltWr_n <= pSltWr_n; 596 | iSltAdr <= pSltAdr; 597 | iSltDat <= pSltDat; 598 | 599 | if (iSltSltsl_n = '1' and iSltMerq_n = '1' and iSltIorq_n = '1') then 600 | iack <= '0'; 601 | elsif (ack = '1') then 602 | iack <= '1'; 603 | end if; 604 | 605 | if (adr = X"FFFF") then 606 | Dec_FFFF <= '1'; 607 | else 608 | Dec_FFFF <= '0'; 609 | end if; 610 | 611 | if (mem = '1' and slt_erm = '1') then 612 | dlydbi <= MmcDbi; 613 | elsif (mem = '0' and adr(6 downto 2) = "00010") then 614 | dlydbi <= VdpDbi; 615 | elsif (mem = '0' and adr(6 downto 2) = "00110") then 616 | dlydbi <= VdpDbi; 617 | else 618 | dlydbi <= (others => '1'); 619 | end if; 620 | 621 | end if; 622 | 623 | end process; 624 | 625 | process(clk21m, reset) 626 | 627 | begin 628 | 629 | if (reset = '1') then 630 | 631 | jslt_mmc <= '0'; 632 | 633 | elsif (clk21m'event and clk21m = '0') then 634 | 635 | if (mem = '1' and slt_erm = '1') then 636 | if (MmcEna = '1' and adr(15 downto 13) = "010") then 637 | pKeyCaps <= '0'; 638 | jslt_mmc <= '1'; 639 | else 640 | pKeyCaps <= 'Z'; 641 | jslt_mmc <= '0'; 642 | end if; 643 | else 644 | jslt_mmc <= '0'; 645 | end if; 646 | 647 | end if; 648 | 649 | end process; 650 | 651 | -- internal bus signals 652 | req <= '1' when (((iSltMerq_n = '0' and SelfMode = '1') or 653 | iSltSltsl_n = '0' or iSltIorq_n = '0') and 654 | (iSltRd_n = '0' or iSltWr_n = '0') and iack = '0') else '0'; 655 | mem <= iSltIorq_n; -- 1=memory area, 0=i/o area 656 | --wrt <= iSltRd_n; -- 1=write, 0=read 657 | wrt <= not iSltWr_n; -- 1=write, 0=read 658 | dbo <= iSltDat; -- CPU data (CPU > device) 659 | adr <= iSltAdr; -- CPU address (CPU > device) 660 | 661 | ---------------------------------------------------------------- 662 | -- Slot control 663 | ---------------------------------------------------------------- 664 | process(clk21m, reset) 665 | 666 | begin 667 | 668 | if (reset = '1') then 669 | 670 | ExpSlot0 <= (others => '0'); 671 | ExpSlot3 <= "00101011"; -- primary slot : page 0 => boot-rom, page 1/2 => ese-mmc, page 3 => mapper 672 | ExpSlotX <= (others => '0'); 673 | 674 | elsif (clk21m'event and clk21m = '1') then 675 | 676 | -- Memory mapped I/O port access on FFFFh ... expansion slot register (master mode) 677 | if (req = '1' and iSltMerq_n = '0' and wrt = '1' and adr = X"FFFF") then 678 | if (PpiPortA(7 downto 6) = "00") then 679 | ExpSlot0 <= dbo; 680 | elsif (PpiPortA(7 downto 6) = "11") then 681 | ExpSlot3 <= dbo; 682 | end if; 683 | end if; 684 | -- Memory mapped I/O port access on FFFFh ... expansion slot register (slave mode) 685 | if (req = '1' and iSltSltsl_n = '0' and wrt = '1' and adr = X"FFFF") then 686 | ExpSlotX <= dbo; 687 | end if; 688 | 689 | end if; 690 | 691 | end process; 692 | 693 | -- expansion slot register read 694 | ExpDbi <= not ExpSlot0 when SelfMode = '1' and PpiPortA(7 downto 6) = "00" else 695 | not ExpSlot3 when SelfMode = '1' and PpiPortA(7 downto 6) = "11" else 696 | not ExpSlotX; 697 | 698 | -- expansion slot number : slot 0 (master mode) 699 | ExpSltNum0 <= ExpSlot0(1 downto 0) when adr(15 downto 14) = "00" else 700 | ExpSlot0(3 downto 2) when adr(15 downto 14) = "01" else 701 | ExpSlot0(5 downto 4) when adr(15 downto 14) = "10" else 702 | ExpSlot0(7 downto 6); 703 | 704 | -- expansion slot number : slot 3 (master mode) 705 | ExpSltNum3 <= ExpSlot3(1 downto 0) when adr(15 downto 14) = "00" else 706 | ExpSlot3(3 downto 2) when adr(15 downto 14) = "01" else 707 | ExpSlot3(5 downto 4) when adr(15 downto 14) = "10" else 708 | ExpSlot3(7 downto 6); 709 | 710 | -- expansion slot number : slot X (slave mode) 711 | ExpSltNumX <= ExpSlotX(1 downto 0) when adr(15 downto 14) = "00" else 712 | ExpSlotX(3 downto 2) when adr(15 downto 14) = "01" else 713 | ExpSlotX(5 downto 4) when adr(15 downto 14) = "10" else 714 | ExpSlotX(7 downto 6); 715 | 716 | -- primary slot number (master mode) 717 | PriSltNum <= PpiPortA(1 downto 0) when adr(15 downto 14) = "00" else 718 | PpiPortA(3 downto 2) when adr(15 downto 14) = "01" else 719 | PpiPortA(5 downto 4) when adr(15 downto 14) = "10" else 720 | PpiPortA(7 downto 6); 721 | 722 | ---------------------------------------------------------------- 723 | -- slot / address decode 724 | ---------------------------------------------------------------- 725 | slt_erm <= '0' when adr(15 downto 14) = "00" or adr(15 downto 14) = "11" else 726 | '1' when PriSltNum = "11" and 727 | ExpSltNum3 = "10" and SelfMode = '1' else 728 | '1' when ExpSltNumX = "01" and SelfMode = '0' else '0'; 729 | 730 | -- RamX / RamY access request 731 | RamReq <= '0'; 732 | -- RamX / RamY select : 0=RamX(SCC), 1=RamY(ESE-RAM,BIOS,Mapper,VRAM) 733 | RamSel <= '0'; 734 | 735 | -- access request to components 736 | VdpReq <= req when mem = '0' and adr(7 downto 2) = "100010" and SelfMode = '0' else -- I/O:88-8Bh / VDP(V9958) 737 | req when mem = '0' and adr(7 downto 3) = "10011" and SelfMode = '1' else '0'; -- I/O:98-9Bh / VDP(V9958) 738 | PpiReq <= req when mem = '0' and adr(7 downto 2) = "101010" else '0'; -- I/O:A8-ABh / PPI(8255) 739 | MmcReq <= req when mem = '1' and slt_erm = '1' else '0'; 740 | 741 | -- access acknowledge from components 742 | ack <= req; -- PpiAck, VdpAck 743 | 744 | --dbi <= SccDbi when jslt_scc = '1' else 745 | -- RamDbi when jslt_mem = '1' else 746 | -- dlydbi; 747 | 748 | dbi <= dlydbi; 749 | 750 | pSltDat <= dbi when pSltIorq_n = '0' and pSltRd_n = '0' and SelfMode = '0' and pSltAdr(7 downto 2)= "100010" else 751 | dbi when pSltIorq_n = '0' and pSltRd_n = '0' and SelfMode = '1' and pSltAdr(7 downto 2)= "100110" else 752 | dbi when pSltMerq_n = '0' and pSltRd_n = '0' and jslt_mmc = '1' else 753 | (others => 'Z'); 754 | 755 | pSltSltsl_n<= 'Z'; 756 | 757 | pSltBdir_n <= '0' when pSltIorq_n = '0' and pSltRd_n = '0' and SelfMode = '0' and pSltAdr(7 downto 2)= "100010" else 758 | 'Z'; 759 | 760 | ---------------------------------------------------------------- 761 | -- PPI(8255) / primary-slot, keyboard, 1 bit sound port 762 | ---------------------------------------------------------------- 763 | process(clk21m, reset) 764 | 765 | begin 766 | 767 | if (reset = '1') then 768 | 769 | PpiPortA <= "11111111"; -- primary slot : page 0 => boot-rom, page 1/2 => ese-mmc, page 3 => mapper 770 | 771 | elsif (clk21m'event and clk21m = '1') then 772 | 773 | -- I/O port access on A8-ABh ... PPI(8255) access 774 | if (PpiReq = '1') then 775 | if (wrt = '1' and adr(1 downto 0) = "00") then 776 | PpiPortA <= dbo; 777 | end if; 778 | end if; 779 | 780 | end if; 781 | 782 | end process; 783 | 784 | PpiAck <= PpiReq; 785 | 786 | ---------------------------------------------------------------- 787 | -- SD/MMC memory access 788 | ---------------------------------------------------------------- 789 | process(clk21m, reset) 790 | 791 | variable MmcTmp : std_logic_vector(7 downto 0); 792 | 793 | begin 794 | 795 | if (reset = '1') then 796 | 797 | MmcEna <= '0'; 798 | MmcDbo <= (others => '1'); 799 | MmcDbi <= (others => '1'); 800 | MmcSeq <= (others => '0'); 801 | MmcTmp := (others => '1'); 802 | 803 | MMC_CK <= '0'; 804 | MMC_CS <= '1'; 805 | MMC_DI <= 'Z'; 806 | 807 | elsif (clk21m'event and clk21m = '1') then 808 | 809 | -- Memory mapped I/O port access on 6000-67FFh ... SD/MMC enable register 810 | if (MmcReq = '1' and wrt = '1' and adr(15 downto 11) = "01100") then 811 | if (dbo(7 downto 6) = "01") then 812 | MmcEna <= '1'; 813 | else 814 | MmcEna <= '0'; 815 | end if; 816 | end if; 817 | 818 | -- Memory mapped I/O port access on 4000-5FFFh ... SD/MMC data register 819 | if (MmcReq = '1' and adr(15 downto 13) = "010" and MmcEna = '1' and MmcSeq = "00000") then -- 4000-5FFFh 820 | if (wrt = '1') then 821 | MmcDbo <= dbo; 822 | else 823 | MmcDbo <= (others => '1'); 824 | end if; 825 | MMC_CS <= adr(12); 826 | MmcSeq <= "10101"; 827 | elsif (MmcSeq /= "00000") then 828 | MmcSeq <= MmcSeq - 1; 829 | end if; 830 | 831 | if (MmcSeq(4 downto 1) < "1010" and MmcSeq(4 downto 1) > "0001") then 832 | MMC_CK <= MmcSeq(0); 833 | else 834 | MMC_CK <= '0'; 835 | end if; 836 | 837 | if (MmcSeq(0) = '0') then 838 | case MmcSeq(4 downto 1) is 839 | when "1010" => MMC_DI <= MmcDbo(7); 840 | when "1001" => MMC_DI <= MmcDbo(6); 841 | when "1000" => MMC_DI <= MmcDbo(5); 842 | when "0111" => MMC_DI <= MmcDbo(4); 843 | when "0110" => MMC_DI <= MmcDbo(3); 844 | when "0101" => MMC_DI <= MmcDbo(2); 845 | when "0100" => MMC_DI <= MmcDbo(1); 846 | when "0011" => MMC_DI <= MmcDbo(0); 847 | when "0010" => MMC_DI <= '1'; 848 | when "0001" => MMC_DI <= 'Z'; 849 | when others => MMC_DI <= 'Z'; 850 | end case; 851 | end if; 852 | 853 | if (MmcSeq(0) = '0') then 854 | case MmcSeq(4 downto 1) is 855 | when "1001" => MmcTmp(7) := MMC_DO; 856 | when "1000" => MmcTmp(6) := MMC_DO; 857 | when "0111" => MmcTmp(5) := MMC_DO; 858 | when "0110" => MmcTmp(4) := MMC_DO; 859 | when "0101" => MmcTmp(3) := MMC_DO; 860 | when "0100" => MmcTmp(2) := MMC_DO; 861 | when "0011" => MmcTmp(1) := MMC_DO; 862 | when "0010" => MmcTmp(0) := MMC_DO; 863 | when "0001" => MmcDbi <= MmcTmp; 864 | when others => null; 865 | end case; 866 | end if; 867 | 868 | end if; 869 | 870 | end process; 871 | 872 | --MmcAck <= MmcReq; 873 | 874 | ---------------------------------------------------------------- 875 | -- External memory (512kbytes * 2) access 876 | ---------------------------------------------------------------- 877 | process(clk21m, reset) 878 | 879 | begin 880 | 881 | if (reset = '1') then 882 | 883 | RamAck <= '0'; 884 | wex <= '1'; 885 | wey <= '1'; 886 | RamAdr <= (others => '1'); 887 | RamDbi <= (others => '0'); 888 | 889 | elsif (clk21m'event and clk21m = '1') then 890 | wex <= WeVdp_n; 891 | wey <= '1'; 892 | end if; 893 | 894 | end process; 895 | 896 | pRamCeX <= '1' when reset = '0' else '0'; 897 | --pRamCeY_n <= '0'; 898 | 899 | pRamOeX_n <= OeVdp_n; 900 | 901 | -- wrt; 902 | 903 | --pRamOeY_n <= OeVdp_n when VideoDLClk = '1' else 904 | -- wrt; 905 | 906 | pRamWeX_n <= wex; 907 | --pRamWeY_n <= wey; 908 | 909 | pRamAdrX <= "11" & VdpAdr; 910 | 911 | -- JP: VDPのみの場合,pRamDatXは vdpモジュールがドライブする 912 | -- pRamDatX <= (others => 'Z') when VideoDLClk = '1' else 913 | -- dbo when wrt = '1' else (others => 'Z'); 914 | 915 | ---------------------------------------------------------------- 916 | -- Connect components 917 | ---------------------------------------------------------------- 918 | U5 : vdp 919 | port map( 920 | clk21m, reset, VdpReq, VdpAck, wrt, adr, VdpDbi, dbo, pVdpInt_n, 921 | OeVdp_n, WeVdp_n, VdpAdr, pRamDatX, 922 | pVideoR, pVideoG, pVideoB, pVideoHS_n, pVideoVS_n, open, 923 | open, open, VideoSC, pVideoSYNC, Reso 924 | -- VideoDHClk, VideoDLClk, VideoSC, pVideoSYNC, Reso 925 | ); 926 | 927 | -- Reso <= pKeyKana; 928 | Reso <= '1'; 929 | 930 | ---------------------------------------------------------------- 931 | -- 1 bit D/A control 932 | ---------------------------------------------------------------- 933 | process(clk21m, reset) 934 | 935 | variable AmpL : std_logic_vector(15 downto 0); 936 | variable AmpR : std_logic_vector(15 downto 0); 937 | variable Amp : std_logic_vector(15 downto 0); 938 | variable AcuL : std_logic_vector(11 downto 0); 939 | variable AcuR : std_logic_vector(11 downto 0); 940 | variable Acu : std_logic_vector(11 downto 0); 941 | 942 | begin 943 | 944 | if (reset = '1') then 945 | 946 | AmpL := (others => '0'); 947 | AmpR := (others => '0'); 948 | Amp := (others => '0'); 949 | AcuL := (others => '0'); 950 | AcuR := (others => '0'); 951 | Acu := (others => '0'); 952 | pSltSndL <= (others => '0'); 953 | pSltSndR <= (others => '0'); 954 | pSltSound <= (others => '0'); 955 | 956 | elsif (clk21m'event and clk21m = '1') then 957 | 958 | AmpL := (('0' & PsgAmp & "0000000") + (SccAmpL & "00000000")) and "1111111111111111"; 959 | AmpR := (('0' & PsgAmp & "0000000") + (SccAmpR & "00000000")) and "1111111111111111"; 960 | Amp := (('0' & PsgAmp & "0000000") + ('0' & SccAmpL & "0000000") + ('0' & SccAmpR & "0000000")) and "1111111111111111"; 961 | 962 | AcuL := ('0' & AcuL(10 downto 0)) + ('0' & AmpL(10 downto 0)); 963 | AcuR := ('0' & AcuR(10 downto 0)) + ('0' & AmpR(10 downto 0)); 964 | Acu := ('0' & Acu(10 downto 0)) + ('0' & Amp(10 downto 0)); 965 | 966 | pSltSndL <= (AmpL(15)) & AmpL(14 downto 11) & AcuL(11); 967 | pSltSndR <= (AmpR(15)) & AmpR(14 downto 11) & AcuR(11); 968 | pSltSound <= (Amp(15)) & Amp(14 downto 11) & Acu(11); 969 | 970 | end if; 971 | 972 | end process; 973 | 974 | pSltSnd_L <= pSltSound; 975 | pSltSnd_R(5) <= 'Z'; 976 | pSltSnd_R(0) <= 'Z'; 977 | 978 | pSltSnd_R(1) <= MMC_CS; 979 | pSltSnd_R(2) <= MMC_DI; 980 | pSltSnd_R(3) <= MMC_CK; 981 | MMC_DO <= pSltSnd_R(4); 982 | pSltSnd_R(4) <= 'Z'; 983 | 984 | end rtl; 985 | -------------------------------------------------------------------------------- /src/vdp.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- vdp.vhd 3 | -- VHDL Source of ESE-VDP. 4 | -- 5 | -- Copyright (C)2000-2004 Kunihiko Ohnaka 6 | -- All rights reserved. 7 | -- 8 | -- JP: 日本語のコメント行は JP:を頭に付ける事にする 9 | -- 10 | -- 17th,January,2004 modified by Kunihiko Ohnaka 11 | -- JP: LMCMを実装.VDPコマンド全般にまだ不具合あり. 12 | -- 13 | -- 15th,January,2004 modified by Kunihiko Ohnaka 14 | -- JP: VDPコマンドの実装を開始 15 | -- JP: HMMC,HMMM,YMMM,HMMV,LMMC,LMMM,LMMVを実装.まだ不具合あり. 16 | -- 17 | -- 12th,January,2004 modified by Kunihiko Ohnaka 18 | -- JP: コメントの修正 19 | -- 20 | -- 30th,December,2003 modified by Kazuhiro Tsujikawa 21 | -- JP: 起動時の画面モードをNTSCと VGAのどちらにするかを,外部入力で切替 22 | -- JP: DHClk/DLClkを一時的に復活させた 23 | -- 24 | -- 16th,December,2003 modified by Kunihiko Ohnaka 25 | -- JP: 起動時の画面モードをNTSCと VGAのどちらにするかを,vdp_package.vhd 26 | -- JP: 内で定義された定数で切替えるようにした. 27 | -- 28 | -- 10th,December,2003 modified by Kunihiko Ohnaka 29 | -- JP: TEXT MODE 2 (SCREEN0 WIDTH80)をサポート. 30 | -- JP: 初の横方向倍解像度モードである.一応将来対応できるように作って 31 | -- JP: きたつもりだったが,少し収まりが悪い部分があり,あまりきれいな 32 | -- JP: 対応になっていない部分もあります. 33 | -- 34 | -- 13th,October,2003 modified by Kunihiko Ohnaka 35 | -- JP: ESE-MSX基板では 2S300Eを複数用いる事ができるようにり,VDP単体で 36 | -- JP: 2S300Eや SRAMを占有する事が可能となった. 37 | -- JP: これに伴い以下のような変更を行う. 38 | -- JP: ・VGA出力対応(アップスキャンコンバート) 39 | -- JP: ・SCREEN7,8のタイミングを実機と同じに 40 | -- 41 | -- 15th,June,2003 modified by Kunihiko Ohnaka 42 | -- 水平帰線期間割り込みを実装してスペースマンボウを遊べるようにした. 43 | -- GraphicMode3(Screen4)でYライン数が 212ラインにならなかったのを 44 | -- 修正したりした. 45 | -- ただし,スペースマンボウで set adjust機能が動いていないような 46 | -- 感じで,表示がガクガクしてしまう.横方向の同時表示スプライト数も 47 | -- 足りていないように見える.原因不明. 48 | -- 49 | -- 15th,June,2003 modified by Kunihiko Ohnaka 50 | -- 長いブランクが空いてしまったが,Spartan-II E + IO基板でスプライトが 51 | -- 表示されるようになった.原因はおそらくコンパイラのバグで,ISE 5.2に 52 | -- バージョンアップしたら表示されるようになった. 53 | -- ついでに,スプライトモード2で横 8枚並ぶようにした(つもり). 54 | -- その他細かな修正が入っています. 55 | -- 56 | -- 15th,July,2002 modified by Kazuhiro Tsujikawa 57 | -- no comment; 58 | -- 59 | 60 | 61 | library ieee; 62 | use ieee.std_logic_1164.all; 63 | use ieee.std_logic_unsigned.all; 64 | use work.vdp_package.all; 65 | 66 | entity vdp is 67 | port( 68 | -- VDP clock ... 21.477MHz 69 | clk21m : in std_logic; 70 | reset : in std_logic; 71 | req : in std_logic; 72 | ack : out std_logic; 73 | wrt : in std_logic; 74 | adr : in std_logic_vector(15 downto 0); 75 | dbi : out std_logic_vector(7 downto 0); 76 | dbo : in std_logic_vector(7 downto 0); 77 | 78 | int_n : out std_logic; 79 | 80 | pRamOe_n: out std_logic; 81 | pRamWe_n: out std_logic; 82 | pRamAdr : out std_logic_vector(16 downto 0); 83 | pRamDat : inout std_logic_vector(7 downto 0); 84 | 85 | -- Video Output 86 | pVideoR : out std_logic_vector( 5 downto 0); 87 | pVideoG : out std_logic_vector( 5 downto 0); 88 | pVideoB : out std_logic_vector( 5 downto 0); 89 | 90 | pVideoHS_n : out std_logic; 91 | pVideoVS_n : out std_logic; 92 | pVideoCS_n : out std_logic; 93 | 94 | pVideoDHClk : out std_logic; 95 | pVideoDLClk : out std_logic; 96 | 97 | -- CXA1645(RGB->NTSC encoder) signals 98 | pVideoSC : out std_logic; 99 | pVideoSYNC : out std_logic; 100 | 101 | -- Display resolution (0=15kHz, 1=31kHz) 102 | DispReso : in std_logic 103 | ); 104 | end vdp; 105 | 106 | architecture rtl of vdp is 107 | 108 | 109 | -- H counter 110 | signal h_counter : std_logic_vector(10 downto 0); 111 | -- V counter 112 | signal v_counter : std_logic_vector(10 downto 0); 113 | 114 | -- display start position ( when adjust=(0,0) ) 115 | constant OFFSET_X : std_logic_vector( 6 downto 0) := "0110110"; -- = 220/4; 116 | constant OFFSET_Y : std_logic_vector( 6 downto 0) := "0101110"; -- = 3+3+13+26+1 = 46 117 | constant OFFSET_Y_212 : std_logic_vector( 6 downto 0) := "0100100"; -- = 3+3+13+16+1 = 36 118 | 119 | -- signal adjust_x : std_logic_vector( 6 downto 0); 120 | -- signal adjust_y : std_logic_vector( 6 downto 0); 121 | 122 | -- dot state register 123 | signal dotState : std_logic_vector( 1 downto 0); 124 | signal dotResetState : std_logic_vector( 1 downto 0); 125 | 126 | -- display field signal 127 | signal field : std_logic; 128 | 129 | -- sync state register 130 | type typsstate is (sstate_A, sstate_B, sstate_C, sstate_D); 131 | signal sstate : typsstate; 132 | 133 | --@ constant sstate_A : std_logic_vector := "00"; 134 | --@ constant sstate_B : std_logic_vector := "01"; 135 | --@ constant sstate_C : std_logic_vector := "10"; 136 | --@ constant sstate_D : std_logic_vector := "11"; 137 | 138 | -- for vsync interrupt 139 | signal vsyncInt_n : std_logic; 140 | signal vsyncIntReq : std_logic; 141 | signal vsyncIntAck : std_logic; 142 | signal dVideoVS_n : std_logic; 143 | 144 | -- for hsync interrupt 145 | signal hsyncInt_n : std_logic; 146 | signal hsyncIntReq : std_logic; 147 | signal hsyncIntAck : std_logic; 148 | signal dVideoHS_n : std_logic; 149 | 150 | -- display area flags 151 | signal window_x :std_logic; 152 | signal window_y :std_logic; 153 | signal window :std_logic; 154 | signal preWindow_x :std_logic; 155 | signal preWindow_y :std_logic; 156 | signal preWindow :std_logic; 157 | -- for sprites 158 | signal spwindow_ec :std_logic; 159 | signal spwindow :std_logic; 160 | signal spwindow_x :std_logic; 161 | signal spwindow_y :std_logic; 162 | signal spwindow_ecx :std_logic; 163 | -- for text mode 164 | signal twindow : std_logic; 165 | signal twindow_y : std_logic; 166 | signal twindow_x : std_logic; 167 | -- for graphic mode 1,2,3 168 | signal g123window : std_logic; 169 | signal g123window_y : std_logic; 170 | signal g123window_x : std_logic; 171 | -- for frame zone 172 | signal bwindow_x :std_logic; 173 | signal bwindow_y :std_logic; 174 | signal bwindow :std_logic; 175 | 176 | -- dot counter 177 | signal dotCounter_x : std_logic_vector( 8 downto 0); 178 | signal dotCounter_y : std_logic_vector( 7 downto 0); 179 | -- 垂直スクロールレジスタの影響を受けないカウンタ 180 | signal dotCounter_yp : std_logic_vector( 7 downto 0); 181 | -- dot counter - 8 ( fifo read addr ) 182 | signal preDotCounter_x : std_logic_vector( 8 downto 0); 183 | -- signal preDotCounter_y : std_logic_vector( 7 downto 0); 184 | signal preDotCounter_y : std_logic_vector( 8 downto 0); 185 | -- 垂直スクロールレジスタの影響を受けないカウンタ 186 | -- signal preDotCounter_yp : std_logic_vector( 7 downto 0); 187 | signal preDotCounter_yp : std_logic_vector( 8 downto 0); 188 | signal preDotCounter_x_end : std_logic; 189 | 190 | signal VramReadFreeFlag : std_logic; 191 | 192 | -- 3.58MHz generator 193 | signal cpuClockCounter :std_logic_vector( 2 downto 0); 194 | 195 | -- VDP register access 196 | signal VdpP1Is1stByte : std_logic; 197 | signal VdpP2Is1stByte : std_logic; 198 | signal VdpP0Data : std_logic_vector( 7 downto 0); 199 | signal VdpP1Data : std_logic_vector( 7 downto 0); 200 | signal VdpRegPtr : std_logic_vector( 5 downto 0); 201 | signal VdpRegWrPulse : std_logic; 202 | signal VdpVramAccessAddr : std_logic_vector( 16 downto 0); 203 | signal VdpVramAccessData : std_logic_vector( 7 downto 0); 204 | signal VdpVramAccessAddrTmp : std_logic_vector( 16 downto 0); 205 | signal VdpVramAddrSetReq : std_logic; 206 | signal VdpVramAddrSetAck : std_logic; 207 | signal VdpVramAccessRw : std_logic; 208 | signal VdpVramWrReq : std_logic; 209 | signal VdpVramWrAck : std_logic; 210 | signal VdpVramReading : std_logic; 211 | signal VdpVramRdData : std_logic_vector(7 downto 0); 212 | signal VdpVramRdReq : std_logic; 213 | signal VdpVramRdAck : std_logic; 214 | signal dispModeVGA : std_logic; 215 | signal VdpR0DispNum : std_logic_vector(3 downto 1); 216 | signal VdpR0HSyncIntEn : std_logic; 217 | signal VdpR1DispMode : std_logic_vector(1 downto 0); 218 | signal VdpR1SpSize : std_logic; 219 | signal VdpR1SpZoom : std_logic; 220 | signal VdpR1VSyncIntEn : std_logic; 221 | signal VdpR1DispOn : std_logic; 222 | signal VdpR2PtnNameTblBaseAddr : std_logic_vector( 6 downto 0); 223 | signal VdpR4PtnGeneTblBaseAddr : std_logic_vector( 5 downto 0); 224 | signal VdpR10R3ColorTblBaseAddr : std_logic_vector( 10 downto 0); 225 | signal VdpR11R5SpAttrTblBaseAddr : std_logic_vector( 9 downto 0); 226 | signal VdpR6SpPtnGeneTblBaseAddr : std_logic_vector( 5 downto 0); 227 | signal VdpR7FrameColor : std_logic_vector( 7 downto 0); 228 | signal VdpR8SpOff : std_logic; 229 | signal VdpR8Color0On : std_logic; 230 | signal VdpR9InterlaceMode : std_logic; 231 | signal VdpR9TwoPageMode : std_logic; 232 | signal VdpR9YDots : std_logic; 233 | signal VdpR15StatusRegNum : std_logic_vector( 3 downto 0); 234 | signal VdpR16PalNum : std_logic_vector( 3 downto 0); 235 | signal VdpR17RegNum : std_logic_vector( 5 downto 0); 236 | signal VdpR17IncRegNum : std_logic; 237 | signal VdpR18Adjust : std_logic_vector( 7 downto 0); 238 | signal VdpR19HSyncIntLine : std_logic_vector( 7 downto 0); 239 | signal VdpR23VStartLine : std_logic_vector( 7 downto 0); 240 | signal VdpS7ReadData : std_logic_vector( 7 downto 0); 241 | signal VdpS8S9SrchX : std_logic_vector( 9 downto 0); 242 | 243 | 244 | constant VdpCmdHMMC : std_logic_vector( 3 downto 0) := "1111"; 245 | constant VdpCmdYMMM : std_logic_vector( 3 downto 0) := "1110"; 246 | constant VdpCmdHMMM : std_logic_vector( 3 downto 0) := "1101"; 247 | constant VdpCmdHMMV : std_logic_vector( 3 downto 0) := "1100"; 248 | constant VdpCmdLMMC : std_logic_vector( 3 downto 0) := "1011"; 249 | constant VdpCmdLMCM : std_logic_vector( 3 downto 0) := "1010"; 250 | constant VdpCmdLMMM : std_logic_vector( 3 downto 0) := "1001"; 251 | constant VdpCmdLMMV : std_logic_vector( 3 downto 0) := "1000"; 252 | 253 | constant VdpCmdIMP : std_logic_vector( 3 downto 0) := "0000"; 254 | constant VdpCmdAND : std_logic_vector( 3 downto 0) := "0001"; 255 | constant VdpCmdOR : std_logic_vector( 3 downto 0) := "0010"; 256 | constant VdpCmdEOR : std_logic_vector( 3 downto 0) := "0011"; 257 | constant VdpCmdNOT : std_logic_vector( 3 downto 0) := "0100"; 258 | constant VdpCmdTIMP : std_logic_vector( 3 downto 0) := "1000"; 259 | constant VdpCmdTAND : std_logic_vector( 3 downto 0) := "1001"; 260 | constant VdpCmdTOR : std_logic_vector( 3 downto 0) := "1010"; 261 | constant VdpCmdTEOR : std_logic_vector( 3 downto 0) := "1011"; 262 | constant VdpCmdTNOT : std_logic_vector( 3 downto 0) := "1100"; 263 | 264 | signal VdpModeText1 : std_logic; -- text mode 1 (SCREEN0) 265 | signal VdpModeText2 : std_logic; -- text mode 2 (SCREEN0 width 80) 266 | signal VdpModeGraphic1 : std_logic; -- graphic mode 1 (SCREEN1) 267 | signal VdpModeGraphic2 : std_logic; -- graphic mode 2 (SCREEN2) 268 | signal VdpModeGraphic3 : std_logic; -- graphic mode 2 (SCREEN4) 269 | signal VdpModeGraphic4 : std_logic; -- graphic mode 4 (SCREEN5) 270 | signal VdpModeGraphic5 : std_logic; -- graphic mode 5 (SCREEN6) 271 | signal VdpModeGraphic6 : std_logic; -- graphic mode 6 (SCREEN7) 272 | signal VdpModeGraphic7 : std_logic; -- graphic mode 7 (SCREEN8) 273 | -- constant VdpModeGraphic7 : std_logic := '0'; 274 | 275 | -- Color Code 276 | signal colorCode : std_logic_vector( 7 downto 0); 277 | signal colorR : std_logic_vector( 2 downto 0); 278 | signal colorG : std_logic_vector( 2 downto 0); 279 | signal colorB : std_logic_vector( 2 downto 0); 280 | 281 | -- for text 1 282 | signal TXDotCounter_x : std_logic_vector( 2 downto 0); 283 | signal TXCharCounter_x : std_logic_vector( 9 downto 0); 284 | signal T1CharCounter_y : std_logic_vector( 9 downto 0); 285 | signal T1PtnNum : std_logic_vector( 7 downto 0); 286 | signal T1Pattern : std_logic_vector( 7 downto 0); 287 | signal T1ColorCode : std_logic_vector( 3 downto 0); 288 | 289 | signal T2CharCounter_y : std_logic_vector(11 downto 0); 290 | signal T2PtnNum : std_logic_vector( 7 downto 0); 291 | signal T2Pattern : std_logic_vector( 7 downto 0); 292 | signal T2ColorCode : std_logic_vector( 3 downto 0); 293 | 294 | 295 | -- for graphic 1,2,3 296 | signal G1PtnNum : std_logic_vector( 7 downto 0); 297 | signal G1PPattern : std_logic_vector( 7 downto 0); 298 | signal G1Pattern : std_logic_vector( 7 downto 0); 299 | signal G1Color : std_logic_vector( 7 downto 0); 300 | signal G1ColorCode : std_logic_vector( 3 downto 0); 301 | 302 | -- for graphic 4 303 | signal G4ColorCode : std_logic_vector( 3 downto 0); 304 | -- for graphic 7 305 | signal G7ColorCode : std_logic_vector( 7 downto 0); 306 | 307 | -- sprite 308 | signal SpPreReading : std_logic; 309 | 310 | type typSpPreReadState is (spstate_idle, spstate_yread, spstate_xread, spstate_ptnnumread, 311 | spstate_ptnread1, spstate_ptnread2, spstate_colorread); 312 | signal SpPreReadState : typSpPreReadState; 313 | 314 | signal SpMode2 : std_logic; 315 | signal SpPreReadCounter : std_logic_vector( 4 downto 0); -- 0 - 31 316 | signal SpPreReadCounter2 : std_logic_vector( 2 downto 0); -- 0 - 7 317 | -- signal SpPreReadCounter2 : std_logic_vector( 3 downto 0); -- JP: 1ビット増やしてみる 318 | signal SpPreReadPtnNum : std_logic_vector( 7 downto 0); 319 | signal SpY : std_logic_vector( 7 downto 0); 320 | signal SpPreReadY : std_logic_vector( 7 downto 0); 321 | signal spColorCode : std_logic_vector( 2 downto 0); 322 | signal spColorCode_3 : std_logic; 323 | signal spColorIsTransparent : std_logic; 324 | signal SpDispEnd : std_logic; 325 | 326 | constant SpMode1_nSprites: integer := 4; 327 | constant SpMode2_nSprites: integer := 8; 328 | 329 | subtype spPatternType is std_logic_vector(16 downto 0); 330 | subtype spXType is std_logic_vector(8 downto 0); 331 | subtype spColorType is std_logic_vector(3 downto 0); 332 | 333 | type spbitVec is array( 0 to SpMode2_nSprites-1 ) of std_logic; 334 | type sppatternVec is array( 0 to SpMode2_nSprites-1 ) of spPatternType; 335 | type spxVec is array( 0 to SpMode2_nSprites-1 ) of spXType; 336 | type spcolorVec is array( 0 to SpMode2_nSprites-1 ) of spColorType; 337 | 338 | signal SpColorIn : spbitVec; 339 | signal SpPattern : sppatternVec; 340 | signal SpX : spxVec; 341 | signal SpColor : spcolorVec; 342 | -- JP: 連続したスプライト番号のスプライトが同一ラインに並んでいるか 343 | -- JP: どうかを判定するためのフラグ 344 | signal SpReadIsContinuous : std_logic; 345 | signal SpCC : spbitVec; 346 | signal SpEC : spbitVec; 347 | signal SpIC : spbitVec; 348 | 349 | signal fifoAddr : std_logic_vector( 7 downto 0); 350 | signal fifoAddr_in : std_logic_vector( 3 downto 0); 351 | signal fifoAddr_out : std_logic_vector( 3 downto 0); 352 | signal fifoWe : std_logic; 353 | signal fifoIn : std_logic; 354 | signal fifoData_in : std_logic_vector( 7 downto 0); 355 | signal fifoData_out : std_logic_vector( 7 downto 0); 356 | signal fifoFull : std_logic; 357 | 358 | -- palette registers 359 | signal paletteAddr : std_logic_vector( 7 downto 0); 360 | signal paletteAddr_out : std_logic_vector( 3 downto 0); 361 | signal paletteWeRB : std_logic; 362 | signal paletteWeG : std_logic; 363 | signal paletteInRB : std_logic; 364 | signal paletteInG : std_logic; 365 | signal paletteData_in : std_logic_vector( 7 downto 0); 366 | signal paletteDataRB_out : std_logic_vector( 7 downto 0); 367 | signal paletteDataG_out : std_logic_vector( 7 downto 0); 368 | 369 | signal paletteWrTemp : std_logic_vector( 7 downto 0); 370 | signal paletteWrNum : std_logic_vector( 3 downto 0); 371 | signal paletteWrReqRB : std_logic; 372 | signal paletteWrAckRB : std_logic; 373 | signal paletteWrReqG : std_logic; 374 | signal paletteWrAckG : std_logic; 375 | 376 | -- VDP Command Signals 377 | signal VdpCmdSX : std_logic_vector( 8 downto 0); -- R33,32 378 | signal VdpCmdSY : std_logic_vector( 9 downto 0); -- R35,34 379 | signal VdpCmdDX : std_logic_vector( 8 downto 0); -- R37,36 380 | signal VdpCmdDY : std_logic_vector( 9 downto 0); -- R39,38 381 | signal VdpCmdNX : std_logic_vector( 8 downto 0); -- R41,40 382 | signal VdpCmdNY : std_logic_vector( 9 downto 0); -- R43,42 383 | signal VdpCmdCLR : std_logic_vector( 7 downto 0); -- R44 384 | signal VdpCmdDIX : std_logic; -- R45 bit 2 385 | signal VdpCmdDIY : std_logic; -- R45 bit 3 386 | signal VdpCmdMXS : std_logic; -- R45 bit 4 387 | signal VdpCmdMXD : std_logic; -- R45 bit 5 388 | signal VdpCmdCMR : std_logic_vector( 7 downto 0); -- R46 389 | signal VdpCmdTR : std_logic; -- S#2 (bit 7) 390 | signal VdpCmdCE : std_logic; -- S#2 (bit 0) 391 | 392 | signal VdpCmdRegNum : std_logic_vector(3 downto 0); 393 | signal VdpCmdRegData : std_logic_vector(7 downto 0); 394 | signal VdpCmdRegWrReq : std_logic; 395 | signal VdpCmdRegWrAck : std_logic; 396 | signal VdpCmdTRClrReq : std_logic; 397 | signal VdpCmdTRClrAck : std_logic; 398 | signal VdpCmdCLRWr : std_logic; 399 | signal VdpCmdCMRWr : std_logic; 400 | signal VdpCmdVramWrAck : std_logic; 401 | signal VdpCmdVramWrReq : std_logic; 402 | signal VdpCmdVramRdAck : std_logic; 403 | signal VdpCmdVramRdReq : std_logic; 404 | signal VdpCmdVramAccessAddr : std_logic_vector( 16 downto 0); 405 | signal VdpCmdVramReading : std_logic; 406 | signal VdpCmdVramRdData : std_logic_vector(7 downto 0); 407 | signal VdpCmdVramWrData : std_logic_vector(7 downto 0); 408 | signal VdpCmdSXTmp : std_logic_vector( 8 downto 0); 409 | signal VdpCmdDXTmp : std_logic_vector( 8 downto 0); 410 | signal VdpCmdNXTmp : std_logic_vector( 8 downto 0); 411 | 412 | -- state register 413 | type typVdpCmdState is (stVdpCmdIdle, stVdpCmdChkLoop, 414 | stVdpCmdRdCPU, stVdpCmdWaitCPU, 415 | stVdpCmdRdVram, stVdpCmdWaitRdVram, 416 | stVdpCmdPreRdVram, stVdpCmdWaitPreRdVram, 417 | stVdpCmdWrVram, stVdpCmdWaitWrVram, stVdpCmdExecEnd ); 418 | signal VdpCmdState : typVdpCmdState; 419 | 420 | -- 421 | signal iVideoR : std_logic_vector( 5 downto 0); 422 | signal iVideoG : std_logic_vector( 5 downto 0); 423 | signal iVideoB : std_logic_vector( 5 downto 0); 424 | signal iVideoHS_n : std_logic; 425 | signal iVideoVS_n : std_logic; 426 | 427 | signal iVideoR_ntsc : std_logic_vector( 5 downto 0); 428 | signal iVideoG_ntsc : std_logic_vector( 5 downto 0); 429 | signal iVideoB_ntsc : std_logic_vector( 5 downto 0); 430 | signal iVideoHS_n_ntsc : std_logic; 431 | signal iVideoVS_n_ntsc : std_logic; 432 | 433 | signal iVideoR_vga : std_logic_vector( 5 downto 0); 434 | signal iVideoG_vga : std_logic_vector( 5 downto 0); 435 | signal iVideoB_vga : std_logic_vector( 5 downto 0); 436 | signal iVideoHS_n_vga : std_logic; 437 | signal iVideoVS_n_vga : std_logic; 438 | 439 | 440 | begin 441 | ---------------------------------------------------------------- 442 | -- Display Components 443 | ---------------------------------------------------------------- 444 | ntsc1 : ntsc port map( clk21m, 445 | reset, 446 | iVideoR, 447 | iVideoG, 448 | iVideoB, 449 | iVideoHS_n, 450 | iVideoVS_n, 451 | iVideoR_ntsc, 452 | iVideoG_ntsc, 453 | iVideoB_ntsc, 454 | iVideoHS_n_ntsc, 455 | iVideoVS_n_ntsc); 456 | 457 | vga1 : vga port map( clk21m, 458 | reset, 459 | iVideoR, 460 | iVideoG, 461 | iVideoB, 462 | h_counter, 463 | v_counter, 464 | iVideoR_vga, 465 | iVideoG_vga, 466 | iVideoB_vga, 467 | iVideoHS_n_vga, 468 | iVideoVS_n_vga); 469 | 470 | -- JP: 外部から与えられるモード選択信号で 画面モードを変える 471 | pVideoR <= iVideoR_ntsc when dispModeVGA = '0' else iVideoR_vga; 472 | pVideoG <= iVideoG_ntsc when dispModeVGA = '0' else iVideoG_vga; 473 | pVideoB <= iVideoB_ntsc when dispModeVGA = '0' else iVideoB_vga; 474 | -- H Sync signal 475 | pVideoHS_n <= iVideoHS_n_ntsc when dispModeVGA = '0' else iVideoHS_n_vga; 476 | -- V Sync signal 477 | pVideoVS_n <= iVideoVS_n_ntsc when dispModeVGA = '0' else iVideoVS_n_vga; 478 | 479 | 480 | pVideoSYNC <= not (iVideoHS_n_ntsc xor iVideoVS_n_ntsc) when dispModeVGA = '0' 481 | else not (iVideoHS_n_vga xor iVideoVS_n_vga); 482 | 483 | -- JP: 以下の信号は画面モードに関わらず直接出力する 484 | pVideoCS_n <= not (iVideoHS_n xor iVideoVS_n); 485 | -- pVideoSYNC <= not (iVideoHS_n xor iVideoVS_n); 486 | pVideoSC <= cpuClockCounter(2); 487 | 488 | 489 | 490 | ---------------------------------------------------------------- 491 | -- 16byte FIFO control 492 | ---------------------------------------------------------------- 493 | fifoAddr <= ( "0000" & fifoAddr_in ) when (fifoIn = '1') else 494 | ( "0000" & fifoAddr_out ); 495 | fifoData_in <= pRamDat; 496 | fifoWe <= '1' when fifoIn = '1' else '0'; 497 | fifoFull <= '1' when fifoAddr_in+1 = fifoAddr_out else '0'; 498 | 499 | fifoMem : ram port map(fifoAddr, clk21m, fifoWe, fifoData_in, fifoData_out); 500 | 501 | ---------------------------------------------------------------- 502 | -- Palette Register control R and B 503 | ---------------------------------------------------------------- 504 | paletteAddr <= ( "0000" & paletteWrNum ) when (paletteInRB = '1' or paletteInG = '1') else 505 | ( "0000" & paletteAddr_out ); 506 | paletteData_in <= paletteWrTemp; 507 | paletteWeRB <= '1' when paletteInRB = '1' else '0'; 508 | paletteWeG <= '1' when paletteInG = '1' else '0'; 509 | 510 | paletteMemRB : ram port map(paletteAddr, clk21m, paletteWeRB, paletteData_in, paletteDataRB_out); 511 | paletteMemG : ram port map(paletteAddr, clk21m, paletteWeG, paletteData_in, paletteDataG_out); 512 | 513 | -- VSYNC Interrupt 514 | vsyncInt_n <= '0' when (vsyncIntReq /= vsyncIntAck) 515 | else '1'; 516 | -- HSYNC Interrupt 517 | hsyncInt_n <= '0' when (hsyncIntReq /= hsyncIntAck) 518 | else '1'; 519 | 520 | int_n <= '0' when (vsyncInt_n = '0') or (hsyncInt_n = '0') 521 | else 'Z'; 522 | 523 | -- VDP Mode 524 | VdpModeText1 <= '1' when (VdpR0DispNum = "000" and VdpR1DispMode = "10") else '0'; 525 | VdpModeText2 <= '1' when (VdpR0DispNum = "010" and VdpR1DispMode = "10") else '0'; 526 | VdpModeGraphic1 <= '1' when (VdpR0DispNum = "000" and VdpR1DispMode = "00") else '0'; 527 | VdpModeGraphic2 <= '1' when (VdpR0DispNum = "001" and VdpR1DispMode = "00") else '0'; 528 | VdpModeGraphic3 <= '1' when (VdpR0DispNum = "010" and VdpR1DispMode = "00") else '0'; 529 | VdpModeGraphic4 <= '1' when (VdpR0DispNum = "011" and VdpR1DispMode = "00") else '0'; 530 | VdpModeGraphic5 <= '1' when (VdpR0DispNum = "100" and VdpR1DispMode = "00") else '0'; 531 | VdpModeGraphic6 <= '1' when (VdpR0DispNum = "101" and VdpR1DispMode = "00") else '0'; 532 | VdpModeGraphic7 <= '1' when (VdpR0DispNum = "111" and VdpR1DispMode = "00") else '0'; 533 | SpMode2 <= '1' when (VdpModeGraphic3 = '1' or 534 | VdpModeGraphic4 = '1' or 535 | VdpModeGraphic5 = '1' or 536 | VdpModeGraphic6 = '1' or 537 | VdpModeGraphic7 = '1' ) else '0'; 538 | 539 | process( clk21m, reset ) 540 | begin 541 | if (reset = '1') then 542 | ack <= '0'; 543 | h_counter <= (others => '0'); 544 | v_counter <= (others => '0'); 545 | iVideoHS_n <= '1'; 546 | iVideoVS_n <= '1'; 547 | dVideoVS_n <= '1'; 548 | cpuClockCounter <= (others => '0'); 549 | sstate <= sstate_A; 550 | field <= '0'; 551 | vsyncIntReq <= '0'; 552 | hsyncIntReq <= '0'; 553 | elsif (clk21m'event and clk21m = '1') then 554 | ack <= req; 555 | -- 3.58MHz generator 556 | case cpuClockCounter is 557 | when "000" => cpuClockCounter <= "001"; 558 | when "001" => cpuClockCounter <= "011"; 559 | when "011" => cpuClockCounter <= "111"; 560 | when "111" => cpuClockCounter <= "110"; 561 | when "110" => cpuClockCounter <= "100"; 562 | when "100" => cpuClockCounter <= "000"; 563 | when others => cpuClockCounter <= "000"; 564 | end case; 565 | 566 | if( h_counter = CLOCKS_PER_LINE-1 ) then 567 | h_counter <= (others => '0' ); 568 | else 569 | h_counter <= h_counter + 1; 570 | end if; 571 | 572 | if( (h_counter = (CLOCKS_PER_LINE/2) -1) or (h_counter = CLOCKS_PER_LINE-1) ) then 573 | -- 524 lines * 2 = 1048 574 | -- 525 lines * 2 = 1050 575 | -- if( v_counter = 1049 ) then 576 | if((v_counter = 1047 and VdpR9InterlaceMode = '0') or 577 | (v_counter = 1049 and VdpR9InterlaceMode = '1')) then 578 | if(h_counter = CLOCKS_PER_LINE-1) then 579 | v_counter <= (others => '0'); 580 | end if; 581 | else 582 | v_counter <= v_counter + 1; 583 | end if; 584 | end if; 585 | 586 | if( (v_counter = 0) or 587 | (v_counter = 12) or 588 | ((v_counter = 524) and VdpR9InterlaceMode = '0') or 589 | ((v_counter = 525) and VdpR9InterlaceMode = '1') or 590 | ((v_counter = 524 + 12) and VdpR9InterlaceMode = '0') or 591 | ((v_counter = 525 + 12) and VdpR9InterlaceMode = '1') )then 592 | sstate <= sstate_A; 593 | elsif( (v_counter = 6) or 594 | ((v_counter = 524+6) and VdpR9InterlaceMode = '0') or 595 | ((v_counter = 525+6) and VdpR9InterlaceMode = '1') )then 596 | sstate <= sstate_B; 597 | elsif( (v_counter = 18) or 598 | ((v_counter = 524+18) and VdpR9InterlaceMode = '0') or 599 | ((v_counter = 525+18) and VdpR9InterlaceMode = '1') )then 600 | sstate <= sstate_C; 601 | end if; 602 | 603 | -- generate field signal 604 | if( (v_counter = 524 and VdpR9InterlaceMode = '0') or 605 | (v_counter = 525 and VdpR9InterlaceMode = '1') ) then 606 | field <= '1'; 607 | elsif( v_counter = 0 ) then 608 | field <= '0'; 609 | end if; 610 | 611 | -- generate H sync pulse 612 | if( sstate = sstate_A ) then 613 | if( (h_counter = 1) or (h_counter = CLOCKS_PER_LINE/2+1) ) then 614 | iVideoHS_n <= '0'; -- pulse on 615 | elsif( (h_counter = 51) or (h_counter = CLOCKS_PER_LINE/2+51) ) then 616 | iVideoHS_n <= '1'; -- pulse off 617 | end if; 618 | elsif( sstate = sstate_B ) then 619 | if( (h_counter = CLOCKS_PER_LINE -100+1) or 620 | (h_counter = CLOCKS_PER_LINE/2-100+1) ) then 621 | iVideoHS_n <= '0'; -- pulse on 622 | elsif( (h_counter = 1) or 623 | (h_counter = CLOCKS_PER_LINE/2+1) ) then 624 | iVideoHS_n <= '1'; -- pulse off 625 | end if; 626 | elsif( sstate = sstate_C ) then 627 | if( h_counter = 1 ) then 628 | iVideoHS_n <= '0'; -- pulse on 629 | elsif( h_counter = 101 ) then 630 | iVideoHS_n <= '1'; -- pulse off 631 | end if; 632 | end if; 633 | 634 | -- generate V sync pulse 635 | if( sstate = sstate_B ) then 636 | iVideoVS_n <= '0'; 637 | else 638 | iVideoVS_n <= '1'; 639 | end if; 640 | 641 | 642 | -- V Sync Interrupt Request 643 | -- dVideoVS_n <= iVideoVS_n; 644 | -- if( dVideoVS_n = '1' and iVideoVS_n = '0' ) then 645 | -- -- falling edge 646 | -- if( VdpR1VSyncIntEn = '1' ) then 647 | -- vsyncIntReq <= not vsyncIntAck; 648 | -- end if; 649 | -- end if; 650 | dVideoVS_n <= bwindow_y; 651 | if( dVideoVS_n = '1' and bwindow_y = '0' ) then 652 | -- falling edge 653 | if( VdpR1VSyncIntEn = '1' ) then 654 | -- vsyncIntReq <= not vsyncIntAck; 655 | vsyncIntReq <= not vsyncIntReq; 656 | end if; 657 | end if; 658 | 659 | -- H Sync Interrupt Request 660 | -- JP: 水平帰線期間割り込みのかかるラインの判定のしかたが 661 | -- JP: 実機と違うかも.適当な実装. 662 | -- JP: R19で指定している"ライン番号"は,垂直スクロールレジスタの 663 | -- JP: 影響を受けるようである. 664 | -- dVideoHS_n <= iVideoHS_n; 665 | -- if( dVideoHS_n = '1' and iVideoHS_n = '0' ) then 666 | -- -- falling edge 667 | -- if( (VdpR0HSyncIntEn = '1') and 668 | -- (VdpR19HSyncIntLine = preDotCounter_y) ) then 669 | -- hsyncIntReq <= not hsyncIntAck; 670 | -- end if; 671 | -- end if; 672 | 673 | -- if( (h_counter = CLOCKS_PER_LINE-1) and ( preWindow_y = '1') ) then 674 | if( (h_counter = CLOCKS_PER_LINE-1) ) then 675 | if( (VdpR0HSyncIntEn = '1') and 676 | (VdpR19HSyncIntLine = preDotCounter_y(7 downto 0)) ) then 677 | -- hsyncIntReq <= not hsyncIntAck; 678 | hsyncIntReq <= not hsyncIntReq; 679 | end if; 680 | end if; 681 | 682 | end if; 683 | 684 | end process; 685 | 686 | -- generate preWindow, window, g123window, spwindow 687 | preWindow <= (preWindow_x and preWindow_y); 688 | window <= (window_x and window_y); 689 | g123window <= (g123window_x and g123window_y); 690 | twindow <= (twindow_x and twindow_y); 691 | 692 | 693 | spwindow_ec <= spwindow_ecx and spwindow_y; 694 | spwindow <= spwindow_x and spwindow_y; 695 | 696 | -- JP: preDotCounter_x が最大値になったら1になるフラグ 697 | -- JP: SCREEN5(Graphic4)は横128バイト読み終わったらライン終了 698 | -- JP: SCREEN4以前は FIFOを使わないのでpreDotCounter_xが 255まで上がる 699 | -- JP: (汚い実装) 700 | preDotCounter_x_end <= '1' when ( ((VdpModeGraphic4 = '1') and (preDotCounter_x = "001111111")) or 701 | ((VdpModeGraphic4 = '0') and (preDotCounter_x = "011111111")) ) 702 | else '0'; 703 | 704 | process( clk21m, reset ) 705 | variable adjust_x : std_logic_vector(6 downto 0); 706 | variable adjust_y : std_logic_vector(6 downto 0); 707 | begin 708 | if (reset = '1') then 709 | dotCounter_x <= (others =>'0'); 710 | dotCounter_y <= (others =>'0'); 711 | dotCounter_yp <= (others =>'0'); 712 | preDotCounter_x <= (others =>'0'); 713 | preDotCounter_y <= (others =>'0'); 714 | preDotCounter_yp <= (others =>'0'); 715 | window_x <= '0'; 716 | window_y <= '0'; 717 | preWindow_x <= '0'; 718 | preWindow_y <= '0'; 719 | bwindow <= '0'; 720 | bwindow_x <= '0'; 721 | bwindow_y <= '0'; 722 | spwindow_x <= '0'; 723 | spwindow_y <= '0'; 724 | spwindow_ecx <= '0'; 725 | g123window_y <= '0'; 726 | g123window_x <= '0'; 727 | twindow_y <= '0'; 728 | twindow_x <= '0'; 729 | VramReadFreeFlag <= '0'; 730 | TXCharCounter_x <= (others => '0'); 731 | T1CharCounter_y <= (others => '0'); 732 | T2CharCounter_y <= (others => '0'); 733 | TXDotCounter_x <= (others => '0'); 734 | elsif (clk21m'event and clk21m = '1') then 735 | -- adjust 736 | adjust_x := OFFSET_X - ( VdpR18Adjust(3) & VdpR18Adjust(3) & VdpR18Adjust(3) & VdpR18Adjust(3 downto 0) ); 737 | if( VdpR9YDots = '0' ) then 738 | adjust_y := OFFSET_Y - ( VdpR18Adjust(7) & VdpR18Adjust(7) & VdpR18Adjust(7) & VdpR18Adjust(7 downto 4) ); 739 | else 740 | adjust_y := OFFSET_Y_212 - ( VdpR18Adjust(7) & VdpR18Adjust(7) & VdpR18Adjust(7) & VdpR18Adjust(7 downto 4) ); 741 | end if; 742 | 743 | 744 | if( h_counter = ("00" & adjust_x & "10" ) ) then 745 | preWindow_x <= '1'; 746 | g123window_x <= '1'; 747 | elsif( (h_counter( 1 downto 0) = "10") and ( preDotCounter_x_end = '1' ) ) then 748 | preWindow_x <= '0'; 749 | g123window_x <= '0'; 750 | end if; 751 | 752 | if( (v_counter = ("0000" & (adjust_y+1) & '0') ) or 753 | ((v_counter = 524+("0000" & (adjust_y+1) & '0')) and VdpR9InterlaceMode='0') or 754 | ((v_counter = 525+("0000" & (adjust_y+1) & '0')) and VdpR9InterlaceMode='1')) then 755 | preWindow_y <= '1'; 756 | window_y <= '1'; 757 | g123window_y <= '1'; 758 | twindow_y <= '1'; 759 | elsif( (VdpR9YDots = '1') and 760 | ( (v_counter = ("0000" & (adjust_y+1) & '0')+212*2) or 761 | ((v_counter = 524+("0000" & (adjust_y+1) & '0')+212*2) and VdpR9InterlaceMode='0') or 762 | ((v_counter = 525+("0000" & (adjust_y+1) & '0')+212*2) and VdpR9InterlaceMode='1') ) ) then 763 | -- JP: 画面モードにかかわりなく Yドット数変更ビットを有効にして 764 | -- JP: 良いかどうか確認する必要あり. 765 | preWindow_y <= '0'; 766 | window_y <= '0'; 767 | g123window_y <= '0'; 768 | twindow_y <= '0'; 769 | elsif( (VdpR9YDots = '0') and 770 | ( (v_counter = ("0000" & (adjust_y+1) & '0')+192*2) or 771 | ((v_counter = 524+("0000" & (adjust_y+1) & '0')+192*2) and VdpR9InterlaceMode='0') or 772 | ((v_counter = 525+("0000" & (adjust_y+1) & '0')+192*2) and VdpR9InterlaceMode='1') ) ) then 773 | preWindow_y <= '0'; 774 | window_y <= '0'; 775 | g123window_y <= '0'; 776 | twindow_y <= '0'; 777 | end if; 778 | 779 | if( (v_counter = ("0000" & adjust_y & '0') ) or 780 | ((v_counter = 524+("0000" & adjust_y & '0')) and VdpR9InterlaceMode='0') or 781 | ((v_counter = 525+("0000" & adjust_y & '0')) and VdpR9InterlaceMode='1') ) then 782 | spwindow_y <= '1'; 783 | elsif( (v_counter = ("0000" & adjust_y & '0')+212*2) or 784 | ((v_counter = 524+("0000" & adjust_y & '0')+212*2) and VdpR9InterlaceMode='0') or 785 | ((v_counter = 525+("0000" & adjust_y & '0')+212*2) and VdpR9InterlaceMode='1') ) then 786 | spwindow_y <= '0'; 787 | end if; 788 | 789 | -- main window 790 | if( (h_counter( 1 downto 0) = "10") and ( dotCounter_x = "111111111" ) ) then 791 | -- when dotCounter_x = -1 792 | window_x <= '1'; 793 | elsif( (h_counter( 1 downto 0) = "10") and ( dotCounter_x ="011111111" ) ) then 794 | -- when dotCounter_x = 255 795 | window_x <= '0'; 796 | end if; 797 | 798 | -- if( (h_counter( 1 downto 0) = "10") and ( preDotCounter_x = 7- ) and (window_y = '1') ) then 799 | -- elsif( (h_counter( 1 downto 0) = "10") and ( preDotCounter_x = 255 ) ) then 800 | -- end if; 801 | 802 | if( h_counter = ("00" & ( adjust_x - 24 -2) & "10" ) ) then 803 | spwindow_ecx <= '1'; 804 | elsif( h_counter = ("00" & ( adjust_x + 8 -2) & "10" ) ) then 805 | spwindow_x <= '1'; 806 | elsif( (h_counter( 1 downto 0) = "10") and ( preDotCounter_x_end = '1' ) ) then 807 | spwindow_x <= '0'; 808 | spwindow_ecx <= '0'; 809 | end if; 810 | 811 | -- JP: 16回に 1回 vram アクセス用に vramバスを開放するために、FIFOを用いる 812 | -- JP: 813 | -- JP: 814 | -- JP: 815 | -- JP: 816 | -- JP: R23の変更が即座に反映されるようにした. 817 | dotCounter_y <= dotCounter_yp + VdpR23VStartLine; 818 | 819 | if( h_counter = ("00" & adjust_x & "10") ) then 820 | preDotCounter_x <= (others =>'0'); 821 | VramReadFreeFlag <= '0'; 822 | if( v_counter = ("000" & adjust_y & '0') ) then 823 | dotCounter_yp <= (others => '1'); -- -1 824 | elsif( ((v_counter = ("000" & adjust_y & '0')+524) and VdpR9InterlaceMode='0') or 825 | ((v_counter = ("000" & adjust_y & '0')+525) and VdpR9InterlaceMode='1') ) then 826 | dotCounter_yp <= (others => '1'); -- -1 827 | else 828 | dotCounter_yp <= dotCounter_yp + 1; 829 | end if; 830 | elsif( (h_counter( 1 downto 0) = "10") and 831 | (VramReadFreeFlag = '0') and 832 | (fifoFull = '0' ) ) then 833 | -- JP: ReadFreeFlagが立っておらず、FIFOが FULLでないなら、 834 | -- JP: 1"バイト"読む。これは SCREEN5でも8でもいっしょ。 835 | -- JP: (1ドット表示する間に 1バイト読む) 836 | preDotCounter_x <= preDotCounter_x + 1; 837 | if( preDotCounter_x( 3 downto 0 ) = "1111" ) then 838 | VramReadFreeFlag <= '1'; 839 | end if; 840 | elsif( (h_counter( 1 downto 0) = "10") and (VramReadFreeFlag = '1') ) then 841 | VramReadFreeFlag <= '0'; 842 | end if; 843 | 844 | -- dot counter 845 | if( h_counter = ("00" & adjust_x & "10") ) then 846 | dotCounter_x <= "111111000"; -- -8 847 | elsif( h_counter( 1 downto 0) = "10") then 848 | dotCounter_x <= dotCounter_x + 1; 849 | end if; 850 | 851 | -- JP: R23の変更が即座に反映されるようにした. 852 | preDotCounter_y <= preDotCounter_yp + ('0' & VdpR23VStartLine); 853 | if( h_counter = CLOCKS_PER_LINE-1 ) then 854 | if( v_counter = ("0000" & adjust_y & '1') ) then 855 | preDotCounter_yp <= (others => '0'); 856 | elsif( ((v_counter = ("0000" & adjust_y & '1')+524) and VdpR9InterlaceMode='0') or 857 | ((v_counter = ("0000" & adjust_y & '1')+525) and VdpR9InterlaceMode='1') ) then 858 | preDotCounter_yp <= (others => '0'); 859 | else 860 | preDotCounter_yp <= preDotCounter_yp + 1; 861 | end if; 862 | end if; 863 | 864 | if( VdpModeText1 = '1') then 865 | -- counter for Text 1 866 | if( (h_counter( 1 downto 0) = "10") and ( dotCounter_x = "111111111" ) ) then 867 | TXDotCounter_x <= "100"; -- 4 868 | TXCharCounter_x <= "1111111111"; -- -1 869 | if( dotCounter_y = "00000000" ) then 870 | T1CharCounter_y <= (others => '0'); 871 | elsif( dotCounter_y( 2 downto 0) = "000" ) then 872 | T1CharCounter_y <= T1CharCounter_y + 40; 873 | end if; 874 | elsif( h_counter( 1 downto 0) = "10") then 875 | if( TXDotCounter_x = "101" ) then 876 | TXDotCounter_x <= "000"; 877 | TXCharCounter_x <= TXCharCounter_x + 1; 878 | else 879 | TXDotCounter_x <= TXDotCounter_x + 1; 880 | end if; 881 | end if; 882 | elsif( VdpModeText2 = '1' ) then 883 | -- counter for Text 2 884 | if( (h_counter( 1 downto 0) = "10") and ( dotCounter_x = "111111111" ) ) then 885 | TXDotCounter_x <= "001"; -- 1 886 | TXCharCounter_x <= "1111111110"; -- -2 887 | if( dotCounter_y = "00000000" ) then 888 | T2CharCounter_y <= (others => '0'); 889 | elsif( dotCounter_y( 2 downto 0) = "000" ) then 890 | T2CharCounter_y <= T2CharCounter_y + 80; 891 | end if; 892 | elsif( h_counter( 1 downto 0) = "10") then 893 | if( TXDotCounter_x = "010" ) then 894 | TXDotCounter_x <= "000"; 895 | TXCharCounter_x <= TXCharCounter_x + 1; 896 | else 897 | TXDotCounter_x <= TXDotCounter_x + 1; 898 | end if; 899 | end if; 900 | end if; 901 | 902 | -- text1 window 903 | if( (h_counter( 1 downto 0) = "10") and ( dotCounter_x = "000000111" ) ) then 904 | twindow_x <= '1'; 905 | elsif( (h_counter( 1 downto 0) = "10") and ( dotCounter_x = "011110111" ) ) then 906 | twindow_x <= '0'; 907 | end if; 908 | 909 | -- generate bwindow 910 | if( h_counter = 200-1 ) then 911 | bwindow_x <= '1'; 912 | elsif( h_counter = CLOCKS_PER_LINE-1-1 ) then 913 | bwindow_x <= '0'; 914 | end if; 915 | 916 | if( VdpR9InterlaceMode='0' ) then 917 | if( (v_counter = 10*2-1) or 918 | (v_counter = 524+10*2-1) ) then 919 | bwindow_y <= '1'; 920 | elsif( (v_counter = 523-1) or 921 | (v_counter = 524+524-1) ) then 922 | bwindow_y <= '0'; 923 | end if; 924 | else 925 | if( (v_counter = 10*2-1) or 926 | (v_counter = 525+10*2-1) ) then 927 | bwindow_y <= '1'; 928 | elsif( (v_counter = 524-1) or 929 | (v_counter = 525+524-1) ) then 930 | bwindow_y <= '0'; 931 | end if; 932 | end if; 933 | 934 | if( (bwindow_x = '1') and (bwindow_y = '1') )then 935 | bwindow <= '1'; 936 | else 937 | bwindow <= '0'; 938 | end if; 939 | 940 | end if; 941 | end process; 942 | 943 | 944 | -- color generator 945 | process( clk21m, reset ) 946 | variable SpAttrTblBaseAddr : std_logic_vector(9 downto 0); 947 | variable SpPtnGeneTblBaseAddr : std_logic_vector(5 downto 0); 948 | begin 949 | if (reset = '1') then 950 | dotState <= (others => '0' ); 951 | colorCode <= (others => '0' ); 952 | iVideoR <= "000000"; 953 | iVideoG <= "000000"; 954 | iVideoB <= "000000"; 955 | pVideoDHClk <= '0'; 956 | pVideoDLClk <= '0'; 957 | 958 | paletteWrAckRB <= '0'; 959 | paletteWrAckG <= '0'; 960 | paletteAddr_out <= (others => '0'); 961 | paletteInRB <= '0'; 962 | paletteInG <= '0'; 963 | 964 | pRamAdr <= (others => '1'); 965 | pRamDat <= (others => 'Z'); 966 | pRamOe_n <= '1'; 967 | pRamWe_n <= '1'; 968 | 969 | SpPreReading <= '0'; 970 | VdpVramReading <= '0'; 971 | 972 | VdpVramRdAck <= '0'; 973 | VdpVramWrAck <= '0'; 974 | VdpVramRdData <= (others => '0'); 975 | VdpVramAddrSetAck <= '0'; 976 | VdpVramAccessAddr <= (others => '0'); 977 | 978 | VdpCmdVramWrAck <= '0'; 979 | VdpCmdVramRdAck <= '0'; 980 | VdpCmdVramReading <= '0'; 981 | VdpCmdVramRdData <= (others => '0'); 982 | elsif (clk21m'event and clk21m = '1') then 983 | if( h_counter = CLOCKS_PER_LINE-1) then 984 | dotState <= "00"; 985 | pVideoDHClk <= '1'; 986 | pVideoDLClk <= '1'; 987 | else 988 | case dotState is 989 | when "00" => 990 | dotState <= "01"; 991 | pVideoDHClk <= '0'; 992 | pVideoDLClk <= '1'; 993 | when "01" => 994 | dotState <= "11"; 995 | pVideoDHClk <= '1'; 996 | pVideoDLClk <= '0'; 997 | when "11" => 998 | dotState <= "10"; 999 | pVideoDHClk <= '0'; 1000 | pVideoDLClk <= '0'; 1001 | when "10" => 1002 | dotState <= "00"; 1003 | pVideoDHClk <= '1'; 1004 | pVideoDLClk <= '1'; 1005 | when others => null; 1006 | end case; 1007 | end if; 1008 | 1009 | -- 1010 | -- dotState 10 00 01 11 10 00 01 11 10 1011 | -- | | 1012 | -- pRamCe_n 11\000000000000000000000 1013 | -- pRamOe_n 11\00000/111111111111111 1014 | -- pRamWe_n 11111111111111\00000/111 1015 | -- pRamAdr < >-----< > 1016 | -- pRamDat >ZZZZZZ 1017 | -- | 1018 | -- 1019 | 1020 | -- variable 1021 | -- if( v_counter = 200 ) then 1022 | if( SpPreReadState = spstate_idle ) then 1023 | if( SpMode2 = '0' ) then 1024 | SpAttrTblBaseAddr := VdpR11R5SpAttrTblBaseAddr; 1025 | else 1026 | -- SpAttrTblBaseAddr := VdpR11R5SpAttrTblBaseAddr(9 downto 3) & "100"; 1027 | SpAttrTblBaseAddr := VdpR11R5SpAttrTblBaseAddr(9 downto 2) & "00"; 1028 | end if; 1029 | 1030 | SpPtnGeneTblBaseAddr := VdpR6SpPtnGeneTblBaseAddr; 1031 | end if; 1032 | -- end if; 1033 | 1034 | -- main state 1035 | case dotState is 1036 | when "10" => 1037 | if( (VdpModeGraphic7 = '1') and (preWindow = '1') and 1038 | (VramReadFreeFlag = '0' ) and 1039 | (fifoFull = '0') and 1040 | (VdpR1DispOn='1') ) then 1041 | pRamAdr <= (preDotCounter_x(0) & 1042 | VdpR2PtnNameTblBaseAddr(5) & 1043 | preDotCounter_y(7 downto 0) & preDotCounter_x(7 downto 1)); 1044 | pRamDat <= (others => 'Z' ); 1045 | pRamOe_n <= '0'; 1046 | pRamWe_n <= '1'; 1047 | elsif( (VdpModeGraphic4 = '1') and (preWindow = '1') and 1048 | (VramReadFreeFlag = '0' ) and 1049 | (fifoFull = '0') and 1050 | (VdpR1DispOn='1') ) then 1051 | pRamAdr <= (VdpR2PtnNameTblBaseAddr(6 downto 5) & 1052 | preDotCounter_y(7 downto 0) & preDotCounter_x( 6 downto 0)); 1053 | pRamDat <= (others => 'Z' ); 1054 | pRamOe_n <= '0'; 1055 | pRamWe_n <= '1'; 1056 | elsif( (VdpModeGraphic1 = '1') and (g123Window = '1') and 1057 | (dotcounter_x(0) = '1') and (VdpR1DispOn='1') ) then 1058 | -- screen 1 1059 | pRamDat <= (others => 'Z' ); 1060 | pRamOe_n <= '0'; 1061 | pRamWe_n <= '1'; 1062 | case dotCounter_x(2 downto 0) is 1063 | when "011" => 1064 | -- read pattern name table 1065 | pRamAdr <= (VdpR2PtnNameTblBaseAddr & 1066 | dotCounter_y(7 downto 3) & (dotCounter_x(7 downto 3)+1) ); 1067 | when "101" => 1068 | -- read pattern Generator table 1069 | pRamAdr <= (VdpR4PtnGeneTblBaseAddr & G1PtnNum & 1070 | dotCounter_y(2 downto 0) ); 1071 | when "111" => 1072 | -- read color table 1073 | pRamAdr <= (VdpR10R3ColorTblBaseAddr & '0' & G1PtnNum( 7 downto 3 ) ); 1074 | when others => 1075 | null; 1076 | end case; 1077 | elsif( (VdpModeGraphic2 = '1' or VdpModeGraphic3 = '1') and 1078 | (g123Window = '1') and (dotcounter_x(0) = '1') and (VdpR1DispOn='1') ) then 1079 | -- screen 2, 4 1080 | pRamDat <= (others => 'Z'); 1081 | pRamOe_n <= '0'; 1082 | pRamWe_n <= '1'; 1083 | case dotCounter_x(2 downto 0) is 1084 | when "011" => 1085 | -- read pattern name table 1086 | pRamAdr <= (VdpR2PtnNameTblBaseAddr & 1087 | dotCounter_y(7 downto 3) & (dotCounter_x(7 downto 3)+1) ); 1088 | when "101" => 1089 | -- read pattern Generator table 1090 | pRamAdr <= (VdpR4PtnGeneTblBaseAddr(5 downto 2) & 1091 | dotCounter_y(7 downto 6) & G1PtnNum & dotCounter_y(2 downto 0) ) and 1092 | ("1111" & VdpR4PtnGeneTblBaseAddr(1 downto 0) & "11111111" & "111"); 1093 | when "111" => 1094 | -- read color table 1095 | pRamAdr <= (VdpR10R3ColorTblBaseAddr(10 downto 7) & 1096 | dotCounter_y(7 downto 6) & G1PtnNum & dotCounter_y(2 downto 0) ) and 1097 | ("1111" & VdpR10R3ColorTblBaseAddr(6 downto 0) & "111111" ); 1098 | when others => 1099 | null; 1100 | end case; 1101 | elsif( (VdpModeText1 = '1') and (window = '1') and 1102 | (TXDotCounter_x(0) = '1') and (VdpR1DispOn='1') ) then 1103 | -- text 1 (screen 0 width 40) 1104 | pRamDat <= (others => 'Z' ); 1105 | pRamOe_n <= '0'; 1106 | pRamWe_n <= '1'; 1107 | case TXDotCounter_x is 1108 | when "001" => 1109 | -- read pattern name table 1110 | pRamAdr <= (VdpR2PtnNameTblBaseAddr & (T1CharCounter_y+TXCharCounter_x) ); 1111 | when "011" => 1112 | null; 1113 | when "101" => 1114 | -- read pattern Generator table 1115 | pRamAdr <= (VdpR4PtnGeneTblBaseAddr & T1PtnNum & dotCounter_y(2 downto 0) ); 1116 | when others => 1117 | null; 1118 | end case; 1119 | elsif( (VdpModeText2 = '1') and (window = '1') and 1120 | ((TXDotCounter_x = "001") or (TXDotCounter_x = "010")) and 1121 | (VdpR1DispOn='1') ) then 1122 | -- text 2 (screen 0 width 80) 1123 | pRamDat <= (others => 'Z' ); 1124 | pRamOe_n <= '0'; 1125 | pRamWe_n <= '1'; 1126 | case TXDotCounter_x is 1127 | when "001" => 1128 | -- read pattern name table 1129 | pRamAdr <= VdpR2PtnNameTblBaseAddr(6 downto 2) & 1130 | (T2CharCounter_y+TXCharCounter_x) ; 1131 | when "010" => 1132 | -- read pattern Generator table 1133 | pRamAdr <= (VdpR4PtnGeneTblBaseAddr & T2PtnNum & dotCounter_y(2 downto 0) ); 1134 | when others => 1135 | null; 1136 | end case; 1137 | elsif( VdpVramWrReq /= VdpVramWrAck ) then 1138 | -- JP: VRAMへの書き込み 1139 | -- JP: GRAPHIC6,7ではアドレスと RAM上の位置が他の画面モードと 1140 | -- JP: 異るので注意 1141 | if( VdpModeGraphic7 = '1' ) then 1142 | pRamAdr <= VdpVramAccessAddr(0) & 1143 | VdpVramAccessAddr(16 downto 1); 1144 | else 1145 | pRamAdr <= VdpVramAccessAddr; 1146 | end if; 1147 | VdpVramAccessAddr <= VdpVramAccessAddr + 1; 1148 | pRamDat <= VdpVramAccessData; 1149 | pRamOe_n <= '1'; 1150 | pRamWe_n <= '0'; 1151 | VdpVramWrAck <= not VdpVramWrAck; 1152 | elsif( VdpVramRdReq /= VdpVramRdAck ) then 1153 | -- JP: VRAMからの読み込み 1154 | -- JP: GRAPHIC6,7ではアドレスと RAM上の位置が他の画面モードと 1155 | -- JP: 異るので注意(要修正) 1156 | if( VdpVramAddrSetReq /= VdpVramAddrSetAck ) then 1157 | pRamAdr <= VdpVramAccessAddrTmp; 1158 | VdpVramAccessAddr <= VdpVramAccessAddrTmp + 1; 1159 | VdpVramAddrSetAck <= not VdpVramAddrSetAck; 1160 | else 1161 | pRamAdr <= VdpVramAccessAddr; 1162 | VdpVramAccessAddr <= VdpVramAccessAddr + 1; 1163 | end if; 1164 | pRamDat <= (others => 'Z'); 1165 | pRamOe_n <= '0'; 1166 | pRamWe_n <= '1'; 1167 | VdpVramRdAck <= not VdpVramRdAck; 1168 | VdpVramReading <= '1'; 1169 | elsif( (SpPreReadState /= spstate_idle) and (VdpR8SpOff='0') and 1170 | ( VramReadFreeFlag = '0') )then 1171 | SpPreReading <= '1'; 1172 | pRamDat <= (others => 'Z' ); 1173 | pRamOe_n <= '0'; 1174 | pRamWe_n <= '1'; 1175 | 1176 | case SpPreReadState is 1177 | when spstate_yread => 1178 | pRamAdr <= SpAttrTblBaseAddr & SpPreReadCounter & "00"; 1179 | when spstate_xread => 1180 | pRamAdr <= SpAttrTblBaseAddr & SpPreReadCounter & "01"; 1181 | when spstate_ptnnumread => 1182 | pRamAdr <= SpAttrTblBaseAddr & SpPreReadCounter & "10"; 1183 | when spstate_colorread => 1184 | if( SpMode2 = '0' ) then 1185 | pRamAdr <= SpAttrTblBaseAddr & SpPreReadCounter & "11"; 1186 | else 1187 | -- sprite color table 1188 | -- pRamAdr <= (SpAttrTblBaseAddr(9 downto 3) & "0" & 1189 | -- SpPreReadCounter & SpPreReadY( 3 downto 0)); 1190 | pRamAdr <= (SpAttrTblBaseAddr(9 downto 3) & not SpAttrTblBaseAddr(2) & 1191 | SpPreReadCounter & SpPreReadY( 3 downto 0)); 1192 | end if; 1193 | when spstate_ptnread1 => 1194 | if( VdpR1SpSize = '0' ) then 1195 | -- 8x8 mode 1196 | pRamAdr <= (SpPtnGeneTblBaseAddr & 1197 | SpPreReadPtnNum( 7 downto 0) & SpPreReadY( 2 downto 0) ); 1198 | else 1199 | -- 16x16 mode 1200 | pRamAdr <= (SpPtnGeneTblBaseAddr & 1201 | SpPreReadPtnNum( 7 downto 2) & '0' & SpPreReadY( 3 downto 0) ); 1202 | end if; 1203 | when spstate_ptnread2 => 1204 | if( VdpR1SpSize = '0' ) then 1205 | -- 8x8 mode 1206 | null; 1207 | else 1208 | -- 16x16 mode 1209 | pRamAdr <= (SpPtnGeneTblBaseAddr & 1210 | SpPreReadPtnNum( 7 downto 2) & '1' & SpPreReadY( 3 downto 0) ); 1211 | end if; 1212 | when others => 1213 | null; 1214 | end case; 1215 | elsif( VdpCmdVramWrReq /= VdpCmdVramWrAck ) then 1216 | -- JP: VDPコマンドによるVRAMへの書き込み 1217 | -- JP: GRAPHIC6,7ではアドレスと RAM上の位置が他の画面モードと 1218 | -- JP: 異るので注意 1219 | if( VdpModeGraphic7 = '1' ) then 1220 | pRamAdr <= VdpCmdVramAccessAddr(0) & 1221 | VdpCmdVramAccessAddr(16 downto 1); 1222 | else 1223 | pRamAdr <= VdpCmdVramAccessAddr; 1224 | end if; 1225 | pRamDat <= VdpCmdVramWrData; 1226 | pRamOe_n <= '1'; 1227 | pRamWe_n <= '0'; 1228 | VdpCmdVramWrAck <= not VdpCmdVramWrAck; 1229 | elsif( VdpCmdVramRdReq /= VdpCmdVramRdAck ) then 1230 | -- JP: VDPコマンドによるVRAMからの読み込み 1231 | -- JP: GRAPHIC6,7ではアドレスと RAM上の位置が他の画面モードと 1232 | -- JP: 異るので注意 1233 | if( VdpModeGraphic7 = '1' ) then 1234 | pRamAdr <= VdpCmdVramAccessAddr(0) & 1235 | VdpCmdVramAccessAddr(16 downto 1); 1236 | else 1237 | pRamAdr <= VdpCmdVramAccessAddr; 1238 | end if; 1239 | pRamDat <= (others => 'Z'); 1240 | pRamOe_n <= '0'; 1241 | pRamWe_n <= '1'; 1242 | VdpCmdVramReading <= '1'; 1243 | end if; 1244 | if( bwindow = '1' ) then 1245 | if( VdpModeGraphic7 = '1' ) then 1246 | iVideoR <= colorCode(4 downto 2) & "000"; 1247 | iVideoG <= colorCode(7 downto 5) & "000"; 1248 | iVideoB <= colorCode(1 downto 0) & colorCode(1) & "000"; 1249 | else 1250 | iVideoR <= paletteDataRB_out(6 downto 4) & "000"; 1251 | iVideoB <= paletteDataRB_out(2 downto 0) & "000"; 1252 | iVideoG <= paletteDataG_out(2 downto 0) & "000"; 1253 | end if; 1254 | else 1255 | iVideoR <= (others => '0'); 1256 | iVideoG <= (others => '0'); 1257 | iVideoB <= (others => '0'); 1258 | iVideoB <= (others => '0'); 1259 | end if; 1260 | 1261 | when "00" => 1262 | pRamWe_n <= '1'; 1263 | pRamOe_n <= '1'; 1264 | 1265 | if( VdpModeText2 = '1' ) then 1266 | if( twindow = '0' ) then 1267 | paletteAddr_out <= VdpR7FrameColor(3 downto 0); 1268 | elsif( (VdpR8Color0On = '0') and (T2ColorCode = "0000") ) then 1269 | paletteAddr_out <= VdpR7FrameColor(3 downto 0); 1270 | else 1271 | paletteAddr_out <= T2ColorCode; 1272 | end if; 1273 | end if; 1274 | 1275 | when "01" => 1276 | if( paletteWrReqRB /= paletteWrAckRB ) then 1277 | paletteInRB <= '1'; 1278 | paletteWrAckRB <= not paletteWrAckRB; 1279 | elsif( paletteWrReqG /= paletteWrAckG ) then 1280 | paletteInG <= '1'; 1281 | paletteWrAckG <= not paletteWrAckG; 1282 | end if; 1283 | -- paletteInRB <= '0'; 1284 | -- paletteInG <= '0'; 1285 | 1286 | if( bwindow = '1' ) then 1287 | if( VdpModeText2 = '1' ) then 1288 | -- (Screen0 width 80) 1289 | iVideoR <= paletteDataRB_out(6 downto 4) & "000"; 1290 | iVideoB <= paletteDataRB_out(2 downto 0) & "000"; 1291 | iVideoG <= paletteDataG_out(2 downto 0) & "000"; 1292 | end if; 1293 | end if; 1294 | 1295 | if( VdpVramReading = '1' ) then 1296 | VdpVramRdData <= pRamDat; 1297 | end if; 1298 | VdpVramReading <= '0'; 1299 | if( VdpCmdVramReading = '1' ) then 1300 | VdpCmdVramRdData <= pRamDat; 1301 | VdpCmdVramRdAck <= not VdpCmdVramRdAck; 1302 | end if; 1303 | VdpCmdVramReading <= '0'; 1304 | -- pRamWe_n <= '1'; 1305 | -- pRamOe_n <= '1'; 1306 | pRamDat <= (others => 'Z'); 1307 | -- pRamAdr <= (others => 'Z'); 1308 | 1309 | if( (window = '1') and (VdpR1DispOn = '1') ) then 1310 | -- JP: スプライトの表示 1311 | if((SpPattern(0)(16) = '1') or (SpPattern(1)(16) = '1') or 1312 | (SpPattern(2)(16) = '1') or (SpPattern(3)(16) = '1') or 1313 | ((SpMode2 = '1') and 1314 | ((SpPattern(4)(16) = '1') or (SpPattern(5)(16) = '1') or 1315 | (SpPattern(6)(16) = '1') or (SpPattern(7)(16) = '1'))) ) then 1316 | colorCode <= "0000" & spColorCode_3 & spColorCode(2 downto 0); 1317 | elsif( VdpModeGraphic1 = '1' ) then 1318 | if( (VdpR8Color0On = '0') and (G1ColorCode = "0000") ) then 1319 | colorCode <= VdpR7FrameColor; 1320 | else 1321 | colorCode <= "0000" & G1ColorCode; 1322 | end if; 1323 | elsif( VdpModeGraphic2 = '1' or VdpModeGraphic3 = '1' ) then 1324 | if( (VdpR8Color0On = '0') and (G1ColorCode = "0000") ) then 1325 | colorCode <= VdpR7FrameColor; 1326 | else 1327 | colorCode <= "0000" & G1ColorCode; 1328 | end if; 1329 | elsif( VdpModeGraphic4 = '1' ) then 1330 | if( (VdpR8Color0On = '0') and (G4ColorCode = "0000") ) then 1331 | colorCode <= VdpR7FrameColor; 1332 | else 1333 | colorCode <= "0000" & G4ColorCode; 1334 | end if; 1335 | elsif( VdpModeGraphic7 = '1' ) then 1336 | if( (VdpR8Color0On = '0') and (G7ColorCode = "00000000") ) then 1337 | colorCode <= VdpR7FrameColor; 1338 | else 1339 | colorCode <= G7ColorCode; 1340 | end if; 1341 | elsif( VdpModeText1 = '1' ) then 1342 | if( twindow = '0' ) then 1343 | colorCode <= VdpR7FrameColor; 1344 | elsif( (VdpR8Color0On = '0') and (T1ColorCode = "0000") ) then 1345 | colorCode <= VdpR7FrameColor; 1346 | else 1347 | colorCode <= "0000" & T1ColorCode; 1348 | end if; 1349 | elsif( VdpModeText2 = '1' ) then 1350 | if( twindow = '0' ) then 1351 | colorCode <= VdpR7FrameColor; 1352 | elsif( (VdpR8Color0On = '0') and (T2ColorCode = "0000") ) then 1353 | colorCode <= VdpR7FrameColor; 1354 | else 1355 | colorCode <= "0000" & T2ColorCode; 1356 | end if; 1357 | end if; 1358 | else 1359 | colorCode <= VdpR7FrameColor; 1360 | end if; 1361 | when "11" => 1362 | SpPreReading <= '0'; 1363 | paletteInRB <= '0'; 1364 | paletteInG <= '0'; 1365 | 1366 | -- Palette decoding 1367 | paletteAddr_out <= colorCode( 3 downto 0); 1368 | 1369 | if( VdpVramAddrSetReq /= VdpVramAddrSetAck ) then 1370 | VdpVramAccessAddr <= VdpVramAccessAddrTmp; 1371 | VdpVramAddrSetAck <= not VdpVramAddrSetAck; 1372 | end if; 1373 | 1374 | when others => 1375 | null; 1376 | end case; 1377 | end if; 1378 | end process; 1379 | 1380 | process( clk21m, reset ) 1381 | begin 1382 | if (reset = '1') then 1383 | T1ColorCode <= (others => '0'); 1384 | T1PtnNum <= (others => '0'); 1385 | T1Pattern <= (others => '0'); 1386 | T2ColorCode <= (others => '0'); 1387 | T2PtnNum <= (others => '0'); 1388 | T2Pattern <= (others => '0'); 1389 | G1ColorCode <= (others => '0'); 1390 | G1PtnNum <= (others => '0'); 1391 | G1Pattern <= (others => '0'); 1392 | G1PPattern <= (others => '0'); 1393 | G1Color <= (others => '0'); 1394 | G4ColorCode <= (others => '0'); 1395 | G7ColorCode <= (others => '0'); 1396 | fifoAddr_in <= (others => '0'); 1397 | fifoAddr_out <= (others => '0'); 1398 | fifoIn <= '0'; 1399 | elsif (clk21m'event and clk21m = '1') then 1400 | -- text 1 state 1401 | case dotState is 1402 | when "10" => 1403 | null; 1404 | when "00" => 1405 | if( T1Pattern(7) = '1' ) then 1406 | T1ColorCode <= VdpR7FrameColor(7 downto 4); 1407 | else 1408 | T1ColorCode <= VdpR7FrameColor(3 downto 0); 1409 | end if; 1410 | T1Pattern <= T1Pattern(6 downto 0) & '0'; 1411 | when "01" => 1412 | case TXDotCounter_x is 1413 | when "001" => 1414 | -- read pattern name table 1415 | T1PtnNum <= pRamDat; 1416 | when "011" => 1417 | null; 1418 | when "101" => 1419 | -- read pattern Generator table 1420 | T1Pattern <= pRamDat; 1421 | when others => 1422 | null; 1423 | end case; 1424 | when "11" => 1425 | null; 1426 | when others => 1427 | null; 1428 | end case; 1429 | 1430 | -- text 2 state 1431 | case dotState is 1432 | when "00" | "11" => 1433 | if( T2Pattern(7) = '1' ) then 1434 | T2ColorCode <= VdpR7FrameColor(7 downto 4); 1435 | else 1436 | T2ColorCode <= VdpR7FrameColor(3 downto 0); 1437 | end if; 1438 | T2Pattern <= T2Pattern(6 downto 0) & '0'; 1439 | when "01" => 1440 | case TXDotCounter_x is 1441 | when "001" => 1442 | -- read pattern name table 1443 | T2PtnNum <= pRamDat; 1444 | when "010" => 1445 | -- read pattern Generator table 1446 | T2Pattern <= pRamDat; 1447 | when others => 1448 | null; 1449 | end case; 1450 | when "10" => 1451 | null; 1452 | when others => 1453 | null; 1454 | end case; 1455 | 1456 | -- graphic 1,2,3 state 1457 | case dotState is 1458 | when "10" => 1459 | null; 1460 | when "00" => 1461 | if( G1Pattern(7) = '1' ) then 1462 | G1ColorCode <= G1Color(7 downto 4); 1463 | else 1464 | G1ColorCode <= G1Color(3 downto 0); 1465 | end if; 1466 | G1Pattern <= G1Pattern(6 downto 0) & '0'; 1467 | when "01" => 1468 | case dotCounter_x(2 downto 0) is 1469 | when "011" => 1470 | -- read pattern name table 1471 | G1PtnNum <= pRamDat; 1472 | when "101" => 1473 | -- read pattern Generator table 1474 | G1PPattern <= pRamDat; 1475 | when "111" => 1476 | -- read color table 1477 | G1Color <= pRamDat; 1478 | G1Pattern <= G1PPattern; 1479 | when others => 1480 | null; 1481 | end case; 1482 | when "11" => 1483 | null; 1484 | when others => null; 1485 | end case; 1486 | 1487 | if( VdpModeGraphic4 = '1') then 1488 | -- graphic 4 state 1489 | case dotState is 1490 | when "10" => 1491 | null; 1492 | when "00" => 1493 | if( window = '1' ) then 1494 | if( dotCounter_x(0) = '0' ) then 1495 | G4colorCode <= fifoData_out(7 downto 4); 1496 | else 1497 | fifoAddr_out <= fifoAddr_out + 1; 1498 | G4colorCode <= fifoData_out(3 downto 0); 1499 | end if; 1500 | else 1501 | fifoAddr_out <= (others => '0'); 1502 | end if; 1503 | if( (preWindow = '1') and (VramReadFreeFlag = '0' ) and 1504 | (fifoFull = '0') ) then 1505 | fifoIn <= '1'; 1506 | end if; 1507 | when "01" => 1508 | if( preWindow = '0' ) then 1509 | fifoAddr_in <= (others => '0'); 1510 | elsif( fifoIn = '1' ) then 1511 | fifoIn <= '0'; 1512 | fifoAddr_in <= fifoAddr_in + 1; 1513 | end if; 1514 | when "11" => 1515 | null; 1516 | when others => null; 1517 | end case; 1518 | elsif( VdpModeGraphic7 = '1' ) then 1519 | -- graphic 7 state 1520 | case dotState is 1521 | when "10" => 1522 | null; 1523 | when "00" => 1524 | if( window = '1' ) then 1525 | fifoAddr_out <= fifoAddr_out + 1; 1526 | G7colorCode <= fifoData_out; 1527 | else 1528 | fifoAddr_out <= (others => '0'); 1529 | end if; 1530 | if( (preWindow = '1') and (VramReadFreeFlag = '0' ) and 1531 | (fifoFull = '0') ) then 1532 | fifoIn <= '1'; 1533 | end if; 1534 | when "01" => 1535 | if( preWindow = '0' ) then 1536 | fifoAddr_in <= (others => '0'); 1537 | elsif( fifoIn = '1' ) then 1538 | fifoIn <= '0'; 1539 | fifoAddr_in <= fifoAddr_in + 1; 1540 | end if; 1541 | when "11" => 1542 | null; 1543 | when others => null; 1544 | end case; 1545 | end if; 1546 | end if; 1547 | end process; 1548 | 1549 | -- sprite generator 1550 | spColorCode_3 <= 1551 | ((SpColorIn(0) and SpPattern(0)(16)) or 1552 | ( not SpPattern(0)(16) and 1553 | (SpColorIn(1) and SpPattern(1)(16)) ) or 1554 | ( not SpPattern(0)(16) and not SpPattern(1)(16) and 1555 | (SpColorIn(2) and SpPattern(2)(16)) ) or 1556 | ( not SpPattern(0)(16) and not SpPattern(1)(16) and not SpPattern(2)(16) and 1557 | (SpColorIn(3) and SpPattern(3)(16)) )) 1558 | when (SpMode2 = '0') else 1559 | (((SpColorIn(0) and SpPattern(0)(16) ) or 1560 | (SpColorIn(1) and SpPattern(1)(16) and SpCC(1) ) or 1561 | (SpColorIn(2) and SpPattern(2)(16) and SpCC(1) and SpCC(2) ) or 1562 | (SpColorIn(3) and SpPattern(3)(16) and SpCC(1) and SpCC(2) and SpCC(3) ) or 1563 | (SpColorIn(4) and SpPattern(4)(16) and SpCC(1) and SpCC(2) and SpCC(3) and SpCC(4) ) or 1564 | (SpColorIn(5) and SpPattern(5)(16) and SpCC(1) and SpCC(2) and SpCC(3) and SpCC(4) and SpCC(5) ) or 1565 | (SpColorIn(6) and SpPattern(6)(16) and SpCC(1) and SpCC(2) and SpCC(3) and SpCC(4) and SpCC(5) and SpCC(6) ) or 1566 | (SpColorIn(7) and SpPattern(7)(16) and SpCC(1) and SpCC(2) and SpCC(3) and SpCC(4) and SpCC(5) and SpCC(6) and SpCC(7) )) 1567 | or 1568 | (( not SpPattern(0)(16) and not SpCC(1) ) and 1569 | ((SpColorIn(1) and SpPattern(1)(16) ) or 1570 | (SpColorIn(2) and SpPattern(2)(16) and SpCC(2) ) or 1571 | (SpColorIn(3) and SpPattern(3)(16) and SpCC(2) and SpCC(3) ) or 1572 | (SpColorIn(4) and SpPattern(4)(16) and SpCC(2) and SpCC(3) and SpCC(4) ) or 1573 | (SpColorIn(5) and SpPattern(5)(16) and SpCC(2) and SpCC(3) and SpCC(4) and SpCC(5) ) or 1574 | (SpColorIn(6) and SpPattern(6)(16) and SpCC(2) and SpCC(3) and SpCC(4) and SpCC(5) and SpCC(6) ) or 1575 | (SpColorIn(7) and SpPattern(7)(16) and SpCC(2) and SpCC(3) and SpCC(4) and SpCC(5) and SpCC(6) and SpCC(7) ))) 1576 | or 1577 | (( not SpPattern(0)(16) and not SpPattern(1)(16) and not SpCC(2) ) and 1578 | ((SpColorIn(2) and SpPattern(2)(16) ) or 1579 | (SpColorIn(3) and SpPattern(3)(16) and SpCC(3) ) or 1580 | (SpColorIn(4) and SpPattern(4)(16) and SpCC(3) and SpCC(4) ) or 1581 | (SpColorIn(5) and SpPattern(5)(16) and SpCC(3) and SpCC(4) and SpCC(5) ) or 1582 | (SpColorIn(6) and SpPattern(6)(16) and SpCC(3) and SpCC(4) and SpCC(5) and SpCC(6) ) or 1583 | (SpColorIn(7) and SpPattern(7)(16) and SpCC(3) and SpCC(4) and SpCC(5) and SpCC(6) and SpCC(7) ))) 1584 | or 1585 | (( not SpPattern(0)(16) and not SpPattern(1)(16) and not SpPattern(2)(16) and not SpCC(3) ) and 1586 | ((SpColorIn(3) and SpPattern(3)(16) ) or 1587 | (SpColorIn(4) and SpPattern(4)(16) and SpCC(4) ) or 1588 | (SpColorIn(5) and SpPattern(5)(16) and SpCC(4) and SpCC(5) ) or 1589 | (SpColorIn(6) and SpPattern(6)(16) and SpCC(4) and SpCC(5) and SpCC(6) ) or 1590 | (SpColorIn(7) and SpPattern(7)(16) and SpCC(4) and SpCC(5) and SpCC(6) and SpCC(7) ))) 1591 | or 1592 | (( not SpPattern(0)(16) and not SpPattern(1)(16) and not SpPattern(2)(16) and 1593 | not SpPattern(3)(16) and not SpCC(4) ) and 1594 | ((SpColorIn(4) and SpPattern(4)(16) ) or 1595 | (SpColorIn(5) and SpPattern(5)(16) and SpCC(5) ) or 1596 | (SpColorIn(6) and SpPattern(6)(16) and SpCC(5) and SpCC(6) ) or 1597 | (SpColorIn(7) and SpPattern(7)(16) and SpCC(5) and SpCC(6) and SpCC(7) ))) 1598 | or 1599 | (( not SpPattern(0)(16) and not SpPattern(1)(16) and not SpPattern(2)(16) and 1600 | not SpPattern(3)(16) and not SpPattern(4)(16) and not SpCC(5) ) and 1601 | ((SpColorIn(5) and SpPattern(5)(16) ) or 1602 | (SpColorIn(6) and SpPattern(6)(16) and SpCC(6) ) or 1603 | (SpColorIn(7) and SpPattern(7)(16) and SpCC(6) and SpCC(7) ))) 1604 | or 1605 | (( not SpPattern(0)(16) and not SpPattern(1)(16) and not SpPattern(2)(16) and 1606 | not SpPattern(3)(16) and not SpPattern(4)(16) and not SpPattern(5)(16) and 1607 | not SpCC(6) ) and 1608 | ((SpColorIn(6) and SpPattern(6)(16) ) or 1609 | (SpColorIn(7) and SpPattern(7)(16) and SpCC(7) ))) 1610 | or 1611 | (( not SpPattern(0)(16) and not SpPattern(1)(16) and not SpPattern(2)(16) and 1612 | not SpPattern(3)(16) and not SpPattern(4)(16) and not SpPattern(5)(16) and 1613 | not SpPattern(6)(16) and not SpCC(7) ) and 1614 | ((SpColorIn(7) and SpPattern(7)(16) ))) ); 1615 | 1616 | process( clk21m, reset ) 1617 | begin 1618 | if (reset = '1') then 1619 | for i in 0 to SpMode2_nSprites -1 loop 1620 | SpPattern(i) <= (others => '0'); 1621 | SpColor(i) <= (others => '0'); 1622 | SpColorIn(i) <= '0'; 1623 | SpX(i) <= (others => '0'); 1624 | SpIC(i) <= '0'; 1625 | SpEC(i) <= '0'; 1626 | SpCC(i) <= '0'; 1627 | end loop; 1628 | SpReadIsContinuous <= '0'; 1629 | spColorIsTransparent <= '0'; 1630 | spColorCode <= (others => '0' ); 1631 | SpPreReadPtnNum <= (others => '0' ); 1632 | SpPreReadY <= (others => '0' ); 1633 | SpPreReadState <= spstate_idle; 1634 | SpPreReadCounter <= (others => '0' ); 1635 | SpPreReadCounter2 <= (others => '0' ); 1636 | SpY <= (others => '0'); 1637 | elsif (clk21m'event and clk21m = '1') then 1638 | case dotState is 1639 | when "10" => 1640 | for i in 0 to SpMode2_nSprites-1 loop 1641 | SpColorIn(i) <= SpColor(i)(2); 1642 | end loop; 1643 | spColorCode(1) <= spColorCode_3; 1644 | if( (preDotCounter_x_end = '1') and (spwindow_y = '1') ) then 1645 | SpPreReadState <= spstate_idle; 1646 | SpPreReadCounter <= (others => '0'); 1647 | SpPreReadCounter2 <= (others => '0'); 1648 | SpY <= dotCounter_y; 1649 | end if; 1650 | when "00" => 1651 | for i in 0 to SpMode2_nSprites-1 loop 1652 | SpColorIn(i) <= SpColor(i)(3); 1653 | end loop; 1654 | spColorCode(2) <= spColorCode_3; 1655 | when "01" => 1656 | for i in 0 to SpMode2_nSprites-1 loop 1657 | SpColorIn(i) <= SpColor(i)(0); 1658 | end loop; 1659 | if( SpPreReading = '1' ) then 1660 | -- JP: 水平帰線期間にそのラインで表示するスプライトの情報を集める 1661 | -- JP: スプライトアトリビュートテーブルの構造 1662 | -- Sprite Attribute Table 1663 | -- 7 6 5 4 3 2 1 0 1664 | -- +0 : | Y | 1665 | -- +1 : | X | 1666 | -- +2 : | Pattern Num | 1667 | -- +3 : |EC0 0 0| Color | 1668 | -- 1669 | case SpPreReadState is 1670 | when spstate_yread => 1671 | SpPreReadY <= SpY - pRamDat; 1672 | if( (SpMode2 = '0' and pRamDat = "11010000" ) or -- Y = 208 1673 | (SpMode2 = '1' and pRamDat = "11011000" ) ) then -- Y = 216 1674 | -- JP: Y座標が 208(SpMode1) or 216(SpMode2)の時, 1675 | -- JP: 以降のスプライトを OFF 1676 | SpDispEnd <= '1'; 1677 | end if; 1678 | when spstate_xread => 1679 | SpX(conv_integer(SpPreReadCounter2)) <= '0' & pRamDat; 1680 | when spstate_ptnnumread => 1681 | SpPreReadPtnNum <= pRamDat; 1682 | when spstate_colorread => 1683 | SpColor(conv_integer(SpPreReadCounter2)) <= pRamDat( 3 downto 0); 1684 | SpEC(conv_integer(SpPreReadCounter2)) <= pRamDat(7); 1685 | SpCC(conv_integer(SpPreReadCounter2)) <= pRamDat(6); 1686 | SpIC(conv_integer(SpPreReadCounter2)) <= pRamDat(5); 1687 | if( (pRamDat(3 downto 0) = "0000") or 1688 | (pRamDat(6) = '1' and SpReadIsContinuous = '0') ) then 1689 | -- JP: 透明色は表示されない. 1690 | -- JP: CCが 1の時,直前のスプライトプレーンが同一ラインに無い時は 1691 | -- JP: 表示されない. 1692 | spColorIsTransparent <= '1'; 1693 | else 1694 | spColorIsTransparent <= '0'; 1695 | end if; 1696 | when spstate_ptnread1 => 1697 | if( spColorIsTransparent = '1' ) then 1698 | SpPattern(conv_integer(SpPreReadCounter2))(16 downto 8) <= (others => '0'); 1699 | else 1700 | SpPattern(conv_integer(SpPreReadCounter2))(16 downto 8) <= '0' & pRamDat; 1701 | end if; 1702 | when spstate_ptnread2 => 1703 | if( spColorIsTransparent = '1' ) then 1704 | SpPattern(conv_integer(SpPreReadCounter2))(7 downto 0) <= (others => '0'); 1705 | elsif( VdpR1SpSize = '0' ) then 1706 | -- 8x8 mode 1707 | SpPattern(conv_integer(SpPreReadCounter2))(7 downto 0) <= (others => '0'); 1708 | else 1709 | -- 16x16 mode 1710 | SpPattern(conv_integer(SpPreReadCounter2))(7 downto 0) <= pRamDat; 1711 | end if; 1712 | when others => 1713 | null; 1714 | end case; 1715 | else 1716 | for i in 0 to SpMode2_nSprites - 1 loop 1717 | if( (SpX(i)(8) = '1') and 1718 | ( (VdpR1SpZoom='0') or ((VdpR1SpZoom='1')and(SpX(i)(0)='0')) ) ) then 1719 | SpPattern(i) <= SpPattern(i)(15 downto 0) & '0'; 1720 | end if; 1721 | if( spwindow = '1' ) then 1722 | SpX(i) <= SpX(i) - 1; 1723 | elsif( spwindow_ec = '1' ) then 1724 | if( SpEC(i)='1' ) then 1725 | SpX(i) <= SpX(i) - 1; 1726 | end if; 1727 | end if; 1728 | end loop; 1729 | end if; 1730 | when "11" => 1731 | for i in 0 to SpMode2_nSprites - 1 loop 1732 | SpColorIn(i) <= SpColor(i)(1); 1733 | end loop; 1734 | spColorCode(0) <= spColorCode_3; 1735 | 1736 | if( SpDispEnd = '1' ) then 1737 | -- JP: Y座標が 208の時,以降のスプライトを OFF 1738 | SpPreReadState <= spstate_idle; 1739 | SpDispEnd <= '0'; 1740 | elsif( (SpPreReadState = spstate_idle) and (SpPreReadCounter = "00000") ) then 1741 | SpPreReadState <= spstate_yread; 1742 | SpReadIsContinuous <= '0'; 1743 | for i in 0 to SpMode2_nSprites - 1 loop 1744 | SpPattern(i) <= (others =>'0'); 1745 | end loop; 1746 | elsif( SpPreReading = '1' ) then 1747 | case SpPreReadState is 1748 | when spstate_yread => 1749 | if( (SpPreReadY( 7 downto 3) = "00000") and (VdpR1SpSize = '0' ) and (VdpR1SpZoom='0') )then 1750 | SpPreReadState <= spstate_xread; 1751 | elsif( (SpPreReadY( 7 downto 4) = "0000") and (VdpR1SpSize = '1' ) and (VdpR1SpZoom='0') )then 1752 | SpPreReadState <= spstate_xread; 1753 | elsif( (SpPreReadY( 7 downto 4) = "0000") and (VdpR1SpSize = '0' ) and (VdpR1SpZoom='1') )then 1754 | SpPreReadState <= spstate_xread; 1755 | SpPreReadY <= '0' & SpPreReadY(7 downto 1); 1756 | elsif( (SpPreReadY( 7 downto 5) = "000") and (VdpR1SpSize = '1' ) and (VdpR1SpZoom='1') )then 1757 | SpPreReadState <= spstate_xread; 1758 | SpPreReadY <= '0' & SpPreReadY(7 downto 1); 1759 | elsif( SpPreReadCounter = "11111" ) then 1760 | SpPreReadState <= spstate_idle; 1761 | else 1762 | SpPreReadState <= spstate_yread; 1763 | SpPreReadCounter <= SpPreReadCounter + 1; 1764 | -- JP: 連続したスプライトプレーンが表示されない時、SpReadIsContinuous をクリア 1765 | SpReadIsContinuous <= '0'; 1766 | end if; 1767 | when spstate_xread => 1768 | SpPreReadState <= spstate_ptnnumread; 1769 | when spstate_ptnnumread => 1770 | SpPreReadState <= spstate_colorread; 1771 | when spstate_colorread => 1772 | SpPreReadState <= spstate_ptnread1; 1773 | when spstate_ptnread1 => 1774 | SpPreReadState <= spstate_ptnread2; 1775 | when spstate_ptnread2 => 1776 | if( (SpMode2='0') and (SpPreReadCounter2 = SpMode1_nSprites-1) ) then 1777 | -- JP: 横4つ分のスプライトを読んだ 1778 | SpPreReadState <= spstate_idle; 1779 | elsif( (SpMode2='1') and (SpPreReadCounter2 = SpMode2_nSprites-1) ) then 1780 | -- JP: 横8つ分のスプライトを読んだ 1781 | SpPreReadState <= spstate_idle; 1782 | elsif( SpPreReadCounter = "11111" ) then 1783 | -- JP: 32枚のスプライトプレーンの調査終了 1784 | SpPreReadState <= spstate_idle; 1785 | else 1786 | SpPreReadCounter <= SpPreReadCounter + 1; 1787 | SpPreReadCounter2 <= SpPreReadCounter2 + 1; 1788 | -- JP: SpReadIsContinueをセット 1789 | SpReadIsContinuous <= '1'; 1790 | SpPreReadState <= spstate_yread; 1791 | end if; 1792 | when others => 1793 | null; 1794 | end case; 1795 | end if; 1796 | when others => 1797 | null; 1798 | end case; 1799 | 1800 | end if; 1801 | end process; 1802 | 1803 | 1804 | -- VDP register access 1805 | process( clk21m, reset ) 1806 | begin 1807 | if (reset = '1') then 1808 | dbi <= (others => '0'); 1809 | vsyncIntAck <= '0'; 1810 | -- dVsyncIntReq <= '0'; 1811 | VdpP1Data <= (others => '0'); 1812 | VdpP1Is1stByte <= '1'; 1813 | VdpP2Is1stByte <= '1'; 1814 | VdpRegWrPulse <= '0'; 1815 | VdpRegPtr <= (others => '0'); 1816 | VdpVramWrReq <= '0'; 1817 | VdpVramRdReq <= '0'; 1818 | VdpVramAddrSetReq <= '0'; 1819 | VdpVramAccessRw <= '0'; 1820 | VdpVramAccessAddrTmp <= (others => '0'); 1821 | VdpVramAccessData <= (others => '0'); 1822 | VdpR0DispNum <= (others => '0'); 1823 | VdpR0HSyncIntEn <= '0'; 1824 | VdpR1DispMode <= (others => '0'); 1825 | VdpR1SpSize <= '0'; 1826 | VdpR1SpZoom <= '0'; 1827 | VdpR1VSyncIntEn <= '0'; 1828 | VdpR1DispOn <= '0'; 1829 | VdpR2PtnNameTblBaseAddr <= (others => '0'); 1830 | VdpR4PtnGeneTblBaseAddr <= (others => '0'); 1831 | VdpR10R3ColorTblBaseAddr <= (others => '0'); 1832 | VdpR11R5SpAttrTblBaseAddr <= (others => '0'); 1833 | VdpR6SpPtnGeneTblBaseAddr <= (others => '0'); 1834 | VdpR7FrameColor <= (others => '0'); 1835 | VdpR8SpOff <= '0'; 1836 | VdpR8Color0On <= '0'; 1837 | VdpR9TwoPageMode <= '0'; 1838 | VdpR9InterlaceMode <= '0'; 1839 | VdpR9YDots <= '0'; 1840 | VdpR15StatusRegNum <= (others => '0'); 1841 | VdpR16PalNum <= (others => '0'); 1842 | VdpR17RegNum <= (others => '0'); 1843 | VdpR17IncRegNum <= '0'; 1844 | VdpR18Adjust <= (others => '0'); 1845 | VdpR19HSyncIntLine <= (others => '0'); 1846 | VdpR23VStartLine <= (others => '0'); 1847 | 1848 | VdpCmdRegNum <= (others => '0'); 1849 | VdpCmdRegData <= (others => '0'); 1850 | VdpCmdRegWrReq <= '0'; 1851 | VdpCmdTRClrReq <= '0'; 1852 | 1853 | -- palette 1854 | paletteWrTemp <= (others => '0'); 1855 | paletteWrReqRB <= '0'; 1856 | paletteWrReqG <= '0'; 1857 | paletteWrNum <= (others => '0'); 1858 | 1859 | elsif (clk21m'event and clk21m = '1') then 1860 | 1861 | if (req = '1' and wrt = '0') then 1862 | case adr(1 downto 0) is 1863 | when "00" => -- port#0 read 1864 | dbi <= VdpVramRdData; 1865 | VdpVramRdReq <= not VdpVramRdAck; 1866 | when "01" => -- port#1 read 1867 | -- read status registers 1868 | 1869 | -- JP: ステータスレジスタを読む時に 1stバイトフラグをリセットしてみる. 1870 | -- JP: 実機の挙動と合うかどうか不明. 1871 | VdpP1Is1stByte <= '1'; 1872 | VdpP2Is1stByte <= '1'; 1873 | 1874 | case VdpR15StatusRegNum is 1875 | when "0000" => 1876 | -- JP: 未実装あり 1877 | if( vsyncIntAck /= vsyncIntReq ) then 1878 | vsyncIntAck <= not vsyncIntAck; 1879 | dbi <= '1' & "0000000"; 1880 | else 1881 | dbi <= '0' & "0000000"; 1882 | end if; 1883 | when "0001" => 1884 | -- JP: 未実装あり 1885 | if( hsyncIntAck /= hsyncIntReq ) then 1886 | hsyncIntAck <= not hsyncIntAck; 1887 | dbi <= "00" & VDP_ID & '1'; 1888 | else 1889 | dbi <= "00" & VDP_ID & '0'; 1890 | end if; 1891 | when "0010" => 1892 | -- dbi <= '1' & not iVideoVS_n & not iVideoHS_n & '0' & "11" & field & '0'; 1893 | -- dbi <= '1' & not bwindow_y & not bwindow_x & '0' & "11" & field & '0'; 1894 | dbi <= VdpCmdTR & not bwindow_y & not bwindow_x & '0' & "11" & field & VdpCmdCE; 1895 | when "0111" => 1896 | -- LMCM command read 1897 | dbi <= VdpS7ReadData; 1898 | VdpCmdTRClrReq <= not VdpCmdTRClrAck; 1899 | when others => 1900 | dbi <= (others => '0'); 1901 | end case; 1902 | when "10" => -- port#2 read 1903 | dbi <= (others => '1'); 1904 | when others => -- port#3 read 1905 | dbi <= (others => '1'); 1906 | end case; 1907 | 1908 | elsif (req = '1' and wrt = '1') then 1909 | case adr(1 downto 0) is 1910 | when "00" => -- port#0 write 1911 | VdpVramAccessData <= dbo; 1912 | VdpVramWrReq <= not VdpVramWrAck; 1913 | when "01" => -- port#1 write 1914 | if(VdpP1Is1stByte = '1') then 1915 | VdpP1Is1stByte <= '0'; 1916 | VdpP1Data <= dbo; 1917 | else 1918 | VdpP1Is1stByte <= '1'; 1919 | case dbo( 7 downto 6 ) is 1920 | when "01" => -- set vram access address(write) 1921 | VdpVramAccessAddrTmp( 7 downto 0 ) <= VdpP1Data( 7 downto 0); 1922 | VdpVramAccessAddrTmp(13 downto 8 ) <= dbo( 5 downto 0); 1923 | VdpVramAddrSetReq <= not VdpVramAddrSetAck; 1924 | VdpVramAccessRw <= '0'; 1925 | when "00" => -- set vram access address(read) 1926 | VdpVramAccessAddrTmp( 7 downto 0 ) <= VdpP1Data( 7 downto 0); 1927 | VdpVramAccessAddrTmp(13 downto 8 ) <= dbo( 5 downto 0); 1928 | VdpVramAddrSetReq <= not VdpVramAddrSetAck; 1929 | VdpVramAccessRw <= '1'; 1930 | VdpVramRdReq <= not VdpVramRdAck; 1931 | when "10" => -- JP: 直接レジスタ指定アクセス 1932 | VdpRegPtr <= dbo( 5 downto 0); 1933 | VdpRegWrPulse <= '1'; 1934 | when "11" => -- JP: 直接レジスタ指定アクセス? 1935 | VdpRegPtr <= dbo( 5 downto 0); 1936 | VdpRegWrPulse <= '1'; 1937 | when others => 1938 | null; 1939 | end case; 1940 | end if; 1941 | 1942 | when "10" => -- port#2 write 1943 | if(VdpP2Is1stByte = '1') then 1944 | paletteWrTemp <= dbo; 1945 | paletteWrNum <= VdpR16PalNum; 1946 | paletteWrReqRB <= not paletteWrAckRB; 1947 | VdpP2Is1stByte <= '0'; 1948 | else 1949 | paletteWrTemp <= dbo; 1950 | paletteWrNum <= VdpR16PalNum; 1951 | paletteWrReqG <= not paletteWrAckG; 1952 | VdpP2Is1stByte <= '1'; 1953 | VdpR16PalNum <= VdpR16PalNum + 1; 1954 | end if; 1955 | 1956 | when "11" => -- port#3 write 1957 | -- JP: 間接指定では R#17の値は書き換えられない 1958 | if( VdpR17RegNum /= "010001" ) then 1959 | VdpRegWrPulse <= '1'; 1960 | end if; 1961 | VdpP1Data <= dbo; 1962 | VdpRegPtr <= VdpR17RegNum; 1963 | if( VdpR17IncRegNum = '1' ) then 1964 | VdpR17RegNum <= VdpR17RegNum + 1; 1965 | end if; 1966 | 1967 | when others => 1968 | null; 1969 | end case; 1970 | 1971 | elsif (VdpRegWrPulse = '1') then -- register write 1972 | VdpRegWrPulse <= '0'; 1973 | 1974 | if ( VdpRegPtr(5) = '0') then 1975 | case VdpRegPtr(4 downto 0) is 1976 | when "00000" => -- #00 1977 | VdpR0DispNum <= VdpP1Data(3 downto 1); 1978 | VdpR0HSyncIntEn <= VdpP1Data(4); 1979 | when "00001" => -- #01 1980 | VdpR1SpZoom <= VdpP1Data(0); 1981 | VdpR1SpSize <= VdpP1Data(1); 1982 | VdpR1DispMode <= VdpP1Data(4 downto 3); 1983 | VdpR1VSyncIntEn <= VdpP1Data(5); 1984 | VdpR1DispOn <= VdpP1Data(6); 1985 | when "00010" => -- #02 1986 | VdpR2PtnNameTblBaseAddr <= VdpP1Data( 6 downto 0); 1987 | when "00011" => -- #03 1988 | VdpR10R3ColorTblBaseAddr(7 downto 0) <= VdpP1Data( 7 downto 0); 1989 | when "00100" => -- #04 1990 | VdpR4PtnGeneTblBaseAddr <= VdpP1Data( 5 downto 0); 1991 | when "00101" => -- #05 1992 | VdpR11R5SpAttrTblBaseAddr(7 downto 0) <= VdpP1Data; 1993 | when "00110" => -- #06 1994 | VdpR6SpPtnGeneTblBaseAddr <= VdpP1Data( 5 downto 0); 1995 | when "00111" => -- #07 1996 | VdpR7FrameColor <= VdpP1Data( 7 downto 0 ); 1997 | when "01000" => -- #08 1998 | VdpR8SpOff <= VdpP1Data(1); 1999 | VdpR8Color0On <= VdpP1Data(5); 2000 | when "01001" => -- #09 2001 | VdpR9TwoPageMode <= VdpP1Data(2); 2002 | VdpR9InterlaceMode <= VdpP1Data(3); 2003 | VdpR9YDots <= VdpP1Data(7); 2004 | when "01010" => -- #10 2005 | VdpR10R3ColorTblBaseAddr(10 downto 8) <= VdpP1Data( 2 downto 0); 2006 | when "01011" => -- #11 2007 | VdpR11R5SpAttrTblBaseAddr( 9 downto 8) <= VdpP1Data( 1 downto 0); 2008 | when "01110" => -- #14 2009 | VdpVramAccessAddrTmp( 16 downto 14 ) <= VdpP1Data( 2 downto 0); 2010 | VdpVramAddrSetReq <= not VdpVramAddrSetAck; 2011 | when "01111" => -- #15 2012 | VdpR15StatusRegNum <= VdpP1Data( 3 downto 0); 2013 | when "10000" => -- #16 2014 | VdpR16PalNum <= VdpP1Data( 3 downto 0 ); 2015 | when "10001" => -- #17 2016 | VdpR17RegNum <= VdpP1Data( 5 downto 0 ); 2017 | VdpR17IncRegNum <= not VdpP1Data(7); 2018 | when "10010" => -- #18 2019 | VdpR18Adjust <= VdpP1Data; 2020 | when "10011" => -- #19 2021 | VdpR19HSyncIntLine <= VdpP1Data; 2022 | when "10111" => -- #23 2023 | VdpR23VStartLine <= VdpP1Data; 2024 | when others => null; 2025 | end case; 2026 | else 2027 | -- Registers for VDP Command 2028 | VdpCmdRegNum <= VdpRegPtr(3 downto 0); 2029 | VdpCmdRegData <= VdpP1Data; 2030 | VdpCmdRegWrReq <= not VdpCmdRegWrAck; 2031 | end if; 2032 | end if; 2033 | 2034 | end if; 2035 | end process; 2036 | 2037 | -- Display resolution (0=15kHz, 1=31kHz) 2038 | dispModeVGA <= DispReso; 2039 | 2040 | ----------------------------------------------------------------------------- 2041 | -- 2042 | -- VDP Command 2043 | -- 2044 | ----------------------------------------------------------------------------- 2045 | 2046 | process( clk21m, reset ) 2047 | variable nxCount : std_logic_vector(8 downto 0); 2048 | variable xCountUp : integer; 2049 | variable nxLoopEnd : std_logic; 2050 | variable x : std_logic_vector(8 downto 0); 2051 | variable logOpDestCol : std_logic_vector(7 downto 0); 2052 | variable logOpSoucCol : std_logic_vector(7 downto 0); 2053 | begin 2054 | if (reset = '1') then 2055 | nxCount := (others => '0'); 2056 | nxLoopEnd := '0'; 2057 | x := (others => '0'); 2058 | xCountUp := 0; 2059 | VdpCmdState <= stVdpCmdIdle; 2060 | VdpCmdSX <= (others => '0'); -- R32 2061 | VdpCmdSY <= (others => '0'); -- R34 2062 | VdpCmdDX <= (others => '0'); -- R36 2063 | VdpCmdDY <= (others => '0'); -- R38 2064 | VdpCmdNX <= (others => '0'); -- R40 2065 | VdpCmdNY <= (others => '0'); -- R42 2066 | VdpCmdCLR <= (others => '0'); -- R44 2067 | VdpCmdDIX <= '0'; -- R45 bit 2 2068 | VdpCmdDIY <= '0'; -- R45 bit 3 2069 | VdpCmdMXS <= '0'; -- R45 bit 4 2070 | VdpCmdMXD <= '0'; -- R45 bit 5 2071 | VdpCmdCMR <= (others => '0'); -- R46 2072 | VdpCmdSXTmp <= (others => '0'); 2073 | VdpCmdDXTmp <= (others => '0'); 2074 | VdpCmdCLRWr <= '0'; 2075 | VdpCmdCMRWr <= '0'; 2076 | VdpCmdRegWrAck <= '0'; 2077 | VdpCmdVramWrReq <= '0'; 2078 | VdpCmdVramRdReq <= '0'; 2079 | VdpCmdVramWrData <= (others => '0'); 2080 | 2081 | VdpCmdTR <= '1'; -- Transfer Ready 2082 | VdpCmdCE <= '0'; -- Command Executing 2083 | VdpCmdTRClrAck <= '0'; 2084 | 2085 | VdpS7ReadData <= (others => '0'); 2086 | elsif (clk21m'event and clk21m = '1') then 2087 | 2088 | case VdpCmdCMR(7 downto 4) is 2089 | -- JP: HMMC,HMMM,HMMVの横方向転送回数計算 2090 | when VdpCmdHMMC | VdpCmdHMMM | VdpCmdHMMV => 2091 | if( (VdpModeGraphic4 = '1') or 2092 | (VdpModeGraphic6 = '1') ) then 2093 | -- GRAPHIC4,6 2094 | nxCount := '0' & VdpCmdNX(8 downto 1); 2095 | xCountUp := 2; 2096 | elsif( VdpModeGraphic5 = '1' ) then 2097 | -- GRAPHIC5 2098 | nxCount := "00" & VdpCmdNX(8 downto 2); 2099 | xCountUp := 4; 2100 | else 2101 | -- GRAPHIC7 and other 2102 | nxCount := VdpCmdNX; 2103 | xCountUp := 1; 2104 | end if; 2105 | -- JP: LMMC,LMCM,LMMM,LMMVの横方向転送回数計算 2106 | when VdpCmdLMMC | VdpCmdLMCM | VdpCmdLMMM | VdpCmdLMMV => 2107 | nxCount := VdpCmdNX; 2108 | xCountUp := 1; 2109 | when others => 2110 | nxCount := "000000001"; 2111 | end case; 2112 | 2113 | -- JP: 横方向ループ判定 2114 | case VdpCmdCMR(7 downto 4) is 2115 | when VdpCmdHMMC | VdpCmdHMMM | VdpCmdHMMV 2116 | | VdpCmdLMMC | VdpCmdLMMM | VdpCmdLMMV 2117 | | VdpCmdLMCM => 2118 | if( VdpCmdNXTmp = 0 ) then 2119 | nxLoopEnd := '1'; 2120 | else 2121 | nxLoopEnd := '0'; 2122 | end if; 2123 | when VdpCmdYMMM => 2124 | -- JP: DIX=0の時 2125 | -- JP: VdpCmdDxTmpが256か257になったらループ 2126 | -- JP: DIX=1の時 2127 | -- JP: VdpCmdDxTmp+2が0か1になったらループ 2128 | x := VdpCmdDXTmp+("0000000"&VdpCmdDIX&'0'); -- GRAPHIC 4 2129 | if( x(7 downto 0) = 0 ) then 2130 | nxLoopEnd := '1'; 2131 | else 2132 | nxLoopEnd := '0'; 2133 | end if; 2134 | when others => 2135 | nxLoopEnd := '1'; 2136 | end case; 2137 | 2138 | -- JP: ロジカルオペレーションの実行 2139 | -- JP: PreRdVramステートのみで有効 2140 | -- GRAPHI4 2141 | logOpSoucCol := "0000" & VdpCmdVramWrData(3 downto 0); 2142 | if( VdpCmdDxTmp(0) = '0' ) then 2143 | -- JP: 転送先が偶数ドット 2144 | logOpDestCol := "0000" & VdpCmdVramRdData(7 downto 4); 2145 | else 2146 | logOpDestCol := "0000" & VdpCmdVramRdData(3 downto 0); 2147 | end if; 2148 | case VdpCmdCMR(3 downto 0) is 2149 | when VdpCmdIMP => 2150 | logOpDestCol := logOpSoucCol; 2151 | when VdpCmdAND => 2152 | logOpDestCol := logOpSoucCol and logOpDestCol; 2153 | when VdpCmdOR => 2154 | logOpDestCol := logOpSoucCol or logOpDestCol; 2155 | when VdpCmdEOR => 2156 | logOpDestCol := logOpSoucCol xor logOpDestCol; 2157 | when VdpCmdNOT => 2158 | logOpDestCol := not logOpSoucCol; 2159 | when VdpCmdTIMP => 2160 | if( logOpSoucCol /= 0 ) then 2161 | logOpDestCol := logOpSoucCol; 2162 | end if; 2163 | when VdpCmdTAND => 2164 | if( logOpSoucCol /= 0 ) then 2165 | logOpDestCol := logOpSoucCol and logOpDestCol; 2166 | end if; 2167 | when VdpCmdTOR => 2168 | if( logOpSoucCol /= 0 ) then 2169 | logOpDestCol := logOpSoucCol or logOpDestCol; 2170 | end if; 2171 | when VdpCmdTEOR => 2172 | if( logOpSoucCol /= 0 ) then 2173 | logOpDestCol := logOpSoucCol xor logOpDestCol; 2174 | end if; 2175 | when VdpCmdTNOT => 2176 | if( logOpSoucCol /= 0 ) then 2177 | logOpDestCol := not logOpSoucCol; 2178 | end if; 2179 | when others => null; 2180 | end case; 2181 | 2182 | -- process 2183 | if( VdpCmdRegWrReq /= VdpCmdRegWrAck ) then 2184 | VdpCmdRegWrAck <= not VdpCmdRegWrAck; 2185 | case VdpCmdRegNum is 2186 | when "0000" => -- #32 2187 | VdpCmdSX(7 downto 0) <= VdpCmdRegData; 2188 | when "0001" => -- #33 2189 | VdpCmdSX(8) <= VdpCmdRegData(0); 2190 | when "0010" => -- #34 2191 | VdpCmdSY(7 downto 0) <= VdpCmdRegData; 2192 | when "0011" => -- #35 2193 | VdpCmdSY(9 downto 8) <= VdpCmdRegData(1 downto 0); 2194 | when "0100" => -- #36 2195 | VdpCmdDX(7 downto 0) <= VdpCmdRegData; 2196 | when "0101" => -- #37 2197 | VdpCmdDX(8) <= VdpCmdRegData(0); 2198 | when "0110" => -- #38 2199 | VdpCmdDY(7 downto 0) <= VdpCmdRegData; 2200 | when "0111" => -- #39 2201 | VdpCmdDY(9 downto 8) <= VdpCmdRegData(1 downto 0); 2202 | when "1000" => -- #40 2203 | VdpCmdNX(7 downto 0) <= VdpCmdRegData; 2204 | when "1001" => -- #41 2205 | VdpCmdNX(8) <= VdpCmdRegData(0); 2206 | when "1010" => -- #42 2207 | VdpCmdNY(7 downto 0) <= VdpCmdRegData; 2208 | when "1011" => -- #43 2209 | VdpCmdNY(9 downto 8) <= VdpCmdRegData(1 downto 0); 2210 | when "1100" => -- #44 2211 | VdpCmdCLR <= VdpCmdRegData; 2212 | VdpCmdCLRWr <= '1'; 2213 | when "1101" => -- #45 2214 | VdpCmdDIX <= VdpCmdRegData(2); 2215 | VdpCmdDIY <= VdpCmdRegData(3); 2216 | VdpCmdMXD <= VdpCmdRegData(5); 2217 | when "1110" => -- #46 2218 | -- JP: コマンド実行中は書き込まない 2219 | if( VdpCmdState = stVdpCmdIdle ) then 2220 | VdpCmdCMR <= VdpCmdRegData; 2221 | VdpCmdCMRWr <= '1'; 2222 | elsif( VdpCmdRegData = "0000" ) then 2223 | -- stop command (force break command execution) 2224 | VdpCmdState <= stVdpCmdIdle; 2225 | VdpCmdCMR <= VdpCmdRegData; 2226 | end if; 2227 | when others => 2228 | null; 2229 | end case; 2230 | elsif( VdpCmdTRClrReq /= VdpCmdTRClrAck ) then 2231 | -- JP: LMCMコマンドで必要 2232 | -- JP: 他のTRビットを使うコマンドとの兼ね合いは大丈夫か? 2233 | VdpCmdTRClrAck <= not VdpCmdTRClrAck; 2234 | VdpCmdTR <= '0'; 2235 | else 2236 | case VdpCmdState is 2237 | when stVdpCmdIdle => 2238 | if( VdpCmdCMRWr = '0' ) then 2239 | -- VdpCmdTR <= '1'; 2240 | VdpCmdCE <= '0'; 2241 | VdpCmdCE <= '0'; 2242 | else 2243 | -- exec VDP Command 2244 | VdpCmdCMRWr <= '0'; 2245 | -- 2246 | -- VdpCmdTR <= '0'; 2247 | VdpCmdCE <= '1'; 2248 | if( VdpCmdCMR(7 downto 4) = VdpCmdYMMM ) then 2249 | VdpCmdSXTmp <= VdpCmdDX; 2250 | else 2251 | VdpCmdSXTmp <= VdpCmdSX; 2252 | end if; 2253 | VdpCmdDXTmp <= VdpCmdDX; 2254 | VdpCmdNXTmp <= nxCount; 2255 | case VdpCmdCMR(7 downto 4) is 2256 | when VdpCmdHMMC => 2257 | VdpCmdCLRWr <= '1'; -- JP:最初の色は設定済み 2258 | VdpCmdState <= stVdpCmdRdCPU; 2259 | when VdpCmdYMMM => 2260 | VdpCmdState <= stVdpCmdRdVram; 2261 | when VdpCmdHMMM => 2262 | VdpCmdState <= stVdpCmdRdVram; 2263 | when VdpCmdHMMV => 2264 | VdpCmdVramWrData <= VdpCmdCLR; -- JP:塗りつぶす色 2265 | VdpCmdState <= stVdpCmdWrVram; 2266 | when VdpCmdLMMC => 2267 | VdpCmdCLRWr <= '1'; -- JP:最初の色は設定済み 2268 | VdpCmdState <= stVdpCmdRdCPU; 2269 | when VdpCmdLMCM => 2270 | VdpCmdState <= stVdpCmdWaitCPU; 2271 | when VdpCmdLMMM => 2272 | VdpCmdState <= stVdpCmdRdVram; 2273 | when VdpCmdLMMV => 2274 | VdpCmdVramWrData <= VdpCmdCLR; -- JP:塗りつぶす色 2275 | VdpCmdState <= stVdpCmdPreRdVram; 2276 | when others => 2277 | VdpCmdState <= stVdpCmdExecEnd; 2278 | end case; 2279 | end if; 2280 | when stVdpCmdRdCPU => 2281 | VdpCmdTR <= '1'; -- JP: ここで 1を立てるのは遅い? 2282 | if( VdpCmdCLRWr = '1' ) then 2283 | VdpCmdCLRWr <= '0'; 2284 | VdpCmdTR <= '0'; 2285 | VdpCmdVramWrData <= VdpCmdCLR; 2286 | -- check logical command 2287 | case VdpCmdCMR(7 downto 4) is 2288 | when VdpCmdLMMC => 2289 | VdpCmdState <= stVdpCmdPreRdVram; 2290 | when others => 2291 | VdpCmdState <= stVdpCmdWrVram; 2292 | end case; 2293 | end if; 2294 | 2295 | -- JP: LMCMコマンドのCPUのリード待ち 2296 | -- JP: LMCMは最後のドットを処理すると TR=1の状態で CE=0となり 2297 | -- JP: LMCMコマンドの実行は終了する 2298 | -- JP: なので、TR=0になっているかどうかのチェックはVRAMリードの 2299 | -- JP: 直前に行う 2300 | when stVdpCmdWaitCPU => 2301 | if( VdpCmdTR = '0' ) then 2302 | VdpCmdVramWrData <= VdpCmdCLR; 2303 | VdpCmdState <= stVdpCmdRdVram; 2304 | end if; 2305 | 2306 | when stVdpCmdRdVram => 2307 | -- GRAPHIC4(SCREEN5) 2308 | VdpCmdVramAccessAddr <= VdpCmdSY & VdpCmdSxTmp(7 downto 1); 2309 | VdpCmdVramRdReq <= not VdpCmdVramRdAck; 2310 | -- VdpCmdVramRdReq <= VdpCmdVramRdAck; 2311 | VdpCmdState <= stVdpCmdWaitRdVram; 2312 | when stVdpCmdWaitRdVram => 2313 | if ( VdpCmdVramRdReq = VdpCmdVramRdAck ) then 2314 | -- 読み込み完了 2315 | if( VdpCmdDIX = '0' ) then 2316 | VdpCmdSxTmp <= VdpCmdSxTmp + xCountUp; 2317 | else 2318 | VdpCmdSxTmp <= VdpCmdSxTmp - xCountUp; 2319 | end if; 2320 | -- check logical command 2321 | case VdpCmdCMR(7 downto 4) is 2322 | when VdpCmdLMMM => 2323 | if( VdpCmdSxTmp(0) = '0' ) then 2324 | -- GRAPHIC4 2325 | VdpCmdVramWrData(3 downto 0) <= VdpCmdVramRdData(7 downto 4); 2326 | else 2327 | -- GRAPHIC4 2328 | VdpCmdVramWrData(3 downto 0) <= VdpCmdVramRdData(3 downto 0); 2329 | end if; 2330 | VdpCmdState <= stVdpCmdPreRdVram; 2331 | when VdpCmdLMCM => 2332 | if( VdpCmdSxTmp(0) = '0' ) then 2333 | -- GRAPHIC4 2334 | -- JP: 偶数座標 2335 | VdpS7ReadData <= "0000" & VdpCmdVramRdData(7 downto 4); 2336 | else 2337 | -- GRAPHIC4 2338 | VdpS7ReadData <= "0000" & VdpCmdVramRdData(3 downto 0); 2339 | end if; 2340 | VdpCmdTR <= '1'; 2341 | VdpCmdState <= stVdpCmdChkLoop; 2342 | when others => 2343 | VdpCmdVramWrData <= VdpCmdVramRdData; 2344 | VdpCmdState <= stVdpCmdWrVram; 2345 | end case; 2346 | end if; 2347 | 2348 | -- JP: ロジカルオペレーションのための転送先VRAM読みだし 2349 | when stVdpCmdPreRdVram => 2350 | -- GRAPHIC4(SCREEN5) 2351 | VdpCmdVramAccessAddr <= VdpCmdDY & VdpCmdDxTmp(7 downto 1); 2352 | VdpCmdVramRdReq <= not VdpCmdVramRdAck; 2353 | VdpCmdState <= stVdpCmdWaitPreRdVram; 2354 | when stVdpCmdWaitPreRdVram => 2355 | if ( VdpCmdVramRdReq = VdpCmdVramRdAck ) then 2356 | -- 読み込み完了 2357 | if( VdpCmdDxTmp(0) = '0' ) then 2358 | -- JP: 偶数座標 2359 | VdpCmdVramWrData <= logOpDestCol(3 downto 0) & 2360 | VdpCmdVramRdData(3 downto 0); -- GRAPHIC4 2361 | else 2362 | -- JP: 奇数座標 2363 | VdpCmdVramWrData <= VdpCmdVramRdData(7 downto 4) & 2364 | logOpDestCol(3 downto 0); -- GRAPHIC4 2365 | end if; 2366 | VdpCmdState <= stVdpCmdWrVram; 2367 | end if; 2368 | 2369 | -- JP: 書き込み系 2370 | when stVdpCmdWrVram => 2371 | VdpCmdVramAccessAddr <= VdpCmdDY & VdpCmdDxTmp(7 downto 1); -- GRAPHIC4 2372 | VdpCmdVramWrReq <= not VdpCmdVramWrAck; 2373 | VdpCmdState <= stVdpCmdWaitWrVram; 2374 | when stVdpCmdWaitWrVram => 2375 | if ( VdpCmdVramWrReq = VdpCmdVramWrAck ) then 2376 | -- 書き込み完了 2377 | if( VdpCmdDIX = '0' ) then 2378 | VdpCmdDxTmp <= VdpCmdDxTmp + xCountUp; 2379 | else 2380 | VdpCmdDxTmp <= VdpCmdDxTmp - xCountUp; 2381 | end if; 2382 | VdpCmdNXTmp <= VdpCmdNXTmp - 1; 2383 | VdpCmdState <= stVdpCmdChkLoop; 2384 | end if; 2385 | when stVdpCmdChkLoop => 2386 | -- JP: 繰り返し条件のチェック 2387 | if( (nxLoopEnd = '1') and (VdpCmdNY = 1) ) then 2388 | -- JP: 実行終了 2389 | VdpCmdState <= stVdpCmdExecEnd; 2390 | else 2391 | -- 2392 | case VdpCmdCMR(7 downto 4) is 2393 | when VdpCmdHMMC => 2394 | VdpCmdState <= stVdpCmdRdCPU; 2395 | when VdpCmdYMMM => 2396 | VdpCmdState <= stVdpCmdRdVram; 2397 | when VdpCmdHMMM => 2398 | VdpCmdState <= stVdpCmdRdVram; 2399 | when VdpCmdHMMV => 2400 | VdpCmdState <= stVdpCmdWrVram; 2401 | when VdpCmdLMMC => 2402 | VdpCmdState <= stVdpCmdRdCPU; 2403 | when VdpCmdLMMM => 2404 | VdpCmdState <= stVdpCmdRdVram; 2405 | when VdpCmdLMMV => 2406 | VdpCmdVramWrData <= VdpCmdCLR; -- JP:塗りつぶす色 2407 | VdpCmdState <= stVdpCmdPreRdVram; 2408 | when others => 2409 | VdpCmdState <= stVdpCmdExecEnd; 2410 | end case; 2411 | end if; 2412 | if( nxLoopEnd = '1' ) then 2413 | VdpCmdNXTmp <= nxCount; -- reset counter 2414 | VdpCmdSXTmp <= VdpCmdSX; 2415 | VdpCmdDXTmp <= VdpCmdDX; 2416 | VdpCmdNY <= VdpCmdNY - 1; 2417 | if( VdpCmdDIY = '0' ) then 2418 | if( (VdpCmdCMR(7 downto 4) = VdpCmdHMMM) or 2419 | (VdpCmdCMR(7 downto 4) = VdpCmdYMMM) or 2420 | (VdpCmdCMR(7 downto 4) = VdpCmdLMMM) ) then 2421 | VdpCmdSy <= VdpCmdSy + 1; 2422 | end if; 2423 | VdpCmdDy <= VdpCmdDy + 1; 2424 | else 2425 | if( (VdpCmdCMR(7 downto 4) = VdpCmdHMMM) or 2426 | (VdpCmdCMR(7 downto 4) = VdpCmdYMMM) or 2427 | (VdpCmdCMR(7 downto 4) = VdpCmdLMMM) ) then 2428 | VdpCmdSy <= VdpCmdSy - 1; 2429 | end if; 2430 | VdpCmdDy <= VdpCmdDy - 1; 2431 | end if; 2432 | end if; 2433 | when stVdpCmdExecEnd => 2434 | -- JP: VDPコマンド実行終了 2435 | VdpCmdState <= stVdpCmdIdle; 2436 | VdpCmdCE <= '0'; 2437 | VdpCmdTR <= '1'; -- JP: ここで 1にしてしまって良いかわからない 2438 | when others => 2439 | VdpCmdState <= stVdpCmdIdle; 2440 | end case; 2441 | end if; 2442 | end if; 2443 | end process; 2444 | 2445 | 2446 | end rtl; 2447 | --------------------------------------------------------------------------------