mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-04-08 22:01:25 +00:00
Ladybug HW: use common T80 and SN67489
This commit is contained in:
@@ -160,7 +160,6 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
||||
|
||||
# end ENTITY(CosmicAvenger)
|
||||
# -------------------------
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/CosmicAvenger.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_video_unit.vhd
|
||||
@@ -180,13 +179,7 @@ set_global_assignment -name VHDL_FILE rtl/ladybug_chutes.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_chute.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_char.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_addr_dec.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_top.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_tone.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_noise.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_latch_ctrl.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_clock_div.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_attenuator.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/ladybug_sound_unit.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_sound_unit.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_sprite_u.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_sprite_l.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_cpu3.vhd
|
||||
@@ -198,15 +191,12 @@ set_global_assignment -name VHDL_FILE rtl/ROM/prom_decrypt.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_3.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_2.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_1.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80a.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_Reg.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_Pack.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_MCode.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_ALU.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ttl_393.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ttl_175.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/spram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/dpram.vhd
|
||||
set_global_assignment -name QIP_FILE rtl/pll.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/Sound/sn76489/sn76489.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@@ -41,13 +41,16 @@ module CosmicAvenger
|
||||
`include "rtl\build_id.v"
|
||||
|
||||
localparam CONF_STR = {
|
||||
"C.Avenger;;",
|
||||
"CAVENGER;;",
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scanlines,Off,25%,50%,75%;",
|
||||
"O5,Blend,Off,On;",
|
||||
"T6,Reset;",
|
||||
"T0,Reset;",
|
||||
"V,v1.10.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire rotate = status[2];
|
||||
|
||||
assign LED = 1;
|
||||
assign AUDIO_R = AUDIO_L;
|
||||
|
||||
@@ -67,17 +70,43 @@ wire [7:0] joystick_0;
|
||||
wire [7:0] joystick_1;
|
||||
wire scandoublerD;
|
||||
wire ypbpr;
|
||||
wire [10:0] ps2_key;
|
||||
reg [7:0] audio;
|
||||
wire hb, vb;
|
||||
wire blankn = ~(hb | vb);
|
||||
wire ce_vid;
|
||||
wire hs, vs;
|
||||
wire [1:0] r, g, b;
|
||||
wire no_csync;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
ladybugt ladybugt(
|
||||
user_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
user_io(
|
||||
.clk_sys (clk_sys ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_CLK (SPI_SCK ),
|
||||
.SPI_SS_IO (CONF_DATA0 ),
|
||||
.SPI_MISO (SPI_DO ),
|
||||
.SPI_MOSI (SPI_DI ),
|
||||
.buttons (buttons ),
|
||||
.switches (switches ),
|
||||
.scandoubler_disable (scandoublerD),
|
||||
.ypbpr (ypbpr ),
|
||||
.no_csync (no_csync ),
|
||||
.key_strobe (key_strobe ),
|
||||
.key_pressed (key_pressed ),
|
||||
.key_code (key_code ),
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
|
||||
wire [8:0] audio;
|
||||
wire hb, vb;
|
||||
wire blankn = ~(hb | vb);
|
||||
wire ce_vid;
|
||||
wire hs, vs;
|
||||
wire [1:0] r,g,b;
|
||||
|
||||
ladybugt ladybug(
|
||||
.CLK_IN(clk_sys),
|
||||
.I_RESET(status[0] | status[6] | buttons[1]),
|
||||
.I_RESET(status[0] | buttons[1]),
|
||||
.O_PIXCE(ce_vid),
|
||||
.O_VIDEO_R(r),
|
||||
.O_VIDEO_G(g),
|
||||
@@ -87,15 +116,15 @@ ladybugt ladybugt(
|
||||
.O_VBLANK(vb),
|
||||
.O_HBLANK(hb),
|
||||
.O_AUDIO(audio),
|
||||
.but_coin_s(~{1'b0,btn_coin}),
|
||||
.but_fire_s(~{1'b0,m_fire}),
|
||||
.but_bomb_s(~{1'b0,m_bomb}),
|
||||
.but_tilt_s(~{1'b0,1'b0}),
|
||||
.but_select_s(~{btn_two_players, btn_one_player}),
|
||||
.but_up_s(~{1'b0,m_up}),
|
||||
.but_down_s(~{1'b0,m_down}),
|
||||
.but_left_s(~{1'b0,m_left}),
|
||||
.but_right_s(~{1'b0,m_right})
|
||||
.but_coin_s(~{m_coin2,m_coin1}),
|
||||
.but_fire_s(~{m_fire2A,m_fireA}),
|
||||
.but_bomb_s(~{m_fire2B,m_fireB}),
|
||||
.but_tilt_s(~{m_tilt,m_tilt}),
|
||||
.but_select_s(~{m_two_players, m_one_player}),
|
||||
.but_up_s(~{m_up2,m_up}),
|
||||
.but_down_s(~{m_down2,m_down}),
|
||||
.but_left_s(~{m_left2,m_left}),
|
||||
.but_right_s(~{m_right2,m_right})
|
||||
);
|
||||
|
||||
mist_video #(.COLOR_DEPTH(2),.SD_HCNT_WIDTH(10)) mist_video(
|
||||
@@ -113,79 +142,40 @@ mist_video #(.COLOR_DEPTH(2),.SD_HCNT_WIDTH(10)) mist_video(
|
||||
.VGA_B(VGA_B),
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS),
|
||||
.rotate({1'b0,status[2]}),
|
||||
.rotate({1'b0,rotate}),
|
||||
.ce_divider(1'b1),
|
||||
.blend(status[5]),
|
||||
.scandoubler_disable(scandoublerD),
|
||||
.scanlines(status[4:3]),
|
||||
.ypbpr(ypbpr)
|
||||
.ypbpr(ypbpr),
|
||||
.no_csync(no_csync)
|
||||
);
|
||||
|
||||
user_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
user_io(
|
||||
.clk_sys (clk_sys ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_CLK (SPI_SCK ),
|
||||
.SPI_SS_IO (CONF_DATA0 ),
|
||||
.SPI_MISO (SPI_DO ),
|
||||
.SPI_MOSI (SPI_DI ),
|
||||
.buttons (buttons ),
|
||||
.switches (switches ),
|
||||
.scandoubler_disable (scandoublerD),
|
||||
.ypbpr (ypbpr ),
|
||||
.key_strobe (key_strobe ),
|
||||
.key_pressed (key_pressed ),
|
||||
.key_code (key_code ),
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
|
||||
dac dac(
|
||||
dac #(9) dac(
|
||||
.clk_i(clk_sys),
|
||||
.res_n_i(1),
|
||||
.dac_i({~audio[7], audio[6:0]}),
|
||||
.dac_i(audio),
|
||||
.dac_o(AUDIO_L)
|
||||
);
|
||||
|
||||
wire m_up = btn_up | joystick_0[3] | joystick_1[3];
|
||||
wire m_down = btn_down | joystick_0[2] | joystick_1[2];
|
||||
wire m_left = btn_left | joystick_0[1] | joystick_1[1];
|
||||
wire m_right = btn_right | joystick_0[0] | joystick_1[0];
|
||||
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
|
||||
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
|
||||
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
|
||||
|
||||
wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4];
|
||||
wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5];
|
||||
|
||||
reg btn_one_player = 0;
|
||||
reg btn_two_players = 0;
|
||||
reg btn_left = 0;
|
||||
reg btn_right = 0;
|
||||
reg btn_down = 0;
|
||||
reg btn_up = 0;
|
||||
reg btn_fire1 = 0;
|
||||
reg btn_fire2 = 0;
|
||||
reg btn_fire3 = 0;
|
||||
reg btn_coin = 0;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(key_strobe) begin
|
||||
case(key_code)
|
||||
'h75: btn_up <= key_pressed; // up
|
||||
'h72: btn_down <= key_pressed; // down
|
||||
'h6B: btn_left <= key_pressed; // left
|
||||
'h74: btn_right <= key_pressed; // right
|
||||
'h76: btn_coin <= key_pressed; // ESC
|
||||
'h05: btn_one_player <= key_pressed; // F1
|
||||
'h06: btn_two_players <= key_pressed; // F2
|
||||
'h14: btn_fire3 <= key_pressed; // ctrl
|
||||
'h11: btn_fire2 <= key_pressed; // alt
|
||||
'h29: btn_fire1 <= key_pressed; // Space
|
||||
endcase
|
||||
end
|
||||
end
|
||||
arcade_inputs inputs (
|
||||
.clk ( clk_sys ),
|
||||
.key_strobe ( key_strobe ),
|
||||
.key_pressed ( key_pressed ),
|
||||
.key_code ( key_code ),
|
||||
.joystick_0 ( joystick_0 ),
|
||||
.joystick_1 ( joystick_1 ),
|
||||
.rotate ( rotate ),
|
||||
.orientation ( 2'b00 ),
|
||||
.joyswap ( 1'b0 ),
|
||||
.oneplayer ( 1'b1 ),
|
||||
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
|
||||
.player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
|
||||
.player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
|
||||
);
|
||||
|
||||
endmodule
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,370 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0247
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
||||
--
|
||||
-- 0238 : Fixed zero flag for 16 bit SBC and ADC
|
||||
--
|
||||
-- 0240 : Added GB operations
|
||||
--
|
||||
-- 0242 : Cleanup
|
||||
--
|
||||
-- 0247 : Cleanup
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_ALU is
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_ALU;
|
||||
|
||||
architecture rtl of T80_ALU is
|
||||
|
||||
procedure AddSub(A : std_logic_vector;
|
||||
B : std_logic_vector;
|
||||
Sub : std_logic;
|
||||
Carry_In : std_logic;
|
||||
signal Res : out std_logic_vector;
|
||||
signal Carry : out std_logic) is
|
||||
|
||||
variable B_i : unsigned(A'length - 1 downto 0);
|
||||
variable Res_i : unsigned(A'length + 1 downto 0);
|
||||
begin
|
||||
if Sub = '1' then
|
||||
B_i := not unsigned(B);
|
||||
else
|
||||
B_i := unsigned(B);
|
||||
end if;
|
||||
|
||||
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
|
||||
Carry <= Res_i(A'length + 1);
|
||||
Res <= std_logic_vector(Res_i(A'length downto 1));
|
||||
end;
|
||||
|
||||
-- AddSub variables (temporary signals)
|
||||
signal UseCarry : std_logic;
|
||||
signal Carry7_v : std_logic;
|
||||
signal Overflow_v : std_logic;
|
||||
signal HalfCarry_v : std_logic;
|
||||
signal Carry_v : std_logic;
|
||||
signal Q_v : std_logic_vector(7 downto 0);
|
||||
|
||||
signal BitMask : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
with IR(5 downto 3) select BitMask <= "00000001" when "000",
|
||||
"00000010" when "001",
|
||||
"00000100" when "010",
|
||||
"00001000" when "011",
|
||||
"00010000" when "100",
|
||||
"00100000" when "101",
|
||||
"01000000" when "110",
|
||||
"10000000" when others;
|
||||
|
||||
UseCarry <= not ALU_Op(2) and ALU_Op(0);
|
||||
AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v);
|
||||
AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v);
|
||||
AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v);
|
||||
-- bug fix - parity flag is just parity for 8080, also overflow for Z80
|
||||
process (Carry_v, Carry7_v, Q_v)
|
||||
begin
|
||||
if(Mode=2) then
|
||||
OverFlow_v <= not (Q_v(0) xor Q_v(1) xor Q_v(2) xor Q_v(3) xor
|
||||
Q_v(4) xor Q_v(5) xor Q_v(6) xor Q_v(7)); else
|
||||
OverFlow_v <= Carry_v xor Carry7_v;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
|
||||
variable Q_t : std_logic_vector(7 downto 0);
|
||||
variable DAA_Q : unsigned(8 downto 0);
|
||||
begin
|
||||
Q_t := "--------";
|
||||
F_Out <= F_In;
|
||||
DAA_Q := "---------";
|
||||
case ALU_Op is
|
||||
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" =>
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_C) <= '0';
|
||||
case ALU_OP(2 downto 0) is
|
||||
when "000" | "001" => -- ADD, ADC
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_C) <= Carry_v;
|
||||
F_Out(Flag_H) <= HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "010" | "011" | "111" => -- SUB, SBC, CP
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_N) <= '1';
|
||||
F_Out(Flag_C) <= not Carry_v;
|
||||
F_Out(Flag_H) <= not HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "100" => -- AND
|
||||
Q_t(7 downto 0) := BusA and BusB;
|
||||
F_Out(Flag_H) <= '1';
|
||||
when "101" => -- XOR
|
||||
Q_t(7 downto 0) := BusA xor BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
when others => -- OR "110"
|
||||
Q_t(7 downto 0) := BusA or BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
end case;
|
||||
if ALU_Op(2 downto 0) = "111" then -- CP
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
else
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
end if;
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
if Z16 = '1' then
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC
|
||||
end if;
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
case ALU_Op(2 downto 0) is
|
||||
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP
|
||||
when others =>
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
end case;
|
||||
if Arith16 = '1' then
|
||||
F_Out(Flag_S) <= F_In(Flag_S);
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||
F_Out(Flag_P) <= F_In(Flag_P);
|
||||
end if;
|
||||
when "1100" =>
|
||||
-- DAA
|
||||
F_Out(Flag_H) <= F_In(Flag_H);
|
||||
F_Out(Flag_C) <= F_In(Flag_C);
|
||||
DAA_Q(7 downto 0) := unsigned(BusA);
|
||||
DAA_Q(8) := '0';
|
||||
if F_In(Flag_N) = '0' then
|
||||
-- After addition
|
||||
-- Alow > 9 or H = 1
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if (DAA_Q(3 downto 0) > 9) then
|
||||
F_Out(Flag_H) <= '1';
|
||||
else
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q := DAA_Q + 6;
|
||||
end if;
|
||||
-- new Ahigh > 9 or C = 1
|
||||
if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q + 96; -- 0x60
|
||||
end if;
|
||||
else
|
||||
-- After subtraction
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if DAA_Q(3 downto 0) > 5 then
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6;
|
||||
end if;
|
||||
if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q - 352; -- 0x160
|
||||
end if;
|
||||
end if;
|
||||
F_Out(Flag_X) <= DAA_Q(3);
|
||||
F_Out(Flag_Y) <= DAA_Q(5);
|
||||
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
|
||||
Q_t := std_logic_vector(DAA_Q(7 downto 0));
|
||||
if DAA_Q(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= DAA_Q(7);
|
||||
F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor
|
||||
DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7));
|
||||
when "1101" | "1110" =>
|
||||
-- RLD, RRD
|
||||
Q_t(7 downto 4) := BusA(7 downto 4);
|
||||
if ALU_Op(0) = '1' then
|
||||
Q_t(3 downto 0) := BusB(7 downto 4);
|
||||
else
|
||||
Q_t(3 downto 0) := BusB(3 downto 0);
|
||||
end if;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
when "1001" =>
|
||||
-- BIT
|
||||
Q_t(7 downto 0) := BusB and BitMask;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
F_Out(Flag_P) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
F_Out(Flag_P) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_H) <= '1';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= '0';
|
||||
F_Out(Flag_Y) <= '0';
|
||||
if IR(2 downto 0) /= "110" then
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
end if;
|
||||
when "1010" =>
|
||||
-- SET
|
||||
Q_t(7 downto 0) := BusB or BitMask;
|
||||
when "1011" =>
|
||||
-- RES
|
||||
Q_t(7 downto 0) := BusB and not BitMask;
|
||||
when "1000" =>
|
||||
-- ROT
|
||||
case IR(5 downto 3) is
|
||||
when "000" => -- RLC
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "010" => -- RL
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "001" => -- RRC
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(0);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "011" => -- RR
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "100" => -- SLA
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '0';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "110" => -- SLL (Undocumented) / SWAP
|
||||
if Mode = 3 then
|
||||
Q_t(7 downto 4) := BusA(3 downto 0);
|
||||
Q_t(3 downto 0) := BusA(7 downto 4);
|
||||
F_Out(Flag_C) <= '0';
|
||||
else
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '1';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
end if;
|
||||
when "101" => -- SRA
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when others => -- SRL
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := '0';
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
end case;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
if ISet = "00" then
|
||||
F_Out(Flag_P) <= F_In(Flag_P);
|
||||
F_Out(Flag_S) <= F_In(Flag_S);
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
Q <= Q_t;
|
||||
end process;
|
||||
end;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,220 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0242
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
package T80_Pack is
|
||||
|
||||
component T80
|
||||
generic(
|
||||
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
IORQ : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DInst : in std_logic_vector(7 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0);
|
||||
MC : out std_logic_vector(2 downto 0);
|
||||
TS : out std_logic_vector(2 downto 0);
|
||||
IntCycle_n : out std_logic;
|
||||
IntE : out std_logic;
|
||||
Stop : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_Reg
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_MCode
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
IR : in std_logic_vector(7 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
MCycle : in std_logic_vector(2 downto 0);
|
||||
F : in std_logic_vector(7 downto 0);
|
||||
NMICycle : in std_logic;
|
||||
IntCycle : in std_logic;
|
||||
XY_State : in std_logic_vector(1 downto 0);
|
||||
MCycles : out std_logic_vector(2 downto 0);
|
||||
TStates : out std_logic_vector(2 downto 0);
|
||||
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
|
||||
Inc_PC : out std_logic;
|
||||
Inc_WZ : out std_logic;
|
||||
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
|
||||
Read_To_Reg : out std_logic;
|
||||
Read_To_Acc : out std_logic;
|
||||
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
|
||||
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
|
||||
ALU_Op : out std_logic_vector(3 downto 0);
|
||||
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
|
||||
Save_ALU : out std_logic;
|
||||
PreserveC : out std_logic;
|
||||
Arith16 : out std_logic;
|
||||
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
|
||||
IORQ : out std_logic;
|
||||
Jump : out std_logic;
|
||||
JumpE : out std_logic;
|
||||
JumpXY : out std_logic;
|
||||
Call : out std_logic;
|
||||
RstP : out std_logic;
|
||||
LDZ : out std_logic;
|
||||
LDW : out std_logic;
|
||||
LDSPHL : out std_logic;
|
||||
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
|
||||
ExchangeDH : out std_logic;
|
||||
ExchangeRp : out std_logic;
|
||||
ExchangeAF : out std_logic;
|
||||
ExchangeRS : out std_logic;
|
||||
I_DJNZ : out std_logic;
|
||||
I_CPL : out std_logic;
|
||||
I_CCF : out std_logic;
|
||||
I_SCF : out std_logic;
|
||||
I_RETN : out std_logic;
|
||||
I_BT : out std_logic;
|
||||
I_BC : out std_logic;
|
||||
I_BTR : out std_logic;
|
||||
I_RLD : out std_logic;
|
||||
I_RRD : out std_logic;
|
||||
I_INRC : out std_logic;
|
||||
SetDI : out std_logic;
|
||||
SetEI : out std_logic;
|
||||
IMode : out std_logic_vector(1 downto 0);
|
||||
Halt : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
XYbit_undoc : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_ALU
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
end;
|
||||
@@ -1,114 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- T80 Registers, technology independent
|
||||
--
|
||||
-- Version : 0244
|
||||
--
|
||||
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t51/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0242 : Initial release
|
||||
--
|
||||
-- 0244 : Changed to single register file
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_Reg is
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_Reg;
|
||||
|
||||
architecture rtl of T80_Reg is
|
||||
|
||||
type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0);
|
||||
signal RegsH : Register_Image(0 to 7);
|
||||
signal RegsL : Register_Image(0 to 7);
|
||||
|
||||
begin
|
||||
|
||||
process (Clk)
|
||||
begin
|
||||
if Clk'event and Clk = '1' then
|
||||
if CEN = '1' then
|
||||
if WEH = '1' then
|
||||
RegsH(to_integer(unsigned(AddrA))) <= DIH;
|
||||
end if;
|
||||
if WEL = '1' then
|
||||
RegsL(to_integer(unsigned(AddrA))) <= DIL;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
DOAH <= RegsH(to_integer(unsigned(AddrA)));
|
||||
DOAL <= RegsL(to_integer(unsigned(AddrA)));
|
||||
DOBH <= RegsH(to_integer(unsigned(AddrB)));
|
||||
DOBL <= RegsL(to_integer(unsigned(AddrB)));
|
||||
DOCH <= RegsH(to_integer(unsigned(AddrC)));
|
||||
DOCL <= RegsL(to_integer(unsigned(AddrC)));
|
||||
|
||||
end;
|
||||
@@ -1,280 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core, asynchronous top level
|
||||
--
|
||||
-- Version : 0247
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0208 : First complete release
|
||||
--
|
||||
-- 0211 : Fixed interrupt cycle
|
||||
--
|
||||
-- 0235 : Updated for T80 interface change
|
||||
--
|
||||
-- 0238 : Updated for T80 interface change
|
||||
--
|
||||
-- 0240 : Updated for T80 interface change
|
||||
--
|
||||
-- 0242 : Updated for T80 interface change
|
||||
--
|
||||
-- 0247 : Fixed bus req/ack cycle
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use work.T80_Pack.all;
|
||||
|
||||
entity T80a is
|
||||
generic(
|
||||
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CLK_EN_SYS : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
MREQ_n : out std_logic;
|
||||
IORQ_n : out std_logic;
|
||||
RD_n : out std_logic;
|
||||
WR_n : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80a;
|
||||
|
||||
architecture rtl of T80a is
|
||||
|
||||
signal CEN : std_logic;
|
||||
signal Reset_s : std_logic;
|
||||
signal IntCycle_n : std_logic;
|
||||
signal IORQ : std_logic;
|
||||
signal NoRead : std_logic;
|
||||
signal Write : std_logic;
|
||||
signal MREQ : std_logic;
|
||||
signal MReq_Inhibit : std_logic;
|
||||
signal Req_Inhibit : std_logic;
|
||||
signal RD : std_logic;
|
||||
signal MREQ_n_i : std_logic;
|
||||
signal IORQ_n_i : std_logic;
|
||||
signal RD_n_i : std_logic;
|
||||
signal WR_n_i : std_logic;
|
||||
signal RFSH_n_i : std_logic;
|
||||
signal BUSAK_n_i : std_logic;
|
||||
signal A_i : std_logic_vector(15 downto 0);
|
||||
signal DO_Reg : std_logic_vector(7 downto 0);
|
||||
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
|
||||
signal Wait_s : std_logic;
|
||||
signal MCycle : std_logic_vector(2 downto 0);
|
||||
signal TState : std_logic_vector(2 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- clock enable supplied from clocking system
|
||||
CEN <= CLK_EN_SYS;
|
||||
|
||||
BUSAK_n <= BUSAK_n_i;
|
||||
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
|
||||
RD_n_i <= not RD or Req_Inhibit;
|
||||
|
||||
MREQ_n <= MREQ_n_i;
|
||||
IORQ_n <= IORQ_n_i;
|
||||
RD_n <= RD_n_i;
|
||||
WR_n <= WR_n_i;
|
||||
RFSH_n <= RFSH_n_i;
|
||||
A <= A_i;
|
||||
DO <= DO_Reg;
|
||||
|
||||
-- process (RESET_n, CLK_n)
|
||||
-- begin
|
||||
-- if RESET_n = '0' then
|
||||
-- Reset_s <= '0';
|
||||
-- elsif CLK_n'event and CLK_n = '1' then
|
||||
-- Reset_s <= '1';
|
||||
-- end if;
|
||||
-- end process;
|
||||
-- T80 reset input has already proper characteristics:
|
||||
-- * asynchronous assertion
|
||||
-- * deassertion synchronous to CLK_n (main_clk)
|
||||
Reset_s <= RESET_n;
|
||||
|
||||
u0 : T80
|
||||
generic map(
|
||||
Mode => Mode,
|
||||
IOWait => 1)
|
||||
port map(
|
||||
CEN => CEN,
|
||||
M1_n => M1_n,
|
||||
IORQ => IORQ,
|
||||
NoRead => NoRead,
|
||||
Write => Write,
|
||||
RFSH_n => RFSH_n_i,
|
||||
HALT_n => HALT_n,
|
||||
WAIT_n => Wait_s,
|
||||
INT_n => INT_n,
|
||||
NMI_n => NMI_n,
|
||||
RESET_n => Reset_s,
|
||||
BUSRQ_n => BUSRQ_n,
|
||||
BUSAK_n => BUSAK_n_i,
|
||||
CLK_n => CLK_n,
|
||||
A => A_i,
|
||||
DInst => DI,
|
||||
DI => DI_Reg,
|
||||
DO => DO_Reg,
|
||||
MC => MCycle,
|
||||
TS => TState,
|
||||
IntCycle_n => IntCycle_n);
|
||||
|
||||
process (CLK_n)
|
||||
begin
|
||||
if CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
Wait_s <= WAIT_n;
|
||||
if TState = "011" and BUSAK_n_i = '1' then
|
||||
DI_Reg <= to_x01(DI);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
WR_n_i <= '1';
|
||||
elsif CLK_n'event and CLK_n = '1' then
|
||||
if CEN = '1' then
|
||||
WR_n_i <= '1';
|
||||
if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
|
||||
WR_n_i <= not Write;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
Req_Inhibit <= '0';
|
||||
elsif CLK_n'event and CLK_n = '1' then
|
||||
if CEN = '1' then
|
||||
if MCycle = "001" and TState = "010" then
|
||||
Req_Inhibit <= '1';
|
||||
else
|
||||
Req_Inhibit <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
MReq_Inhibit <= '0';
|
||||
elsif CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
if MCycle = "001" and TState = "010" then
|
||||
MReq_Inhibit <= '1';
|
||||
else
|
||||
MReq_Inhibit <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '0';
|
||||
elsif CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
|
||||
if MCycle = "001" then
|
||||
if TState = "001" then
|
||||
RD <= IntCycle_n;
|
||||
MREQ <= IntCycle_n;
|
||||
IORQ_n_i <= IntCycle_n;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '1';
|
||||
end if;
|
||||
if TState = "100" then
|
||||
MREQ <= '0';
|
||||
end if;
|
||||
else
|
||||
if TState = "001" and NoRead = '0' then
|
||||
RD <= not Write;
|
||||
IORQ_n_i <= not IORQ;
|
||||
MREQ <= not IORQ;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end;
|
||||
@@ -65,7 +65,7 @@ port (
|
||||
O_PIXCE : out std_logic;
|
||||
|
||||
-- Audio Interface --------------------------------------------------------
|
||||
O_AUDIO : out signed(7 downto 0);
|
||||
O_AUDIO : out std_logic_vector( 8 downto 0);
|
||||
|
||||
but_coin_s : in std_logic_vector( 1 downto 0);
|
||||
but_fire_s : in std_logic_vector( 1 downto 0);
|
||||
@@ -160,8 +160,8 @@ begin
|
||||
rgb_b_o => O_VIDEO_B,
|
||||
hsync_n_o => O_HSYNC,
|
||||
vsync_n_o => O_VSYNC,
|
||||
vblank_o => O_VBLANK,
|
||||
hblank_o => O_HBLANK,
|
||||
vblank_o => O_VBLANK,
|
||||
hblank_o => O_HBLANK,
|
||||
audio_o => O_AUDIO,
|
||||
rom_cpu_a_o => rom_cpu_a_s,
|
||||
rom_cpu_d_i => rom_cpu_d_s,
|
||||
|
||||
@@ -119,14 +119,14 @@ begin
|
||||
-- "wait" has to be modelled with the clock enable because the T80 is not
|
||||
-- able to enlarge write accesses properly when they are delayed with "wait"
|
||||
t80_clk_en_s <= clk_en_4mhz_i and wait_n_s;
|
||||
T80a_b : entity work.T80a
|
||||
T80a_b : entity work.T80s
|
||||
generic map (
|
||||
Mode => 0
|
||||
)
|
||||
port map (
|
||||
RESET_n => res_n_i,
|
||||
CLK_n => clk_20mhz_i,
|
||||
CLK_EN_SYS => t80_clk_en_s,
|
||||
CLK => clk_20mhz_i,
|
||||
CEN => t80_clk_en_s,
|
||||
WAIT_n => wait_n_s,
|
||||
INT_n => int_n_s,
|
||||
NMI_n => nmi_n_s,
|
||||
|
||||
@@ -77,10 +77,10 @@ entity ladybug_machine is
|
||||
hsync_n_o : out std_logic;
|
||||
vsync_n_o : out std_logic;
|
||||
comp_sync_n_o : out std_logic;
|
||||
vblank_o : out std_logic;
|
||||
hblank_o : out std_logic;
|
||||
vblank_o : out std_logic;
|
||||
hblank_o : out std_logic;
|
||||
-- Audio Interface --------------------------------------------------------
|
||||
audio_o : out signed( 7 downto 0);
|
||||
audio_o : out std_logic_vector( 8 downto 0);
|
||||
-- CPU ROM Interface ------------------------------------------------------
|
||||
rom_cpu_a_o : out std_logic_vector(14 downto 0);
|
||||
rom_cpu_d_i : in std_logic_vector( 7 downto 0);
|
||||
|
||||
@@ -59,7 +59,7 @@ entity ladybug_sound_unit is
|
||||
wr_n_i : in std_logic;
|
||||
d_from_cpu_i : in std_logic_vector(7 downto 0);
|
||||
sound_wait_n_o : out std_logic;
|
||||
audio_o : out signed(7 downto 0)
|
||||
audio_o : out std_logic_vector(8 downto 0)
|
||||
);
|
||||
|
||||
end ladybug_sound_unit;
|
||||
@@ -70,7 +70,7 @@ architecture struct of ladybug_sound_unit is
|
||||
ready_c1_s : std_logic;
|
||||
|
||||
signal aout_b1_s,
|
||||
aout_c1_s : signed(7 downto 0);
|
||||
aout_c1_s : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
@@ -117,23 +117,7 @@ begin
|
||||
--
|
||||
-- Purpose:
|
||||
-- Mix the digital audio of the two SN76489 instances.
|
||||
-- Additional care is taken to avoid audio overfow/clipping.
|
||||
--
|
||||
mix: process (aout_b1_s,
|
||||
aout_c1_s)
|
||||
variable sum_v : signed(8 downto 0);
|
||||
begin
|
||||
sum_v := RESIZE(aout_b1_s, 9) + RESIZE(aout_c1_s, 9);
|
||||
|
||||
if sum_v > 127 then
|
||||
audio_o <= to_signed(127, 8);
|
||||
elsif sum_v < -128 then
|
||||
audio_o <= to_signed(-128, 8);
|
||||
else
|
||||
audio_o <= RESIZE(sum_v, 8);
|
||||
end if;
|
||||
|
||||
end process mix;
|
||||
audio_o <= std_logic_vector(unsigned('0'&aout_b1_s) + unsigned('0'&aout_c1_s));
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -1,143 +0,0 @@
|
||||
|
||||
An SN76489AN Compatible Implementation in VHDL
|
||||
==============================================
|
||||
Version: $Date: 2006/06/18 19:28:40 $
|
||||
|
||||
Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
See the file COPYING.
|
||||
|
||||
|
||||
Integration
|
||||
-----------
|
||||
|
||||
The sn76489 design exhibits all interface signals as the original chip. It
|
||||
only differs in the audio data output which is provided as an 8 bit signed
|
||||
vector instead of an analog output pin.
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
-- Set to '1' when operating the design in SN76489 mode. The primary clock
|
||||
-- input is divided by 16 in this variant. The data sheet mentions the
|
||||
-- SN76494 which contains a divide-by-2 clock input stage. Set the generic
|
||||
-- to '0' to enable this mode.
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
-- Primary clock input
|
||||
-- Drive with the target frequency or any integer multiple of it.
|
||||
|
||||
clock_en_i : in std_logic;
|
||||
-- Clock enable
|
||||
-- A '1' on this input qualifies a valid rising edge on clock_i. A '0'
|
||||
-- disables the next rising clock edge, effectivley halting the design
|
||||
-- until the next enabled rising clock edge.
|
||||
-- Can be used to run the core at lower frequencies than applied on
|
||||
-- clock_i.
|
||||
|
||||
res_n_i : in std_logic;
|
||||
-- Asynchronous low active reset input.
|
||||
-- Sets all sequential elements to a known state.
|
||||
|
||||
ce_n_i : in std_logic;
|
||||
-- Chip enable, low active.
|
||||
|
||||
we_n_i : in std_logic;
|
||||
-- Write enable, low active.
|
||||
|
||||
ready_o : out std_logic;
|
||||
-- Ready indication to microprocessor.
|
||||
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
-- Data input
|
||||
-- MSB 0 ... 7 LSB
|
||||
|
||||
aout_o : out signed(0 to 7)
|
||||
-- Audio output, signed vector
|
||||
-- MSB/SIGN 0 ... 7 LSB
|
||||
);
|
||||
|
||||
|
||||
Both 8 bit vector ports are defined (0 to 7) which declares bit 0 to be the
|
||||
MSB and bit 7 to be the LSB. This has been implemented according to TI's data
|
||||
sheet, thus all register/data format figures apply 1:1 for this design.
|
||||
Many systems will flip the system data bus bit wise before it is connected to
|
||||
this PSG. This is simply achieved with the following VHDL construct:
|
||||
|
||||
signal data_s : std_logic_vector(7 downto 0);
|
||||
|
||||
...
|
||||
d_i => data_s,
|
||||
...
|
||||
|
||||
d_i and data_s will be assigned from left to right, resulting in the expected
|
||||
bit assignment:
|
||||
|
||||
d_i data_s
|
||||
0 7
|
||||
1 6
|
||||
...
|
||||
6 1
|
||||
7 0
|
||||
|
||||
|
||||
As this design is fully synchronous, care has to be taken when the design
|
||||
replaces an SN76489 in asynchronous mode. No problems are expected when
|
||||
interfacing the code to other synchronous components.
|
||||
|
||||
|
||||
Design Hierarchy
|
||||
----------------
|
||||
|
||||
sn76489_top
|
||||
|
|
||||
+-- sn76489_latch_ctrl
|
||||
|
|
||||
+-- sn76489_clock_div
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
\-- sn76489_noise
|
||||
|
|
||||
\-- sn76489_attentuator
|
||||
|
||||
Resulting compilation sequence:
|
||||
|
||||
sn76489_comp_pack-p.vhd
|
||||
sn76489_top.vhd
|
||||
sn76489_latch_ctrl.vhd
|
||||
sn76489_latch_ctrl-c.vhd
|
||||
sn76489_clock_div.vhd
|
||||
sn76489_clock_div-c.vhd
|
||||
sn76489_attenuator.vhd
|
||||
sn76489_attenuator-c.vhd
|
||||
sn76489_tone.vhd
|
||||
sn76489_tone-c.vhd
|
||||
sn76489_noise.vhd
|
||||
sn76489_noise-c.vhd
|
||||
sn76489_top-c.vhd
|
||||
|
||||
Skip the files containing VHDL configurations when analyzing the code for
|
||||
synthesis.
|
||||
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
* TI Data sheet SN76489.pdf
|
||||
ftp://ftp.whtech.com/datasheets%20&%20manuals/SN76489.pdf
|
||||
|
||||
* John Kortink's article on the SN76489:
|
||||
http://web.inter.nl.net/users/J.Kortink/home/articles/sn76489/
|
||||
|
||||
* Maxim's "SN76489 notes" in
|
||||
http://www.smspower.org/maxim/docs/SN76489.txt
|
||||
@@ -1,114 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_attenuator.vhd,v 1.7 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Attenuator Module
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_attenuator is
|
||||
|
||||
port (
|
||||
attenuation_i : in std_logic_vector(0 to 3);
|
||||
factor_i : in signed(0 to 1);
|
||||
product_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_attenuator;
|
||||
|
||||
|
||||
architecture rtl of sn76489_attenuator is
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process attenuate
|
||||
--
|
||||
-- Purpose:
|
||||
-- Determine the attenuation and generate the resulting product.
|
||||
--
|
||||
-- The maximum attenuation value is 31 which corresponds to volume off.
|
||||
-- As described in the data sheet, the maximum "playing" attenuation is
|
||||
-- 28 = 16 + 8 + 4
|
||||
--
|
||||
-- The table for the volume constants is derived from the following
|
||||
-- formula (each step is 2dB voltage):
|
||||
-- v(0) = 31
|
||||
-- v(n+1) = v(n) * 0.79432823
|
||||
--
|
||||
attenuate: process (attenuation_i,
|
||||
factor_i)
|
||||
|
||||
type volume_t is array (natural range 0 to 15) of natural;
|
||||
constant volume_c : volume_t :=
|
||||
(31, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3, 2, 2, 2, 1, 0);
|
||||
|
||||
variable attenuation_v : unsigned(attenuation_i'range);
|
||||
variable volume_v : signed(product_o'range);
|
||||
|
||||
begin
|
||||
|
||||
attenuation_v := unsigned(attenuation_i);
|
||||
|
||||
-- volume look-up table
|
||||
volume_v := to_signed(volume_c(to_integer(attenuation_v)),
|
||||
product_o'length);
|
||||
|
||||
-- this replaces a multiplier and consumes a bit fewer
|
||||
-- resources
|
||||
case to_integer(factor_i) is
|
||||
when +1 =>
|
||||
product_o <= volume_v;
|
||||
when -1 =>
|
||||
product_o <= -volume_v;
|
||||
when others =>
|
||||
product_o <= (others => '0');
|
||||
end case;
|
||||
|
||||
end process attenuate;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
||||
@@ -1,134 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_clock_div.vhd,v 1.4 2005/10/10 21:51:27 arnim Exp $
|
||||
--
|
||||
-- Clock Divider Circuit
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity sn76489_clock_div is
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clock_en_i : in std_logic;
|
||||
res_n_i : in std_logic;
|
||||
clk_en_o : out boolean
|
||||
);
|
||||
|
||||
end sn76489_clock_div;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture rtl of sn76489_clock_div is
|
||||
|
||||
signal cnt_s,
|
||||
cnt_q : unsigned(3 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential counter element.
|
||||
--
|
||||
seq: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
cnt_q <= (others => '0');
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
cnt_q <= cnt_s;
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process comb
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the combinational counter logic.
|
||||
--
|
||||
comb: process (clock_en_i,
|
||||
cnt_q)
|
||||
begin
|
||||
-- default assignments
|
||||
cnt_s <= cnt_q;
|
||||
clk_en_o <= false;
|
||||
|
||||
if clock_en_i = '1' then
|
||||
|
||||
if cnt_q = 0 then
|
||||
clk_en_o <= true;
|
||||
|
||||
if clock_div_16_g = 1 then
|
||||
cnt_s <= to_unsigned(15, cnt_q'length);
|
||||
elsif clock_div_16_g = 0 then
|
||||
cnt_s <= to_unsigned( 1, cnt_q'length);
|
||||
else
|
||||
-- pragma translate_off
|
||||
assert false
|
||||
report "Generic clock_div_16_g must be either 0 or 1."
|
||||
severity failure;
|
||||
-- pragma translate_on
|
||||
end if;
|
||||
|
||||
else
|
||||
cnt_s <= cnt_q - 1;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end process comb;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
||||
@@ -1,138 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_latch_ctrl.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Latch Control Unit
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity sn76489_latch_ctrl is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
ce_n_i : in std_logic;
|
||||
we_n_i : in std_logic;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
ready_o : out std_logic;
|
||||
tone1_we_o : out boolean;
|
||||
tone2_we_o : out boolean;
|
||||
tone3_we_o : out boolean;
|
||||
noise_we_o : out boolean;
|
||||
r2_o : out std_logic
|
||||
);
|
||||
|
||||
end sn76489_latch_ctrl;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture rtl of sn76489_latch_ctrl is
|
||||
|
||||
signal reg_q : std_logic_vector(0 to 2);
|
||||
signal we_q : boolean;
|
||||
signal ready_q : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential elements.
|
||||
--
|
||||
seq: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
reg_q <= (others => '0');
|
||||
we_q <= false;
|
||||
ready_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
-- READY Flag Output ----------------------------------------------------
|
||||
if ready_q = '0' and we_q then
|
||||
if clk_en_i then
|
||||
-- assert READY when write access happened
|
||||
ready_q <= '1';
|
||||
end if;
|
||||
elsif ce_n_i = '1' then
|
||||
-- deassert READY when access has finished
|
||||
ready_q <= '0';
|
||||
end if;
|
||||
|
||||
-- Register Selection ---------------------------------------------------
|
||||
if ce_n_i = '0' and we_n_i = '0' then
|
||||
if clk_en_i then
|
||||
if d_i(0) = '1' then
|
||||
reg_q <= d_i(1 to 3);
|
||||
end if;
|
||||
we_q <= true;
|
||||
end if;
|
||||
else
|
||||
we_q <= false;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
tone1_we_o <= reg_q(0 to 1) = "00" and we_q;
|
||||
tone2_we_o <= reg_q(0 to 1) = "01" and we_q;
|
||||
tone3_we_o <= reg_q(0 to 1) = "10" and we_q;
|
||||
noise_we_o <= reg_q(0 to 1) = "11" and we_q;
|
||||
|
||||
r2_o <= reg_q(2);
|
||||
|
||||
ready_o <= ready_q
|
||||
when ce_n_i = '0' else
|
||||
'1';
|
||||
|
||||
end rtl;
|
||||
@@ -1,278 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_noise.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Noise Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_noise is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
we_i : in boolean;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
tone3_ff_i : in std_logic;
|
||||
noise_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_noise;
|
||||
|
||||
architecture rtl of sn76489_noise is
|
||||
|
||||
signal nf_q : std_logic_vector(0 to 1);
|
||||
signal fb_q : std_logic;
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 6);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal shift_source_s,
|
||||
shift_source_q : std_logic;
|
||||
signal shift_rise_edge_s : boolean;
|
||||
|
||||
signal lfsr_q : std_logic_vector(0 to 15);
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process cpu_regs
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the registers writable by the CPU.
|
||||
--
|
||||
cpu_regs: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
nf_q <= (others => '0');
|
||||
fb_q <= '0';
|
||||
a_q <= (others => '1');
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i and we_i then
|
||||
if r2_i = '0' then
|
||||
-- access to control register
|
||||
-- both access types can write to the control register!
|
||||
nf_q <= d_i(6 to 7);
|
||||
fb_q <= d_i(5);
|
||||
|
||||
else
|
||||
-- access to attenuator register
|
||||
-- both access types can write to the attenuator register!
|
||||
a_q <= d_i(4 to 7);
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process cpu_regs;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process freq_gen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the frequency generation components.
|
||||
--
|
||||
freq_gen: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
freq_cnt_q <= (others => '0');
|
||||
freq_ff_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if freq_cnt_q = 0 then
|
||||
-- reload frequency counter according to NF setting
|
||||
case nf_q is
|
||||
when "00" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 2 - 1, freq_cnt_q'length);
|
||||
when "01" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 4 - 1, freq_cnt_q'length);
|
||||
when "10" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 8 - 1, freq_cnt_q'length);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
freq_ff_q <= not freq_ff_q;
|
||||
|
||||
else
|
||||
-- decrement frequency counter
|
||||
freq_cnt_q <= freq_cnt_q - 1;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process freq_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Multiplex the source of the LFSR's shift enable
|
||||
-----------------------------------------------------------------------------
|
||||
shift_source_s <= tone3_ff_i
|
||||
when nf_q = "11" else
|
||||
freq_ff_q;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process rise_edge
|
||||
--
|
||||
-- Purpose:
|
||||
-- Detect the rising edge of the selected LFSR shift source.
|
||||
--
|
||||
rise_edge: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
shift_source_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
shift_source_q <= shift_source_s;
|
||||
end if;
|
||||
end if;
|
||||
end process rise_edge;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
-- detect rising edge on shift source
|
||||
shift_rise_edge_s <= shift_source_q = '0' and shift_source_s = '1';
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process lfsr
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the LFSR that generates noise.
|
||||
-- Note: This implementation shifts the register right, i.e. from index
|
||||
-- 15 towards 0 => bit 15 is the input, bit 0 is the output
|
||||
--
|
||||
-- Tapped bits according to MAME's sn76496.c, implemented in function
|
||||
-- lfsr_tapped_f.
|
||||
--
|
||||
lfsr: process (clock_i, res_n_i)
|
||||
|
||||
function lfsr_tapped_f(lfsr : in std_logic_vector) return std_logic is
|
||||
constant tapped_bits_c : std_logic_vector(0 to 15)
|
||||
-- tapped bits are 0, 2, 15
|
||||
:= "1010000000000001";
|
||||
variable parity_v : std_logic;
|
||||
begin
|
||||
parity_v := '0';
|
||||
|
||||
for idx in lfsr'low to lfsr'high loop
|
||||
parity_v := parity_v xor (lfsr(idx) and tapped_bits_c(idx));
|
||||
end loop;
|
||||
|
||||
return parity_v;
|
||||
end;
|
||||
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
-- reset LFSR to "0000000000000001"
|
||||
lfsr_q <= (others => '0');
|
||||
lfsr_q(lfsr_q'right) <= '1';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if we_i and r2_i = '0' then
|
||||
-- write to noise register
|
||||
-- -> reset LFSR
|
||||
lfsr_q <= (others => '0');
|
||||
lfsr_q(lfsr_q'right) <= '1';
|
||||
|
||||
elsif shift_rise_edge_s then
|
||||
|
||||
-- shift LFSR left towards MSB
|
||||
for idx in lfsr_q'right-1 downto lfsr_q'left loop
|
||||
lfsr_q(idx) <= lfsr_q(idx+1);
|
||||
end loop;
|
||||
|
||||
-- determine input bit
|
||||
if fb_q = '0' then
|
||||
-- "Periodic" Noise
|
||||
-- -> input to LFSR is output
|
||||
lfsr_q(lfsr_q'right) <= lfsr_q(lfsr_q'left);
|
||||
else
|
||||
-- "White" Noise
|
||||
-- -> input to LFSR is parity of tapped bits
|
||||
lfsr_q(lfsr_q'right) <= lfsr_tapped_f(lfsr_q);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process lfsr;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map output of LFSR to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when lfsr_q(0) = '1' else
|
||||
to_signed( 0, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The attenuator itself
|
||||
-----------------------------------------------------------------------------
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
product_o => noise_o
|
||||
);
|
||||
|
||||
end rtl;
|
||||
@@ -1,188 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_tone.vhd,v 1.5 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Tone Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_tone is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
we_i : in boolean;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
ff_o : out std_logic;
|
||||
tone_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_tone;
|
||||
|
||||
architecture rtl of sn76489_tone is
|
||||
|
||||
signal f_q : std_logic_vector(0 to 9);
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 9);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
|
||||
function all_zero(a : in std_logic_vector) return boolean is
|
||||
variable result_v : boolean;
|
||||
begin
|
||||
result_v := true;
|
||||
|
||||
for idx in a'low to a'high loop
|
||||
if a(idx) /= '0' then
|
||||
result_v := false;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return result_v;
|
||||
end;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process cpu_regs
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the registers writable by the CPU.
|
||||
--
|
||||
cpu_regs: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
f_q <= (others => '0');
|
||||
a_q <= (others => '1');
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i and we_i then
|
||||
if r2_i = '0' then
|
||||
-- access to frequency register
|
||||
if d_i(0) = '0' then
|
||||
f_q(0 to 5) <= d_i(2 to 7);
|
||||
else
|
||||
f_q(6 to 9) <= d_i(4 to 7);
|
||||
end if;
|
||||
|
||||
else
|
||||
-- access to attenuator register
|
||||
-- both access types can write to the attenuator register!
|
||||
a_q <= d_i(4 to 7);
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process cpu_regs;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process freq_gen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the frequency generation components.
|
||||
--
|
||||
freq_gen: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
freq_cnt_q <= (others => '0');
|
||||
freq_ff_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if freq_cnt_q = 0 then
|
||||
-- update counter from frequency register
|
||||
freq_cnt_q <= unsigned(f_q);
|
||||
|
||||
-- and toggle the frequency flip-flop if enabled
|
||||
if not all_zero(f_q) then
|
||||
freq_ff_q <= not freq_ff_q;
|
||||
else
|
||||
-- if frequency setting is 0, then keep flip-flop at +1
|
||||
freq_ff_q <= '1';
|
||||
end if;
|
||||
|
||||
else
|
||||
-- decrement frequency counter
|
||||
freq_cnt_q <= freq_cnt_q - 1;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process freq_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map frequency flip-flop to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when freq_ff_q = '1' else
|
||||
to_signed(-1, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The attenuator itself
|
||||
-----------------------------------------------------------------------------
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
product_o => tone_o
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
ff_o <= freq_ff_q;
|
||||
|
||||
end rtl;
|
||||
@@ -1,200 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_top.vhd,v 1.9 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Chip Toplevel
|
||||
--
|
||||
-- References:
|
||||
--
|
||||
-- * TI Data sheet SN76489.pdf
|
||||
-- ftp://ftp.whtech.com/datasheets%20&%20manuals/SN76489.pdf
|
||||
--
|
||||
-- * John Kortink's article on the SN76489:
|
||||
-- http://web.inter.nl.net/users/J.Kortink/home/articles/sn76489/
|
||||
--
|
||||
-- * Maxim's "SN76489 notes" in
|
||||
-- http://www.smspower.org/maxim/docs/SN76489.txt
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_top is
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clock_en_i : in std_logic;
|
||||
res_n_i : in std_logic;
|
||||
ce_n_i : in std_logic;
|
||||
we_n_i : in std_logic;
|
||||
ready_o : out std_logic;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
aout_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_top;
|
||||
|
||||
architecture struct of sn76489_top is
|
||||
|
||||
signal clk_en_s : boolean;
|
||||
|
||||
signal tone1_we_s,
|
||||
tone2_we_s,
|
||||
tone3_we_s,
|
||||
noise_we_s : boolean;
|
||||
signal r2_s : std_logic;
|
||||
|
||||
signal tone1_s,
|
||||
tone2_s,
|
||||
tone3_s,
|
||||
noise_s : signed(0 to 7);
|
||||
|
||||
signal tone3_ff_s : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Clock Divider
|
||||
-----------------------------------------------------------------------------
|
||||
clock_div_b : entity work.sn76489_clock_div
|
||||
generic map (
|
||||
clock_div_16_g => clock_div_16_g
|
||||
)
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clock_en_i => clock_en_i,
|
||||
res_n_i => res_n_i,
|
||||
clk_en_o => clk_en_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Latch Control = CPU Interface
|
||||
-----------------------------------------------------------------------------
|
||||
latch_ctrl_b : entity work.sn76489_latch_ctrl
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
ce_n_i => ce_n_i,
|
||||
we_n_i => we_n_i,
|
||||
d_i => d_i,
|
||||
ready_o => ready_o,
|
||||
tone1_we_o => tone1_we_s,
|
||||
tone2_we_o => tone2_we_s,
|
||||
tone3_we_o => tone3_we_s,
|
||||
noise_we_o => noise_we_s,
|
||||
r2_o => r2_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 1
|
||||
-----------------------------------------------------------------------------
|
||||
tone1_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone1_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => open,
|
||||
tone_o => tone1_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 2
|
||||
-----------------------------------------------------------------------------
|
||||
tone2_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone2_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => open,
|
||||
tone_o => tone2_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 3
|
||||
-----------------------------------------------------------------------------
|
||||
tone3_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone3_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => tone3_ff_s,
|
||||
tone_o => tone3_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Noise Channel
|
||||
-----------------------------------------------------------------------------
|
||||
noise_b : entity work.sn76489_noise
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => noise_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
tone3_ff_i => tone3_ff_s,
|
||||
noise_o => noise_s
|
||||
);
|
||||
|
||||
|
||||
aout_o <= tone1_s + tone2_s + tone3_s + noise_s;
|
||||
|
||||
end struct;
|
||||
@@ -160,7 +160,6 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
||||
|
||||
# end ENTITY(Dorodon)
|
||||
# -------------------
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Dorodon.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_video_unit.vhd
|
||||
@@ -180,13 +179,7 @@ set_global_assignment -name VHDL_FILE rtl/ladybug_chutes.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_chute.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_char.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_addr_dec.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_top.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_tone.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_noise.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_latch_ctrl.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_clock_div.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_attenuator.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/ladybug_sound_unit.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_sound_unit.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_sprite_u.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_sprite_l.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_cpu3.vhd
|
||||
@@ -198,15 +191,12 @@ set_global_assignment -name VHDL_FILE rtl/ROM/prom_decrypt.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_3.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_2.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_1.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80a.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_Reg.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_Pack.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_MCode.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_ALU.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ttl_393.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ttl_175.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/spram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/dpram.vhd
|
||||
set_global_assignment -name QIP_FILE ../../../common/Sound/sn76489/sn76489.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name QIP_FILE rtl/pll.qip
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@@ -41,14 +41,16 @@ module Dorodon
|
||||
`include "rtl\build_id.v"
|
||||
|
||||
localparam CONF_STR = {
|
||||
"Dorodon;;",
|
||||
"Ladybug;;",
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scanlines,Off,25%,50%,75%;",
|
||||
"O5,Blend,Off,On;",
|
||||
"T6,Reset;",
|
||||
"T0,Reset;",
|
||||
"V,v1.10.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire rotate = status[2];
|
||||
|
||||
assign LED = 1;
|
||||
assign AUDIO_R = AUDIO_L;
|
||||
|
||||
@@ -68,17 +70,43 @@ wire [7:0] joystick_0;
|
||||
wire [7:0] joystick_1;
|
||||
wire scandoublerD;
|
||||
wire ypbpr;
|
||||
wire [10:0] ps2_key;
|
||||
reg [7:0] audio;
|
||||
wire hb, vb;
|
||||
wire no_csync;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
user_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
user_io(
|
||||
.clk_sys (clk_sys ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_CLK (SPI_SCK ),
|
||||
.SPI_SS_IO (CONF_DATA0 ),
|
||||
.SPI_MISO (SPI_DO ),
|
||||
.SPI_MOSI (SPI_DI ),
|
||||
.buttons (buttons ),
|
||||
.switches (switches ),
|
||||
.scandoubler_disable (scandoublerD),
|
||||
.ypbpr (ypbpr ),
|
||||
.no_csync (no_csync ),
|
||||
.key_strobe (key_strobe ),
|
||||
.key_pressed (key_pressed ),
|
||||
.key_code (key_code ),
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
|
||||
wire [8:0] audio;
|
||||
wire hb, vb;
|
||||
wire blankn = ~(hb | vb);
|
||||
wire ce_vid;
|
||||
wire hs, vs;
|
||||
wire ce_vid;
|
||||
wire hs, vs;
|
||||
wire [1:0] r,g,b;
|
||||
|
||||
ladybugt dorodon(
|
||||
ladybugt ladybug(
|
||||
.CLK_IN(clk_sys),
|
||||
.I_RESET(status[0] | status[6] | buttons[1]),
|
||||
.I_RESET(status[0] | buttons[1]),
|
||||
.O_PIXCE(ce_vid),
|
||||
.O_VIDEO_R(r),
|
||||
.O_VIDEO_G(g),
|
||||
@@ -88,15 +116,15 @@ ladybugt dorodon(
|
||||
.O_VBLANK(vb),
|
||||
.O_HBLANK(hb),
|
||||
.O_AUDIO(audio),
|
||||
.but_coin_s(~{1'b0,btn_coin}),
|
||||
.but_fire_s(~{1'b0,m_fire}),
|
||||
.but_bomb_s(~{1'b0,m_bomb}),
|
||||
.but_tilt_s(~{1'b0,1'b0}),
|
||||
.but_select_s(~{btn_two_players, btn_one_player}),
|
||||
.but_up_s(~{1'b0,m_up}),
|
||||
.but_down_s(~{1'b0,m_down}),
|
||||
.but_left_s(~{1'b0,m_left}),
|
||||
.but_right_s(~{1'b0,m_right})
|
||||
.but_coin_s(~{m_coin2,m_coin1}),
|
||||
.but_fire_s(~{m_fire2A,m_fireA}),
|
||||
.but_bomb_s(~{m_fire2B,m_fireB}),
|
||||
.but_tilt_s(~{m_tilt,m_tilt}),
|
||||
.but_select_s(~{m_two_players, m_one_player}),
|
||||
.but_up_s(~{m_up2,m_up}),
|
||||
.but_down_s(~{m_down2,m_down}),
|
||||
.but_left_s(~{m_left2,m_left}),
|
||||
.but_right_s(~{m_right2,m_right})
|
||||
);
|
||||
|
||||
mist_video #(.COLOR_DEPTH(2),.SD_HCNT_WIDTH(10)) mist_video(
|
||||
@@ -114,79 +142,40 @@ mist_video #(.COLOR_DEPTH(2),.SD_HCNT_WIDTH(10)) mist_video(
|
||||
.VGA_B(VGA_B),
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS),
|
||||
.rotate({1'b0,status[2]}),
|
||||
.rotate({1'b0,rotate}),
|
||||
.ce_divider(1'b1),
|
||||
.blend(status[5]),
|
||||
.scandoubler_disable(scandoublerD),
|
||||
.scanlines(status[4:3]),
|
||||
.ypbpr(ypbpr)
|
||||
.ypbpr(ypbpr),
|
||||
.no_csync(no_csync)
|
||||
);
|
||||
|
||||
user_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
user_io(
|
||||
.clk_sys (clk_sys ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_CLK (SPI_SCK ),
|
||||
.SPI_SS_IO (CONF_DATA0 ),
|
||||
.SPI_MISO (SPI_DO ),
|
||||
.SPI_MOSI (SPI_DI ),
|
||||
.buttons (buttons ),
|
||||
.switches (switches ),
|
||||
.scandoubler_disable (scandoublerD),
|
||||
.ypbpr (ypbpr ),
|
||||
.key_strobe (key_strobe ),
|
||||
.key_pressed (key_pressed ),
|
||||
.key_code (key_code ),
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
|
||||
dac dac(
|
||||
dac #(9) dac(
|
||||
.clk_i(clk_sys),
|
||||
.res_n_i(1),
|
||||
.dac_i({~audio[7], audio[6:0]}),
|
||||
.dac_i(audio),
|
||||
.dac_o(AUDIO_L)
|
||||
);
|
||||
|
||||
wire m_up = ~status[2] ? btn_right | joystick_0[0] | joystick_1[0] : btn_up | joystick_0[3] | joystick_1[3];
|
||||
wire m_down = ~status[2] ? btn_left | joystick_0[1] | joystick_1[1] : btn_down | joystick_0[2] | joystick_1[2];
|
||||
wire m_left = ~status[2] ? btn_up | joystick_0[3] | joystick_1[3] : btn_left | joystick_0[1] | joystick_1[1];
|
||||
wire m_right = ~status[2] ? btn_down | joystick_0[2] | joystick_1[2] : btn_right | joystick_0[0] | joystick_1[0];
|
||||
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
|
||||
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
|
||||
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
|
||||
|
||||
wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4];
|
||||
wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5];
|
||||
|
||||
reg btn_one_player = 0;
|
||||
reg btn_two_players = 0;
|
||||
reg btn_left = 0;
|
||||
reg btn_right = 0;
|
||||
reg btn_down = 0;
|
||||
reg btn_up = 0;
|
||||
reg btn_fire1 = 0;
|
||||
reg btn_fire2 = 0;
|
||||
reg btn_fire3 = 0;
|
||||
reg btn_coin = 0;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(key_strobe) begin
|
||||
case(key_code)
|
||||
'h75: btn_up <= key_pressed; // up
|
||||
'h72: btn_down <= key_pressed; // down
|
||||
'h6B: btn_left <= key_pressed; // left
|
||||
'h74: btn_right <= key_pressed; // right
|
||||
'h76: btn_coin <= key_pressed; // ESC
|
||||
'h05: btn_one_player <= key_pressed; // F1
|
||||
'h06: btn_two_players <= key_pressed; // F2
|
||||
'h14: btn_fire3 <= key_pressed; // ctrl
|
||||
'h11: btn_fire2 <= key_pressed; // alt
|
||||
'h29: btn_fire1 <= key_pressed; // Space
|
||||
endcase
|
||||
end
|
||||
end
|
||||
arcade_inputs inputs (
|
||||
.clk ( clk_sys ),
|
||||
.key_strobe ( key_strobe ),
|
||||
.key_pressed ( key_pressed ),
|
||||
.key_code ( key_code ),
|
||||
.joystick_0 ( joystick_0 ),
|
||||
.joystick_1 ( joystick_1 ),
|
||||
.rotate ( rotate ),
|
||||
.orientation ( 2'b01 ),
|
||||
.joyswap ( 1'b0 ),
|
||||
.oneplayer ( 1'b1 ),
|
||||
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
|
||||
.player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
|
||||
.player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
|
||||
);
|
||||
|
||||
endmodule
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,370 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0247
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
||||
--
|
||||
-- 0238 : Fixed zero flag for 16 bit SBC and ADC
|
||||
--
|
||||
-- 0240 : Added GB operations
|
||||
--
|
||||
-- 0242 : Cleanup
|
||||
--
|
||||
-- 0247 : Cleanup
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_ALU is
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_ALU;
|
||||
|
||||
architecture rtl of T80_ALU is
|
||||
|
||||
procedure AddSub(A : std_logic_vector;
|
||||
B : std_logic_vector;
|
||||
Sub : std_logic;
|
||||
Carry_In : std_logic;
|
||||
signal Res : out std_logic_vector;
|
||||
signal Carry : out std_logic) is
|
||||
|
||||
variable B_i : unsigned(A'length - 1 downto 0);
|
||||
variable Res_i : unsigned(A'length + 1 downto 0);
|
||||
begin
|
||||
if Sub = '1' then
|
||||
B_i := not unsigned(B);
|
||||
else
|
||||
B_i := unsigned(B);
|
||||
end if;
|
||||
|
||||
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
|
||||
Carry <= Res_i(A'length + 1);
|
||||
Res <= std_logic_vector(Res_i(A'length downto 1));
|
||||
end;
|
||||
|
||||
-- AddSub variables (temporary signals)
|
||||
signal UseCarry : std_logic;
|
||||
signal Carry7_v : std_logic;
|
||||
signal Overflow_v : std_logic;
|
||||
signal HalfCarry_v : std_logic;
|
||||
signal Carry_v : std_logic;
|
||||
signal Q_v : std_logic_vector(7 downto 0);
|
||||
|
||||
signal BitMask : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
with IR(5 downto 3) select BitMask <= "00000001" when "000",
|
||||
"00000010" when "001",
|
||||
"00000100" when "010",
|
||||
"00001000" when "011",
|
||||
"00010000" when "100",
|
||||
"00100000" when "101",
|
||||
"01000000" when "110",
|
||||
"10000000" when others;
|
||||
|
||||
UseCarry <= not ALU_Op(2) and ALU_Op(0);
|
||||
AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v);
|
||||
AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v);
|
||||
AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v);
|
||||
-- bug fix - parity flag is just parity for 8080, also overflow for Z80
|
||||
process (Carry_v, Carry7_v, Q_v)
|
||||
begin
|
||||
if(Mode=2) then
|
||||
OverFlow_v <= not (Q_v(0) xor Q_v(1) xor Q_v(2) xor Q_v(3) xor
|
||||
Q_v(4) xor Q_v(5) xor Q_v(6) xor Q_v(7)); else
|
||||
OverFlow_v <= Carry_v xor Carry7_v;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
|
||||
variable Q_t : std_logic_vector(7 downto 0);
|
||||
variable DAA_Q : unsigned(8 downto 0);
|
||||
begin
|
||||
Q_t := "--------";
|
||||
F_Out <= F_In;
|
||||
DAA_Q := "---------";
|
||||
case ALU_Op is
|
||||
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" =>
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_C) <= '0';
|
||||
case ALU_OP(2 downto 0) is
|
||||
when "000" | "001" => -- ADD, ADC
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_C) <= Carry_v;
|
||||
F_Out(Flag_H) <= HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "010" | "011" | "111" => -- SUB, SBC, CP
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_N) <= '1';
|
||||
F_Out(Flag_C) <= not Carry_v;
|
||||
F_Out(Flag_H) <= not HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "100" => -- AND
|
||||
Q_t(7 downto 0) := BusA and BusB;
|
||||
F_Out(Flag_H) <= '1';
|
||||
when "101" => -- XOR
|
||||
Q_t(7 downto 0) := BusA xor BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
when others => -- OR "110"
|
||||
Q_t(7 downto 0) := BusA or BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
end case;
|
||||
if ALU_Op(2 downto 0) = "111" then -- CP
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
else
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
end if;
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
if Z16 = '1' then
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC
|
||||
end if;
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
case ALU_Op(2 downto 0) is
|
||||
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP
|
||||
when others =>
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
end case;
|
||||
if Arith16 = '1' then
|
||||
F_Out(Flag_S) <= F_In(Flag_S);
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||
F_Out(Flag_P) <= F_In(Flag_P);
|
||||
end if;
|
||||
when "1100" =>
|
||||
-- DAA
|
||||
F_Out(Flag_H) <= F_In(Flag_H);
|
||||
F_Out(Flag_C) <= F_In(Flag_C);
|
||||
DAA_Q(7 downto 0) := unsigned(BusA);
|
||||
DAA_Q(8) := '0';
|
||||
if F_In(Flag_N) = '0' then
|
||||
-- After addition
|
||||
-- Alow > 9 or H = 1
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if (DAA_Q(3 downto 0) > 9) then
|
||||
F_Out(Flag_H) <= '1';
|
||||
else
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q := DAA_Q + 6;
|
||||
end if;
|
||||
-- new Ahigh > 9 or C = 1
|
||||
if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q + 96; -- 0x60
|
||||
end if;
|
||||
else
|
||||
-- After subtraction
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if DAA_Q(3 downto 0) > 5 then
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6;
|
||||
end if;
|
||||
if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q - 352; -- 0x160
|
||||
end if;
|
||||
end if;
|
||||
F_Out(Flag_X) <= DAA_Q(3);
|
||||
F_Out(Flag_Y) <= DAA_Q(5);
|
||||
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
|
||||
Q_t := std_logic_vector(DAA_Q(7 downto 0));
|
||||
if DAA_Q(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= DAA_Q(7);
|
||||
F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor
|
||||
DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7));
|
||||
when "1101" | "1110" =>
|
||||
-- RLD, RRD
|
||||
Q_t(7 downto 4) := BusA(7 downto 4);
|
||||
if ALU_Op(0) = '1' then
|
||||
Q_t(3 downto 0) := BusB(7 downto 4);
|
||||
else
|
||||
Q_t(3 downto 0) := BusB(3 downto 0);
|
||||
end if;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
when "1001" =>
|
||||
-- BIT
|
||||
Q_t(7 downto 0) := BusB and BitMask;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
F_Out(Flag_P) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
F_Out(Flag_P) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_H) <= '1';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= '0';
|
||||
F_Out(Flag_Y) <= '0';
|
||||
if IR(2 downto 0) /= "110" then
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
end if;
|
||||
when "1010" =>
|
||||
-- SET
|
||||
Q_t(7 downto 0) := BusB or BitMask;
|
||||
when "1011" =>
|
||||
-- RES
|
||||
Q_t(7 downto 0) := BusB and not BitMask;
|
||||
when "1000" =>
|
||||
-- ROT
|
||||
case IR(5 downto 3) is
|
||||
when "000" => -- RLC
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "010" => -- RL
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "001" => -- RRC
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(0);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "011" => -- RR
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "100" => -- SLA
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '0';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "110" => -- SLL (Undocumented) / SWAP
|
||||
if Mode = 3 then
|
||||
Q_t(7 downto 4) := BusA(3 downto 0);
|
||||
Q_t(3 downto 0) := BusA(7 downto 4);
|
||||
F_Out(Flag_C) <= '0';
|
||||
else
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '1';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
end if;
|
||||
when "101" => -- SRA
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when others => -- SRL
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := '0';
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
end case;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
if ISet = "00" then
|
||||
F_Out(Flag_P) <= F_In(Flag_P);
|
||||
F_Out(Flag_S) <= F_In(Flag_S);
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
Q <= Q_t;
|
||||
end process;
|
||||
end;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,220 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0242
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
package T80_Pack is
|
||||
|
||||
component T80
|
||||
generic(
|
||||
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
IORQ : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DInst : in std_logic_vector(7 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0);
|
||||
MC : out std_logic_vector(2 downto 0);
|
||||
TS : out std_logic_vector(2 downto 0);
|
||||
IntCycle_n : out std_logic;
|
||||
IntE : out std_logic;
|
||||
Stop : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_Reg
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_MCode
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
IR : in std_logic_vector(7 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
MCycle : in std_logic_vector(2 downto 0);
|
||||
F : in std_logic_vector(7 downto 0);
|
||||
NMICycle : in std_logic;
|
||||
IntCycle : in std_logic;
|
||||
XY_State : in std_logic_vector(1 downto 0);
|
||||
MCycles : out std_logic_vector(2 downto 0);
|
||||
TStates : out std_logic_vector(2 downto 0);
|
||||
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
|
||||
Inc_PC : out std_logic;
|
||||
Inc_WZ : out std_logic;
|
||||
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
|
||||
Read_To_Reg : out std_logic;
|
||||
Read_To_Acc : out std_logic;
|
||||
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
|
||||
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
|
||||
ALU_Op : out std_logic_vector(3 downto 0);
|
||||
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
|
||||
Save_ALU : out std_logic;
|
||||
PreserveC : out std_logic;
|
||||
Arith16 : out std_logic;
|
||||
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
|
||||
IORQ : out std_logic;
|
||||
Jump : out std_logic;
|
||||
JumpE : out std_logic;
|
||||
JumpXY : out std_logic;
|
||||
Call : out std_logic;
|
||||
RstP : out std_logic;
|
||||
LDZ : out std_logic;
|
||||
LDW : out std_logic;
|
||||
LDSPHL : out std_logic;
|
||||
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
|
||||
ExchangeDH : out std_logic;
|
||||
ExchangeRp : out std_logic;
|
||||
ExchangeAF : out std_logic;
|
||||
ExchangeRS : out std_logic;
|
||||
I_DJNZ : out std_logic;
|
||||
I_CPL : out std_logic;
|
||||
I_CCF : out std_logic;
|
||||
I_SCF : out std_logic;
|
||||
I_RETN : out std_logic;
|
||||
I_BT : out std_logic;
|
||||
I_BC : out std_logic;
|
||||
I_BTR : out std_logic;
|
||||
I_RLD : out std_logic;
|
||||
I_RRD : out std_logic;
|
||||
I_INRC : out std_logic;
|
||||
SetDI : out std_logic;
|
||||
SetEI : out std_logic;
|
||||
IMode : out std_logic_vector(1 downto 0);
|
||||
Halt : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
XYbit_undoc : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_ALU
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
end;
|
||||
@@ -1,114 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- T80 Registers, technology independent
|
||||
--
|
||||
-- Version : 0244
|
||||
--
|
||||
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t51/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0242 : Initial release
|
||||
--
|
||||
-- 0244 : Changed to single register file
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_Reg is
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_Reg;
|
||||
|
||||
architecture rtl of T80_Reg is
|
||||
|
||||
type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0);
|
||||
signal RegsH : Register_Image(0 to 7);
|
||||
signal RegsL : Register_Image(0 to 7);
|
||||
|
||||
begin
|
||||
|
||||
process (Clk)
|
||||
begin
|
||||
if Clk'event and Clk = '1' then
|
||||
if CEN = '1' then
|
||||
if WEH = '1' then
|
||||
RegsH(to_integer(unsigned(AddrA))) <= DIH;
|
||||
end if;
|
||||
if WEL = '1' then
|
||||
RegsL(to_integer(unsigned(AddrA))) <= DIL;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
DOAH <= RegsH(to_integer(unsigned(AddrA)));
|
||||
DOAL <= RegsL(to_integer(unsigned(AddrA)));
|
||||
DOBH <= RegsH(to_integer(unsigned(AddrB)));
|
||||
DOBL <= RegsL(to_integer(unsigned(AddrB)));
|
||||
DOCH <= RegsH(to_integer(unsigned(AddrC)));
|
||||
DOCL <= RegsL(to_integer(unsigned(AddrC)));
|
||||
|
||||
end;
|
||||
@@ -1,280 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core, asynchronous top level
|
||||
--
|
||||
-- Version : 0247
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0208 : First complete release
|
||||
--
|
||||
-- 0211 : Fixed interrupt cycle
|
||||
--
|
||||
-- 0235 : Updated for T80 interface change
|
||||
--
|
||||
-- 0238 : Updated for T80 interface change
|
||||
--
|
||||
-- 0240 : Updated for T80 interface change
|
||||
--
|
||||
-- 0242 : Updated for T80 interface change
|
||||
--
|
||||
-- 0247 : Fixed bus req/ack cycle
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use work.T80_Pack.all;
|
||||
|
||||
entity T80a is
|
||||
generic(
|
||||
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CLK_EN_SYS : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
MREQ_n : out std_logic;
|
||||
IORQ_n : out std_logic;
|
||||
RD_n : out std_logic;
|
||||
WR_n : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80a;
|
||||
|
||||
architecture rtl of T80a is
|
||||
|
||||
signal CEN : std_logic;
|
||||
signal Reset_s : std_logic;
|
||||
signal IntCycle_n : std_logic;
|
||||
signal IORQ : std_logic;
|
||||
signal NoRead : std_logic;
|
||||
signal Write : std_logic;
|
||||
signal MREQ : std_logic;
|
||||
signal MReq_Inhibit : std_logic;
|
||||
signal Req_Inhibit : std_logic;
|
||||
signal RD : std_logic;
|
||||
signal MREQ_n_i : std_logic;
|
||||
signal IORQ_n_i : std_logic;
|
||||
signal RD_n_i : std_logic;
|
||||
signal WR_n_i : std_logic;
|
||||
signal RFSH_n_i : std_logic;
|
||||
signal BUSAK_n_i : std_logic;
|
||||
signal A_i : std_logic_vector(15 downto 0);
|
||||
signal DO_Reg : std_logic_vector(7 downto 0);
|
||||
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
|
||||
signal Wait_s : std_logic;
|
||||
signal MCycle : std_logic_vector(2 downto 0);
|
||||
signal TState : std_logic_vector(2 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- clock enable supplied from clocking system
|
||||
CEN <= CLK_EN_SYS;
|
||||
|
||||
BUSAK_n <= BUSAK_n_i;
|
||||
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
|
||||
RD_n_i <= not RD or Req_Inhibit;
|
||||
|
||||
MREQ_n <= MREQ_n_i;
|
||||
IORQ_n <= IORQ_n_i;
|
||||
RD_n <= RD_n_i;
|
||||
WR_n <= WR_n_i;
|
||||
RFSH_n <= RFSH_n_i;
|
||||
A <= A_i;
|
||||
DO <= DO_Reg;
|
||||
|
||||
-- process (RESET_n, CLK_n)
|
||||
-- begin
|
||||
-- if RESET_n = '0' then
|
||||
-- Reset_s <= '0';
|
||||
-- elsif CLK_n'event and CLK_n = '1' then
|
||||
-- Reset_s <= '1';
|
||||
-- end if;
|
||||
-- end process;
|
||||
-- T80 reset input has already proper characteristics:
|
||||
-- * asynchronous assertion
|
||||
-- * deassertion synchronous to CLK_n (main_clk)
|
||||
Reset_s <= RESET_n;
|
||||
|
||||
u0 : T80
|
||||
generic map(
|
||||
Mode => Mode,
|
||||
IOWait => 1)
|
||||
port map(
|
||||
CEN => CEN,
|
||||
M1_n => M1_n,
|
||||
IORQ => IORQ,
|
||||
NoRead => NoRead,
|
||||
Write => Write,
|
||||
RFSH_n => RFSH_n_i,
|
||||
HALT_n => HALT_n,
|
||||
WAIT_n => Wait_s,
|
||||
INT_n => INT_n,
|
||||
NMI_n => NMI_n,
|
||||
RESET_n => Reset_s,
|
||||
BUSRQ_n => BUSRQ_n,
|
||||
BUSAK_n => BUSAK_n_i,
|
||||
CLK_n => CLK_n,
|
||||
A => A_i,
|
||||
DInst => DI,
|
||||
DI => DI_Reg,
|
||||
DO => DO_Reg,
|
||||
MC => MCycle,
|
||||
TS => TState,
|
||||
IntCycle_n => IntCycle_n);
|
||||
|
||||
process (CLK_n)
|
||||
begin
|
||||
if CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
Wait_s <= WAIT_n;
|
||||
if TState = "011" and BUSAK_n_i = '1' then
|
||||
DI_Reg <= to_x01(DI);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
WR_n_i <= '1';
|
||||
elsif CLK_n'event and CLK_n = '1' then
|
||||
if CEN = '1' then
|
||||
WR_n_i <= '1';
|
||||
if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
|
||||
WR_n_i <= not Write;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
Req_Inhibit <= '0';
|
||||
elsif CLK_n'event and CLK_n = '1' then
|
||||
if CEN = '1' then
|
||||
if MCycle = "001" and TState = "010" then
|
||||
Req_Inhibit <= '1';
|
||||
else
|
||||
Req_Inhibit <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
MReq_Inhibit <= '0';
|
||||
elsif CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
if MCycle = "001" and TState = "010" then
|
||||
MReq_Inhibit <= '1';
|
||||
else
|
||||
MReq_Inhibit <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '0';
|
||||
elsif CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
|
||||
if MCycle = "001" then
|
||||
if TState = "001" then
|
||||
RD <= IntCycle_n;
|
||||
MREQ <= IntCycle_n;
|
||||
IORQ_n_i <= IntCycle_n;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '1';
|
||||
end if;
|
||||
if TState = "100" then
|
||||
MREQ <= '0';
|
||||
end if;
|
||||
else
|
||||
if TState = "001" and NoRead = '0' then
|
||||
RD <= not Write;
|
||||
IORQ_n_i <= not IORQ;
|
||||
MREQ <= not IORQ;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end;
|
||||
@@ -65,7 +65,7 @@ port (
|
||||
O_PIXCE : out std_logic;
|
||||
|
||||
-- Audio Interface --------------------------------------------------------
|
||||
O_AUDIO : out signed(7 downto 0);
|
||||
O_AUDIO : out std_logic_vector( 8 downto 0);
|
||||
|
||||
but_coin_s : in std_logic_vector( 1 downto 0);
|
||||
but_fire_s : in std_logic_vector( 1 downto 0);
|
||||
@@ -160,8 +160,8 @@ begin
|
||||
rgb_b_o => O_VIDEO_B,
|
||||
hsync_n_o => O_HSYNC,
|
||||
vsync_n_o => O_VSYNC,
|
||||
vblank_o => O_VBLANK,
|
||||
hblank_o => O_HBLANK,
|
||||
vblank_o => O_VBLANK,
|
||||
hblank_o => O_HBLANK,
|
||||
audio_o => O_AUDIO,
|
||||
rom_cpu_a_o => rom_cpu_a_s,
|
||||
rom_cpu_d_i => rom_cpu_d_s,
|
||||
|
||||
@@ -119,14 +119,14 @@ begin
|
||||
-- "wait" has to be modelled with the clock enable because the T80 is not
|
||||
-- able to enlarge write accesses properly when they are delayed with "wait"
|
||||
t80_clk_en_s <= clk_en_4mhz_i and wait_n_s;
|
||||
T80a_b : entity work.T80a
|
||||
T80a_b : entity work.T80s
|
||||
generic map (
|
||||
Mode => 0
|
||||
)
|
||||
port map (
|
||||
RESET_n => res_n_i,
|
||||
CLK_n => clk_20mhz_i,
|
||||
CLK_EN_SYS => t80_clk_en_s,
|
||||
CLK => clk_20mhz_i,
|
||||
CEN => t80_clk_en_s,
|
||||
WAIT_n => wait_n_s,
|
||||
INT_n => int_n_s,
|
||||
NMI_n => nmi_n_s,
|
||||
|
||||
@@ -77,10 +77,10 @@ entity ladybug_machine is
|
||||
hsync_n_o : out std_logic;
|
||||
vsync_n_o : out std_logic;
|
||||
comp_sync_n_o : out std_logic;
|
||||
vblank_o : out std_logic;
|
||||
hblank_o : out std_logic;
|
||||
vblank_o : out std_logic;
|
||||
hblank_o : out std_logic;
|
||||
-- Audio Interface --------------------------------------------------------
|
||||
audio_o : out signed( 7 downto 0);
|
||||
audio_o : out std_logic_vector( 8 downto 0);
|
||||
-- CPU ROM Interface ------------------------------------------------------
|
||||
rom_cpu_a_o : out std_logic_vector(14 downto 0);
|
||||
rom_cpu_d_i : in std_logic_vector( 7 downto 0);
|
||||
|
||||
@@ -59,7 +59,7 @@ entity ladybug_sound_unit is
|
||||
wr_n_i : in std_logic;
|
||||
d_from_cpu_i : in std_logic_vector(7 downto 0);
|
||||
sound_wait_n_o : out std_logic;
|
||||
audio_o : out signed(7 downto 0)
|
||||
audio_o : out std_logic_vector(8 downto 0)
|
||||
);
|
||||
|
||||
end ladybug_sound_unit;
|
||||
@@ -70,7 +70,7 @@ architecture struct of ladybug_sound_unit is
|
||||
ready_c1_s : std_logic;
|
||||
|
||||
signal aout_b1_s,
|
||||
aout_c1_s : signed(7 downto 0);
|
||||
aout_c1_s : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
@@ -117,23 +117,7 @@ begin
|
||||
--
|
||||
-- Purpose:
|
||||
-- Mix the digital audio of the two SN76489 instances.
|
||||
-- Additional care is taken to avoid audio overfow/clipping.
|
||||
--
|
||||
mix: process (aout_b1_s,
|
||||
aout_c1_s)
|
||||
variable sum_v : signed(8 downto 0);
|
||||
begin
|
||||
sum_v := RESIZE(aout_b1_s, 9) + RESIZE(aout_c1_s, 9);
|
||||
|
||||
if sum_v > 127 then
|
||||
audio_o <= to_signed(127, 8);
|
||||
elsif sum_v < -128 then
|
||||
audio_o <= to_signed(-128, 8);
|
||||
else
|
||||
audio_o <= RESIZE(sum_v, 8);
|
||||
end if;
|
||||
|
||||
end process mix;
|
||||
audio_o <= std_logic_vector(unsigned('0'&aout_b1_s) + unsigned('0'&aout_c1_s));
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -1,143 +0,0 @@
|
||||
|
||||
An SN76489AN Compatible Implementation in VHDL
|
||||
==============================================
|
||||
Version: $Date: 2006/06/18 19:28:40 $
|
||||
|
||||
Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
See the file COPYING.
|
||||
|
||||
|
||||
Integration
|
||||
-----------
|
||||
|
||||
The sn76489 design exhibits all interface signals as the original chip. It
|
||||
only differs in the audio data output which is provided as an 8 bit signed
|
||||
vector instead of an analog output pin.
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
-- Set to '1' when operating the design in SN76489 mode. The primary clock
|
||||
-- input is divided by 16 in this variant. The data sheet mentions the
|
||||
-- SN76494 which contains a divide-by-2 clock input stage. Set the generic
|
||||
-- to '0' to enable this mode.
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
-- Primary clock input
|
||||
-- Drive with the target frequency or any integer multiple of it.
|
||||
|
||||
clock_en_i : in std_logic;
|
||||
-- Clock enable
|
||||
-- A '1' on this input qualifies a valid rising edge on clock_i. A '0'
|
||||
-- disables the next rising clock edge, effectivley halting the design
|
||||
-- until the next enabled rising clock edge.
|
||||
-- Can be used to run the core at lower frequencies than applied on
|
||||
-- clock_i.
|
||||
|
||||
res_n_i : in std_logic;
|
||||
-- Asynchronous low active reset input.
|
||||
-- Sets all sequential elements to a known state.
|
||||
|
||||
ce_n_i : in std_logic;
|
||||
-- Chip enable, low active.
|
||||
|
||||
we_n_i : in std_logic;
|
||||
-- Write enable, low active.
|
||||
|
||||
ready_o : out std_logic;
|
||||
-- Ready indication to microprocessor.
|
||||
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
-- Data input
|
||||
-- MSB 0 ... 7 LSB
|
||||
|
||||
aout_o : out signed(0 to 7)
|
||||
-- Audio output, signed vector
|
||||
-- MSB/SIGN 0 ... 7 LSB
|
||||
);
|
||||
|
||||
|
||||
Both 8 bit vector ports are defined (0 to 7) which declares bit 0 to be the
|
||||
MSB and bit 7 to be the LSB. This has been implemented according to TI's data
|
||||
sheet, thus all register/data format figures apply 1:1 for this design.
|
||||
Many systems will flip the system data bus bit wise before it is connected to
|
||||
this PSG. This is simply achieved with the following VHDL construct:
|
||||
|
||||
signal data_s : std_logic_vector(7 downto 0);
|
||||
|
||||
...
|
||||
d_i => data_s,
|
||||
...
|
||||
|
||||
d_i and data_s will be assigned from left to right, resulting in the expected
|
||||
bit assignment:
|
||||
|
||||
d_i data_s
|
||||
0 7
|
||||
1 6
|
||||
...
|
||||
6 1
|
||||
7 0
|
||||
|
||||
|
||||
As this design is fully synchronous, care has to be taken when the design
|
||||
replaces an SN76489 in asynchronous mode. No problems are expected when
|
||||
interfacing the code to other synchronous components.
|
||||
|
||||
|
||||
Design Hierarchy
|
||||
----------------
|
||||
|
||||
sn76489_top
|
||||
|
|
||||
+-- sn76489_latch_ctrl
|
||||
|
|
||||
+-- sn76489_clock_div
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
\-- sn76489_noise
|
||||
|
|
||||
\-- sn76489_attentuator
|
||||
|
||||
Resulting compilation sequence:
|
||||
|
||||
sn76489_comp_pack-p.vhd
|
||||
sn76489_top.vhd
|
||||
sn76489_latch_ctrl.vhd
|
||||
sn76489_latch_ctrl-c.vhd
|
||||
sn76489_clock_div.vhd
|
||||
sn76489_clock_div-c.vhd
|
||||
sn76489_attenuator.vhd
|
||||
sn76489_attenuator-c.vhd
|
||||
sn76489_tone.vhd
|
||||
sn76489_tone-c.vhd
|
||||
sn76489_noise.vhd
|
||||
sn76489_noise-c.vhd
|
||||
sn76489_top-c.vhd
|
||||
|
||||
Skip the files containing VHDL configurations when analyzing the code for
|
||||
synthesis.
|
||||
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
* TI Data sheet SN76489.pdf
|
||||
ftp://ftp.whtech.com/datasheets%20&%20manuals/SN76489.pdf
|
||||
|
||||
* John Kortink's article on the SN76489:
|
||||
http://web.inter.nl.net/users/J.Kortink/home/articles/sn76489/
|
||||
|
||||
* Maxim's "SN76489 notes" in
|
||||
http://www.smspower.org/maxim/docs/SN76489.txt
|
||||
@@ -1,114 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_attenuator.vhd,v 1.7 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Attenuator Module
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_attenuator is
|
||||
|
||||
port (
|
||||
attenuation_i : in std_logic_vector(0 to 3);
|
||||
factor_i : in signed(0 to 1);
|
||||
product_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_attenuator;
|
||||
|
||||
|
||||
architecture rtl of sn76489_attenuator is
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process attenuate
|
||||
--
|
||||
-- Purpose:
|
||||
-- Determine the attenuation and generate the resulting product.
|
||||
--
|
||||
-- The maximum attenuation value is 31 which corresponds to volume off.
|
||||
-- As described in the data sheet, the maximum "playing" attenuation is
|
||||
-- 28 = 16 + 8 + 4
|
||||
--
|
||||
-- The table for the volume constants is derived from the following
|
||||
-- formula (each step is 2dB voltage):
|
||||
-- v(0) = 31
|
||||
-- v(n+1) = v(n) * 0.79432823
|
||||
--
|
||||
attenuate: process (attenuation_i,
|
||||
factor_i)
|
||||
|
||||
type volume_t is array (natural range 0 to 15) of natural;
|
||||
constant volume_c : volume_t :=
|
||||
(31, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3, 2, 2, 2, 1, 0);
|
||||
|
||||
variable attenuation_v : unsigned(attenuation_i'range);
|
||||
variable volume_v : signed(product_o'range);
|
||||
|
||||
begin
|
||||
|
||||
attenuation_v := unsigned(attenuation_i);
|
||||
|
||||
-- volume look-up table
|
||||
volume_v := to_signed(volume_c(to_integer(attenuation_v)),
|
||||
product_o'length);
|
||||
|
||||
-- this replaces a multiplier and consumes a bit fewer
|
||||
-- resources
|
||||
case to_integer(factor_i) is
|
||||
when +1 =>
|
||||
product_o <= volume_v;
|
||||
when -1 =>
|
||||
product_o <= -volume_v;
|
||||
when others =>
|
||||
product_o <= (others => '0');
|
||||
end case;
|
||||
|
||||
end process attenuate;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
||||
@@ -1,134 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_clock_div.vhd,v 1.4 2005/10/10 21:51:27 arnim Exp $
|
||||
--
|
||||
-- Clock Divider Circuit
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity sn76489_clock_div is
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clock_en_i : in std_logic;
|
||||
res_n_i : in std_logic;
|
||||
clk_en_o : out boolean
|
||||
);
|
||||
|
||||
end sn76489_clock_div;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture rtl of sn76489_clock_div is
|
||||
|
||||
signal cnt_s,
|
||||
cnt_q : unsigned(3 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential counter element.
|
||||
--
|
||||
seq: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
cnt_q <= (others => '0');
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
cnt_q <= cnt_s;
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process comb
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the combinational counter logic.
|
||||
--
|
||||
comb: process (clock_en_i,
|
||||
cnt_q)
|
||||
begin
|
||||
-- default assignments
|
||||
cnt_s <= cnt_q;
|
||||
clk_en_o <= false;
|
||||
|
||||
if clock_en_i = '1' then
|
||||
|
||||
if cnt_q = 0 then
|
||||
clk_en_o <= true;
|
||||
|
||||
if clock_div_16_g = 1 then
|
||||
cnt_s <= to_unsigned(15, cnt_q'length);
|
||||
elsif clock_div_16_g = 0 then
|
||||
cnt_s <= to_unsigned( 1, cnt_q'length);
|
||||
else
|
||||
-- pragma translate_off
|
||||
assert false
|
||||
report "Generic clock_div_16_g must be either 0 or 1."
|
||||
severity failure;
|
||||
-- pragma translate_on
|
||||
end if;
|
||||
|
||||
else
|
||||
cnt_s <= cnt_q - 1;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end process comb;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
||||
@@ -1,138 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_latch_ctrl.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Latch Control Unit
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity sn76489_latch_ctrl is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
ce_n_i : in std_logic;
|
||||
we_n_i : in std_logic;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
ready_o : out std_logic;
|
||||
tone1_we_o : out boolean;
|
||||
tone2_we_o : out boolean;
|
||||
tone3_we_o : out boolean;
|
||||
noise_we_o : out boolean;
|
||||
r2_o : out std_logic
|
||||
);
|
||||
|
||||
end sn76489_latch_ctrl;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture rtl of sn76489_latch_ctrl is
|
||||
|
||||
signal reg_q : std_logic_vector(0 to 2);
|
||||
signal we_q : boolean;
|
||||
signal ready_q : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential elements.
|
||||
--
|
||||
seq: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
reg_q <= (others => '0');
|
||||
we_q <= false;
|
||||
ready_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
-- READY Flag Output ----------------------------------------------------
|
||||
if ready_q = '0' and we_q then
|
||||
if clk_en_i then
|
||||
-- assert READY when write access happened
|
||||
ready_q <= '1';
|
||||
end if;
|
||||
elsif ce_n_i = '1' then
|
||||
-- deassert READY when access has finished
|
||||
ready_q <= '0';
|
||||
end if;
|
||||
|
||||
-- Register Selection ---------------------------------------------------
|
||||
if ce_n_i = '0' and we_n_i = '0' then
|
||||
if clk_en_i then
|
||||
if d_i(0) = '1' then
|
||||
reg_q <= d_i(1 to 3);
|
||||
end if;
|
||||
we_q <= true;
|
||||
end if;
|
||||
else
|
||||
we_q <= false;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
tone1_we_o <= reg_q(0 to 1) = "00" and we_q;
|
||||
tone2_we_o <= reg_q(0 to 1) = "01" and we_q;
|
||||
tone3_we_o <= reg_q(0 to 1) = "10" and we_q;
|
||||
noise_we_o <= reg_q(0 to 1) = "11" and we_q;
|
||||
|
||||
r2_o <= reg_q(2);
|
||||
|
||||
ready_o <= ready_q
|
||||
when ce_n_i = '0' else
|
||||
'1';
|
||||
|
||||
end rtl;
|
||||
@@ -1,278 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_noise.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Noise Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_noise is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
we_i : in boolean;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
tone3_ff_i : in std_logic;
|
||||
noise_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_noise;
|
||||
|
||||
architecture rtl of sn76489_noise is
|
||||
|
||||
signal nf_q : std_logic_vector(0 to 1);
|
||||
signal fb_q : std_logic;
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 6);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal shift_source_s,
|
||||
shift_source_q : std_logic;
|
||||
signal shift_rise_edge_s : boolean;
|
||||
|
||||
signal lfsr_q : std_logic_vector(0 to 15);
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process cpu_regs
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the registers writable by the CPU.
|
||||
--
|
||||
cpu_regs: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
nf_q <= (others => '0');
|
||||
fb_q <= '0';
|
||||
a_q <= (others => '1');
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i and we_i then
|
||||
if r2_i = '0' then
|
||||
-- access to control register
|
||||
-- both access types can write to the control register!
|
||||
nf_q <= d_i(6 to 7);
|
||||
fb_q <= d_i(5);
|
||||
|
||||
else
|
||||
-- access to attenuator register
|
||||
-- both access types can write to the attenuator register!
|
||||
a_q <= d_i(4 to 7);
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process cpu_regs;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process freq_gen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the frequency generation components.
|
||||
--
|
||||
freq_gen: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
freq_cnt_q <= (others => '0');
|
||||
freq_ff_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if freq_cnt_q = 0 then
|
||||
-- reload frequency counter according to NF setting
|
||||
case nf_q is
|
||||
when "00" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 2 - 1, freq_cnt_q'length);
|
||||
when "01" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 4 - 1, freq_cnt_q'length);
|
||||
when "10" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 8 - 1, freq_cnt_q'length);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
freq_ff_q <= not freq_ff_q;
|
||||
|
||||
else
|
||||
-- decrement frequency counter
|
||||
freq_cnt_q <= freq_cnt_q - 1;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process freq_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Multiplex the source of the LFSR's shift enable
|
||||
-----------------------------------------------------------------------------
|
||||
shift_source_s <= tone3_ff_i
|
||||
when nf_q = "11" else
|
||||
freq_ff_q;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process rise_edge
|
||||
--
|
||||
-- Purpose:
|
||||
-- Detect the rising edge of the selected LFSR shift source.
|
||||
--
|
||||
rise_edge: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
shift_source_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
shift_source_q <= shift_source_s;
|
||||
end if;
|
||||
end if;
|
||||
end process rise_edge;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
-- detect rising edge on shift source
|
||||
shift_rise_edge_s <= shift_source_q = '0' and shift_source_s = '1';
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process lfsr
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the LFSR that generates noise.
|
||||
-- Note: This implementation shifts the register right, i.e. from index
|
||||
-- 15 towards 0 => bit 15 is the input, bit 0 is the output
|
||||
--
|
||||
-- Tapped bits according to MAME's sn76496.c, implemented in function
|
||||
-- lfsr_tapped_f.
|
||||
--
|
||||
lfsr: process (clock_i, res_n_i)
|
||||
|
||||
function lfsr_tapped_f(lfsr : in std_logic_vector) return std_logic is
|
||||
constant tapped_bits_c : std_logic_vector(0 to 15)
|
||||
-- tapped bits are 0, 2, 15
|
||||
:= "1010000000000001";
|
||||
variable parity_v : std_logic;
|
||||
begin
|
||||
parity_v := '0';
|
||||
|
||||
for idx in lfsr'low to lfsr'high loop
|
||||
parity_v := parity_v xor (lfsr(idx) and tapped_bits_c(idx));
|
||||
end loop;
|
||||
|
||||
return parity_v;
|
||||
end;
|
||||
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
-- reset LFSR to "0000000000000001"
|
||||
lfsr_q <= (others => '0');
|
||||
lfsr_q(lfsr_q'right) <= '1';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if we_i and r2_i = '0' then
|
||||
-- write to noise register
|
||||
-- -> reset LFSR
|
||||
lfsr_q <= (others => '0');
|
||||
lfsr_q(lfsr_q'right) <= '1';
|
||||
|
||||
elsif shift_rise_edge_s then
|
||||
|
||||
-- shift LFSR left towards MSB
|
||||
for idx in lfsr_q'right-1 downto lfsr_q'left loop
|
||||
lfsr_q(idx) <= lfsr_q(idx+1);
|
||||
end loop;
|
||||
|
||||
-- determine input bit
|
||||
if fb_q = '0' then
|
||||
-- "Periodic" Noise
|
||||
-- -> input to LFSR is output
|
||||
lfsr_q(lfsr_q'right) <= lfsr_q(lfsr_q'left);
|
||||
else
|
||||
-- "White" Noise
|
||||
-- -> input to LFSR is parity of tapped bits
|
||||
lfsr_q(lfsr_q'right) <= lfsr_tapped_f(lfsr_q);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process lfsr;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map output of LFSR to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when lfsr_q(0) = '1' else
|
||||
to_signed( 0, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The attenuator itself
|
||||
-----------------------------------------------------------------------------
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
product_o => noise_o
|
||||
);
|
||||
|
||||
end rtl;
|
||||
@@ -1,188 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_tone.vhd,v 1.5 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Tone Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_tone is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
we_i : in boolean;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
ff_o : out std_logic;
|
||||
tone_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_tone;
|
||||
|
||||
architecture rtl of sn76489_tone is
|
||||
|
||||
signal f_q : std_logic_vector(0 to 9);
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 9);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
|
||||
function all_zero(a : in std_logic_vector) return boolean is
|
||||
variable result_v : boolean;
|
||||
begin
|
||||
result_v := true;
|
||||
|
||||
for idx in a'low to a'high loop
|
||||
if a(idx) /= '0' then
|
||||
result_v := false;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return result_v;
|
||||
end;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process cpu_regs
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the registers writable by the CPU.
|
||||
--
|
||||
cpu_regs: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
f_q <= (others => '0');
|
||||
a_q <= (others => '1');
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i and we_i then
|
||||
if r2_i = '0' then
|
||||
-- access to frequency register
|
||||
if d_i(0) = '0' then
|
||||
f_q(0 to 5) <= d_i(2 to 7);
|
||||
else
|
||||
f_q(6 to 9) <= d_i(4 to 7);
|
||||
end if;
|
||||
|
||||
else
|
||||
-- access to attenuator register
|
||||
-- both access types can write to the attenuator register!
|
||||
a_q <= d_i(4 to 7);
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process cpu_regs;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process freq_gen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the frequency generation components.
|
||||
--
|
||||
freq_gen: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
freq_cnt_q <= (others => '0');
|
||||
freq_ff_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if freq_cnt_q = 0 then
|
||||
-- update counter from frequency register
|
||||
freq_cnt_q <= unsigned(f_q);
|
||||
|
||||
-- and toggle the frequency flip-flop if enabled
|
||||
if not all_zero(f_q) then
|
||||
freq_ff_q <= not freq_ff_q;
|
||||
else
|
||||
-- if frequency setting is 0, then keep flip-flop at +1
|
||||
freq_ff_q <= '1';
|
||||
end if;
|
||||
|
||||
else
|
||||
-- decrement frequency counter
|
||||
freq_cnt_q <= freq_cnt_q - 1;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process freq_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map frequency flip-flop to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when freq_ff_q = '1' else
|
||||
to_signed(-1, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The attenuator itself
|
||||
-----------------------------------------------------------------------------
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
product_o => tone_o
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
ff_o <= freq_ff_q;
|
||||
|
||||
end rtl;
|
||||
@@ -1,200 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_top.vhd,v 1.9 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Chip Toplevel
|
||||
--
|
||||
-- References:
|
||||
--
|
||||
-- * TI Data sheet SN76489.pdf
|
||||
-- ftp://ftp.whtech.com/datasheets%20&%20manuals/SN76489.pdf
|
||||
--
|
||||
-- * John Kortink's article on the SN76489:
|
||||
-- http://web.inter.nl.net/users/J.Kortink/home/articles/sn76489/
|
||||
--
|
||||
-- * Maxim's "SN76489 notes" in
|
||||
-- http://www.smspower.org/maxim/docs/SN76489.txt
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_top is
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clock_en_i : in std_logic;
|
||||
res_n_i : in std_logic;
|
||||
ce_n_i : in std_logic;
|
||||
we_n_i : in std_logic;
|
||||
ready_o : out std_logic;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
aout_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_top;
|
||||
|
||||
architecture struct of sn76489_top is
|
||||
|
||||
signal clk_en_s : boolean;
|
||||
|
||||
signal tone1_we_s,
|
||||
tone2_we_s,
|
||||
tone3_we_s,
|
||||
noise_we_s : boolean;
|
||||
signal r2_s : std_logic;
|
||||
|
||||
signal tone1_s,
|
||||
tone2_s,
|
||||
tone3_s,
|
||||
noise_s : signed(0 to 7);
|
||||
|
||||
signal tone3_ff_s : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Clock Divider
|
||||
-----------------------------------------------------------------------------
|
||||
clock_div_b : entity work.sn76489_clock_div
|
||||
generic map (
|
||||
clock_div_16_g => clock_div_16_g
|
||||
)
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clock_en_i => clock_en_i,
|
||||
res_n_i => res_n_i,
|
||||
clk_en_o => clk_en_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Latch Control = CPU Interface
|
||||
-----------------------------------------------------------------------------
|
||||
latch_ctrl_b : entity work.sn76489_latch_ctrl
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
ce_n_i => ce_n_i,
|
||||
we_n_i => we_n_i,
|
||||
d_i => d_i,
|
||||
ready_o => ready_o,
|
||||
tone1_we_o => tone1_we_s,
|
||||
tone2_we_o => tone2_we_s,
|
||||
tone3_we_o => tone3_we_s,
|
||||
noise_we_o => noise_we_s,
|
||||
r2_o => r2_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 1
|
||||
-----------------------------------------------------------------------------
|
||||
tone1_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone1_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => open,
|
||||
tone_o => tone1_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 2
|
||||
-----------------------------------------------------------------------------
|
||||
tone2_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone2_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => open,
|
||||
tone_o => tone2_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 3
|
||||
-----------------------------------------------------------------------------
|
||||
tone3_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone3_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => tone3_ff_s,
|
||||
tone_o => tone3_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Noise Channel
|
||||
-----------------------------------------------------------------------------
|
||||
noise_b : entity work.sn76489_noise
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => noise_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
tone3_ff_i => tone3_ff_s,
|
||||
noise_o => noise_s
|
||||
);
|
||||
|
||||
|
||||
aout_o <= tone1_s + tone2_s + tone3_s + noise_s;
|
||||
|
||||
end struct;
|
||||
@@ -137,16 +137,17 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
||||
|
||||
# Incremental Compilation Assignments
|
||||
# ===================================
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
|
||||
# end DESIGN_PARTITION(Top)
|
||||
# -------------------------
|
||||
|
||||
# end ENTITY(LadyBug)
|
||||
# -------------------
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name ENABLE_SIGNALTAP OFF
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE output_files/snd.stp
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/LadyBug.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_video_unit.vhd
|
||||
@@ -166,13 +167,7 @@ set_global_assignment -name VHDL_FILE rtl/ladybug_chutes.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_chute.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_char.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_addr_dec.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/ladybug_sound_unit.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_top.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_tone.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_noise.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_latch_ctrl.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_clock_div.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_attenuator.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_sound_unit.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_sprite_u.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_sprite_l.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_cpu3.vhd
|
||||
@@ -184,15 +179,12 @@ set_global_assignment -name VHDL_FILE rtl/ROM/prom_decrypt.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_3.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_2.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_1.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80a.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_Reg.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_Pack.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_MCode.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_ALU.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ttl_393.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ttl_175.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/spram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/dpram.vhd
|
||||
set_global_assignment -name QIP_FILE rtl/pll.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/Sound/sn76489/sn76489.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@@ -45,10 +45,12 @@ localparam CONF_STR = {
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scanlines,Off,25%,50%,75%;",
|
||||
"O5,Blend,Off,On;",
|
||||
"T6,Reset;",
|
||||
"T0,Reset;",
|
||||
"V,v1.10.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire rotate = status[2];
|
||||
|
||||
assign LED = 1;
|
||||
assign AUDIO_R = AUDIO_L;
|
||||
|
||||
@@ -68,17 +70,43 @@ wire [7:0] joystick_0;
|
||||
wire [7:0] joystick_1;
|
||||
wire scandoublerD;
|
||||
wire ypbpr;
|
||||
wire [10:0] ps2_key;
|
||||
reg [7:0] audio;
|
||||
wire hb, vb;
|
||||
wire no_csync;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
user_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
user_io(
|
||||
.clk_sys (clk_sys ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_CLK (SPI_SCK ),
|
||||
.SPI_SS_IO (CONF_DATA0 ),
|
||||
.SPI_MISO (SPI_DO ),
|
||||
.SPI_MOSI (SPI_DI ),
|
||||
.buttons (buttons ),
|
||||
.switches (switches ),
|
||||
.scandoubler_disable (scandoublerD),
|
||||
.ypbpr (ypbpr ),
|
||||
.no_csync (no_csync ),
|
||||
.key_strobe (key_strobe ),
|
||||
.key_pressed (key_pressed ),
|
||||
.key_code (key_code ),
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
|
||||
wire [8:0] audio;
|
||||
wire hb, vb;
|
||||
wire blankn = ~(hb | vb);
|
||||
wire ce_vid;
|
||||
wire hs, vs;
|
||||
wire ce_vid;
|
||||
wire hs, vs;
|
||||
wire [1:0] r,g,b;
|
||||
|
||||
ladybugt ladybug(
|
||||
.CLK_IN(clk_sys),
|
||||
.I_RESET(status[0] | status[6] | buttons[1]),
|
||||
.I_RESET(status[0] | buttons[1]),
|
||||
.O_PIXCE(ce_vid),
|
||||
.O_VIDEO_R(r),
|
||||
.O_VIDEO_G(g),
|
||||
@@ -88,17 +116,17 @@ ladybugt ladybug(
|
||||
.O_VBLANK(vb),
|
||||
.O_HBLANK(hb),
|
||||
.O_AUDIO(audio),
|
||||
.but_coin_s(~{1'b0,btn_coin}),
|
||||
.but_fire_s(~{1'b0,m_fire}),
|
||||
.but_bomb_s(~{1'b0,m_bomb}),
|
||||
.but_tilt_s(~{1'b0,1'b0}),
|
||||
.but_select_s(~{btn_two_players, btn_one_player}),
|
||||
.but_up_s(~{1'b0,m_up}),
|
||||
.but_down_s(~{1'b0,m_down}),
|
||||
.but_left_s(~{1'b0,m_left}),
|
||||
.but_right_s(~{1'b0,m_right})
|
||||
.but_coin_s(~{m_coin2,m_coin1}),
|
||||
.but_fire_s(~{m_fire2A,m_fireA}),
|
||||
.but_bomb_s(~{m_fire2B,m_fireB}),
|
||||
.but_tilt_s(~{m_tilt,m_tilt}),
|
||||
.but_select_s(~{m_two_players, m_one_player}),
|
||||
.but_up_s(~{m_up2,m_up}),
|
||||
.but_down_s(~{m_down2,m_down}),
|
||||
.but_left_s(~{m_left2,m_left}),
|
||||
.but_right_s(~{m_right2,m_right})
|
||||
);
|
||||
|
||||
|
||||
mist_video #(.COLOR_DEPTH(2),.SD_HCNT_WIDTH(10)) mist_video(
|
||||
.clk_sys(clk_sys),
|
||||
.SPI_SCK(SPI_SCK),
|
||||
@@ -114,84 +142,40 @@ mist_video #(.COLOR_DEPTH(2),.SD_HCNT_WIDTH(10)) mist_video(
|
||||
.VGA_B(VGA_B),
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS),
|
||||
.rotate({1'b0,status[2]}),
|
||||
.rotate({1'b0,rotate}),
|
||||
.ce_divider(1'b1),
|
||||
.blend(status[5]),
|
||||
.scandoubler_disable(scandoublerD),
|
||||
.scanlines(status[4:3]),
|
||||
.ypbpr(ypbpr)
|
||||
.ypbpr(ypbpr),
|
||||
.no_csync(no_csync)
|
||||
);
|
||||
|
||||
user_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
user_io(
|
||||
.clk_sys (clk_sys ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_CLK (SPI_SCK ),
|
||||
.SPI_SS_IO (CONF_DATA0 ),
|
||||
.SPI_MISO (SPI_DO ),
|
||||
.SPI_MOSI (SPI_DI ),
|
||||
.buttons (buttons ),
|
||||
.switches (switches ),
|
||||
.scandoubler_disable (scandoublerD),
|
||||
.ypbpr (ypbpr ),
|
||||
.key_strobe (key_strobe ),
|
||||
.key_pressed (key_pressed ),
|
||||
.key_code (key_code ),
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
|
||||
dac dac(
|
||||
dac #(9) dac(
|
||||
.clk_i(clk_sys),
|
||||
.res_n_i(1),
|
||||
.dac_i({~audio[7], audio[6:0]}),
|
||||
.dac_i(audio),
|
||||
.dac_o(AUDIO_L)
|
||||
);
|
||||
|
||||
//wire m_up = status[2] ? kbjoy[7] | joystick_0[0] | joystick_1[0] : kbjoy[4] | joystick_0[3] | joystick_1[3];
|
||||
//wire m_down = status[2] ? kbjoy[6] | joystick_0[1] | joystick_1[1] : kbjoy[5] | joystick_0[2] | joystick_1[2];
|
||||
//wire m_left = status[2] ? kbjoy[4] | joystick_0[3] | joystick_1[3] : kbjoy[6] | joystick_0[1] | joystick_1[1];
|
||||
//wire m_right = status[2] ? kbjoy[5] | joystick_0[2] | joystick_1[2] : kbjoy[7] | joystick_0[0] | joystick_1[0];
|
||||
|
||||
wire m_up = ~status[2] ? btn_right | joystick_0[0] | joystick_1[0] : btn_up | joystick_0[3] | joystick_1[3];
|
||||
wire m_down = ~status[2] ? btn_left | joystick_0[1] | joystick_1[1] : btn_down | joystick_0[2] | joystick_1[2];
|
||||
wire m_left = ~status[2] ? btn_up | joystick_0[3] | joystick_1[3] : btn_left | joystick_0[1] | joystick_1[1];
|
||||
wire m_right = ~status[2] ? btn_down | joystick_0[2] | joystick_1[2] : btn_right | joystick_0[0] | joystick_1[0];
|
||||
|
||||
wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4];
|
||||
wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5];
|
||||
|
||||
reg btn_one_player = 0;
|
||||
reg btn_two_players = 0;
|
||||
reg btn_left = 0;
|
||||
reg btn_right = 0;
|
||||
reg btn_down = 0;
|
||||
reg btn_up = 0;
|
||||
reg btn_fire1 = 0;
|
||||
reg btn_fire2 = 0;
|
||||
reg btn_fire3 = 0;
|
||||
reg btn_coin = 0;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(key_strobe) begin
|
||||
case(key_code)
|
||||
'h75: btn_up <= key_pressed; // up
|
||||
'h72: btn_down <= key_pressed; // down
|
||||
'h6B: btn_left <= key_pressed; // left
|
||||
'h74: btn_right <= key_pressed; // right
|
||||
'h76: btn_coin <= key_pressed; // ESC
|
||||
'h05: btn_one_player <= key_pressed; // F1
|
||||
'h06: btn_two_players <= key_pressed; // F2
|
||||
'h14: btn_fire3 <= key_pressed; // ctrl
|
||||
'h11: btn_fire2 <= key_pressed; // alt
|
||||
'h29: btn_fire1 <= key_pressed; // Space
|
||||
endcase
|
||||
end
|
||||
end
|
||||
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
|
||||
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
|
||||
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
|
||||
|
||||
arcade_inputs inputs (
|
||||
.clk ( clk_sys ),
|
||||
.key_strobe ( key_strobe ),
|
||||
.key_pressed ( key_pressed ),
|
||||
.key_code ( key_code ),
|
||||
.joystick_0 ( joystick_0 ),
|
||||
.joystick_1 ( joystick_1 ),
|
||||
.rotate ( rotate ),
|
||||
.orientation ( 2'b01 ),
|
||||
.joyswap ( 1'b0 ),
|
||||
.oneplayer ( 1'b1 ),
|
||||
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
|
||||
.player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
|
||||
.player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
|
||||
);
|
||||
|
||||
endmodule
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,370 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0247
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
||||
--
|
||||
-- 0238 : Fixed zero flag for 16 bit SBC and ADC
|
||||
--
|
||||
-- 0240 : Added GB operations
|
||||
--
|
||||
-- 0242 : Cleanup
|
||||
--
|
||||
-- 0247 : Cleanup
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_ALU is
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_ALU;
|
||||
|
||||
architecture rtl of T80_ALU is
|
||||
|
||||
procedure AddSub(A : std_logic_vector;
|
||||
B : std_logic_vector;
|
||||
Sub : std_logic;
|
||||
Carry_In : std_logic;
|
||||
signal Res : out std_logic_vector;
|
||||
signal Carry : out std_logic) is
|
||||
|
||||
variable B_i : unsigned(A'length - 1 downto 0);
|
||||
variable Res_i : unsigned(A'length + 1 downto 0);
|
||||
begin
|
||||
if Sub = '1' then
|
||||
B_i := not unsigned(B);
|
||||
else
|
||||
B_i := unsigned(B);
|
||||
end if;
|
||||
|
||||
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
|
||||
Carry <= Res_i(A'length + 1);
|
||||
Res <= std_logic_vector(Res_i(A'length downto 1));
|
||||
end;
|
||||
|
||||
-- AddSub variables (temporary signals)
|
||||
signal UseCarry : std_logic;
|
||||
signal Carry7_v : std_logic;
|
||||
signal Overflow_v : std_logic;
|
||||
signal HalfCarry_v : std_logic;
|
||||
signal Carry_v : std_logic;
|
||||
signal Q_v : std_logic_vector(7 downto 0);
|
||||
|
||||
signal BitMask : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
with IR(5 downto 3) select BitMask <= "00000001" when "000",
|
||||
"00000010" when "001",
|
||||
"00000100" when "010",
|
||||
"00001000" when "011",
|
||||
"00010000" when "100",
|
||||
"00100000" when "101",
|
||||
"01000000" when "110",
|
||||
"10000000" when others;
|
||||
|
||||
UseCarry <= not ALU_Op(2) and ALU_Op(0);
|
||||
AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v);
|
||||
AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v);
|
||||
AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v);
|
||||
-- bug fix - parity flag is just parity for 8080, also overflow for Z80
|
||||
process (Carry_v, Carry7_v, Q_v)
|
||||
begin
|
||||
if(Mode=2) then
|
||||
OverFlow_v <= not (Q_v(0) xor Q_v(1) xor Q_v(2) xor Q_v(3) xor
|
||||
Q_v(4) xor Q_v(5) xor Q_v(6) xor Q_v(7)); else
|
||||
OverFlow_v <= Carry_v xor Carry7_v;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
|
||||
variable Q_t : std_logic_vector(7 downto 0);
|
||||
variable DAA_Q : unsigned(8 downto 0);
|
||||
begin
|
||||
Q_t := "--------";
|
||||
F_Out <= F_In;
|
||||
DAA_Q := "---------";
|
||||
case ALU_Op is
|
||||
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" =>
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_C) <= '0';
|
||||
case ALU_OP(2 downto 0) is
|
||||
when "000" | "001" => -- ADD, ADC
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_C) <= Carry_v;
|
||||
F_Out(Flag_H) <= HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "010" | "011" | "111" => -- SUB, SBC, CP
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_N) <= '1';
|
||||
F_Out(Flag_C) <= not Carry_v;
|
||||
F_Out(Flag_H) <= not HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "100" => -- AND
|
||||
Q_t(7 downto 0) := BusA and BusB;
|
||||
F_Out(Flag_H) <= '1';
|
||||
when "101" => -- XOR
|
||||
Q_t(7 downto 0) := BusA xor BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
when others => -- OR "110"
|
||||
Q_t(7 downto 0) := BusA or BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
end case;
|
||||
if ALU_Op(2 downto 0) = "111" then -- CP
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
else
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
end if;
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
if Z16 = '1' then
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC
|
||||
end if;
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
case ALU_Op(2 downto 0) is
|
||||
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP
|
||||
when others =>
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
end case;
|
||||
if Arith16 = '1' then
|
||||
F_Out(Flag_S) <= F_In(Flag_S);
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||
F_Out(Flag_P) <= F_In(Flag_P);
|
||||
end if;
|
||||
when "1100" =>
|
||||
-- DAA
|
||||
F_Out(Flag_H) <= F_In(Flag_H);
|
||||
F_Out(Flag_C) <= F_In(Flag_C);
|
||||
DAA_Q(7 downto 0) := unsigned(BusA);
|
||||
DAA_Q(8) := '0';
|
||||
if F_In(Flag_N) = '0' then
|
||||
-- After addition
|
||||
-- Alow > 9 or H = 1
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if (DAA_Q(3 downto 0) > 9) then
|
||||
F_Out(Flag_H) <= '1';
|
||||
else
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q := DAA_Q + 6;
|
||||
end if;
|
||||
-- new Ahigh > 9 or C = 1
|
||||
if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q + 96; -- 0x60
|
||||
end if;
|
||||
else
|
||||
-- After subtraction
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if DAA_Q(3 downto 0) > 5 then
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6;
|
||||
end if;
|
||||
if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q - 352; -- 0x160
|
||||
end if;
|
||||
end if;
|
||||
F_Out(Flag_X) <= DAA_Q(3);
|
||||
F_Out(Flag_Y) <= DAA_Q(5);
|
||||
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
|
||||
Q_t := std_logic_vector(DAA_Q(7 downto 0));
|
||||
if DAA_Q(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= DAA_Q(7);
|
||||
F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor
|
||||
DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7));
|
||||
when "1101" | "1110" =>
|
||||
-- RLD, RRD
|
||||
Q_t(7 downto 4) := BusA(7 downto 4);
|
||||
if ALU_Op(0) = '1' then
|
||||
Q_t(3 downto 0) := BusB(7 downto 4);
|
||||
else
|
||||
Q_t(3 downto 0) := BusB(3 downto 0);
|
||||
end if;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
when "1001" =>
|
||||
-- BIT
|
||||
Q_t(7 downto 0) := BusB and BitMask;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
F_Out(Flag_P) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
F_Out(Flag_P) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_H) <= '1';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= '0';
|
||||
F_Out(Flag_Y) <= '0';
|
||||
if IR(2 downto 0) /= "110" then
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
end if;
|
||||
when "1010" =>
|
||||
-- SET
|
||||
Q_t(7 downto 0) := BusB or BitMask;
|
||||
when "1011" =>
|
||||
-- RES
|
||||
Q_t(7 downto 0) := BusB and not BitMask;
|
||||
when "1000" =>
|
||||
-- ROT
|
||||
case IR(5 downto 3) is
|
||||
when "000" => -- RLC
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "010" => -- RL
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "001" => -- RRC
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(0);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "011" => -- RR
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "100" => -- SLA
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '0';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "110" => -- SLL (Undocumented) / SWAP
|
||||
if Mode = 3 then
|
||||
Q_t(7 downto 4) := BusA(3 downto 0);
|
||||
Q_t(3 downto 0) := BusA(7 downto 4);
|
||||
F_Out(Flag_C) <= '0';
|
||||
else
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '1';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
end if;
|
||||
when "101" => -- SRA
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when others => -- SRL
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := '0';
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
end case;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
if ISet = "00" then
|
||||
F_Out(Flag_P) <= F_In(Flag_P);
|
||||
F_Out(Flag_S) <= F_In(Flag_S);
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
Q <= Q_t;
|
||||
end process;
|
||||
end;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,220 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0242
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
package T80_Pack is
|
||||
|
||||
component T80
|
||||
generic(
|
||||
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
IORQ : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DInst : in std_logic_vector(7 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0);
|
||||
MC : out std_logic_vector(2 downto 0);
|
||||
TS : out std_logic_vector(2 downto 0);
|
||||
IntCycle_n : out std_logic;
|
||||
IntE : out std_logic;
|
||||
Stop : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_Reg
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_MCode
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
IR : in std_logic_vector(7 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
MCycle : in std_logic_vector(2 downto 0);
|
||||
F : in std_logic_vector(7 downto 0);
|
||||
NMICycle : in std_logic;
|
||||
IntCycle : in std_logic;
|
||||
XY_State : in std_logic_vector(1 downto 0);
|
||||
MCycles : out std_logic_vector(2 downto 0);
|
||||
TStates : out std_logic_vector(2 downto 0);
|
||||
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
|
||||
Inc_PC : out std_logic;
|
||||
Inc_WZ : out std_logic;
|
||||
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
|
||||
Read_To_Reg : out std_logic;
|
||||
Read_To_Acc : out std_logic;
|
||||
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
|
||||
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
|
||||
ALU_Op : out std_logic_vector(3 downto 0);
|
||||
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
|
||||
Save_ALU : out std_logic;
|
||||
PreserveC : out std_logic;
|
||||
Arith16 : out std_logic;
|
||||
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
|
||||
IORQ : out std_logic;
|
||||
Jump : out std_logic;
|
||||
JumpE : out std_logic;
|
||||
JumpXY : out std_logic;
|
||||
Call : out std_logic;
|
||||
RstP : out std_logic;
|
||||
LDZ : out std_logic;
|
||||
LDW : out std_logic;
|
||||
LDSPHL : out std_logic;
|
||||
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
|
||||
ExchangeDH : out std_logic;
|
||||
ExchangeRp : out std_logic;
|
||||
ExchangeAF : out std_logic;
|
||||
ExchangeRS : out std_logic;
|
||||
I_DJNZ : out std_logic;
|
||||
I_CPL : out std_logic;
|
||||
I_CCF : out std_logic;
|
||||
I_SCF : out std_logic;
|
||||
I_RETN : out std_logic;
|
||||
I_BT : out std_logic;
|
||||
I_BC : out std_logic;
|
||||
I_BTR : out std_logic;
|
||||
I_RLD : out std_logic;
|
||||
I_RRD : out std_logic;
|
||||
I_INRC : out std_logic;
|
||||
SetDI : out std_logic;
|
||||
SetEI : out std_logic;
|
||||
IMode : out std_logic_vector(1 downto 0);
|
||||
Halt : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
XYbit_undoc : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_ALU
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
end;
|
||||
@@ -1,114 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- T80 Registers, technology independent
|
||||
--
|
||||
-- Version : 0244
|
||||
--
|
||||
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t51/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0242 : Initial release
|
||||
--
|
||||
-- 0244 : Changed to single register file
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_Reg is
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_Reg;
|
||||
|
||||
architecture rtl of T80_Reg is
|
||||
|
||||
type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0);
|
||||
signal RegsH : Register_Image(0 to 7);
|
||||
signal RegsL : Register_Image(0 to 7);
|
||||
|
||||
begin
|
||||
|
||||
process (Clk)
|
||||
begin
|
||||
if Clk'event and Clk = '1' then
|
||||
if CEN = '1' then
|
||||
if WEH = '1' then
|
||||
RegsH(to_integer(unsigned(AddrA))) <= DIH;
|
||||
end if;
|
||||
if WEL = '1' then
|
||||
RegsL(to_integer(unsigned(AddrA))) <= DIL;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
DOAH <= RegsH(to_integer(unsigned(AddrA)));
|
||||
DOAL <= RegsL(to_integer(unsigned(AddrA)));
|
||||
DOBH <= RegsH(to_integer(unsigned(AddrB)));
|
||||
DOBL <= RegsL(to_integer(unsigned(AddrB)));
|
||||
DOCH <= RegsH(to_integer(unsigned(AddrC)));
|
||||
DOCL <= RegsL(to_integer(unsigned(AddrC)));
|
||||
|
||||
end;
|
||||
@@ -1,280 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core, asynchronous top level
|
||||
--
|
||||
-- Version : 0247
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0208 : First complete release
|
||||
--
|
||||
-- 0211 : Fixed interrupt cycle
|
||||
--
|
||||
-- 0235 : Updated for T80 interface change
|
||||
--
|
||||
-- 0238 : Updated for T80 interface change
|
||||
--
|
||||
-- 0240 : Updated for T80 interface change
|
||||
--
|
||||
-- 0242 : Updated for T80 interface change
|
||||
--
|
||||
-- 0247 : Fixed bus req/ack cycle
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use work.T80_Pack.all;
|
||||
|
||||
entity T80a is
|
||||
generic(
|
||||
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CLK_EN_SYS : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
MREQ_n : out std_logic;
|
||||
IORQ_n : out std_logic;
|
||||
RD_n : out std_logic;
|
||||
WR_n : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80a;
|
||||
|
||||
architecture rtl of T80a is
|
||||
|
||||
signal CEN : std_logic;
|
||||
signal Reset_s : std_logic;
|
||||
signal IntCycle_n : std_logic;
|
||||
signal IORQ : std_logic;
|
||||
signal NoRead : std_logic;
|
||||
signal Write : std_logic;
|
||||
signal MREQ : std_logic;
|
||||
signal MReq_Inhibit : std_logic;
|
||||
signal Req_Inhibit : std_logic;
|
||||
signal RD : std_logic;
|
||||
signal MREQ_n_i : std_logic;
|
||||
signal IORQ_n_i : std_logic;
|
||||
signal RD_n_i : std_logic;
|
||||
signal WR_n_i : std_logic;
|
||||
signal RFSH_n_i : std_logic;
|
||||
signal BUSAK_n_i : std_logic;
|
||||
signal A_i : std_logic_vector(15 downto 0);
|
||||
signal DO_Reg : std_logic_vector(7 downto 0);
|
||||
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
|
||||
signal Wait_s : std_logic;
|
||||
signal MCycle : std_logic_vector(2 downto 0);
|
||||
signal TState : std_logic_vector(2 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- clock enable supplied from clocking system
|
||||
CEN <= CLK_EN_SYS;
|
||||
|
||||
BUSAK_n <= BUSAK_n_i;
|
||||
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
|
||||
RD_n_i <= not RD or Req_Inhibit;
|
||||
|
||||
MREQ_n <= MREQ_n_i;
|
||||
IORQ_n <= IORQ_n_i;
|
||||
RD_n <= RD_n_i;
|
||||
WR_n <= WR_n_i;
|
||||
RFSH_n <= RFSH_n_i;
|
||||
A <= A_i;
|
||||
DO <= DO_Reg;
|
||||
|
||||
-- process (RESET_n, CLK_n)
|
||||
-- begin
|
||||
-- if RESET_n = '0' then
|
||||
-- Reset_s <= '0';
|
||||
-- elsif CLK_n'event and CLK_n = '1' then
|
||||
-- Reset_s <= '1';
|
||||
-- end if;
|
||||
-- end process;
|
||||
-- T80 reset input has already proper characteristics:
|
||||
-- * asynchronous assertion
|
||||
-- * deassertion synchronous to CLK_n (main_clk)
|
||||
Reset_s <= RESET_n;
|
||||
|
||||
u0 : T80
|
||||
generic map(
|
||||
Mode => Mode,
|
||||
IOWait => 1)
|
||||
port map(
|
||||
CEN => CEN,
|
||||
M1_n => M1_n,
|
||||
IORQ => IORQ,
|
||||
NoRead => NoRead,
|
||||
Write => Write,
|
||||
RFSH_n => RFSH_n_i,
|
||||
HALT_n => HALT_n,
|
||||
WAIT_n => Wait_s,
|
||||
INT_n => INT_n,
|
||||
NMI_n => NMI_n,
|
||||
RESET_n => Reset_s,
|
||||
BUSRQ_n => BUSRQ_n,
|
||||
BUSAK_n => BUSAK_n_i,
|
||||
CLK_n => CLK_n,
|
||||
A => A_i,
|
||||
DInst => DI,
|
||||
DI => DI_Reg,
|
||||
DO => DO_Reg,
|
||||
MC => MCycle,
|
||||
TS => TState,
|
||||
IntCycle_n => IntCycle_n);
|
||||
|
||||
process (CLK_n)
|
||||
begin
|
||||
if CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
Wait_s <= WAIT_n;
|
||||
if TState = "011" and BUSAK_n_i = '1' then
|
||||
DI_Reg <= to_x01(DI);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
WR_n_i <= '1';
|
||||
elsif CLK_n'event and CLK_n = '1' then
|
||||
if CEN = '1' then
|
||||
WR_n_i <= '1';
|
||||
if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
|
||||
WR_n_i <= not Write;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
Req_Inhibit <= '0';
|
||||
elsif CLK_n'event and CLK_n = '1' then
|
||||
if CEN = '1' then
|
||||
if MCycle = "001" and TState = "010" then
|
||||
Req_Inhibit <= '1';
|
||||
else
|
||||
Req_Inhibit <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
MReq_Inhibit <= '0';
|
||||
elsif CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
if MCycle = "001" and TState = "010" then
|
||||
MReq_Inhibit <= '1';
|
||||
else
|
||||
MReq_Inhibit <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '0';
|
||||
elsif CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
|
||||
if MCycle = "001" then
|
||||
if TState = "001" then
|
||||
RD <= IntCycle_n;
|
||||
MREQ <= IntCycle_n;
|
||||
IORQ_n_i <= IntCycle_n;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '1';
|
||||
end if;
|
||||
if TState = "100" then
|
||||
MREQ <= '0';
|
||||
end if;
|
||||
else
|
||||
if TState = "001" and NoRead = '0' then
|
||||
RD <= not Write;
|
||||
IORQ_n_i <= not IORQ;
|
||||
MREQ <= not IORQ;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end;
|
||||
@@ -65,7 +65,7 @@ port (
|
||||
O_PIXCE : out std_logic;
|
||||
|
||||
-- Audio Interface --------------------------------------------------------
|
||||
O_AUDIO : out signed(7 downto 0);
|
||||
O_AUDIO : out std_logic_vector( 8 downto 0);
|
||||
|
||||
but_coin_s : in std_logic_vector( 1 downto 0);
|
||||
but_fire_s : in std_logic_vector( 1 downto 0);
|
||||
@@ -160,8 +160,8 @@ begin
|
||||
rgb_b_o => O_VIDEO_B,
|
||||
hsync_n_o => O_HSYNC,
|
||||
vsync_n_o => O_VSYNC,
|
||||
vblank_o => O_VBLANK,
|
||||
hblank_o => O_HBLANK,
|
||||
vblank_o => O_VBLANK,
|
||||
hblank_o => O_HBLANK,
|
||||
audio_o => O_AUDIO,
|
||||
rom_cpu_a_o => rom_cpu_a_s,
|
||||
rom_cpu_d_i => rom_cpu_d_s,
|
||||
|
||||
@@ -119,14 +119,14 @@ begin
|
||||
-- "wait" has to be modelled with the clock enable because the T80 is not
|
||||
-- able to enlarge write accesses properly when they are delayed with "wait"
|
||||
t80_clk_en_s <= clk_en_4mhz_i and wait_n_s;
|
||||
T80a_b : entity work.T80a
|
||||
T80a_b : entity work.T80s
|
||||
generic map (
|
||||
Mode => 0
|
||||
)
|
||||
port map (
|
||||
RESET_n => res_n_i,
|
||||
CLK_n => clk_20mhz_i,
|
||||
CLK_EN_SYS => t80_clk_en_s,
|
||||
CLK => clk_20mhz_i,
|
||||
CEN => t80_clk_en_s,
|
||||
WAIT_n => wait_n_s,
|
||||
INT_n => int_n_s,
|
||||
NMI_n => nmi_n_s,
|
||||
|
||||
@@ -77,10 +77,10 @@ entity ladybug_machine is
|
||||
hsync_n_o : out std_logic;
|
||||
vsync_n_o : out std_logic;
|
||||
comp_sync_n_o : out std_logic;
|
||||
vblank_o : out std_logic;
|
||||
hblank_o : out std_logic;
|
||||
vblank_o : out std_logic;
|
||||
hblank_o : out std_logic;
|
||||
-- Audio Interface --------------------------------------------------------
|
||||
audio_o : out signed( 7 downto 0);
|
||||
audio_o : out std_logic_vector( 8 downto 0);
|
||||
-- CPU ROM Interface ------------------------------------------------------
|
||||
rom_cpu_a_o : out std_logic_vector(14 downto 0);
|
||||
rom_cpu_d_i : in std_logic_vector( 7 downto 0);
|
||||
|
||||
@@ -59,7 +59,7 @@ entity ladybug_sound_unit is
|
||||
wr_n_i : in std_logic;
|
||||
d_from_cpu_i : in std_logic_vector(7 downto 0);
|
||||
sound_wait_n_o : out std_logic;
|
||||
audio_o : out signed(7 downto 0)
|
||||
audio_o : out std_logic_vector(8 downto 0)
|
||||
);
|
||||
|
||||
end ladybug_sound_unit;
|
||||
@@ -70,7 +70,7 @@ architecture struct of ladybug_sound_unit is
|
||||
ready_c1_s : std_logic;
|
||||
|
||||
signal aout_b1_s,
|
||||
aout_c1_s : signed(7 downto 0);
|
||||
aout_c1_s : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
@@ -117,23 +117,7 @@ begin
|
||||
--
|
||||
-- Purpose:
|
||||
-- Mix the digital audio of the two SN76489 instances.
|
||||
-- Additional care is taken to avoid audio overfow/clipping.
|
||||
--
|
||||
mix: process (aout_b1_s,
|
||||
aout_c1_s)
|
||||
variable sum_v : signed(8 downto 0);
|
||||
begin
|
||||
sum_v := RESIZE(aout_b1_s, 9) + RESIZE(aout_c1_s, 9);
|
||||
|
||||
if sum_v > 127 then
|
||||
audio_o <= to_signed(127, 8);
|
||||
elsif sum_v < -128 then
|
||||
audio_o <= to_signed(-128, 8);
|
||||
else
|
||||
audio_o <= RESIZE(sum_v, 8);
|
||||
end if;
|
||||
|
||||
end process mix;
|
||||
audio_o <= std_logic_vector(unsigned('0'&aout_b1_s) + unsigned('0'&aout_c1_s));
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -1,143 +0,0 @@
|
||||
|
||||
An SN76489AN Compatible Implementation in VHDL
|
||||
==============================================
|
||||
Version: $Date: 2006/06/18 19:28:40 $
|
||||
|
||||
Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
See the file COPYING.
|
||||
|
||||
|
||||
Integration
|
||||
-----------
|
||||
|
||||
The sn76489 design exhibits all interface signals as the original chip. It
|
||||
only differs in the audio data output which is provided as an 8 bit signed
|
||||
vector instead of an analog output pin.
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
-- Set to '1' when operating the design in SN76489 mode. The primary clock
|
||||
-- input is divided by 16 in this variant. The data sheet mentions the
|
||||
-- SN76494 which contains a divide-by-2 clock input stage. Set the generic
|
||||
-- to '0' to enable this mode.
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
-- Primary clock input
|
||||
-- Drive with the target frequency or any integer multiple of it.
|
||||
|
||||
clock_en_i : in std_logic;
|
||||
-- Clock enable
|
||||
-- A '1' on this input qualifies a valid rising edge on clock_i. A '0'
|
||||
-- disables the next rising clock edge, effectivley halting the design
|
||||
-- until the next enabled rising clock edge.
|
||||
-- Can be used to run the core at lower frequencies than applied on
|
||||
-- clock_i.
|
||||
|
||||
res_n_i : in std_logic;
|
||||
-- Asynchronous low active reset input.
|
||||
-- Sets all sequential elements to a known state.
|
||||
|
||||
ce_n_i : in std_logic;
|
||||
-- Chip enable, low active.
|
||||
|
||||
we_n_i : in std_logic;
|
||||
-- Write enable, low active.
|
||||
|
||||
ready_o : out std_logic;
|
||||
-- Ready indication to microprocessor.
|
||||
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
-- Data input
|
||||
-- MSB 0 ... 7 LSB
|
||||
|
||||
aout_o : out signed(0 to 7)
|
||||
-- Audio output, signed vector
|
||||
-- MSB/SIGN 0 ... 7 LSB
|
||||
);
|
||||
|
||||
|
||||
Both 8 bit vector ports are defined (0 to 7) which declares bit 0 to be the
|
||||
MSB and bit 7 to be the LSB. This has been implemented according to TI's data
|
||||
sheet, thus all register/data format figures apply 1:1 for this design.
|
||||
Many systems will flip the system data bus bit wise before it is connected to
|
||||
this PSG. This is simply achieved with the following VHDL construct:
|
||||
|
||||
signal data_s : std_logic_vector(7 downto 0);
|
||||
|
||||
...
|
||||
d_i => data_s,
|
||||
...
|
||||
|
||||
d_i and data_s will be assigned from left to right, resulting in the expected
|
||||
bit assignment:
|
||||
|
||||
d_i data_s
|
||||
0 7
|
||||
1 6
|
||||
...
|
||||
6 1
|
||||
7 0
|
||||
|
||||
|
||||
As this design is fully synchronous, care has to be taken when the design
|
||||
replaces an SN76489 in asynchronous mode. No problems are expected when
|
||||
interfacing the code to other synchronous components.
|
||||
|
||||
|
||||
Design Hierarchy
|
||||
----------------
|
||||
|
||||
sn76489_top
|
||||
|
|
||||
+-- sn76489_latch_ctrl
|
||||
|
|
||||
+-- sn76489_clock_div
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
\-- sn76489_noise
|
||||
|
|
||||
\-- sn76489_attentuator
|
||||
|
||||
Resulting compilation sequence:
|
||||
|
||||
sn76489_comp_pack-p.vhd
|
||||
sn76489_top.vhd
|
||||
sn76489_latch_ctrl.vhd
|
||||
sn76489_latch_ctrl-c.vhd
|
||||
sn76489_clock_div.vhd
|
||||
sn76489_clock_div-c.vhd
|
||||
sn76489_attenuator.vhd
|
||||
sn76489_attenuator-c.vhd
|
||||
sn76489_tone.vhd
|
||||
sn76489_tone-c.vhd
|
||||
sn76489_noise.vhd
|
||||
sn76489_noise-c.vhd
|
||||
sn76489_top-c.vhd
|
||||
|
||||
Skip the files containing VHDL configurations when analyzing the code for
|
||||
synthesis.
|
||||
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
* TI Data sheet SN76489.pdf
|
||||
ftp://ftp.whtech.com/datasheets%20&%20manuals/SN76489.pdf
|
||||
|
||||
* John Kortink's article on the SN76489:
|
||||
http://web.inter.nl.net/users/J.Kortink/home/articles/sn76489/
|
||||
|
||||
* Maxim's "SN76489 notes" in
|
||||
http://www.smspower.org/maxim/docs/SN76489.txt
|
||||
@@ -1,114 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_attenuator.vhd,v 1.7 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Attenuator Module
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_attenuator is
|
||||
|
||||
port (
|
||||
attenuation_i : in std_logic_vector(0 to 3);
|
||||
factor_i : in signed(0 to 1);
|
||||
product_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_attenuator;
|
||||
|
||||
|
||||
architecture rtl of sn76489_attenuator is
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process attenuate
|
||||
--
|
||||
-- Purpose:
|
||||
-- Determine the attenuation and generate the resulting product.
|
||||
--
|
||||
-- The maximum attenuation value is 31 which corresponds to volume off.
|
||||
-- As described in the data sheet, the maximum "playing" attenuation is
|
||||
-- 28 = 16 + 8 + 4
|
||||
--
|
||||
-- The table for the volume constants is derived from the following
|
||||
-- formula (each step is 2dB voltage):
|
||||
-- v(0) = 31
|
||||
-- v(n+1) = v(n) * 0.79432823
|
||||
--
|
||||
attenuate: process (attenuation_i,
|
||||
factor_i)
|
||||
|
||||
type volume_t is array (natural range 0 to 15) of natural;
|
||||
constant volume_c : volume_t :=
|
||||
(31, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3, 2, 2, 2, 1, 0);
|
||||
|
||||
variable attenuation_v : unsigned(attenuation_i'range);
|
||||
variable volume_v : signed(product_o'range);
|
||||
|
||||
begin
|
||||
|
||||
attenuation_v := unsigned(attenuation_i);
|
||||
|
||||
-- volume look-up table
|
||||
volume_v := to_signed(volume_c(to_integer(attenuation_v)),
|
||||
product_o'length);
|
||||
|
||||
-- this replaces a multiplier and consumes a bit fewer
|
||||
-- resources
|
||||
case to_integer(factor_i) is
|
||||
when +1 =>
|
||||
product_o <= volume_v;
|
||||
when -1 =>
|
||||
product_o <= -volume_v;
|
||||
when others =>
|
||||
product_o <= (others => '0');
|
||||
end case;
|
||||
|
||||
end process attenuate;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
||||
@@ -1,134 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_clock_div.vhd,v 1.4 2005/10/10 21:51:27 arnim Exp $
|
||||
--
|
||||
-- Clock Divider Circuit
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity sn76489_clock_div is
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clock_en_i : in std_logic;
|
||||
res_n_i : in std_logic;
|
||||
clk_en_o : out boolean
|
||||
);
|
||||
|
||||
end sn76489_clock_div;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture rtl of sn76489_clock_div is
|
||||
|
||||
signal cnt_s,
|
||||
cnt_q : unsigned(3 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential counter element.
|
||||
--
|
||||
seq: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
cnt_q <= (others => '0');
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
cnt_q <= cnt_s;
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process comb
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the combinational counter logic.
|
||||
--
|
||||
comb: process (clock_en_i,
|
||||
cnt_q)
|
||||
begin
|
||||
-- default assignments
|
||||
cnt_s <= cnt_q;
|
||||
clk_en_o <= false;
|
||||
|
||||
if clock_en_i = '1' then
|
||||
|
||||
if cnt_q = 0 then
|
||||
clk_en_o <= true;
|
||||
|
||||
if clock_div_16_g = 1 then
|
||||
cnt_s <= to_unsigned(15, cnt_q'length);
|
||||
elsif clock_div_16_g = 0 then
|
||||
cnt_s <= to_unsigned( 1, cnt_q'length);
|
||||
else
|
||||
-- pragma translate_off
|
||||
assert false
|
||||
report "Generic clock_div_16_g must be either 0 or 1."
|
||||
severity failure;
|
||||
-- pragma translate_on
|
||||
end if;
|
||||
|
||||
else
|
||||
cnt_s <= cnt_q - 1;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end process comb;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
||||
@@ -1,138 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_latch_ctrl.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Latch Control Unit
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity sn76489_latch_ctrl is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
ce_n_i : in std_logic;
|
||||
we_n_i : in std_logic;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
ready_o : out std_logic;
|
||||
tone1_we_o : out boolean;
|
||||
tone2_we_o : out boolean;
|
||||
tone3_we_o : out boolean;
|
||||
noise_we_o : out boolean;
|
||||
r2_o : out std_logic
|
||||
);
|
||||
|
||||
end sn76489_latch_ctrl;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture rtl of sn76489_latch_ctrl is
|
||||
|
||||
signal reg_q : std_logic_vector(0 to 2);
|
||||
signal we_q : boolean;
|
||||
signal ready_q : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential elements.
|
||||
--
|
||||
seq: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
reg_q <= (others => '0');
|
||||
we_q <= false;
|
||||
ready_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
-- READY Flag Output ----------------------------------------------------
|
||||
if ready_q = '0' and we_q then
|
||||
if clk_en_i then
|
||||
-- assert READY when write access happened
|
||||
ready_q <= '1';
|
||||
end if;
|
||||
elsif ce_n_i = '1' then
|
||||
-- deassert READY when access has finished
|
||||
ready_q <= '0';
|
||||
end if;
|
||||
|
||||
-- Register Selection ---------------------------------------------------
|
||||
if ce_n_i = '0' and we_n_i = '0' then
|
||||
if clk_en_i then
|
||||
if d_i(0) = '1' then
|
||||
reg_q <= d_i(1 to 3);
|
||||
end if;
|
||||
we_q <= true;
|
||||
end if;
|
||||
else
|
||||
we_q <= false;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
tone1_we_o <= reg_q(0 to 1) = "00" and we_q;
|
||||
tone2_we_o <= reg_q(0 to 1) = "01" and we_q;
|
||||
tone3_we_o <= reg_q(0 to 1) = "10" and we_q;
|
||||
noise_we_o <= reg_q(0 to 1) = "11" and we_q;
|
||||
|
||||
r2_o <= reg_q(2);
|
||||
|
||||
ready_o <= ready_q
|
||||
when ce_n_i = '0' else
|
||||
'1';
|
||||
|
||||
end rtl;
|
||||
@@ -1,278 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_noise.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Noise Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_noise is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
we_i : in boolean;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
tone3_ff_i : in std_logic;
|
||||
noise_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_noise;
|
||||
|
||||
architecture rtl of sn76489_noise is
|
||||
|
||||
signal nf_q : std_logic_vector(0 to 1);
|
||||
signal fb_q : std_logic;
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 6);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal shift_source_s,
|
||||
shift_source_q : std_logic;
|
||||
signal shift_rise_edge_s : boolean;
|
||||
|
||||
signal lfsr_q : std_logic_vector(0 to 15);
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process cpu_regs
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the registers writable by the CPU.
|
||||
--
|
||||
cpu_regs: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
nf_q <= (others => '0');
|
||||
fb_q <= '0';
|
||||
a_q <= (others => '1');
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i and we_i then
|
||||
if r2_i = '0' then
|
||||
-- access to control register
|
||||
-- both access types can write to the control register!
|
||||
nf_q <= d_i(6 to 7);
|
||||
fb_q <= d_i(5);
|
||||
|
||||
else
|
||||
-- access to attenuator register
|
||||
-- both access types can write to the attenuator register!
|
||||
a_q <= d_i(4 to 7);
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process cpu_regs;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process freq_gen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the frequency generation components.
|
||||
--
|
||||
freq_gen: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
freq_cnt_q <= (others => '0');
|
||||
freq_ff_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if freq_cnt_q = 0 then
|
||||
-- reload frequency counter according to NF setting
|
||||
case nf_q is
|
||||
when "00" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 2 - 1, freq_cnt_q'length);
|
||||
when "01" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 4 - 1, freq_cnt_q'length);
|
||||
when "10" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 8 - 1, freq_cnt_q'length);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
freq_ff_q <= not freq_ff_q;
|
||||
|
||||
else
|
||||
-- decrement frequency counter
|
||||
freq_cnt_q <= freq_cnt_q - 1;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process freq_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Multiplex the source of the LFSR's shift enable
|
||||
-----------------------------------------------------------------------------
|
||||
shift_source_s <= tone3_ff_i
|
||||
when nf_q = "11" else
|
||||
freq_ff_q;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process rise_edge
|
||||
--
|
||||
-- Purpose:
|
||||
-- Detect the rising edge of the selected LFSR shift source.
|
||||
--
|
||||
rise_edge: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
shift_source_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
shift_source_q <= shift_source_s;
|
||||
end if;
|
||||
end if;
|
||||
end process rise_edge;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
-- detect rising edge on shift source
|
||||
shift_rise_edge_s <= shift_source_q = '0' and shift_source_s = '1';
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process lfsr
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the LFSR that generates noise.
|
||||
-- Note: This implementation shifts the register right, i.e. from index
|
||||
-- 15 towards 0 => bit 15 is the input, bit 0 is the output
|
||||
--
|
||||
-- Tapped bits according to MAME's sn76496.c, implemented in function
|
||||
-- lfsr_tapped_f.
|
||||
--
|
||||
lfsr: process (clock_i, res_n_i)
|
||||
|
||||
function lfsr_tapped_f(lfsr : in std_logic_vector) return std_logic is
|
||||
constant tapped_bits_c : std_logic_vector(0 to 15)
|
||||
-- tapped bits are 0, 2, 15
|
||||
:= "1010000000000001";
|
||||
variable parity_v : std_logic;
|
||||
begin
|
||||
parity_v := '0';
|
||||
|
||||
for idx in lfsr'low to lfsr'high loop
|
||||
parity_v := parity_v xor (lfsr(idx) and tapped_bits_c(idx));
|
||||
end loop;
|
||||
|
||||
return parity_v;
|
||||
end;
|
||||
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
-- reset LFSR to "0000000000000001"
|
||||
lfsr_q <= (others => '0');
|
||||
lfsr_q(lfsr_q'right) <= '1';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if we_i and r2_i = '0' then
|
||||
-- write to noise register
|
||||
-- -> reset LFSR
|
||||
lfsr_q <= (others => '0');
|
||||
lfsr_q(lfsr_q'right) <= '1';
|
||||
|
||||
elsif shift_rise_edge_s then
|
||||
|
||||
-- shift LFSR left towards MSB
|
||||
for idx in lfsr_q'right-1 downto lfsr_q'left loop
|
||||
lfsr_q(idx) <= lfsr_q(idx+1);
|
||||
end loop;
|
||||
|
||||
-- determine input bit
|
||||
if fb_q = '0' then
|
||||
-- "Periodic" Noise
|
||||
-- -> input to LFSR is output
|
||||
lfsr_q(lfsr_q'right) <= lfsr_q(lfsr_q'left);
|
||||
else
|
||||
-- "White" Noise
|
||||
-- -> input to LFSR is parity of tapped bits
|
||||
lfsr_q(lfsr_q'right) <= lfsr_tapped_f(lfsr_q);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process lfsr;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map output of LFSR to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when lfsr_q(0) = '1' else
|
||||
to_signed( 0, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The attenuator itself
|
||||
-----------------------------------------------------------------------------
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
product_o => noise_o
|
||||
);
|
||||
|
||||
end rtl;
|
||||
@@ -1,188 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_tone.vhd,v 1.5 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Tone Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_tone is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
we_i : in boolean;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
ff_o : out std_logic;
|
||||
tone_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_tone;
|
||||
|
||||
architecture rtl of sn76489_tone is
|
||||
|
||||
signal f_q : std_logic_vector(0 to 9);
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 9);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
|
||||
function all_zero(a : in std_logic_vector) return boolean is
|
||||
variable result_v : boolean;
|
||||
begin
|
||||
result_v := true;
|
||||
|
||||
for idx in a'low to a'high loop
|
||||
if a(idx) /= '0' then
|
||||
result_v := false;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return result_v;
|
||||
end;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process cpu_regs
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the registers writable by the CPU.
|
||||
--
|
||||
cpu_regs: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
f_q <= (others => '0');
|
||||
a_q <= (others => '1');
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i and we_i then
|
||||
if r2_i = '0' then
|
||||
-- access to frequency register
|
||||
if d_i(0) = '0' then
|
||||
f_q(0 to 5) <= d_i(2 to 7);
|
||||
else
|
||||
f_q(6 to 9) <= d_i(4 to 7);
|
||||
end if;
|
||||
|
||||
else
|
||||
-- access to attenuator register
|
||||
-- both access types can write to the attenuator register!
|
||||
a_q <= d_i(4 to 7);
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process cpu_regs;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process freq_gen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the frequency generation components.
|
||||
--
|
||||
freq_gen: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
freq_cnt_q <= (others => '0');
|
||||
freq_ff_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if freq_cnt_q = 0 then
|
||||
-- update counter from frequency register
|
||||
freq_cnt_q <= unsigned(f_q);
|
||||
|
||||
-- and toggle the frequency flip-flop if enabled
|
||||
if not all_zero(f_q) then
|
||||
freq_ff_q <= not freq_ff_q;
|
||||
else
|
||||
-- if frequency setting is 0, then keep flip-flop at +1
|
||||
freq_ff_q <= '1';
|
||||
end if;
|
||||
|
||||
else
|
||||
-- decrement frequency counter
|
||||
freq_cnt_q <= freq_cnt_q - 1;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process freq_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map frequency flip-flop to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when freq_ff_q = '1' else
|
||||
to_signed(-1, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The attenuator itself
|
||||
-----------------------------------------------------------------------------
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
product_o => tone_o
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
ff_o <= freq_ff_q;
|
||||
|
||||
end rtl;
|
||||
@@ -1,200 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_top.vhd,v 1.9 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Chip Toplevel
|
||||
--
|
||||
-- References:
|
||||
--
|
||||
-- * TI Data sheet SN76489.pdf
|
||||
-- ftp://ftp.whtech.com/datasheets%20&%20manuals/SN76489.pdf
|
||||
--
|
||||
-- * John Kortink's article on the SN76489:
|
||||
-- http://web.inter.nl.net/users/J.Kortink/home/articles/sn76489/
|
||||
--
|
||||
-- * Maxim's "SN76489 notes" in
|
||||
-- http://www.smspower.org/maxim/docs/SN76489.txt
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_top is
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clock_en_i : in std_logic;
|
||||
res_n_i : in std_logic;
|
||||
ce_n_i : in std_logic;
|
||||
we_n_i : in std_logic;
|
||||
ready_o : out std_logic;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
aout_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_top;
|
||||
|
||||
architecture struct of sn76489_top is
|
||||
|
||||
signal clk_en_s : boolean;
|
||||
|
||||
signal tone1_we_s,
|
||||
tone2_we_s,
|
||||
tone3_we_s,
|
||||
noise_we_s : boolean;
|
||||
signal r2_s : std_logic;
|
||||
|
||||
signal tone1_s,
|
||||
tone2_s,
|
||||
tone3_s,
|
||||
noise_s : signed(0 to 7);
|
||||
|
||||
signal tone3_ff_s : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Clock Divider
|
||||
-----------------------------------------------------------------------------
|
||||
clock_div_b : entity work.sn76489_clock_div
|
||||
generic map (
|
||||
clock_div_16_g => clock_div_16_g
|
||||
)
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clock_en_i => clock_en_i,
|
||||
res_n_i => res_n_i,
|
||||
clk_en_o => clk_en_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Latch Control = CPU Interface
|
||||
-----------------------------------------------------------------------------
|
||||
latch_ctrl_b : entity work.sn76489_latch_ctrl
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
ce_n_i => ce_n_i,
|
||||
we_n_i => we_n_i,
|
||||
d_i => d_i,
|
||||
ready_o => ready_o,
|
||||
tone1_we_o => tone1_we_s,
|
||||
tone2_we_o => tone2_we_s,
|
||||
tone3_we_o => tone3_we_s,
|
||||
noise_we_o => noise_we_s,
|
||||
r2_o => r2_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 1
|
||||
-----------------------------------------------------------------------------
|
||||
tone1_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone1_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => open,
|
||||
tone_o => tone1_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 2
|
||||
-----------------------------------------------------------------------------
|
||||
tone2_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone2_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => open,
|
||||
tone_o => tone2_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 3
|
||||
-----------------------------------------------------------------------------
|
||||
tone3_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone3_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => tone3_ff_s,
|
||||
tone_o => tone3_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Noise Channel
|
||||
-----------------------------------------------------------------------------
|
||||
noise_b : entity work.sn76489_noise
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => noise_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
tone3_ff_i => tone3_ff_s,
|
||||
noise_o => noise_s
|
||||
);
|
||||
|
||||
|
||||
aout_o <= tone1_s + tone2_s + tone3_s + noise_s;
|
||||
|
||||
end struct;
|
||||
@@ -160,7 +160,6 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
||||
|
||||
# end ENTITY(Snapjack)
|
||||
# --------------------
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Snapjack.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_video_unit.vhd
|
||||
@@ -180,13 +179,7 @@ set_global_assignment -name VHDL_FILE rtl/ladybug_chutes.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_chute.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_char.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_addr_dec.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/ladybug_sound_unit.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_top.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_tone.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_noise.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_latch_ctrl.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_clock_div.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_attenuator.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_sound_unit.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_sprite_u.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_sprite_l.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/rom_cpu3.vhd
|
||||
@@ -198,15 +191,12 @@ set_global_assignment -name VHDL_FILE rtl/ROM/prom_decrypt.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_3.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_2.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_1.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80a.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_Reg.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_Pack.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_MCode.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80_ALU.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu/T80.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ttl_393.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ttl_175.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/spram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/dpram.vhd
|
||||
set_global_assignment -name QIP_FILE rtl/pll.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/Sound/sn76489/sn76489.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@@ -21,14 +21,14 @@
|
||||
|
||||
module Snapjack
|
||||
(
|
||||
output LED,
|
||||
output LED,
|
||||
output [5:0] VGA_R,
|
||||
output [5:0] VGA_G,
|
||||
output [5:0] VGA_B,
|
||||
output VGA_HS,
|
||||
output VGA_VS,
|
||||
output AUDIO_L,
|
||||
output AUDIO_R,
|
||||
output AUDIO_R,
|
||||
input SPI_SCK,
|
||||
output SPI_DO,
|
||||
input SPI_DI,
|
||||
@@ -41,13 +41,16 @@ module Snapjack
|
||||
`include "rtl\build_id.v"
|
||||
|
||||
localparam CONF_STR = {
|
||||
"Snapjack;;",
|
||||
"SNAPJACK;;",
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scanlines,Off,25%,50%,75%;",
|
||||
"O5,Blend,Off,On;",
|
||||
"T6,Reset;",
|
||||
"T0,Reset;",
|
||||
"V,v1.10.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire rotate = status[2];
|
||||
|
||||
assign LED = 1;
|
||||
assign AUDIO_R = AUDIO_L;
|
||||
|
||||
@@ -67,17 +70,43 @@ wire [7:0] joystick_0;
|
||||
wire [7:0] joystick_1;
|
||||
wire scandoublerD;
|
||||
wire ypbpr;
|
||||
wire [10:0] ps2_key;
|
||||
reg [7:0] audio;
|
||||
wire hb, vb;
|
||||
wire blankn = ~(hb | vb);
|
||||
wire ce_vid;
|
||||
wire hs, vs;
|
||||
wire [1:0] r, g, b;
|
||||
wire no_csync;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
ladybugt snapjack(
|
||||
user_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
user_io(
|
||||
.clk_sys (clk_sys ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_CLK (SPI_SCK ),
|
||||
.SPI_SS_IO (CONF_DATA0 ),
|
||||
.SPI_MISO (SPI_DO ),
|
||||
.SPI_MOSI (SPI_DI ),
|
||||
.buttons (buttons ),
|
||||
.switches (switches ),
|
||||
.scandoubler_disable (scandoublerD),
|
||||
.ypbpr (ypbpr ),
|
||||
.no_csync (no_csync ),
|
||||
.key_strobe (key_strobe ),
|
||||
.key_pressed (key_pressed ),
|
||||
.key_code (key_code ),
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
|
||||
wire [8:0] audio;
|
||||
wire hb, vb;
|
||||
wire blankn = ~(hb | vb);
|
||||
wire ce_vid;
|
||||
wire hs, vs;
|
||||
wire [1:0] r,g,b;
|
||||
|
||||
ladybugt ladybug(
|
||||
.CLK_IN(clk_sys),
|
||||
.I_RESET(status[0] | status[6] | buttons[1]),
|
||||
.I_RESET(status[0] | buttons[1]),
|
||||
.O_PIXCE(ce_vid),
|
||||
.O_VIDEO_R(r),
|
||||
.O_VIDEO_G(g),
|
||||
@@ -87,15 +116,15 @@ ladybugt snapjack(
|
||||
.O_VBLANK(vb),
|
||||
.O_HBLANK(hb),
|
||||
.O_AUDIO(audio),
|
||||
.but_coin_s(~{1'b0,btn_coin}),
|
||||
.but_fire_s(~{m_fire,m_fire}),
|
||||
.but_bomb_s(~{m_bomb,m_bomb}),
|
||||
.but_tilt_s(~{1'b0,1'b0}),
|
||||
.but_select_s(~{btn_two_players, btn_one_player}),
|
||||
.but_up_s(~{m_up,m_up}),
|
||||
.but_down_s(~{m_down,m_down}),
|
||||
.but_left_s(~{m_left,m_left}),
|
||||
.but_right_s(~{m_right,m_right})
|
||||
.but_coin_s(~{m_coin2,m_coin1}),
|
||||
.but_fire_s(~{m_fire2A,m_fireA}),
|
||||
.but_bomb_s(~{m_fire2B,m_fireB}),
|
||||
.but_tilt_s(~{m_tilt,m_tilt}),
|
||||
.but_select_s(~{m_two_players, m_one_player}),
|
||||
.but_up_s(~{m_up2,m_up}),
|
||||
.but_down_s(~{m_down2,m_down}),
|
||||
.but_left_s(~{m_left2,m_left}),
|
||||
.but_right_s(~{m_right2,m_right})
|
||||
);
|
||||
|
||||
mist_video #(.COLOR_DEPTH(2),.SD_HCNT_WIDTH(10)) mist_video(
|
||||
@@ -113,79 +142,40 @@ mist_video #(.COLOR_DEPTH(2),.SD_HCNT_WIDTH(10)) mist_video(
|
||||
.VGA_B(VGA_B),
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS),
|
||||
.rotate({1'b0,status[2]}),
|
||||
.rotate({1'b0,rotate}),
|
||||
.ce_divider(1'b1),
|
||||
.blend(status[5]),
|
||||
.scandoubler_disable(scandoublerD),
|
||||
.scanlines(status[4:3]),
|
||||
.ypbpr(ypbpr)
|
||||
.ypbpr(ypbpr),
|
||||
.no_csync(no_csync)
|
||||
);
|
||||
|
||||
user_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
user_io(
|
||||
.clk_sys (clk_sys ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_CLK (SPI_SCK ),
|
||||
.SPI_SS_IO (CONF_DATA0 ),
|
||||
.SPI_MISO (SPI_DO ),
|
||||
.SPI_MOSI (SPI_DI ),
|
||||
.buttons (buttons ),
|
||||
.switches (switches ),
|
||||
.scandoubler_disable (scandoublerD),
|
||||
.ypbpr (ypbpr ),
|
||||
.key_strobe (key_strobe ),
|
||||
.key_pressed (key_pressed ),
|
||||
.key_code (key_code ),
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
|
||||
dac dac(
|
||||
dac #(9) dac(
|
||||
.clk_i(clk_sys),
|
||||
.res_n_i(1),
|
||||
.dac_i({~audio[7], audio[6:0]}),
|
||||
.dac_i(audio),
|
||||
.dac_o(AUDIO_L)
|
||||
);
|
||||
|
||||
wire m_up = btn_up | joystick_0[3] | joystick_1[3];
|
||||
wire m_down = btn_down | joystick_0[2] | joystick_1[2];
|
||||
wire m_left = btn_left | joystick_0[1] | joystick_1[1];
|
||||
wire m_right = btn_right | joystick_0[0] | joystick_1[0];
|
||||
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
|
||||
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
|
||||
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
|
||||
|
||||
wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4];
|
||||
wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5];
|
||||
|
||||
reg btn_one_player = 0;
|
||||
reg btn_two_players = 0;
|
||||
reg btn_left = 0;
|
||||
reg btn_right = 0;
|
||||
reg btn_down = 0;
|
||||
reg btn_up = 0;
|
||||
reg btn_fire1 = 0;
|
||||
reg btn_fire2 = 0;
|
||||
reg btn_fire3 = 0;
|
||||
reg btn_coin = 0;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(key_strobe) begin
|
||||
case(key_code)
|
||||
'h75: btn_up <= key_pressed; // up
|
||||
'h72: btn_down <= key_pressed; // down
|
||||
'h6B: btn_left <= key_pressed; // left
|
||||
'h74: btn_right <= key_pressed; // right
|
||||
'h76: btn_coin <= key_pressed; // ESC
|
||||
'h05: btn_one_player <= key_pressed; // F1
|
||||
'h06: btn_two_players <= key_pressed; // F2
|
||||
'h14: btn_fire3 <= key_pressed; // ctrl
|
||||
'h11: btn_fire2 <= key_pressed; // alt
|
||||
'h29: btn_fire1 <= key_pressed; // Space
|
||||
endcase
|
||||
end
|
||||
end
|
||||
arcade_inputs inputs (
|
||||
.clk ( clk_sys ),
|
||||
.key_strobe ( key_strobe ),
|
||||
.key_pressed ( key_pressed ),
|
||||
.key_code ( key_code ),
|
||||
.joystick_0 ( joystick_0 ),
|
||||
.joystick_1 ( joystick_1 ),
|
||||
.rotate ( rotate ),
|
||||
.orientation ( 2'b00 ),
|
||||
.joyswap ( 1'b0 ),
|
||||
.oneplayer ( 1'b1 ),
|
||||
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
|
||||
.player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
|
||||
.player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
|
||||
);
|
||||
|
||||
endmodule
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,370 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0247
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
||||
--
|
||||
-- 0238 : Fixed zero flag for 16 bit SBC and ADC
|
||||
--
|
||||
-- 0240 : Added GB operations
|
||||
--
|
||||
-- 0242 : Cleanup
|
||||
--
|
||||
-- 0247 : Cleanup
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_ALU is
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_ALU;
|
||||
|
||||
architecture rtl of T80_ALU is
|
||||
|
||||
procedure AddSub(A : std_logic_vector;
|
||||
B : std_logic_vector;
|
||||
Sub : std_logic;
|
||||
Carry_In : std_logic;
|
||||
signal Res : out std_logic_vector;
|
||||
signal Carry : out std_logic) is
|
||||
|
||||
variable B_i : unsigned(A'length - 1 downto 0);
|
||||
variable Res_i : unsigned(A'length + 1 downto 0);
|
||||
begin
|
||||
if Sub = '1' then
|
||||
B_i := not unsigned(B);
|
||||
else
|
||||
B_i := unsigned(B);
|
||||
end if;
|
||||
|
||||
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
|
||||
Carry <= Res_i(A'length + 1);
|
||||
Res <= std_logic_vector(Res_i(A'length downto 1));
|
||||
end;
|
||||
|
||||
-- AddSub variables (temporary signals)
|
||||
signal UseCarry : std_logic;
|
||||
signal Carry7_v : std_logic;
|
||||
signal Overflow_v : std_logic;
|
||||
signal HalfCarry_v : std_logic;
|
||||
signal Carry_v : std_logic;
|
||||
signal Q_v : std_logic_vector(7 downto 0);
|
||||
|
||||
signal BitMask : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
with IR(5 downto 3) select BitMask <= "00000001" when "000",
|
||||
"00000010" when "001",
|
||||
"00000100" when "010",
|
||||
"00001000" when "011",
|
||||
"00010000" when "100",
|
||||
"00100000" when "101",
|
||||
"01000000" when "110",
|
||||
"10000000" when others;
|
||||
|
||||
UseCarry <= not ALU_Op(2) and ALU_Op(0);
|
||||
AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v);
|
||||
AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v);
|
||||
AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v);
|
||||
-- bug fix - parity flag is just parity for 8080, also overflow for Z80
|
||||
process (Carry_v, Carry7_v, Q_v)
|
||||
begin
|
||||
if(Mode=2) then
|
||||
OverFlow_v <= not (Q_v(0) xor Q_v(1) xor Q_v(2) xor Q_v(3) xor
|
||||
Q_v(4) xor Q_v(5) xor Q_v(6) xor Q_v(7)); else
|
||||
OverFlow_v <= Carry_v xor Carry7_v;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
|
||||
variable Q_t : std_logic_vector(7 downto 0);
|
||||
variable DAA_Q : unsigned(8 downto 0);
|
||||
begin
|
||||
Q_t := "--------";
|
||||
F_Out <= F_In;
|
||||
DAA_Q := "---------";
|
||||
case ALU_Op is
|
||||
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" =>
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_C) <= '0';
|
||||
case ALU_OP(2 downto 0) is
|
||||
when "000" | "001" => -- ADD, ADC
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_C) <= Carry_v;
|
||||
F_Out(Flag_H) <= HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "010" | "011" | "111" => -- SUB, SBC, CP
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_N) <= '1';
|
||||
F_Out(Flag_C) <= not Carry_v;
|
||||
F_Out(Flag_H) <= not HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "100" => -- AND
|
||||
Q_t(7 downto 0) := BusA and BusB;
|
||||
F_Out(Flag_H) <= '1';
|
||||
when "101" => -- XOR
|
||||
Q_t(7 downto 0) := BusA xor BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
when others => -- OR "110"
|
||||
Q_t(7 downto 0) := BusA or BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
end case;
|
||||
if ALU_Op(2 downto 0) = "111" then -- CP
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
else
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
end if;
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
if Z16 = '1' then
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC
|
||||
end if;
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
case ALU_Op(2 downto 0) is
|
||||
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP
|
||||
when others =>
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
end case;
|
||||
if Arith16 = '1' then
|
||||
F_Out(Flag_S) <= F_In(Flag_S);
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||
F_Out(Flag_P) <= F_In(Flag_P);
|
||||
end if;
|
||||
when "1100" =>
|
||||
-- DAA
|
||||
F_Out(Flag_H) <= F_In(Flag_H);
|
||||
F_Out(Flag_C) <= F_In(Flag_C);
|
||||
DAA_Q(7 downto 0) := unsigned(BusA);
|
||||
DAA_Q(8) := '0';
|
||||
if F_In(Flag_N) = '0' then
|
||||
-- After addition
|
||||
-- Alow > 9 or H = 1
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if (DAA_Q(3 downto 0) > 9) then
|
||||
F_Out(Flag_H) <= '1';
|
||||
else
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q := DAA_Q + 6;
|
||||
end if;
|
||||
-- new Ahigh > 9 or C = 1
|
||||
if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q + 96; -- 0x60
|
||||
end if;
|
||||
else
|
||||
-- After subtraction
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if DAA_Q(3 downto 0) > 5 then
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6;
|
||||
end if;
|
||||
if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q - 352; -- 0x160
|
||||
end if;
|
||||
end if;
|
||||
F_Out(Flag_X) <= DAA_Q(3);
|
||||
F_Out(Flag_Y) <= DAA_Q(5);
|
||||
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
|
||||
Q_t := std_logic_vector(DAA_Q(7 downto 0));
|
||||
if DAA_Q(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= DAA_Q(7);
|
||||
F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor
|
||||
DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7));
|
||||
when "1101" | "1110" =>
|
||||
-- RLD, RRD
|
||||
Q_t(7 downto 4) := BusA(7 downto 4);
|
||||
if ALU_Op(0) = '1' then
|
||||
Q_t(3 downto 0) := BusB(7 downto 4);
|
||||
else
|
||||
Q_t(3 downto 0) := BusB(3 downto 0);
|
||||
end if;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
when "1001" =>
|
||||
-- BIT
|
||||
Q_t(7 downto 0) := BusB and BitMask;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
F_Out(Flag_P) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
F_Out(Flag_P) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_H) <= '1';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= '0';
|
||||
F_Out(Flag_Y) <= '0';
|
||||
if IR(2 downto 0) /= "110" then
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
end if;
|
||||
when "1010" =>
|
||||
-- SET
|
||||
Q_t(7 downto 0) := BusB or BitMask;
|
||||
when "1011" =>
|
||||
-- RES
|
||||
Q_t(7 downto 0) := BusB and not BitMask;
|
||||
when "1000" =>
|
||||
-- ROT
|
||||
case IR(5 downto 3) is
|
||||
when "000" => -- RLC
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "010" => -- RL
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "001" => -- RRC
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(0);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "011" => -- RR
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "100" => -- SLA
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '0';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "110" => -- SLL (Undocumented) / SWAP
|
||||
if Mode = 3 then
|
||||
Q_t(7 downto 4) := BusA(3 downto 0);
|
||||
Q_t(3 downto 0) := BusA(7 downto 4);
|
||||
F_Out(Flag_C) <= '0';
|
||||
else
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '1';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
end if;
|
||||
when "101" => -- SRA
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when others => -- SRL
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := '0';
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
end case;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
if ISet = "00" then
|
||||
F_Out(Flag_P) <= F_In(Flag_P);
|
||||
F_Out(Flag_S) <= F_In(Flag_S);
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
Q <= Q_t;
|
||||
end process;
|
||||
end;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,220 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0242
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
package T80_Pack is
|
||||
|
||||
component T80
|
||||
generic(
|
||||
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
IORQ : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DInst : in std_logic_vector(7 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0);
|
||||
MC : out std_logic_vector(2 downto 0);
|
||||
TS : out std_logic_vector(2 downto 0);
|
||||
IntCycle_n : out std_logic;
|
||||
IntE : out std_logic;
|
||||
Stop : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_Reg
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_MCode
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
IR : in std_logic_vector(7 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
MCycle : in std_logic_vector(2 downto 0);
|
||||
F : in std_logic_vector(7 downto 0);
|
||||
NMICycle : in std_logic;
|
||||
IntCycle : in std_logic;
|
||||
XY_State : in std_logic_vector(1 downto 0);
|
||||
MCycles : out std_logic_vector(2 downto 0);
|
||||
TStates : out std_logic_vector(2 downto 0);
|
||||
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
|
||||
Inc_PC : out std_logic;
|
||||
Inc_WZ : out std_logic;
|
||||
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
|
||||
Read_To_Reg : out std_logic;
|
||||
Read_To_Acc : out std_logic;
|
||||
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
|
||||
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
|
||||
ALU_Op : out std_logic_vector(3 downto 0);
|
||||
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
|
||||
Save_ALU : out std_logic;
|
||||
PreserveC : out std_logic;
|
||||
Arith16 : out std_logic;
|
||||
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
|
||||
IORQ : out std_logic;
|
||||
Jump : out std_logic;
|
||||
JumpE : out std_logic;
|
||||
JumpXY : out std_logic;
|
||||
Call : out std_logic;
|
||||
RstP : out std_logic;
|
||||
LDZ : out std_logic;
|
||||
LDW : out std_logic;
|
||||
LDSPHL : out std_logic;
|
||||
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
|
||||
ExchangeDH : out std_logic;
|
||||
ExchangeRp : out std_logic;
|
||||
ExchangeAF : out std_logic;
|
||||
ExchangeRS : out std_logic;
|
||||
I_DJNZ : out std_logic;
|
||||
I_CPL : out std_logic;
|
||||
I_CCF : out std_logic;
|
||||
I_SCF : out std_logic;
|
||||
I_RETN : out std_logic;
|
||||
I_BT : out std_logic;
|
||||
I_BC : out std_logic;
|
||||
I_BTR : out std_logic;
|
||||
I_RLD : out std_logic;
|
||||
I_RRD : out std_logic;
|
||||
I_INRC : out std_logic;
|
||||
SetDI : out std_logic;
|
||||
SetEI : out std_logic;
|
||||
IMode : out std_logic_vector(1 downto 0);
|
||||
Halt : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
XYbit_undoc : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_ALU
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
end;
|
||||
@@ -1,114 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- T80 Registers, technology independent
|
||||
--
|
||||
-- Version : 0244
|
||||
--
|
||||
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t51/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0242 : Initial release
|
||||
--
|
||||
-- 0244 : Changed to single register file
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_Reg is
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_Reg;
|
||||
|
||||
architecture rtl of T80_Reg is
|
||||
|
||||
type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0);
|
||||
signal RegsH : Register_Image(0 to 7);
|
||||
signal RegsL : Register_Image(0 to 7);
|
||||
|
||||
begin
|
||||
|
||||
process (Clk)
|
||||
begin
|
||||
if Clk'event and Clk = '1' then
|
||||
if CEN = '1' then
|
||||
if WEH = '1' then
|
||||
RegsH(to_integer(unsigned(AddrA))) <= DIH;
|
||||
end if;
|
||||
if WEL = '1' then
|
||||
RegsL(to_integer(unsigned(AddrA))) <= DIL;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
DOAH <= RegsH(to_integer(unsigned(AddrA)));
|
||||
DOAL <= RegsL(to_integer(unsigned(AddrA)));
|
||||
DOBH <= RegsH(to_integer(unsigned(AddrB)));
|
||||
DOBL <= RegsL(to_integer(unsigned(AddrB)));
|
||||
DOCH <= RegsH(to_integer(unsigned(AddrC)));
|
||||
DOCL <= RegsL(to_integer(unsigned(AddrC)));
|
||||
|
||||
end;
|
||||
@@ -1,280 +0,0 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- Z80 compatible microprocessor core, asynchronous top level
|
||||
--
|
||||
-- Version : 0247
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0208 : First complete release
|
||||
--
|
||||
-- 0211 : Fixed interrupt cycle
|
||||
--
|
||||
-- 0235 : Updated for T80 interface change
|
||||
--
|
||||
-- 0238 : Updated for T80 interface change
|
||||
--
|
||||
-- 0240 : Updated for T80 interface change
|
||||
--
|
||||
-- 0242 : Updated for T80 interface change
|
||||
--
|
||||
-- 0247 : Fixed bus req/ack cycle
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use work.T80_Pack.all;
|
||||
|
||||
entity T80a is
|
||||
generic(
|
||||
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CLK_EN_SYS : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
MREQ_n : out std_logic;
|
||||
IORQ_n : out std_logic;
|
||||
RD_n : out std_logic;
|
||||
WR_n : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80a;
|
||||
|
||||
architecture rtl of T80a is
|
||||
|
||||
signal CEN : std_logic;
|
||||
signal Reset_s : std_logic;
|
||||
signal IntCycle_n : std_logic;
|
||||
signal IORQ : std_logic;
|
||||
signal NoRead : std_logic;
|
||||
signal Write : std_logic;
|
||||
signal MREQ : std_logic;
|
||||
signal MReq_Inhibit : std_logic;
|
||||
signal Req_Inhibit : std_logic;
|
||||
signal RD : std_logic;
|
||||
signal MREQ_n_i : std_logic;
|
||||
signal IORQ_n_i : std_logic;
|
||||
signal RD_n_i : std_logic;
|
||||
signal WR_n_i : std_logic;
|
||||
signal RFSH_n_i : std_logic;
|
||||
signal BUSAK_n_i : std_logic;
|
||||
signal A_i : std_logic_vector(15 downto 0);
|
||||
signal DO_Reg : std_logic_vector(7 downto 0);
|
||||
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
|
||||
signal Wait_s : std_logic;
|
||||
signal MCycle : std_logic_vector(2 downto 0);
|
||||
signal TState : std_logic_vector(2 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- clock enable supplied from clocking system
|
||||
CEN <= CLK_EN_SYS;
|
||||
|
||||
BUSAK_n <= BUSAK_n_i;
|
||||
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
|
||||
RD_n_i <= not RD or Req_Inhibit;
|
||||
|
||||
MREQ_n <= MREQ_n_i;
|
||||
IORQ_n <= IORQ_n_i;
|
||||
RD_n <= RD_n_i;
|
||||
WR_n <= WR_n_i;
|
||||
RFSH_n <= RFSH_n_i;
|
||||
A <= A_i;
|
||||
DO <= DO_Reg;
|
||||
|
||||
-- process (RESET_n, CLK_n)
|
||||
-- begin
|
||||
-- if RESET_n = '0' then
|
||||
-- Reset_s <= '0';
|
||||
-- elsif CLK_n'event and CLK_n = '1' then
|
||||
-- Reset_s <= '1';
|
||||
-- end if;
|
||||
-- end process;
|
||||
-- T80 reset input has already proper characteristics:
|
||||
-- * asynchronous assertion
|
||||
-- * deassertion synchronous to CLK_n (main_clk)
|
||||
Reset_s <= RESET_n;
|
||||
|
||||
u0 : T80
|
||||
generic map(
|
||||
Mode => Mode,
|
||||
IOWait => 1)
|
||||
port map(
|
||||
CEN => CEN,
|
||||
M1_n => M1_n,
|
||||
IORQ => IORQ,
|
||||
NoRead => NoRead,
|
||||
Write => Write,
|
||||
RFSH_n => RFSH_n_i,
|
||||
HALT_n => HALT_n,
|
||||
WAIT_n => Wait_s,
|
||||
INT_n => INT_n,
|
||||
NMI_n => NMI_n,
|
||||
RESET_n => Reset_s,
|
||||
BUSRQ_n => BUSRQ_n,
|
||||
BUSAK_n => BUSAK_n_i,
|
||||
CLK_n => CLK_n,
|
||||
A => A_i,
|
||||
DInst => DI,
|
||||
DI => DI_Reg,
|
||||
DO => DO_Reg,
|
||||
MC => MCycle,
|
||||
TS => TState,
|
||||
IntCycle_n => IntCycle_n);
|
||||
|
||||
process (CLK_n)
|
||||
begin
|
||||
if CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
Wait_s <= WAIT_n;
|
||||
if TState = "011" and BUSAK_n_i = '1' then
|
||||
DI_Reg <= to_x01(DI);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
WR_n_i <= '1';
|
||||
elsif CLK_n'event and CLK_n = '1' then
|
||||
if CEN = '1' then
|
||||
WR_n_i <= '1';
|
||||
if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
|
||||
WR_n_i <= not Write;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
Req_Inhibit <= '0';
|
||||
elsif CLK_n'event and CLK_n = '1' then
|
||||
if CEN = '1' then
|
||||
if MCycle = "001" and TState = "010" then
|
||||
Req_Inhibit <= '1';
|
||||
else
|
||||
Req_Inhibit <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
MReq_Inhibit <= '0';
|
||||
elsif CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
if MCycle = "001" and TState = "010" then
|
||||
MReq_Inhibit <= '1';
|
||||
else
|
||||
MReq_Inhibit <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(Reset_s,CLK_n)
|
||||
begin
|
||||
if Reset_s = '0' then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '0';
|
||||
elsif CLK_n'event and CLK_n = '0' then
|
||||
if CEN = '1' then
|
||||
|
||||
if MCycle = "001" then
|
||||
if TState = "001" then
|
||||
RD <= IntCycle_n;
|
||||
MREQ <= IntCycle_n;
|
||||
IORQ_n_i <= IntCycle_n;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '1';
|
||||
end if;
|
||||
if TState = "100" then
|
||||
MREQ <= '0';
|
||||
end if;
|
||||
else
|
||||
if TState = "001" and NoRead = '0' then
|
||||
RD <= not Write;
|
||||
IORQ_n_i <= not IORQ;
|
||||
MREQ <= not IORQ;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
RD <= '0';
|
||||
IORQ_n_i <= '1';
|
||||
MREQ <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end;
|
||||
@@ -65,7 +65,7 @@ port (
|
||||
O_PIXCE : out std_logic;
|
||||
|
||||
-- Audio Interface --------------------------------------------------------
|
||||
O_AUDIO : out signed(7 downto 0);
|
||||
O_AUDIO : out std_logic_vector( 8 downto 0);
|
||||
|
||||
but_coin_s : in std_logic_vector( 1 downto 0);
|
||||
but_fire_s : in std_logic_vector( 1 downto 0);
|
||||
@@ -160,8 +160,8 @@ begin
|
||||
rgb_b_o => O_VIDEO_B,
|
||||
hsync_n_o => O_HSYNC,
|
||||
vsync_n_o => O_VSYNC,
|
||||
vblank_o => O_VBLANK,
|
||||
hblank_o => O_HBLANK,
|
||||
vblank_o => O_VBLANK,
|
||||
hblank_o => O_HBLANK,
|
||||
audio_o => O_AUDIO,
|
||||
rom_cpu_a_o => rom_cpu_a_s,
|
||||
rom_cpu_d_i => rom_cpu_d_s,
|
||||
|
||||
@@ -119,14 +119,14 @@ begin
|
||||
-- "wait" has to be modelled with the clock enable because the T80 is not
|
||||
-- able to enlarge write accesses properly when they are delayed with "wait"
|
||||
t80_clk_en_s <= clk_en_4mhz_i and wait_n_s;
|
||||
T80a_b : entity work.T80a
|
||||
T80a_b : entity work.T80s
|
||||
generic map (
|
||||
Mode => 0
|
||||
)
|
||||
port map (
|
||||
RESET_n => res_n_i,
|
||||
CLK_n => clk_20mhz_i,
|
||||
CLK_EN_SYS => t80_clk_en_s,
|
||||
CLK => clk_20mhz_i,
|
||||
CEN => t80_clk_en_s,
|
||||
WAIT_n => wait_n_s,
|
||||
INT_n => int_n_s,
|
||||
NMI_n => nmi_n_s,
|
||||
|
||||
@@ -77,10 +77,10 @@ entity ladybug_machine is
|
||||
hsync_n_o : out std_logic;
|
||||
vsync_n_o : out std_logic;
|
||||
comp_sync_n_o : out std_logic;
|
||||
vblank_o : out std_logic;
|
||||
hblank_o : out std_logic;
|
||||
vblank_o : out std_logic;
|
||||
hblank_o : out std_logic;
|
||||
-- Audio Interface --------------------------------------------------------
|
||||
audio_o : out signed( 7 downto 0);
|
||||
audio_o : out std_logic_vector( 8 downto 0);
|
||||
-- CPU ROM Interface ------------------------------------------------------
|
||||
rom_cpu_a_o : out std_logic_vector(14 downto 0);
|
||||
rom_cpu_d_i : in std_logic_vector( 7 downto 0);
|
||||
|
||||
@@ -59,7 +59,7 @@ entity ladybug_sound_unit is
|
||||
wr_n_i : in std_logic;
|
||||
d_from_cpu_i : in std_logic_vector(7 downto 0);
|
||||
sound_wait_n_o : out std_logic;
|
||||
audio_o : out signed(7 downto 0)
|
||||
audio_o : out std_logic_vector(8 downto 0)
|
||||
);
|
||||
|
||||
end ladybug_sound_unit;
|
||||
@@ -70,7 +70,7 @@ architecture struct of ladybug_sound_unit is
|
||||
ready_c1_s : std_logic;
|
||||
|
||||
signal aout_b1_s,
|
||||
aout_c1_s : signed(7 downto 0);
|
||||
aout_c1_s : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
@@ -117,23 +117,7 @@ begin
|
||||
--
|
||||
-- Purpose:
|
||||
-- Mix the digital audio of the two SN76489 instances.
|
||||
-- Additional care is taken to avoid audio overfow/clipping.
|
||||
--
|
||||
mix: process (aout_b1_s,
|
||||
aout_c1_s)
|
||||
variable sum_v : signed(8 downto 0);
|
||||
begin
|
||||
sum_v := RESIZE(aout_b1_s, 9) + RESIZE(aout_c1_s, 9);
|
||||
|
||||
if sum_v > 127 then
|
||||
audio_o <= to_signed(127, 8);
|
||||
elsif sum_v < -128 then
|
||||
audio_o <= to_signed(-128, 8);
|
||||
else
|
||||
audio_o <= RESIZE(sum_v, 8);
|
||||
end if;
|
||||
|
||||
end process mix;
|
||||
audio_o <= std_logic_vector(unsigned('0'&aout_b1_s) + unsigned('0'&aout_c1_s));
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -1,143 +0,0 @@
|
||||
|
||||
An SN76489AN Compatible Implementation in VHDL
|
||||
==============================================
|
||||
Version: $Date: 2006/06/18 19:28:40 $
|
||||
|
||||
Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
See the file COPYING.
|
||||
|
||||
|
||||
Integration
|
||||
-----------
|
||||
|
||||
The sn76489 design exhibits all interface signals as the original chip. It
|
||||
only differs in the audio data output which is provided as an 8 bit signed
|
||||
vector instead of an analog output pin.
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
-- Set to '1' when operating the design in SN76489 mode. The primary clock
|
||||
-- input is divided by 16 in this variant. The data sheet mentions the
|
||||
-- SN76494 which contains a divide-by-2 clock input stage. Set the generic
|
||||
-- to '0' to enable this mode.
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
-- Primary clock input
|
||||
-- Drive with the target frequency or any integer multiple of it.
|
||||
|
||||
clock_en_i : in std_logic;
|
||||
-- Clock enable
|
||||
-- A '1' on this input qualifies a valid rising edge on clock_i. A '0'
|
||||
-- disables the next rising clock edge, effectivley halting the design
|
||||
-- until the next enabled rising clock edge.
|
||||
-- Can be used to run the core at lower frequencies than applied on
|
||||
-- clock_i.
|
||||
|
||||
res_n_i : in std_logic;
|
||||
-- Asynchronous low active reset input.
|
||||
-- Sets all sequential elements to a known state.
|
||||
|
||||
ce_n_i : in std_logic;
|
||||
-- Chip enable, low active.
|
||||
|
||||
we_n_i : in std_logic;
|
||||
-- Write enable, low active.
|
||||
|
||||
ready_o : out std_logic;
|
||||
-- Ready indication to microprocessor.
|
||||
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
-- Data input
|
||||
-- MSB 0 ... 7 LSB
|
||||
|
||||
aout_o : out signed(0 to 7)
|
||||
-- Audio output, signed vector
|
||||
-- MSB/SIGN 0 ... 7 LSB
|
||||
);
|
||||
|
||||
|
||||
Both 8 bit vector ports are defined (0 to 7) which declares bit 0 to be the
|
||||
MSB and bit 7 to be the LSB. This has been implemented according to TI's data
|
||||
sheet, thus all register/data format figures apply 1:1 for this design.
|
||||
Many systems will flip the system data bus bit wise before it is connected to
|
||||
this PSG. This is simply achieved with the following VHDL construct:
|
||||
|
||||
signal data_s : std_logic_vector(7 downto 0);
|
||||
|
||||
...
|
||||
d_i => data_s,
|
||||
...
|
||||
|
||||
d_i and data_s will be assigned from left to right, resulting in the expected
|
||||
bit assignment:
|
||||
|
||||
d_i data_s
|
||||
0 7
|
||||
1 6
|
||||
...
|
||||
6 1
|
||||
7 0
|
||||
|
||||
|
||||
As this design is fully synchronous, care has to be taken when the design
|
||||
replaces an SN76489 in asynchronous mode. No problems are expected when
|
||||
interfacing the code to other synchronous components.
|
||||
|
||||
|
||||
Design Hierarchy
|
||||
----------------
|
||||
|
||||
sn76489_top
|
||||
|
|
||||
+-- sn76489_latch_ctrl
|
||||
|
|
||||
+-- sn76489_clock_div
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
+-- sn76489_tone
|
||||
| |
|
||||
| \-- sn76489_attentuator
|
||||
|
|
||||
\-- sn76489_noise
|
||||
|
|
||||
\-- sn76489_attentuator
|
||||
|
||||
Resulting compilation sequence:
|
||||
|
||||
sn76489_comp_pack-p.vhd
|
||||
sn76489_top.vhd
|
||||
sn76489_latch_ctrl.vhd
|
||||
sn76489_latch_ctrl-c.vhd
|
||||
sn76489_clock_div.vhd
|
||||
sn76489_clock_div-c.vhd
|
||||
sn76489_attenuator.vhd
|
||||
sn76489_attenuator-c.vhd
|
||||
sn76489_tone.vhd
|
||||
sn76489_tone-c.vhd
|
||||
sn76489_noise.vhd
|
||||
sn76489_noise-c.vhd
|
||||
sn76489_top-c.vhd
|
||||
|
||||
Skip the files containing VHDL configurations when analyzing the code for
|
||||
synthesis.
|
||||
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
* TI Data sheet SN76489.pdf
|
||||
ftp://ftp.whtech.com/datasheets%20&%20manuals/SN76489.pdf
|
||||
|
||||
* John Kortink's article on the SN76489:
|
||||
http://web.inter.nl.net/users/J.Kortink/home/articles/sn76489/
|
||||
|
||||
* Maxim's "SN76489 notes" in
|
||||
http://www.smspower.org/maxim/docs/SN76489.txt
|
||||
@@ -1,114 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_attenuator.vhd,v 1.7 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Attenuator Module
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_attenuator is
|
||||
|
||||
port (
|
||||
attenuation_i : in std_logic_vector(0 to 3);
|
||||
factor_i : in signed(0 to 1);
|
||||
product_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_attenuator;
|
||||
|
||||
|
||||
architecture rtl of sn76489_attenuator is
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process attenuate
|
||||
--
|
||||
-- Purpose:
|
||||
-- Determine the attenuation and generate the resulting product.
|
||||
--
|
||||
-- The maximum attenuation value is 31 which corresponds to volume off.
|
||||
-- As described in the data sheet, the maximum "playing" attenuation is
|
||||
-- 28 = 16 + 8 + 4
|
||||
--
|
||||
-- The table for the volume constants is derived from the following
|
||||
-- formula (each step is 2dB voltage):
|
||||
-- v(0) = 31
|
||||
-- v(n+1) = v(n) * 0.79432823
|
||||
--
|
||||
attenuate: process (attenuation_i,
|
||||
factor_i)
|
||||
|
||||
type volume_t is array (natural range 0 to 15) of natural;
|
||||
constant volume_c : volume_t :=
|
||||
(31, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3, 2, 2, 2, 1, 0);
|
||||
|
||||
variable attenuation_v : unsigned(attenuation_i'range);
|
||||
variable volume_v : signed(product_o'range);
|
||||
|
||||
begin
|
||||
|
||||
attenuation_v := unsigned(attenuation_i);
|
||||
|
||||
-- volume look-up table
|
||||
volume_v := to_signed(volume_c(to_integer(attenuation_v)),
|
||||
product_o'length);
|
||||
|
||||
-- this replaces a multiplier and consumes a bit fewer
|
||||
-- resources
|
||||
case to_integer(factor_i) is
|
||||
when +1 =>
|
||||
product_o <= volume_v;
|
||||
when -1 =>
|
||||
product_o <= -volume_v;
|
||||
when others =>
|
||||
product_o <= (others => '0');
|
||||
end case;
|
||||
|
||||
end process attenuate;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
||||
@@ -1,134 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_clock_div.vhd,v 1.4 2005/10/10 21:51:27 arnim Exp $
|
||||
--
|
||||
-- Clock Divider Circuit
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity sn76489_clock_div is
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clock_en_i : in std_logic;
|
||||
res_n_i : in std_logic;
|
||||
clk_en_o : out boolean
|
||||
);
|
||||
|
||||
end sn76489_clock_div;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture rtl of sn76489_clock_div is
|
||||
|
||||
signal cnt_s,
|
||||
cnt_q : unsigned(3 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential counter element.
|
||||
--
|
||||
seq: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
cnt_q <= (others => '0');
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
cnt_q <= cnt_s;
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process comb
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the combinational counter logic.
|
||||
--
|
||||
comb: process (clock_en_i,
|
||||
cnt_q)
|
||||
begin
|
||||
-- default assignments
|
||||
cnt_s <= cnt_q;
|
||||
clk_en_o <= false;
|
||||
|
||||
if clock_en_i = '1' then
|
||||
|
||||
if cnt_q = 0 then
|
||||
clk_en_o <= true;
|
||||
|
||||
if clock_div_16_g = 1 then
|
||||
cnt_s <= to_unsigned(15, cnt_q'length);
|
||||
elsif clock_div_16_g = 0 then
|
||||
cnt_s <= to_unsigned( 1, cnt_q'length);
|
||||
else
|
||||
-- pragma translate_off
|
||||
assert false
|
||||
report "Generic clock_div_16_g must be either 0 or 1."
|
||||
severity failure;
|
||||
-- pragma translate_on
|
||||
end if;
|
||||
|
||||
else
|
||||
cnt_s <= cnt_q - 1;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end process comb;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
||||
@@ -1,138 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_latch_ctrl.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Latch Control Unit
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity sn76489_latch_ctrl is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
ce_n_i : in std_logic;
|
||||
we_n_i : in std_logic;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
ready_o : out std_logic;
|
||||
tone1_we_o : out boolean;
|
||||
tone2_we_o : out boolean;
|
||||
tone3_we_o : out boolean;
|
||||
noise_we_o : out boolean;
|
||||
r2_o : out std_logic
|
||||
);
|
||||
|
||||
end sn76489_latch_ctrl;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture rtl of sn76489_latch_ctrl is
|
||||
|
||||
signal reg_q : std_logic_vector(0 to 2);
|
||||
signal we_q : boolean;
|
||||
signal ready_q : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential elements.
|
||||
--
|
||||
seq: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
reg_q <= (others => '0');
|
||||
we_q <= false;
|
||||
ready_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
-- READY Flag Output ----------------------------------------------------
|
||||
if ready_q = '0' and we_q then
|
||||
if clk_en_i then
|
||||
-- assert READY when write access happened
|
||||
ready_q <= '1';
|
||||
end if;
|
||||
elsif ce_n_i = '1' then
|
||||
-- deassert READY when access has finished
|
||||
ready_q <= '0';
|
||||
end if;
|
||||
|
||||
-- Register Selection ---------------------------------------------------
|
||||
if ce_n_i = '0' and we_n_i = '0' then
|
||||
if clk_en_i then
|
||||
if d_i(0) = '1' then
|
||||
reg_q <= d_i(1 to 3);
|
||||
end if;
|
||||
we_q <= true;
|
||||
end if;
|
||||
else
|
||||
we_q <= false;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
tone1_we_o <= reg_q(0 to 1) = "00" and we_q;
|
||||
tone2_we_o <= reg_q(0 to 1) = "01" and we_q;
|
||||
tone3_we_o <= reg_q(0 to 1) = "10" and we_q;
|
||||
noise_we_o <= reg_q(0 to 1) = "11" and we_q;
|
||||
|
||||
r2_o <= reg_q(2);
|
||||
|
||||
ready_o <= ready_q
|
||||
when ce_n_i = '0' else
|
||||
'1';
|
||||
|
||||
end rtl;
|
||||
@@ -1,278 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_noise.vhd,v 1.6 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Noise Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_noise is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
we_i : in boolean;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
tone3_ff_i : in std_logic;
|
||||
noise_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_noise;
|
||||
|
||||
architecture rtl of sn76489_noise is
|
||||
|
||||
signal nf_q : std_logic_vector(0 to 1);
|
||||
signal fb_q : std_logic;
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 6);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal shift_source_s,
|
||||
shift_source_q : std_logic;
|
||||
signal shift_rise_edge_s : boolean;
|
||||
|
||||
signal lfsr_q : std_logic_vector(0 to 15);
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process cpu_regs
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the registers writable by the CPU.
|
||||
--
|
||||
cpu_regs: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
nf_q <= (others => '0');
|
||||
fb_q <= '0';
|
||||
a_q <= (others => '1');
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i and we_i then
|
||||
if r2_i = '0' then
|
||||
-- access to control register
|
||||
-- both access types can write to the control register!
|
||||
nf_q <= d_i(6 to 7);
|
||||
fb_q <= d_i(5);
|
||||
|
||||
else
|
||||
-- access to attenuator register
|
||||
-- both access types can write to the attenuator register!
|
||||
a_q <= d_i(4 to 7);
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process cpu_regs;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process freq_gen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the frequency generation components.
|
||||
--
|
||||
freq_gen: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
freq_cnt_q <= (others => '0');
|
||||
freq_ff_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if freq_cnt_q = 0 then
|
||||
-- reload frequency counter according to NF setting
|
||||
case nf_q is
|
||||
when "00" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 2 - 1, freq_cnt_q'length);
|
||||
when "01" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 4 - 1, freq_cnt_q'length);
|
||||
when "10" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 8 - 1, freq_cnt_q'length);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
freq_ff_q <= not freq_ff_q;
|
||||
|
||||
else
|
||||
-- decrement frequency counter
|
||||
freq_cnt_q <= freq_cnt_q - 1;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process freq_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Multiplex the source of the LFSR's shift enable
|
||||
-----------------------------------------------------------------------------
|
||||
shift_source_s <= tone3_ff_i
|
||||
when nf_q = "11" else
|
||||
freq_ff_q;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process rise_edge
|
||||
--
|
||||
-- Purpose:
|
||||
-- Detect the rising edge of the selected LFSR shift source.
|
||||
--
|
||||
rise_edge: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
shift_source_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
shift_source_q <= shift_source_s;
|
||||
end if;
|
||||
end if;
|
||||
end process rise_edge;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
-- detect rising edge on shift source
|
||||
shift_rise_edge_s <= shift_source_q = '0' and shift_source_s = '1';
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process lfsr
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the LFSR that generates noise.
|
||||
-- Note: This implementation shifts the register right, i.e. from index
|
||||
-- 15 towards 0 => bit 15 is the input, bit 0 is the output
|
||||
--
|
||||
-- Tapped bits according to MAME's sn76496.c, implemented in function
|
||||
-- lfsr_tapped_f.
|
||||
--
|
||||
lfsr: process (clock_i, res_n_i)
|
||||
|
||||
function lfsr_tapped_f(lfsr : in std_logic_vector) return std_logic is
|
||||
constant tapped_bits_c : std_logic_vector(0 to 15)
|
||||
-- tapped bits are 0, 2, 15
|
||||
:= "1010000000000001";
|
||||
variable parity_v : std_logic;
|
||||
begin
|
||||
parity_v := '0';
|
||||
|
||||
for idx in lfsr'low to lfsr'high loop
|
||||
parity_v := parity_v xor (lfsr(idx) and tapped_bits_c(idx));
|
||||
end loop;
|
||||
|
||||
return parity_v;
|
||||
end;
|
||||
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
-- reset LFSR to "0000000000000001"
|
||||
lfsr_q <= (others => '0');
|
||||
lfsr_q(lfsr_q'right) <= '1';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if we_i and r2_i = '0' then
|
||||
-- write to noise register
|
||||
-- -> reset LFSR
|
||||
lfsr_q <= (others => '0');
|
||||
lfsr_q(lfsr_q'right) <= '1';
|
||||
|
||||
elsif shift_rise_edge_s then
|
||||
|
||||
-- shift LFSR left towards MSB
|
||||
for idx in lfsr_q'right-1 downto lfsr_q'left loop
|
||||
lfsr_q(idx) <= lfsr_q(idx+1);
|
||||
end loop;
|
||||
|
||||
-- determine input bit
|
||||
if fb_q = '0' then
|
||||
-- "Periodic" Noise
|
||||
-- -> input to LFSR is output
|
||||
lfsr_q(lfsr_q'right) <= lfsr_q(lfsr_q'left);
|
||||
else
|
||||
-- "White" Noise
|
||||
-- -> input to LFSR is parity of tapped bits
|
||||
lfsr_q(lfsr_q'right) <= lfsr_tapped_f(lfsr_q);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process lfsr;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map output of LFSR to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when lfsr_q(0) = '1' else
|
||||
to_signed( 0, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The attenuator itself
|
||||
-----------------------------------------------------------------------------
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
product_o => noise_o
|
||||
);
|
||||
|
||||
end rtl;
|
||||
@@ -1,188 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_tone.vhd,v 1.5 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Tone Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_tone is
|
||||
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clk_en_i : in boolean;
|
||||
res_n_i : in std_logic;
|
||||
we_i : in boolean;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
ff_o : out std_logic;
|
||||
tone_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_tone;
|
||||
|
||||
architecture rtl of sn76489_tone is
|
||||
|
||||
signal f_q : std_logic_vector(0 to 9);
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 9);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
|
||||
function all_zero(a : in std_logic_vector) return boolean is
|
||||
variable result_v : boolean;
|
||||
begin
|
||||
result_v := true;
|
||||
|
||||
for idx in a'low to a'high loop
|
||||
if a(idx) /= '0' then
|
||||
result_v := false;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return result_v;
|
||||
end;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process cpu_regs
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the registers writable by the CPU.
|
||||
--
|
||||
cpu_regs: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
f_q <= (others => '0');
|
||||
a_q <= (others => '1');
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i and we_i then
|
||||
if r2_i = '0' then
|
||||
-- access to frequency register
|
||||
if d_i(0) = '0' then
|
||||
f_q(0 to 5) <= d_i(2 to 7);
|
||||
else
|
||||
f_q(6 to 9) <= d_i(4 to 7);
|
||||
end if;
|
||||
|
||||
else
|
||||
-- access to attenuator register
|
||||
-- both access types can write to the attenuator register!
|
||||
a_q <= d_i(4 to 7);
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process cpu_regs;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process freq_gen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the frequency generation components.
|
||||
--
|
||||
freq_gen: process (clock_i, res_n_i)
|
||||
begin
|
||||
if res_n_i = '0' then
|
||||
freq_cnt_q <= (others => '0');
|
||||
freq_ff_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if freq_cnt_q = 0 then
|
||||
-- update counter from frequency register
|
||||
freq_cnt_q <= unsigned(f_q);
|
||||
|
||||
-- and toggle the frequency flip-flop if enabled
|
||||
if not all_zero(f_q) then
|
||||
freq_ff_q <= not freq_ff_q;
|
||||
else
|
||||
-- if frequency setting is 0, then keep flip-flop at +1
|
||||
freq_ff_q <= '1';
|
||||
end if;
|
||||
|
||||
else
|
||||
-- decrement frequency counter
|
||||
freq_cnt_q <= freq_cnt_q - 1;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process freq_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map frequency flip-flop to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when freq_ff_q = '1' else
|
||||
to_signed(-1, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The attenuator itself
|
||||
-----------------------------------------------------------------------------
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
product_o => tone_o
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
ff_o <= freq_ff_q;
|
||||
|
||||
end rtl;
|
||||
@@ -1,200 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's SN76489AN.
|
||||
--
|
||||
-- $Id: sn76489_top.vhd,v 1.9 2006/02/27 20:30:10 arnim Exp $
|
||||
--
|
||||
-- Chip Toplevel
|
||||
--
|
||||
-- References:
|
||||
--
|
||||
-- * TI Data sheet SN76489.pdf
|
||||
-- ftp://ftp.whtech.com/datasheets%20&%20manuals/SN76489.pdf
|
||||
--
|
||||
-- * John Kortink's article on the SN76489:
|
||||
-- http://web.inter.nl.net/users/J.Kortink/home/articles/sn76489/
|
||||
--
|
||||
-- * Maxim's "SN76489 notes" in
|
||||
-- http://www.smspower.org/maxim/docs/SN76489.txt
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2005, 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity sn76489_top is
|
||||
|
||||
generic (
|
||||
clock_div_16_g : integer := 1
|
||||
);
|
||||
port (
|
||||
clock_i : in std_logic;
|
||||
clock_en_i : in std_logic;
|
||||
res_n_i : in std_logic;
|
||||
ce_n_i : in std_logic;
|
||||
we_n_i : in std_logic;
|
||||
ready_o : out std_logic;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
aout_o : out signed(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_top;
|
||||
|
||||
architecture struct of sn76489_top is
|
||||
|
||||
signal clk_en_s : boolean;
|
||||
|
||||
signal tone1_we_s,
|
||||
tone2_we_s,
|
||||
tone3_we_s,
|
||||
noise_we_s : boolean;
|
||||
signal r2_s : std_logic;
|
||||
|
||||
signal tone1_s,
|
||||
tone2_s,
|
||||
tone3_s,
|
||||
noise_s : signed(0 to 7);
|
||||
|
||||
signal tone3_ff_s : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Clock Divider
|
||||
-----------------------------------------------------------------------------
|
||||
clock_div_b : entity work.sn76489_clock_div
|
||||
generic map (
|
||||
clock_div_16_g => clock_div_16_g
|
||||
)
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clock_en_i => clock_en_i,
|
||||
res_n_i => res_n_i,
|
||||
clk_en_o => clk_en_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Latch Control = CPU Interface
|
||||
-----------------------------------------------------------------------------
|
||||
latch_ctrl_b : entity work.sn76489_latch_ctrl
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
ce_n_i => ce_n_i,
|
||||
we_n_i => we_n_i,
|
||||
d_i => d_i,
|
||||
ready_o => ready_o,
|
||||
tone1_we_o => tone1_we_s,
|
||||
tone2_we_o => tone2_we_s,
|
||||
tone3_we_o => tone3_we_s,
|
||||
noise_we_o => noise_we_s,
|
||||
r2_o => r2_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 1
|
||||
-----------------------------------------------------------------------------
|
||||
tone1_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone1_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => open,
|
||||
tone_o => tone1_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 2
|
||||
-----------------------------------------------------------------------------
|
||||
tone2_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone2_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => open,
|
||||
tone_o => tone2_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Tone Channel 3
|
||||
-----------------------------------------------------------------------------
|
||||
tone3_b : entity work.sn76489_tone
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => tone3_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
ff_o => tone3_ff_s,
|
||||
tone_o => tone3_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Noise Channel
|
||||
-----------------------------------------------------------------------------
|
||||
noise_b : entity work.sn76489_noise
|
||||
port map (
|
||||
clock_i => clock_i,
|
||||
clk_en_i => clk_en_s,
|
||||
res_n_i => res_n_i,
|
||||
we_i => noise_we_s,
|
||||
d_i => d_i,
|
||||
r2_i => r2_s,
|
||||
tone3_ff_i => tone3_ff_s,
|
||||
noise_o => noise_s
|
||||
);
|
||||
|
||||
|
||||
aout_o <= tone1_s + tone2_s + tone3_s + noise_s;
|
||||
|
||||
end struct;
|
||||
@@ -45,22 +45,24 @@
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity sn76489_attenuator is
|
||||
|
||||
port (
|
||||
attenuation_i : in std_logic_vector(0 to 3);
|
||||
factor_i : in signed(0 to 1);
|
||||
product_o : out signed(0 to 7)
|
||||
factor_i : in std_logic;
|
||||
product_o : out std_logic_vector(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_attenuator;
|
||||
|
||||
|
||||
architecture rtl of sn76489_attenuator is
|
||||
|
||||
type volume_t is array (natural range 0 to 15) of natural;
|
||||
constant volume_c : volume_t := (31, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3, 2, 2, 2, 1, 0);
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -78,37 +80,8 @@ begin
|
||||
-- v(0) = 31
|
||||
-- v(n+1) = v(n) * 0.79432823
|
||||
--
|
||||
attenuate: process (attenuation_i,
|
||||
factor_i)
|
||||
|
||||
type volume_t is array (natural range 0 to 15) of natural;
|
||||
constant volume_c : volume_t :=
|
||||
(31, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3, 2, 2, 2, 1, 0);
|
||||
|
||||
variable attenuation_v : unsigned(attenuation_i'range);
|
||||
variable volume_v : signed(product_o'range);
|
||||
|
||||
begin
|
||||
|
||||
attenuation_v := unsigned(attenuation_i);
|
||||
|
||||
-- volume look-up table
|
||||
volume_v := to_signed(volume_c(to_integer(attenuation_v)),
|
||||
product_o'length);
|
||||
|
||||
-- this replaces a multiplier and consumes a bit fewer
|
||||
-- resources
|
||||
case to_integer(factor_i) is
|
||||
when +1 =>
|
||||
product_o <= volume_v;
|
||||
when -1 =>
|
||||
product_o <= -volume_v;
|
||||
when others =>
|
||||
product_o <= (others => '0');
|
||||
end case;
|
||||
|
||||
end process attenuate;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
product_o <= conv_std_logic_vector(volume_c(conv_integer(attenuation_i)), product_o'length) when factor_i = '1'
|
||||
else (others => '0');
|
||||
|
||||
end rtl;
|
||||
|
||||
@@ -45,7 +45,9 @@
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity sn76489_clock_div is
|
||||
|
||||
@@ -68,7 +70,7 @@ use ieee.numeric_std.all;
|
||||
architecture rtl of sn76489_clock_div is
|
||||
|
||||
signal cnt_s,
|
||||
cnt_q : unsigned(3 downto 0);
|
||||
cnt_q : std_logic_vector(3 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
@@ -109,9 +111,9 @@ begin
|
||||
clk_en_o <= true;
|
||||
|
||||
if clock_div_16_g = 1 then
|
||||
cnt_s <= to_unsigned(15, cnt_q'length);
|
||||
cnt_s <= conv_std_logic_vector(15, cnt_q'length);
|
||||
elsif clock_div_16_g = 0 then
|
||||
cnt_s <= to_unsigned( 1, cnt_q'length);
|
||||
cnt_s <= conv_std_logic_vector( 1, cnt_q'length);
|
||||
else
|
||||
-- pragma translate_off
|
||||
assert false
|
||||
|
||||
@@ -75,6 +75,7 @@ architecture rtl of sn76489_latch_ctrl is
|
||||
signal reg_q : std_logic_vector(0 to 2);
|
||||
signal we_q : boolean;
|
||||
signal ready_q : std_logic;
|
||||
signal we_n_d : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
@@ -92,6 +93,12 @@ begin
|
||||
ready_q <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
we_n_d <= we_n_i;
|
||||
elsif we_n_i = '1' then
|
||||
we_n_d <= '1';
|
||||
end if;
|
||||
|
||||
-- READY Flag Output ----------------------------------------------------
|
||||
if ready_q = '0' and we_q then
|
||||
if clk_en_i then
|
||||
@@ -104,15 +111,15 @@ begin
|
||||
end if;
|
||||
|
||||
-- Register Selection ---------------------------------------------------
|
||||
if ce_n_i = '0' and we_n_i = '0' then
|
||||
if clk_en_i then
|
||||
if clk_en_i then
|
||||
if ce_n_i = '0' and we_n_d = '1' and we_n_i = '0' then
|
||||
if d_i(0) = '1' then
|
||||
reg_q <= d_i(1 to 3);
|
||||
end if;
|
||||
we_q <= true;
|
||||
else
|
||||
we_q <= false;
|
||||
end if;
|
||||
else
|
||||
we_q <= false;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
@@ -45,8 +45,9 @@
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity sn76489_noise is
|
||||
|
||||
@@ -58,26 +59,25 @@ entity sn76489_noise is
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
tone3_ff_i : in std_logic;
|
||||
noise_o : out signed(0 to 7)
|
||||
noise_o : out std_logic_vector(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_noise;
|
||||
|
||||
|
||||
architecture rtl of sn76489_noise is
|
||||
|
||||
signal nf_q : std_logic_vector(0 to 1);
|
||||
signal fb_q : std_logic;
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 6);
|
||||
signal freq_cnt_q : std_logic_vector(0 to 6);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal shift_source_s,
|
||||
shift_source_q : std_logic;
|
||||
signal shift_rise_edge_s : boolean;
|
||||
|
||||
signal lfsr_q : std_logic_vector(0 to 15);
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
signal lfsr_q : std_logic_vector(0 to 14);
|
||||
|
||||
begin
|
||||
|
||||
@@ -133,11 +133,11 @@ begin
|
||||
-- reload frequency counter according to NF setting
|
||||
case nf_q is
|
||||
when "00" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 2 - 1, freq_cnt_q'length);
|
||||
freq_cnt_q <= conv_std_logic_vector(16 * 2 - 1, freq_cnt_q'length);
|
||||
when "01" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 4 - 1, freq_cnt_q'length);
|
||||
freq_cnt_q <= conv_std_logic_vector(16 * 4 - 1, freq_cnt_q'length);
|
||||
when "10" =>
|
||||
freq_cnt_q <= to_unsigned(16 * 8 - 1, freq_cnt_q'length);
|
||||
freq_cnt_q <= conv_std_logic_vector(16 * 8 - 1, freq_cnt_q'length);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@@ -202,9 +202,9 @@ begin
|
||||
lfsr: process (clock_i, res_n_i)
|
||||
|
||||
function lfsr_tapped_f(lfsr : in std_logic_vector) return std_logic is
|
||||
constant tapped_bits_c : std_logic_vector(0 to 15)
|
||||
constant tapped_bits_c : std_logic_vector(0 to 14)
|
||||
-- tapped bits are 0, 2, 15
|
||||
:= "1010000000000001";
|
||||
:= "110000000000000";
|
||||
variable parity_v : std_logic;
|
||||
begin
|
||||
parity_v := '0';
|
||||
@@ -253,17 +253,6 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
end process lfsr;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map output of LFSR to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when lfsr_q(0) = '1' else
|
||||
to_signed( 0, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The attenuator itself
|
||||
@@ -271,7 +260,7 @@ begin
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
factor_i => lfsr_q(0),
|
||||
product_o => noise_o
|
||||
);
|
||||
|
||||
|
||||
@@ -45,8 +45,9 @@
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity sn76489_tone is
|
||||
|
||||
@@ -58,7 +59,7 @@ entity sn76489_tone is
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
r2_i : in std_logic;
|
||||
ff_o : out std_logic;
|
||||
tone_o : out signed(0 to 7)
|
||||
tone_o : out std_logic_vector(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_tone;
|
||||
@@ -67,10 +68,9 @@ architecture rtl of sn76489_tone is
|
||||
|
||||
signal f_q : std_logic_vector(0 to 9);
|
||||
signal a_q : std_logic_vector(0 to 3);
|
||||
signal freq_cnt_q : unsigned(0 to 9);
|
||||
signal freq_cnt_q : std_logic_vector(0 to 9);
|
||||
signal freq_ff_q : std_logic;
|
||||
|
||||
signal freq_s : signed(0 to 1);
|
||||
signal output_ff : std_logic;
|
||||
|
||||
function all_zero(a : in std_logic_vector) return boolean is
|
||||
variable result_v : boolean;
|
||||
@@ -134,21 +134,25 @@ begin
|
||||
if res_n_i = '0' then
|
||||
freq_cnt_q <= (others => '0');
|
||||
freq_ff_q <= '0';
|
||||
output_ff <= '0';
|
||||
|
||||
elsif clock_i'event and clock_i = '1' then
|
||||
if clk_en_i then
|
||||
if freq_cnt_q = 0 then
|
||||
if freq_cnt_q = 1 then
|
||||
-- update counter from frequency register
|
||||
freq_cnt_q <= unsigned(f_q);
|
||||
freq_cnt_q <= f_q;
|
||||
|
||||
-- and toggle the frequency flip-flop if enabled
|
||||
if not all_zero(f_q) then
|
||||
if (f_q > 5) then
|
||||
freq_ff_q <= not freq_ff_q;
|
||||
else
|
||||
-- if frequency setting is 0, then keep flip-flop at +1
|
||||
freq_ff_q <= '1';
|
||||
end if;
|
||||
|
||||
-- either way toggle the output_ff - this is used to clock noise
|
||||
output_ff <= not output_ff;
|
||||
|
||||
else
|
||||
-- decrement frequency counter
|
||||
freq_cnt_q <= freq_cnt_q - 1;
|
||||
@@ -157,16 +161,6 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
end process freq_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Map frequency flip-flop to signed value for attenuator.
|
||||
-----------------------------------------------------------------------------
|
||||
freq_s <= to_signed(+1, 2)
|
||||
when freq_ff_q = '1' else
|
||||
to_signed(-1, 2);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -175,7 +169,7 @@ begin
|
||||
attenuator_b : entity work.sn76489_attenuator
|
||||
port map (
|
||||
attenuation_i => a_q,
|
||||
factor_i => freq_s,
|
||||
factor_i => freq_ff_q,
|
||||
product_o => tone_o
|
||||
);
|
||||
|
||||
@@ -183,6 +177,6 @@ begin
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
ff_o <= freq_ff_q;
|
||||
ff_o <= output_ff;
|
||||
|
||||
end rtl;
|
||||
|
||||
@@ -56,11 +56,9 @@
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity sn76489_top is
|
||||
|
||||
@@ -75,11 +73,15 @@ entity sn76489_top is
|
||||
we_n_i : in std_logic;
|
||||
ready_o : out std_logic;
|
||||
d_i : in std_logic_vector(0 to 7);
|
||||
aout_o : out signed(0 to 7)
|
||||
aout_o : out std_logic_vector(0 to 7)
|
||||
);
|
||||
|
||||
end sn76489_top;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture struct of sn76489_top is
|
||||
|
||||
signal clk_en_s : boolean;
|
||||
@@ -93,7 +95,7 @@ architecture struct of sn76489_top is
|
||||
signal tone1_s,
|
||||
tone2_s,
|
||||
tone3_s,
|
||||
noise_s : signed(0 to 7);
|
||||
noise_s : std_logic_vector(0 to 7);
|
||||
|
||||
signal tone3_ff_s : std_logic;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user