1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-04-16 07:56:43 +00:00

Organize Files

This commit is contained in:
Marcel
2019-07-23 21:42:55 +02:00
parent 462f0490bd
commit 48f696d075
59 changed files with 1215 additions and 17615 deletions

View File

@@ -18,7 +18,7 @@
#
# Quartus II 64-Bit
# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition
# Date created = 02:08:17 July 22, 2019
# Date created = 21:40:59 July 23, 2019
#
# -------------------------------------------------------------------------- #
#
@@ -49,9 +49,11 @@ set_global_assignment -name VHDL_FILE rtl/oricatmos.vhd
set_global_assignment -name VHDL_FILE rtl/ula.vhd
set_global_assignment -name VHDL_FILE rtl/ay8912.vhd
set_global_assignment -name VHDL_FILE rtl/m6522.vhd
set_global_assignment -name VHDL_FILE rtl/rom/BASIC.vhd
set_global_assignment -name VHDL_FILE rtl/ram48k.vhd
set_global_assignment -name VHDL_FILE rtl/video.vhd
set_global_assignment -name VHDL_FILE rtl/rom/BASIC11.vhd
set_global_assignment -name VHDL_FILE rtl/rom/BASIC10.vhd
set_global_assignment -name VHDL_FILE rtl/rom/BASIC22.vhd
set_global_assignment -name VHDL_FILE rtl/T65/t65_MCode.vhd
set_global_assignment -name VHDL_FILE rtl/T65/t65_alu.vhd
set_global_assignment -name VHDL_FILE rtl/T65/t65.vhd
@@ -214,10 +216,10 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
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_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
# end DESIGN_PARTITION(Top)
# -------------------------
# end ENTITY(OricAtmos_MiST)
# --------------------------
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
# --------------------------

View File

@@ -0,0 +1,3 @@
Oric 1 / Atmos
only 32768 kb ram

View File

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 176 KiB

View File

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

View File

@@ -55,9 +55,6 @@
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library WORK;
library STD;
USE STD.TEXTIO.ALL;
entity oricatmos is
@@ -67,8 +64,6 @@ entity oricatmos is
K7_TAPEIN : in std_logic;
K7_TAPEOUT : out std_logic;
K7_REMOTE : out std_logic;
-- PSG_RIGHT : out std_logic_vector(15 downto 0);
-- PSG_LEFT : out std_logic_vector(15 downto 0);
PSG_OUT : out std_logic_vector(15 downto 0);
VIDEO_R : out std_logic;
VIDEO_G : out std_logic;
@@ -146,22 +141,19 @@ architecture RTL of oricatmos is
signal lSRAM_D : std_logic_vector(7 downto 0);
signal ENA_1MHZ : std_logic;
signal ROM_DO : std_logic_vector(7 downto 0);
signal ROM_DO : std_logic_vector(7 downto 0);
signal ad : std_logic_vector(15 downto 0);
signal SRAM_DO : std_logic_vector(7 downto 0);
signal break : std_logic;
signal ad : std_logic_vector(15 downto 0);
signal SRAM_DO : std_logic_vector(7 downto 0);
signal break : std_logic;
component keyboard port (
clk_24 : in std_logic;
clk : in std_logic;
reset : in std_logic;
ps2_key : in std_logic_vector(10 downto 0);
row : in std_logic_vector(7 downto 0);
col : in std_logic_vector(2 downto 0);
ROWbit : out std_logic_vector(7 downto 0);
swrst : out std_logic
@@ -171,184 +163,141 @@ end component;
begin
RESETn <= not RESET;
------------------------------------------------------------
-- GESTION CPU 6502
------------------------------------------------------------
cpu : entity work.T65
port map (
Mode => "00",
Res_n => RESETn,
Enable => '1',
Clk => ula_phi2,
Rdy => '1',
Abort_n => '1',
IRQ_n => cpu_irq,
NMI_n => not break,
SO_n => '1',
R_W_n => cpu_rw,
A => cpu_ad,
DI => cpu_di,
DO => cpu_do
);
inst_cpu : entity work.T65
port map (
Mode => "00",
Res_n => RESETn,
Enable => '1',
Clk => ula_phi2,
Rdy => '1',
Abort_n => '1',
IRQ_n => cpu_irq,
NMI_n => not break,
SO_n => '1',
R_W_n => cpu_rw,
A => cpu_ad,
DI => cpu_di,
DO => cpu_do
);
ad <= ula_AD_SRAM when ula_PHI2 = '0' else cpu_ad(15 downto 0);
inst_ram : entity work.ram48k
inst_ram : entity work.ram48k
port map(
clk => CLK_IN,
cs => ula_CE_SRAM,
oe => ula_OE_SRAM,
we => ula_WE_SRAM,
addr => ad,
di => cpu_do,
do => SRAM_DO
);
clk => CLK_IN,
cs => ula_CE_SRAM,
oe => ula_OE_SRAM,
we => ula_WE_SRAM,
addr => ad,
di => cpu_do,
do => SRAM_DO
);
inst_rom : entity work.BASIC
inst_rom : entity work.BASIC11
port map (
clk => CLK_IN,
addr => cpu_ad(13 downto 0),
data => ROM_DO
);
clk => CLK_IN,
addr => cpu_ad(13 downto 0),
data => ROM_DO
);
------------------------------------------------------------
-- GESTION ULA
------------------------------------------------------------
ulag : entity work.ULA
port map (
CLK => CLK_IN,
PHI2 => ula_PHI2,
CLK_4 => ula_CLK_4,
RW => cpu_rw,
RESETn => RESETn,
MAPn => '1',
DB => SRAM_DO,
ADDR => cpu_ad(15 downto 0),
inst_ula : entity work.ULA
port map (
CLK => CLK_IN,
PHI2 => ula_PHI2,
CLK_4 => ula_CLK_4,
RW => cpu_rw,
RESETn => RESETn,
MAPn => '1',
DB => SRAM_DO,
ADDR => cpu_ad(15 downto 0),
SRAM_AD => ula_AD_SRAM,
SRAM_OE => ula_OE_SRAM,
SRAM_CE => ula_CE_SRAM,
SRAM_WE => ula_WE_SRAM,
LATCH_SRAM => ula_LATCH_SRAM,
CSIOn => ula_CSIOn,
CSROMn => ula_CSROMn,
CSRAMn => ula_CSRAMn,
R => VIDEO_R,
G => VIDEO_G,
B => VIDEO_B,
SYNC => VIDEO_SYNC,
HSYNC => VIDEO_HSYNC,
VSYNC => VIDEO_VSYNC
);
SRAM_AD => ula_AD_SRAM,
SRAM_OE => ula_OE_SRAM,
SRAM_CE => ula_CE_SRAM,
SRAM_WE => ula_WE_SRAM,
LATCH_SRAM => ula_LATCH_SRAM,
CSIOn => ula_CSIOn,
CSROMn => ula_CSROMn,
CSRAMn => ula_CSRAMn,
R => VIDEO_R,
G => VIDEO_G,
B => VIDEO_B,
SYNC => VIDEO_SYNC,
HSYNC => VIDEO_HSYNC,
VSYNC => VIDEO_VSYNC
);
------------------------------------------------------------
-- GESTION VIA
------------------------------------------------------------
ula_CSIO <= not(ula_CSIOn);
inst_via : entity work.M6522
ula_CSIO <= not(ula_CSIOn);
inst_via : entity work.M6522
port map (
I_RS => cpu_ad(3 downto 0),
I_DATA => cpu_do(7 downto 0),
O_DATA => VIA_DO,
O_DATA_OE_L => open,
I_RW_L => cpu_rw,
I_CS1 => ula_CSIO,
I_CS2_L => ula_IOCONTROL,
O_IRQ_L => cpu_irq, -- note, not open drain
-- PORT A
I_CA1 => '1', -- PRT_ACK
I_CA2 => '1', -- psg_bdir
O_CA2 => psg_bdir, -- via_ca2_out
O_CA2_OE_L => open,
I_PA => via_pa_in,
O_PA => via_pa_out,
O_PA_OE_L => via_pa_out_oe,
-- PORT B
I_CB1 => K7_TAPEIN,
O_CB1 => via_cb1_out,
O_CB1_OE_L => via_cb1_oe_l,
I_CB2 => '1',
O_CB2 => via_cb2_out,
O_CB2_OE_L => via_cb2_oe_l,
I_PB => via_in,
O_PB => via_out,
O_PB_OE_L => via_oe_l,
--
RESET_L => RESETn,
I_P2_H => ula_phi2,
ENA_4 => '1',
CLK => ula_CLK_4
);
I_RS => cpu_ad(3 downto 0),
I_DATA => cpu_do(7 downto 0),
O_DATA => VIA_DO,
I_RW_L => cpu_rw,
I_CS1 => ula_CSIO,
I_CS2_L => ula_IOCONTROL,
O_IRQ_L => cpu_irq, -- note, not open drain
I_CA1 => '1', -- PRT_ACK
I_CA2 => '1', -- psg_bdir
O_CA2 => psg_bdir, -- via_ca2_out
I_PA => via_pa_in,
O_PA => via_pa_out,
O_PA_OE_L => via_pa_out_oe,
I_CB1 => K7_TAPEIN,
O_CB1 => via_cb1_out,
O_CB1_OE_L => via_cb1_oe_l,
I_CB2 => '1',
O_CB2 => via_cb2_out,
O_CB2_OE_L => via_cb2_oe_l,
I_PB => via_in,
O_PB => via_out,
O_PB_OE_L => via_oe_l,
RESET_L => RESETn,
I_P2_H => ula_phi2,
ENA_4 => '1',
CLK => ula_CLK_4
);
inst_psg : entity work.ay8912
inst_psg : entity work.ay8912
port map (
cpuclk => CLK_IN,
reset => RESETn,
cs => '1',
bc0 => psg_bdir,
bdir => via_cb2_out,
Data_in => via_pa_out,
Data_out => via_pa_in,
IO_A => x"FF",
chanA => open,
chanB => open,
chanC => open,
-- Arechts => PSG_RIGHT,
-- Alinks => PSG_LEFT,
Amono => PSG_OUT
);
cpuclk => CLK_IN,
reset => RESETn,
cs => '1',
bc0 => psg_bdir,
bdir => via_cb2_out,
Data_in => via_pa_out,
Data_out => via_pa_in,
IO_A => x"FF",
Amono => PSG_OUT
);
inst_key : keyboard
inst_key : keyboard
port map(
clk_24 => CLK_IN,
clk => ula_phi2,
reset => not RESETn,
ps2_key => ps2_key,
row => via_pa_out,
col => via_out(2 downto 0),
ROWbit => KEY_ROW,
swrst => break
);
clk_24 => CLK_IN,
clk => ula_phi2,
reset => not RESETn,
ps2_key => ps2_key,
row => via_pa_out,
col => via_out(2 downto 0),
ROWbit => KEY_ROW,
swrst => break
);
-- Keyboard
via_in <= x"F7" when (KEY_ROW or via_pa_out) = x"FF" else x"FF";
------------------------------------------------------------
-- GESTION PORT K7
------------------------------------------------------------
K7_TAPEOUT <= via_out(7);
K7_REMOTE <= via_out(6);
via_in <= x"F7" when (KEY_ROW or via_pa_out) = x"FF" else x"FF";
K7_TAPEOUT <= via_out(7);
K7_REMOTE <= via_out(6);
ula_IOCONTROL <= '0'; -- ula_IOCONTROL <= IOCONTROL;
process
begin
wait until rising_edge(clk_in);
-- expansion port
if cpu_rw = '1' and ula_IOCONTROL = '1' and ula_CSIOn = '0' then
cpu_di <= SRAM_DO;
-- Via
process begin
wait until rising_edge(clk_in);
if cpu_rw = '1' and ula_IOCONTROL = '1' and ula_CSIOn = '0' then
cpu_di <= SRAM_DO;-- expansion port
elsif cpu_rw = '1' and ula_IOCONTROL = '0' and ula_CSIOn = '0' and ula_LATCH_SRAM = '0' then
cpu_di <= VIA_DO;
-- ROM
elsif cpu_rw = '1' and ula_IOCONTROL = '0' and ula_CSROMn = '0' then
cpu_di <= ROM_DO;
-- Read data
cpu_di <= VIA_DO;-- Via
elsif cpu_rw = '1' and ula_IOCONTROL = '0' and ula_CSROMn = '0' then
cpu_di <= ROM_DO; -- ROM
elsif cpu_rw = '1' and ula_IOCONTROL = '0' and ula_phi2 = '1' and ula_LATCH_SRAM = '0' then
cpu_di <= SRAM_DO;
cpu_di <= SRAM_DO;-- Read data
end if;
end process;
end process;
end RTL;

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
library ieee;
use ieee.std_logic_1164.all,ieee.numeric_std.all;
entity BASIC is
entity BASIC22 is
port (
clk : in std_logic;
addr : in std_logic_vector(13 downto 0);
@@ -9,7 +9,7 @@ port (
);
end entity;
architecture prom of BASIC is
architecture prom of BASIC22 is
type rom is array(0 to 16383) of std_logic_vector(7 downto 0);
signal rom_data: rom := (
X"4C",X"CC",X"EC",X"4C",X"71",X"C4",X"72",X"C9",X"91",X"C6",X"86",X"E9",X"D0",X"E9",X"15",X"CD",

File diff suppressed because it is too large Load Diff

107
common/IO/PIA8255.v Normal file
View File

@@ -0,0 +1,107 @@
/****************************************************************************
PIA 8255
Version 050111
Copyright(C) 2004,2005 Tatsuyuki Satoh
This software is provided "AS IS", with NO WARRANTY.
NON-COMMERCIAL USE ONLY
Histry:
2005. 1.11 Ver.0.1
Note:
Distributing all and a part is prohibited.
Because this version is developer-alpha version.
mode 0,1,2 handshake is not supported , mode 3 bit I/O only
****************************************************************************/
module PIA8255(
I_RESET,
I_A,
I_CS,
I_RD,
I_WR,
I_D,
O_D,
//
I_PA,O_PA,
//
I_PB,O_PB,
//
I_PC,O_PC
);
input I_RESET;
input [1:0] I_A;
input I_CS;
input I_WR;
input I_RD;
input [7:0] I_D;
output [7:0] O_D;
input [7:0] I_PA,I_PB,I_PC;
output [7:0] O_PA,O_PB,O_PC;
////////////////////////////////////////////////////////////////////////////
reg [7:0] pa_o,pb_o,pc_o;
reg pa_dir , pb_dir , pcl_dir , pch_dir;
reg [1:0] pa_mode;
reg pb_mode;
// wirte data
always @(negedge I_WR or posedge I_RESET)
begin
if(I_RESET) begin
pa_o <= 8'h00;
pb_o <= 8'h00;
pc_o <= 8'h00;
pa_mode <= 2'b00;
pa_dir <= 1'b1;
pcl_dir <= 1'b1;
pb_mode <= 1'b0;
pb_dir <= 1'b1;
pch_dir <= 1'b1;
end else if(I_CS) begin
case(I_A)
2'b00:pa_o <= I_D;
2'b01:pb_o <= I_D;
2'b10:pc_o <= I_D;
2'b11:begin
if(I_D[7])
begin
// mode set
pa_mode <= I_D[6:5];
pa_dir <= I_D[4];
pch_dir <= I_D[3];
pb_mode <= I_D[2];
pb_dir <= I_D[1];
pcl_dir <= I_D[0];
end else begin
// bit operation
pc_o[I_D[3:1]] <= I_D[0];
end
end
endcase
end
end
// read data
//wire read_gate = I_CS & I_RD;
wire [7:0] pa_r = pa_dir ? I_PA : pa_o;
wire [7:0] pb_r = pb_dir ? I_PB : pb_o;
wire [7:0] pc_r = { pch_dir ? I_PC[7:4] : pc_o[7:4] , pcl_dir ? I_PC[3:0] : pc_o[3:0] };
wire [7:0] ct_r = {1'b0,pa_mode,pa_dir,pcl_dir,pb_mode,pb_dir,pch_dir};
assign O_D = (I_A==2'b00) ? pa_r :
(I_A==2'b01) ? pb_r :
(I_A==2'b10) ? pc_r :
ct_r;
// port output
assign O_PA = pa_o;
assign O_PB = pb_o;
assign O_PC = pc_o;
endmodule

138
common/IO/i8253.vhd Normal file
View File

@@ -0,0 +1,138 @@
--
-- i8253.vhd
--
-- Intel 8253 (PIT:Programmable Interval Timer) partiality compatible module
-- for MZ-700 on FPGA
--
-- PIT main module
--
-- Nibbles Lab. 2005
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity i8253 is
Port ( RST : in std_logic;
CLK : in std_logic;
A : in std_logic_vector(1 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
CS : in std_logic;
WR : in std_logic;
RD : in std_logic;
CLK0 : in std_logic;
GATE0 : in std_logic;
OUT0 : out std_logic;
CLK1 : in std_logic;
GATE1 : in std_logic;
OUT1 : out std_logic;
CLK2 : in std_logic;
GATE2 : in std_logic;
OUT2 : out std_logic);
end i8253;
architecture Behavioral of i8253 is
signal WRD0 : std_logic;
signal WRD1 : std_logic;
signal WRD2 : std_logic;
signal WRM0 : std_logic;
signal WRM1 : std_logic;
signal WRM2 : std_logic;
--signal RD0 : std_logic;
signal RD1 : std_logic;
signal RD2 : std_logic;
signal DO0 : std_logic_vector(7 downto 0);
signal DO1 : std_logic_vector(7 downto 0);
signal DO2 : std_logic_vector(7 downto 0);
component counter0
Port ( DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
WRD : in std_logic;
WRM : in std_logic;
KCLK : in std_logic;
CLK : in std_logic;
GATE : in std_logic;
POUT : out std_logic);
end component;
component counter1
Port ( DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
WRD : in std_logic;
WRM : in std_logic;
KCLK : in std_logic;
CLK : in std_logic;
GATE : in std_logic;
POUT : out std_logic);
end component;
component counter2
Port ( DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
WRD : in std_logic;
WRM : in std_logic;
KCLK : in std_logic;
RD : in std_logic;
CLK : in std_logic;
GATE : in std_logic;
POUT : out std_logic);
end component;
begin
WRD0<=WR when CS='0' and A="00" else '1';
WRD1<=WR when CS='0' and A="01" else '1';
WRD2<=WR when CS='0' and A="10" else '1';
WRM0<=WR when CS='0' and A="11" and DI(7 downto 6)="00" else '1';
WRM1<=WR when CS='0' and A="11" and DI(7 downto 6)="01" else '1';
WRM2<=WR when CS='0' and A="11" and DI(7 downto 6)="10" else '1';
-- RD0<=RD when CS='0' and A="00" else '1';
RD1<=RD when CS='0' and A="01" else '1';
RD2<=RD when CS='0' and A="10" else '1';
DO<=DO0 when CS='0' and A="00" else
DO1 when CS='0' and A="01" else
DO2 when CS='0' and A="10" else (others=>'1');
CTR0 : counter0 port map (
DI => DI,
DO => DO0,
WRD => WRD0,
WRM => WRM0,
KCLK => CLK,
CLK => CLK0,
GATE => GATE0,
POUT => OUT0);
CTR1 : counter1 port map (
DI => DI,
DO => DO1,
WRD => WRD1,
WRM => WRM1,
KCLK => CLK,
CLK => CLK1,
GATE => GATE1,
POUT => OUT1);
CTR2 : counter2 port map (
DI => DI,
DO => DO2,
WRD => WRD2,
WRM => WRM2,
KCLK => CLK,
RD => RD2,
CLK => CLK2,
GATE => GATE2,
POUT => OUT2);
end Behavioral;

174
common/RIOT.sv Normal file
View File

@@ -0,0 +1,174 @@
/* Atari on an FPGA
Masters of Engineering Project
Cornell University, 2007
Daniel Beer
RIOT.v
Redesign of the MOS 6532 chip. Provides RAM, I/O and timers to the Atari.
*/
`timescale 1ns / 1ps
`include "riot.vh"
module RIOT(A, // Address bus input
Din, // Data bus input
Dout, // Data bus output
CS, // Chip select input
CS_n, // Active low chip select input
R_W_n, // Active low read/write input
RS_n, // Active low rom select input
RES_n, // Active low reset input
IRQ_n, // Active low interrupt output
CLK, // Clock input
PAin, // 8 bit port A input
PAout, // 8 bit port A output
PBin, // 8 bit port B input
PBout);// 8 bit port B output
input [6:0] A;
input [7:0] Din;
output [7:0] Dout;
input CS, CS_n, R_W_n, RS_n, RES_n, CLK;
output IRQ_n;
input [7:0] PAin, PBin;
output [7:0] PAout, PBout; // Output register
reg [7:0] Dout; // RAM allocation
reg [7:0] RAM[127:0]; // I/O registers
reg [7:0] DRA, DRB; // Data registers
reg [7:0] DDRA, DDRB; // Data direction registers
wire PA7;
reg R_PA7;
assign PA7 = (PAin[7] & ~DDRA[7]) | (DRA[7] & DDRA[7]);
assign PAout = DRA & DDRA;
assign PBout = DRB & DDRB;
// Timer registers
reg [8:0] Timer;
reg [9:0] Prescaler;
reg [1:0] Timer_Mode;
reg Timer_Int_Flag, PA7_Int_Flag, Timer_Int_Enable, PA7_Int_Enable, PA7_Int_Mode; // Timer prescaler constants
wire [9:0] PRESCALER_VALS[3:0];
assign PRESCALER_VALS[0] = 10'd0;
assign PRESCALER_VALS[1] = 10'd7;
assign PRESCALER_VALS[2] = 10'd63;
assign PRESCALER_VALS[3] = 10'd1023;
// Interrupt
assign IRQ_n = ~(Timer_Int_Flag & Timer_Int_Enable | PA7_Int_Flag & PA7_Int_Enable);
// Operation decoding
wire [6:0] op;
reg [6:0] R_op;
assign op = {RS_n, R_W_n, A[4:0]};
// Registered data in
reg [7:0] R_Din;
integer cnt;
// Software operations
always @(posedge CLK)
begin
// Reset operation
if (~RES_n) begin
DRA <= 8'b0;
DDRA <= 8'b0;
DRB <= 8'b00010100;
DDRB <= 8'b00010100;
Timer_Int_Flag <= 1'b0;
PA7_Int_Flag <= 1'b0;
PA7_Int_Enable <= 1'b0;
PA7_Int_Mode <= 1'b0;
// Fill RAM with 0s
for (cnt = 0; cnt < 128; cnt = cnt + 1)
RAM[cnt] <= 8'b0;
R_PA7 <= 1'b0;
R_op <= `NOP;
R_Din <= 8'b0;
end
// If the chip is enabled, execute an operation
else if (CS & ~CS_n) begin
// Register inputs for use later
R_PA7 <= PA7;
R_op <= op;
R_Din <= Din;
// Update the timer interrupt flag
casex (op)
`WRITE_TIMER: Timer_Int_Flag <= 1'b0;
`READ_TIMER: Timer_Int_Flag <= 1'b0;
default: if (Timer == 9'b111111111) Timer_Int_Flag <= 1'b1;
endcase
// Update the port A interrupt flag
casex (op)
`READ_INT_FLAG: PA7_Int_Flag <= 1'b0;
default: PA7_Int_Flag <= PA7_Int_Flag | (PA7 != R_PA7 & PA7 == PA7_Int_Mode);
endcase
// Process the current operation
casex(op) // RAM access
`READ_RAM: Dout <= RAM[A];
`WRITE_RAM: RAM[A] <= Din;
// Port A data access
`READ_DRA : Dout <= (PAin & ~DDRA) | (DRA & DDRA);
`WRITE_DRA: DRA <= Din;
// Port A direction register access
`READ_DDRA: Dout <= DDRA;
`WRITE_DDRA: DDRA <= Din;
// Port B data access
`READ_DRB: Dout <= (PBin & ~DDRB) | (DRB & DDRB);
`WRITE_DRB: DRB <= Din;
// Port B direction register access
`READ_DDRB: Dout <= DDRB;
`WRITE_DDRB: DDRB <= Din;
// Timer access
`READ_TIMER: Dout <= Timer[7:0];
// Status register access
`READ_INT_FLAG: Dout <= {Timer_Int_Flag, PA7_Int_Flag, 6'b0};
// Enable the port A interrupt
`WRITE_EDGE_DETECT: begin
PA7_Int_Mode <= A[0]; PA7_Int_Enable <= A[1];
end
endcase
end
// Even if the chip is not enabled, update background functions
else begin
// Update the timer interrupt
if (Timer == 9'b111111111)
Timer_Int_Flag <= 1'b1;
// Update the port A interrupt
R_PA7 <= PA7;
PA7_Int_Flag <= PA7_Int_Flag | (PA7 != R_PA7 & PA7 == PA7_Int_Mode);
// Set the operation to a NOP
R_op <=`NOP;
end
end
// Update the timer at the negative edge of the clock
always @(negedge CLK)begin
// Reset operation
if (~RES_n) begin
Timer <= 9'b0;
Timer_Mode <= 2'b0;
Prescaler <= 10'b0;
Timer_Int_Enable <= 1'b0;
end
// Otherwise, process timer operations
else
casex
(R_op)
// Write value to the timer and update the prescaler based on the address
`WRITE_TIMER:begin
Timer <= {1'b0, R_Din};
Timer_Mode <= R_op[1:0];
Prescaler <= PRESCALER_VALS[R_op[1:0]];
Timer_Int_Enable <= R_op[3];
end
// Otherwise decrement the prescaler and if necessary the timer.
// The prescaler holds a variable number of counts that must be
// run before the timer is decremented
default:if (Timer != 9'b100000000) begin
if (Prescaler != 10'b0)
Prescaler <= Prescaler - 10'b1;
else begin
if (Timer == 9'b0)
begin
Prescaler <= 10'b0;
Timer_Mode <= 2'b0;
end
else
Prescaler <= PRESCALER_VALS[Timer_Mode];
Timer <= Timer - 9'b1;
end
end
endcase
end
endmodule

477
common/TIA.sv Normal file
View File

@@ -0,0 +1,477 @@
/* Atari on an FPGA
Masters of Engineering Project
Cornell University, 2007
Daniel Beer
TIA.v
Redesign of the Atari TIA chip. Provides the Atari with video generation,
sound generation and I/O.
*/
`timescale 1ns / 1ps
`include "tia.vh"
module TIA(A, // Address bus input
Din, // Data bus input
Dout, // Data bus output
CS_n, // Active low chip select input
CS, // Chip select input
R_W_n, // Active low read/write input
RDY, // CPU ready output
MASTERCLK, // 3.58 Mhz pixel clock input
CLK2, // 1.19 Mhz bus clock input
idump_in, // Dumped I/O
Ilatch, // Latched I/O
HSYNC, // Video horizontal sync output
HBLANK, // Video horizontal blank output
VSYNC, // Video vertical sync output
VBLANK, // Video vertical sync output
COLOROUT, // Indexed color output
RES_n, // Active low reset input
AUD0, //audio pin 0
AUD1, //audio pin 1
audv0, //audio volume for use with external xformer module
audv1); //audio volume for use with external xformer module
input [5:0] A;
input [7:0] Din;
output [7:0] Dout;
input [2:0] CS_n;
input CS;
input R_W_n;
output RDY;
input MASTERCLK;
input CLK2;
input [1:0] Ilatch;
input [3:0] idump_in;
output HSYNC, HBLANK;
output VSYNC, VBLANK;
output [7:0] COLOROUT;
input RES_n;
output AUD0, AUD1;
output reg [3:0] audv0, audv1;
// Data output register
reg [7:0] Dout;
// Video control signal registers
wire HSYNC;
reg VSYNC, VBLANK;
// Horizontal pixel counter
reg [7:0] hCount;
reg [3:0] hCountReset;
reg clk_30;
reg [7:0] clk_30_count;
wire [3:0] Idump;
// Pixel counter update
always @(posedge MASTERCLK)
begin
// Reset operation
if (~RES_n) begin
hCount <= 8'd0;
hCountReset[3:1] <= 3'd0;
clk_30 <= 0;
clk_30_count <= 0;
latchedInputs <= 2'b11;
end
else begin
if (inputLatchReset)
latchedInputs <= 2'b11;
else
latchedInputs <= latchedInputs & Ilatch;
if (clk_30_count == 57) begin
clk_30 <= ~clk_30;
clk_30_count <= 0;
end else begin
clk_30_count <= clk_30_count + 1;
end
// Increment the count and reset if necessary
if ((hCountReset[3]) ||(hCount == 8'd227))
hCount <= 8'd0;
else
hCount <= hCount + 8'd1;
// Software resets are delayed by three cycles
hCountReset[3:1] <= hCountReset[2:0];
end
end
assign HSYNC = (hCount >= 8'd20) && (hCount < 8'd36);
assign HBLANK = (hCount < 8'd68);
// Screen object registers
// These registers are set by the software and used to generate pixels
reg [7:0] player0Pos, player1Pos, missile0Pos, missile1Pos, ballPos;
reg [4:0] player0Size, player1Size;
reg [7:0] player0Color, player1Color, ballColor, pfColor, bgColor;
reg [3:0] player0Motion, player1Motion, missile0Motion, missile1Motion,
ballMotion;
reg missile0Enable, missile1Enable, ballEnable, R_ballEnable;
reg [1:0] ballSize;
reg [19:0] pfGraphic;
reg [7:0] player0Graphic, player1Graphic;
reg [7:0] R_player0Graphic, R_player1Graphic;
reg pfReflect, player0Reflect, player1Reflect;
reg prioCtrl;
reg pfColorCtrl;
reg [14:0] collisionLatch;
reg missile0Lock, missile1Lock;
reg player0VertDelay, player1VertDelay, ballVertDelay;
reg [3:0] audc0, audc1;
reg [4:0] audf0, audf1;
// Pixel number calculation
wire [7:0] pixelNum;
//audio control
audio audio_ctrl(.AUDC0(audc0),
.AUDC1(audc1),
.AUDF0(audf0),
.AUDF1(audf1),
.CLK_30(clk_30), //30khz clock
.AUD0(AUD0),
.AUD1(AUD1));
assign pixelNum = (hCount >= 8'd68) ? (hCount - 8'd68) : 8'd227;
// Pixel tests. For each pixel and screen object, a test is done based on the
// screen objects register to determine if the screen object should show on that
// pixel. The results of all the tests are fed into logic to pick which displayed
// object has priority and color the pixel the color of that object.
// Playfield pixel test
wire [5:0] pfPixelNum;
wire pfPixelOn, pfLeftPixelVal, pfRightPixelVal;
assign pfPixelNum = pixelNum[7:2];
assign pfLeftPixelVal = pfGraphic[pfPixelNum];
assign pfRightPixelVal = (pfReflect == 1'b0)? pfGraphic[pfPixelNum - 6'd20]:
pfGraphic[6'd39 - pfPixelNum];
assign pfPixelOn = (pfPixelNum < 6'd20)? pfLeftPixelVal : pfRightPixelVal;
// Player 0 sprite pixel test
wire pl0PixelOn;
wire [7:0] pl0Mask, pl0MaskDel;
assign pl0MaskDel = (player0VertDelay)? R_player0Graphic : player0Graphic;
assign pl0Mask = (!player0Reflect)? pl0MaskDel : {pl0MaskDel[0], pl0MaskDel[1],
pl0MaskDel[2], pl0MaskDel[3],
pl0MaskDel[4], pl0MaskDel[5],
pl0MaskDel[6], pl0MaskDel[7]};
objPixelOn player0_test(pixelNum, player0Pos, player0Size[2:0], pl0Mask, pl0PixelOn);
// Player 1 sprite pixel test
wire pl1PixelOn;
wire [7:0] pl1Mask, pl1MaskDel;
assign pl1MaskDel = (player1VertDelay)? R_player1Graphic : player1Graphic;
assign pl1Mask = (!player1Reflect)? pl1MaskDel : {pl1MaskDel[0], pl1MaskDel[1],
pl1MaskDel[2], pl1MaskDel[3],
pl1MaskDel[4], pl1MaskDel[5],
pl1MaskDel[6], pl1MaskDel[7]};
objPixelOn player1_test(pixelNum, player1Pos, player1Size[2:0], pl1Mask, pl1PixelOn);
// Missile 0 pixel test
wire mis0PixelOn, mis0PixelOut;
wire [7:0] mis0ActualPos;
reg [7:0] mis0Mask;
always @(player0Size)
begin
case(player0Size[4:3])
2'd0: mis0Mask <= 8'h01;
2'd1: mis0Mask <= 8'h03;
2'd2: mis0Mask <= 8'h0F;
2'd3: mis0Mask <= 8'hFF;
endcase
end
assign mis0ActualPos = (missile0Lock)? player0Pos : missile0Pos;
objPixelOn missile0_test(pixelNum, mis0ActualPos, player0Size[2:0], mis0Mask, mis0PixelOut);
assign mis0PixelOn = mis0PixelOut && missile0Enable;
// Missile 1 pixel test
wire mis1PixelOn, mis1PixelOut;
wire [7:0] mis1ActualPos;
reg [7:0] mis1Mask;
always @(player1Size)
begin
case(player1Size[4:3])
2'd0: mis1Mask <= 8'h01;
2'd1: mis1Mask <= 8'h03;
2'd2: mis1Mask <= 8'h0F;
2'd3: mis1Mask <= 8'hFF;
endcase
end
assign mis1ActualPos = (missile1Lock)? player1Pos : missile1Pos;
objPixelOn missile1_test(pixelNum, mis1ActualPos, player1Size[2:0], mis1Mask, mis1PixelOut);
assign mis1PixelOn = mis1PixelOut && missile1Enable;
// Ball pixel test
wire ballPixelOut, ballPixelOn, ballEnableDel;
reg [7:0] ballMask;
always @(ballSize)
begin
case(ballSize)
2'd0: ballMask <= 8'h01;
2'd1: ballMask <= 8'h03;
2'd2: ballMask <= 8'h0F;
2'd3: ballMask <= 8'hFF;
endcase
end
objPixelOn ball_test(pixelNum, ballPos, 3'd0, ballMask, ballPixelOut);
assign ballEnableDel = ((ballVertDelay)? R_ballEnable : ballEnable);
assign ballPixelOn = ballPixelOut && ballEnableDel;
// Playfield color selection
// The programmer can select a unique color for the playfield or have it match
// the player's sprites colors
reg [7:0] pfActualColor;
always @(pfColorCtrl, pfColor, player0Color, player1Color, pfPixelNum)
begin
if (pfColorCtrl)
begin
if (pfPixelNum < 6'd20)
pfActualColor <= player0Color;
else
pfActualColor <= player1Color;
end
else
pfActualColor <= pfColor;
end
// Final pixel color selection
reg [7:0] pixelColor;
assign COLOROUT = (HBLANK)? 8'b0 : pixelColor;
// This combinational logic uses a priority encoder like structure to select
// the highest priority screen object and color the pixel.
always @(prioCtrl, pfPixelOn, pl0PixelOn, pl1PixelOn, mis0PixelOn, mis1PixelOn,
ballPixelOn, pfActualColor, player0Color, player1Color, bgColor)
begin
// Show the playfield behind the players
if (!prioCtrl)
begin
if (pl0PixelOn || mis0PixelOn)
pixelColor <= player0Color;
else if (pl1PixelOn || mis1PixelOn)
pixelColor <= player1Color;
else if (pfPixelOn)
pixelColor <= pfActualColor;
else
pixelColor <= bgColor;
end
// Otherwise, show the playfield in front of the players
else begin
if (pfPixelOn)
pixelColor <= pfActualColor;
else if (pl0PixelOn || mis0PixelOn)
pixelColor <= player0Color;
else if (pl1PixelOn || mis1PixelOn)
pixelColor <= player1Color;
else
pixelColor <= bgColor;
end
end
// Collision register and latching update
wire [14:0] collisions;
reg collisionLatchReset;
assign collisions = {pl0PixelOn && pl1PixelOn, mis0PixelOn && mis1PixelOn,
ballPixelOn && pfPixelOn,
mis1PixelOn && pfPixelOn, mis1PixelOn && ballPixelOn,
mis0PixelOn && pfPixelOn, mis0PixelOn && ballPixelOn,
pl1PixelOn && pfPixelOn, pl1PixelOn && ballPixelOn,
pl0PixelOn && pfPixelOn, pl0PixelOn && ballPixelOn,
mis1PixelOn && pl0PixelOn, mis1PixelOn && pl1PixelOn,
mis0PixelOn && pl1PixelOn, mis0PixelOn && pl0PixelOn};
always @(posedge MASTERCLK, posedge collisionLatchReset)
begin
if (collisionLatchReset)
collisionLatch <= 15'b000000000000000;
else
collisionLatch <= collisionLatch | collisions;
end
// WSYNC logic
// When a WSYNC is signalled by the programmer, the CPU ready line is lowered
// until the end of a scanline
reg wSync, wSyncReset;
always @(hCount, wSyncReset)
begin
if (hCount == 8'd0)
wSync <= 1'b0;
else if (wSyncReset && hCount > 8'd2)
wSync <= 1'b1;
end
assign RDY = ~wSync;
// Latched input registers and update
wire [1:0] latchedInputsValue;
reg inputLatchEnabled;
reg inputLatchReset;
reg [1:0] latchedInputs;
/*always_ff @(Ilatch, inputLatchReset)
begin
if (inputLatchReset)
latchedInputs <= 2'b11;
else
latchedInputs <= latchedInputs & Ilatch;
end*/
assign latchedInputsValue = (inputLatchEnabled)? latchedInputs : Ilatch;
// Dumped input registers update
reg inputDumpEnabled;
assign Idump = (inputDumpEnabled)? 4'b0000 : idump_in;
// Software operations
always @(posedge CLK2)
begin
// Reset operation
if (~RES_n) begin
inputLatchReset <= 1'b0;
collisionLatchReset <= 1'b0;
hCountReset[0] <= 1'b0;
wSyncReset <= 1'b0;
Dout <= 8'b00000000;
end
// If the chip is enabled, execute an operation
else if (CS) begin
// Software reset signals
inputLatchReset <= ({R_W_n, A[5:0]} == `VBLANK && Din[6] && !inputLatchEnabled);
collisionLatchReset <= ({R_W_n, A[5:0]} == `CXCLR);
hCountReset[0] <= ({R_W_n, A[5:0]} == `RSYNC);
wSyncReset <= ({R_W_n, A[5:0]} == `WSYNC) && !wSync;
case({R_W_n, A[5:0]})
// Collision latch reads
`CXM0P, `CXM0P_7800: Dout <= {collisionLatch[1:0],6'b000000};
`CXM1P, `CXM1P_7800: Dout <= {collisionLatch[3:2],6'b000000};
`CXP0FB, `CXP0FB_7800: Dout <= {collisionLatch[5:4],6'b000000};
`CXP1FB, `CXP1FB_7800: Dout <= {collisionLatch[7:6],6'b000000};
`CXM0FB, `CXM0FB_7800: Dout <= {collisionLatch[9:8],6'b000000};
`CXM1FB, `CXM1FB_7800: Dout <= {collisionLatch[11:10],6'b000000};
`CXBLPF, `CXBLPF_7800: Dout <= {collisionLatch[12],7'b0000000};
`CXPPMM, `CXPPMM_7800: Dout <= {collisionLatch[14:13],6'b000000};
// I/O reads
`INPT0, `INPT0_7800: Dout <= {Idump[0], 7'b0000000};
`INPT1, `INPT1_7800: Dout <= {Idump[1], 7'b0000000};
`INPT2, `INPT2_7800: Dout <= {Idump[2], 7'b0000000};
`INPT3, `INPT3_7800: Dout <= {Idump[3], 7'b0000000};
`INPT4, `INPT4_7800: Dout <= {latchedInputsValue[0], 7'b0000000};
`INPT5, `INPT5_7800: Dout <= {latchedInputsValue[1], 7'b0000000};
// Video signals
`VSYNC: VSYNC <= Din[1];
`VBLANK: begin
inputLatchEnabled <= Din[6];
inputDumpEnabled <= Din[7];
VBLANK <= Din[1];
end
`WSYNC:;
`RSYNC:;
// Screen object register access
`NUSIZ0: player0Size <= {Din[5:4],Din[2:0]};
`NUSIZ1: player1Size <= {Din[5:4],Din[2:0]};
`COLUP0: player0Color <= Din;
`COLUP1: player1Color <= Din;
`COLUPF: pfColor <= Din;
`COLUBK: bgColor <= Din;
`CTRLPF: begin
pfReflect <= Din[0];
pfColorCtrl <= Din[1];
prioCtrl <= Din[2];
ballSize <= Din[5:4];
end
`REFP0: player0Reflect <= Din[3];
`REFP1: player1Reflect <= Din[3];
`PF0: pfGraphic[3:0] <= Din[7:4];
`PF1: pfGraphic[11:4] <= {Din[0], Din[1], Din[2], Din[3],
Din[4], Din[5], Din[6], Din[7]};
`PF2: pfGraphic[19:12] <= Din[7:0];
`RESP0: player0Pos <= pixelNum;
`RESP1: player1Pos <= pixelNum;
`RESM0: missile0Pos <= pixelNum;
`RESM1: missile1Pos <= pixelNum;
`RESBL: ballPos <= pixelNum;
// Audio controls
`AUDC0: audc0 <= Din[3:0];
`AUDC1: audc1 <= Din[3:0];
`AUDF0: audf0 <= Din[4:0];
`AUDF1: audf1 <= Din[4:0];
`AUDV0: audv0 <= Din[3:0];
`AUDV1: audv1 <= Din[3:0];
// Screen object register access
`GRP0: begin
player0Graphic <= {Din[0], Din[1], Din[2], Din[3],
Din[4], Din[5], Din[6], Din[7]};
R_player1Graphic <= player1Graphic;
end
`GRP1: begin
player1Graphic <= {Din[0], Din[1], Din[2], Din[3],
Din[4], Din[5], Din[6], Din[7]};
R_player0Graphic <= player0Graphic;
R_ballEnable <= ballEnable;
end
`ENAM0: missile0Enable <= Din[1];
`ENAM1: missile1Enable <= Din[1];
`ENABL: ballEnable <= Din[1];
`HMP0: player0Motion <= Din[7:4];
`HMP1: player1Motion <= Din[7:4];
`HMM0: missile0Motion <= Din[7:4];
`HMM1: missile1Motion <= Din[7:4];
`HMBL: ballMotion <= Din[7:4];
`VDELP0: player0VertDelay <= Din[0];
`VDELP1: player1VertDelay <= Din[0];
`VDELBL: ballVertDelay <= Din[0];
`RESMP0: missile0Lock <= Din[1];
`RESMP1: missile1Lock <= Din[1];
// Strobed line that initiates an object move
`HMOVE: begin
player0Pos <= player0Pos - {{4{player0Motion[3]}},
player0Motion[3:0]};
player1Pos <= player1Pos - {{4{player1Motion[3]}},
player1Motion[3:0]};
missile0Pos <= missile0Pos - {{4{missile0Motion[3]}},
missile0Motion[3:0]};
missile1Pos <= missile1Pos - {{4{missile1Motion[3]}},
missile1Motion[3:0]};
ballPos <= ballPos - {{4{ballMotion[3]}},ballMotion[3:0]};
end
// Motion register clear
`HMCLR: begin
player0Motion <= Din[7:4];
player1Motion <= Din[7:4];
missile0Motion <= Din[7:4];
missile1Motion <= Din[7:4];
ballMotion <= Din[7:4];
end
`CXCLR:;
default: Dout <= 8'b00000000;
endcase
end
// If the chip is not enabled, do nothing
else begin
inputLatchReset <= 1'b0;
collisionLatchReset <= 1'b0;
hCountReset[0] <= 1'b0;
wSyncReset <= 1'b0;
Dout <= 8'b00000000;
end
end
endmodule
// objPixelOn module
// Checks the pixel number against a stretched and possibly duplicated version of the
// object.
module objPixelOn(pixelNum, objPos, objSize, objMask, pixelOn);
input [7:0] pixelNum, objPos, objMask;
input [2:0] objSize;
output pixelOn;
wire [7:0] objIndex;
wire [8:0] objByteIndex;
wire objMaskOn, objPosOn;
reg objSizeOn;
reg [2:0] objMaskSel;
assign objIndex = pixelNum - objPos - 8'd1;
assign objByteIndex = 9'b1 << (objIndex[7:3]);
always @(objSize, objByteIndex)
begin
case (objSize)
3'd0: objSizeOn <= (objByteIndex & 9'b00000001) != 0;
3'd1: objSizeOn <= (objByteIndex & 9'b00000101) != 0;
3'd2: objSizeOn <= (objByteIndex & 9'b00010001) != 0;
3'd3: objSizeOn <= (objByteIndex & 9'b00010101) != 0;
3'd4: objSizeOn <= (objByteIndex & 9'b10000001) != 0;
3'd5: objSizeOn <= (objByteIndex & 9'b00000011) != 0;
3'd6: objSizeOn <= (objByteIndex & 9'b10010001) != 0;
3'd7: objSizeOn <= (objByteIndex & 9'b00001111) != 0;
endcase
end
always @(objSize, objIndex)
begin
case (objSize)
3'd5: objMaskSel <= objIndex[3:1];
3'd7: objMaskSel <= objIndex[4:2];
default: objMaskSel <= objIndex[2:0];
endcase
end
assign objMaskOn = objMask[objMaskSel];
assign objPosOn = (pixelNum > objPos) && ({1'b0, pixelNum} <= {1'b0, objPos} + 9'd72);
assign pixelOn = objSizeOn && objMaskOn && objPosOn;
endmodule

80
common/TTL/ls367.vhd Normal file
View File

@@ -0,0 +1,80 @@
--
-- ls367.vhd
--
-- LS367 and the others circuit module
-- for MZ-700 on FPGA
--
-- TEMPO generator
-- TONE gate
--
-- Nibbles Lab. 2005
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ls367 is
Port ( RST : in std_logic;
CLKIN : in std_logic;
CLKOUT : out std_logic;
GATE : out std_logic;
CS : in std_logic;
WR : in std_logic;
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0));
end ls367;
architecture Behavioral of ls367 is
--
-- TEMPO counter
--
signal TCOUNT : std_logic_vector(15 downto 0);
signal TEMPO : std_logic;
--
-- GATE control
--
signal GT : std_logic;
begin
--
-- TEMPO
--
process( CLKIN ) begin
if( CLKIN'event and CLKIN='1' ) then
TCOUNT<=TCOUNT+'1';
if( TCOUNT=46976 ) then
TCOUNT<=(others=>'0');
TEMPO<=not TEMPO;
end if;
end if;
end process;
DO(0)<=TEMPO;
DO(7 downto 1)<=(others=>'1');
CLKOUT<=TEMPO;
--
-- TONE gate control
--
process( WR, RST ) begin
if( RST='0' ) then
GT<='0';
elsif( WR'event and WR='1' ) then
if( CS='0' ) then
GT<=DI(0);
end if;
end if;
end process;
GATE<=GT;
end Behavioral;

26
common/riot.vh Normal file
View File

@@ -0,0 +1,26 @@
/* Atari on an FPGA
Masters of Engineering Project
Cornell University, 2007
Daniel Beer
RIOT.h
Header file that contains useful definitions for the RIOT module.
*/
`define READ_RAM 7'b01xxxxx
`define WRITE_RAM 7'b00xxxxx
`define READ_DRA 7'b11xx000
`define WRITE_DRA 7'b10xx000
`define READ_DDRA 7'b11xx001
`define WRITE_DDRA 7'b10xx001
`define READ_DRB 7'b11xx010
`define WRITE_DRB 7'b10xx010
`define READ_DDRB 7'b11xx011
`define WRITE_DDRB 7'b10xx011
`define WRITE_TIMER 7'b101x1xx
`define READ_TIMER 7'b11xx1x0
`define READ_INT_FLAG 7'b11xx1x1
`define WRITE_EDGE_DETECT 7'b100x1x0
`define NOP 7'b0100000
`define TM_1 2'b00
`define TM_8 2'b01
`define TM_64 2'b10
`define TM_1024 2'b11

81
common/tia.vh Normal file
View File

@@ -0,0 +1,81 @@
/* Atari on an FPGA
Masters of Engineering Project
Cornell University, 2007
Daniel Beer
TIA.h
Header file that contains useful definitions for the TIA module.
*/
`define CXM0P 7'h70
`define CXM1P 7'h71
`define CXP0FB 7'h72
`define CXP1FB 7'h73
`define CXM0FB 7'h74
`define CXM1FB 7'h75
`define CXBLPF 7'h76
`define CXPPMM 7'h77
`define INPT0 7'h78
`define INPT1 7'h79
`define INPT2 7'h7A
`define INPT3 7'h7B
`define INPT4 7'h7C
`define INPT5 7'h7D
`define VSYNC 7'h00
`define VBLANK 7'h01
`define WSYNC 7'h02
`define RSYNC 7'h03
`define NUSIZ0 7'h04
`define NUSIZ1 7'h05
`define COLUP0 7'h06
`define COLUP1 7'h07
`define COLUPF 7'h08
`define COLUBK 7'h09
`define CTRLPF 7'h0A
`define REFP0 7'h0B
`define REFP1 7'h0C
`define PF0 7'h0D
`define PF1 7'h0E
`define PF2 7'h0F
`define RESP0 7'h10
`define RESP1 7'h11
`define RESM0 7'h12
`define RESM1 7'h13
`define RESBL 7'h14
`define AUDC0 7'h15
`define AUDC1 7'h16
`define AUDF0 7'h17
`define AUDF1 7'h18
`define AUDV0 7'h19
`define AUDV1 7'h1A
`define GRP0 7'h1B
`define GRP1 7'h1C
`define ENAM0 7'h1D
`define ENAM1 7'h1E
`define ENABL 7'h1F
`define HMP0 7'h20
`define HMP1 7'h21
`define HMM0 7'h22
`define HMM1 7'h23
`define HMBL 7'h24
`define VDELP0 7'h25
`define VDELP1 7'h26
`define VDELBL 7'h27
`define RESMP0 7'h28
`define RESMP1 7'h29
`define HMOVE 7'h2A
`define HMCLR 7'h2B
`define CXCLR 7'h2C
`define CXM0P_7800 7'h40
`define CXM1P_7800 7'h41
`define CXP0FB_7800 7'h42
`define CXP1FB_7800 7'h43
`define CXM0FB_7800 7'h44
`define CXM1FB_7800 7'h45
`define CXBLPF_7800 7'h46
`define CXPPMM_7800 7'h47
`define INPT0_7800 7'h48
`define INPT1_7800 7'h49
`define INPT2_7800 7'h4A
`define INPT3_7800 7'h4B
`define INPT4_7800 7'h4C
`define INPT5_7800 7'h4D