Project

General

Profile

« Previous | Next » 

Revision 438

Added by markw over 9 years ago

First cut implementation of veronica clone for ultimate cart - does not work yet, but getting close. Project to try out Rob Finchs 65816 core.

View differences:

ultimate_cart/veronica/veronica.sdc
create_clock -period 40MHz [get_ports CLK]
derive_pll_clocks
derive_clock_uncertainty
create_clock -period 14MHz -name sram_clk
set_output_delay -clock sram_clk -max 60.0 [get_ports EXT_SRAM_ADDR[*]]
set_output_delay -clock sram_clk -min 0.0 [get_ports EXT_SRAM_ADDR[*]]
set_output_delay -clock sram_clk -max 60.0 [get_ports EXT_SRAM_DATA[*]]
set_output_delay -clock sram_clk -min 0.0 [get_ports EXT_SRAM_DATA[*]]
set_input_delay -clock sram_clk -max 60.0 [get_ports EXT_SRAM_DATA[*]]
set_input_delay -clock sram_clk -min 0.0 [get_ports EXT_SRAM_DATA[*]]
ultimate_cart/veronica/simulate_sram.sh
#!/bin/bash
echo "---------------------------------------------------------"
echo "Use 'simulate -run' to skip compilation stage."
echo "Use 'simulate -view' to show previous simulation results."
echo "---------------------------------------------------------"
name=sram
#. /home/markw/fpga/xilinx/14.7/ISE_DS/settings64.sh
export XILINX=C:\Xilinx\14.7\ISE_DS\ISE
mkdir -p sim
pushd sim
# if we have a WDB file, we can view it if requested (otherwise we remove it)
if [ ! -e $name.wdb -o "$1" != "-view" ]; then
rm -f $name.wdb
# if we have a EXE, we can run it if requested (otherwise we remove it)
if [ ! -e $name.exe -o "$1" != "-run" ]; then
rm -f $name.exe
# copy testbench files
cp -p ../tb_sram/* .
# copy source files
cp ../sram_mux.vhd .
# cp `find ../a8core/ -iname "*.vhd"` .
# cp `find ../a8core/ -iname "*.vhdl"` .
# cp `find ../components/ -iname "*.vhd"` .
# cp `find ../components/ -iname "*.vhdl"` .
#
# set up project definition file
ls *.vhd* | perl -e 'while (<>){s/(.*)/vhdl work $1/;print $_;}' | cat > $name.prj
echo NumericStdNoWarnings = 1 >> xilinxsim.ini
# verbose & no multthreading - fallback in case of problems
# fuse -v 1 -mt off -incremental -prj %name%.prj -o %name%.exe -t %name%
/drives/c/Xilinx/14.7/ISE_DS/ISE/bin/nt64/fuse.exe -timeprecision_vhdl 1fs -incremental -prj $name.prj -o $name.exe -t ${name}_tb || exit 1
# fuse --mt off -prj %name%.prj -o %name%.exe -t %name%_tb
# Check for the EXE again, independent of the errorlevel of fuse...
[ -e $name.exe ] || echo "No simulation executable created"
fi
# Open the iSIM GUI and run the simulation
./$name.exe -gui -f ../$name.cmd -wdb $name.wdb -log $name.log -view ../$name.wcfg || exit 1
#strace ./$name.exe -gui -f ../$name.cmd -wdb $name.wdb -log $name.log -view ../$name.wcfg >& out
#./$name.exe -h -log $name.log
else
# Only start the viewer on an existing wave configuration (from an old simulation)
isimgui -view ../$name.wcfg || exit 1
fi
popd
ultimate_cart/veronica/sram_mux.vhd
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY sram_mux IS
PORT (
clk : in std_logic;
clk7x : in std_logic;
reset_n : in std_logic;
sram_addr : out std_logic_vector(19 downto 0);
sram_data_out : out std_logic_vector(7 downto 0);
sram_drive_data : out std_logic;
sram_we_n : out std_logic;
atari_bus_request : in std_logic;
atari_sram_select : in std_logic;
atari_address : in std_logic_vector(16 downto 0);
atari_w_n : in std_logic;
atari_write_data : in std_logic_vector(7 downto 0);
veronica_address : in std_logic_vector(16 downto 0);
veronica_sram_select : in std_logic;
veronica_w_n : in std_logic;
veronica_write_data : in std_logic_vector(7 downto 0)
);
END sram_mux;
ARCHITECTURE vhdl OF sram_mux IS
signal sram_we_next : std_logic;
signal sram_we_reg : std_logic;
signal tick_next : std_logic;
signal tick_reg : std_logic;
signal tick_fast_next : std_logic_vector(6 downto 0);
signal tick_fast_reg : std_logic_vector(6 downto 0);
signal tick_mask : std_logic_vector(6 downto 0);
begin
-- Back to back writes from 65816?
process(veronica_address, veronica_write_data, veronica_w_n, veronica_sram_select,
atari_bus_request, atari_address,atari_write_data, atari_w_n, atari_sram_select)
begin
sram_addr <= (others=>'0');
sram_data_out <= (others=>'0');
sram_drive_data <= '0';
if (atari_bus_request='1') then
sram_addr(16 downto 0) <= atari_address;
sram_data_out <= atari_write_data;
sram_we_next <= (atari_w_n or not(atari_sram_select));
sram_drive_data <= not(atari_w_n);
else
sram_addr(16 downto 0) <= veronica_address;
sram_data_out <= veronica_write_data;
sram_we_next <= (veronica_w_n or not(veronica_sram_select));
sram_drive_data <= not(veronica_w_n);
end if;
end process;
--
-- 12345
-- 01111
-- 00000
process(clk,reset_n)
begin
if (reset_n='0') then
tick_reg <= '0';
elsif (clk'event and clk='1') then
tick_reg <= tick_next;
end if;
end process;
tick_next <= not(tick_reg);
process(clk7x,reset_n)
begin
if (reset_n='0') then
tick_fast_reg <= (others=>'0');
sram_we_reg <= '1';
elsif (clk7x'event and clk7x='1') then
tick_fast_reg <= tick_fast_next;
sram_we_reg <= sram_we_next;
end if;
end process;
tick_fast_next <= tick_fast_reg(5 downto 0)&tick_reg;
tick_mask <= (tick_reg&tick_reg&tick_reg&tick_reg&tick_reg&tick_reg&tick_reg) xor tick_fast_reg; --1000000 1000000 1000000 (raise WE - how long must WE be high?)
-- 55 addr, 45 write pulse, 20 we -> drive
-- 71.4 total -> 7x clock-> about 10ns
-- 10 (we high), 60 (we low) 1 000 000
-- 30 (no drive), 40 (drive) 0 001 111
sram_we_n <= sram_we_reg;
end vhdl;
ultimate_cart/veronica/tb_sram/sram_tb.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
library std_developerskit ; -- used for to_string
-- use std_developerskit.std_iopak.all;
entity sram_tb is
end;
architecture rtl of sram_tb is
constant CLK_PERIOD : time := 1 us / (14);
constant CLK_FAST_PERIOD : time := 1 us / (14*7);
signal reset_n : std_logic;
signal clk : std_logic;
signal clk_fast : std_logic;
signal EXT_SRAM_ADDR: std_logic_vector(19 downto 0);
signal EXT_SRAM_DATA: std_logic_vector(7 downto 0);
signal EXT_SRAM_CE: std_logic;
signal EXT_SRAM_OE: std_logic;
signal EXT_SRAM_WE: std_logic;
-- 65816 bus
signal veronica_address : std_logic_vector(23 downto 0);
signal veronica_read_data : std_logic_vector(7 downto 0);
signal veronica_write_data : std_logic_vector(7 downto 0);
signal veronica_w_n : std_logic;
signal veronica_config_w_n : std_logic;
-- 6502 bus
signal atari_bus_request : std_logic;
signal atari_address : std_logic_vector(12 downto 0);
signal atari_data_bus : std_logic_vector(7 downto 0);
signal atari_read_data : std_logic_vector(7 downto 0);
signal atari_write_data : std_logic_vector(7 downto 0);
signal atari_w_n : std_logic;
signal atari_config_w_n : std_logic;
signal atari_s4 : std_logic;
signal atari_s5 : std_logic;
signal atari_ctl : std_logic;
-- address decode
signal veronica_config_select : std_logic;
signal veronica_sram_select : std_logic;
signal veronica_sram_address: std_logic_vector(16 downto 0);
signal atari_config_select : std_logic;
signal atari_sram_select : std_logic;
signal atari_sram_address: std_logic_vector(16 downto 0);
-- veronica config
signal veronica_window_address : std_logic;
signal veronica_bank_half_select : std_logic;
signal veronica_config_data : std_logic_vector(7 downto 0);
-- atari config
signal atari_banka_enable : std_logic;
signal atari_bank8_enable : std_logic;
signal atari_bank_half_select : std_logic;
signal atari_config_data : std_logic_vector(7 downto 0);
-- common config
signal common_sem : std_logic;
signal common_bank_select : std_logic;
-- cart driving
signal cart_bus_data_out : std_logic_vector(7 downto 0);
signal cart_bus_drive : std_logic;
-- sram driving
signal sram_write_data : std_logic_vector(7 downto 0);
signal sram_drive_data : std_logic;
signal sram_read_data : std_logic_vector(7 downto 0);
begin
p_clk_gen_a : process
begin
clk <= '1';
wait for CLK_PERIOD/2;
clk <= '0';
wait for CLK_PERIOD - (CLK_PERIOD/2 );
end process;
p_clk_gen_b : process
begin
clk_fast <= '1';
wait for CLK_FAST_PERIOD/2;
clk_fast <= '0';
wait for CLK_FAST_PERIOD - (CLK_FAST_PERIOD/2 );
end process;
reset_n <= '0', '1' after 1000ns;
process_setup_sram : process
begin
atari_bus_request <= '0';
atari_sram_select <= '0';
atari_address <= (others=>'0');
atari_w_n <= '1';
atari_write_data <= (others=>'0');
veronica_address <= (others=>'0');
veronica_sram_select <= '0';
veronica_w_n <= '1';
veronica_write_data <= (others=>'0');
wait for 1100ns;
wait until clk'event and clk = '1';
atari_w_n <= '0';
atari_address<= '0'&x"402";
atari_write_data <= x"56";
wait until clk'event and clk = '1';
atari_w_n <= '0';
atari_address<= '0'&x"313";
atari_write_data <= x"65";
wait until clk'event and clk = '1';
atari_w_n <= '0';
atari_address<= '0'&x"402";
atari_write_data <= x"56";
wait for 100000000us;
end process;
glue6: entity work.sram_mux
port map
(
clk => clk,
clk7x => clk_fast,
reset_n => reset_n,
sram_addr => EXT_SRAM_ADDR,
sram_data_out => sram_write_data,
sram_drive_data => sram_drive_data,
sram_we_n => EXT_SRAM_WE,
atari_bus_request => atari_bus_request,
atari_sram_select => atari_sram_select,
atari_address => atari_sram_address,
atari_w_n => atari_w_n,
atari_write_data => atari_write_data,
veronica_address => veronica_sram_address,
veronica_sram_select => veronica_sram_select,
veronica_w_n => veronica_w_n,
veronica_write_data => veronica_write_data
);
end rtl;
ultimate_cart/veronica/BCDMath.v
`timescale 1ns / 1ps
//=============================================================================
// __
// \\__/ o\ (C) 2012 Robert Finch
// \ __ / All rights reserved.
// \/_// robfinch<remove>@opencores.org
// ||
//
// BCDMath.v
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file 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, see <http://www.gnu.org/licenses/>.
//
//
//=============================================================================
//
module BCDAdd(ci,a,b,o,c);
input ci; // carry input
input [7:0] a;
input [7:0] b;
output [7:0] o;
output c;
wire c0,c1;
wire [4:0] hsN0 = a[3:0] + b[3:0] + ci;
wire [4:0] hsN1 = a[7:4] + b[7:4] + c0;
BCDAddAdjust u1 (hsN0,o[3:0],c0);
BCDAddAdjust u2 (hsN1,o[7:4],c);
endmodule
module BCDAdd4(ci,a,b,o,c,c8);
input ci; // carry input
input [15:0] a;
input [15:0] b;
output [15:0] o;
output c;
output c8;
wire c0,c1,c2;
assign c8 = c1;
wire [4:0] hsN0 = a[3:0] + b[3:0] + ci;
wire [4:0] hsN1 = a[7:4] + b[7:4] + c0;
wire [4:0] hsN2 = a[11:8] + b[11:8] + c1;
wire [4:0] hsN3 = a[15:12] + b[15:12] + c2;
BCDAddAdjust u1 (hsN0,o[3:0],c0);
BCDAddAdjust u2 (hsN1,o[7:4],c1);
BCDAddAdjust u3 (hsN2,o[11:8],c2);
BCDAddAdjust u4 (hsN3,o[15:12],c);
endmodule
module BCDSub(ci,a,b,o,c);
input ci; // carry input
input [7:0] a;
input [7:0] b;
output [7:0] o;
output c;
wire c0,c1;
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci;
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0;
BCDSubAdjust u1 (hdN0,o[3:0],c0);
BCDSubAdjust u2 (hdN1,o[7:4],c);
endmodule
module BCDSub4(ci,a,b,o,c,c8);
input ci; // carry input
input [15:0] a;
input [15:0] b;
output [15:0] o;
output c;
output c8;
wire c0,c1,c2;
assign c8 = c1;
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci;
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0;
wire [4:0] hdN2 = a[11:8] - b[11:8] - c1;
wire [4:0] hdN3 = a[15:12] - b[15:12] - c2;
BCDSubAdjust u1 (hdN0,o[3:0],c0);
BCDSubAdjust u2 (hdN1,o[7:4],c1);
BCDSubAdjust u3 (hdN2,o[11:8],c2);
BCDSubAdjust u4 (hdN3,o[15:12],c);
endmodule
module BCDAddAdjust(i,o,c);
input [4:0] i;
output [3:0] o;
reg [3:0] o;
output c;
reg c;
always @(i)
case(i)
5'h0: begin o = 4'h0; c = 1'b0; end
5'h1: begin o = 4'h1; c = 1'b0; end
5'h2: begin o = 4'h2; c = 1'b0; end
5'h3: begin o = 4'h3; c = 1'b0; end
5'h4: begin o = 4'h4; c = 1'b0; end
5'h5: begin o = 4'h5; c = 1'b0; end
5'h6: begin o = 4'h6; c = 1'b0; end
5'h7: begin o = 4'h7; c = 1'b0; end
5'h8: begin o = 4'h8; c = 1'b0; end
5'h9: begin o = 4'h9; c = 1'b0; end
5'hA: begin o = 4'h0; c = 1'b1; end
5'hB: begin o = 4'h1; c = 1'b1; end
5'hC: begin o = 4'h2; c = 1'b1; end
5'hD: begin o = 4'h3; c = 1'b1; end
5'hE: begin o = 4'h4; c = 1'b1; end
5'hF: begin o = 4'h5; c = 1'b1; end
5'h10: begin o = 4'h6; c = 1'b1; end
5'h11: begin o = 4'h7; c = 1'b1; end
5'h12: begin o = 4'h8; c = 1'b1; end
5'h13: begin o = 4'h9; c = 1'b1; end
default: begin o = 4'h9; c = 1'b1; end
endcase
endmodule
module BCDSubAdjust(i,o,c);
input [4:0] i;
output [3:0] o;
reg [3:0] o;
output c;
reg c;
always @(i)
case(i)
5'h0: begin o = 4'h0; c = 1'b0; end
5'h1: begin o = 4'h1; c = 1'b0; end
5'h2: begin o = 4'h2; c = 1'b0; end
5'h3: begin o = 4'h3; c = 1'b0; end
5'h4: begin o = 4'h4; c = 1'b0; end
5'h5: begin o = 4'h5; c = 1'b0; end
5'h6: begin o = 4'h6; c = 1'b0; end
5'h7: begin o = 4'h7; c = 1'b0; end
5'h8: begin o = 4'h8; c = 1'b0; end
5'h9: begin o = 4'h9; c = 1'b0; end
5'h16: begin o = 4'h0; c = 1'b1; end
5'h17: begin o = 4'h1; c = 1'b1; end
5'h18: begin o = 4'h2; c = 1'b1; end
5'h19: begin o = 4'h3; c = 1'b1; end
5'h1A: begin o = 4'h4; c = 1'b1; end
5'h1B: begin o = 4'h5; c = 1'b1; end
5'h1C: begin o = 4'h6; c = 1'b1; end
5'h1D: begin o = 4'h7; c = 1'b1; end
5'h1E: begin o = 4'h8; c = 1'b1; end
5'h1F: begin o = 4'h9; c = 1'b1; end
default: begin o = 4'h9; c = 1'b1; end
endcase
endmodule
// Multiply two BCD digits
// Method used is table lookup
module BCDMul1(a,b,o);
input [3:0] a;
input [3:0] b;
output [7:0] o;
reg [7:0] o;
always @(a or b)
casex({a,b})
8'h00: o = 8'h00;
8'h01: o = 8'h00;
8'h02: o = 8'h00;
8'h03: o = 8'h00;
8'h04: o = 8'h00;
8'h05: o = 8'h00;
8'h06: o = 8'h00;
8'h07: o = 8'h00;
8'h08: o = 8'h00;
8'h09: o = 8'h00;
8'h10: o = 8'h00;
8'h11: o = 8'h01;
8'h12: o = 8'h02;
8'h13: o = 8'h03;
8'h14: o = 8'h04;
8'h15: o = 8'h05;
8'h16: o = 8'h06;
8'h17: o = 8'h07;
8'h18: o = 8'h08;
8'h19: o = 8'h09;
8'h20: o = 8'h00;
8'h21: o = 8'h02;
8'h22: o = 8'h04;
8'h23: o = 8'h06;
8'h24: o = 8'h08;
8'h25: o = 8'h10;
8'h26: o = 8'h12;
8'h27: o = 8'h14;
8'h28: o = 8'h16;
8'h29: o = 8'h18;
8'h30: o = 8'h00;
8'h31: o = 8'h03;
8'h32: o = 8'h06;
8'h33: o = 8'h09;
8'h34: o = 8'h12;
8'h35: o = 8'h15;
8'h36: o = 8'h18;
8'h37: o = 8'h21;
8'h38: o = 8'h24;
8'h39: o = 8'h27;
8'h40: o = 8'h00;
8'h41: o = 8'h04;
8'h42: o = 8'h08;
8'h43: o = 8'h12;
8'h44: o = 8'h16;
8'h45: o = 8'h20;
8'h46: o = 8'h24;
8'h47: o = 8'h28;
8'h48: o = 8'h32;
8'h49: o = 8'h36;
8'h50: o = 8'h00;
8'h51: o = 8'h05;
8'h52: o = 8'h10;
8'h53: o = 8'h15;
8'h54: o = 8'h20;
8'h55: o = 8'h25;
8'h56: o = 8'h30;
8'h57: o = 8'h35;
8'h58: o = 8'h40;
8'h59: o = 8'h45;
8'h60: o = 8'h00;
8'h61: o = 8'h06;
8'h62: o = 8'h12;
8'h63: o = 8'h18;
8'h64: o = 8'h24;
8'h65: o = 8'h30;
8'h66: o = 8'h36;
8'h67: o = 8'h42;
8'h68: o = 8'h48;
8'h69: o = 8'h54;
8'h70: o = 8'h00;
8'h71: o = 8'h07;
8'h72: o = 8'h14;
8'h73: o = 8'h21;
8'h74: o = 8'h28;
8'h75: o = 8'h35;
8'h76: o = 8'h42;
8'h77: o = 8'h49;
8'h78: o = 8'h56;
8'h79: o = 8'h63;
8'h80: o = 8'h00;
8'h81: o = 8'h08;
8'h82: o = 8'h16;
8'h83: o = 8'h24;
8'h84: o = 8'h32;
8'h85: o = 8'h40;
8'h86: o = 8'h48;
8'h87: o = 8'h56;
8'h88: o = 8'h64;
8'h89: o = 8'h72;
8'h90: o = 8'h00;
8'h91: o = 8'h09;
8'h92: o = 8'h18;
8'h93: o = 8'h27;
8'h94: o = 8'h36;
8'h95: o = 8'h45;
8'h96: o = 8'h54;
8'h97: o = 8'h63;
8'h98: o = 8'h72;
8'h99: o = 8'h81;
default: o = 8'h00;
endcase
endmodule
// Multiply two pairs of BCD digits
// handles from 0x0 to 99x99
module BCDMul2(a,b,o);
input [7:0] a;
input [7:0] b;
output [15:0] o;
wire [7:0] p1,p2,p3,p4;
wire [15:0] s1;
BCDMul1 u1 (a[3:0],b[3:0],p1);
BCDMul1 u2 (a[7:4],b[3:0],p2);
BCDMul1 u3 (a[3:0],b[7:4],p3);
BCDMul1 u4 (a[7:4],b[7:4],p4);
BCDAdd4 u5 (1'b0,{p4,p1},{4'h0,p2,4'h0},s1);
BCDAdd4 u6 (1'b0,s1,{4'h0,p3,4'h0},o);
endmodule
module BCDMul_tb();
wire [15:0] o1,o2,o3,o4;
BCDMul2 u1 (8'h00,8'h00,o1);
BCDMul2 u2 (8'h99,8'h99,o2);
BCDMul2 u3 (8'h25,8'h18,o3);
BCDMul2 u4 (8'h37,8'h21,o4);
endmodule
ultimate_cart/veronica/FT816.v
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2013, 2014 Robert Finch, Stratford
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// FT816.v
// - 16 bit CPU
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file 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, see <http://www.gnu.org/licenses/>.
//
// ============================================================================
//
`define TRUE 1'b1
`define FALSE 1'b0
`define DEBUG 1'b1
`define SUPPORT_ICACHE 1'b1
`define ICACHE_4K 1'b1
//`define ICACHE_16K 1'b1
//`define ICACHE_2WAY 1'b1
//`define SUPPORT_DCACHE 1'b1
`define SUPPORT_BCD 1'b1
`define SUPPORT_DIVMOD 1'b1
`define SUPPORT_EM8 1'b1
`define SUPPORT_816 1'b1
//`define SUPPORT_EXEC 1'b1
`define SUPPORT_BERR 1'b1
`define SUPPORT_STRING 1'b1
`define SUPPORT_SHIFT 1'b1
//`define SUPPORT_CGI 1'b1 // support the control giveaway interrupt
`define BRK_VECTNO 9'd0
`define SLP_VECTNO 9'd1
`define BYTE_RST_VECT 24'h00FFFC
`define BYTE_NMI_VECT 24'h00FFFA
`define BYTE_IRQ_VECT 24'h00FFFE
`define BYTE_ABT_VECT 24'h00FFF8
`define BYTE_COP_VECT 24'h00FFF4
`define RST_VECT_816 24'h00FFFC
`define IRQ_VECT_816 24'h00FFEE
`define NMI_VECT_816 24'h00FFEA
`define ABT_VECT_816 24'h00FFE8
`define BRK_VECT_816 24'h00FFE6
`define COP_VECT_816 24'h00FFE4
`define BRK 9'h00
`define RTI 9'h40
`define RTS 9'h60
`define PHP 9'h08
`define CLC 9'h18
`define PLP 9'h28
`define SEC 9'h38
`define PHA 9'h48
`define CLI 9'h58
`define PLA 9'h68
`define SEI 9'h78
`define DEY 9'h88
`define TYA 9'h98
`define TAY 9'hA8
`define CLV 9'hB8
`define INY 9'hC8
`define CLD 9'hD8
`define INX 9'hE8
`define SED 9'hF8
`define ROR_ACC 9'h6A
`define TXA 9'h8A
`define TXS 9'h9A
`define TAX 9'hAA
`define TSX 9'hBA
`define DEX 9'hCA
`define NOP 9'hEA
`define TXY 9'h9B
`define TYX 9'hBB
`define TAS 9'h1B
`define TSA 9'h3B
`define TRS 9'h8B
`define TSR 9'hAB
`define TCD 9'h5B
`define TDC 9'h7B
`define STP 9'hDB
`define NAT 9'hFB
`define EMM 9'hFB
`define XCE 9'hFB
`define INA 9'h1A
`define DEA 9'h3A
`define SEP 9'hE2
`define REP 9'hC2
`define PEA 9'hF4
`define PEI 9'hD4
`define PER 9'h62
`define WDM 9'h42
// CMP = SUB r0,....
`define ADC_IMM 9'h69
`define ADC_ZP 9'h65
`define ADC_ZPX 9'h75
`define ADC_IX 9'h61
`define ADC_IY 9'h71
`define ADC_IYL 9'h77
`define ADC_ABS 9'h6D
`define ADC_ABSX 9'h7D
`define ADC_ABSY 9'h79
`define ADC_I 9'h72
`define ADC_IL 9'h67
`define ADC_AL 9'h6F
`define ADC_ALX 9'h7F
`define ADC_DSP 9'h63
`define ADC_DSPIY 9'h73
`define SBC_IMM 9'hE9
`define SBC_ZP 9'hE5
`define SBC_ZPX 9'hF5
`define SBC_IX 9'hE1
`define SBC_IY 9'hF1
`define SBC_IYL 9'hF7
`define SBC_ABS 9'hED
`define SBC_ABSX 9'hFD
`define SBC_ABSY 9'hF9
`define SBC_I 9'hF2
`define SBC_IL 9'hE7
`define SBC_AL 9'hEF
`define SBC_ALX 9'hFF
`define SBC_DSP 9'hE3
`define SBC_DSPIY 9'hF3
`define CMP_IMM 9'hC9
`define CMP_ZP 9'hC5
`define CMP_ZPX 9'hD5
`define CMP_IX 9'hC1
`define CMP_IY 9'hD1
`define CMP_IYL 8'hD7
`define CMP_ABS 9'hCD
`define CMP_ABSX 9'hDD
`define CMP_ABSY 9'hD9
`define CMP_I 9'hD2
`define CMP_IL 9'hC7
`define CMP_AL 9'hCF
`define CMP_ALX 9'hDF
`define CMP_DSP 9'hC3
`define CMP_DSPIY 9'hD3
`define LDA_IMM8 9'hA5
`define LDA_IMM16 9'hB9
`define LDA_IMM32 9'hA9
`define AND_IMM 9'h29
`define AND_ZP 9'h25
`define AND_ZPX 9'h35
`define AND_IX 9'h21
`define AND_IY 9'h31
`define AND_IYL 9'h37
`define AND_ABS 9'h2D
`define AND_ABSX 9'h3D
`define AND_ABSY 9'h39
`define AND_RIND 9'h32
`define AND_I 9'h32
`define AND_IL 9'h27
`define AND_DSP 9'h23
`define AND_DSPIY 9'h33
`define AND_AL 9'h2F
`define AND_ALX 9'h3F
`define ORA_IMM 9'h09
`define ORA_ZP 9'h05
`define ORA_ZPX 9'h15
`define ORA_IX 9'h01
`define ORA_IY 9'h11
`define ORA_IYL 9'h17
`define ORA_ABS 9'h0D
`define ORA_ABSX 9'h1D
`define ORA_ABSY 9'h19
`define ORA_I 9'h12
`define ORA_IL 9'h07
`define ORA_AL 9'h0F
`define ORA_ALX 9'h1F
`define ORA_DSP 9'h03
`define ORA_DSPIY 9'h13
`define EOR_IMM 9'h49
`define EOR_ZP 9'h45
`define EOR_ZPX 9'h55
`define EOR_IX 9'h41
`define EOR_IY 9'h51
`define EOR_IYL 9'h57
`define EOR_ABS 9'h4D
`define EOR_ABSX 9'h5D
`define EOR_ABSY 9'h59
`define EOR_RIND 9'h52
`define EOR_I 9'h52
`define EOR_IL 9'h47
`define EOR_DSP 9'h43
`define EOR_DSPIY 9'h53
`define EOR_AL 9'h4F
`define EOR_ALX 9'h5F
//`define LDB_RIND 9'hB2 // Conflict with LDX #imm16
`define LDA_IMM 9'hA9
`define LDA_ZP 9'hA5
`define LDA_ZPX 9'hB5
`define LDA_IX 9'hA1
`define LDA_IY 9'hB1
`define LDA_IYL 9'hB7
`define LDA_ABS 9'hAD
`define LDA_ABSX 9'hBD
`define LDA_ABSY 9'hB9
`define LDA_I 9'hB2
`define LDA_IL 9'hA7
`define LDA_AL 9'hAF
`define LDA_ALX 9'hBF
`define LDA_DSP 9'hA3
`define LDA_DSPIY 9'hB3
`define STA_ZP 9'h85
`define STA_ZPX 9'h95
`define STA_IX 9'h81
`define STA_IY 9'h91
`define STA_IYL 9'h97
`define STA_ABS 9'h8D
`define STA_ABSX 9'h9D
`define STA_ABSY 9'h99
`define STA_I 9'h92
`define STA_IL 9'h87
`define STA_AL 9'h8F
`define STA_ALX 9'h9F
`define STA_DSP 9'h83
`define STA_DSPIY 9'h93
`define ASL_ACC 9'h0A
`define ASL_ZP 9'h06
`define ASL_RR 9'h06
`define ASL_ZPX 9'h16
`define ASL_ABS 9'h0E
`define ASL_ABSX 9'h1E
`define ROL_ACC 9'h2A
`define ROL_ZP 9'h26
`define ROL_RR 9'h26
`define ROL_ZPX 9'h36
`define ROL_ABS 9'h2E
`define ROL_ABSX 9'h3E
`define LSR_ACC 9'h4A
`define LSR_ZP 9'h46
`define LSR_RR 9'h46
`define LSR_ZPX 9'h56
`define LSR_ABS 9'h4E
`define LSR_ABSX 9'h5E
`define ROR_RR 9'h66
`define ROR_ZP 9'h66
`define ROR_ZPX 9'h76
`define ROR_ABS 9'h6E
`define ROR_ABSX 9'h7E
`define DEC_RR 9'hC6
`define DEC_ZP 9'hC6
`define DEC_ZPX 9'hD6
`define DEC_ABS 9'hCE
`define DEC_ABSX 9'hDE
`define INC_RR 9'hE6
`define INC_ZP 9'hE6
`define INC_ZPX 9'hF6
`define INC_ABS 9'hEE
`define INC_ABSX 9'hFE
`define BIT_IMM 9'h89
`define BIT_ZP 9'h24
`define BIT_ZPX 9'h34
`define BIT_ABS 9'h2C
`define BIT_ABSX 9'h3C
// CMP = SUB r0,...
// BIT = AND r0,...
`define BPL 9'h10
`define BVC 9'h50
`define BCC 9'h90
`define BNE 9'hD0
`define BMI 9'h30
`define BVS 9'h70
`define BCS 9'hB0
`define BEQ 9'hF0
`define BRL 9'h82
`define BRA 9'h80
`define JML 9'h5C
`define JMP 9'h4C
`define JMP_IND 9'h6C
`define JMP_INDX 9'h7C
`define JMP_RIND 9'hD2
`define JSR 9'h20
`define JSL 9'h22
`define JSR_IND 9'h2C
`define JSR_INDX 9'hFC
`define JSR_RIND 9'hC2
`define RTS 9'h60
`define RTL 9'h6B
`define BSR 9'h62
`define NOP 9'hEA
`define BRK 9'h00
`define PLX 9'hFA
`define PLY 9'h7A
`define PHX 9'hDA
`define PHY 9'h5A
`define WAI 9'hCB
`define PUSH 9'h0B
`define POP 9'h2B
`define PHB 9'h8B
`define PHD 9'h0B
`define PHK 9'h4B
`define XBA 9'hEB
`define COP 9'h02
`define PLB 9'hAB
`define PLD 9'h2B
`define PSHR4 9'h0F
`define POPR4 9'h2F
`define LDX_IMM 9'hA2
`define LDX_ZP 9'hA6
`define LDX_ZPX 9'hB6
`define LDX_ZPY 9'hB6
`define LDX_ABS 9'hAE
`define LDX_ABSY 9'hBE
`define LDX_IMM32 9'hA2
`define LDX_IMM16 9'hB2
`define LDX_IMM8 9'hA6
`define LDY_IMM 9'hA0
`define LDY_ZP 9'hA4
`define LDY_ZPX 9'hB4
`define LDY_IMM32 9'hA0
`define LDY_IMM8 9'hA1
`define LDY_ABS 9'hAC
`define LDY_ABSX 9'hBC
`define STX_ZP 9'h86
`define STX_ZPX 9'h96
`define STX_ZPY 9'h96
`define STX_ABS 9'h8E
`define STY_ZP 9'h84
`define STY_ZPX 9'h94
`define STY_ABS 9'h8C
`define STZ_ZP 9'h64
`define STZ_ZPX 9'h74
`define STZ_ABS 9'h9C
`define STZ_ABSX 9'h9E
`define CPX_IMM 9'hE0
`define CPX_IMM32 9'hE0
`define CPX_IMM8 9'hE2
`define CPX_ZP 9'hE4
`define CPX_ZPX 9'hE4
`define CPX_ABS 9'hEC
`define CPY_IMM 9'hC0
`define CPY_IMM32 9'hC0
`define CPY_IMM8 9'hC1
`define CPY_ZP 9'hC4
`define CPY_ZPX 9'hC4
`define CPY_ABS 9'hCC
`define TRB_ZP 9'h14
`define TRB_ZPX 9'h14
`define TRB_ABS 9'h1C
`define TSB_ZP 9'h04
`define TSB_ZPX 9'h04
`define TSB_ABS 9'h0C
`define MVP 9'h44
`define MVN 9'h54
`define STS 9'h64
// Page Two Opcodes
`define PG2 9'h42
`define ICOFF 9'h108
`define ICON 9'h128
`define TOFF 9'h118
`define TON 9'h138
`define MUL_IMM8 9'h105
`define MUL_IMM16 9'h119
`define MUL_IMM32 9'h109
`define MULS_IMM8 9'h125
`define MULS_IMM16 9'h139
`define MULS_IMM32 9'h129
`define DIV_IMM8 9'h145
`define DIV_IMM16 9'h159
`define DIV_IMM32 9'h149
`define DIVS_IMM8 9'h165
`define DIVS_IMM16 9'h179
`define DIVS_IMM32 9'h169
`define MOD_IMM8 9'h185
`define MOD_IMM16 9'h199
`define MOD_IMM32 9'h189
`define MODS_IMM8 9'h1A5
`define MODS_IMM16 9'h1B9
`define MODS_IMM32 9'h1A9
`define PUSHA 9'h10B
`define POPA 9'h12B
`define BMS_ZPX 9'h106
`define BMS_ABS 9'h10E
`define BMS_ABSX 9'h11E
`define BMC_ZPX 9'h126
`define BMC_ABS 9'h12E
`define BMC_ABSX 9'h13E
`define BMF_ZPX 9'h146
`define BMF_ABS 9'h14E
`define BMF_ABSX 9'h15E
`define BMT_ZPX 9'h166
`define BMT_ABS 9'h16E
`define BMT_ABSX 9'h17E
`define HOFF 9'h158
`define CMPS 9'h144
`define SPL_ABS 9'h18E
`define SPL_ABSX 9'h19E
`define LEA_ZPX 9'h1D5
`define LEA_IX 9'h1C1
`define LEA_IY 9'h1D1
`define LEA_ABS 9'h1CD
`define LEA_ABSX 9'h1DD
`define LEA_RIND 9'h1D2
`define LEA_I 9'h1D2
`define LEA_DSP 9'h1C3
`define NOTHING 5'd0
`define SR_70 5'd1
`define SR_310 5'd2
`define BYTE_70 5'd3
`define WORD_310 5'd4
`define PC_70 5'd5
`define PC_158 5'd6
`define PC_2316 5'd7
`define PC_3124 5'd8
`define PC_310 5'd9
`define WORD_311 5'd10
`define IA_310 5'd11
`define IA_70 5'd12
`define IA_158 5'd13
`define BYTE_71 5'd14
`define WORD_312 5'd15
`define WORD_313 5'd16
`define WORD_314 5'd17
`define IA_2316 5'd18
`define HALF_70 5'd19
`define HALF_158 5'd20
`define HALF_71 5'd21
`define HALF_159 5'd22
`define HALF_71S 5'd23
`define HALF_159S 5'd24
`define BYTE_72 5'd25
`define TRIP_2316 5'd26
`define STW_DEF 6'h0
`define STW_RES8 6'd14
`define STW_R4 6'd15
`define STW_ACC8 6'd16
`define STW_X8 6'd17
`define STW_Y8 6'd18
`define STW_PC3124 6'd19
`define STW_PC2316 6'd20
`define STW_PC158 6'd21
`define STW_PC70 6'd22
`define STW_SR70 6'd23
`define STW_Z8 6'd24
`define STW_DEF8 6'd25
`define STW_DEF70 6'd26
`define STW_DEF158 6'd27
`define STW_DEF2316 6'd28
`define STW_ACC70 6'd32
`define STW_ACC158 6'd33
`define STW_X70 6'd34
`define STW_X158 6'd35
`define STW_Y70 6'd36
`define STW_Y158 6'd37
`define STW_Z70 6'd38
`define STW_Z158 6'd39
`define STW_DBR 6'd40
`define STW_DPR158 6'd41
`define STW_DPR70 6'd42
`define STW_TMP158 6'd43
`define STW_TMP70 6'd44
`define STW_IA158 6'd45
`define STW_IA70 6'd46
`define STW_BRA 6'd47
// Input Frequency is 32 times the 00 clock
module FT816(rst, clk, clko, cyc, phi11, phi12, phi81, phi82, nmi, irq, abort, e, mx, rdy, be, vpa, vda, mlb, vpb, rw, ad, db, dw, err_i, rty_i);
parameter SUPPORT_TRIBYTES = 1'b0;
parameter STORE_SKIPPING = 1'b1;
parameter EXTRA_LONG_BRANCHES = 1'b1;
parameter RESET1 = 6'd0;
parameter IFETCH1 = 6'd1;
parameter IFETCH2 = 6'd2;
parameter IFETCH3 = 6'd3;
parameter IFETCH4 = 6'd4;
parameter DECODE1 = 6'd5;
parameter DECODE2 = 6'd6;
parameter DECODE3 = 6'd7;
parameter DECODE4 = 6'd8;
parameter STORE1 = 6'd9;
parameter STORE2 = 6'd10;
parameter JSR161 = 6'd11;
parameter RTS1 = 6'd12;
parameter IY3 = 6'd13;
parameter BSR1 = 6'd14;
parameter BYTE_IX5 = 6'd15;
parameter BYTE_IY5 = 6'd16;
parameter WAIT_DHIT = 6'd17;
parameter BYTE_CALC = 6'd18;
parameter BUS_ERROR = 6'd19;
parameter LOAD_MAC1 = 6'd20;
parameter LOAD_MAC2 = 6'd21;
parameter LOAD_MAC3 = 6'd22;
parameter MVN3 = 6'd23;
parameter IFETCH0 = 6'd24;
parameter LOAD_DCACHE = 6'd26;
parameter LOAD_ICACHE = 6'd27;
parameter LOAD_IBUF1 = 6'd28;
parameter LOAD_IBUF2 = 6'd29;
parameter LOAD_IBUF3 = 6'd30;
parameter ICACHE1 = 6'd31;
parameter IBUF1 = 6'd32;
parameter DCACHE1 = 6'd33;
parameter HALF_CALC = 6'd35;
parameter MVN816 = 6'd36;
input rst;
input clk;
output clko;
output reg [4:0] cyc;
output phi11;
output phi12;
output phi81;
output phi82;
input nmi;
input irq;
input abort;
output e;
output mx;
input rdy;
input be;
output reg vpa;
output reg vda;
output reg mlb;
output reg vpb;
output tri rw;
output tri [23:0] ad;
input [7:0] db;
output[7:0] dw;
input err_i;
input rty_i;
parameter TRUE = 1'b1;
parameter FALSE = 1'b0;
reg [31:0] phi1r,phi2r;
reg rwo;
reg [23:0] ado;
reg [7:0] dbo;
reg [7:0] dbi;
reg pg2;
reg [5:0] state;
reg [5:0] retstate;
reg [31:0] ir;
wire [8:0] ir9 = {pg2,ir[7:0]};
reg [23:0] pc,opc;
reg [15:0] dpr; // direct page register
reg [7:0] dbr; // data bank register
reg [15:0] x,y,acc,sp;
reg [15:0] tmp;
wire [15:0] acc16 = acc;
wire [7:0] acc8=acc[7:0];
wire [7:0] x8=x[7:0];
wire [7:0] y8=y[7:0];
wire [15:0] x16 = x[15:0];
wire [15:0] y16 = y[15:0];
wire [15:0] acc_dec = acc - 16'd1;
wire [15:0] acc_inc = acc + 16'd1;
wire [15:0] x_dec = x - 16'd1;
wire [15:0] x_inc = x + 16'd1;
wire [15:0] y_dec = y - 16'd1;
wire [15:0] y_inc = y + 16'd1;
wire [15:0] sp_dec = sp - 16'd1;
wire [15:0] sp_inc = sp + 16'd1;
wire [15:0] sp_dec2 = sp - 16'd2;
reg gie; // global interrupt enable (set when sp is loaded)
reg hwi; // hardware interrupt indicator
reg im;
reg cf,vf,nf,zf,df,em,bf;
reg m816;
reg x_bit,m_bit;
wire m16 = m816 & ~m_bit;
wire xb16 = m816 & ~x_bit;
wire [7:0] sr8 = m816 ? {nf,vf,m_bit,x_bit,df,im,zf,cf} : {nf,vf,1'b0,bf,df,im,zf,cf};
reg nmi1,nmi_edge;
reg wai;
reg [7:0] b8;
reg [15:0] b16;
reg [7:0] b24;
reg [8:0] res8;
reg [16:0] res16;
wire resc8 = res8[8];
wire resc16 = res16[16];
wire resz8 = ~|res8[7:0];
wire resz16 = ~|res16[15:0];
wire resn8 = res8[7];
wire resn16 = res16[15];
reg [23:0] radr;
reg [23:0] wadr;
reg [23:0] wdat;
wire [7:0] rdat;
reg [4:0] load_what;
reg [5:0] store_what;
reg [15:0] tmp16;
reg first_ifetch;
reg [23:0] derr_address;
reg [8:0] intno;
reg isBusErr;
reg isBrk,isMove,isSts;
reg isMove816;
reg isRTI,isRTL,isRTS;
reg isRMW;
reg isSub;
reg isJsrIndx,isJsrInd;
reg isIY,isIY24,isI24;
reg isTribyte;
wire isCmp = ir9==`CPX_ZPX || ir9==`CPX_ABS ||
ir9==`CPY_ZPX || ir9==`CPY_ABS;
wire isRMW8 =
ir9==`ASL_ZP || ir9==`ROL_ZP || ir9==`LSR_ZP || ir9==`ROR_ZP || ir9==`INC_ZP || ir9==`DEC_ZP ||
ir9==`ASL_ZPX || ir9==`ROL_ZPX || ir9==`LSR_ZPX || ir9==`ROR_ZPX || ir9==`INC_ZPX || ir9==`DEC_ZPX ||
ir9==`ASL_ABS || ir9==`ROL_ABS || ir9==`LSR_ABS || ir9==`ROR_ABS || ir9==`INC_ABS || ir9==`DEC_ABS ||
ir9==`ASL_ABSX || ir9==`ROL_ABSX || ir9==`LSR_ABSX || ir9==`ROR_ABSX || ir9==`INC_ABSX || ir9==`DEC_ABSX ||
ir9==`TRB_ZP || ir9==`TRB_ZPX || ir9==`TRB_ABS || ir9==`TSB_ZP || ir9==`TSB_ZPX || ir9==`TSB_ABS;
wire isBranch = ir9==`BRA || ir9==`BEQ || ir9==`BNE || ir9==`BVS || ir9==`BVC || ir9==`BMI || ir9==`BPL || ir9==`BCS || ir9==`BCC;
// Registerable decodes
// The following decodes can be registered because they aren't needed until at least the cycle after
// the DECODE stage.
always @(posedge clk)
if (state==RESET1)
isBrk <= `TRUE;
else if (state==DECODE1||state==DECODE2||state==DECODE3||state==DECODE4) begin
isRMW <= isRMW8;
isRTI <= ir9==`RTI;
isRTL <= ir9==`RTL;
isRTS <= ir9==`RTS;
isBrk <= ir9==`BRK || ir9==`COP;
isMove <= ir9==`MVP || ir9==`MVN;
isJsrIndx <= ir9==`JSR_INDX;
isJsrInd <= ir9==`JSR_IND;
end
assign mx = clk ? m_bit : x_bit;
assign e = ~m816;
wire [15:0] bcaio;
wire [15:0] bcao;
wire [15:0] bcsio;
wire [15:0] bcso;
wire bcaico,bcaco,bcsico,bcsco;
wire bcaico8,bcaco8,bcsico8,bcsco8;
`ifdef SUPPORT_BCD
BCDAdd4 ubcdai1 (.ci(cf),.a(acc16),.b(ir[23:8]),.o(bcaio),.c(bcaico),.c8(bcaico8));
BCDAdd4 ubcda2 (.ci(cf),.a(acc16),.b(b8),.o(bcao),.c(bcaco),.c8(bcaco8));
BCDSub4 ubcdsi1 (.ci(cf),.a(acc16),.b(ir[23:8]),.o(bcsio),.c(bcsico),.c8(bcsico8));
BCDSub4 ubcds2 (.ci(cf),.a(acc16),.b(b8),.o(bcso),.c(bcsco),.c8(bcsco8));
`endif
wire [7:0] dati = db;
// Evaluate branches
//
reg takb;
always @(ir9 or cf or vf or nf or zf)
case(ir9)
`BEQ: takb <= zf;
`BNE: takb <= !zf;
`BPL: takb <= !nf;
`BMI: takb <= nf;
`BCS: takb <= cf;
`BCC: takb <= !cf;
`BVS: takb <= vf;
`BVC: takb <= !vf;
`BRA: takb <= 1'b1;
`BRL: takb <= 1'b1;
default: takb <= 1'b0;
endcase
reg [23:0] ia;
wire [23:0] mvnsrc_address = {ir[23:16],x16};
wire [23:0] mvndst_address = {ir[15: 8],y16};
wire [23:0] iapy8 = ia + y16; // Don't add in abs8, already included with ia
wire [23:0] zp_address = {8'h00,ir[15:8]} + dpr;
wire [23:0] zpx_address = {{16'h00,ir[15:8]} + x16} + dpr;
wire [23:0] zpy_address = {{16'h00,ir[15:8]} + y16} + dpr;
wire [23:0] abs_address = {dbr,ir[23:8]};
wire [23:0] absx_address = {dbr,ir[23:8] + x16}; // simulates 64k bank wrap-around
wire [23:0] absy_address = {dbr,ir[23:8] + y16};
wire [23:0] al_address = {ir[31:8]};
wire [23:0] alx_address = {ir[31:8] + x16};
wire [23:0] dsp_address = m816 ? {8'h00,sp + ir[15:8]} : {16'h0001,sp[7:0]+ir[15:8]};
reg [23:0] vect;
assign rw = be ? rwo : 1'bz;
assign ad = be ? ado : {24{1'bz}};
assign dw = rwo ? {8{1'bz}} : be ? dbo : {8{1'bz}};
reg [31:0] phi11r,phi12r,phi81r,phi82r;
assign phi11 = phi11r[31];
assign phi12 = phi12r[31];
assign phi81 = phi81r[31];
assign phi82 = phi82r[31];
always @(posedge clk)
if (~rst) begin
cyc <= 5'd0;
phi11r <= 32'b01111111111111100000000000000000;
phi12r <= 32'b00000000000000000111111111111110;
phi81r <= 32'b01110000011100000111000001110000;
phi82r <= 32'b00000111000001110000011100000111;
end
else begin
cyc <= cyc + 5'd1;
phi11r <= {phi11r[30:0],phi11r[31]};
phi12r <= {phi12r[30:0],phi12r[31]};
phi81r <= {phi81r[30:0],phi81r[31]};
phi82r <= {phi82r[30:0],phi82r[31]};
end
// Detect a single byte opcode
function isOneByte;
input [7:0] ir;
casex(ir)
8'hx8: isOneByte = TRUE;
8'hxA: isOneByte = TRUE;
8'hxB: isOneByte = TRUE;
`RTI,`RTS: isOneByte = TRUE;
default: isOneByte = FALSE;
endcase
endfunction
// Detect double byte opcode
function isTwoBytes;
input [7:0] ir;
input m16;
input xb16;
casex(ir)
`BRK,`COP: isTwoBytes = TRUE;
8'hx1: isTwoBytes = TRUE;
8'hx3: isTwoBytes = TRUE;
8'hx5: isTwoBytes = TRUE;
8'hx6: isTwoBytes = TRUE;
8'hx7: isTwoBytes = TRUE;
`BPL,`BMI,`BVS,`BVC,`BCS,`BCC,`BEQ,`BNE,`BRA: isTwoBytes = TRUE;
`LDY_IMM,`CPY_IMM,`CPX_IMM,`LDX_IMM: isTwoBytes = !xb16;
`ORA_I,`AND_I,`EOR_I,`LDA_I,`CMP_I,`STA_I,`ADC_I,`SBC_I,`PEI:
isTwoBytes = TRUE;
`REP,`SEP: isTwoBytes = TRUE;
`TSB_ZPX,`TRB_ZPX,`BIT_ZP,`BIT_ZPX,`STZ_ZP,`STZ_ZPX,`STY_ZP,`STY_ZPX,
`LDY_ZP,`LDY_ZPX,`CPY_ZP,`CPX_ZP:
isTwoBytes = TRUE;
`ORA_IMM,`AND_IMM,`EOR_IMM,`ADC_IMM,`SBC_IMM,`CMP_IMM,`LDA_IMM,`BIT_IMM:
isTwoBytes = !m16;
default: isTwoBytes = FALSE;
endcase
endfunction
function isThreeBytes;
input [7:0] ir;
input m16;
input xb16;
casex(ir)
`JSR: isThreeBytes = TRUE;
`PER,`BRL: isThreeBytes = TRUE;
`MVP,`MVN,`PEA: isThreeBytes = TRUE;
`LDY_IMM,`CPY_IMM,`CPX_IMM,`LDX_IMM: isThreeBytes = xb16;
`ORA_IMM,`AND_IMM,`EOR_IMM,`ADC_IMM,`SBC_IMM,`CMP_IMM,`LDA_IMM,`BIT_IMM:
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff