OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/tags/V10/rtl/vhdl/cpu09.vhd
0,0 → 1,9535
--===========================================================================----
--
-- S Y N T H E Z I A B L E CPU09 - 6809 compatible CPU Core
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : cpu09.vhd
--
-- Purpose : 6809 CPU core
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Uses : None
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 26 June 2003 - John Kent
-- Added extra level in state stack
-- fixed some calls to the extended addressing state
--
-- Version 0.2 - 5 Sept 2003 - John Kent
-- Fixed 16 bit indexed offset (was doing read rather than fetch)
-- Added/Fixed STY and STS instructions.
-- ORCC_STATE ANDed CC state rather than ORed it - Now fixed
-- CMPX Loaded ACCA and ACCB - Now fixed
--
-- Version 1.0 - 6 Sep 2003 - John Kent
-- Initial release to Open Cores
-- reversed clock edge
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity cpu09 is
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic;
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
firq: in std_logic;
nmi: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end;
 
architecture CPU_ARCH of cpu09 is
 
constant EBIT : integer := 7;
constant FBIT : integer := 6;
constant HBIT : integer := 5;
constant IBIT : integer := 4;
constant NBIT : integer := 3;
constant ZBIT : integer := 2;
constant VBIT : integer := 1;
constant CBIT : integer := 0;
 
--
-- Interrupt vector modifiers
--
constant RST_VEC : std_logic_vector(2 downto 0) := "111";
constant NMI_VEC : std_logic_vector(2 downto 0) := "110";
constant SWI_VEC : std_logic_vector(2 downto 0) := "101";
constant IRQ_VEC : std_logic_vector(2 downto 0) := "100";
constant FIRQ_VEC : std_logic_vector(2 downto 0) := "011";
constant SWI2_VEC : std_logic_vector(2 downto 0) := "010";
constant SWI3_VEC : std_logic_vector(2 downto 0) := "001";
constant RESV_VEC : std_logic_vector(2 downto 0) := "000";
 
type state_type is (-- Start off in Reset
reset_state,
-- Fetch Interrupt Vectors (including reset)
vect_lo_state, vect_hi_state,
-- Fetch Instruction Cycle
fetch_state,
-- Decode Instruction Cycles
decode1_state, decode2_state, decode3_state,
-- Calculate Effective Address
imm16_state,
indexed_state, index8_state, index16_state, index16_2_state,
pcrel8_state, pcrel16_state, pcrel16_2_state,
indexaddr_state, indexaddr2_state,
postincr1_state, postincr2_state,
indirect_state, indirect2_state, indirect3_state,
extended_state,
-- single ops
single_op_read_state,
single_op_exec_state,
single_op_write_state,
-- Dual op states
dual_op_read8_state, dual_op_read16_state, dual_op_read16_2_state,
dual_op_write8_state, dual_op_write16_state,
--
sync_state, halt_state, error_state,
--
andcc_state, orcc_state,
tfr_state, exg_state, exg1_state,
lea_state,
-- Multiplication
mul_state, mulea_state, muld_state,
mul0_state, mul1_state, mul2_state, mul3_state,
mul4_state, mul5_state, mul6_state, mul7_state,
-- Branches
lbranch_state, sbranch_state,
-- Jumps, Subroutine Calls and Returns
jsr_state, jmp_state,
push_return_hi_state, push_return_lo_state,
pull_return_hi_state, pull_return_lo_state,
-- Interrupt cycles
int_decr_state,
int_entire_state,
int_pcl_state, int_pch_state,
int_upl_state, int_uph_state,
int_iyl_state, int_iyh_state,
int_ixl_state, int_ixh_state,
int_cc_state,
int_acca_state, int_accb_state,
int_dp_state,
int_cwai_state, int_mask_state,
-- Return From Interrupt
rti_state,
rti_acca_state, rti_accb_state,
rti_cc_state, rti_dp_state,
rti_ixl_state, rti_ixh_state,
rti_iyl_state, rti_iyh_state,
rti_upl_state, rti_uph_state,
rti_pcl_state, rti_pch_state,
-- Push Registers using SP
pshs_state,
pshs_pcl_state, pshs_pch_state,
pshs_upl_state, pshs_uph_state,
pshs_iyl_state, pshs_iyh_state,
pshs_ixl_state, pshs_ixh_state,
pshs_dp_state,
pshs_acca_state, pshs_accb_state,
pshs_cc_state,
-- Pull Registers using SP
puls_state,
puls_cc_state,
puls_acca_state, puls_accb_state,
puls_dp_state,
puls_ixl_state, puls_ixh_state,
puls_iyl_state, puls_iyh_state,
puls_upl_state, puls_uph_state,
puls_pcl_state, puls_pch_state,
-- Push Registers using UP
pshu_state,
pshu_pcl_state, pshu_pch_state,
pshu_spl_state, pshu_sph_state,
pshu_iyl_state, pshu_iyh_state,
pshu_ixl_state, pshu_ixh_state,
pshu_dp_state,
pshu_acca_state, pshu_accb_state,
pshu_cc_state,
-- Pull Registers using UP
pulu_state,
pulu_cc_state,
pulu_acca_state, pulu_accb_state,
pulu_dp_state,
pulu_ixl_state, pulu_ixh_state,
pulu_iyl_state, pulu_iyh_state,
pulu_spl_state, pulu_sph_state,
pulu_pcl_state, pulu_pch_state );
 
type stack_type is array(2 downto 0) of state_type;
type st_type is (idle_st, push_st, pull_st );
type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, pushu_ad, pullu_ad, pushs_ad, pulls_ad, int_hi_ad, int_lo_ad );
type dout_type is (cc_dout, acca_dout, accb_dout, dp_dout,
ix_lo_dout, ix_hi_dout, iy_lo_dout, iy_hi_dout,
up_lo_dout, up_hi_dout, sp_lo_dout, sp_hi_dout,
pc_lo_dout, pc_hi_dout, md_lo_dout, md_hi_dout );
type op_type is (reset_op, fetch_op, latch_op );
type pre_type is (reset_pre, fetch_pre, latch_pre );
type cc_type is (reset_cc, load_cc, pull_cc, latch_cc );
type acca_type is (reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca );
type accb_type is (reset_accb, load_accb, pull_accb, latch_accb );
type dp_type is (reset_dp, load_dp, pull_dp, latch_dp );
type ix_type is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix );
type iy_type is (reset_iy, load_iy, pull_lo_iy, pull_hi_iy, latch_iy );
type sp_type is (reset_sp, latch_sp, load_sp, pull_hi_sp, pull_lo_sp );
type up_type is (reset_up, latch_up, load_up, pull_hi_up, pull_lo_up );
type pc_type is (reset_pc, latch_pc, load_pc, pull_lo_pc, pull_hi_pc, incr_pc );
type md_type is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md );
type ea_type is (reset_ea, latch_ea, load_ea, fetch_first_ea, fetch_next_ea );
type iv_type is (reset_iv, latch_iv, nmi_iv, irq_iv, firq_iv, swi_iv, swi2_iv, swi3_iv, resv_iv);
type nmi_type is (reset_nmi, set_nmi, latch_nmi );
type left_type is (cc_left, acca_left, accb_left, dp_left,
ix_left, iy_left, up_left, sp_left,
accd_left, md_left, pc_left, ea_left );
type right_type is (ea_right, zero_right, one_right, two_right,
acca_right, accb_right, accd_right,
md_right, md_sign5_right, md_sign8_right );
type alu_type is (alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc,
alu_and, alu_ora, alu_eor,
alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
alu_inx, alu_dex,
alu_lsr16, alu_lsl16,
alu_ror8, alu_rol8,
alu_asr8, alu_asl8, alu_lsr8,
alu_andcc, alu_orcc, alu_sex, alu_tfr,
alu_seif, alu_sei, alu_see, alu_cle,
alu_ld8, alu_st8, alu_ld16, alu_st16, alu_nop, alu_daa );
 
signal op_code: std_logic_vector(7 downto 0);
signal pre_code: std_logic_vector(7 downto 0);
signal acca: std_logic_vector(7 downto 0);
signal accb: std_logic_vector(7 downto 0);
signal cc: std_logic_vector(7 downto 0);
signal cc_out: std_logic_vector(7 downto 0);
signal dp: std_logic_vector(7 downto 0);
signal xreg: std_logic_vector(15 downto 0);
signal yreg: std_logic_vector(15 downto 0);
signal sp: std_logic_vector(15 downto 0);
signal up: std_logic_vector(15 downto 0);
signal ea: std_logic_vector(15 downto 0);
signal pc: std_logic_vector(15 downto 0);
signal md: std_logic_vector(15 downto 0);
signal left: std_logic_vector(15 downto 0);
signal right: std_logic_vector(15 downto 0);
signal out_alu: std_logic_vector(15 downto 0);
signal iv: std_logic_vector(2 downto 0);
signal nmi_req: std_logic;
signal nmi_ack: std_logic;
 
signal state: state_type;
signal next_state: state_type;
signal saved_state: state_type;
signal return_state: state_type;
signal state_stack: stack_type;
signal st_ctrl: st_type;
signal pc_ctrl: pc_type;
signal ea_ctrl: ea_type;
signal op_ctrl: op_type;
signal pre_ctrl: pre_type;
signal md_ctrl: md_type;
signal acca_ctrl: acca_type;
signal accb_ctrl: accb_type;
signal ix_ctrl: ix_type;
signal iy_ctrl: iy_type;
signal cc_ctrl: cc_type;
signal dp_ctrl: dp_type;
signal sp_ctrl: sp_type;
signal up_ctrl: up_type;
signal iv_ctrl: iv_type;
signal left_ctrl: left_type;
signal right_ctrl: right_type;
signal alu_ctrl: alu_type;
signal addr_ctrl: addr_type;
signal dout_ctrl: dout_type;
signal nmi_ctrl: nmi_type;
 
 
begin
 
----------------------------------
--
-- State machine stack
--
----------------------------------
state_stack_proc: process( clk, st_ctrl, state_stack, return_state, hold )
begin
if clk'event and clk = '0' then
if hold= '1' then
state_stack(0) <= state_stack(0);
state_stack(1) <= state_stack(1);
state_stack(2) <= state_stack(2);
else
case st_ctrl is
when idle_st =>
state_stack(0) <= state_stack(0);
state_stack(1) <= state_stack(1);
state_stack(2) <= state_stack(2);
when push_st =>
state_stack(0) <= return_state;
state_stack(1) <= state_stack(0);
state_stack(2) <= state_stack(1);
when pull_st =>
state_stack(0) <= state_stack(1);
state_stack(1) <= state_stack(2);
state_stack(2) <= fetch_state;
when others =>
state_stack(0) <= state_stack(0);
state_stack(1) <= state_stack(1);
state_stack(2) <= state_stack(2);
end case;
end if;
end if;
saved_state <= state_stack(0);
end process;
 
----------------------------------
--
-- Program Counter Control
--
----------------------------------
 
pc_reg: process( clk, pc_ctrl, hold, pc, out_alu, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
pc <= pc;
else
case pc_ctrl is
when reset_pc =>
pc <= "0000000000000000";
when load_pc =>
pc <= out_alu(15 downto 0);
when pull_lo_pc =>
pc(7 downto 0) <= data_in;
when pull_hi_pc =>
pc(15 downto 8) <= data_in;
when incr_pc =>
pc <= pc + 1;
when others =>
-- when latch_pc =>
pc <= pc;
end case;
end if;
end if;
end process;
 
----------------------------------
--
-- Effective Address Control
--
----------------------------------
 
ea_reg: process( clk, ea_ctrl, hold, ea, out_alu, data_in, dp )
begin
 
if clk'event and clk = '0' then
if hold= '1' then
ea <= ea;
else
case ea_ctrl is
when reset_ea =>
ea <= "0000000000000000";
when fetch_first_ea =>
ea(7 downto 0) <= data_in;
ea(15 downto 8) <= dp;
when fetch_next_ea =>
ea(15 downto 8) <= ea(7 downto 0);
ea(7 downto 0) <= data_in;
when load_ea =>
ea <= out_alu(15 downto 0);
when others =>
-- when latch_ea =>
ea <= ea;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- Accumulator A
--
--------------------------------
acca_reg : process( clk, acca_ctrl, hold, out_alu, acca, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
acca <= acca;
else
case acca_ctrl is
when reset_acca =>
acca <= "00000000";
when load_acca =>
acca <= out_alu(7 downto 0);
when load_hi_acca =>
acca <= out_alu(15 downto 8);
when pull_acca =>
acca <= data_in;
when others =>
-- when latch_acca =>
acca <= acca;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- Accumulator B
--
--------------------------------
accb_reg : process( clk, accb_ctrl, hold, out_alu, accb, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
accb <= accb;
else
case accb_ctrl is
when reset_accb =>
accb <= "00000000";
when load_accb =>
accb <= out_alu(7 downto 0);
when pull_accb =>
accb <= data_in;
when others =>
-- when latch_accb =>
accb <= accb;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- X Index register
--
--------------------------------
ix_reg : process( clk, ix_ctrl, hold, out_alu, xreg, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
xreg <= xreg;
else
case ix_ctrl is
when reset_ix =>
xreg <= "0000000000000000";
when load_ix =>
xreg <= out_alu(15 downto 0);
when pull_hi_ix =>
xreg(15 downto 8) <= data_in;
when pull_lo_ix =>
xreg(7 downto 0) <= data_in;
when others =>
-- when latch_ix =>
xreg <= xreg;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- Y Index register
--
--------------------------------
iy_reg : process( clk, iy_ctrl, hold, out_alu, yreg, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
yreg <= yreg;
else
case iy_ctrl is
when reset_iy =>
yreg <= "0000000000000000";
when load_iy =>
yreg <= out_alu(15 downto 0);
when pull_hi_iy =>
yreg(15 downto 8) <= data_in;
when pull_lo_iy =>
yreg(7 downto 0) <= data_in;
when others =>
-- when latch_iy =>
yreg <= yreg;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- S stack pointer
--
--------------------------------
sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
sp <= sp;
else
case sp_ctrl is
when reset_sp =>
sp <= "0000000000000000";
when load_sp =>
sp <= out_alu(15 downto 0);
when pull_hi_sp =>
sp(15 downto 8) <= data_in;
when pull_lo_sp =>
sp(7 downto 0) <= data_in;
when others =>
-- when latch_sp =>
sp <= sp;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- U stack pointer
--
--------------------------------
up_reg : process( clk, up_ctrl, hold, up, out_alu, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
up <= up;
else
case up_ctrl is
when reset_up =>
up <= "0000000000000000";
when load_up =>
up <= out_alu(15 downto 0);
when pull_hi_up =>
up(15 downto 8) <= data_in;
when pull_lo_up =>
up(7 downto 0) <= data_in;
when others =>
-- when latch_up =>
up <= up;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- Memory Data
--
--------------------------------
md_reg : process( clk, md_ctrl, hold, out_alu, data_in, md )
begin
if clk'event and clk = '0' then
if hold= '1' then
md <= md;
else
case md_ctrl is
when reset_md =>
md <= "0000000000000000";
when load_md =>
md <= out_alu(15 downto 0);
when fetch_first_md => -- sign extend md for branches
md(15 downto 8) <= data_in(7) & data_in(7) & data_in(7) & data_in(7) &
data_in(7) & data_in(7) & data_in(7) & data_in(7) ;
md(7 downto 0) <= data_in;
when fetch_next_md =>
md(15 downto 8) <= md(7 downto 0);
md(7 downto 0) <= data_in;
when shiftl_md =>
md(15 downto 1) <= md(14 downto 0);
md(0) <= '0';
when others =>
-- when latch_md =>
md <= md;
end case;
end if;
end if;
end process;
 
 
----------------------------------
--
-- Condition Codes
--
----------------------------------
 
cc_reg: process( clk, cc_ctrl, hold, cc_out, cc, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
cc <= cc;
else
case cc_ctrl is
when reset_cc =>
cc <= "11010000"; -- set EBIT, FBIT & IBIT
when load_cc =>
cc <= cc_out;
when pull_cc =>
cc <= data_in;
when others =>
-- when latch_cc =>
cc <= cc;
end case;
end if;
end if;
end process;
 
----------------------------------
--
-- Direct Page register
--
----------------------------------
 
dp_reg: process( clk, dp_ctrl, hold, out_alu, dp, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
dp <= dp;
else
case dp_ctrl is
when reset_dp =>
dp <= "00000000";
when load_dp =>
dp <= out_alu(7 downto 0);
when pull_dp =>
dp <= data_in;
when others =>
-- when latch_dp =>
dp <= dp;
end case;
end if;
end if;
end process;
 
----------------------------------
--
-- interrupt vector
--
----------------------------------
 
iv_mux: process( clk, iv_ctrl, hold, iv )
begin
if clk'event and clk = '0' then
if hold= '1' then
iv <= iv;
else
case iv_ctrl is
when reset_iv =>
iv <= RST_VEC;
when nmi_iv =>
iv <= NMI_VEC;
when swi_iv =>
iv <= SWI_VEC;
when irq_iv =>
iv <= IRQ_VEC;
when firq_iv =>
iv <= FIRQ_VEC;
when swi2_iv =>
iv <= SWI2_VEC;
when swi3_iv =>
iv <= SWI3_VEC;
when resv_iv =>
iv <= RESV_VEC;
when others =>
iv <= iv;
end case;
end if;
end if;
end process;
 
 
----------------------------------
--
-- op code register
--
----------------------------------
 
op_reg: process( clk, op_ctrl, hold, op_code, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
op_code <= op_code;
else
case op_ctrl is
when reset_op =>
op_code <= "00010010";
when fetch_op =>
op_code <= data_in;
when others =>
-- when latch_op =>
op_code <= op_code;
end case;
end if;
end if;
end process;
 
 
----------------------------------
--
-- pre byte op code register
--
----------------------------------
 
pre_reg: process( clk, pre_ctrl, hold, pre_code, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
pre_code <= pre_code;
else
case pre_ctrl is
when reset_pre =>
pre_code <= "00000000";
when fetch_pre =>
pre_code <= data_in;
when others =>
-- when latch_pre =>
pre_code <= pre_code;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- state machine
--
--------------------------------
 
change_state: process( clk, rst, state, hold, next_state )
begin
if clk'event and clk = '0' then
if rst = '1' then
state <= reset_state;
else
if hold = '1' then
state <= state;
else
state <= next_state;
end if;
end if;
end if;
end process;
-- output
------------------------------------
--
-- Nmi register
--
------------------------------------
 
nmi_reg: process( clk, nmi_ctrl, hold, nmi_ack )
begin
if clk'event and clk='0' then
if hold = '1' then
nmi_ack <= nmi_ack;
else
case nmi_ctrl is
when set_nmi =>
nmi_ack <= '1';
when reset_nmi =>
nmi_ack <= '0';
when others =>
-- when latch_nmi =>
nmi_ack <= nmi_ack;
end case;
end if;
end if;
end process;
 
------------------------------------
--
-- Detect Edge of NMI interrupt
--
------------------------------------
 
nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req )
begin
if clk'event and clk='0' then
if rst='1' then
nmi_req <= '0';
else
if (nmi='1') and (nmi_ack='0') then
nmi_req <= '1';
else
if (nmi='0') and (nmi_ack='1') then
nmi_req <= '0';
else
nmi_req <= nmi_req;
end if;
end if;
end if;
end if;
end process;
 
 
----------------------------------
--
-- Address output multiplexer
--
----------------------------------
 
addr_mux: process( addr_ctrl, pc, ea, up, sp, iv )
begin
case addr_ctrl is
when idle_ad =>
address <= "1111111111111111";
vma <= '0';
rw <= '1';
when fetch_ad =>
address <= pc;
vma <= '1';
rw <= '1';
when read_ad =>
address <= ea;
vma <= '1';
rw <= '1';
when write_ad =>
address <= ea;
vma <= '1';
rw <= '0';
when pushs_ad =>
address <= sp;
vma <= '1';
rw <= '0';
when pulls_ad =>
address <= sp;
vma <= '1';
rw <= '1';
when pushu_ad =>
address <= up;
vma <= '1';
rw <= '0';
when pullu_ad =>
address <= up;
vma <= '1';
rw <= '1';
when int_hi_ad =>
address <= "111111111111" & iv & "0";
vma <= '1';
rw <= '1';
when int_lo_ad =>
address <= "111111111111" & iv & "1";
vma <= '1';
rw <= '1';
when others =>
address <= "1111111111111111";
vma <= '0';
rw <= '1';
end case;
end process;
 
--------------------------------
--
-- Data Bus output
--
--------------------------------
dout_mux : process( dout_ctrl, md, acca, accb, dp, xreg, yreg, sp, up, pc, cc )
begin
case dout_ctrl is
when md_hi_dout => -- alu output
data_out <= md(15 downto 8);
when md_lo_dout => -- alu output
data_out <= md(7 downto 0);
when acca_dout => -- accumulator a
data_out <= acca;
when accb_dout => -- accumulator b
data_out <= accb;
when ix_lo_dout => -- index reg
data_out <= xreg(7 downto 0);
when ix_hi_dout => -- index reg
data_out <= xreg(15 downto 8);
when iy_lo_dout => -- index reg
data_out <= yreg(7 downto 0);
when iy_hi_dout => -- index reg
data_out <= yreg(15 downto 8);
when sp_lo_dout => -- s stack pointer
data_out <= sp(7 downto 0);
when sp_hi_dout => -- s stack pointer
data_out <= sp(15 downto 8);
when up_lo_dout => -- u stack pointer
data_out <= up(7 downto 0);
when up_hi_dout => -- u stack pointer
data_out <= up(15 downto 8);
when cc_dout => -- condition code register
data_out <= cc;
when dp_dout => -- direct page register
data_out <= dp;
when pc_lo_dout => -- low order pc
data_out <= pc(7 downto 0);
when pc_hi_dout => -- high order pc
data_out <= pc(15 downto 8);
when others =>
data_out <= "00000000";
end case;
end process;
 
----------------------------------
--
-- Left Mux
--
----------------------------------
 
left_mux: process( left_ctrl, acca, accb, cc, dp, xreg, yreg, up, sp, pc, ea, md )
begin
case left_ctrl is
when cc_left =>
left(15 downto 8) <= "00000000";
left(7 downto 0) <= cc;
when acca_left =>
left(15 downto 8) <= "00000000";
left(7 downto 0) <= acca;
when accb_left =>
left(15 downto 8) <= "00000000";
left(7 downto 0) <= accb;
when dp_left =>
left(15 downto 8) <= "00000000";
left(7 downto 0) <= dp;
when accd_left =>
left(15 downto 8) <= acca;
left(7 downto 0) <= accb;
when md_left =>
left <= md;
when ix_left =>
left <= xreg;
when iy_left =>
left <= yreg;
when sp_left =>
left <= sp;
when up_left =>
left <= up;
when pc_left =>
left <= pc;
when others =>
-- when ea_left =>
left <= ea;
end case;
end process;
 
----------------------------------
--
-- Right Mux
--
----------------------------------
 
right_mux: process( right_ctrl, md, acca, accb, ea )
begin
case right_ctrl is
when ea_right =>
right <= ea;
when zero_right =>
right <= "0000000000000000";
when one_right =>
right <= "0000000000000001";
when two_right =>
right <= "0000000000000010";
when acca_right =>
right <= "00000000" & acca;
when accb_right =>
right <= "00000000" & accb;
when accd_right =>
right <= acca & accb;
when md_sign5_right =>
if md(4) = '0' then
right <= "00000000000" & md(4 downto 0);
else
right <= "11111111111" & md(4 downto 0);
end if;
when md_sign8_right =>
if md(7) = '0' then
right <= "00000000" & md(7 downto 0);
else
right <= "11111111" & md(7 downto 0);
end if;
when others =>
-- when md_right =>
right <= md;
end case;
end process;
 
----------------------------------
--
-- Arithmetic Logic Unit
--
----------------------------------
 
alu: process( alu_ctrl, cc, left, right, out_alu, cc_out )
variable valid_lo, valid_hi : boolean;
variable carry_in : std_logic;
variable daa_reg : std_logic_vector(7 downto 0);
begin
 
case alu_ctrl is
when alu_adc | alu_sbc |
alu_rol8 | alu_ror8 =>
carry_in := cc(CBIT);
when others =>
carry_in := '0';
end case;
 
valid_lo := left(3 downto 0) <= 9;
valid_hi := left(7 downto 4) <= 9;
 
if (cc(CBIT) = '0') then
if( cc(HBIT) = '1' ) then
if valid_hi then
daa_reg := "00000110";
else
daa_reg := "01100110";
end if;
else
if valid_lo then
if valid_hi then
daa_reg := "00000000";
else
daa_reg := "01100000";
end if;
else
if( left(7 downto 4) <= 8 ) then
daa_reg := "00000110";
else
daa_reg := "01100110";
end if;
end if;
end if;
else
if ( cc(HBIT) = '1' )then
daa_reg := "01100110";
else
if valid_lo then
daa_reg := "01100000";
else
daa_reg := "01100110";
end if;
end if;
end if;
 
case alu_ctrl is
when alu_add8 | alu_inc |
alu_add16 | alu_inx |
alu_adc =>
out_alu <= left + right + ("000000000000000" & carry_in);
when alu_sub8 | alu_dec |
alu_sub16 | alu_dex |
alu_sbc =>
out_alu <= left - right - ("000000000000000" & carry_in);
when alu_and =>
out_alu <= left and right; -- and/bit
when alu_ora =>
out_alu <= left or right; -- or
when alu_eor =>
out_alu <= left xor right; -- eor/xor
when alu_lsl16 | alu_asl8 | alu_rol8 =>
out_alu <= left(14 downto 0) & carry_in; -- rol8/asl8/lsl16
when alu_lsr16 | alu_lsr8 =>
out_alu <= carry_in & left(15 downto 1); -- lsr
when alu_ror8 =>
out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror
when alu_asr8 =>
out_alu <= "00000000" & left(7) & left(7 downto 1); -- asr
when alu_neg =>
out_alu <= right - left; -- neg (right=0)
when alu_com =>
out_alu <= not left;
when alu_clr | alu_ld8 | alu_ld16 =>
out_alu <= right; -- clr, ld
when alu_st8 | alu_st16 | alu_andcc | alu_orcc =>
out_alu <= left;
when alu_daa =>
out_alu <= left + ("00000000" & daa_reg);
when alu_sex =>
if left(7) = '0' then
out_alu <= "00000000" & left(7 downto 0);
else
out_alu <= "11111111" & left(7 downto 0);
end if;
when others =>
out_alu <= left; -- nop, tfr
end case;
 
--
-- carry bit
--
case alu_ctrl is
when alu_add8 | alu_adc =>
cc_out(CBIT) <= (left(7) and right(7)) or
(left(7) and not out_alu(7)) or
(right(7) and not out_alu(7));
when alu_sub8 | alu_sbc =>
cc_out(CBIT) <= ((not left(7)) and right(7)) or
((not left(7)) and out_alu(7)) or
(right(7) and out_alu(7));
when alu_add16 =>
cc_out(CBIT) <= (left(15) and right(15)) or
(left(15) and not out_alu(15)) or
(right(15) and not out_alu(15));
when alu_sub16 =>
cc_out(CBIT) <= ((not left(15)) and right(15)) or
((not left(15)) and out_alu(15)) or
(right(15) and out_alu(15));
when alu_ror8 | alu_lsr16 | alu_lsr8 | alu_asr8 =>
cc_out(CBIT) <= left(0);
when alu_rol8 | alu_asl8 =>
cc_out(CBIT) <= left(7);
when alu_lsl16 =>
cc_out(CBIT) <= left(15);
when alu_com =>
cc_out(CBIT) <= '1';
when alu_neg | alu_clr =>
cc_out(CBIT) <= out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0);
when alu_daa =>
if ( daa_reg(7 downto 4) = "0110" ) then
cc_out(CBIT) <= '1';
else
cc_out(CBIT) <= '0';
end if;
when alu_andcc =>
cc_out(CBIT) <= left(CBIT) and cc(CBIT);
when alu_orcc =>
cc_out(CBIT) <= left(CBIT) or cc(CBIT);
when alu_tfr =>
cc_out(CBIT) <= left(CBIT);
when others =>
cc_out(CBIT) <= cc(CBIT);
end case;
--
-- Zero flag
--
case alu_ctrl is
when alu_add8 | alu_sub8 |
alu_adc | alu_sbc |
alu_and | alu_ora | alu_eor |
alu_inc | alu_dec |
alu_neg | alu_com | alu_clr |
alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 |
alu_ld8 | alu_st8 | alu_sex =>
cc_out(ZBIT) <= not( out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) );
when alu_add16 | alu_sub16 |
alu_lsl16 | alu_lsr16 |
alu_inx | alu_dex |
alu_ld16 | alu_st16 =>
cc_out(ZBIT) <= not( out_alu(15) or out_alu(14) or out_alu(13) or out_alu(12) or
out_alu(11) or out_alu(10) or out_alu(9) or out_alu(8) or
out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) );
when alu_andcc =>
cc_out(ZBIT) <= left(ZBIT) and cc(ZBIT);
when alu_orcc =>
cc_out(ZBIT) <= left(ZBIT) or cc(ZBIT);
when alu_tfr =>
cc_out(ZBIT) <= left(ZBIT);
when others =>
cc_out(ZBIT) <= cc(ZBIT);
end case;
 
--
-- negative flag
--
case alu_ctrl is
when alu_add8 | alu_sub8 |
alu_adc | alu_sbc |
alu_and | alu_ora | alu_eor |
alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 |
alu_inc | alu_dec | alu_neg | alu_com | alu_clr |
alu_ld8 | alu_st8 | alu_sex =>
cc_out(NBIT) <= out_alu(7);
when alu_add16 | alu_sub16 |
alu_lsl16 | alu_lsr16 |
alu_ld16 | alu_st16 =>
cc_out(NBIT) <= out_alu(15);
when alu_andcc =>
cc_out(NBIT) <= left(NBIT) and cc(NBIT);
when alu_orcc =>
cc_out(NBIT) <= left(NBIT) or cc(NBIT);
when alu_tfr =>
cc_out(NBIT) <= left(NBIT);
when others =>
cc_out(NBIT) <= cc(NBIT);
end case;
 
--
-- Interrupt mask flag
--
case alu_ctrl is
when alu_andcc =>
cc_out(IBIT) <= left(IBIT) and cc(IBIT);
when alu_orcc =>
cc_out(IBIT) <= left(IBIT) or cc(IBIT);
when alu_seif | alu_sei =>
cc_out(IBIT) <= '1';
when alu_tfr =>
cc_out(IBIT) <= left(IBIT);
when others =>
cc_out(IBIT) <= cc(IBIT); -- interrupt mask
end case;
 
--
-- Half Carry flag
--
case alu_ctrl is
when alu_add8 | alu_adc =>
cc_out(HBIT) <= (left(3) and right(3)) or
(right(3) and not out_alu(3)) or
(left(3) and not out_alu(3));
when alu_andcc =>
cc_out(HBIT) <= left(HBIT) and cc(HBIT);
when alu_orcc =>
cc_out(HBIT) <= left(HBIT) or cc(HBIT);
when alu_tfr =>
cc_out(HBIT) <= left(HBIT);
when others =>
cc_out(HBIT) <= cc(HBIT);
end case;
 
--
-- Overflow flag
--
case alu_ctrl is
when alu_add8 | alu_adc =>
cc_out(VBIT) <= (left(7) and right(7) and (not out_alu(7))) or
((not left(7)) and (not right(7)) and out_alu(7));
when alu_sub8 | alu_sbc =>
cc_out(VBIT) <= (left(7) and (not right(7)) and (not out_alu(7))) or
((not left(7)) and right(7) and out_alu(7));
when alu_add16 =>
cc_out(VBIT) <= (left(15) and right(15) and (not out_alu(15))) or
((not left(15)) and (not right(15)) and out_alu(15));
when alu_sub16 =>
cc_out(VBIT) <= (left(15) and (not right(15)) and (not out_alu(15))) or
((not left(15)) and right(15) and out_alu(15));
when alu_inc =>
cc_out(VBIT) <= ((not left(7)) and left(6) and left(5) and left(4) and
left(3) and left(2) and left(1) and left(0));
when alu_dec | alu_neg =>
cc_out(VBIT) <= (left(7) and (not left(6)) and (not left(5)) and (not left(4)) and
(not left(3)) and (not left(2)) and (not left(1)) and (not left(0)));
when alu_asr8 =>
cc_out(VBIT) <= left(0) xor left(7);
when alu_lsr8 | alu_lsr16 =>
cc_out(VBIT) <= left(0);
when alu_ror8 =>
cc_out(VBIT) <= left(0) xor cc(CBIT);
when alu_lsl16 =>
cc_out(VBIT) <= left(15) xor left(14);
when alu_rol8 | alu_asl8 =>
cc_out(VBIT) <= left(7) xor left(6);
when alu_and | alu_ora | alu_eor | alu_com |
alu_st8 | alu_st16 | alu_ld8 | alu_ld16 | alu_sex =>
cc_out(VBIT) <= '0';
when alu_andcc =>
cc_out(VBIT) <= left(VBIT) and cc(VBIT);
when alu_orcc =>
cc_out(VBIT) <= left(VBIT) or cc(VBIT);
when alu_tfr =>
cc_out(VBIT) <= left(VBIT);
when others =>
cc_out(VBIT) <= cc(VBIT);
end case;
 
case alu_ctrl is
when alu_andcc =>
cc_out(FBIT) <= left(FBIT) and cc(FBIT);
when alu_orcc =>
cc_out(FBIT) <= left(FBIT) or cc(FBIT);
when alu_tfr =>
cc_out(FBIT) <= left(FBIT);
when alu_seif =>
cc_out(FBIT) <= '1';
when others =>
cc_out(FBIT) <= cc(FBIT);
end case;
 
case alu_ctrl is
when alu_andcc =>
cc_out(EBIT) <= left(EBIT) and cc(EBIT);
when alu_orcc =>
cc_out(EBIT) <= left(EBIT) or cc(EBIT);
when alu_tfr =>
cc_out(EBIT) <= left(EBIT);
when alu_see =>
cc_out(EBIT) <= '1';
when alu_cle =>
cc_out(EBIT) <= '0';
when others =>
cc_out(EBIT) <= cc(EBIT);
end case;
 
test_alu <= out_alu;
test_cc <= cc_out;
end process;
 
------------------------------------
--
-- state sequencer
--
------------------------------------
process( state, saved_state,
op_code, pre_code,
cc, ea, md, iv,
irq, firq, nmi_req, nmi_ack, halt )
variable cond_true : boolean; -- variable used to evaluate coditional branches
begin
case state is
when reset_state => -- released from reset
-- reset the registers
op_ctrl <= reset_op;
pre_ctrl <= reset_pre;
acca_ctrl <= reset_acca;
accb_ctrl <= reset_accb;
ix_ctrl <= reset_ix;
iy_ctrl <= reset_iy;
sp_ctrl <= reset_sp;
up_ctrl <= reset_up;
pc_ctrl <= reset_pc;
ea_ctrl <= reset_ea;
md_ctrl <= reset_md;
iv_ctrl <= reset_iv;
nmi_ctrl <= reset_nmi;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= reset_cc;
dp_ctrl <= reset_dp;
-- idle the bus
dout_ctrl <= md_lo_dout;
addr_ctrl <= idle_ad;
st_ctrl <= idle_st;
return_state <= vect_hi_state;
next_state <= vect_hi_state;
 
--
-- Jump via interrupt vector
-- iv holds interrupt type
-- fetch PC hi from vector location
--
when vect_hi_state =>
-- default the registers
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
md_ctrl <= latch_md;
ea_ctrl <= latch_ea;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
-- fetch pc low interrupt vector
pc_ctrl <= pull_hi_pc;
addr_ctrl <= int_hi_ad;
dout_ctrl <= pc_hi_dout;
st_ctrl <= idle_st;
return_state <= vect_lo_state;
next_state <= vect_lo_state;
--
-- jump via interrupt vector
-- iv holds vector type
-- fetch PC lo from vector location
--
when vect_lo_state =>
-- default the registers
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
md_ctrl <= latch_md;
ea_ctrl <= latch_ea;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
-- fetch the vector low byte
pc_ctrl <= pull_lo_pc;
addr_ctrl <= int_lo_ad;
dout_ctrl <= pc_lo_dout;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
--
-- Here to fetch an instruction
-- PC points to opcode
-- Should service interrupt requests at this point
-- either from the timer
-- or from the external input.
--
when fetch_state =>
-- fetch the op code
op_ctrl <= fetch_op;
pre_ctrl <= fetch_pre;
ea_ctrl <= reset_ea;
md_ctrl <= latch_md;
-- Fetch op code
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
dp_ctrl <= latch_dp;
--
case op_code(7 downto 6) is
when "10" => -- acca
case op_code(3 downto 0) is
when "0000" => -- suba
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub8;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0001" => -- cmpa
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0010" => -- sbca
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sbc;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0011" =>
case pre_code is
when "00010000" => -- page 2 -- cmpd
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "00010001" => -- page 3 -- cmpu
left_ctrl <= up_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- subd
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= load_hi_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when "0100" => -- anda
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0101" => -- bita
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0110" => -- ldaa
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld8;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0111" => -- staa
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1000" => -- eora
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_eor;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1001" => -- adca
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_adc;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1010" => -- oraa
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ora;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1011" => -- adda
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_add8;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1100" =>
case pre_code is
when "00010000" => -- page 2 -- cmpy
left_ctrl <= iy_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "00010001" => -- page 3 -- cmps
left_ctrl <= sp_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- cmpx
left_ctrl <= ix_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when "1101" => -- bsr / jsr
left_ctrl <= pc_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1110" => -- ldx
case pre_code is
when "00010000" => -- page 2 -- ldy
left_ctrl <= iy_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- ldx
left_ctrl <= ix_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when "1111" => -- stx
case pre_code is
when "00010000" => -- page 2 -- sty
left_ctrl <= iy_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- stx
left_ctrl <= ix_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when others =>
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when "11" => -- accb dual op
case op_code(3 downto 0) is
when "0000" => -- subb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0001" => -- cmpb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0010" => -- sbcb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sbc;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0011" => -- addd
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_add16;
cc_ctrl <= load_cc;
acca_ctrl <= load_hi_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0100" => -- andb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0101" => -- bitb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0110" => -- ldab
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0111" => -- stab
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1000" => -- eorb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_eor;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1001" => -- adcb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_adc;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1010" => -- orab
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ora;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1011" => -- addb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_add8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1100" => -- ldd
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= load_hi_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1101" => -- std
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1110" => -- ldu
case pre_code is
when "00010000" => -- page 2 -- lds
left_ctrl <= sp_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
when others => -- page 1 -- ldu
left_ctrl <= up_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
end case;
when "1111" =>
case pre_code is
when "00010000" => -- page 2 -- sts
left_ctrl <= sp_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- stu
left_ctrl <= up_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when others =>
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when others =>
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
if halt = '1' then
iv_ctrl <= reset_iv;
pc_ctrl <= latch_pc;
nmi_ctrl <= latch_nmi;
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= halt_state;
-- service non maskable interrupts
elsif (nmi_req = '1') and (nmi_ack = '0') then
iv_ctrl <= nmi_iv;
pc_ctrl <= latch_pc;
nmi_ctrl <= set_nmi;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_decr_state;
-- service maskable interrupts
else
--
-- nmi request is not cleared until nmi input goes low
--
if(nmi_req = '0') and (nmi_ack='1') then
nmi_ctrl <= reset_nmi;
else
nmi_ctrl <= latch_nmi;
end if;
--
-- IRQ is level sensitive
--
if (irq = '1') and (cc(IBIT) = '0') then
iv_ctrl <= irq_iv;
pc_ctrl <= latch_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_decr_state;
elsif (firq = '1') and (cc(FBIT) = '0') then
iv_ctrl <= firq_iv;
pc_ctrl <= latch_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_decr_state;
else
-- Advance the PC to fetch next instruction byte
iv_ctrl <= reset_iv; -- default to reset
pc_ctrl <= incr_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= decode1_state;
end if;
end if;
--
-- Here to decode instruction
-- and fetch next byte of intruction
-- whether it be necessary or not
--
when decode1_state =>
pre_ctrl <= latch_pre;
-- fetch first byte of address or immediate data
ea_ctrl <= fetch_first_ea;
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
nmi_ctrl <= latch_nmi;
dp_ctrl <= latch_dp;
case op_code(7 downto 4) is
--
-- direct single op (2 bytes)
-- 6809 => 6 cycles
-- cpu09 => 5 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 ea_hi=0 / ea_lo=(pc) / pc=pc+1
-- 3 md_lo=(ea) / pc=pc
-- 4 alu_left=md / md=alu_out / pc=pc
-- 5 (ea)=md_lo / pc=pc
--
-- Exception is JMP
-- 6809 => 3 cycles
-- cpu09 => 3 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 ea_hi=0 / ea_lo=(pc) / pc=pc+1
-- 3 pc=ea
--
when "0000" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- advance the PC
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= single_op_read_state;
 
-- acca / accb inherent instructions
when "0001" =>
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
case op_code(3 downto 0) is
--
-- Page2 pre byte
-- pre=(pc) / pc=pc+1
-- op=(pc) / pc=pc+1
--
when "0000" => -- page2
op_ctrl <= fetch_op;
acca_ctrl <= latch_acca;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- advance pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= decode2_state;
 
--
-- Page3 pre byte
-- pre=(pc) / pc=pc+1
-- op=(pc) / pc=pc+1
--
when "0001" => -- page3
op_ctrl <= fetch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- advance pc
pc_ctrl <= incr_pc;
-- Next state
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= decode3_state;
 
--
-- nop - No operation ( 1 byte )
-- 6809 => 2 cycles
-- cpu09 => 2 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 decode
--
when "0010" => -- nop
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
--
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- sync - halt execution until an interrupt is received
-- interrupt may be NMI, IRQ or FIRQ
-- program execution continues if the
-- interrupt is asserted for 3 clock cycles
-- note that registers are not pushed onto the stack
-- CPU09 => Interrupts need only be asserted for one clock cycle
--
when "0011" => -- sync
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
--
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= sync_state;
 
--
-- lbra -- long branch (3 bytes)
-- 6809 => 5 cycles
-- cpu09 => 4 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1
-- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1
-- 4 pc=pc+md
--
when "0110" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= lbranch_state;
 
--
-- lbsr - long branch to subroutine (3 bytes)
-- 6809 => 9 cycles
-- cpu09 => 6 cycles
-- 1 op=(pc) /pc=pc+1
-- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / sp=sp-1
-- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1
-- 4 (sp)= pc_lo / sp=sp-1 / pc=pc
-- 5 (sp)=pc_hi / pc=pc
-- 6 pc=pc+md
--
when "0111" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- pre decrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= lbranch_state;
 
when "1001" => -- daa
op_ctrl <= latch_op;
--
left_ctrl <= acca_left;
right_ctrl <= accb_right;
alu_ctrl <= alu_daa;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
sp_ctrl <= latch_sp;
-- idle pc
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
when "1010" => -- orcc
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
-- next state
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= orcc_state;
 
when "1100" => -- andcc
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= andcc_state;
 
when "1101" => -- sex
op_ctrl <= latch_op;
-- have sex
left_ctrl <= accb_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_sex;
cc_ctrl <= load_cc;
acca_ctrl <= load_hi_acca;
sp_ctrl <= latch_sp;
-- idle PC
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
when "1110" => -- exg
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= exg_state;
 
when "1111" => -- tfr
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
-- call transfer as a subroutine
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= tfr_state;
 
when others =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
--
-- Short branch conditional
-- 6809 => always 3 cycles
-- cpu09 => always = 3 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / test cc
-- 3 if cc tru pc=pc+md else pc=pc
--
when "0010" => -- branch conditional
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= sbranch_state;
--
-- Single byte stack operators
-- Do not advance PC
--
when "0011" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
--
-- lea - load effective address (2+ bytes)
-- 6809 => 4 cycles + addressing mode
-- cpu09 => 4 cycles + addressing mode
-- 1 op=(pc) / pc=pc+1
-- 2 md_lo=(pc) / pc=pc+1
-- 3 calculate ea
-- 4 ix/iy/sp/up = ea
--
case op_code(3 downto 0) is
when "0000" | -- leax
"0001" | -- leay
"0010" | -- leas
"0011" => -- leau
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= push_st;
return_state <= lea_state;
next_state <= indexed_state;
 
--
-- pshs - push registers onto sp stack
-- 6809 => 5 cycles + registers
-- cpu09 => 3 cycles + registers
-- 1 op=(pc) / pc=pc+1
-- 2 ea_lo=(pc) / pc=pc+1
-- 3 if ea(7 downto 0) != "00000000" then sp=sp-1
-- 4 if ea(7) = 1 (sp)=pcl, sp=sp-1
-- 5 if ea(7) = 1 (sp)=pch
-- if ea(6 downto 0) != "0000000" then sp=sp-1
-- 6 if ea(6) = 1 (sp)=upl, sp=sp-1
-- 7 if ea(6) = 1 (sp)=uph
-- if ea(5 downto 0) != "000000" then sp=sp-1
-- 8 if ea(5) = 1 (sp)=iyl, sp=sp-1
-- 9 if ea(5) = 1 (sp)=iyh
-- if ea(4 downto 0) != "00000" then sp=sp-1
-- 10 if ea(4) = 1 (sp)=ixl, sp=sp-1
-- 11 if ea(4) = 1 (sp)=ixh
-- if ea(3 downto 0) != "0000" then sp=sp-1
-- 12 if ea(3) = 1 (sp)=dp
-- if ea(2 downto 0) != "000" then sp=sp-1
-- 13 if ea(2) = 1 (sp)=accb
-- if ea(1 downto 0) != "00" then sp=sp-1
-- 14 if ea(1) = 1 (sp)=acca
-- if ea(0 downto 0) != "0" then sp=sp-1
-- 15 if ea(0) = 1 (sp)=cc
--
when "0100" => -- pshs
--
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pshs_state;
 
--
-- puls - pull registers of sp stack
-- 6809 => 5 cycles + registers
-- cpu09 => 3 cycles + registers
--
when "0101" => -- puls
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= puls_state;
 
--
-- pshu - push registers onto up stack
-- 6809 => 5 cycles + registers
-- cpu09 => 3 cycles + registers
--
when "0110" => -- pshu
-- idle UP
left_ctrl <= up_left;
right_ctrl <= one_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pshu_state;
 
--
-- pulu - pull registers of up stack
-- 6809 => 5 cycles + registers
-- cpu09 => 3 cycles + registers
--
when "0111" => -- pulu
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pulu_state;
 
--
-- rts - return from subroutine
-- 6809 => 5 cycles
-- cpu09 => 4 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 decode op
-- 3 pc_hi = (sp) / sp=sp+1
-- 4 pc_lo = (sp) / sp=sp+1
--
when "1001" =>
left_ctrl <= sp_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle PC
pc_ctrl <= latch_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= pull_return_hi_state;
 
--
-- abx - add accb to index register
-- 6809 => 3 cycles
-- cpu09 => 2 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 alu_left=ix / alu_right=accb / ix=alu_out / pc=pc
--
when "1010" => -- abx
left_ctrl <= ix_left;
right_ctrl <= accb_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ix_ctrl <= load_ix;
--
pc_ctrl <= latch_pc;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
when "1011" => -- rti
-- idle ALU
left_ctrl <= sp_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= rti_cc_state;
 
when "1100" => -- cwai
-- pre decrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= int_entire_state; -- set entire flag
next_state <= andcc_state;
 
when "1101" => -- mul
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= mul_state;
 
when "1111" => -- swi
-- predecrement SP
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= swi_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_entire_state;
 
when others =>
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle PC
pc_ctrl <= latch_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
--
-- Accumulator A Single operand
-- source = acca, dest = acca
-- Do not advance PC
-- Typically 2 cycles 1 bytes
-- 1 opcode fetch
-- 2 post byte fetch / instruction decode
-- Note that there is no post byte
-- so do not advance PC in decode cycle
-- Re-run opcode fetch cycle after decode
--
when "0100" => -- acca single op
op_ctrl <= latch_op;
accb_ctrl <= latch_accb;
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
left_ctrl <= acca_left;
case op_code(3 downto 0) is
when "0000" => -- neg
right_ctrl <= zero_right;
alu_ctrl <= alu_neg;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "0011" => -- com
right_ctrl <= zero_right;
alu_ctrl <= alu_com;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "0100" => -- lsr
right_ctrl <= zero_right;
alu_ctrl <= alu_lsr8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "0110" => -- ror
right_ctrl <= zero_right;
alu_ctrl <= alu_ror8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "0111" => -- asr
right_ctrl <= zero_right;
alu_ctrl <= alu_asr8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1000" => -- asl
right_ctrl <= zero_right;
alu_ctrl <= alu_asl8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1001" => -- rol
right_ctrl <= zero_right;
alu_ctrl <= alu_rol8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1010" => -- dec
right_ctrl <= one_right;
alu_ctrl <= alu_dec;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1011" => -- undefined
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
acca_ctrl <= latch_acca;
cc_ctrl <= latch_cc;
when "1100" => -- inc
right_ctrl <= one_right;
alu_ctrl <= alu_inc;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1101" => -- tst
right_ctrl <= zero_right;
alu_ctrl <= alu_st8;
acca_ctrl <= latch_acca;
cc_ctrl <= load_cc;
when "1110" => -- jmp
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
acca_ctrl <= latch_acca;
cc_ctrl <= latch_cc;
when "1111" => -- clr
right_ctrl <= zero_right;
alu_ctrl <= alu_ld8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when others =>
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
acca_ctrl <= latch_acca;
cc_ctrl <= latch_cc;
end case;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
--
-- Single Operand accb
-- source = accb, dest = accb
-- Typically 2 cycles 1 bytes
-- 1 opcode fetch
-- 2 post byte fetch / instruction decode
-- Note that there is no post byte
-- so do not advance PC in decode cycle
-- Re-run opcode fetch cycle after decode
--
when "0101" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
left_ctrl <= accb_left;
case op_code(3 downto 0) is
when "0000" => -- neg
right_ctrl <= zero_right;
alu_ctrl <= alu_neg;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "0011" => -- com
right_ctrl <= zero_right;
alu_ctrl <= alu_com;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "0100" => -- lsr
right_ctrl <= zero_right;
alu_ctrl <= alu_lsr8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "0110" => -- ror
right_ctrl <= zero_right;
alu_ctrl <= alu_ror8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "0111" => -- asr
right_ctrl <= zero_right;
alu_ctrl <= alu_asr8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1000" => -- asl
right_ctrl <= zero_right;
alu_ctrl <= alu_asl8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1001" => -- rol
right_ctrl <= zero_right;
alu_ctrl <= alu_rol8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1010" => -- dec
right_ctrl <= one_right;
alu_ctrl <= alu_dec;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1011" => -- undefined
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
when "1100" => -- inc
right_ctrl <= one_right;
alu_ctrl <= alu_inc;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1101" => -- tst
right_ctrl <= zero_right;
alu_ctrl <= alu_st8;
accb_ctrl <= latch_accb;
cc_ctrl <= load_cc;
when "1110" => -- jmp
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
when "1111" => -- clr
right_ctrl <= zero_right;
alu_ctrl <= alu_ld8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when others =>
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
end case;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
--
-- Single operand indexed
-- Two byte instruction so advance PC
-- EA should hold index offset
--
when "0110" => -- indexed single op
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
-- next state
case op_code(3 downto 0) is
when "1110" => -- jmp
return_state <= jmp_state;
when "1111" => -- clr
return_state <= single_op_exec_state;
when others =>
return_state <= single_op_read_state;
end case;
st_ctrl <= push_st;
next_state <= indexed_state;
--
-- Single operand extended addressing
-- three byte instruction so advance the PC
-- Low order EA holds high order address
--
when "0111" => -- extended single op
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment PC
pc_ctrl <= incr_pc;
--
case op_code(3 downto 0) is
when "1110" => -- jmp
return_state <= jmp_state;
when "1111" => -- clr
return_state <= single_op_exec_state;
when others =>
return_state <= single_op_read_state;
end case;
st_ctrl <= push_st;
next_state <= extended_state;
 
when "1000" => -- acca immediate
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- subd #
"1100" | -- cmpx #
"1110" => -- ldx #
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
 
--
-- bsr offset - Branch to subroutine (2 bytes)
-- 6809 => 7 cycles
-- cpu09 => 5 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 md_hi=sign(pc) / md_lo=(pc) / sp=sp-1 / pc=pc+1
-- 3 (sp)=pc_lo / sp=sp-1
-- 4 (sp)=pc_hi
-- 5 pc=pc+md
--
when "1101" => -- bsr
-- pre decrement SP
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
st_ctrl <= push_st;
return_state <= sbranch_state;
next_state <= push_return_lo_state;
 
when others =>
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1001" => -- acca direct
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- subd
"1100" | -- cmpx
"1110" => -- ldx
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when "0111" => -- sta direct
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write8_state;
 
when "1111" => -- stx direct
-- idle ALU
left_ctrl <= ix_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
--
-- jsr direct - Jump to subroutine in direct page (2 bytes)
-- 6809 => 7 cycles
-- cpu09 => 5 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 ea_hi=0 / ea_lo=(pc) / sp=sp-1 / pc=pc+1
-- 3 (sp)=pc_lo / sp=sp-1
-- 4 (sp)=pc_hi
-- 5 pc=ea
--
when "1101" => -- jsr direct
-- pre decrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
st_ctrl <= push_st;
return_state <= jmp_state;
next_state <= push_return_lo_state;
 
when others =>
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read8_state;
end case;
 
when "1010" => -- acca indexed
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- subd
"1100" | -- cmpx
"1110" => -- ldx
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when "0111" => -- staa ,x
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_write8_state;
next_state <= indexed_state;
 
when "1111" => -- stx ,x
-- idle ALU
left_ctrl <= ix_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when "1101" => -- jsr ,x
-- pre decrement SP
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
st_ctrl <= push_st;
return_state <= jsr_state;
next_state <= indexed_state;
 
when others =>
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_read8_state;
next_state <= indexed_state;
end case;
 
when "1011" => -- acca extended
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- subd
"1100" | -- cmpx
"1110" => -- ldx
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
 
when "0111" => -- staa >
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_write8_state;
next_state <= extended_state;
 
when "1111" => -- stx >
-- idle ALU
left_ctrl <= ix_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when "1101" => -- jsr >extended
-- pre decrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
st_ctrl <= push_st;
return_state <= jsr_state;
next_state <= extended_state;
 
when others =>
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_st8;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_read8_state;
next_state <= extended_state;
end case;
 
when "1100" => -- accb immediate
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
--
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- addd #
"1100" | -- ldd #
"1110" => -- ldu #
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
 
when "1101" => -- accb direct
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
case op_code(3 downto 0) is
when "0011" | -- addd
"1100" | -- ldd
"1110" => -- ldu
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when "0111" => -- stab direct
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write8_state;
 
when "1101" => -- std direct
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
when "1111" => -- stu direct
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read8_state;
end case;
 
when "1110" => -- accb indexed
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
case op_code(3 downto 0) is
when "0011" | -- addd
"1100" | -- ldd
"1110" => -- ldu
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when "0111" => -- stab indexed
st_ctrl <= push_st;
return_state <= dual_op_write8_state;
next_state <= indexed_state;
 
when "1101" => -- std indexed
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when "1111" => -- stu indexed
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when others =>
st_ctrl <= push_st;
return_state <= dual_op_read8_state;
next_state <= indexed_state;
end case;
 
when "1111" => -- accb extended
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
case op_code(3 downto 0) is
when "0011" | -- addd
"1100" | -- ldd
"1110" => -- ldu
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
 
when "0111" => -- stab extended
st_ctrl <= push_st;
return_state <= dual_op_write8_state;
next_state <= extended_state;
 
when "1101" => -- std extended
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when "1111" => -- stu extended
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when others =>
st_ctrl <= push_st;
return_state <= dual_op_read8_state;
next_state <= extended_state;
end case;
 
when others =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle the pc
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
--
-- Here to decode prefix 2 instruction
-- and fetch next byte of intruction
-- whether it be necessary or not
--
when decode2_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
-- fetch first byte of address or immediate data
ea_ctrl <= fetch_first_ea;
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
nmi_ctrl <= latch_nmi;
dp_ctrl <= latch_dp;
case op_code(7 downto 4) is
--
-- lbcc -- long branch conditional
-- 6809 => branch 6 cycles, no branch 5 cycles
-- cpu09 => always 5 cycles
-- 1 pre=(pc) / pc=pc+1
-- 2 op=(pc) / pc=pc+1
-- 3 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1
-- 4 md_hi=md_lo / md_lo=(pc) / pc=pc+1
-- 5 if cond pc=pc+md else pc=pc
--
when "0010" =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= lbranch_state;
 
--
-- Single byte stack operators
-- Do not advance PC
--
when "0011" =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
pc_ctrl <= latch_pc;
case op_code(3 downto 0) is
when "1111" => -- swi 2
-- predecrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
iv_ctrl <= swi2_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_entire_state;
 
when others =>
left_ctrl <= sp_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1000" => -- acca immediate
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- Idle the ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpd #
"1100" | -- cmpy #
"1110" => -- ldy #
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1001" => -- acca direct
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpd <
"1100" | -- cmpy <
"1110" => -- ldy <
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when "1111" => -- sty <
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1010" => -- acca indexed
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpd ,ind
"1100" | -- cmpy ,ind
"1110" => -- ldy ,ind
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when "1111" => -- sty ,ind
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1011" => -- acca extended
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpd <
"1100" | -- cmpy <
"1110" => -- ldy <
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
 
when "1111" => -- sty >
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1100" => -- accb immediate
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- undef #
"1100" | -- undef #
"1110" => -- lds #
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1101" => -- accb direct
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- undef <
"1100" | -- undef <
"1110" => -- lds <
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when "1111" => -- sts <
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1110" => -- accb indexed
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- undef ,ind
"1100" | -- undef ,ind
"1110" => -- lds ,ind
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when "1111" => -- sts ,ind
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1111" => -- accb extended
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- undef >
"1100" | -- undef >
"1110" => -- lds >
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
 
when "1111" => -- sts >
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when others =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle the pc
pc_ctrl <= latch_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
--
-- Here to decode instruction
-- and fetch next byte of intruction
-- whether it be necessary or not
--
when decode3_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
ea_ctrl <= fetch_first_ea;
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
nmi_ctrl <= latch_nmi;
dp_ctrl <= latch_dp;
case op_code(7 downto 4) is
--
-- Single byte stack operators
-- Do not advance PC
--
when "0011" =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
pc_ctrl <= latch_pc;
--
case op_code(3 downto 0) is
when "1111" => -- swi3
-- predecrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
iv_ctrl <= swi3_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_entire_state;
when others =>
left_ctrl <= sp_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1000" => -- acca immediate
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpu #
"1100" | -- cmps #
"1110" => -- undef #
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1001" => -- acca direct
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpu <
"1100" | -- cmps <
"1110" => -- undef <
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1010" => -- acca indexed
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpu ,X
"1100" | -- cmps ,X
"1110" => -- undef ,X
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1011" => -- acca extended
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpu >
"1100" | -- cmps >
"1110" => -- undef >
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when others =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle the pc
pc_ctrl <= latch_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
--
-- here if ea holds low byte
-- Direct
-- Extended
-- Indexed
-- read memory location
--
when single_op_read_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
-- idle ALU
left_ctrl <= ea_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- read memory into md
md_ctrl <= fetch_first_md;
addr_ctrl <= read_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= single_op_exec_state;
 
when single_op_exec_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
iv_ctrl <= latch_iv;
ea_ctrl <= latch_ea;
-- idle the bus
addr_ctrl <= idle_ad;
dout_ctrl <= md_lo_dout;
st_ctrl <= idle_st;
return_state <= fetch_state;
case op_code(3 downto 0) is
when "0000" => -- neg
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_neg;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "0011" => -- com
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_com;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "0100" => -- lsr
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_lsr8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "0110" => -- ror
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_ror8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "0111" => -- asr
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_asr8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1000" => -- asl
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_asl8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1001" => -- rol
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_rol8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1010" => -- dec
left_ctrl <= md_left;
right_ctrl <= one_right;
alu_ctrl <= alu_dec;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1011" => -- undefined
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
next_state <= fetch_state;
when "1100" => -- inc
left_ctrl <= md_left;
right_ctrl <= one_right;
alu_ctrl <= alu_inc;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1101" => -- tst
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_st8;
cc_ctrl <= load_cc;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
next_state <= fetch_state;
when "1110" => -- jmp
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= latch_cc;
md_ctrl <= latch_md;
pc_ctrl <= load_pc;
next_state <= fetch_state;
when "1111" => -- clr
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_ld8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when others =>
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
next_state <= fetch_state;
end case;
--
-- single operand 8 bit write
-- Write low 8 bits of ALU output
-- EA holds address
-- MD holds data
--
when single_op_write_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
ea_ctrl <= latch_ea;
-- idle the ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- write ALU low byte output
addr_ctrl <= write_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- here if ea holds address of low byte
-- read memory location
--
when dual_op_read8_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
left_ctrl <= ea_left;
-- Leave the ea alone
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- read first data byte from ea
md_ctrl <= fetch_first_md;
addr_ctrl <= read_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- Here to read a 16 bit value into MD
-- pointed to by the EA register
-- The first byte is read
-- and the EA is incremented
--
when dual_op_read16_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
-- increment the effective address
left_ctrl <= ea_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
ea_ctrl <= load_ea;
-- read the low byte of the 16 bit data
md_ctrl <= fetch_first_md;
addr_ctrl <= read_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_2_state;
 
--
-- here to read the second byte
-- pointed to by EA into MD
--
when dual_op_read16_2_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
-- idle the effective address
left_ctrl <= ea_left;
right_ctrl <= one_right;
alu_ctrl <= alu_nop;
ea_ctrl <= latch_ea;
-- read the low byte of the 16 bit data
md_ctrl <= fetch_next_md;
addr_ctrl <= read_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- 16 bit Write state
-- EA hold address of memory to write to
-- Advance the effective address in ALU
-- decode op_code to determine which
-- register to write
--
when dual_op_write16_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
-- increment the effective address
left_ctrl <= ea_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
-- write the ALU hi byte at ea
addr_ctrl <= write_ad;
if op_code(6) = '0' then
case op_code(3 downto 0) is
when "1111" => -- stx / sty
case pre_code is
when "00010000" => -- page 2 -- sty
dout_ctrl <= iy_hi_dout;
when others => -- page 1 -- stx
dout_ctrl <= ix_hi_dout;
end case;
when others =>
dout_ctrl <= md_hi_dout;
end case;
else
case op_code(3 downto 0) is
when "1101" => -- std
dout_ctrl <= acca_dout; -- acca is high byte of ACCD
when "1111" => -- stu / sts
case pre_code is
when "00010000" => -- page 2 -- sts
dout_ctrl <= sp_hi_dout;
when others => -- page 1 -- stu
dout_ctrl <= up_hi_dout;
end case;
when others =>
dout_ctrl <= md_hi_dout;
end case;
end if;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write8_state;
 
--
-- Dual operand 8 bit write
-- Write 8 bit accumulator
-- or low byte of 16 bit register
-- EA holds address
-- decode opcode to determine
-- which register to apply to the bus
-- Also set the condition codes here
--
when dual_op_write8_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
md_ctrl <= latch_md;
-- idle ALU
left_ctrl <= ea_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
if op_code(6) = '0' then -- '0' = acca line
case op_code(3 downto 0) is
when "0111" => -- sta
dout_ctrl <= acca_dout;
when "1111" => -- stx / sty
case pre_code is
when "00010000" => -- page 2 -- sty
dout_ctrl <= iy_lo_dout;
when others => -- page 1 -- stx
dout_ctrl <= ix_lo_dout;
end case;
when others =>
dout_ctrl <= md_lo_dout;
end case;
else -- '1' = accb line
case op_code(3 downto 0) is
when "0111" => -- stb
dout_ctrl <= accb_dout;
when "1101" => -- std
dout_ctrl <= accb_dout; -- accb is low byte of accd
when "1111" => -- stu / sts
case pre_code is
when "00010000" => -- page 2 -- sts
dout_ctrl <= sp_lo_dout;
when others => -- page 1 -- stu
dout_ctrl <= up_lo_dout;
end case;
when others =>
dout_ctrl <= md_lo_dout;
end case;
end if;
-- write ALU low byte output
addr_ctrl <= write_ad;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- 16 bit immediate addressing mode
--
when imm16_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
ea_ctrl <= latch_ea;
-- increment pc
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
pc_ctrl <= incr_pc;
-- fetch next immediate byte
md_ctrl <= fetch_next_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
-- return to caller
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
 
--
-- ea holds 8 bit index offet
-- calculate the effective memory address
-- using the alu
--
when indexed_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
dout_ctrl <= md_lo_dout;
--
-- decode indexing mode
--
if md(7) = '0' then
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= md_sign5_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
 
else
case md(3 downto 0) is
when "0000" => -- ,R+
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
left_ctrl <= sp_left;
end case;
--
right_ctrl <= zero_right;
alu_ctrl <= alu_st16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= postincr1_state;
 
when "0001" => -- ,R++
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_st16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= postincr2_state;
 
when "0010" => -- ,-R
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "01" =>
left_ctrl <= iy_left;
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "10" =>
left_ctrl <= up_left;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
end case;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
 
when "0011" => -- ,--R
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "01" =>
left_ctrl <= iy_left;
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "10" =>
left_ctrl <= up_left;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
end case;
right_ctrl <= two_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "0100" => -- ,R (zero offset)
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_st16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "0101" => -- ACCB,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= accb_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "0110" => -- ACCA,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= acca_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "0111" => -- undefined
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "1000" => -- offset8,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
md_ctrl <= fetch_first_md; -- pick up 8 bit offset
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= index8_state;
 
when "1001" => -- offset16,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
md_ctrl <= fetch_first_md; -- pick up first byte of 16 bit offset
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= index16_state;
 
when "1010" => -- undefined
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "1011" => -- ACCD,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= accd_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "1100" => -- offset8,PC
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- fetch 8 bit offset
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pcrel8_state;
 
when "1101" => -- offset16,PC
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- fetch offset
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pcrel16_state;
 
when "1110" => -- undefined
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when others =>
-- when "1111" => -- [,address]
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- advance PC to pick up address
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indexaddr_state;
end case;
end if;
 
-- load index register with ea plus one
when postincr1_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
ea_ctrl <= latch_ea;
--
left_ctrl <= ea_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
case md(6 downto 5) is
when "00" =>
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "01" =>
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "10" =>
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
when others =>
-- when "11" =>
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
end case;
addr_ctrl <= idle_ad;
dout_ctrl <= md_lo_dout;
-- return to previous state
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
-- load index register with ea plus two
when postincr2_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
ea_ctrl <= latch_ea;
-- increment register by two (address)
left_ctrl <= ea_left;
right_ctrl <= two_right;
alu_ctrl <= alu_add16;
case md(6 downto 5) is
when "00" =>
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "01" =>
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "10" =>
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
when others =>
-- when "11" =>
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
end case;
addr_ctrl <= idle_ad;
dout_ctrl <= md_lo_dout;
-- return to previous state
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
--
-- ea = index register + md (8 bit signed offset)
-- ea holds post byte
--
when index8_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
case ea(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
-- ea = index reg + md
right_ctrl <= md_sign8_right;
alu_ctrl <= alu_add16;
ea_ctrl <= load_ea;
-- idle bus
addr_ctrl <= idle_ad;
dout_ctrl <= md_lo_dout;
-- return to previous state
if ea(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
-- fetch low byte of 16 bit indexed offset
when index16_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
-- advance pc
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
pc_ctrl <= incr_pc;
-- fetch low byte
ea_ctrl <= latch_ea;
md_ctrl <= fetch_next_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= index16_2_state;
 
-- ea = index register + md (16 bit offset)
-- ea holds post byte
when index16_2_state =>
op_ctrl <= latch_op;
+ acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + case ea(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + -- ea = index reg + md + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + if ea(4) = '0' then + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect_state; + end if; + -- + -- pc relative with 8 bit signed offest + -- md holds signed offset + -- + when pcrel8_state => + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + -- ea = pc + signed md + left_ctrl <= pc_left; + right_ctrl <= md_sign8_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + if ea(4) = '0' then + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect_state; + end if; + + -- pc relative addressing with 16 bit offset + -- pick up the low byte of the offset in md + -- advance the pc + when pcrel16_state => + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- advance pc + left_ctrl <= pc_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + pc_ctrl <= incr_pc; + -- fetch low byte + ea_ctrl <= latch_ea; + md_ctrl <= fetch_next_md; + addr_ctrl <= fetch_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pcrel16_2_state; + + -- pc relative with16 bit signed offest + -- md holds signed offset + when pcrel16_2_state => + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- ea = pc + md + left_ctrl <= pc_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + md_ctrl <= latch_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + if ea(4) = '0' then + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect_state; + end if; + + -- indexed to absolute address + -- md holds address + -- ea hold indexing mode byte + when indexaddr2_state => + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- ea = md + left_ctrl <= pc_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + ea_ctrl <= load_ea; + md_ctrl <= latch_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + if ea(4) = '0' then + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect_state; + end if; + + -- indexed to address + -- pick up the low byte of the address + -- advance the pc + when indexaddr_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- advance pc + left_ctrl <= pc_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + pc_ctrl <= incr_pc; + -- fetch low byte + md_ctrl <= fetch_next_md; + addr_ctrl <= read_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indexaddr2_state; + -- + -- load md with high byte of indirect address + -- pointed to by ea + -- increment ea + -- + when indirect_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- increment ea + left_ctrl <= ea_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- fetch high byte + md_ctrl <= fetch_first_md; + addr_ctrl <= read_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect2_state; + -- + -- load md with low byte of indirect address + -- pointed to by ea + -- ea has previously been incremented + -- + when indirect2_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- idle ea + left_ctrl <= ea_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + ea_ctrl <= latch_ea; + -- fetch high byte + md_ctrl <= fetch_next_md; + addr_ctrl <= read_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect3_state; + -- + -- complete idirect addressing + -- by loading ea with md + -- + when indirect3_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- load ea with md + left_ctrl <= ea_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + ea_ctrl <= load_ea; + -- idle cycle + md_ctrl <= latch_md; + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + -- + -- ea holds the low byte of the absolute address + -- Move ea low byte into ea high byte + -- load new ea low byte to for absolute 16 bit address + -- advance the program counter + -- + when extended_state => -- fetch ea low byte + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + -- increment pc + left_ctrl <= pc_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + cc_ctrl <= latch_cc; + pc_ctrl <= incr_pc; + -- fetch next effective address bytes + ea_ctrl <= fetch_next_ea; + addr_ctrl <= fetch_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when lea_state => -- here on load effective address + op_ctrl <= latch_op; + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iv_ctrl <= latch_iv; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + ea_ctrl <= latch_ea; + pc_ctrl <= latch_pc; + -- load index register with effective address + left_ctrl <= pc_left; + right_ctrl <= ea_right; + alu_ctrl <= alu_ld16; + case op_code(3 downto 0) is + when "0000" => -- leax + ix_ctrl <= load_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + when "0001" => -- leay + ix_ctrl <= latch_ix; + iy_ctrl <= load_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + when "0010" => -- leas + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= load_sp; + when "0011" => -- leau + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= load_up; + sp_ctrl <= latch_sp; + when others => + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + end case; + -- idle the bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- jump to subroutine + -- (sp)=pc_lo + -- sp=sp-1 + -- call push_return_hi_state to save hi pc + -- return to jmp_state + -- + when jsr_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + ea_ctrl <= latch_ea; + pc_ctrl <= latch_pc; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc lo byte + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- call second half of push_return_state + st_ctrl <= push_st; + return_state <= jmp_state; + next_state <= push_return_hi_state; + + -- + -- Load pc with ea + -- (JMP) + -- + when jmp_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + ea_ctrl <= latch_ea; + -- load PC with effective address + left_ctrl <= pc_left; + right_ctrl <= ea_right; + alu_ctrl <= alu_ld16; + pc_ctrl <= load_pc; + -- idle the bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- long branch or branch to subroutine + -- pick up next md byte + -- md_hi = md_lo + -- md_lo = (pc) + -- pc=pc+1 + -- if a lbsr push return address + -- continue to sbranch_state + -- to evaluate conditional branches + -- + when lbranch_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- + left_ctrl <= pc_left; + right_ctrl <= ea_right; + alu_ctrl <= alu_ld16; + pc_ctrl <= incr_pc; + -- fetch the next byte into md_lo + md_ctrl <= fetch_next_md; + addr_ctrl <= fetch_ad; + dout_ctrl <= md_lo_dout; + -- if lbsr - push return address + -- then continue on to short branch + if op_code = "00010111" then + st_ctrl <= push_st; + return_state <= sbranch_state; + next_state <= push_return_lo_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= sbranch_state; + end if; + + -- + -- here to execute conditional branch + -- short conditional branch md = signed 8 bit offset + -- long branch md = 16 bit offset + -- + when sbranch_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- + left_ctrl <= pc_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + -- + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + if op_code(7 downto 4) = "0010" then -- conditional branch + case op_code(3 downto 0) is + when "0000" => -- bra + cond_true := (1 = 1); + when "0001" => -- brn + cond_true := (1 = 0); + when "0010" => -- bhi + cond_true := ((cc(CBIT) or cc(ZBIT)) = '0'); + when "0011" => -- bls + cond_true := ((cc(CBIT) or cc(ZBIT)) = '1'); + when "0100" => -- bcc/bhs + cond_true := (cc(CBIT) = '0'); + when "0101" => -- bcs/blo + cond_true := (cc(CBIT) = '1'); + when "0110" => -- bne + cond_true := (cc(ZBIT) = '0'); + when "0111" => -- beq + cond_true := (cc(ZBIT) = '1'); + when "1000" => -- bvc + cond_true := (cc(VBIT) = '0'); + when "1001" => -- bvs + cond_true := (cc(VBIT) = '1'); + when "1010" => -- bpl + cond_true := (cc(NBIT) = '0'); + when "1011" => -- bmi + cond_true := (cc(NBIT) = '1'); + when "1100" => -- bge + cond_true := ((cc(NBIT) xor cc(VBIT)) = '0'); + when "1101" => -- blt + cond_true := ((cc(NBIT) xor cc(VBIT)) = '1'); + when "1110" => -- bgt + cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0'); + when "1111" => -- ble + cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1'); + when others => + cond_true := (1 = 1); + end case; + else + cond_true := (1 = 1); -- lbra, lbsr, bsr + end if; + if cond_true then + pc_ctrl <= load_pc; + else + pc_ctrl <= latch_pc; + end if; + + -- + -- push return address onto the S stack + -- + -- (sp) = pc_lo + -- sp = sp - 1 + -- + when push_return_lo_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement the sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= latch_cc; + sp_ctrl <= load_sp; + -- write PC low + pc_ctrl <= latch_pc; + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= push_return_hi_state; + + -- + -- push program counter hi byte onto the stack + -- (sp) = pc_hi + -- sp = sp + -- return to originating state + -- + when push_return_hi_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle the SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= latch_cc; + sp_ctrl <= latch_sp; + -- write pc hi bytes + pc_ctrl <= latch_pc; + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when pull_return_hi_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment the sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + cc_ctrl <= latch_cc; + sp_ctrl <= load_sp; + -- read pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pull_return_lo_state; + + when pull_return_lo_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment the SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + cc_ctrl <= latch_cc; + sp_ctrl <= load_sp; + -- read pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when andcc_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- AND CC with md + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_andcc; + cc_ctrl <= load_cc; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when orcc_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- OR CC with md + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_orcc; + cc_ctrl <= load_cc; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when tfr_state => + -- default + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- select source register + case md(7 downto 4) is + when "0000" => + left_ctrl <= accd_left; + when "0001" => + left_ctrl <= ix_left; + when "0010" => + left_ctrl <= iy_left; + when "0011" => + left_ctrl <= up_left; + when "0100" => + left_ctrl <= sp_left; + when "0101" => + left_ctrl <= pc_left; + when "1000" => + left_ctrl <= acca_left; + when "1001" => + left_ctrl <= accb_left; + when "1010" => + left_ctrl <= cc_left; + when "1011" => + left_ctrl <= dp_left; + when others => + left_ctrl <= md_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + -- select destination register + case md(3 downto 0) is + when "0000" => -- accd + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0001" => -- ix + ix_ctrl <= load_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0010" => -- iy + ix_ctrl <= latch_ix; + iy_ctrl <= load_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0011" => -- up + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= load_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0100" => -- sp + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= load_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0101" => -- pc + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= load_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1000" => -- acca + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= load_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1001" => -- accb + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= load_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1010" => -- cc + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= load_cc; + dp_ctrl <= latch_dp; + when "1011" => --dp + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= load_dp; + when others => + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + end case; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when exg_state => + -- default + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + -- save destination register + case md(3 downto 0) is + when "0000" => + left_ctrl <= accd_left; + when "0001" => + left_ctrl <= ix_left; + when "0010" => + left_ctrl <= iy_left; + when "0011" => + left_ctrl <= up_left; + when "0100" => + left_ctrl <= sp_left; + when "0101" => + left_ctrl <= pc_left; + when "1000" => + left_ctrl <= acca_left; + when "1001" => + left_ctrl <= accb_left; + when "1010" => + left_ctrl <= cc_left; + when "1011" => + left_ctrl <= dp_left; + when others => + left_ctrl <= md_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + ea_ctrl <= load_ea; + + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- call tranfer microcode + st_ctrl <= push_st; + return_state <= exg1_state; + next_state <= tfr_state; + + when exg1_state => + -- default + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- restore destination + left_ctrl <= ea_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + -- save as source register + case md(7 downto 4) is + when "0000" => -- accd + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0001" => -- ix + ix_ctrl <= load_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0010" => -- iy + ix_ctrl <= latch_ix; + iy_ctrl <= load_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0011" => -- up + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= load_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0100" => -- sp + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= load_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0101" => -- pc + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= load_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1000" => -- acca + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= load_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1001" => -- accb + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= load_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1010" => -- cc + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= load_cc; + dp_ctrl <= latch_dp; + when "1011" => --dp + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= load_dp; + when others => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + end case; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + when mul_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- move acca to md + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_st16; + cc_ctrl <= latch_cc; + md_ctrl <= load_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mulea_state; + + when mulea_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + -- move accb to ea + left_ctrl <= accb_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_st16; + cc_ctrl <= latch_cc; + ea_ctrl <= load_ea; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= muld_state; + + when muld_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- clear accd + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_ld8; + cc_ctrl <= latch_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul0_state; + + when mul0_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 0 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(0) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul1_state; + + when mul1_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 1 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(1) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul2_state; + + when mul2_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 2 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(2) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul3_state; + + when mul3_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 3 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(3) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul4_state; + + when mul4_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + nmi_ctrl <= latch_nmi; + pre_ctrl <= latch_pre; + ea_ctrl <= latch_ea; + -- if bit 4 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(4) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul5_state; + + when mul5_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 5 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(5) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul6_state; + + when mul6_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 6 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(6) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul7_state; + + when mul7_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 7 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(7) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- Enter here on pushs + -- ea holds post byte + -- + when pshs_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp if any registers to be pushed + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(7 downto 0) = "00000000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(7) = '1' then + next_state <= pshs_pcl_state; + elsif ea(6) = '1' then + next_state <= pshs_upl_state; + elsif ea(5) = '1' then + next_state <= pshs_iyl_state; + elsif ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshs_pch_state; + + when pshs_pch_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(6 downto 0) = "0000000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write pc hi + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(6) = '1' then + next_state <= pshs_upl_state; + elsif ea(5) = '1' then + next_state <= pshs_iyl_state; + elsif ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + + when pshs_upl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshs_uph_state; + + when pshs_uph_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(5 downto 0) = "000000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write pc hi + addr_ctrl <= pushs_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(5) = '1' then + next_state <= pshs_iyl_state; + elsif ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write iy low + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshs_iyh_state; + + when pshs_iyh_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(4 downto 0) = "00000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write iy hi + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix low + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshs_ixh_state; + + when pshs_ixh_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(3 downto 0) = "0000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_dp_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(2 downto 0) = "000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write dp + addr_ctrl <= pushs_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_accb_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(1 downto 0) = "00" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write accb + addr_ctrl <= pushs_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_acca_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(0) = '1' then + sp_ctrl <= load_sp; + else + sp_ctrl <= latch_sp; + end if; + -- write acca + addr_ctrl <= pushs_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_cc_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_nop; + sp_ctrl <= latch_sp; + -- write cc + addr_ctrl <= pushs_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- enter here on PULS + -- ea hold register mask + -- + when puls_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= latch_sp; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(0) = '1' then + next_state <= puls_cc_state; + elsif ea(1) = '1' then + next_state <= puls_acca_state; + elsif ea(2) = '1' then + next_state <= puls_accb_state; + elsif ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_cc_state => + -- default registers + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- Increment SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read cc + cc_ctrl <= pull_cc; + addr_ctrl <= pulls_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(1) = '1' then + next_state <= puls_acca_state; + elsif ea(2) = '1' then + next_state <= puls_accb_state; + elsif ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_acca_state => + -- default registers + cc_ctrl <= latch_cc; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- Increment SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read acca + acca_ctrl <= pull_acca; + addr_ctrl <= pulls_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(2) = '1' then + next_state <= puls_accb_state; + elsif ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_accb_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- Increment SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read accb + accb_ctrl <= pull_accb; + addr_ctrl <= pulls_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_dp_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read dp + dp_ctrl <= pull_dp; + addr_ctrl <= pulls_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_ixh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull ix hi + ix_ctrl <= pull_hi_ix; + addr_ctrl <= pulls_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= puls_ixl_state; + + when puls_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read ix low + ix_ctrl <= pull_lo_ix; + addr_ctrl <= pulls_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_iyh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull iy hi + iy_ctrl <= pull_hi_iy; + addr_ctrl <= pulls_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= puls_iyl_state; + + when puls_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read iy low + iy_ctrl <= pull_lo_iy; + addr_ctrl <= pulls_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_uph_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull up hi + up_ctrl <= pull_hi_up; + addr_ctrl <= pulls_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= puls_upl_state; + + when puls_upl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read up low + up_ctrl <= pull_lo_up; + addr_ctrl <= pulls_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_pch_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= puls_pcl_state; + + when puls_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- Enter here on pshu + -- ea holds post byte + -- + when pshu_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp if any registers to be pushed + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(7 downto 0) = "00000000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(7) = '1' then + next_state <= pshu_pcl_state; + elsif ea(6) = '1' then + next_state <= pshu_spl_state; + elsif ea(5) = '1' then + next_state <= pshu_iyl_state; + elsif ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + -- + -- push PC onto U stack + -- + when pshu_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshu_pch_state; + + when pshu_pch_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(6 downto 0) = "0000000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write pc hi + addr_ctrl <= pushu_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(6) = '1' then + next_state <= pshu_spl_state; + elsif ea(5) = '1' then + next_state <= pshu_iyl_state; + elsif ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_spl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write pc low + addr_ctrl <= pushu_ad; + dout_ctrl <= sp_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshu_sph_state; + + when pshu_sph_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(5 downto 0) = "000000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write sp hi + addr_ctrl <= pushu_ad; + dout_ctrl <= sp_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(5) = '1' then + next_state <= pshu_iyl_state; + elsif ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write iy low + addr_ctrl <= pushu_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshu_iyh_state; + + when pshu_iyh_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(4 downto 0) = "00000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write iy hi + addr_ctrl <= pushu_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write ix low + addr_ctrl <= pushu_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshu_ixh_state; + + when pshu_ixh_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(3 downto 0) = "0000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write ix hi + addr_ctrl <= pushu_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_dp_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(2 downto 0) = "000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write accb + addr_ctrl <= pushu_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_accb_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(1 downto 0) = "00" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write accb + addr_ctrl <= pushu_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_acca_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(0) = '0' then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write acca + addr_ctrl <= pushu_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_cc_state => + -- default registers + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= up_left; + right_ctrl <= one_right; + cc_ctrl <= latch_cc; + alu_ctrl <= alu_nop; + up_ctrl <= latch_up; + -- write cc + addr_ctrl <= pushu_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- enter here on PULU + -- ea hold register mask + -- + when pulu_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle UP + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= latch_up; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(0) = '1' then + next_state <= pulu_cc_state; + elsif ea(1) = '1' then + next_state <= pulu_acca_state; + elsif ea(2) = '1' then + next_state <= pulu_accb_state; + elsif ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_cc_state => + -- default registers + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read cc + cc_ctrl <= pull_cc; + addr_ctrl <= pullu_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(1) = '1' then + next_state <= pulu_acca_state; + elsif ea(2) = '1' then + next_state <= pulu_accb_state; + elsif ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_acca_state => + -- default registers + cc_ctrl <= latch_cc; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read acca + acca_ctrl <= pull_acca; + addr_ctrl <= pullu_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(2) = '1' then + next_state <= pulu_accb_state; + elsif ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_accb_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read accb + accb_ctrl <= pull_accb; + addr_ctrl <= pullu_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_dp_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read dp + dp_ctrl <= pull_dp; + addr_ctrl <= pullu_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_ixh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- pull ix hi + ix_ctrl <= pull_hi_ix; + addr_ctrl <= pullu_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pulu_ixl_state; + + when pulu_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read ix low + ix_ctrl <= pull_lo_ix; + addr_ctrl <= pullu_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_iyh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- pull iy hi + iy_ctrl <= pull_hi_iy; + addr_ctrl <= pullu_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pulu_iyl_state; + + when pulu_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read iy low + iy_ctrl <= pull_lo_iy; + addr_ctrl <= pullu_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_sph_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- pull sp hi + sp_ctrl <= pull_hi_sp; + addr_ctrl <= pullu_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pulu_spl_state; + + when pulu_spl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read sp low + sp_ctrl <= pull_lo_sp; + addr_ctrl <= pullu_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_pch_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- pull pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pullu_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pulu_pcl_state; + + when pulu_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pullu_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + when rti_cc_state => + -- default registers + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read cc + cc_ctrl <= pull_cc; + addr_ctrl <= pulls_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + -- + -- CC is clocked at the end of this cycle + -- so this test tests the current state + -- of the condition codes, not the popped value + -- Mind you, the Entire flag is set before + -- the registers are pushed, so it should not matter + -- + if cc(EBIT) = '1' then + next_state <= rti_acca_state; + else + next_state <= rti_pch_state; + end if; + + when rti_acca_state => + -- default registers + cc_ctrl <= latch_cc; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read acca + acca_ctrl <= pull_acca; + addr_ctrl <= pulls_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_accb_state; + + when rti_accb_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read accb + accb_ctrl <= pull_accb; + addr_ctrl <= pulls_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_dp_state; + + when rti_dp_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read dp + dp_ctrl <= pull_dp; + addr_ctrl <= pulls_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_ixh_state; + + when rti_ixh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read ix hi + ix_ctrl <= pull_hi_ix; + addr_ctrl <= pulls_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_ixl_state; + + when rti_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read ix low + ix_ctrl <= pull_lo_ix; + addr_ctrl <= pulls_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_iyh_state; + + when rti_iyh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read iy hi + iy_ctrl <= pull_hi_iy; + addr_ctrl <= pulls_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_iyl_state; + + when rti_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read iy low + iy_ctrl <= pull_lo_iy; + addr_ctrl <= pulls_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_uph_state; + + + when rti_uph_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read up hi + up_ctrl <= pull_hi_up; + addr_ctrl <= pulls_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_upl_state; + + when rti_upl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + ix_ctrl <= latch_ix; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read up low + up_ctrl <= pull_lo_up; + addr_ctrl <= pulls_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_pch_state; + + when rti_pch_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_pcl_state; + + when rti_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- here on IRQ, NMI or FIRQ interrupt + -- pre decrement the sp + -- + when int_decr_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_entire_state; + + -- + -- set Entire Flag on SWI, SWI2, SWI3 and CWAI, IRQ and NMI + -- clear Entire Flag on FIRQ + -- before stacking all registers + -- + when int_entire_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- + left_ctrl <= sp_left; + right_ctrl <= zero_right; + if iv = FIRQ_VEC then + -- clear entire flag + alu_ctrl <= alu_cle; + else + -- set entire flag + alu_ctrl <= alu_see; + end if; + cc_ctrl <= load_cc; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_pcl_state; + + when int_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_pch_state; + + when int_pch_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc hi + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if cc(EBIT) = '1' then + next_state <= int_upl_state; + else + next_state <= int_cc_state; + end if; + + when int_upl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write up low + addr_ctrl <= pushs_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_uph_state; + + when int_uph_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_iyl_state; + + when int_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix low + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_iyh_state; + + when int_iyh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_ixl_state; + + when int_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix low + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_ixh_state; + + when int_ixh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_dp_state; + + when int_dp_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write accb + addr_ctrl <= pushs_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_accb_state; + + when int_accb_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write accb + addr_ctrl <= pushs_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_acca_state; + + when int_acca_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write acca + addr_ctrl <= pushs_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_cc_state; + + when int_cc_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + iv_ctrl <= latch_iv; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= sp_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + sp_ctrl <= latch_sp; + -- write cc + addr_ctrl <= pushs_ad; + dout_ctrl <= cc_dout; + nmi_ctrl <= latch_nmi; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + case iv is + when NMI_VEC => + next_state <= int_mask_state; + when SWI_VEC => + next_state <= int_mask_state; + when IRQ_VEC => + next_state <= int_mask_state; + when SWI2_VEC => + next_state <= vect_hi_state; + when FIRQ_VEC => + next_state <= int_mask_state; + when SWI3_VEC => + next_state <= vect_hi_state; + when others => + if op_code = "00111100" then -- CWAI + next_state <= int_cwai_state; + else + next_state <= rti_state; + end if; + end case; + + -- + -- wait here for an inteerupt + -- + when int_cwai_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + ea_ctrl <= latch_ea; + -- + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_nop; + cc_ctrl <= latch_cc; + sp_ctrl <= latch_sp; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + -- + if (nmi_req = '1') and (nmi_ack='0') then + iv_ctrl <= nmi_iv; + nmi_ctrl <= set_nmi; + next_state <= vect_hi_state; + else + -- + -- nmi request is not cleared until nmi input goes low + -- + if (nmi_req = '0') and (nmi_ack='1') then + nmi_ctrl <= reset_nmi; + else + nmi_ctrl <= latch_nmi; + end if; + -- + -- IRQ is level sensitive + -- + if (irq = '1') and (cc(IBIT) = '0') then + iv_ctrl <= irq_iv; + next_state <= int_mask_state; + elsif (firq = '1') and (cc(FBIT) = '0') then + -- + -- FIRQ is level sensitive + -- + iv_ctrl <= firq_iv; + next_state <= int_mask_state; + else + iv_ctrl <= latch_iv; + next_state <= int_cwai_state; + end if; + end if; + + when int_mask_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- Mask IRQ and FIRQ + left_ctrl <= sp_left; + right_ctrl <= zero_right; + -- + -- FIRQ can interrupt an IRQ service routine + -- + if iv = IRQ_VEC then + alu_ctrl <= alu_sei; + else + alu_ctrl <= alu_seif; + end if; + cc_ctrl <= load_cc; + sp_ctrl <= latch_sp; + -- idle bus cycle + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= vect_hi_state; + + when sync_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + ea_ctrl <= latch_ea; + -- + left_ctrl <= pc_left; + right_ctrl <= one_right; + alu_ctrl <= alu_nop; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + -- + if (nmi_req = '1') and (nmi_ack='0') then + iv_ctrl <= nmi_iv; + nmi_ctrl <= set_nmi; + next_state <= fetch_state; + else + -- + -- nmi request is not cleared until nmi input goes low + -- + if (nmi_req = '0') and (nmi_ack='1') then + nmi_ctrl <= reset_nmi; + else + nmi_ctrl <= latch_nmi; + end if; + -- + -- IRQ is level sensitive + -- + if (irq = '1') and (cc(IBIT) = '0') then + iv_ctrl <= irq_iv; + next_state <= fetch_state; + elsif (firq = '1') and (cc(FBIT) = '0') then + -- + -- FIRQ is level sensitive + -- + iv_ctrl <= firq_iv; + next_state <= fetch_state; + else + iv_ctrl <= latch_iv; + next_state <= sync_state; + end if; + end if; + + + when halt_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle ALU + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + sp_ctrl <= latch_sp; + -- idle bus cycle + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + if halt <= '1' then + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= halt_state; + else + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + end if; + + when others => -- halt on undefine states + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- do nothing in ALU + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + -- idle bus cycle + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= error_state; + end case; +end process; + +end CPU_ARCH; +
/tags/V10/rtl/vhdl/sbug.vhd
0,0 → 1,2096
--===========================================================================----
--
-- S Y N T H E Z I A B L E SBUG - Monitor ROM for System09.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- FILE NAME: sbug.vhd
-- ENTITY NAME: boot_rom
-- ARCHITECTURE NAME: basic
-- VERSION: 1.0
-- AUTHOR: John E. Kent
-- DATE: 15 December 2002
-- DEPENDENCIES: ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- DESCRIPTION: 2048 byte x 8 bit ROM Monitor program
-- for the System09 using slices
-- Sits at $F800
-- ACIA at $E004
-- DAT at $FFF0
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
entity boot_rom is
port (
addr : in std_logic_vector(10 downto 0);
data : out std_logic_vector(7 downto 0)
);
end;
 
architecture basic of boot_rom is
constant width : integer := 8;
constant memsize : integer := 2048;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
"11111000",
"00010100",
"11111000",
"01100001",
"11111101",
"11001111",
"11111101",
"11001001",
"11111101",
"11011111",
"11111101",
"11101110",
"11111101",
"10111101",
"11111101",
"10110001",
"11111101",
"10101101",
"11111011",
"10000001",
"10001110",
"11111110",
"01001111",
"00010000",
"10001110",
"11011111",
"11000000",
"11000110",
"00010000",
"10100110",
"10000000",
"10100111",
"10100000",
"01011010",
"00100110",
"11111001",
"10001110",
"11100000",
"00000100",
"10111111",
"11011111",
"11100000",
"00010111",
"00000010",
"01111010",
"11000110",
"00001100",
"01101111",
"11100010",
"01011010",
"00100110",
"11111011",
"00110000",
"10001100",
"11011101",
"10101111",
"01101010",
"10000110",
"11010000",
"10100111",
"11100100",
"00011111",
"01000011",
"00010111",
"00000101",
"10111110",
"10001110",
"11111110",
"01011111",
"00010111",
"00000101",
"01110101",
"10001110",
"11011111",
"11010000",
"01001111",
"11000110",
"00001101",
"01101101",
"10000101",
"00100111",
"00000011",
"10001011",
"00000100",
"00011001",
"01011010",
"00101010",
"11110110",
"00010111",
"00000101",
"00100110",
"10001110",
"11111110",
"01110100",
"00010111",
"00000101",
"01011100",
"10001110",
"11111110",
"01111011",
"00010111",
"00000101",
"01000110",
"00010111",
"00000101",
"01100101",
"10000100",
"01111111",
"10000001",
"00001101",
"00100111",
"11110001",
"00011111",
"10001001",
"10000001",
"00100000",
"00101100",
"00001001",
"10000110",
"01011110",
"00010111",
"00000101",
"01110011",
"00011111",
"10011000",
"10001011",
"01000000",
"00010111",
"00000101",
"01101100",
"00010111",
"00000101",
"01100111",
"11000001",
"01100000",
"00101111",
"00000010",
"11000000",
"00100000",
"10001110",
"11111110",
"00010011",
"11100001",
"10000000",
"00100111",
"00001111",
"00110000",
"00000010",
"10001100",
"11111110",
"01001111",
"00100110",
"11110101",
"10001110",
"11111110",
"01111101",
"00010111",
"00000101",
"00011110",
"00100000",
"11000000",
"10101101",
"10010100",
"00100000",
"10111100",
"00011111",
"00110100",
"00111011",
"10001110",
"11111110",
"10000011",
"00010111",
"00000100",
"11111111",
"00010111",
"00000100",
"00010001",
"00010111",
"00000100",
"00011001",
"00010111",
"00000100",
"00100001",
"00010111",
"00000100",
"00101001",
"00010111",
"00000100",
"00110001",
"10001110",
"11111110",
"10000011",
"00010111",
"00000100",
"11101010",
"00010111",
"00000100",
"00110011",
"00010111",
"00000100",
"00111010",
"00010111",
"00000100",
"01000001",
"00010110",
"00000100",
"01001000",
"00010111",
"00000100",
"00100111",
"00010111",
"00000101",
"00010111",
"00010111",
"00000100",
"01010111",
"00101001",
"00000010",
"10101111",
"01001010",
"00111001",
"00010111",
"00000011",
"11101101",
"00010111",
"00000101",
"00001001",
"00010111",
"00000100",
"01001001",
"00101001",
"00000010",
"10101111",
"01001000",
"00111001",
"00010111",
"00000100",
"00000000",
"00010111",
"00000100",
"11111011",
"00010111",
"00000100",
"00111011",
"00101001",
"00000010",
"10101111",
"01000110",
"00111001",
"00010111",
"00000011",
"11100111",
"00010111",
"00000100",
"11101101",
"00010111",
"00000100",
"00101101",
"00101001",
"00000010",
"10101111",
"01000100",
"00111001",
"00010111",
"00000011",
"11001110",
"00010111",
"00000100",
"11011111",
"00010111",
"00000100",
"00110000",
"00101001",
"00000010",
"10100111",
"01000011",
"00111001",
"00010111",
"00000011",
"11110101",
"00010111",
"00000100",
"11010001",
"00010111",
"00000100",
"00100010",
"00101001",
"00000010",
"10100111",
"01000010",
"00111001",
"00010111",
"00000011",
"11011101",
"00010111",
"00000100",
"11000011",
"00010111",
"00000100",
"00010100",
"00101001",
"00000010",
"10100111",
"01000001",
"00111001",
"00010111",
"00000011",
"11100011",
"00010111",
"00000100",
"10110101",
"00010111",
"00000100",
"00000110",
"00101001",
"00000100",
"10001010",
"10000000",
"10100111",
"11000100",
"00111001",
"00010111",
"00000011",
"11101011",
"00101001",
"00101101",
"00011111",
"00010010",
"10001110",
"11111110",
"10000011",
"00010111",
"00000100",
"01011111",
"00011111",
"00100001",
"00010111",
"00000100",
"00100110",
"00010111",
"00000100",
"10010110",
"10100110",
"10100100",
"00010111",
"00000100",
"00100110",
"00010111",
"00000100",
"10001110",
"00010111",
"00000011",
"11011111",
"00101000",
"00010001",
"10000001",
"00001000",
"00100111",
"11100001",
"10000001",
"00011000",
"00100111",
"11011101",
"10000001",
"01011110",
"00100111",
"00010111",
"10000001",
"00001101",
"00100110",
"00001111",
"00111001",
"10100111",
"10100100",
"10100001",
"10100100",
"00100111",
"00001000",
"00010111",
"00000100",
"01101111",
"10000110",
"00111111",
"00010111",
"00000100",
"01101100",
"00110001",
"00100001",
"00100000",
"11000010",
"00110001",
"00111111",
"00100000",
"10111110",
"00010111",
"00000011",
"00110101",
"00011111",
"00110010",
"10001110",
"11011111",
"11000000",
"00110000",
"00011111",
"00100000",
"00000101",
"00010111",
"00000011",
"10001011",
"00101001",
"00000110",
"00110100",
"00100000",
"10101100",
"11100001",
"00100100",
"00000001",
"00111001",
"00011111",
"00010000",
"11000011",
"00000000",
"00010000",
"11000100",
"11110000",
"00110100",
"00000110",
"00011111",
"00100000",
"11000100",
"11110000",
"00011111",
"00000001",
"10101100",
"11100100",
"00100111",
"00000101",
"00010111",
"00000100",
"00100111",
"00100111",
"00000011",
"00110010",
"01100010",
"00111001",
"00110100",
"00010000",
"10001110",
"11111110",
"10000011",
"00010111",
"00000011",
"11101000",
"10101110",
"11100100",
"00010111",
"00000011",
"10101111",
"11000110",
"00010000",
"10100110",
"10000000",
"00010111",
"00000011",
"10110000",
"00010111",
"00000100",
"00011000",
"01011010",
"00100110",
"11110101",
"00010111",
"00000100",
"00010000",
"10101110",
"11100001",
"11000110",
"00010000",
"10100110",
"10000000",
"10000001",
"00100000",
"00100101",
"00000100",
"10000001",
"01111110",
"00100011",
"00000010",
"10000110",
"00101110",
"00010111",
"00000100",
"00000001",
"01011010",
"00100110",
"11101110",
"00100000",
"10111111",
"01101111",
"11100010",
"01101111",
"11100010",
"00010111",
"00000011",
"00101011",
"00110100",
"00110000",
"00101001",
"01111011",
"10101100",
"01100010",
"00100101",
"01110111",
"00010111",
"00000011",
"11101000",
"00011111",
"00100000",
"11100011",
"01100100",
"00110100",
"00000100",
"10101011",
"11100000",
"10100111",
"10100000",
"00010000",
"10101100",
"11100100",
"00100101",
"11110001",
"00010000",
"10101110",
"01100010",
"00011111",
"00100000",
"11100011",
"01100100",
"00110100",
"00000010",
"11101011",
"11100000",
"11101000",
"10100000",
"00100111",
"00111100",
"10001110",
"11111110",
"10000011",
"00010111",
"00000011",
"10000101",
"00110000",
"00111111",
"00010111",
"00000011",
"01001100",
"00110100",
"00010000",
"10001110",
"11111110",
"10100001",
"00010111",
"00000011",
"10001000",
"00110101",
"00010000",
"00010111",
"00000001",
"01000111",
"00010111",
"00000011",
"01010000",
"00010111",
"00000011",
"00111001",
"10001110",
"11111110",
"10000111",
"00010111",
"00000011",
"01110111",
"10101110",
"01100100",
"00010111",
"00000011",
"00101110",
"10001110",
"11111110",
"10001111",
"00010111",
"00000011",
"01101100",
"00011111",
"10011000",
"10001110",
"11111110",
"10100110",
"00010111",
"00000011",
"00111110",
"00010111",
"00000011",
"10000011",
"00100110",
"00011010",
"00010000",
"10101100",
"11100100",
"00100101",
"10110011",
"10000110",
"00101011",
"00010111",
"00000011",
"10000110",
"00010111",
"00000011",
"01110100",
"00100110",
"00001011",
"00010000",
"10101110",
"01100010",
"01101100",
"01100101",
"00100110",
"10010000",
"01101100",
"01100100",
"00100110",
"10001100",
"00110010",
"01100110",
"00111001",
"00010111",
"00000010",
"10110001",
"00101001",
"00011110",
"10001100",
"11011111",
"11000000",
"00100100",
"00011010",
"00110100",
"00010000",
"10001110",
"11111111",
"11111111",
"10001101",
"01010101",
"00110101",
"00010000",
"00100111",
"00001111",
"10100110",
"10000100",
"10000001",
"00111111",
"00100111",
"00001001",
"10100111",
"10100000",
"10101111",
"10100100",
"10000110",
"00111111",
"10100111",
"10000100",
"00111001",
"00010111",
"00000011",
"01001010",
"10000110",
"00111111",
"00010110",
"00000011",
"01000111",
"00010000",
"10001110",
"11011111",
"11100011",
"11000110",
"00001000",
"10001101",
"00011000",
"01011010",
"00100110",
"11111011",
"00111001",
"00011111",
"01000011",
"10101110",
"01001010",
"00110000",
"00011111",
"10001101",
"00100110",
"00100111",
"00000100",
"10101111",
"01001010",
"10001101",
"00000110",
"00010111",
"11111101",
"11100100",
"00010110",
"11111101",
"10011010",
"10101110",
"00100001",
"10001100",
"11011111",
"11000000",
"00100100",
"00001010",
"10100110",
"10000100",
"10000001",
"00111111",
"00100110",
"00000100",
"10100110",
"10100100",
"10100111",
"10000100",
"10000110",
"11111111",
"10100111",
"10100000",
"10100111",
"10100000",
"10100111",
"10100000",
"00111001",
"00010000",
"10001110",
"11011111",
"11100011",
"11000110",
"00001000",
"10100110",
"10100000",
"10101100",
"10100001",
"00100111",
"00000100",
"01011010",
"00100110",
"11110111",
"00111001",
"00110001",
"00111101",
"00111001",
"10000110",
"11011110",
"10110111",
"11110000",
"00100100",
"10000110",
"11111111",
"10110111",
"11110000",
"00010100",
"10110111",
"11110000",
"00010000",
"10110111",
"11110000",
"00010101",
"10110111",
"11110000",
"00010110",
"01111101",
"11110000",
"00010000",
"10000110",
"11011000",
"10110111",
"11110000",
"00100000",
"00010111",
"00000000",
"10010111",
"10110110",
"11110000",
"00100000",
"00101011",
"11111011",
"10000110",
"00001001",
"10110111",
"11110000",
"00100000",
"00010111",
"00000000",
"10001010",
"10110110",
"11110000",
"00100000",
"10000101",
"00000001",
"00100110",
"11111001",
"10000101",
"00010000",
"00100110",
"11001010",
"10001110",
"11000000",
"00000000",
"10001101",
"01010010",
"10001010",
"00010000",
"10110111",
"11110000",
"01000000",
"00011111",
"00010000",
"01000011",
"01010011",
"11111101",
"11110000",
"00000000",
"10001110",
"11111110",
"11111111",
"10111111",
"11110000",
"00000010",
"10000110",
"11111111",
"10110111",
"11110000",
"00010000",
"10000110",
"11111110",
"10110111",
"11110000",
"00010100",
"10000110",
"00000001",
"10110111",
"11110000",
"00100010",
"10000110",
"10001100",
"10110111",
"11110000",
"00100000",
"10001101",
"01010010",
"01011111",
"00110100",
"00000100",
"01011111",
"01111101",
"11110000",
"00010000",
"00101010",
"00001010",
"01011010",
"00100110",
"11111000",
"00110101",
"00000100",
"01011010",
"00100110",
"11110000",
"00100000",
"10001010",
"00110101",
"00000100",
"10110110",
"11110000",
"00100000",
"10000101",
"00011100",
"00100111",
"00000001",
"00111001",
"11000110",
"11011110",
"11110111",
"11110000",
"00100100",
"10001110",
"11000000",
"00000000",
"10101111",
"01001010",
"00011111",
"00110100",
"00111011",
"00110100",
"00110110",
"10100110",
"01100010",
"01000100",
"01000100",
"01000100",
"01000100",
"00010000",
"10001110",
"11011111",
"11010000",
"11100110",
"10100110",
"01010100",
"01010100",
"01010100",
"01010100",
"11100111",
"11100100",
"11100110",
"10100110",
"01010011",
"01011000",
"01011000",
"01011000",
"01011000",
"10100110",
"01100010",
"10000100",
"00001111",
"10100111",
"01100010",
"11101010",
"01100010",
"11100111",
"01100010",
"00110101",
"00110110",
"00111001",
"00110100",
"00000100",
"11000110",
"00100000",
"01011010",
"00100110",
"11111101",
"00110101",
"00000100",
"00111001",
"01111101",
"11100000",
"00011000",
"01111111",
"11100000",
"00010100",
"11000110",
"00000011",
"10001110",
"00000000",
"00000000",
"00110000",
"00000001",
"10001100",
"00000000",
"00000000",
"00100110",
"11111001",
"01011010",
"00100110",
"11110110",
"10000110",
"00001111",
"10110111",
"11100000",
"00011000",
"10001101",
"00110111",
"11110110",
"11100000",
"00011000",
"11000101",
"00000001",
"00100110",
"11111001",
"10000110",
"00000001",
"10110111",
"11100000",
"00011010",
"10001101",
"00101001",
"10000110",
"10001100",
"10110111",
"11100000",
"00011000",
"10001101",
"00100010",
"10001110",
"11000000",
"00000000",
"00100000",
"00001001",
"11000101",
"00000010",
"00100111",
"00000101",
"10110110",
"11100000",
"00011011",
"10100111",
"10000000",
"11110110",
"11100000",
"00011000",
"11000101",
"00000001",
"00100110",
"11110000",
"11000101",
"00101100",
"00100111",
"00000001",
"00111001",
"10001110",
"11000000",
"00000000",
"10101111",
"01001010",
"00011111",
"00110100",
"00111011",
"11000110",
"00100000",
"01011010",
"00100110",
"11111101",
"00111001",
"10000110",
"00010001",
"00010111",
"00000001",
"11011101",
"01111111",
"11011111",
"11100010",
"00010111",
"00000001",
"10101101",
"10000001",
"01010011",
"00100110",
"11111001",
"00010111",
"00000001",
"10100110",
"10000001",
"00111001",
"00100111",
"00111101",
"10000001",
"00110001",
"00100110",
"11110001",
"00010111",
"00000001",
"00010111",
"00110100",
"00000010",
"00101001",
"00100110",
"00010111",
"00000000",
"11111111",
"00101001",
"00100001",
"00110100",
"00010000",
"11100110",
"11100000",
"11101011",
"11100000",
"11101011",
"11100100",
"01101010",
"11100100",
"01101010",
"11100100",
"00110100",
"00000100",
"00010111",
"00000000",
"11111101",
"00110101",
"00000100",
"00101001",
"00001100",
"00110100",
"00000010",
"11101011",
"11100000",
"01101010",
"11100100",
"00100111",
"00000101",
"10100111",
"10000000",
"00100000",
"11101011",
"01011111",
"00110101",
"00000010",
"11000001",
"11111111",
"00100111",
"10110010",
"10000110",
"00111111",
"00010111",
"00000001",
"10001111",
"01110011",
"11011111",
"11100010",
"10000110",
"00010011",
"00010110",
"00000001",
"10000111",
"01101111",
"11100010",
"00010111",
"00000000",
"10111000",
"00110100",
"00110000",
"00101001",
"01001010",
"10101100",
"01100010",
"00100101",
"01000110",
"00110000",
"00000001",
"10101111",
"11100100",
"10000110",
"00010010",
"00010111",
"00000001",
"01110001",
"11101100",
"11100100",
"10100011",
"01100010",
"00100111",
"00000110",
"00010000",
"10000011",
"00000000",
"00100000",
"00100011",
"00000010",
"11000110",
"00100000",
"11100111",
"01100100",
"10001110",
"11111110",
"11101011",
"00010111",
"00000001",
"00011010",
"11001011",
"00000011",
"00011111",
"10011000",
"00010111",
"00000000",
"11100111",
"10101110",
"01100010",
"00010111",
"00000000",
"11011010",
"11101011",
"01100010",
"11101011",
"01100011",
"11101011",
"10000100",
"10100110",
"10000000",
"00010111",
"00000000",
"11010111",
"01101010",
"01100100",
"00100110",
"11110101",
"01010011",
"00011111",
"10011000",
"00010111",
"00000000",
"11001101",
"10101111",
"01100010",
"10101100",
"11100100",
"00100110",
"11000011",
"10000110",
"00010100",
"00010111",
"00000001",
"00101111",
"00110010",
"01100101",
"00111001",
"10001110",
"11111110",
"10101110",
"00010111",
"00000000",
"11110101",
"00011111",
"00110001",
"00010110",
"00000000",
"10101100",
"10001110",
"11111110",
"10111010",
"00010111",
"00000000",
"11101010",
"10101110",
"01001000",
"00010110",
"00000000",
"10100001",
"10001110",
"11111110",
"11001100",
"00010111",
"00000000",
"11011111",
"10100110",
"01000011",
"00010110",
"00000000",
"10011110",
"10001110",
"11111110",
"11000110",
"00010111",
"00000000",
"11010100",
"10101110",
"01000100",
"00010110",
"00000000",
"10001011",
"10001110",
"11111110",
"11000000",
"00010111",
"00000000",
"11001001",
"10101110",
"01000110",
"00010110",
"00000000",
"10000000",
"10001110",
"11111110",
"10110100",
"00010111",
"00000000",
"10111110",
"10101110",
"01001010",
"00100000",
"01110110",
"10001110",
"11111110",
"11010010",
"00010111",
"00000000",
"10110100",
"10100110",
"01000001",
"00100000",
"01110100",
"10001110",
"11111110",
"11010111",
"00010111",
"00000000",
"10101010",
"10100110",
"01000010",
"00100000",
"01101010",
"10001110",
"11111110",
"11011100",
"00010111",
"00000000",
"10100000",
"10100110",
"11000100",
"10001110",
"11111110",
"11100011",
"00100000",
"01110011",
"10001101",
"00001001",
"00101001",
"01001110",
"00011111",
"00010010",
"10000110",
"00101101",
"00010111",
"00000000",
"10111111",
"10001101",
"00001111",
"00101001",
"01000011",
"00011111",
"00000001",
"10001101",
"00001001",
"00101001",
"00111101",
"00110100",
"00010000",
"10100111",
"01100001",
"00110101",
"00010000",
"00111001",
"10001101",
"00010001",
"00101001",
"00110010",
"01001000",
"01001000",
"01001000",
"01001000",
"00011111",
"10001001",
"10001101",
"00000111",
"00101001",
"00101000",
"00110100",
"00000100",
"10101011",
"11100000",
"00111001",
"10001101",
"01101111",
"10000001",
"00110000",
"00100101",
"00011101",
"10000001",
"00111001",
"00100010",
"00000011",
"10000000",
"00110000",
"00111001",
"10000001",
"01000001",
"00100101",
"00010010",
"10000001",
"01000110",
"00100010",
"00000011",
"10000000",
"00110111",
"00111001",
"10000001",
"01100001",
"00100101",
"00000111",
"10000001",
"01100110",
"00100010",
"00000011",
"10000000",
"01010111",
"00111001",
"00011010",
"00000010",
"00111001",
"00110100",
"00010000",
"00110101",
"00000010",
"10001101",
"00000010",
"00110101",
"00000010",
"00110100",
"00000010",
"01000100",
"01000100",
"01000100",
"01000100",
"10001101",
"00000100",
"00110101",
"00000010",
"10000100",
"00001111",
"10001011",
"00110000",
"10000001",
"00111001",
"00101111",
"00000010",
"10001011",
"00000111",
"00100000",
"01010111",
"00110100",
"00000010",
"11000110",
"00001000",
"10100110",
"10000000",
"01101000",
"11100100",
"00100101",
"00000010",
"10000110",
"00101101",
"10001101",
"01001001",
"10001101",
"01000101",
"01011010",
"00100110",
"11110001",
"00110101",
"00000010",
"00111001",
"10001101",
"00000010",
"00100000",
"00001100",
"00110100",
"00010000",
"10001110",
"11111110",
"01110101",
"10001101",
"00000101",
"00110101",
"00010000",
"00111001",
"10001101",
"00110001",
"10100110",
"10000000",
"10000001",
"00000100",
"00100110",
"11111000",
"00111001",
"01111101",
"11011111",
"11100010",
"00100111",
"00000110",
"10001101",
"00000100",
"10000100",
"01111111",
"00100000",
"00011111",
"00110100",
"00010000",
"10111110",
"11011111",
"11100000",
"10100110",
"10000100",
"10000101",
"00000001",
"00100111",
"11111010",
"10100110",
"00000001",
"00110101",
"00010000",
"00111001",
"00110100",
"00000010",
"10100110",
"10011111",
"11011111",
"11100000",
"10000101",
"00000001",
"00110101",
"00000010",
"00111001",
"10001101",
"00000000",
"10000110",
"00100000",
"00110100",
"00010010",
"10111110",
"11011111",
"11100000",
"10100110",
"10000100",
"10000101",
"00000010",
"00100111",
"11111010",
"00110101",
"00000010",
"10100111",
"00000001",
"00110101",
"00010000",
"00111001",
"10111110",
"11011111",
"11100000",
"10000110",
"00000011",
"10100111",
"10000100",
"10000110",
"00010001",
"10100111",
"10000100",
"01101101",
"00000001",
"10000110",
"11111111",
"10110111",
"11011111",
"11100010",
"00111001",
"00000001",
"11111001",
"00100011",
"00000010",
"11111001",
"00010101",
"00000011",
"11111001",
"00110001",
"00000100",
"11111001",
"00000111",
"00010000",
"11111000",
"11001111",
"00010101",
"11111000",
"11011101",
"00011000",
"11111000",
"11111001",
"00011001",
"11111000",
"11101011",
"01000010",
"11111010",
"01111011",
"01000100",
"11111010",
"11110100",
"01000101",
"11111001",
"10010110",
"01000111",
"11111000",
"10100101",
"01001100",
"11111100",
"00001100",
"01001101",
"11111001",
"01000001",
"01010000",
"11111100",
"01100111",
"01010001",
"11111001",
"11110010",
"01010010",
"11111000",
"10101000",
"01010011",
"11111001",
"10001010",
"01010101",
"11111011",
"10110011",
"01011000",
"11111010",
"10100111",
"11111010",
"10110011",
"11111000",
"10100111",
"11111000",
"10100111",
"11111000",
"10100111",
"11111000",
"10100111",
"11111010",
"10110011",
"11111111",
"11111111",
"11111111",
"11111111",
"00000000",
"00000000",
"00000000",
"00001101",
"00001010",
"00000000",
"00000000",
"00000000",
"01010011",
"00101101",
"01000010",
"01010101",
"01000111",
"00100000",
"00110001",
"00101110",
"00111000",
"00100000",
"00101101",
"00100000",
"00000100",
"01001011",
"00001101",
"00001010",
"00000000",
"00000000",
"00000000",
"00000100",
"00111110",
"00000100",
"01010111",
"01001000",
"01000001",
"01010100",
"00111111",
"00000100",
"00100000",
"00101101",
"00100000",
"00000100",
"00101100",
"00100000",
"01010000",
"01000001",
"01010011",
"01010011",
"00100000",
"00000100",
"00101100",
"00100000",
"01000010",
"01001001",
"01010100",
"01010011",
"00100000",
"01001001",
"01001110",
"00100000",
"01000101",
"01010010",
"01010010",
"01001111",
"01010010",
"00111010",
"00100000",
"00000100",
"00100000",
"00111101",
"00111110",
"00100000",
"00000100",
"00110111",
"00110110",
"00110101",
"00110100",
"00110011",
"00110010",
"00110001",
"00110000",
"00100000",
"00100000",
"01010011",
"01010000",
"00111101",
"00000100",
"00100000",
"00100000",
"01010000",
"01000011",
"00111101",
"00000100",
"00100000",
"00100000",
"01010101",
"01010011",
"00111101",
"00000100",
"00100000",
"00100000",
"01001001",
"01011001",
"00111101",
"00000100",
"00100000",
"00100000",
"01001001",
"01011000",
"00111101",
"00000100",
"00100000",
"00100000",
"01000100",
"01010000",
"00111101",
"00000100",
"00100000",
"00100000",
"01000001",
"00111101",
"00000100",
"00100000",
"00100000",
"01000010",
"00111101",
"00000100",
"00100000",
"00100000",
"01000011",
"01000011",
"00111010",
"00100000",
"00000100",
"01000101",
"01000110",
"01001000",
"01001001",
"01001110",
"01011010",
"01010110",
"01000011",
"01010011",
"00110001",
"00000100",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"00000000",
"00000000",
"00000000",
"10001110",
"11111111",
"11110000",
"10000110",
"00001111",
"10100111",
"10000000",
"01001010",
"00100110",
"11111011",
"10000110",
"11110000",
"10100111",
"10000100",
"10001110",
"11010000",
"10100000",
"00010000",
"10001110",
"01010101",
"10101010",
"11101110",
"10000100",
"00010000",
"10101111",
"10000100",
"00010000",
"10101100",
"10000100",
"00100111",
"00001011",
"00110000",
"10001001",
"11110000",
"00000000",
"10001100",
"11110000",
"10100000",
"00100110",
"11101101",
"00100000",
"11010110",
"11101111",
"10000100",
"00011111",
"00010000",
"01000011",
"01000100",
"01000100",
"01000100",
"01000100",
"10110111",
"11111111",
"11111101",
"00010000",
"11001110",
"11011111",
"11000000",
"00010000",
"10001110",
"11011111",
"11010000",
"10100111",
"00101101",
"01101111",
"00101110",
"10000110",
"11110000",
"10100111",
"00101111",
"10000110",
"00001100",
"01101111",
"10100110",
"01001010",
"00101010",
"11111011",
"00110000",
"10001001",
"11110000",
"00000000",
"10001100",
"11110000",
"10100000",
"00100111",
"00100010",
"11101110",
"10000100",
"00010000",
"10001110",
"01010101",
"10101010",
"00010000",
"10101111",
"10000100",
"00010000",
"10101100",
"10000100",
"00100110",
"11101001",
"11101111",
"10000100",
"00010000",
"10001110",
"11011111",
"11010000",
"00011111",
"00010000",
"01000100",
"01000100",
"01000100",
"01000100",
"00011111",
"10001001",
"10001000",
"00001111",
"10100111",
"10100101",
"00100000",
"11010101",
"10000110",
"11110001",
"00010000",
"10001110",
"11011111",
"11010000",
"10100111",
"00101110",
"10000110",
"00001100",
"11100110",
"10100110",
"00100110",
"00000101",
"01001010",
"00101010",
"11111001",
"00100000",
"00010100",
"01101111",
"10100110",
"11100111",
"00101100",
"01001111",
"00011111",
"00100001",
"11100110",
"10100110",
"00100111",
"00000100",
"01101111",
"10100110",
"11100111",
"10000000",
"01001100",
"10000001",
"00001100",
"00101101",
"11110011",
"10001110",
"11111111",
"11110000",
"11000110",
"00010000",
"10100110",
"10100000",
"10100111",
"10000000",
"01011010",
"00100110",
"11111001",
"01010011",
"11110111",
"11011111",
"11100010",
"00010110",
"11111000",
"01100010",
"01101110",
"10011111",
"11011111",
"11000000",
"01101110",
"10011111",
"11011111",
"11000100",
"01101110",
"10011111",
"11011111",
"11000110",
"01101110",
"10011111",
"11011111",
"11001000",
"01101110",
"10011111",
"11011111",
"11001010",
"00011111",
"01000011",
"10101110",
"01001010",
"11100110",
"10000000",
"10101111",
"01001010",
"01001111",
"01011000",
"01001001",
"10111110",
"11011111",
"11001100",
"10001100",
"11111111",
"11111111",
"00100111",
"00001111",
"00110000",
"10001011",
"10111100",
"11011111",
"11001110",
"00100010",
"00001000",
"00110100",
"00010000",
"11101100",
"11000100",
"10101110",
"01000100",
"01101110",
"11110001",
"00110111",
"00011111",
"11101110",
"01000010",
"01101110",
"10011111",
"11011111",
"11000010",
"11111111",
"10110010",
"11111111",
"11000110",
"11111111",
"10110110",
"11111111",
"10111010",
"11111111",
"10111110",
"11111111",
"11000010",
"11111111",
"10110010",
"11111111",
"00000000"
);
begin
data <= rom_data(conv_integer(addr));
end;
 
/tags/V10/rtl/vhdl/testbench1.vhd
0,0 → 1,180
--===========================================================================----
--
-- T E S T B E N C H tesetbench1 - CPU09 Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : Testbench1.vhd
--
-- Purpose : cpu09 Microprocessor Test Bench 1
-- Contains ROM to print out "Hello World"
-- on a none existant Uart
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu09 (cpu09.vhd) CPU core
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 12st April 2003 - John Kent
-- First version
--
-- Version 1.0- 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
--===========================================================================--
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
-- library work;
-- use work.UART_Def.all;
-- use work.typedefines.all;
-- use work.memory.all;
 
entity my_testbench is
end my_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
signal cpu_irq : Std_Logic;
signal cpu_nmi : std_logic;
signal cpu_firq : Std_Logic;
 
 
constant width : integer := 8;
constant memsize : integer := 64;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
"10001110", "11111000", "00101000", -- F800 - 8E F828 RESET LDX #MSG
"10000110", "00010001", -- F803 - 86 11 LDA #$11
"10110111", "11100000", "00000100", -- F805 - B7 E004 STA UARTCR
"10110110", "11100000", "00000100", -- F808 - B6 E004 POLL1 LDA UARTCR
"10000101", "00000010", -- F80B - 85 02 BITA #TXBE
"00100110", "11111001", -- F80D - 26 F9 BNE POLL1
"10100110", "10000000", -- F80F - A6 80 LDA ,X+
"00100111", "00000110", -- F811 - 27 06 BEQ POLL2
"00010010", -- F813 - 12 NOP
"10110111", "11100000", "00000101", -- F814 - B7 E005 STA UARTDR
"00100110", "11101111", -- F817 - 26 EF BNE POLL1
"10110110", "11100000", "00000100", -- F819 - B6 E004 POLL2 LDA UARTCR
"10000101", "00000001", -- F81C - 85 01 BITA #RXBF
"00100111", "11111001", -- F81E - 27 F9 BEQ POLL2
"10110110", "11100000", "00000101", -- F820 - B6 E005 LDA UARTDR
"01111110", "11111000", "00000000", -- F823 - 7E F800 JMP RESET
"00000000", "00000000", -- F826 - 00 00 fcb $00,$00
"01001000", "01100101", "01101100", -- F828 - 48 65 6c MSG FCC "Hel"
"01101100", "01101111", "00100000", -- F82B - 6c 6f 20 FCC "lo "
"01010111", "01101111", "01110010", -- F82E - 57 6f 72 FCC "Wor"
"01101100", "01100100", -- F831 - 6c 64 FCC "ld"
"00001010", "00001101", "00000000", -- F833 - 0a 0d 00 FCB LF,CR,NULL
"00000000", "00000000", -- F836 - 00 00 fcb null,null
"11111000", "00000000", -- F838 - F8 00 fdb $F800 ; Timer irq
"11111000", "00000000", -- F83A - F8 00 fdb $F800 ; Ext IRQ
"11111000", "00000000", -- F83C - F8 00 fcb $F800 ; SWI
"11111000", "00000000" -- F83E - F8 00 fdb $F800 ; Reset
);
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component cpu09;
 
 
begin
cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => '0',
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr )
begin
cpu_data_in <= rom_data(conv_integer(cpu_addr(5 downto 0)));
end process;
 
end behavior; --===================== End of architecture =======================--
 
/tags/V10/rtl/vhdl/testbench2.vhd
0,0 → 1,304
--===========================================================================----
--
-- T E S T B E N C H tesetbench2 - CPU09 Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : Testbench2.vhd
--
-- Purpose : cpu09 Microprocessor Test Bench 2
-- Contains ROM to read sector from
-- a none existant Compact Flash module
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu09 (cpu09.vhd) CPU core
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 12st April 2003 - John Kent
-- First version
--
-- Version 1.0- 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
--===========================================================================--
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity my_testbench is
end my_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
 
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
signal cpu_irq : Std_Logic;
signal cpu_nmi : Std_Logic;
signal cpu_firq : std_logic;
 
constant width : integer := 8;
constant memsize : integer := 128;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
"00010000", -- $F800 LDS #$F878 (Point to dummy return to test stack)
"11001110",
"11111000",
"01111000",
"10000110", -- $F804 LDA #$E0 *** START
"11100000",
"00011111", -- $F806 TFR A,DPR
"10001011",
---------------------------
-- "10001101", -- $F80E BSR WAITRDY $F86A
-- "01100000",
"10001101", -- $F808 BSR $F874 -- test sub call
"01101010",
---------------------------
"10000110", -- $F80A LDA #$E0
"11100000",
"10010111", -- $F80C STA <$E016
"00010110",
---------------------------
-- "10001101", -- $F80E BSR WAITRDY $F86A
-- "01011010",
"10001101", -- $F80E BSR $F810
"00000000",
--------------------------
"10000110", -- $F810 LDA #$01
"00000001",
"10010111", -- $F812 STA <$E011
"00010001",
"10000110", -- $F814 LDA #$EF
"11101111",
"10010111", -- $F816 STA <$E017
"00010111",
--------------------------
-- "10001101", -- $F818 BSR WAITRDY $F86A
-- "01010000",
"10001101", -- $F818 BSR $F816
"00000000",
--------------------------
"00010000", -- $F81A LDY #$F800
"10001110",
"11111000",
"00000000",
"11000110", -- $F81E LDB #$7C
"01111100",
"10000110", -- $F820 LDA #$01 *** RDLP1
"00000001",
"10010111", -- $F822 STA <$E012
"00010010",
"11010111", -- $F824 STB <$E013
"00010011",
"10000110", -- $F826 LDA #$F4
"11110100",
"10010111", -- $F828 STA <$E014
"00010100",
"01001111", -- $F82A CLRA
"10010111", -- $F82B STA <$E015
"00010101",
"10001110", -- $F82D LDX #512
"00000010",
"00000000",
"10000110", -- $F830 LDA #$20
"00100000",
"10010111", -- $F832 STA <$E017
"00010111",
--------------------------
-- "10001101", -- $F834 BSR WAITRDY $F86A
-- "00110100",
"10001101", -- $F834 BSR *
"00000000",
--------------------------
"10010110", -- $F836 LDA <$E017 *** WAITDRQ
"00010111",
"10000101", -- $F838 BITA #$08
"00001000",
"00100111", -- $F83A BEQ WAITDRQ
"11111010",
"10010110", -- $F83C LDA <$E010
"00010000",
"10100111", -- $F83E STA ,Y+
"10100000",
"00110000", -- $F840 LEAX -1,X
"00011111",
"10001100", -- $F842 CMPX #$0000
"00000000",
"00000000",
"00100110", -- $F845 BNE RDLP2
"11110011",
--------------------------
-- "10001101", -- $F847 BSR WAITRDY $F86A
-- "00100001",
"10001101", -- $F847 BSR $F841
"00000000",
--------------------------
"01011100", -- $F849 INCB
"11000001", -- $F84A CMPB #$80
"10000000",
"00100110", -- $F84C BNE RDLP1
"11010110",
"10001110", -- $F84E LDX #$FF97
"11111111",
"10010111",
"00010000", -- $F851 LDY #$F000
"10001110",
"11110000",
"00000000",
"11000110", -- $F855 LDB #$61
"01100001",
"10100110", -- $F857 LDA 0,X+ *** MOVELP
"10000000",
"10100111", -- $F859 STA 0,Y+
"10100000",
"01011010", -- $F85B DECB
----------------------------
-- "00100110", -- $F85C BNE MOVELP
-- "11111001",
"00100110", --$F85C BNE $F861
"00000011",
----------------------------
"01111110", -- $F85E JMP $F000
"11110000",
"00000000",
"00001111", -- $F861 CLR <$E030
"00110000",
"01001111", -- $F863 CLRA
"00011111", -- $F864 TFR A,DPR
"10001011",
"01101110", -- $F866 JMP [$FFFE]
"10011111",
"11111111",
"11111110",
--
-- Wait for Ready
--
"10010110", -- $F86A LDA <$E017 *** WAITRDY
"00010111",
"00101011", -- $F86C BMI WAITRDY
"11111100",
"10010110", -- $F86E LDA <$E017
"00010111",
"10000101", -- $F870 BITA #$40
"01000000",
"00100111", -- $F872 BNE WAITRQY
"11110110",
"00111001", -- $F874 RTS
"00010010", -- $F875 NOP
"11111000", -- $F876 FDB $F80A -- dummy sub return
"00001010",
"11111000", -- $F878 FDB $F800
"00000000",
"11111000", -- $F87A FDB $F800
"00000000",
"11111000", -- $F87C FDB $F800
"00000000",
"11111000", -- $F87E FDB $F800
"00000000"
);
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component cpu09;
 
 
begin
cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => '0',
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr )
begin
cpu_data_in <= rom_data(conv_integer(cpu_addr(6 downto 0)));
end process;
 
end behavior; --===================== End of architecture =======================--
 
/tags/V10/rtl/vhdl/testbench3.vhd
0,0 → 1,186
--===========================================================================----
--
-- T E S T B E N C H tesetbench3 - CPU09 Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : Testbench3.vhd
--
-- Purpose : cpu09 Microprocessor Test Bench 3
-- Contains ROM to test interrupts
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu09 (cpu09.vhd) CPU core
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 12st April 2003 - John Kent
-- First version
--
-- Version 1.0 - 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
--===========================================================================--
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity my_testbench is
end my_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal cpu_irq : std_Logic;
signal cpu_firq : std_logic;
signal cpu_nmi : std_logic;
 
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
 
constant width : integer := 8;
constant memsize : integer := 64;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
"00010000", "11001110", "11111000", "00110000", -- F800 - 10CE F830 RET1 LDS #STACK
"00111111", -- F804 - 3F SWI
"00010000", "00111111", -- F805 - 103F SWIVEC SWI2
"00010001", "00111111", -- F807 - 113F SWI2VEC SWI3
"00111011", -- F809 - 3B SWI3VEC RTI
"00100000", "11111110", -- F80A - 20 FE BRA *
"10110001", -- F80C - B1 STACK3 FCB $B1 ; CC
"00110010", -- F80D - 32 FCB $32 ; ACCA
"00110011", -- F8OE - 33 FCB $33 ; ACCB
"00110100", -- F8OF - 34 FCB $34 ; DPR
"00110101", "00110110", -- F810 - 3536 FDB $3536 ; IX
"00110111", "00111000", -- F812 - 3738 FDB $3738 ; IY
"00111001", "00111010", -- F814 - 393A FDB $393A ; UP
"11111000", "00001001", -- F816 - F809 FDB SWI3VEC ; PC
"10100001", -- F818 - A1 STACK2 FCB $A1 ; CC
"00100010", -- F819 - 22 FCB $22 ; ACCA
"00100011", -- F81A - 23 FCB $23 ; ACCB
"00100100", -- F81B - 24 FCB $24 ; DPR
"00100101", "00100110", -- F81C - 2526 FDB $2526 ; IX
"00100111", "00101000", -- F81E - 2728 FDB $2728 ; IY
"00101001", "00101010", -- F820 - 292A FDB $292A ; UP
"11111000", "00001001", -- F822 - F809 FDB SWI3VEC ; PC
"10010001", -- F824 - 91 STACK1 FCB $91 ; CC
"00010010", -- F825 - 12 FCB $12 ; ACCA
"00010011", -- F826 - 13 FCB $13 ; ACCB
"00010100", -- F827 - 14 FCB $14 ; DPR
"00010101", "00010110", -- F828 - 1516 FDB $1516 ; IX
"00010111", "00011000", -- F82A - 1718 FDB $1718 ; IY
"00011001", "00011010", -- F82C - 191A FDB $191A ; UP
"11111000", "00000000", -- F82E - F800 FDB RESET ; PC
"11111000", "00000000", -- F830 - F800 STACK FDB RESET ; RESV
"11111000", "00001001", -- F832 - F809 FDB SWIVEC3 ; SWI3
"11111000", "00000111", -- F834 - F807 FDB SWIVEC2 ; SWI2
"11111000", "00000000", -- F836 - F800 fdb RESET ; FIRQ
"11111000", "00000000", -- F838 - F800 fdb RESET ; IRQ
"11111000", "00000101", -- F83A - F805 fdb SWIVEC ; SWI
"11111000", "00000000", -- F83C - F800 fcb RESET ; NMI
"11111000", "00000000" -- F83E - F800 fdb RESET ; Reset
);
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component cpu09;
 
 
begin
cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => '0',
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr )
begin
cpu_data_in <= rom_data(conv_integer(cpu_addr(5 downto 0)));
end process;
 
end behavior; --===================== End of architecture =======================--
 
/tags/V10/rtl/vhdl/testbench4.vhd
0,0 → 1,161
--===========================================================================--
--
-- MC6809 Microprocessor Test Bench 4
-- Test Software - SBUG ROM
--
--
-- John Kent 12st April 2003
--
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use ieee.numeric_std.all;
 
entity my_testbench is
end my_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal cpu_irq : std_Logic;
signal cpu_firq : std_logic;
signal cpu_nmi : std_logic;
 
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_halt : Std_logic;
signal cpu_hold : Std_logic;
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
signal rom_data_out: Std_Logic_Vector(7 downto 0);
signal ram_data_out: Std_Logic_Vector(7 downto 0);
signal ram_cs : Std_Logic;
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component;
 
 
component sbug_rom
Port (
MEMclk : in std_logic;
MEMaddr : in std_logic_vector (10 downto 0);
MEMrdata : out std_logic_vector (7 downto 0)
);
end component;
 
component block_ram
Port (
MEMclk : in std_logic;
MEMcs : in std_logic;
MEMrw : in std_logic;
MEMaddr : in std_logic_vector (10 downto 0);
MEMrdata : out std_logic_vector (7 downto 0);
MEMwdata : in std_logic_vector (7 downto 0)
);
end component;
 
begin
my_cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => cpu_halt,
hold => cpu_hold,
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
);
 
 
my_ram : block_ram port map (
MEMclk => SysClk,
MEMcs => ram_cs,
MEMrw => cpu_rw,
MEMaddr => cpu_addr(10 downto 0),
MEMrdata => ram_data_out,
MEMwdata => cpu_data_out
);
 
my_rom : sbug_rom port map (
MEMclk => SysClk,
MEMaddr => cpu_addr(10 downto 0),
MEMrdata => rom_data_out
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
cpu_halt <= '0';
cpu_hold <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr, rom_data_out, ram_data_out )
begin
if( cpu_addr(15 downto 11) = "11111" ) then
cpu_data_in <= rom_data_out;
ram_cs <= '0';
else
cpu_data_in <= ram_data_out;
ram_cs <= '1';
end if;
end process;
 
end behavior; --===================== End of architecture =======================--
 
/tags/V10/rtl/vhdl/System09.npl
0,0 → 1,37
JDF E
// Created by ISE ver 1.0
PROJECT System09
DESIGN system09 Normal
DEVKIT xc2s300e-6pq208
DEVFAM spartan2e
FLOW XST VHDL
STIMULUS testbench1.vhd Normal
STIMULUS testbench2.vhd Normal
STIMULUS testbench3.vhd Normal
STIMULUS System09_tb.vhd Normal
MODULE ioport.vhd
MODSTYLE ioport Normal
MODULE rxunit2.vhd
MODSTYLE rxunit Normal
MODULE txunit2.vhd
MODSTYLE txunit Normal
MODULE cpu09.vhd
MODSTYLE cpu09 Normal
MODULE clkunit2.vhd
MODSTYLE clkunit Normal
MODULE datram.vhd
MODSTYLE dat_ram Normal
MODULE timer.vhd
MODSTYLE timer Normal
MODULE System09.vhd
MODSTYLE system09 Normal
MODULE sbug.vhd
MODSTYLE boot_rom Normal
MODULE miniUART2.vhd
MODSTYLE miniuart Normal
 
[STRATEGY-LIST]
Normal=True, 1062166682
 
[Normal]
p_impactConfigMode=xstvhd, SPARTAN2E, Implementation.t_impactProgrammingTool, 1031246025, Slave Serial
/tags/V10/rtl/vhdl/datram.vhd
0,0 → 1,184
--===========================================================================--
--
-- S Y N T H E Z I A B L E Dynamic Address Translation Registers
--
-- www.OpenCores.Org - December 2002
-- This core adheres to the GNU public license
--
-- File name : datram.vhd
--
-- entity name : dat_ram
--
-- Purpose : Implements a Dynamic Address Translation RAM module
-- Maps the high order 4 address bits to 8 address lines
-- extending the memory addressing range to 1 Mbytes
-- Memory segments are mapped on 4 KByte boundaries
-- The DAT registers map to the top of memory
-- ($FFF0 - $FFFF) and are write only so can map over ROM.
-- Since the DAT is not supported by SWTBUG for the 6800,
-- the resgisters reset state map the bottom 64K of RAM.
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Author : John E. Kent
--
--===========================================================================----
--
-- Revision History:
--
-- Date Revision Author
-- 10 Nov 2002 0.1 John Kent
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity dat_ram is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr_hi : in std_logic_vector(3 downto 0);
addr_lo : in std_logic_vector(3 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0));
end;
 
architecture datram_arch of dat_ram is
signal dat_reg0 : std_logic_vector(7 downto 0);
signal dat_reg1 : std_logic_vector(7 downto 0);
signal dat_reg2 : std_logic_vector(7 downto 0);
signal dat_reg3 : std_logic_vector(7 downto 0);
signal dat_reg4 : std_logic_vector(7 downto 0);
signal dat_reg5 : std_logic_vector(7 downto 0);
signal dat_reg6 : std_logic_vector(7 downto 0);
signal dat_reg7 : std_logic_vector(7 downto 0);
signal dat_reg8 : std_logic_vector(7 downto 0);
signal dat_reg9 : std_logic_vector(7 downto 0);
signal dat_reg10 : std_logic_vector(7 downto 0);
signal dat_reg11 : std_logic_vector(7 downto 0);
signal dat_reg12 : std_logic_vector(7 downto 0);
signal dat_reg13 : std_logic_vector(7 downto 0);
signal dat_reg14 : std_logic_vector(7 downto 0);
signal dat_reg15 : std_logic_vector(7 downto 0);
 
begin
 
---------------------------------
--
-- Write DAT RAM
--
---------------------------------
 
dat_write : process( clk, rst, addr_lo, cs, rw, data_in )
begin
if clk'event and clk = '0' then
if rst = '1' then
dat_reg0 <= "00000000";
dat_reg1 <= "00000001";
dat_reg2 <= "00000010";
dat_reg3 <= "00000011";
dat_reg4 <= "00000100";
dat_reg5 <= "00000101";
dat_reg6 <= "00000110";
dat_reg7 <= "00000111";
dat_reg8 <= "00001000";
dat_reg9 <= "00001001";
dat_reg10 <= "00001010";
dat_reg11 <= "00001011";
dat_reg12 <= "00001100";
dat_reg13 <= "00001101";
dat_reg14 <= "00001110";
dat_reg15 <= "00001111";
else
if cs = '1' and rw = '0' then
case addr_lo is
when "0000" =>
dat_reg0 <= data_in;
when "0001" =>
dat_reg1 <= data_in;
when "0010" =>
dat_reg2 <= data_in;
when "0011" =>
dat_reg3 <= data_in;
when "0100" =>
dat_reg4 <= data_in;
when "0101" =>
dat_reg5 <= data_in;
when "0110" =>
dat_reg6 <= data_in;
when "0111" =>
dat_reg7 <= data_in;
when "1000" =>
dat_reg8 <= data_in;
when "1001" =>
dat_reg9 <= data_in;
when "1010" =>
dat_reg10 <= data_in;
when "1011" =>
dat_reg11 <= data_in;
when "1100" =>
dat_reg12 <= data_in;
when "1101" =>
dat_reg13 <= data_in;
when "1110" =>
dat_reg14 <= data_in;
when "1111" =>
dat_reg15 <= data_in;
when others =>
null;
end case;
end if;
end if;
end if;
end process;
 
dat_read : process( addr_hi,
dat_reg0, dat_reg1, dat_reg2, dat_reg3,
dat_reg4, dat_reg5, dat_reg6, dat_reg7,
dat_reg8, dat_reg9, dat_reg10, dat_reg11,
dat_reg12, dat_reg13, dat_reg14, dat_reg15 )
begin
case addr_hi is
when "0000" =>
data_out <= dat_reg0;
when "0001" =>
data_out <= dat_reg1;
when "0010" =>
data_out <= dat_reg2;
when "0011" =>
data_out <= dat_reg3;
when "0100" =>
data_out <= dat_reg4;
when "0101" =>
data_out <= dat_reg5;
when "0110" =>
data_out <= dat_reg6;
when "0111" =>
data_out <= dat_reg7;
when "1000" =>
data_out <= dat_reg8;
when "1001" =>
data_out <= dat_reg9;
when "1010" =>
data_out <= dat_reg10;
when "1011" =>
data_out <= dat_reg11;
when "1100" =>
data_out <= dat_reg12;
when "1101" =>
data_out <= dat_reg13;
when "1110" =>
data_out <= dat_reg14;
when "1111" =>
data_out <= dat_reg15;
when others =>
null;
end case;
end process;
 
end datram_arch;
/tags/V10/rtl/vhdl/miniUART2.vhd
0,0 → 1,288
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : miniuart2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 1.0 Ovidiu Lupas January 2000 Synthesis optimizations
-- 2.0 Ovidiu Lupas April 2000 Bugs removed - RSBusCtrl
-- the RSBusCtrl did not process all possible situations
--
-- olupas@opencores.org
--
-- 3.0 John Kent October 2002 Changed Status bits to match mc6805
-- Added CTS, RTS, Baud rate control
-- & Software Reset
-- 3.1 John Kent 5 January 2003 Added Word Format control a'la mc6850
-- 3.2 John Kent 19 July 2003 Latched Data input to UART
-- 3.3 John Kent 6 September 2003 Changed Clock Edge.
-- dilbert57@opencores.org
--
-------------------------------------------------------------------------------
-- Entity for miniUART Unit - 9600 baudrate --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity miniUART is
port (
SysClk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input (active high)
cs : in Std_Logic;
rw : in Std_Logic;
RxD : in Std_Logic;
TxD : out Std_Logic;
CTS_n : in Std_Logic;
RTS_n : out Std_Logic;
Irq : out Std_Logic; -- interrupt
Addr : in Std_Logic; -- Register Select
DataIn : in Std_Logic_Vector(7 downto 0); --
DataOut : out Std_Logic_Vector(7 downto 0)); --
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for miniUART Controller Unit
-------------------------------------------------------------------------------
architecture uart of miniUART is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal RxData : Std_Logic_Vector(7 downto 0); --
signal TxData : Std_Logic_Vector(7 downto 0); --
signal StatReg : Std_Logic_Vector(7 downto 0); -- status register
-- StatReg detailed
-----------+--------+--------+--------+--------+--------+--------+--------+
-- Irq | PErr | ORErr | FErr | CTS | DCD | TBufE | DRdy |
-----------+--------+--------+--------+--------+--------+--------+--------+
signal CtrlReg : Std_Logic_Vector(7 downto 0); -- control register
-- CtrlReg detailed
-----------+--------+--------+--------+--------+--------+--------+--------+
-- IrqEnb |TxCtl(1)|TxCtl(0)|WdFmt(2)|WdFmt(1)|WdFmt(0)|BdCtl(1)|BdCtl(0)|
-----------+--------+--------+--------+--------+--------+--------+--------+
-- IrqEnb
-- 0 - Rx Interrupt disabled
-- 1 - Rx Interrupt enabled
-- TxCtl
-- 0 1 - Tx Interrupt Enable
-- 1 0 - RTS high
-- WdFmt
-- 0 0 0 - 7 data, even parity, 2 stop
-- 0 0 1 - 7 data, odd parity, 2 stop
-- 0 1 0 - 7 data, even parity, 1 stop
-- 0 1 1 - 7 data, odd parity, 1 stop
-- 1 0 0 - 8 data, no parity, 2 stop
-- 1 0 1 - 8 data, no parity, 1 stop
-- 1 1 0 - 8 data, even parity, 1 stop
-- 1 1 1 - 8 data, odd parity, 1 stop
-- BdCtl
-- 0 0 - Baud Clk divide by 1 (not implemented)
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - reset
signal EnabRx : Std_Logic; -- Enable RX unit
signal EnabTx : Std_Logic; -- Enable TX unit
signal DRdy : Std_Logic; -- Receive Data ready
signal TBufE : Std_Logic; -- Transmit buffer empty
signal FErr : Std_Logic; -- Frame error
signal OErr : Std_Logic; -- Output error
signal PErr : Std_Logic; -- Parity Error
signal Read : Std_Logic; -- Read receive buffer
signal Load : Std_Logic; -- Load transmit buffer
signal Int : Std_Logic; -- Interrupt bit
signal Reset : Std_Logic; -- Reset (Software & Hardware)
-----------------------------------------------------------------------------
-- Baud rate Generator
-----------------------------------------------------------------------------
component ClkUnit
port (
Clk : in Std_Logic; -- System Clock
Reset : in Std_Logic; -- Reset input
EnableRX : out Std_Logic; -- Control signal
EnableTX : out Std_Logic; -- Control signal
BaudRate : in Std_Logic_Vector(1 downto 0));
end component;
-----------------------------------------------------------------------------
-- Receive Unit
-----------------------------------------------------------------------------
component RxUnit
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
Enable : in Std_Logic; -- Enable input
RxD : in Std_Logic; -- RS-232 data input
ReadD : in Std_Logic; -- Read data signal
Format : in Std_Logic_Vector(2 downto 0); -- word format
FRErr : out Std_Logic; -- Status signal
ORErr : out Std_Logic; -- Status signal
PAErr : out Std_logic; -- Status signal
DARdy : out Std_Logic; -- Status signal
DAOut : out Std_Logic_Vector(7 downto 0));
end component;
-----------------------------------------------------------------------------
-- Transmitter Unit
-----------------------------------------------------------------------------
component TxUnit
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
Enable : in Std_Logic; -- Enable input
LoadD : in Std_Logic; -- Load transmit data
Format : in Std_Logic_Vector(2 downto 0); -- word format
TxD : out Std_Logic; -- RS-232 data output
TBE : out Std_Logic; -- Tx buffer empty
DataO : in Std_Logic_Vector(7 downto 0));
end component;
begin
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
ClkDiv : ClkUnit port map (
Clk => SysClk,
EnableRx => EnabRX,
EnableTx => EnabTX,
BaudRate => CtrlReg(1 downto 0),
Reset => Reset);
TxDev : TxUnit port map (
Clk => SysClk,
Reset => Reset,
Enable => EnabTX,
LoadD => Load,
Format => CtrlReg(4 downto 2),
TxD => TxD,
TBE => TBufE,
DataO => TxData);
 
RxDev : RxUnit port map (
Clk => SysClk,
Reset => Reset,
Enable => EnabRX,
RxD => RxD,
ReadD => Read,
Format => CtrlReg(4 downto 2),
FRErr => FErr,
ORErr => OErr,
PAErr => PErr,
DARdy => DRdy,
DAOut => RxData);
 
-----------------------------------------------------------------------------
-- Implements the controller for Rx&Tx units
-----------------------------------------------------------------------------
RSBusCtrl : process(SysClk, Reset, DRdy, TBufE, FErr, OErr, CTS_n, PErr, Int, CtrlReg)
variable StatM : Std_Logic_Vector(7 downto 0);
begin
if SysClk'event and SysClk='0' then
if Reset = '1' then
StatM := "00000000";
Int <= '0';
else
StatM(0) := DRdy;
StatM(1) := TBufE;
StatM(2) := '0'; -- DCD
StatM(3) := CTS_n;
StatM(4) := FErr; -- Framing error
StatM(5) := OErr; -- Overrun error
StatM(6) := PErr; -- Parity error
StatM(7) := Int;
Int <= (CtrlReg(7) and DRdy) or
((not CtrlReg(6)) and CtrlReg(5) and TBufE);
end if;
 
RTS_n <= CtrlReg(6) and not CtrlReg(5);
Irq <= Int;
StatReg <= StatM;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Combinational section
-----------------------------------------------------------------------------
 
control_strobe: process(SysClk, Reset, cs, rw, Addr, DataIn, CtrlReg, TxData )
begin
if SysClk'event and SysClk='0' then
if (reset = '1') then
CtrlReg <= "00000000";
Load <= '0';
Read <= '0';
else
if cs = '1' then
if Addr = '1' then
CtrlReg <= CtrlReg;
if rw = '0' then -- write data register
TxData <= DataIn;
Load <= '1';
Read <= '0';
else -- read Data Register
TxData <= TxData;
Load <= '0';
Read <= '1';
end if; -- rw
else -- read Status Register
TxData <= TxData;
Load <= '0';
Read <= '0';
if rw = '0' then -- write control register
CtrlReg <= DataIn;
else -- read control Register
CtrlReg <= CtrlReg;
end if; -- rw
end if; -- Addr
else -- not selected
Load <= '0';
Read <= '0';
CtrlReg <= CtrlReg;
end if; -- cs
end if; -- reset
end if; -- SysClk
end process;
 
---------------------------------------------------------------
--
-- set data output mux
--
--------------------------------------------------------------
 
data_port: process(Addr, StatReg, RxData )
begin
if Addr = '1' then
DataOut <= RxData; -- read data register
else
DataOut <= StatReg; -- read status register
end if; -- Addr
end process;
 
---------------------------------------------------------------
--
-- reset may be hardware or software
--
---------------------------------------------------------------
 
uart_reset: process(CtrlReg, rst )
begin
Reset <= (CtrlReg(1) and CtrlReg(0)) or rst;
end process;
 
end uart; --===================== End of architecture =======================--
 
/tags/V10/rtl/vhdl/rxunit2.vhd
0,0 → 1,341
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : rxunit2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the cpu68 cpu and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164.all;
-- ieee.numeric_std.all;
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 samples counter cleared for bit 0
-- olupas@opencores.org
--
-- 3.0 John Kent 5 January 2003 Added 6850 word format control
-- 3.1 John Kent 12 January 2003 Significantly revamped receive code.
-- 3.3 John Kent 6 September 2003 Changed Clock Edge.
-- dilbert57@opencores.org
-------------------------------------------------------------------------------
-- Description : Implements the receive unit of the miniUART core. Samples
-- 16 times the RxD line and retain the value in the middle of
-- the time interval.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Receive unit
-------------------------------------------------------------------------------
entity RxUnit is
port (
Clk : in Std_Logic; -- system clock signal
Reset : in Std_Logic; -- Reset input
Enable : in Std_Logic; -- Enable input
RxD : in Std_Logic; -- RS-232 data input
ReadD : in Std_Logic; -- Read data signal
Format : in Std_Logic_Vector(2 downto 0);
FRErr : out Std_Logic; -- Status signal
ORErr : out Std_Logic; -- Status signal
PAErr : out Std_logic; -- Status Signal
DARdy : out Std_Logic; -- Status signal
DAOut : out Std_Logic_Vector(7 downto 0)
);
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for receive Unit
-------------------------------------------------------------------------------
architecture Behaviour of RxUnit is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal RxStart : Std_Logic; -- Start Receive Request
signal RxFinish : Std_Logic; -- Receive finished
signal RxValid : Std_Logic; -- Receive data valid
signal RxFalse : Std_Logic; -- False start flag
signal tmpRxD : Std_Logic; -- RxD buffer
signal tmpRxC : Std_Logic; -- Rx clock
signal tmpDRdy : Std_Logic; -- Data Ready flag
signal tmpRxVal : Std_Logic; -- Rx Data Valid
signal tmpRxFin : Std_Logic; -- Rx Finish
signal outErr : Std_Logic; -- Over run error bit
signal frameErr : Std_Logic; -- Framing error bit
signal ParityErr : Std_Logic; -- Parity Error Bit
signal RxParity : Std_Logic; -- Calculated RX parity bit
signal RxState : Std_Logic_Vector(3 downto 0); -- receive bit state
signal SampleCnt : Std_Logic_Vector(3 downto 0); -- samples on one bit counter
signal ShtReg : Std_Logic_Vector(7 downto 0); -- Shift Register
signal DataOut : Std_Logic_Vector(7 downto 0); -- Data Output register
 
constant CntOne : Std_Logic_Vector(3 downto 0):= "0001";
constant CntZero : Std_Logic_Vector(3 downto 0):= "0000";
 
begin
---------------------------------------------------------------------
-- Receiver Read process
---------------------------------------------------------------------
RcvRead : process(Clk, Reset, ReadD, RxValid, tmpRxVal, tmpDRdy )
begin
if Clk'event and Clk='0' then
if Reset = '1' then
tmpDRdy <= '0';
tmpRxVal <= '0';
else
if ReadD = '1' then
tmpDRdy <= '0'; -- Data was read
tmpRxVal <= tmpRxVal;
else
if RxValid = '1' and tmpRxVal = '0' then
tmpDRdy <= '1'; -- Data was received
tmpRxVal <= '1';
else
tmpDRdy <= tmpDRdy;
if RxValid = '0' and tmpRxVal = '1' then
tmpRxVal <= '0';
else
tmpRxVal <= tmpRxVal;
end if;
end if; -- RxValid
end if; -- ReadD
end if; -- reset
end if; -- clk
end process;
 
---------------------------------------------------------------------
-- Receiver Synchronisation process
---------------------------------------------------------------------
RcvSync : process(Clk, Reset, Enable, RxStart, RxFalse, RxFinish, RxD, SampleCnt )
variable CntIni : Std_Logic_Vector(3 downto 0);
variable CntAdd : Std_Logic_Vector(3 downto 0);
begin
if Clk'event and Clk='0' then
if Reset = '1' then
RxStart <= '0';
SampleCnt <= "0000";
CntIni := SampleCnt;
CntAdd := CntZero;
else
if Enable = '1' then
if RxFinish = '1' and RxStart = '0' then -- Are we looking for a start bit ?
if RxD = '0' then -- yes, look for Start Edge
RxStart <= '1'; -- we have a start edge
CntIni := CntZero;
CntAdd := CntZero;
else
RxStart <= '0'; -- no start, spin sample count
CntIni := SampleCnt;
CntAdd := CntOne;
end if;
else
if RxFinish = '0' and RxStart = '1' then -- have we received a start bit ?
RxStart <= '0'; -- yes, reset start request
else
if RxFalse = '1' and RxStart = '1' then -- false start ?
RxStart <= '0'; -- yep, reset start request
else
RxStart <= RxStart;
end if;
end if;
CntIni := SampleCnt;
CntAdd := CntOne;
end if; -- RxStart
else
CntIni := SampleCnt;
CntAdd := CntZero;
RxStart <= RxStart;
end if; -- enable
end if; -- reset
SampleCnt <= CntIni + CntAdd;
end if; -- clk
end process;
 
 
---------------------------------------------------------------------
-- Receiver Clock process
---------------------------------------------------------------------
RcvClock : process(Clk, Reset, SampleCnt, RxD, tmpRxD )
begin
if Clk'event and Clk='0' then
if Reset = '1' then
tmpRxC <= '0';
tmpRxD <= '1';
else
if SampleCnt = "1000" then
tmpRxD <= RxD;
else
tmpRxD <= tmpRxD;
end if;
 
if SampleCnt = "1111" then
tmpRxC <= '1';
else
tmpRxC <= '0';
end if;
end if; -- reset
end if; -- clk
end process;
 
---------------------------------------------------------------------
-- Receiver process
---------------------------------------------------------------------
RcvProc : process(Clk, Reset, RxState, tmpRxC, Enable, tmpRxD, RxStart,
frameErr, outErr, DataOut, tmpDRdy,
ShtReg, RxParity, parityErr, Format,
RxValid, RxFalse, RxFinish
)
begin
if Clk'event and Clk='0' then
if Reset = '1' then
frameErr <= '0';
outErr <= '0';
parityErr <= '0';
 
ShtReg <= "00000000"; -- Shift register
RxParity <= '0'; -- Parity bit
RxFinish <= '1'; -- Data RX finish flag
RxValid <= '0'; -- Data RX data valid flag
RxFalse <= '0';
RxState <= "1111";
DataOut <= "00000000";
else
if tmpRxC = '1' and Enable = '1' then
case RxState is
when "0000" | "0001" | "0010" | "0011" |
"0100" | "0101" | "0110" => -- data bits 0 to 6
ShtReg <= tmpRxD & ShtReg(7 downto 1);
RxParity <= RxParity xor tmpRxD;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
RxFalse <= '0';
RxFinish <= '0';
if RxState = "0110" then
if Format(2) = '0' then
RxState <= "1000"; -- 7 data + parity
else
RxState <= "0111"; -- 8 data bits
end if; -- Format(2)
else
RxState <= RxState + CntOne;
end if; -- RxState
when "0111" => -- data bit 7
ShtReg <= tmpRxD & ShtReg(7 downto 1);
RxParity <= RxParity xor tmpRxD;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
RxFalse <= '0';
RxFinish <= '0';
if Format(1) = '1' then -- parity bit ?
RxState <= "1000"; -- yes, go to parity
else
RxState <= "1001"; -- no, must be 2 stop bit bits
end if;
when "1000" => -- parity bit
if Format(2) = '0' then
ShtReg <= tmpRxD & ShtReg(7 downto 1); -- 7 data + parity
else
ShtReg <= ShtReg; -- 8 data + parity
end if;
RxParity <= RxParity;
if Format(0) = '0' then -- parity polarity ?
if RxParity = tmpRxD then -- check even parity
parityErr <= '1';
else
parityErr <= '0';
end if;
else
if RxParity = tmpRxD then -- check for odd parity
parityErr <= '0';
else
parityErr <= '1';
end if;
end if;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
RxFalse <= '0';
RxFinish <= '0';
RxState <= "1001";
when "1001" => -- stop bit (Only one required for RX)
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
if tmpRxD = '1' then -- stop bit expected
frameErr <= '0'; -- yes, no framing error
else
frameErr <= '1'; -- no, framing error
end if;
if tmpDRdy = '1' then -- Has previous data been read ?
outErr <= '1'; -- no, overrun error
else
outErr <= '0'; -- yes, no over run error
end if;
RxValid <= '1';
DataOut <= ShtReg;
RxFalse <= '0';
RxFinish <= '1';
RxState <= "1111";
when others => -- this is the idle state
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
if RxStart = '1' and tmpRxD = '0' then -- look for start request
RxFalse <= '0';
RxFinish <= '0';
RxState <= "0000"; -- yes, read data
else
if RxStart = '1' and tmpRxD = '1' then -- start request, but no start bit
RxFalse <= '1';
else
RxFalse <= '0';
end if;
RxFinish <= '1';
RxState <= "1111"; -- otherwise idle
end if;
end case; -- RxState
else
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= RxValid;
DataOut <= DataOut;
RxFalse <= RxFalse;
RxFinish <= RxFinish;
RxState <= RxState;
end if; -- tmpRxC
end if; -- reset
end if; -- clk
end process;
 
DARdy <= tmpDRdy;
DAOut <= DataOut;
FRErr <= frameErr;
ORErr <= outErr;
PAErr <= parityErr;
 
end Behaviour; --==================== End of architecture ====================--
/tags/V10/rtl/vhdl/ioport.vhd
0,0 → 1,194
--===========================================================================----
--
-- S Y N T H E Z I A B L E ioport - 2 x 8 bit parallel I/O port
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : ioport.vhd
--
-- Purpose : dual 8 bit I/O module for System09
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Uses : None
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 11 Oct 2002
-- Used a loop counter for data direction & read port signals
-- Version 0.2 - 5 Sept 2003
-- Reduced to 2 x 8 bit ports
-- Version 1.0 - 6 Sept 2003 - John Kent
-- Realeased to open Cores
-- changed Clock Edge
--
--===========================================================================
--
--
-- John Kent - 6 Sept 2002
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity ioport is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector(1 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
porta_io : inout std_logic_vector(7 downto 0);
portb_io : inout std_logic_vector(7 downto 0)
);
end;
 
architecture ioport_arch of ioport is
signal porta_ddr : std_logic_vector(7 downto 0);
signal portb_ddr : std_logic_vector(7 downto 0);
signal porta_data : std_logic_vector(7 downto 0);
signal portb_data : std_logic_vector(7 downto 0);
 
begin
 
 
--------------------------------
--
-- read I/O port
--
--------------------------------
 
ioport_read : process( addr,
porta_ddr, portb_ddr,
porta_data, portb_data,
porta_io, portb_io )
variable count : integer;
begin
case addr is
when "00" =>
for count in 0 to 7 loop
if porta_ddr(count) = '1' then
data_out(count) <= porta_data(count);
else
data_out(count) <= porta_io(count);
end if;
end loop;
 
when "01" =>
for count in 0 to 7 loop
if portb_ddr(count) = '1' then
data_out(count) <= portb_data(count);
else
data_out(count) <= portb_io(count);
end if;
end loop;
 
when "10" =>
data_out <= porta_ddr;
when "11" =>
data_out <= portb_ddr;
when others =>
data_out <= "00000000";
end case;
end process;
 
---------------------------------
--
-- Write I/O ports
--
---------------------------------
 
ioport_write : process( clk, rst, addr, cs, rw, data_in,
porta_data, portb_data,
porta_ddr, portb_ddr )
begin
if clk'event and clk = '0' then
if rst = '1' then
porta_data <= "00000000";
portb_data <= "00000000";
porta_ddr <= "00000000";
portb_ddr <= "00000000";
elsif cs = '1' and rw = '0' then
case addr is
when "00" =>
porta_data <= data_in;
portb_data <= portb_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
when "01" =>
porta_data <= porta_data;
portb_data <= data_in;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
when "10" =>
porta_data <= porta_data;
portb_data <= portb_data;
porta_ddr <= data_in;
portb_ddr <= portb_ddr;
when "11" =>
porta_data <= porta_data;
portb_data <= portb_data;
porta_ddr <= porta_ddr;
portb_ddr <= data_in;
when others =>
porta_data <= porta_data;
portb_data <= portb_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
end case;
else
porta_data <= porta_data;
portb_data <= portb_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
end if;
end if;
end process;
 
---------------------------------
--
-- direction control port a
--
---------------------------------
porta_direction : process ( porta_data, porta_ddr )
variable count : integer;
begin
for count in 0 to 7 loop
if porta_ddr(count) = '1' then
porta_io(count) <= porta_data(count);
else
porta_io(count) <= 'Z';
end if;
end loop;
end process;
---------------------------------
--
-- direction control port b
--
---------------------------------
portb_direction : process ( portb_data, portb_ddr )
variable count : integer;
begin
for count in 0 to 7 loop
if portb_ddr(count) = '1' then
portb_io(count) <= portb_data(count);
else
portb_io(count) <= 'Z';
end if;
end loop;
end process;
---------------------------------
 
end ioport_arch;
/tags/V10/rtl/vhdl/txunit2.vhd
0,0 → 1,232
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : txunit2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : IEEE.Std_Logic_1164
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 unnecessary variable removed
-- olupas@opencores.org
--
-- 3.0 John Kent 5 January 2003 added 6850 word format control
-- 3.1 John Kent 12 January 2003 Rearranged state machine code
-- 3.2 John Kent 30 March 2003 Revamped State machine
-- 3.3 John Kent 6 September 2003 Changed Clock Edge.
--
-- dilbert57@opencores.org
--
-------------------------------------------------------------------------------
-- Description :
-------------------------------------------------------------------------------
-- Entity for the Tx Unit --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Transmitter unit
-------------------------------------------------------------------------------
entity TxUnit is
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
Enable : in Std_Logic; -- Enable input
LoadD : in Std_Logic; -- Load transmit data
Format : in Std_Logic_Vector(2 downto 0); -- word format
TxD : out Std_Logic; -- RS-232 data output
TBE : out Std_Logic; -- Tx buffer empty
DataO : in Std_Logic_Vector(7 downto 0));
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for TxUnit
-------------------------------------------------------------------------------
architecture Behaviour of TxUnit is
type TxStateType is (TxReset_State, TxIdle_State, Start_State, Data_State, Parity_State, Stop_State );
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal TBuff : Std_Logic_Vector(7 downto 0); -- transmit buffer
signal tmpTBufE : Std_Logic; -- Transmit Buffer Empty
 
signal TReg : Std_Logic_Vector(7 downto 0); -- transmit register
signal TxParity : Std_logic; -- Parity Bit
signal DataCnt : Std_Logic_Vector(3 downto 0); -- Data Bit Counter
signal tmpTRegE : Std_Logic; -- Transmit Register empty
signal TxState : TxStateType;
 
signal NextTReg : Std_Logic_Vector(7 downto 0); -- transmit register
signal NextTxParity : Std_logic; -- Parity Bit
signal NextDataCnt : Std_Logic_Vector(3 downto 0); -- Data Bit Counter
signal NextTRegE : Std_Logic; -- Transmit Register empty
signal NextTxState : TxStateType;
begin
---------------------------------------------------------------------
-- Transmitter activation process
---------------------------------------------------------------------
TxSync : process(Clk, Reset, Enable, LoadD, DataO, tmpTBufE, tmpTRegE, TBuff )
begin
if Clk'event and Clk = '0' then
if Reset = '1' then
tmpTBufE <= '1';
TBuff <= "00000000";
else
if LoadD = '1' then
TBuff <= DataO;
tmpTBufE <= '0';
else
TBuff <= TBuff;
if (Enable = '1') and (tmpTBufE = '0') and (tmpTRegE = '1') then
tmpTBufE <= '1';
else
tmpTBufE <= tmpTBufE;
end if;
end if;
end if; -- reset
end if; -- clk
TBE <= tmpTBufE;
 
end process;
 
-----------------------------------------------------------------------------
-- Implements the Tx unit
-----------------------------------------------------------------------------
TxProc : process(TxState, TBuff, TReg, TxParity, DataCnt, Format, tmpTRegE, tmpTBufE)
begin
case TxState is
when TxReset_State =>
TxD <= '1';
NextTReg <= "00000000";
NextTxParity <= '0';
NextDataCnt <= "0000";
NextTRegE <= '1';
NextTxState <= TxIdle_State;
 
when Start_State =>
TxD <= '0'; -- Start bit
NextTReg <= TReg;
NextTxParity <= '0';
if Format(2) = '0' then
NextDataCnt <= "0110"; -- 7 data + parity
else
NextDataCnt <= "0111"; -- 8 data
end if;
NextTRegE <= '0';
NextTxState <= Data_State;
 
when Data_State =>
TxD <= TReg(0);
NextTReg <= '1' & TReg(7 downto 1);
NextTxParity <= TxParity xor TReg(0);
NextTRegE <= '0';
NextDataCnt <= DataCnt - "0001";
if DataCnt = "0000" then
if (Format(2) = '1') and (Format(1) = '0') then
if Format(0) = '0' then -- 8 data bits
NextTxState <= Stop_State; -- 2 stops
else
NextTxState <= TxIdle_State; -- 1 stop
end if;
else
NextTxState <= Parity_State; -- parity
end if;
else
NextTxState <= Data_State;
end if;
 
when Parity_State => -- 7/8 data + parity bit
if Format(0) = '0' then
TxD <= not( TxParity ); -- even parity
else
TXD <= TxParity; -- odd parity
end if;
NextTreg <= Treg;
NextTxParity <= '0';
NextTRegE <= '0';
NextDataCnt <= "0000";
if Format(1) = '0' then
NextTxState <= Stop_State; -- 2 stops
else
NextTxState <= TxIdle_State; -- 1 stop
end if;
 
when Stop_State => -- first stop bit
TxD <= '1'; -- 2 stop bits
NextTreg <= Treg;
NextTxParity <= '0';
NextDataCnt <= "0000";
NextTRegE <= '0';
NextTxState <= TxIdle_State;
 
when others => -- TxIdle_State (2nd Stop bit)
TxD <= '1';
NextTreg <= TBuff;
NextTxParity <= '0';
NextDataCnt <= "0000";
if (tmpTBufE = '0') and (tmpTRegE = '1') then
NextTRegE <= '0';
NextTxState <= Start_State;
else
NextTRegE <= '1';
NextTxState <= TxIdle_State;
end if;
 
end case; -- TxState
 
end process;
 
--
-- Tx State Machine
-- Slowed down by "Enable"
--
TX_State_Machine: process( Clk, Reset, Enable,
Treg, NextTReg,
TxParity, NextTxParity,
DataCnt, NextDataCnt,
tmpTRegE, NextTRegE,
TxState, NextTxState )
begin
if Clk'event and Clk = '0' then
if Reset = '1' then
Treg <= "00000000";
TxParity <= '0';
DataCnt <= "0000";
tmpTRegE <= '1';
TxState <= TxReset_State;
else
if Enable = '1' then
Treg <= NextTreg;
TxParity <= NextTxParity;
DataCnt <= NextDataCnt;
tmpTRegE <= NextTRegE;
TxState <= NextTxState;
else
Treg <= Treg;
TxParity <= TxParity;
DataCnt <= DataCnt;
tmpTRegE <= tmpTRegE;
TxState <= TxState;
end if;
end if;
end if;
 
end process;
 
end Behaviour; --=================== End of architecture ====================--
/tags/V10/rtl/vhdl/timer.vhd
0,0 → 1,256
--===========================================================================----
--
-- S Y N T H E Z I A B L E timer - 9 bit timer
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : timer.vhd
--
-- Purpose : 9 bit timer module for System 09
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Uses : None
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 6 Sept 2002 - John Kent
-- converted to a single timer
-- made syncronous with system clock
--
-- Version 1.0 - 6 Sept 2003 - John Kent
-- Realeased to open Cores
-- changed Clock Edge
--
--===========================================================================
--
-- Register Addressing:
-- addr=0 rw=1 down count
-- addr=0 rw=0 preset count
-- addr=1 rw=1 status
-- addr=0 rw=0 control
--
-- Control register
-- b0 = counter enable
-- b1 = mode (0 = counter, 1 = timer)
-- b7 = interrupt enable
--
-- Status register
-- b6 = timer output
-- b7 = interrupt flag
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity timer is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq : out std_logic;
timer_in : in std_logic;
timer_out : out std_logic
);
end;
 
architecture timer_arch of timer is
signal timer_ctrl : std_logic_vector(7 downto 0);
signal timer_stat : std_logic_vector(7 downto 0);
signal timer_reg : std_logic_vector(7 downto 0);
signal timer_count : std_logic_vector(7 downto 0);
signal timer_int : std_logic; -- Timer interrupt
signal timer_term : std_logic; -- Timer terminal count
signal timer_tog : std_logic; -- Timer output
--
-- control/status register bits
--
constant T_enab : integer := 0; -- 0=disable, 1=enabled
constant T_mode : integer := 1; -- 0=counter, 1=timer
constant T_out : integer := 6; -- 0=disabled, 1=enabled
constant T_irq : integer := 7; -- 0=disabled, 1-enabled
 
begin
 
--------------------------------
--
-- write control registers
-- doesn't do anything yet
--
--------------------------------
timer_write : process( clk, rst, cs, rw, addr, data_in,
timer_reg, timer_ctrl, timer_term, timer_count )
begin
if clk'event and clk = '0' then
if rst = '1' then
timer_reg <= "00000000";
timer_ctrl <= "00000000";
elsif cs = '1' and rw = '0' then
if addr='0' then
timer_reg <= data_in;
timer_ctrl <= timer_ctrl;
timer_term <= '0';
else
timer_reg <= timer_reg;
timer_ctrl <= data_in;
timer_term <= timer_term;
end if;
else
timer_ctrl <= timer_ctrl;
timer_reg <= timer_reg;
if (timer_ctrl(T_enab) = '1') then
if (timer_count = "00000000" ) then
timer_term <= '1';
elsif timer_ctrl(T_mode) = '0' then
timer_term <= '0'; -- counter mode, reset on non zero
else
timer_term <= timer_term; -- timer mode, keep as is
end if;
else
timer_term <= timer_term;
end if;
end if;
end if;
end process;
 
--
-- timer data output mux
--
timer_read : process( addr, timer_count, timer_stat )
begin
if addr='0' then
data_out <= timer_count;
else
data_out <= timer_stat;
end if;
end process;
 
--------------------------------
--
-- counters
--
--------------------------------
 
my_counter: process( clk, rst, timer_ctrl, timer_count, timer_reg, timer_in )
variable timer_tmp : std_logic;
begin
if clk'event and clk = '0' then
if rst = '1' then
timer_count <= "00000000";
timer_tmp := '0';
else
if timer_ctrl( T_enab ) = '1' then
if timer_in = '0' and timer_tmp = '1' then
timer_tmp := '0';
if timer_count = "00000000" then
timer_count <= timer_reg;
else
timer_count <= timer_count - 1;
end if;
elsif timer_in = '1' and timer_tmp = '0' then
timer_tmp := '1';
timer_count <= timer_count;
else
timer_tmp := timer_tmp;
timer_count <= timer_count;
end if;
else
timer_tmp := timer_tmp;
timer_count <= timer_count;
end if; -- timer_ctrl
end if; -- rst
end if; -- clk
end process;
 
--
-- read timer strobe to reset interrupts
--
timer_interrupt : process( Clk, rst, cs, rw, addr,
timer_term, timer_int, timer_ctrl )
begin
if clk'event and clk = '0' then
if rst = '1' then
timer_int <= '0';
elsif cs = '1' and rw = '1' then
if addr = '0' then
timer_int <= '0'; -- reset interrupt on read count
else
timer_int <= timer_int;
end if;
else
if timer_term = '1' then
timer_int <= '1';
else
timer_int <= timer_int;
end if;
end if;
end if;
 
if timer_ctrl( T_irq ) = '1' then
irq <= timer_int;
else
irq <= '0';
end if;
end process;
 
--
-- timer status register
--
timer_status : process( timer_ctrl, timer_int, timer_tog )
begin
timer_stat(5 downto 0) <= timer_ctrl(5 downto 0);
timer_stat(T_out) <= timer_tog;
timer_stat(T_irq) <= timer_int;
end process;
 
--
-- timer output
--
timer_output : process( Clk, rst, timer_term, timer_ctrl, timer_tog )
variable timer_tmp : std_logic; -- tracks change in terminal count
begin
if clk'event and clk = '0' then
if rst = '1' then
timer_tog <= '0';
timer_tmp := '0';
elsif timer_ctrl(T_mode) = '0' then -- free running ?
if (timer_term = '1') and (timer_tmp = '0') then
timer_tmp := '1';
timer_tog <= not timer_tog;
elsif (timer_term = '0') and (timer_tmp = '1') then
timer_tmp := '0';
timer_tog <= timer_tog;
else
timer_tmp := timer_tmp;
timer_tog <= timer_tog;
end if;
else -- one shot timer mode, follow terminal count
if (timer_term = '1') and (timer_tmp = '0') then
timer_tmp := '1';
timer_tog <= '1';
elsif (timer_term = '0') and (timer_tmp = '1') then
timer_tmp := '0';
timer_tog <= '0';
else
timer_tmp := timer_tmp;
timer_tog <= timer_tog;
end if;
end if;
end if;
timer_out <= timer_tog and timer_ctrl(T_out);
end process;
 
end timer_arch;
/tags/V10/rtl/vhdl/System09_tb.vhd
0,0 → 1,601
--===========================================================================----
--
-- T E S T B E N C H System09_tb - SOC Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : System09_tb.vhd
--
-- Purpose : Test Bench for system 09
-- Top level file for 6809 compatible system on a chip
-- Designed with Xilinx XC2S300e Spartan 2+ FPGA.
-- Implemented With BurchED B5-X300 FPGA board,
-- B3-SRAM module, B5-CF module and B3-FPGA-CPU-IO module
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : boot_rom (sbug.vhd) Monitor ROM
-- cpu09 (cpu09.vhd) CPU core
-- dat_ram (datram.vhd) Dynamic Address Translation
-- miniuart (minitUART2.vhd) ACIA / MiniUART
-- (rxunit2.vhd)
-- (tx_unit2.vhd)
-- (clkunit2.vhd)
-- timer (timer.vhd) Timer module
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 1.0
-- John Kent - 6 Sep 2003 - Initial release to Open Cores
--
--===========================================================================--
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity System09 is
port(
LED : out std_logic; -- Diagnostic LED Flasher
 
-- Memory Interface signals
ram_csn : out Std_Logic;
ram_wrln : out Std_Logic;
ram_wrun : out Std_Logic;
ram_addr : out Std_Logic_Vector(16 downto 0);
ram_data : inout Std_Logic_Vector(15 downto 0);
 
-- Stuff on the peripheral board
-- aux_clock : in Std_Logic; -- FPGA-CPU-IO clock
 
-- PS/2 Mouse interface
-- mouse_clock : in Std_Logic;
-- mouse_data : in Std_Logic;
 
-- Uart Interface
rxbit : in Std_Logic;
txbit : out Std_Logic;
rts_n : out Std_Logic;
cts_n : in Std_Logic;
 
-- CRTC output signals
-- v_drive : out Std_Logic;
-- h_drive : out Std_Logic;
-- blue_lo : out std_logic;
-- blue_hi : out std_logic;
-- green_lo : out std_logic;
-- green_hi : out std_logic;
-- red_lo : out std_logic;
-- red_hi : out std_logic;
-- buzzer : out std_logic;
 
-- Compact Flash
cf_rst_n : out std_logic;
cf_cs0_n : out std_logic;
cf_cs1_n : out std_logic;
cf_rd_n : out std_logic;
cf_wr_n : out std_logic;
cf_cs16_n : out std_logic;
cf_a : out std_logic_vector(2 downto 0);
cf_d : inout std_logic_vector(15 downto 0);
 
-- Test Pins
 
test_alu : out std_logic_vector(15 downto 0);
test_cc : out std_logic_vector(7 downto 0)
);
end;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture my_computer of System09 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal SysClk : std_logic;
signal reset_n : std_logic;
 
-- BOOT ROM
signal rom_data_out : Std_Logic_Vector(7 downto 0);
 
-- UART Interface signals
signal uart_data_out : Std_Logic_Vector(7 downto 0);
signal uart_cs : Std_Logic;
signal uart_irq : Std_Logic;
 
-- timer
signal timer_data_out : std_logic_vector(7 downto 0);
signal timer_cs : std_logic;
signal timer_irq : std_logic;
signal timer_out : std_logic;
 
-- compact flash port
signal cf_data_out : std_logic_vector(7 downto 0);
signal cf_cs : std_logic;
signal cf_rd : std_logic;
signal cf_wr : std_logic;
 
-- RAM
signal ram_cs : std_logic; -- memory chip select
signal ram_wrl : std_logic; -- memory write lower
signal ram_wru : std_logic; -- memory write upper
signal ram_data_out : std_logic_vector(7 downto 0);
 
-- CPU Interface signals
signal cpu_reset : Std_Logic;
signal cpu_clk : Std_Logic;
signal cpu_rw : std_logic;
signal cpu_vma : std_logic;
signal cpu_halt : std_logic;
signal cpu_hold : std_logic;
signal cpu_firq : std_logic;
signal cpu_irq : std_logic;
signal cpu_nmi : std_logic;
signal cpu_addr : std_logic_vector(15 downto 0);
signal cpu_data_in : std_logic_vector(7 downto 0);
signal cpu_data_out: std_logic_vector(7 downto 0);
 
-- Dynamic address translation
signal dat_cs : std_logic;
signal dat_addr : std_logic_vector(7 downto 0);
 
-- Boot ROM Map switch
-- signal map_cs : Std_Logic;
-- signal map_sw : Std_Logic;
 
-- synchronous RAM
signal xram_data_out : std_logic_vector(7 downto 0);
signal xram_cs : std_logic;
 
-- Flashing Led test signals
signal countL : std_logic_vector(23 downto 0);
 
-----------------------------------------------------------------
--
-- CPU09 CPU core
--
-----------------------------------------------------------------
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component;
 
-----------------------------------------------------------------
--
-- Open Cores Mini UART
--
-----------------------------------------------------------------
 
component miniUART
port (
SysClk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input
cs : in Std_Logic;
rw : in Std_Logic;
RxD : in Std_Logic;
TxD : out Std_Logic;
CTS_n : in Std_Logic;
RTS_n : out Std_Logic;
Irq : out Std_logic;
Addr : in Std_Logic;
DataIn : in Std_Logic_Vector(7 downto 0); --
DataOut : out Std_Logic_Vector(7 downto 0)); --
end component;
 
----------------------------------------
--
-- Timer module
--
----------------------------------------
 
component timer
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq : out std_logic;
timer_in : in std_logic;
timer_out : out std_logic
);
end component;
 
 
component boot_rom
port (
addr : in Std_Logic_Vector(10 downto 0); -- 2K byte boot rom
data : out Std_Logic_Vector(7 downto 0));
end component;
 
--component sbug_rom
-- Port (
-- MEMclk : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0)
-- );
--end component sbug_rom;
 
component dat_ram
port (
clk: in std_logic;
rst: in std_logic;
cs: in std_logic;
rw: in std_logic;
addr_lo: in std_logic_vector(3 downto 0);
addr_hi: in std_logic_vector(3 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0)
);
end component;
 
 
-- component block_ram
-- Port (
-- MEMclk : in std_logic;
-- MEMcs : in std_logic;
-- MEMrw : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0);
-- MEMwdata : in std_logic_vector (7 downto 0)
-- );
--end component;
 
 
-- component BUFG
-- port (
-- i: in std_logic;
-- o: out std_logic
-- );
-- end component;
 
begin
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
my_cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => cpu_halt,
hold => cpu_hold,
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => test_alu,
test_cc => test_cc
);
 
 
my_uart : miniUART port map (
SysClk => SysClk,
rst => cpu_reset,
cs => uart_cs,
rw => cpu_rw,
RxD => rxbit,
TxD => txbit,
CTS_n => cts_n,
RTS_n => rts_n,
Irq => uart_irq,
Addr => cpu_addr(0),
Datain => cpu_data_out,
DataOut => uart_data_out
);
 
my_timer : timer port map (
clk => SysClk,
rst => cpu_reset,
cs => timer_cs,
rw => cpu_rw,
addr => cpu_addr(0),
data_in => cpu_data_out,
data_out => timer_data_out,
irq => timer_irq,
timer_in => CountL(5),
timer_out => timer_out
);
 
my_rom : boot_rom port map (
addr => cpu_addr(10 downto 0),
data => rom_data_out
);
 
--my_rom : sbug_rom port map (
-- MEMclk => SysClk,
-- MEMaddr => cpu_addr(10 downto 0),
-- MEMrdata => rom_data_out
-- );
 
 
my_dat : dat_ram port map (
clk => SysClk,
rst => cpu_reset,
cs => dat_cs,
rw => cpu_rw,
addr_hi => cpu_addr(15 downto 12),
addr_lo => cpu_addr(3 downto 0),
data_in => cpu_data_out,
data_out => dat_addr(7 downto 0)
);
 
 
--my_ram : block_ram port map (
-- MEMclk => SysClk,
-- MEMcs => xram_cs,
-- MEMrw => cpu_rw,
-- MEMaddr => cpu_addr(10 downto 0),
-- MEMwdata => cpu_data_out,
-- MEMrdata => xram_data_out
-- );
 
-- clk_buffer : BUFG port map(
-- i => e_clk,
-- o => cpu_clk
-- );
----------------------------------------------------------------------
--
-- Process to decode memory map
--
----------------------------------------------------------------------
 
mem_decode: process(
cpu_addr, cpu_vma,
-- map_cs, map_sw,
rom_data_out, ram_data_out,
-- xram_data_out,
cf_data_out,
timer_data_out,
uart_data_out )
begin
--
-- Memory map
--
case cpu_addr(15 downto 11) is
when "11111" => -- $F800 - $FFFF
cpu_data_in <= rom_data_out; -- read ROM
dat_cs <= cpu_vma; -- write DAT
ram_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
-- xram_cs <= '0';
-- map_cs <= '0';
-- when "11101" => -- $E800 - $EFFF
-- when "11111" => -- $F800 - $FFFF
-- if map_sw = '1' then
-- cpu_data_in <= rom_data_out; -- read ROM
-- dat_cs <= '0'; -- disable write to DAT
-- ram_cs <= cpu_vma; -- enable write to RAM
-- else
-- cpu_data_in <= ram_data_out; -- read RAM
-- dat_cs <= cpu_vma; -- enable write DAT
-- ram_cs <= cpu_vma and cpu_rw; -- disable write to RAM
-- end if;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- map_cs <= '0';
-- when "11110" => -- $F000 - $F7FF
-- cpu_data_in <= xram_data_out;
-- dat_cs <= '0';
-- ram_cs <= '0';
-- uart_cs <= '0';
-- cf_cs <= '0';
-- xram_cs <= cpu_vma;
when "11100" => -- $E000 - $E7FF
dat_cs <= '0';
ram_cs <= '0';
-- xram_cs <= '0';
case cpu_addr(7 downto 4) is
when "0000" => -- $E000
cpu_data_in <= uart_data_out;
uart_cs <= cpu_vma;
cf_cs <= '0';
timer_cs <= '0';
-- map_cs <= '0';
when "0001" => -- $E010
cpu_data_in <= cf_data_out;
uart_cs <= '0';
cf_cs <= cpu_vma;
timer_cs <= '0';
-- map_cs <= '0';
when "0010" => -- $E020
cpu_data_in <= timer_data_out;
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= cpu_vma;
map_cs <= '0';
when "0011" => -- $E030
cpu_data_in <= "00000000";
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
-- map_cs <= cpu_vma;
when others => -- $E040 to $E7FF
cpu_data_in <= "00000000";
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
-- map_cs <= '0';
end case;
when others =>
cpu_data_in <= ram_data_out;
ram_cs <= cpu_vma;
-- xram_cs <= '0';
dat_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
-- map_cs <= '0';
end case;
end process;
 
--
-- B3-SRAM Control
-- Processes to read and write memory based on bus signals
--
ram_process: process( SysClk, Reset_n,
cpu_addr, cpu_rw, cpu_data_out,
dat_addr,
ram_cs, ram_wrl, ram_wru, ram_data )
begin
ram_csn <= not( ram_cs and Reset_n );
ram_wrl <= (not dat_addr(5)) and (not cpu_rw) and (not SysClk);
ram_wrln <= not (ram_wrl);
ram_wru <= dat_addr(5) and (not cpu_rw) and (not SysClk);
ram_wrun <= not (ram_wru);
ram_addr(16 downto 12) <= dat_addr(4 downto 0);
ram_addr(11 downto 0) <= cpu_addr(11 downto 0);
 
if ram_wrl = '1' then
ram_data(7 downto 0) <= cpu_data_out;
else
ram_data(7 downto 0) <= "ZZZZZZZZ";
end if;
 
if ram_wru = '1' then
ram_data(15 downto 8) <= cpu_data_out;
else
ram_data(15 downto 8) <= "ZZZZZZZZ";
end if;
 
if dat_addr(5) = '1' then
ram_data_out <= ram_data(15 downto 8);
else
ram_data_out <= ram_data(7 downto 0);
end if;
end process;
 
--
-- Compact Flash Control
--
compact_flash: process( Reset_n,
cpu_addr, cpu_rw, cpu_data_out,
cf_cs, cf_rd, cf_wr, cf_d )
begin
cf_rst_n <= Reset_n;
cf_cs0_n <= not( cf_cs ) or cpu_addr(3);
cf_cs1_n <= not( cf_cs and cpu_addr(3));
cf_cs16_n <= '1';
cf_wr <= cf_cs and (not cpu_rw);
cf_rd <= cf_cs and cpu_rw;
cf_wr_n <= not cf_wr;
cf_rd_n <= not cf_rd;
cf_a <= cpu_addr(2 downto 0);
if cf_wr = '1' then
cf_d(7 downto 0) <= cpu_data_out;
else
cf_d(7 downto 0) <= "ZZZZZZZZ";
end if;
cf_data_out <= cf_d(7 downto 0);
cf_d(15 downto 8) <= "ZZZZZZZZ";
end process;
 
--
-- ROM Map switch
-- The Map switch output is initially set
-- On a Write to the Map Switch port, clear the Map Switch
-- and map the RAM in place of the boot ROM.
--
--map_proc : process( SysClk, Reset_n, map_cs, cpu_rw )
--begin
-- if SysClk'event and SysClk = '1' then
-- if Reset_n = '0' then
-- map_sw <= '1';
-- else
-- if (map_cs = '1') and (cpu_rw = '0') then
-- map_sw <= '0';
-- else
-- map_sw <= map_sw;
-- end if;
-- end if;
-- end if;
--end process;
 
--
-- Interrupts and other bus control signals
--
interrupts : process( Reset_n, uart_irq
-- ,timer_irq
)
begin
cpu_reset <= not Reset_n; -- CPU reset is active high
cpu_irq <= uart_irq;
cpu_nmi <= timer_irq;
-- cpu_nmi <= '0';
cpu_firq <= '0';
cpu_halt <= '0';
cpu_hold <= '0';
end process;
 
--
-- flash led to indicate code is working
--
increment: process (SysClk, CountL )
begin
if(SysClk'event and SysClk = '1') then
countL <= countL + 1;
end if;
LED <= countL(21);
end process;
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
SysClk <= '0';
Reset_n <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
Reset_n <= '0';
elsif count = 1 then
Reset_n <= '1';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
end; --===================== End of architecture =======================--
 
/tags/V10/rtl/vhdl/system09.ucf
0,0 → 1,288
#### UCF file created by Project Navigator
#
NET "reset_n" LOC = "p57" ;
NET "sysclk" LOC = "p77" ;
#
# For B5-Compact-Flash:
# Connector A
#
#NET "pin2" LOC = "P3" ; #J1-2
#NET "pin3" LOC = "P4" ; #J1-3
#NET "cf_intrq" LOC = "P5" ; #J1-4
NET "cf_wr_n" LOC = "P6" ; #J1-5
NET "cf_rd_n" LOC = "P7" ; #J1-6
NET "cf_cs1_n" LOC = "P8" ; #J1-7
NET "cf_d<15>" LOC = "P9" ; #J1-8
NET "cf_d<14>" LOC = "P10" ; #J1-9
NET "cf_d<13>" LOC = "P11" ; #J1-10
NET "cf_d<12>" LOC = "P15" ; #J1-11
NET "cf_d<11>" LOC = "P16" ; #J1-12
#NET "cf_present" LOC = "P17" ; #J1-13
NET "cf_d<3>" LOC = "P18" ; #J1-14
NET "cf_d<4>" LOC = "P20" ; #J1-15
NET "cf_d<5>" LOC = "P21" ; #J1-16
NET "cf_d<6>" LOC = "P22" ; #J1-17
NET "cf_d<7>" LOC = "P23" ; #J1-18
NET "cf_cs0_n" LOC = "P24" ; #J1-19
#
# For B5-Compact-Flash:
# Connector B
#
NET "cf_a<2>" LOC = "P33" ; #J2-6
NET "cf_a<1>" LOC = "P34" ; #J2-7
NET "cf_a<0>" LOC = "P35" ; #J2-8
NET "cf_d<0>" LOC = "P36" ; #J2-9
NET "cf_d<1>" LOC = "P40" ; #J2-10
NET "cf_d<2>" LOC = "P41" ; #J2-11
NET "cf_cs16_n" LOC = "P42" ; #J2-12
NET "cf_d<10>" LOC = "P43" ; #J2-13
NET "cf_d<9>" LOC = "P44" ; #J2-14
NET "cf_d<8>" LOC = "P45" ; #J2-15
#NET "cf_pdiag" LOC = "P46" ; #J2-16
#NET "cf_dase" LOC = "P47" ; #J2-17
#NET "cf_iordy" LOC = "P48" ; #J2-18
NET "cf_rst_n" LOC = "P49" ; #J2-19
#
# I/O Port
# Connector C
#
#NET "porta<0>" LOC = "p55" ; #pin 3
#NET "porta<1>" LOC = "p56" ; #pin 4
#NET "porta<2>" LOC = "p58" ; #pin 5
#NET "porta<3>" LOC = "p59" ; #pin 6
#NET "porta<4>" LOC = "p60" ; #pin 7
#NET "porta<5>" LOC = "p61" ; #pin 8
#NET "porta<6>" LOC = "p62" ; #pin 8
#NET "porta<7>" LOC = "p63" ; #pin 10
#NET "portb<0>" LOC = "p64" ; #pin 11
#NET "portb<1>" LOC = "p68" ; #pin 12
#NET "portb<2>" LOC = "p69" ; #pin 13
#NET "portb<3>" LOC = "p70" ; #pin 14
#NET "portb<4>" LOC = "p71" ; #pin 15
#NET "portb<5>" LOC = "p73" ; #pin 16
#NET "portb<6>" LOC = "p74" ; #pin 17
#NET "portb<7>" LOC = "p75" ; #pin 18
#NET "timer_out" LOC = "p81" ; #pin 19
#
# For B3-FPGA-CPU-IO
# Connector D
#
#NET "aux_clock" LOC = "p80" ; #pin 2
#NET "buzzer" LOC = "p82" ; #pin 3
NET "led" LOC = "p82" ; #pin 3
#NET "mouse_clock" LOC = "p83" ; #pin 4
#NET "mouse_data" LOC = "p84" ; #pin 5
NET "cts_n" LOC = "p86" ; #pin 6
NET "rts_n" LOC = "p87" ; #pin 7
NET "txbit" LOC = "p88" ; #pin 8
NET "rxbit" LOC = "p89" ; #pin 9
#NET "kb_clock" LOC = "p93" ; #pin 10
#NET "kb_data" LOC = "p94" ; #pin 11
#NET "v_drive" LOC = "p95" ; #pin 12
#NET "h_drive" LOC = "p96" ; #pin 13
#NET "blue_lo" LOC = "p97" ; #pin 14
#NET "blue_hi" LOC = "p98" ; #pin 15
#NET "green_lo" LOC = "p99" ; #pin 16
#NET "green_hi" LOC = "p100"; #pin 17
#NET "red_lo" LOC = "p101"; #pin 18
#NET "red_hi" LOC = "p102"; #pin 19
#
# For modified B3-SRAM
# Connector E
#
NET "ram_addr<0>" LOC = "p108"; #J1.2
NET "ram_addr<1>" LOC = "p109"; #J1.3
NET "ram_addr<2>" LOC = "p110"; #J1.4
NET "ram_addr<3>" LOC = "p111"; #J1.5
NET "ram_addr<4>" LOC = "p112"; #J1.6
NET "ram_addr<5>" LOC = "p113"; #J1.7
NET "ram_addr<6>" LOC = "p114"; #J1.8
NET "ram_addr<7>" LOC = "p115"; #J1.9
NET "ram_csn" LOC = "p116"; #J1.10
NET "ram_addr<8>" LOC = "p120"; #J1.11
NET "ram_addr<9>" LOC = "p121"; #J1.12
NET "ram_addr<10>" LOC = "p122"; #J1.13
NET "ram_addr<11>" LOC = "p123"; #J1.14
NET "ram_addr<12>" LOC = "p125"; #J1.15
NET "ram_addr<13>" LOC = "p126"; #J1.16
NET "ram_addr<14>" LOC = "p127"; #J1.17
NET "ram_addr<15>" LOC = "p129"; #J1.18
NET "ram_addr<16>" LOC = "p132"; #J1.19
#
# For modified B3-SRAM
# Connector F
#
NET "ram_data<0>" LOC = "p133"; #J2.2
NET "ram_data<1>" LOC = "p134"; #J2.3
NET "ram_data<2>" LOC = "p135"; #J2.4
NET "ram_data<3>" LOC = "p136"; #J2.5
NET "ram_data<4>" LOC = "p138"; #J2.6
NET "ram_data<5>" LOC = "p139"; #J2.7
NET "ram_data<6>" LOC = "p140"; #J2.8
NET "ram_data<7>" LOC = "p141"; #J2.9
NET "ram_data<8>" LOC = "p145"; #J2.10
NET "ram_data<9>" LOC = "p146"; #J2.11
NET "ram_data<10>" LOC = "p147"; #J2.12
NET "ram_data<11>" LOC = "p148"; #J2.13
NET "ram_data<12>" LOC = "p149"; #J2.14
NET "ram_data<13>" LOC = "p150"; #J2.15
NET "ram_data<14>" LOC = "p151"; #J2.16
NET "ram_data<15>" LOC = "p152"; #J2.17
NET "ram_wrun" LOC = "p153"; #J2.18
NET "ram_wrln" LOC = "p154"; #J2.19
#
# Connector G
#
#NET "pin2" LOC = "p182"; #pin 2 (clk input)
NET "test_alu<0>" LOC = "p160"; #pin 3
NET "test_alu<1>" LOC = "p161"; #pin 4
NET "test_alu<2>" LOC = "p162"; #pin 5
NET "test_alu<3>" LOC = "p163"; #pin 6
NET "test_alu<4>" LOC = "p164"; #pin 7
NET "test_alu<5>" LOC = "p165"; #pin 8
NET "test_alu<6>" LOC = "p166"; #pin 9
NET "test_alu<7>" LOC = "p167"; #pin 10
NET "test_alu<8>" LOC = "p168"; #pin 11
NET "test_alu<9>" LOC = "p169"; #pin 12
NET "test_alu<10>" LOC = "p173"; #pin 13
NET "test_alu<11>" LOC = "p174"; #pin 14
NET "test_alu<12>" LOC = "p175"; #pin 15
NET "test_alu<13>" LOC = "p176"; #pin 16
NET "test_alu<14>" LOC = "p178"; #pin 17
NET "test_alu<15>" LOC = "p179"; #pin 18
#NET "pin19" LOC = "p180"; #pin 19
#
# Connector H
#
#NET "pin2" LOC = "p185"; #pin 2 (clk input)
#NET "pin3" LOC = "p181"; #pin 3
#NET "uart_csn" LOC = "p187"; #pin 4
#NET "test_rw" LOC = "p188"; #pin 5
#NET "test_d0" LOC = "p189"; #pin 6
#NET "test_d1" LOC = "p191"; #pin 7
#NET "pin8" LOC = "p192"; #pin 8
#NET "pin9" LOC = "p193"; #pin 9
#NET "pin10" LOC = "p194"; #pin 10
NET "test_cc<0>" LOC = "p198"; #pin 11
NET "test_cc<1>" LOC = "p199"; #pin 12
NET "test_cc<2>" LOC = "p200"; #pin 13
NET "test_cc<3>" LOC = "p201"; #pin 14
NET "test_cc<4>" LOC = "p202"; #pin 15
NET "test_cc<5>" LOC = "p203"; #pin 16
NET "test_cc<6>" LOC = "p204"; #pin 17
NET "test_cc<7>" LOC = "p205"; #pin 18
#NET "pin19" LOC = "p206"; #pin 19
#
# Timing Groups
#
INST "ram_addr<0>" TNM = "ram_addr";
INST "ram_addr<1>" TNM = "ram_addr";
INST "ram_addr<2>" TNM = "ram_addr";
INST "ram_addr<3>" TNM = "ram_addr";
INST "ram_addr<4>" TNM = "ram_addr";
INST "ram_addr<5>" TNM = "ram_addr";
INST "ram_addr<6>" TNM = "ram_addr";
INST "ram_addr<7>" TNM = "ram_addr";
INST "ram_addr<8>" TNM = "ram_addr";
INST "ram_addr<9>" TNM = "ram_addr";
INST "ram_addr<10>" TNM = "ram_addr";
INST "ram_addr<11>" TNM = "ram_addr";
INST "ram_addr<12>" TNM = "ram_addr";
INST "ram_addr<13>" TNM = "ram_addr";
INST "ram_addr<14>" TNM = "ram_addr";
INST "ram_addr<15>" TNM = "ram_addr";
INST "ram_addr<16>" TNM = "ram_addr";
INST "ram_data<0>" TNM = "ram_data";
INST "ram_data<1>" TNM = "ram_data";
INST "ram_data<2>" TNM = "ram_data";
INST "ram_data<3>" TNM = "ram_data";
INST "ram_data<4>" TNM = "ram_data";
INST "ram_data<5>" TNM = "ram_data";
INST "ram_data<6>" TNM = "ram_data";
INST "ram_data<7>" TNM = "ram_data";
INST "ram_data<8>" TNM = "ram_data";
INST "ram_data<9>" TNM = "ram_data";
INST "ram_data<10>" TNM = "ram_data";
INST "ram_data<11>" TNM = "ram_data";
INST "ram_data<12>" TNM = "ram_data";
INST "ram_data<13>" TNM = "ram_data";
INST "ram_data<14>" TNM = "ram_data";
INST "ram_data<15>" TNM = "ram_data";
INST "ram_wrln" TNM = "ram_wr";
INST "ram_wrun" TNM = "ram_wr";
INST "ram_csn" TNM = "ram_cs";
INST "test_alu<0>" TNM = "test_alu";
INST "test_alu<1>" TNM = "test_alu";
INST "test_alu<2>" TNM = "test_alu";
INST "test_alu<3>" TNM = "test_alu";
INST "test_alu<4>" TNM = "test_alu";
INST "test_alu<5>" TNM = "test_alu";
INST "test_alu<6>" TNM = "test_alu";
INST "test_alu<7>" TNM = "test_alu";
INST "test_alu<8>" TNM = "test_alu";
INST "test_alu<9>" TNM = "test_alu";
INST "test_alu<10>" TNM = "test_alu";
INST "test_alu<11>" TNM = "test_alu";
INST "test_alu<12>" TNM = "test_alu";
INST "test_alu<13>" TNM = "test_alu";
INST "test_alu<14>" TNM = "test_alu";
INST "test_alu<15>" TNM = "test_alu";
INST "test_cc<0>" TNM = "test_cc";
INST "test_cc<1>" TNM = "test_cc";
INST "test_cc<2>" TNM = "test_cc";
INST "test_cc<3>" TNM = "test_cc";
INST "test_cc<4>" TNM = "test_cc";
INST "test_cc<5>" TNM = "test_cc";
INST "test_cc<6>" TNM = "test_cc";
INST "test_cc<7>" TNM = "test_cc";
#
# Timing Constraints
#
TIMEGRP "ram_cs" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_wr" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_addr" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_data" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_data" OFFSET = IN 15 ns BEFORE "sysclk";
TIMEGRP "test_alu" OFFSET = OUT 90 ns AFTER "sysclk";
TIMEGRP "test_cc" OFFSET = OUT 95 ns AFTER "sysclk";
NET "sysclk" TNM_NET = "sysclk";
TIMESPEC "TS_sysclk" = PERIOD "sysclk" 100 ns LOW 50 %;
#
# Fast I/O Pins
#
NET "ram_addr<0>" FAST;
NET "ram_addr<1>" FAST;
NET "ram_addr<2>" FAST;
NET "ram_addr<3>" FAST;
NET "ram_addr<4>" FAST;
NET "ram_addr<5>" FAST;
NET "ram_addr<6>" FAST;
NET "ram_addr<7>" FAST;
NET "ram_addr<8>" FAST;
NET "ram_addr<9>" FAST;
NET "ram_addr<10>" FAST;
NET "ram_addr<11>" FAST;
NET "ram_addr<12>" FAST;
NET "ram_addr<13>" FAST;
NET "ram_addr<14>" FAST;
NET "ram_addr<15>" FAST;
NET "ram_addr<16>" FAST;
NET "ram_csn" FAST;
NET "ram_data<0>" FAST;
NET "ram_data<1>" FAST;
NET "ram_data<2>" FAST;
NET "ram_data<3>" FAST;
NET "ram_data<4>" FAST;
NET "ram_data<5>" FAST;
NET "ram_data<6>" FAST;
NET "ram_data<7>" FAST;
NET "ram_data<8>" FAST;
NET "ram_data<9>" FAST;
NET "ram_data<10>" FAST;
NET "ram_data<11>" FAST;
NET "ram_data<12>" FAST;
NET "ram_data<13>" FAST;
NET "ram_data<14>" FAST;
NET "ram_data<15>" FAST;
NET "ram_wrln" FAST;
NET "ram_wrun" FAST;
/tags/V10/rtl/vhdl/clkunit2.vhd
0,0 → 1,138
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
 
-- Design units : miniUART core for the System68
--
-- File name : clkunit2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- olupas@opencores.org
--
-- 2.0 John Kent 10 November 2002 Added programmable baud rate
-- 3.0 John Kent 15 December 2002 Fix TX clock divider
-- 3.1 John kent 12 January 2003 Changed divide by 1 for 38.4Kbps
-- 3.3 John Kent 6 September 2003 Changed Clock Edge.
-- dilbert57@opencores.org
-------------------------------------------------------------------------------
-- Description : Generates the Baud clock and enable signals for RX & TX
-- units.
-------------------------------------------------------------------------------
-- Entity for Baud rate generator Unit - 9600 baudrate --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-------------------------------------------------------------------------------
-- Baud rate generator
-------------------------------------------------------------------------------
entity ClkUnit is
port (
Clk : in Std_Logic; -- System Clock
Reset : in Std_Logic; -- Reset input
EnableRx : out Std_Logic; -- Control signal
EnableTx : out Std_Logic; -- Control signal
BaudRate : in Std_Logic_Vector(1 downto 0));
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for Baud rate generator Unit
-------------------------------------------------------------------------------
architecture Behaviour of ClkUnit is
signal tmpEnRx : std_logic;
 
begin
-----------------------------------------------------------------------------
-- Divides the system clock of 40 MHz div 260 gives 153KHz for 9600bps
-- 48 MHz div 156 gives 306KHz for 19.2Kbps
-- 24 MHz div 156 gives 153KHz for 9600bps
-- 9.8304MHz div 32 gives 306KHz for 19.2Kbps
-- 4.9152MHz div 32 gives 153KHz for 9600bps
-----------------------------------------------------------------------------
DivClk : process(Clk,Reset,tmpEnRx, BaudRate)
variable Count : unsigned(7 downto 0);
constant CntOne : Unsigned(7 downto 0):="00000001";
begin
if Clk'event and Clk = '0' then
if Reset = '1' then
Count := "00000000";
tmpEnRx <= '0';
else
if Count = "00000000" then
tmpEnRx <= '1';
case BaudRate is
when "00" =>
-- 6850 divide by 1 ((1*2)-1) (synchronous)
-- miniUart 9.83MHz div 16 = 38.4Kbps
Count := "00001111";
when "01" =>
-- 6850 divide by 16 ((16*2)-1) (9600 Baud)
-- miniUart 9.83MHz div 32 = 19.2Kbps
Count := "00011111";
when "10" =>
-- 6850 divide by 64 ((64*2)-1) (2400 Baud)
-- miniUart 9.83MHz div 128 = 4800bps
Count := "01111111";
when others =>
-- when "11" => -- reset
Count := "00000000";
null;
end case;
else
tmpEnRx <= '0';
Count := Count - CntOne;
end if;
end if;
end if;
EnableRx <= tmpEnRx;
end process;
 
-----------------------------------------------------------------------------
-- Provides the EnableTX signal, at 9.6 KHz
-- Divide by 16
-- Except it wasn't ... it counted up to "10010" (18)
-----------------------------------------------------------------------------
DivClk16 : process(Clk,Reset,tmpEnRX)
variable Cnt16 : unsigned(4 downto 0);
constant CntOne : Unsigned(4 downto 0):="00001";
begin
if Clk'event and Clk = '0' then
if Reset = '1' then
Cnt16 := "00000";
EnableTX <= '0';
else
case Cnt16 is
when "00000" =>
if tmpEnRx = '1' then
Cnt16 := "01111";
EnableTx <='1';
else
Cnt16 := Cnt16;
EnableTx <= '0';
end if;
when others =>
if tmpEnRx = '1' then
Cnt16 := Cnt16 - CntOne;
else
Cnt16 := Cnt16;
end if;
EnableTX <= '0';
end case;
end if;
end if;
end process;
end Behaviour; --==================== End of architecture ===================--
/tags/V10/rtl/vhdl/System09.vhd
0,0 → 1,691
--===========================================================================----
--
-- S Y N T H E Z I A B L E System09 - SOC.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : System09.vhd
--
-- Purpose : Top level file for 6809 compatible system on a chip
-- Designed with Xilinx XC2S300e Spartan 2+ FPGA.
-- Implemented With BurchED B5-X300 FPGA board,
-- B3-SRAM module, B5-CF module and B3-FPGA-CPU-IO module
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : boot_rom (sbug.vhd) Monitor ROM
-- cpu09 (cpu09.vhd) CPU core
-- dat_ram (datram.vhd) Dynamic Address Translation
-- miniuart (minitUART2.vhd) ACIA / MiniUART
-- (rxunit2.vhd)
-- (tx_unit2.vhd)
-- (clkunit2.vhd)
-- timer (timer.vhd) Timer module
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
-- Version 0.1 - 20 March 2003
-- Version 0.2 - 30 March 2003
-- Version 0.3 - 29 April 2003
-- Version 0.4 - 29 June 2003
-- Version 0.5 - 19 July 2003
-- prints out "Hello World"
-- Version 0.6 - 5 September 2003
-- Runs SBUG
-- Version 1.0- 6 Sep 2003 - John Kent
-- Inverted SysClk
-- Initial release to Open Cores
--
--===========================================================================--
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity System09 is
port(
SysClk : in Std_Logic; -- System Clock input
Reset_n : in Std_logic; -- Master Reset input (active low)
LED : out std_logic; -- Diagnostic LED Flasher
 
-- Memory Interface signals
ram_csn : out Std_Logic;
ram_wrln : out Std_Logic;
ram_wrun : out Std_Logic;
ram_addr : out Std_Logic_Vector(16 downto 0);
ram_data : inout Std_Logic_Vector(15 downto 0);
 
-- Stuff on the peripheral board
-- aux_clock : in Std_Logic; -- FPGA-CPU-IO clock
 
-- PS/2 Mouse interface
-- mouse_clock : in Std_Logic;
-- mouse_data : in Std_Logic;
 
-- Uart Interface
rxbit : in Std_Logic;
txbit : out Std_Logic;
rts_n : out Std_Logic;
cts_n : in Std_Logic;
 
-- CRTC output signals
-- v_drive : out Std_Logic;
-- h_drive : out Std_Logic;
-- blue_lo : out std_logic;
-- blue_hi : out std_logic;
-- green_lo : out std_logic;
-- green_hi : out std_logic;
-- red_lo : out std_logic;
-- red_hi : out std_logic;
-- buzzer : out std_logic;
 
-- Compact Flash
cf_rst_n : out std_logic;
cf_cs0_n : out std_logic;
cf_cs1_n : out std_logic;
cf_rd_n : out std_logic;
cf_wr_n : out std_logic;
cf_cs16_n : out std_logic;
cf_a : out std_logic_vector(2 downto 0);
cf_d : inout std_logic_vector(15 downto 0);
 
-- Parallel I/O port
-- porta : inout std_logic_vector(7 downto 0);
-- portb : inout std_logic_vector(7 downto 0);
-- timer_out : out std_logic;
 
-- Test Pins
test_alu : out std_logic_vector(15 downto 0);
test_cc : out std_logic_vector(7 downto 0)
);
end System09;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture my_computer of System09 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- BOOT ROM
signal rom_data_out : Std_Logic_Vector(7 downto 0);
 
-- UART Interface signals
signal uart_data_out : Std_Logic_Vector(7 downto 0);
signal uart_cs : Std_Logic;
signal uart_irq : Std_Logic;
 
-- timer
-- signal timer_data_out : std_logic_vector(7 downto 0);
-- signal timer_cs : std_logic;
-- signal timer_irq : std_logic;
 
-- Parallel I/O port
-- signal ioport_data_out : std_logic_vector(7 downto 0);
-- signal ioport_cs : std_logic;
 
-- compact flash port
signal cf_data_out : std_logic_vector(7 downto 0);
signal cf_cs : std_logic;
signal cf_rd : std_logic;
signal cf_wr : std_logic;
 
-- RAM
signal ram_cs : std_logic; -- memory chip select
signal ram_wrl : std_logic; -- memory write lower
signal ram_wru : std_logic; -- memory write upper
signal ram_data_out : std_logic_vector(7 downto 0);
 
-- CPU Interface signals
signal cpu_reset : Std_Logic;
signal cpu_clk : Std_Logic;
signal cpu_rw : std_logic;
signal cpu_vma : std_logic;
signal cpu_halt : std_logic;
signal cpu_hold : std_logic;
signal cpu_firq : std_logic;
signal cpu_irq : std_logic;
signal cpu_nmi : std_logic;
signal cpu_addr : std_logic_vector(15 downto 0);
signal cpu_data_in : std_logic_vector(7 downto 0);
signal cpu_data_out: std_logic_vector(7 downto 0);
 
-- Dynamic address translation
signal dat_cs : std_logic;
signal dat_addr : std_logic_vector(7 downto 0);
 
-- Boot ROM Map switch
-- signal map_cs : Std_Logic;
-- signal map_sw : Std_Logic;
 
-- synchronous RAM
-- signal xram_data_out : std_logic_vector(7 downto 0);
-- signal xram_cs : std_logic;
 
-- Flashing Led test signals
signal countL : std_logic_vector(23 downto 0);
 
-----------------------------------------------------------------
--
-- CPU09 CPU core
--
-----------------------------------------------------------------
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component;
 
-----------------------------------------------------------------
--
-- Open Cores Mini UART
--
-----------------------------------------------------------------
 
component miniUART
port (
SysClk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input
cs : in Std_Logic;
rw : in Std_Logic;
RxD : in Std_Logic;
TxD : out Std_Logic;
CTS_n : in Std_Logic;
RTS_n : out Std_Logic;
Irq : out Std_logic;
Addr : in Std_Logic;
DataIn : in Std_Logic_Vector(7 downto 0); --
DataOut : out Std_Logic_Vector(7 downto 0)); --
end component;
 
----------------------------------------
--
-- Timer module
--
----------------------------------------
 
--component timer
-- port (
-- clk : in std_logic;
-- rst : in std_logic;
-- cs : in std_logic;
-- rw : in std_logic;
-- addr : in std_logic;
-- data_in : in std_logic_vector(7 downto 0);
-- data_out : out std_logic_vector(7 downto 0);
-- irq : out std_logic;
-- timer_in : in std_logic;
-- timer_out : out std_logic
-- );
--end component;
 
----------------------------------------
--
-- Dual 8 bit Parallel I/O module
--
----------------------------------------
--component ioport
-- port (
-- clk : in std_logic;
-- rst : in std_logic;
-- cs : in std_logic;
-- rw : in std_logic;
-- addr : in std_logic_vector(1 downto 0);
-- data_in : in std_logic_vector(7 downto 0);
-- data_out : out std_logic_vector(7 downto 0);
-- porta_io : inout std_logic_vector(7 downto 0);
-- portb_io : inout std_logic_vector(7 downto 0)
-- );
--end component;
 
----------------------------------------
--
-- SBUG Slice Monitor ROM
--
----------------------------------------
component boot_rom
port (
addr : in Std_Logic_Vector(10 downto 0); -- 2K byte boot rom
data : out Std_Logic_Vector(7 downto 0));
end component;
 
----------------------------------------
--
-- SBUG Block RAM Monitor ROM
--
----------------------------------------
--component sbug_rom
-- Port (
-- MEMclk : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0)
-- );
--end component;
 
----------------------------------------
--
-- Dynamic Address Translation Registers
--
----------------------------------------
component dat_ram
port (
clk: in std_logic;
rst: in std_logic;
cs: in std_logic;
rw: in std_logic;
addr_lo: in std_logic_vector(3 downto 0);
addr_hi: in std_logic_vector(3 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0)
);
end component;
 
----------------------------------------
--
-- Block RAM module
--
----------------------------------------
-- component block_ram
-- Port (
-- MEMclk : in std_logic;
-- MEMcs : in std_logic;
-- MEMrw : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0);
-- MEMwdata : in std_logic_vector (7 downto 0)
-- );
--end component;
 
 
-- component BUFG
-- port (
-- i: in std_logic;
-- o: out std_logic
-- );
-- end component;
 
begin
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
my_cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => cpu_halt,
hold => cpu_hold,
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => test_alu,
test_cc => test_cc
);
 
 
my_uart : miniUART port map (
SysClk => SysClk,
rst => cpu_reset,
cs => uart_cs,
rw => cpu_rw,
RxD => rxbit,
TxD => txbit,
CTS_n => cts_n,
RTS_n => rts_n,
Irq => uart_irq,
Addr => cpu_addr(0),
Datain => cpu_data_out,
DataOut => uart_data_out
);
 
--my_timer : timer port map (
-- clk => SysClk,
-- rst => cpu_reset,
-- cs => timer_cs,
-- rw => cpu_rw,
-- addr => cpu_addr(0),
-- data_in => cpu_data_out,
-- data_out => timer_data_out,
-- irq => timer_irq,
-- timer_in => CountL(5),
-- timer_out => timer_out
-- );
 
--my_ioport : ioport port map (
-- clk => SysClk,
-- rst => cpu_reset,
-- cs => ioport_cs,
-- rw => cpu_rw,
-- addr => cpu_addr(1 downto 0),
-- data_in => cpu_data_out,
-- data_out => ioport_data_out,
-- porta_io => porta,
-- portb_io => portb
-- );
 
my_rom : boot_rom port map (
addr => cpu_addr(10 downto 0),
data => rom_data_out
);
 
--my_rom : sbug_rom port map (
-- MEMclk => SysClk,
-- MEMaddr => cpu_addr(10 downto 0),
-- MEMrdata => rom_data_out
-- );
 
my_dat : dat_ram port map (
clk => SysClk,
rst => cpu_reset,
cs => dat_cs,
rw => cpu_rw,
addr_hi => cpu_addr(15 downto 12),
addr_lo => cpu_addr(3 downto 0),
data_in => cpu_data_out,
data_out => dat_addr(7 downto 0)
);
 
--my_ram : block_ram port map (
-- MEMclk => SysClk,
-- MEMcs => xram_cs,
-- MEMrw => cpu_rw,
-- MEMaddr => cpu_addr(10 downto 0),
-- MEMwdata => cpu_data_out,
-- MEMrdata => xram_data_out
-- );
 
-- clk_buffer : BUFG port map(
-- i => e_clk,
-- o => cpu_clk
-- );
----------------------------------------------------------------------
--
-- Process to decode memory map
--
----------------------------------------------------------------------
 
mem_decode: process( SysClk, Reset_n,
cpu_addr, cpu_rw, cpu_vma,
dat_cs, dat_addr,
-- map_cs, map_sw,
rom_data_out, ram_data_out,
-- xram_data_out,
cf_data_out,
-- timer_data_out, ioport_data_out,
uart_data_out )
begin
case cpu_addr(15 downto 11) is
--
-- SBUG Monitor ROM $F800 - $FFFF
--
when "11111" => -- $F800 - $FFFF
cpu_data_in <= rom_data_out; -- read ROM
dat_cs <= cpu_vma; -- write DAT
ram_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= '0';
-- map_cs <= '0';
 
--
-- Shadow RAM Monitor switch
--
-- when "11101" => -- $E800 - $EFFF
-- when "11111" => -- $F800 - $FFFF
-- if map_sw = '1' then
-- cpu_data_in <= rom_data_out; -- read ROM
-- dat_cs <= '0'; -- disable write to DAT
-- ram_cs <= cpu_vma; -- enable write to RAM
-- else
-- cpu_data_in <= ram_data_out; -- read RAM
-- dat_cs <= cpu_vma; -- enable write DAT
-- ram_cs <= cpu_vma and cpu_rw; -- disable write to RAM
-- end if;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= cpu_vma;
-- map_cs <= '0';
 
--
-- Synchronous Block RAM $F000 - $F7FF
--
-- when "11110" => -- $F000 - $F7FF
-- cpu_data_in <= xram_data_out;
-- dat_cs <= '0';
-- ram_cs <= '0';
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= cpu_vma;
-- map_cs <= '0';
 
--
-- IO Devices $E000 - $E7FF
--
when "11100" => -- $E000 - $E7FF
dat_cs <= '0';
ram_cs <= '0';
-- xram_cs <= '0';
case cpu_addr(7 downto 4) is
--
-- UART / ACIA $E000
--
when "0000" => -- $E000
cpu_data_in <= uart_data_out;
uart_cs <= cpu_vma;
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= '0';
--
-- Compact Flash $E010 - $E01F
--
when "0001" => -- $E010
cpu_data_in <= cf_data_out;
uart_cs <= '0';
cf_cs <= cpu_vma;
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= '0';
--
-- Timer $E020 - $E02F
--
-- when "0010" => -- $E020
-- cpu_data_in <= timer_data_out;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= cpu_vma;
-- ioport_cs <= '0';
-- map_cs <= '0';
 
--
-- ROM Map switch $E030
--
-- when "0011" => -- $E030
-- cpu_data_in <= "00000000";
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= cpu_vma;
 
--
-- I/O port $E040 - $E04F
--
-- when "0100" => -- $E040
-- cpu_data_in <= ioport_data_out;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= cpu_vma;
-- map_cs <= '0';
 
when others => -- $E040 to $E7FF
cpu_data_in <= "00000000";
uart_cs <= '0';
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= '0';
end case;
--
-- Everything else is RAM
--
when others =>
cpu_data_in <= ram_data_out;
ram_cs <= cpu_vma;
dat_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= '0';
-- map_cs <= '0';
end case;
end process;
 
--
-- B3-SRAM Control
-- Processes to read and write memory based on bus signals
--
ram_process: process( SysClk, Reset_n,
cpu_addr, cpu_rw, cpu_vma, cpu_data_out,
dat_addr,
ram_cs, ram_wrl, ram_wru, ram_data_out )
begin
ram_csn <= not( ram_cs and Reset_n );
ram_wrl <= (not dat_addr(5)) and (not cpu_rw) and SysClk;
ram_wrln <= not (ram_wrl);
ram_wru <= dat_addr(5) and (not cpu_rw) and SysClk;
ram_wrun <= not (ram_wru);
ram_addr(16 downto 12) <= dat_addr(4 downto 0);
ram_addr(11 downto 0) <= cpu_addr(11 downto 0);
 
if ram_wrl = '1' then
ram_data(7 downto 0) <= cpu_data_out;
else
ram_data(7 downto 0) <= "ZZZZZZZZ";
end if;
 
if ram_wru = '1' then
ram_data(15 downto 8) <= cpu_data_out;
else
ram_data(15 downto 8) <= "ZZZZZZZZ";
end if;
 
if dat_addr(5) = '1' then
ram_data_out <= ram_data(15 downto 8);
else
ram_data_out <= ram_data(7 downto 0);
end if;
end process;
 
--
-- Compact Flash Control
--
compact_flash: process( SysClk, Reset_n,
cpu_addr, cpu_rw, cpu_vma, cpu_data_out,
cf_cs, cf_rd, cf_wr, cf_data_out )
begin
cf_rst_n <= Reset_n;
cf_cs0_n <= not( cf_cs ) or cpu_addr(3);
cf_cs1_n <= not( cf_cs and cpu_addr(3));
cf_cs16_n <= '1';
cf_wr <= cf_cs and (not cpu_rw);
cf_rd <= cf_cs and cpu_rw;
cf_wr_n <= not cf_wr;
cf_rd_n <= not cf_rd;
cf_a <= cpu_addr(2 downto 0);
if cf_wr = '1' then
cf_d(7 downto 0) <= cpu_data_out;
else
cf_d(7 downto 0) <= "ZZZZZZZZ";
end if;
cf_data_out <= cf_d(7 downto 0);
cf_d(15 downto 8) <= "ZZZZZZZZ";
end process;
 
--
-- ROM Map switch
-- The Map switch output is initially set
-- On a Write to the Map Switch port, clear the Map Switch
-- and map the RAM in place of the boot ROM.
--
--map_proc : process( SysClk, Reset_n, map_cs, cpu_rw )
--begin
-- if SysClk'event and SysClk = '0' then
-- if Reset_n = '0' then
-- map_sw <= '1';
-- else
-- if (map_cs = '1') and (cpu_rw = '0') then
-- map_sw <= '0';
-- else
-- map_sw <= map_sw;
-- end if;
-- end if;
-- end if;
--end process;
 
--
-- Interrupts and other bus control signals
--
interrupts : process( Reset_n, uart_irq
-- ,timer_irq
)
begin
cpu_reset <= not Reset_n; -- CPU reset is active high
cpu_irq <= uart_irq;
-- cpu_nmi <= timer_irq;
cpu_nmi <= '0';
cpu_firq <= '0';
cpu_halt <= '0';
cpu_hold <= '0';
end process;
 
--
-- flash led to indicate code is working
--
increment: process (SysClk, CountL )
begin
if(SysClk'event and SysClk = '0') then
countL <= countL + 1;
end if;
LED <= countL(21);
end process;
end my_computer; --===================== End of architecture =======================--
 
/tags/V10/doc/SBUG_Listing.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/V10/doc/SBUG_Listing.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/V10/doc/SBUG_UsersGuide.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/V10/doc/SBUG_UsersGuide.pdf =================================================================== --- tags/V10/doc/SBUG_UsersGuide.pdf (nonexistent) +++ tags/V10/doc/SBUG_UsersGuide.pdf (revision 3)
tags/V10/doc/SBUG_UsersGuide.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/V10/sw/sbug_src.s19 =================================================================== --- tags/V10/sw/sbug_src.s19 (nonexistent) +++ tags/V10/sw/sbug_src.s19 (revision 3) @@ -0,0 +1,65 @@ +S123F800F814F861FDCFFDC9FDDFFDEEFDBDFDB1FDADFB818EFE4F108EDFC0C610A680A7DD +S123F820A05A26F98EE004BFDFE017027AC60C6FE25A26FB308CDDAF6A86D0A7E41F43177E +S123F84005BE8EFE5F1705758EDFD04FC60D6D8527038B04195A2AF61705268EFE7417056A +S123F8605C8EFE7B170546170565847F810D27F11F8981202C09865E1705731F988B40170B +S123F880056C170567C1602F02C0208EFE13E180270F30028CFE4F26F58EFE7D17051E207F +S123F8A0C0AD9420BC1F343B8EFE831704FF1704111704191704211704291704318EFE8375 +S123F8C01704EA17043317043A1704411604481704271705171704572902AF4A391703ED73 +S123F8E01705091704492902AF48391704001704FB17043B2902AF46391703E71704ED1720 +S123F900042D2902AF44391703CE1704DF1704302902A743391703F51704D117042229027D +S123F920A742391703DD1704C31704142902A741391703E31704B517040629048A80A7C4C1 +S123F940391703EB292D1F128EFE8317045F1F21170426170496A6A417042617048E1703D5 +S123F960DF2811810827E1811827DD815E2717810D260F39A7A4A1A4270817046F863F17FF +S123F980046C312120C2313F20BE1703351F328EDFC0301F200517038B29063420ACE12457 +S123F9A001391F10C30010C4F034061F20C4F01F01ACE42705170427270332623934108E3F +S123F9C0FE831703E8AEE41703AFC610A6801703B01704185A26F5170410AEE1C610A68021 +S123F9E081202504817E2302862E1704015A26EE20BF6FE26FE217032B3430297BAC6225D6 +S123FA00771703E81F20E3643404ABE0A7A010ACE425F110AE621F20E3643402EBE0E8A0F4 +S123FA20273C8EFE83170385303F17034C34108EFEA1170388351017014717035017033968 +S123FA408EFE87170377AE6417032E8EFE8F17036C1F988EFEA617033E170383261A10AC29 +S123FA60E425B3862B170386170374260B10AE626C6526906C64268C3266391702B1291EAB +S123FA808CDFC0241A34108EFFFF8D553510270FA684813F2709A7A0AFA4863FA7843917D8 +S123FAA0034A863F160347108EDFE3C6088D185A26FB391F43AE4A301F8D262704AF4A8D3C +S123FAC00617FDE416FD9AAE218CDFC0240AA684813F2604A6A4A78486FFA7A0A7A0A7A06C +S123FAE039108EDFE3C608A6A0ACA127045A26F739313D3986DEB7F02486FFB7F014B7F070 +S123FB0010B7F015B7F0167DF01086D8B7F020170097B6F0202BFB8609B7F02017008AB66F +S123FB20F020850126F9851026CA8EC0008D528A10B7F0401F104353FDF0008EFEFFBFF0ED +S123FB400286FFB7F01086FEB7F0148601B7F022868CB7F0208D525F34045F7DF0102A0A75 +S123FB605A26F835045A26F0208A3504B6F020851C270139C6DEF7F0248EC000AF4A1F346C +S123FB803B3436A66244444444108EDFD0E6A654545454E7E4E6A65358585858A662840FD6 +S123FBA0A762EA62E7623536393404C6205A26FD3504397DE0187FE014C6038E0000300182 +S123FBC08C000026F95A26F6860FB7E0188D37F6E018C50126F98601B7E01A8D29868CB76E +S123FBE0E0188D228EC0002009C5022705B6E01BA780F6E018C50126F0C52C2701398EC0AE +S123FC0000AF4A1F343BC6205A26FD3986111701DD7FDFE21701AD815326F91701A68139C1 +S123FC20273D813126F1170117340229261700FF29213410E6E0EBE0EBE46AE46AE4340407 +S123FC401700FD3504290C3402EBE06AE42705A78020EB5F3502C1FF27B2863F17018F7363 +S123FC60DFE286131601876FE21700B83430294AAC6225463001AFE48612170171ECE4A3C0 +S123FC80622706108300202302C620E7648EFEEB17011ACB031F981700E7AE621700DAEBB0 +S123FCA062EB63EB84A6801700D76A6426F5531F981700CDAF62ACE426C3861417012F3299 +S123FCC065398EFEAE1700F51F311600AC8EFEBA1700EAAE481600A18EFECC1700DFA643FF +S123FCE016009E8EFEC61700D4AE4416008B8EFEC01700C9AE461600808EFEB41700BEAE03 +S123FD004A20768EFED21700B4A64120748EFED71700AAA642206A8EFEDC1700A0A6C48EAE +S123FD20FEE320738D09294E1F12862D1700BF8D0F29431F018D09293D3410A76135103996 +S123FD408D112932484848481F898D0729283404ABE0398D6F8130251D8139220380303946 +S123FD60814125128146220380373981612507816622038057391A0239341035028D0235EC +S123FD80023402444444448D043502840F8B3081392F028B0720573402C608A68068E42572 +S123FDA002862D8D498D455A26F13502398D02200C34108EFE758D053510398D31A680818C +S123FDC00426F8397DDFE227068D04847F201F3410BEDFE0A684850127FAA601351039349B +S123FDE002A69FDFE085013502398D0086203412BEDFE0A684850227FA3502A701351039DE +S123FE00BEDFE08603A7848611A7846D0186FFB7DFE23901F92302F91503F93104F90710D9 +S123FE20F8CF15F8DD18F8F919F8EB42FA7B44FAF445F99647F8A54CFC0C4DF94150FC67D9 +S123FE4051F9F252F8A853F98A55FBB358FAA7FAB3F8A7F8A7F8A7F8A7FAB3FFFFFFFF00CC +S123FE6000000D0A000000532D42554720312E38202D20044B0D0A000000043E0457484159 +S123FE80543F04202D20042C205041535320042C204249545320494E204552524F523A2076 +S123FEA004203D3E20043736353433323130202053503D04202050433D04202055533D047E +S123FEC0202049593D04202049583D04202044503D042020413D042020423D042020434379 +S120FEE03A2004454648494E5A5643533104FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S123FF008EFFF0860FA7804A26FB86F0A7848ED0A0108E55AAEE8410AF8410AC84270B30A6 +S123FF2089F0008CF0A026ED20D6EF841F104344444444B7FFFD10CEDFC0108EDFD0A72DD9 +S123FF406F2E86F0A72F860C6FA64A2AFB3089F0008CF0A02722EE84108E55AA10AF84102E +S123FF60AC8426E9EF84108EDFD01F10444444441F89880FA7A520D586F1108EDFD0A72E26 +S123FF80860CE6A626054A2AF920146FA6E72C4F1F21E6A627046FA6E7804C810C2DF38E02 +S123FFA0FFF0C610A6A0A7805A26F953F7DFE216F8626E9FDFC06E9FDFC46E9FDFC66E9FFC +S123FFC0DFC86E9FDFCA1F43AE4AE680AF4A4F5849BEDFCC8CFFFF270F308BBCDFCE2208A0 +S123FFE03410ECC4AE446EF1371FEE426E9FDFC2FFB2FFC6FFB6FFBAFFBEFFC2FFB2FF0072 +S9030000FC Index: tags/V10/sw/sbug_src.txt =================================================================== --- tags/V10/sw/sbug_src.txt (nonexistent) +++ tags/V10/sw/sbug_src.txt (revision 3) @@ -0,0 +1,1402 @@ +* NAM SBUG18 MP-09 MONITOR + OPT l + PAGE +* +* MONITOR PROGRAM FOR THE SOUTHWEST TECHNICAL +* PRODUCTS MP-09 CPU BOARD AS COMMENTED BY.... +* +* ALLEN CLARK WALLACE WATSON +* 2502 REGAL OAKS LANE 4815 EAST 97th AVE. +* LUTZ, FLA. 33549 TEMPLE TERRACE, FLA. 33617 +* PH. 813-977-0347 PH. 813-985-1359 +* +* MODIFIED TO SBUG09 VER 1.8 BY: RANDY JARRETT +* 2561 NANTUCKET DR APT. E +* ATLANTA, GA 30345 +* PH. 404-320-1043 +* +* +* *** COMMANDS *** +* +* CONTROL A = ALTER THE "A" ACCUMULATOR +* CONTROL B = ALTER THE "B" ACCUMULATOR +* CONTROL C = ALTER THE CONDITION CODE REGISTER +* CONTROL D = ALTER THE DIRECT PAGE REGISTER +* CONTROL P = ALTER THE PROGRAM COUNTER +* CONTROL U = ALTER USER STACK POINTER +* CONTROL X = ALTER "X" INDEX REGISTER +* CONTROL Y = ALTER "Y" INDEX REGISTER +* B hhhh = SET BREAKPOINT AT LOCATION $hhhh +* D = BOOT A SWTPC 8 INCH FLOPPY SYSTEM +* U = BOOT A SWTPC 5 INCH FLOPPY SYSTEM +* E ssss-eeee = EXAMINE MEMORY FROM STARTING ADDRESS ssss +* -TO ENDING ADDRESS eeee. +* G = CONTINUE EXECUTION FROM BREAKPOINT OR SWI +* L = LOAD TAPE +* M hhhh = EXAMINE AND CHANGE MEMORY LOCATION hhhh +* P ssss-eeee = PUNCH TAPE, START ssss TO END eeee ADDR. +* Q ssss-eeee = TEST MEMORY FROM ssss TO eeee +* R = DISPLAY REGISTER CONTENTS +* S = DISPLAY STACK FROM ssss TO $DFC0 +* X = REMOVE ALL BREAKPOINTS +* +* +TSTPAT EQU $55AA TEST PATTERN +* +* +* + ORG $DFC0 +STACK RMB 2 TOP OF INTERNAL STACK / USER VECTOR +SWI3 RMB 2 SOFTWARE INTERRUPT VECTOR #3 +SWI2 RMB 2 SOFTWARE INTERRUPT VECTOR #2 +FIRQ RMB 2 FAST INTERRUPT VECTOR +IRQ RMB 2 INTERRUPT VECTOR +SWI RMB 2 SOFTWARE INTERRUPT VECTOR +SVCVO RMB 2 SUPERVISOR CALL VECTOR ORGIN +SVCVL RMB 2 SUPERVISOR CALL VECTOR LIMIT +LRARAM RMB 16 LRA ADDRESSES +CPORT RMB 2 RE-VECTORABLE CONTROL PORT +ECHO RMB 1 ECHO FLAG +BPTBL RMB 24 BREAKPOINT TABLE BASE ADDR +ACIAS EQU $E004 CONTROL PORT +Comreg EQU $E018 COMMAND REGISTER +Drvreg EQU $E014 DRIVE REGISTER +Secreg EQU $E01A SECTOR REGISTER +Datreg EQU $E01B DATA REGISTER +* +ADDREG EQU $F000 ADDRESS REGISTER +CNTREG EQU $F002 COUNT REGISTER +CCREG EQU $F010 CHANNEL CONTROL REGISTER +PRIREG EQU $F014 DMA PRIORITY REGISTER +AAAREG EQU $F015 ??? +BBBREG EQU $F016 ??? +COMREG EQU $F020 1791 COMMAND REGISTER +SECREG EQU $F022 SECTOR REGISTER +DRVREG EQU $F024 DRIVE SELECT LATCH +CCCREG EQU $F040 ??? +* +IC11 EQU $FFF0 DAT RAM CHIP +* + ORG $F800 + FDB MONITOR + FDB NEXTCMD + FDB INCH + FDB INCHE + FDB INCHEK + FDB OUTCH + FDB PDATA + FDB PCRLF + FDB PSTRNG + FDB LRA +* +* MONITOR +* +* VECTOR ADDRESS STRING IS..... +* $F8A1-$F8A1-$F8A1-$F8A1-$F8A1-$FAB0-$FFFF-$FFFF +* +MONITOR LDX #RAMVEC POINT TO VECTOR ADDR. STRING + LDY #STACK POINT TO RAM VECTOR LOCATION + LDB #$10 BYTES TO MOVE = 16 +LOOPA LDA ,X+ GET VECTOR BYTE + STA ,Y+ PUT VECTORS IN RAM / $DFC0-$DFCF + DECB SUBTRACT 1 FROM NUMBER OF BYTES TO MOVE + BNE LOOPA CONTINUE UNTIL ALL VECTORS MOVED +* +* CONTENTS FROM TO FUNCTION +* $F8A1 $FE40 $DFC0 USER-V +* $F8A1 $FE42 $DFC2 SWI3-V +* $F8A1 $FE44 $DFC4 SWI2-V +* $F8A1 $FE46 $DFC6 FIRQ-V +* $F8A1 $FE48 $DFC8 IRQ-V +* $FAB0 $FE4A $DFCA SWI-V +* $FFFF $FE4C $DFCC SVC-VO +* $FFFF $FE4E $DFCE SVC-VL +* + LDX #ACIAS GET CONTROL PORT ADDR. + STX CPORT STORE ADDR. IN RAM + LBSR XBKPNT CLEAR OUTSTANDING BREAKPOINTS + LDB #12 CLEAR 12 BYTES ON STACK +CLRSTK CLR ,-S + DECB + BNE CLRSTK + LEAX MONITOR,PCR SET PC TO SBUG-E ENTRY + STX 10,S ON STACK + LDA #$D0 PRESET CONDITION CODES ON STACK + STA ,S + TFR S,U + LBSR ACINIZ INITIALIZE CONTROL PORT + LDX #MSG1 POINT TO 'SBUG 1.8' MESSAGE + LBSR PDATA PRINT MSG + LDX #LRARAM POINT TO LRA RAM STORAGE AREA + CLRA START TOTAL AT ZERO + LDB #13 TOTAL UP ALL ACTIVE RAM MEMORY +FNDREL TST B,X TEST FOR RAM AT NEXT LOC. + BEQ RELPAS IF NO RAM GO TO NEXT LOC. + ADDA #4 ELSE ADD 4K TO TOTAL + DAA ADJ. TOTAL FOR DECIMAL +RELPAS DECB SUB. 1 FROM LOCS. TO TEST + BPL FNDREL PRINT TOTAL OF RAM + LBSR OUT2H OUTPUT HEX BYTE AS ASCII + LDX #MSG2 POINT TO MSG 'K' CR/LF + 3 NULS + LBSR PDATA PRINT MSG +* +***** NEXTCMD ***** +* +NEXTCMD LDX #MSG3 POINT TO MSG ">" + LBSR PSTRNG PRINT MSG + LBSR INCH GET ONE CHAR. FROM TERMINAL + ANDA #$7F STRIP PARITY FROM CHAR. + CMPA #$0D IS IT CARRIAGE RETURN ? + BEQ NEXTCMD IF CR THEN GET ANOTHER CHAR. + TFR A,B PUT CHAR. IN "B" ACCUM. + CMPA #$20 IS IT CONTROL OR DATA CHAR ? + BGE PRTCMD IF CMD CHAR IS DATA, PRNT IT + LDA #'^ ELSE CNTRL CHAR CMD SO... + LBSR OUTCH PRINT "^" + TFR B,A RECALL CNTRL CMD CHAR + ADDA #$40 CONVERT IT TO ASCII LETTER +PRTCMD LBSR OUTCH PRNT CMD CHAR + LBSR OUT1S PRNT SPACE + CMPB #$60 + BLE NXTCH0 + SUBB #$20 +* +* +***** DO TABLE LOOKUP ***** +* FOR COMMAND FUNCTIONS +* +* +NXTCH0 LDX #JMPTAB POINT TO JUMP TABLE +NXTCHR CMPB ,X+ DOES COMMAND MATCH TABLE ENTRY ? + BEQ JMPCMD BRANCH IF MATCH FOUND + LEAX 2,X POINT TO NEXT ENTRY IN TABLE + CMPX #TABEND REACHED END OF TABLE YET ? + BNE NXTCHR IF NOT END, CHECK NEXT ENTRY + LDX #MSG4 POINT TO MSG "WHAT?" + LBSR PDATA PRINT MSG + BRA NEXTCMD IF NO MATCH, PRMPT FOR NEW CMD +JMPCMD JSR [,X] JUMP TO COMMAND ROUTINE + BRA NEXTCMD PROMPT FOR NEW COMMAND +* +* "G" GO OR CONTINUE +* +GO TFR U,S +RTI RTI +* +* "R" DISPLAY REGISTERS +* +REGSTR LDX #MSG5 POINT TO MSG " - " + LBSR PSTRNG PRINT MSG + LBSR PRTSP $FCBF + LBSR PRTUS $FCCA + LBSR PRTDP $FCD5 + LBSR PRTIX $FCE0 + LBSR PRTIY $FCEB + LDX #MSG5 POINT TO MSG " - " + LBSR PSTRNG PRINT MSG + LBSR PRTPC $FCF5 + LBSR PRTA $FCFF + LBSR PRTB $FD09 + LBRA PRTCC $FD13 +* +* +* ALTER "PC" PROGRAM COUNTER +* +* +ALTRPC LBSR PRTPC $FCF5 PRINT MSG " PC = " + LBSR OUT1S OUTPUT SPACE + LBSR IN1ADR GET NEW CONTENTS FOR "PC" + BVS ALTPCD EXIT IF INVALID HEX + STX 10,U POKE IN NEW CONTENTS +ALTPCD RTS ; +* +* +* ALTER "U" USER STACK POINTER +* +* +ALTRU LBSR PRTUS $FCCA PRINT MSG " US = " + LBSR OUT1S OUTPUT SPACE + LBSR IN1ADR + BVS ALTUD + STX 8,U +ALTUD RTS ; +* +* +* ALTER "Y" INDEX REGISTER +* +* +ALTRY LBSR PRTIY PRINT MSG " IY = " + LBSR OUT1S OUTPUT SPACE + LBSR IN1ADR + BVS ALTYD + STX 6,U $F8F0 +ALTYD RTS ; +* +* +* ALTER "X" INDEX REGISTER +* +* +ALTRX LBSR PRTIX $FCE0 PRINT MSG " IX = " + LBSR OUT1S OUTPUT SPACE + LBSR IN1ADR + BVS ALTXD + STX 4,U +ALTXD RTS ; +* +* +* ALTER "DP" DIRECT PAGE REGISTER +* +* +ALTRDP LBSR PRTDP $FCD5 PRINT MSG " DP = " + LBSR OUT1S OUTPUT SPACE + LBSR BYTE INPUT BYTE (2 HEX CHAR) + BVS ALTDPD + STA 3,U +ALTDPD RTS ; +* +* +* ALTER "B" ACCUMULATOR +* +* +ALTRB LBSR PRTB $FD09 PRINT MSG " B = " + LBSR OUT1S OUTPUT SPACE + LBSR BYTE INPUT BYTE (2 HEX CHAR) + BVS ALTBD + STA 2,U +ALTBD RTS $F91C +* +* +* ALTER "A" ACCUMULATOR +* +* +ALTRA LBSR PRTA $FCFF RINT MSG " A = " + LBSR OUT1S OUTPUT SPACE + LBSR BYTE INPUT BYTE (2 HEX CHAR) + BVS ALTAD + STA 1,U +ALTAD RTS ; +* +* +* ALTER "CC" REGISTER +* +* +ALTRCC LBSR PRTCC $FD13 PRINT MSG " CC: " + LBSR OUT1S OUTPUT SPACE + LBSR BYTE INPUT BYTE (2 HEX CHAR) + BVS ALTCCD + ORA #$80 SETS "E" FLAG IN PRINT LIST + STA ,U +ALTCCD RTS ; +* +***** "M" MEMORY EXAMINE AND CHANGE ***** +* +MEMCHG LBSR IN1ADR INPUT ADDRESS + BVS CHRTN IF NOT HEX, RETURN + TFR X,Y SAVE ADDR IN "Y" +MEMC2 LDX #MSG5 POINT TO MSG " - " + LBSR PSTRNG PRINT MSG + TFR Y,X FETCH ADDRESS + LBSR OUT4H PRINT ADDR IN HEX + LBSR OUT1S OUTPUT SPACE + LDA ,Y GET CONTENTS OF CURRENT ADDR. + LBSR OUT2H OUTPUT CONTENTS IN ASCII + LBSR OUT1S OUTPUT SPACE + LBSR BYTE LOOP WAITING FOR OPERATOR INPUT + BVC CHANGE IF VALID HEX GO CHANGE MEM. LOC. + CMPA #8 IS IT A BACKSPACE (CNTRL H)? + BEQ MEMC2 PROMPT OPERATOR AGAIN + CMPA #$18 IS IT A CANCEL (CNTRL X)? + BEQ MEMC2 PROMPT OPERATOR AGAIN + CMPA #'^ IS IT AN UP ARROW? + BEQ BACK DISPLAY PREVIOUS BYTE + CMPA #$D IS IT A CR? + BNE FORWRD DISPLAY NEXT BYTE +CHRTN RTS EXIT ROUTINE +* +* +CHANGE STA ,Y CHANGE BYTE IN MEMORY + CMPA ,Y DID MEMORY BYTE CHANGE? + BEQ FORWRD $F972 + LBSR OUT1S OUTPUT SPACE + LDA #'? LOAD QUESTION MARK + LBSR OUTCH PRINT IT +FORWRD LEAY 1,Y POINT TO NEXT HIGHER MEM LOCATION + BRA MEMC2 PRINT LOCATION & CONTENTS +BACK LEAY -1,Y POINT TO LAST MEM LOCATION + BRA MEMC2 PRINT LOCATION & CONTENTS +* +* "S" DISPLAY STACK +* HEX-ASCII DISPLAY OF CURRENT STACK CONTENTS FROM +** CURRENT STACK POINTER TO INTERNAL STACK LIMIT. +* +DISSTK LBSR PRTSP PRINT CURRENT STACK POINTER + TFR U,Y + LDX #STACK LOAD INTERNAL STACK AS UPPER LIMIT + LEAX -1,X POINT TO CURRENT STACK + BRA MDUMP1 ENTER MEMORY DUMP OF STACK CONTENTS +* +* "E" DUMP MEMORY FOR EXAMINE IN HEX AND ASCII +* AFTER CALLING 'IN2ADR' LOWER ADDRESS IN Y-REG. +* UPPER ADDRESS IN X-REG. +* IF HEX ADDRESSES ARE INVALID (V)=1. +* +MEMDUMP LBSR IN2ADR INPUT ADDRESS BOUNDRIES + BVS EDPRTN NEW COMMAND IF ILLEGAL HEX +MDUMP1 PSHS Y COMPARE LOWER TO UPPER BOUNDS + CMPX ,S++ LOWER BOUNDS > UPPER BOUNDS? + BCC AJDUMP IF NOT, DUMP HEX AND ASCII +EDPRTN RTS ; +* +* ADJUST LOWER AND UPPER ADDRESS LIMITS +* TO EVEN 16 BYTE BOUNDRIES. +* +* IF LOWER ADDR = $4532 +* LOWER BOUNDS WILL BE ADJUSTED TO = $4530. +* +* IF UPPER ADDR = $4567 +* UPPER BOUNDS WILL BE ADJUSTED TO = $4570. +* +* ENTER WITH LOWER ADDRESS IN X-REG. +* -UPPER ADDRESS ON TOP OF STACK. +* +AJDUMP TFR X,D GET UPPER ADDR IN D-REG + ADDD #$10 ADD 16 TO UPPER ADDRESS + ANDB #$F0 MASK TO EVEN 16 BYTE BOUNDRY + PSHS A,B SAVE ON STACK AS UPPER DUMP LIMIT + TFR Y,D $F9A5 GET LOWER ADDRESS IN D-REG + ANDB #$F0 MASK TO EVEN 16 BYTE BOUNDRY + TFR D,X PUT IN X-REG AS LOWER DUMP LIMIT +NXTLIN CMPX ,S COMPARE LOWER TO UPPER LIMIT + BEQ SKPDMP IF EQUAL SKIP HEX-ASCII DUMP + LBSR INCHEK CHECK FOR INPUT FROM KEYBOARD + BEQ EDUMP IF NONE, CONTINUE WITH DUMP +SKPDMP LEAS 2,S READJUST STACK IF NOT DUMPING + RTS ; +* +* PRINT 16 HEX BYTES FOLLOWED BY 16 ASCII CHARACTERS +* FOR EACH LINE THROUGHOUT ADDRESS LIMITS. +* +EDUMP PSHS X PUSH LOWER ADDR LIMIT ON STACK + LDX #MSG5 POINT TO MSG " - " + LBSR PSTRNG PRINT MSG + LDX ,S LOAD LOWER ADDR FROM TOP OF STACK + LBSR OUT4H PRINT THE ADDRESS LBSR OUT2S PRINT 2 SPACES + LDB #$10 LOAD COUNT OF 16 BYTES TO DUMP +ELOOP LDA ,X+ GET FROM MEMORY HEX BYTE TO PRINT + LBSR OUT2H OUTPUT HEX BYTE AS ASCII + LBSR OUT1S OUTPUT SPACE + DECB $F9D1 DECREMENT BYTE COUNT + BNE ELOOP CONTINUE TIL 16 HEX BYTES PRINTED +* +* PRINT 16 ASCII CHARACTERS +* IF NOT PRINTABLE OR NOT VALID +* ASCII PRINT A PERIOD (.) + LBSR OUT2S 2 SPACES + LDX ,S++ GET LOW LIMIT FRM STACK - ADJ STACK + LDB #$10 SET ASCII CHAR TO PRINT = 16 +EDPASC LDA ,X+ GET CHARACTER FROM MEMORY + CMPA #$20 IF LESS THAN $20, NON-PRINTABLE? + BCS PERIOD IF SO, PRINT PERIOD INSTEAD + CMPA #$7E IS IT VALID ASCII? + BLS PRASC IF SO PRINT IT +PERIOD LDA #'. LOAD A PERIOD (.) +PRASC LBSR OUTCH PRINT ASCII CHARACTER + DECB DECREMENT COUNT + BNE EDPASC + BRA NXTLIN +* +***** "Q" MEMORY TEST ***** +* +MEMTST CLR ,-S CLEAR BYTE ON STACK + CLR ,-S CLEAR ANOTHER BYTE + LBSR IN2ADR GET BEGIN(Y) & END(X) ADDR. LIMITS + PSHS X,Y SAVE ADDRESSES ON STACK + BVS ADJSK6 EXIT IF NOT VALID HEX + CMPX 2,S COMPARE BEGIN TO END ADDR. + BCS ADJSK6 EXIT IF BEGIN > END ADDR. + LBSR OUT1S OUTPUT SPACE +MEMSET TFR Y,D PUT BEGIN ADDR. IN 'D'-ACCUM. + ADDD 4,S ADD PASS COUNT TO BEGIN ADDR + PSHS B ADD LS BYTE TO MS BYTE OF BEGIN ADDR + ADDA ,S+ + STA ,Y+ SAVE THIS DATA BYTE AT BEGIN ADDR + CMPY ,S COMPARE END TO BEGIN ADDR + BCS MEMSET IF BEGIN LOWER, CONTINUE TO SET MEMORY + LDY 2,S RELOAD BEGIN ADDRESS +TEST1 TFR Y,D PUT BEGIN ADDR IN 'D'-ACC. + ADDD 4,S ADD PASS COUNT TO ADDRESS + PSHS A ADD MS BYTE TO LS BYTE OF ADDRESS + ADDB ,S+ + EORB ,Y+ EX-OR THIS DATA WITH DATA IN MEMORY LOC. + BEQ GUDPAS IF (Z) SET, MEMORY BYTE OK + LDX #MSG5 POINT TO MSG " - " + LBSR PSTRNG PRINT MSG + LEAX -1,Y GET ERROR ADDRESS IN X-REG + LBSR OUT4H OUTPUT IT + PSHS X PUSH ERROR ADDR ON STACK + LDX #MSG8 POINT TO MSG " =>" + LBSR PDATA PRINT MSG + PULS X POP ERROR ADDR FROM STACK + LBSR LRA GET PHYSICAL ADDR FROM LRA + LBSR XASCII OUTPUT EXTENDED 4 BITS OF PHYSICAL ADDR + LBSR OUT4H OUTPUT LS 16 BITS OF PHYSICAL ADDR + LDX #MSG6 POINT TO MSG ", PASS " + LBSR PDATA PRINT MSG + LDX 4,S LOAD PASS COUNT + LBSR OUT4H OUTPUT IT + LDX #MSG7 POINT TO MSG ", BITS IN ERROR + LBSR PDATA PRINT MSG + TFR B,A GET ERROR BYTE INTO A-ACC + LDX #MSG9 POINT TO MSG "76543210" + LBSR BIASCI OUTPUT IN BINARY/ASCII FORMAT + LBSR INCHEK CHECK FOR INPUT FROM KEYBOARD $FA56 + BNE ADJSK6 IF SO, EXIT MEMORY TEST +GUDPAS CMPY ,S COMPARE END ADDR TO BEGIN ADDR + BCS TEST1 + LDA #'+ GET "PASS" SYMBOL IF MEMORY PASS OK + LBSR OUTCH OUTPUT SYMBOL TO TERMINAL + LBSR INCHEK INPUT FROM KEYBOARD? + BNE ADJSK6 IF SO, EXIT MEMORY TEST + LDY 2,S LOAD BEGIN ADDRESS + INC 5,S INCREMENT LS BYTE OF PASS COUNT + BNE MEMSET IF NOT ZERO, SET NEXT MEMORY BYTE + INC 4,S INCREMENT MS BYTE OF PASS COUNT + BNE MEMSET DONE WITH 65,535 PASSES OF MEMORY? +ADJSK6 LEAS 6,S ADJ STACK POINTER BY 6 + RTS +* +***** "B" SET BREAKPOINT ***** +* +BRKPNT LBSR IN1ADR GET BREAKPOINT ADDRESS + BVS EXITBP EXIT IF INVALID HEX ADDR. + CMPX #STACK ADDRESS ILLEGAL IF >=$DFC0 + BCC BPERR IF ERROR PRINT (?), EXIT + PSHS X $FA82 PUSH BP ADDRESS ON STACK + LDX #$FFFF LOAD DUMMY ADDR TO TEST BP TABLE + BSR BPTEST TEST BP TABLE FOR FREE SPACE + PULS X POP BP ADDRESS FROM STACK + BEQ BPERR (Z) SET, OUT OF BP TABLE SPACE + LDA ,X GET DATA AT BREAKPOINT ADDRESS + CMPA #$3F IS IT A SWI? + BEQ BPERR IF SWI ALREADY, INDICATE ERROR + STA ,Y+ SAVE DATA BYTE IN BP TABLE + STX ,Y SAVE BP ADDRESS IN BP TABLE + LDA #$3F LOAD A SWI ($3F) + STA ,X SAVE SWI AT BREAKPOINT ADDRESS +EXITBP RTS ; +* +* INDICATE ERROR SETTING BREAKPOINT +* +BPERR LBSR OUT1S OUTPUT SPACE + LDA #'? LOAD (?), INDICATE BREAKPOINT ERROR + LBRA OUTCH PRINT "?" +* +*** "X" CLEAR OUTSTANDING BREAKPOINTS *** +* +XBKPNT LDY #BPTBL POINT TO BREAKPOINT TABLE + LDB #8 LOAD BREAKPOINT COUNTER +XBPLP BSR RPLSWI REMOVE USED ENTRY IN BP TABLE + DECB $FAAC DECREMENT BP COUNTER + BNE XBPLP END OF BREAKPOINT TABLE? + RTS +* +***** SWI ENTRY POINT ***** +* +SWIE TFR S,U TRANSFER STACK TO USER POINTER + LDX 10,U LOAD PC FROM STACK INTO X-REG + LEAX -1,X ADJUST ADDR DOWN 1 BYTE. + BSR BPTEST FIND BREAKPOINT IN BP TABLE + BEQ REGPR IF FOUND, REPLACE DATA AT BP ADDR + STX 10,U SAVE BREAKPOINT ADDR IN STACK + BSR RPLSWI GO REPLACE SWI WITH ORIGINAL DATA +REGPR LBSR REGSTR GO PRINT REGISTERS + LBRA NEXTCMD GET NEXT COMMAND +RPLSWI LDX 1,Y LOAD BP ADDRESS FROM BP TABLE + CMPX #STACK COMPARE TO TOP AVAILABLE USER MEMORY + BCC FFSTBL GO RESET TABLE ENTRY TO $FF'S + LDA ,X GET DATA FROM BP ADDRESS + CMPA #$3F IS IT SWI? + BNE FFSTBL IF NOT, RESET TABLE ENTRY TO $FF'S + LDA ,Y GET ORIGINAL DATA FROM BP TABLE + STA ,X $FAD3 RESTORE DATA AT BP ADDRESS +FFSTBL LDA #$FF LOAD $FF IN A-ACC + STA ,Y+ RESET BREAKPOINT TABLE DATA TO $FF'S + STA ,Y+ RESET BREAKPOINT TABLE ADDR TO $FF'S + STA ,Y+ + RTS +* +** SEARCH BREAKPOINT TABLE FOR MATCH ** +* +BPTEST LDY #BPTBL POINT TO BREAKPOINT TABLE + LDB #8 LOAD BREAKPOINT COUNTER +FNDBP LDA ,Y+ LOAD DATA BYTE + CMPX ,Y++ COMPARE ADDRESS, IS IT SAME? + BEQ BPADJ IF SO, ADJUST POINTER FOR TABLE ENTRY + DECB IF NOT, DECREMENT BREAKPOINT COUNTER + BNE FNDBP AND LOOK FOR NEXT POSSIBLE MATCH + RTS ; +* +* +BPADJ LEAY -3,Y MOVE POINTER TO BEGIN OF BP ENTRY + RTS +* +*** "D" DISK BOOT FOR DMAF2 *** +* +DBOOT LDA #$DE + STA DRVREG + LDA #$FF + STA PRIREG $FAF8 + STA CCREG + STA AAAREG + STA BBBREG + TST CCREG + LDA #$D8 + STA COMREG + LBSR DLY +DBOOT0 LDA COMREG + BMI DBOOT0 + LDA #$09 + STA COMREG + LBSR DLY +* +DISKWT LDA COMREG FETCH DRIVE STATUS + BITA #1 TEST BUSY BIT + BNE DISKWT LOOP UNTIL NOT BUSY +* + BITA #$10 + BNE DBOOT +* + LDX #$C000 LOGICAL ADDR. = $C000 + BSR LRA GET 20 BIT PHYSICAL ADDR. OF LOG. ADDR. + ORA #$10 + STA CCCREG + TFR X,D + COMA ; + COMB ; + STD ADDREG + LDX #$FEFF LOAD DMA BYTE COUNT = $100 + STX CNTREG STORE IN COUNT REGISTER + LDA #$FF LOAD THE CHANNEL REGISTER + STA CCREG + LDA #$FE SET CHANNEL 0 + STA PRIREG + LDA #1 SET SECTOR TO "1" + STA SECREG ISSUE COMMAND + LDA #$8C SET SINGLE SECTOR READ + STA COMREG ISSUE COMMAND + BSR DLY +* +* THE FOLLOWING CODE TESTS THE STATUS OF THE +* CHANNEL CONTROL REGISTER. IF "D7" IS NOT +* ZERO THEN IT WILL LOOP WAITING FOR "D7" +* TO GO TO ZERO. IF AFTER 65,536 TRIES IT +* IS STILL A ONE THE BOOT OPERATION WILL +* BE STARTED OVER FROM THE BEGINING. +* + CLRB ; +DBOOT1 PSHS B $FB55 + CLRB ; +DBOOT2 TST CCREG + BPL DBOOT3 + DECB ; + BNE DBOOT2 + PULS B + DECB + BNE DBOOT1 + BRA DBOOT +DBOOT3 PULS B + LDA COMREG + BITA #$1C + BEQ DBOOT4 + RTS ; +* +* +DBOOT4 LDB #$DE + STB DRVREG + LDX #$C000 + STX 10,U + TFR U,S $FB7B + RTI ; +* +***** LRA LOAD REAL ADDRESS ***** +* +* THE FOLLOWING CODE LOADS THE 20-BIT +* PHYSICAL ADDRESS OF A MEMORY BYTE +* INTO THE "A" AND "X" REGISTERS. THIS +* ROUTINE IS ENTERED WITH THE LOGICAL +* ADDRESS OF A MEMORY BYTE IN THE "IX" +* REGISTER. EXIT IS MADE WITH THE HIGH- +* ORDER FOUR BITS OF THE 20-BIT PHYSICAL +* ADDRESS IN THE "A" REGISTER, AND THE +* LOW-ORDER 16-BITS OF THE 20-BIT +* PHYSICAL ADDRESS IN THE "IX" REGISTER. +* ALL OTHER REGISTERS ARE PRESERVED. +* THIS ROUTINE IS REQUIRED SINCE THE +* DMAF1 AND DMAF2 DISK CONTROLLERS MUST +* PRESENT PHYSICAL ADDRESSES ON THE +* SYSTEM BUS. +* +LRA PSHS A,B,X,Y PUSH REGISTERS ON STACK + LDA 2,S GET MSB LOGICAL ADDR FRM X REG ON STACK + LSRA ; + LSRA ADJ FOR INDEXED INTO + LSRA CORRESPONDING LOCATION + LSRA IN LRA TABLE + LDY #LRARAM LOAD LRA TABLE BASE ADDRESS + LDB A,Y GET PHYSICAL ADDR. DATA FROM LRA TABLE + LSRB ADJ. REAL ADDR. TO REFLECT EXTENDED + LSRB PHYSICAL ADDRESS. + LSRB EXTENDED MS 4-BITS ARE RETURNED + LSRB IN THE "A" ACCUMULATOR + STB ,S MS 4 BITS IN A ACCUM. STORED ON STACK + LDB A,Y LOAD REAL ADDRESS DATA FROM LRA TABLE + COMB COMP TO ADJ FOR PHYSICAL ADDR. IN X REG + ASLB ADJ DATA FOR RELOCATION IN X REG + ASLB ; + ASLB $FB97 + ASLB ; + LDA 2,S GET MS BYTE OF LOGICAL ADDR. + ANDA #$0F MASK MS NIBBLE OF LOGICAL ADDRESS + STA 2,S SAVE IT IN X REG ON STACK + ORB 2,S SET MS BYTE IN X REG TO ADJ PHY ADDR. +* +* PLUS LS NIBBLE OF LOGICAL ADDRESS + STB 2,S SAVE AS LS 16 BITS OF PHY ADDR IN X REG +* ON STACK + PULS A,B,X,Y POP REGS. FROM STACK + RTS ; +* +* DELAY LOOP +* +DLY PSHS B SAVE CONTENTS OF "B" + LDB #$20 GET LOOP DELAY VALUE +SUB1 DECB SUBTRACT ONE FROM VALUE + BNE SUB1 LOOP UNTIL ZERO + PULS B RESTORE CONTENTS OF "B" + RTS ; +* +***** "U" MINIDISK BOOT ***** +* +MINBOOT TST Comreg + CLR Drvreg SELECT DRIVE 0 +* +* DELAY BEFORE ISSUING RESTORE COMMAND + LDB #3 + LDX #0 +LOOP LEAX 1,X $FBBB + CMPX #0 + BNE LOOP + DECB $FBC2 + BNE LOOP +* + LDA #$0F *LOAD HEAD, VERIFY, 20msec/step + STA Comreg ISSUE RESTORE COMMAND + BSR DELAY +LOOP1 LDB Comreg $FBCC + BITB #1 + BNE LOOP1 LOOP UNTIL THRU + LDA #1 + STA Secreg SET SECTOR REGISTER TO ONE + BSR DELAY + LDA #$8C LOAD HEAD, DELAY 10msec, + STA Comreg AND READ SINGLE RECORD + BSR DELAY + LDX #$C000 + BRA LOOP3 +* +LOOP2 BITB #2 $FBE6 DRQ? + BEQ LOOP3 + LDA Datreg + STA ,X+ +* +LOOP3 LDB Comreg FETCH STATUS + BITB #1 BUSY? + BNE LOOP2 + BITB #$2C CRC ERROR OR LOST DATA? + BEQ LOOP4 + RTS ; +LOOP4 LDX #$C000 $FBFB + STX 10,U + TFR U,S + RTI ; +* +* DELAY +* +DELAY LDB #$20 +LOOP5 DECB ; + BNE LOOP5 + RTS ; +* +***** "L" LOAD MIKBUG TAPE ***** +* +LOAD LDA #$11 LOAD 'DC1' CASS. READ ON CODE + LBSR OUTCH OUTPUT IT TO TERMINAL PORT + CLR ECHO TURN OFF ECHO FLAG +LOAD1 LBSR ECHON INPUT 8 BIT BYTE WITH NO ECHO +LOAD2 CMPA #'S IS IT AN "S", START CHARACTER ? + BNE LOAD1 IF NOT, DISCARD AND GET NEXT CHAR. + LBSR ECHON + CMPA #'9 IS IT A "9" , END OF FILE CHAR ? + BEQ LOAD21 IF SO, EXIT LOAD + CMPA #'1 IS IT A "1" , FILE LOAD CHAR ? + BNE LOAD2 IF NOT, LOOK FOR START CHAR. + LBSR BYTE INPUT BYTE COUNT + PSHS A PUSH COUNT ON STACK + BVS LODERR (V) C-CODE SET, ILLEGAL HEX + LBSR IN1ADR INPUT LOAD ADDRESS + BVS LODERR (V) C-CODE SET, ADDR NOT HEX + PSHS X PUSH ADDR ON STACK + LDB ,S+ LOAD MSB OF ADDR AS CHECKSUM BYTE + ADDB ,S+ ADD LSB OF ADDR TO CHECKSUM + ADDB ,S ADD BYTE COUNT BYTE TO CHECKSUM + DEC ,S $FC37 DECREMENT BYTE COUNT 2 TO BYPASS + DEC ,S ADDRESS BYTES. +LOAD10 PSHS B PUSH CHECKSUM ON STACK + LBSR BYTE INPUT DATA BYTE (2 HEX CHAR) + PULS B POP CHECKSUM FROM STACK + BVS LODERR (V) SET, DATA BYTE NOT HEX + PSHS A PUSH DATA BYTE ON STACK + ADDB ,S+ ADD DATA TO CHECKSUM, AUTO INC STACK + DEC ,S DECREMENT BYTE COUNT 1 + BEQ LOAD16 IF BYTE COUNT ZERO, TEST CHECKSUM + STA ,X+ SAVE DATA BYTE IN MEMORY + BRA LOAD10 GET NEXT DATA BYTE +LODERR CLRB ;ERROR CONDITION, ZERO CHECKSUM ; +LOAD16 PULS A ADJUST STACK (REMOVE BYTE COUNT) + CMPB #$FF CHECKSUM OK? + BEQ LOAD IF SO, LOAD NEXT LINE + LDA #'? LOAD (?) ERROR INDICATOR + LBSR OUTCH OUTPUT IT TO TERMINAL +LOAD21 COM ECHO TURN ECHO ON + LDA #$13 $FC5F LOAD 'DC3' CASS. READ OFF CODE + LBRA OUTCH OUTPUT IT +* +***** "P" PUNCH MIKBUG TAPE ***** +* +PUNCH CLR ,-S CLEAR RESERVED BYTE ON STACK + LBSR IN2ADR GET BEGIN AND END ADDRESS + PSHS X,Y SAVE ADDRESSES ON STACK + BVS PUNEXT (V) C-CODE SET, EXIT PUNCH + CMPX 2,S COMPARE BEGIN TO END ADDR + BCS PUNEXT IF BEGIN GREATER THAN END, EXIT PUNCH + LEAX 1,X INCREMENT END ADDRESS + STX ,S STORE END ADDR ON STACK + LDA #$12 LOAD 'DC2' PUNCH ON CODE + LBSR OUTCH OUTPUT IT TO TERMINAL +PUNCH2 LDD ,S LOAD END ADDR IN D-ACC + SUBD 2,S SUBTRACT BEGIN FROM END + BEQ PUNCH3 SAME, PUNCH 32 BYTES DEFAULT + CMPD #$20 LESS THAN 32 BYTES? + BLS PUNCH4 PUNCH THAT MANY BYTES +PUNCH3 LDB #$20 LOAD BYTE COUNT OF 32. +PUNCH4 STB 4,S STORE ON STACK AS BYTE COUNT + LDX #MSG20 POINT TO MSG "S1" + LBSR PSTRNG PRINT MSG + ADDB #3 ADD 3 BYTES TO BYTE COUNT + TFR B,A GET BYTE COUNT IN A-ACC TO PUNCH + LBSR OUT2H OUTPUT BYTE COUNT + LDX 2,S LOAD BEGIN ADDRESS + LBSR OUT4H PUNCH ADDRESS + ADDB 2,S ADD ADDR MSB TO CHECKSUM + ADDB 3,S ADD ADDR LSB TO CHECKSUM +PUNCHL ADDB ,X ADD DATA BYTE TO CHECKSUM + LDA ,X+ LOAD DATA BYTE TO PUNCH + LBSR OUT2H OUTPUT DATA BYTE + DEC 4,S DECREMENT BYTE COUNT + BNE PUNCHL NOT DONE, PUNCH NEXT BYTE + COMB 1's COMPLIMENT CHECKSUM BYTE + TFR B,A GET IT IN A-ACC TO PUNCH + LBSR OUT2H OUTPUT CHECKSUM BYTE + STX 2,S SAVE X-REG IN STACK AS NEW PUNCH ADDR + CMPX ,S COMPARE IT TO END ADDR + BNE PUNCH2 $FCB5 PUNCH NOT DONE, CONT. +PUNEXT LDA #$14 LOAD 'DC4' PUNCH OFF CODE + LBSR OUTCH OUTPUT IT + LEAS 5,S READJUST STACK POINTER + RTS ; +* +* +PRTSP LDX #MSG10 POINT TO MSG "SP=" + LBSR PDATA PRINT MSG + TFR U,X + LBRA OUT4H +PRTUS LDX #MSG12 POINT TO MSG "US=" + LBSR PDATA PRINT MSG + LDX 8,U + LBRA OUT4H +PRTDP LDX #MSG15 POINT TO MSG "DP=" + LBSR PDATA PRINT MSG + LDA 3,U + LBRA OUT2H OUTPUT HEX BYTE AS ASCII +PRTIX LDX #MSG14 POINT TO MSG "IX=" + LBSR PDATA PRINT MSG + LDX 4,U $FCE6 + LBRA OUT4H +PRTIY LDX #MSG13 POINT TO MSG "IY=" + LBSR PDATA PRINT MSG + LDX 6,U + LBRA OUT4H +PRTPC LDX #MSG11 POINT TO MSG "PC=" + LBSR PDATA PRINT MSG + LDX 10,U + BRA OUT4H +PRTA LDX #MSG16 POINT TO MSG "A=" + LBSR PDATA PRINT MSG + LDA 1,U + BRA OUT2H OUTPUT HEX BYTE AS ASCII +PRTB LDX #MSG17 POINT TO MSG "B=" + LBSR PDATA PRINT MSG + LDA 2,U + BRA OUT2H OUTPUT HEX BYTE AS ASCII +PRTCC LDX #MSG18 POINT TO MSG "CC:" + LBSR PDATA PRINT MSG + LDA ,U + LDX #MSG19 POINT TO MSG "EFHINZVC" + BRA BIASCI OUTPUT IN BINARY/ASCII FORMAT +* +* THE FOLLOWING ROUTINE LOOPS WAITING FOR THE +* OPERATOR TO INPUT TWO VALID HEX ADDRESSES. +* THE FIRST ADDRESS INPUT IS RETURNED IN "IY". +* THE SECOND IS RETURNED IN "IX". THE "V" BIT +* IN THE C-CODE REG. IS SET IF AN INVALID HEX +* ADDRESS IS INPUT. +* +IN2ADR BSR IN1ADR GET FIRST ADDRESS + BVS NOTHEX EXIT IF NOT VALID HEX + TFR X,Y SAVE FIRST ADDR. IN "IY" + LDA #'- + LBSR OUTCH PRINT " - " +* +* THE FOLLOWING ROUTINE LOOPS WAITING FOR THE +* OPERATOR TO INPUT ONE VALID HEX ADDRESS. THE +* ADDRESS IS RETURNED IN THE "X" REGISTER. +* +IN1ADR BSR BYTE INPUT BYTE (2 HEX CHAR) + BVS NOTHEX EXIT IF NOT VALID HEX + TFR D,X + BSR BYTE INPUT BYTE (2 HEX CHAR) + BVS NOTHEX + PSHS X + STA 1,S + PULS X + RTS ; +* +***** INPUT BYTE (2 HEX CHAR.) ***** +* +BYTE BSR INHEX GET HEX LEFT + BVS NOTHEX EXIT IF NOT VALID HEX + ASLA ; + ASLA ; + ASLA ; SHIFT INTO LEFT NIBBLE + ASLA ; + TFR A,B PUT HEXL IN "B" + BSR INHEX GET HEX RIGHT + BVS NOTHEX EXIT IF NOT VALID HEX + PSHS B PUSH HEXL ON STACK + ADDA ,S+ ADD HEXL TO HEXR AND ADJ. STK + RTS RETURN WITH HEX L&R IN "A" +* +* +INHEX BSR ECHON INPUT ASCII CHAR. + CMPA #'0 IS IT > OR = "0" ? + BCS NOTHEX IF LESS IT AIN'T HEX + CMPA #'9 IS IT < OR = "9" ? + BHI INHEXA IF > MAYBE IT'S ALPHA + SUBA #$30 ASCII ADJ. NUMERIC + RTS ; +* +* +INHEXA CMPA #'A IS IT > OR = "A" + BCS NOTHEX IF LESS IT AIN'T HEX + CMPA #'F IS IT < OR = "F" ? + BHI INHEXL IF > IT AIN'T HEX + SUBA #$37 ASCII ADJ. ALPHA + RTS ; +* +INHEXL CMPA #'a IS IT > OR = "a" + BCS NOTHEX IF LESS IT AIN'T HEX + CMPA #'f IS IT < "f" + BHI NOTHEX IF > IT AIN'T HEX + SUBA #$57 ADJUST TO LOWER CASE + RTS ; +* +* +NOTHEX ORCC #2 SET (V) FLAG IN C-CODES REGISTER + RTS ; +* +* +OUT4H PSHS X PUSH X-REG. ON THE STACK + PULS A POP MS BYTE OF X-REG INTO A-ACC. + BSR OUTHL OUTPUT HEX LEFT + PULS A POP LS BYTE OF X-REG INTO A-ACC. +OUTHL EQU * +OUT2H PSHS A SAVE IT BACK ON STACK + LSRA CONVERT UPPER HEX NIBBLE TO ASCII + LSRA ; + LSRA ; + LSRA ; + BSR XASCII PRINT HEX NIBBLE AS ASCII +OUTHR PULS A CONVERT LOWER HEX NIBBLE TO ASCII + ANDA #$0F STRIP LEFT NIBBLE +XASCII ADDA #$30 ASCII ADJ + CMPA #$39 IS IT < OR = "9" ? + BLE OUTC IF LESS, OUTPUT IT + ADDA #7 IF > MAKE ASCII LETTER +OUTC BRA OUTCH OUTPUT CHAR +* +* BINARY / ASCII --- THIS ROUTINE +* OUTPUTS A BYTE IN ENHANCED +* BINARY FORMAT. THE ENHANCEMENT +* IS DONE BY SUBSTITUTING ASCII +* LETTERS FOR THE ONES IN THE BYTE. +* THE ASCII ENHANCEMENT LETTERS +* ARE OBTAINED FROM THE STRING +* POINTED TO BY THE INDEX REG. "X". +* +BIASCI PSHS A SAVE "A" ON STACK + LDB #8 PRESET LOOP# TO BITS PER BYTE +OUTBA LDA ,X+ GET LETTER FROM STRING + ASL ,S TEST BYTE FOR "1" IN B7 + BCS PRTBA IF ONE PRINT LETTER + LDA #'- IF ZERO PRINT "-" +PRTBA BSR OUTCH PRINT IT + BSR OUT1S PRINT SPACE + DECB SUB 1 FROM #BITS YET TO PRINT + BNE OUTBA + PULS A + RTS +* +* PRINT STRING PRECEEDED BY A CR & LF. +* +PSTRNG BSR PCRLF PRINT CR/LF + BRA PDATA PRINT STRING POINTED TO BY IX +* +* PCRLF +* +PCRLF PSHS X SAVE IX + LDX #MSG2+1 POINT TO MSG CR/LF + 3 NULS + BSR PDATA PRINT MSG + PULS X RESTORE IX + RTS ; +PRINT BSR OUTCH +* +* PDATA +* +PDATA LDA ,X+ GET 1st CHAR. TO PRINT + CMPA #4 IS IT EOT? + BNE PRINT IF NOT EOT PRINT IT + RTS ; +* +* +ECHON TST ECHO IS ECHO REQUIRED ? + BEQ INCH ECHO NOT REQ. IF CLEAR +* +* INCHE +* +* ---GETS CHARACTER FROM TERMINAL AND +* ECHOS SAME. THE CHARACTER IS RETURNED +* IN THE "A" ACCUMULATOR WITH THE PARITY +* BIT MASKED OFF. ALL OTHER REGISTERS +* ARE PRESERVED. +* +INCHE BSR INCH GET CHAR FROM TERMINAL + ANDA #$7F STRIP PARITY FROM CHAR. + BRA OUTCH ECHO CHAR TO TERMINAL +* +* INCH +* +* GET CHARACTER FROM TERMINAL. RETURN +* CHARACTER IN "A" ACCUMULATOR AND PRESERVE +* ALL OTHER REGISTERS. THE INPUT CHARACTER +* IS 8 BITS AND IS NOT ECHOED. +* +* +INCH PSHS X SAVE IX + LDX CPORT POINT TO TERMINAL PORT +GETSTA LDA ,X FETCH PORT STATUS + BITA #1 TEST READY BIT, RDRF ? + BEQ GETSTA IF NOT RDY, THEN TRY AGAIN + LDA 1,X FETCH CHAR + PULS X RESTORE IX + RTS ; +* +* INCHEK +* +* CHECK FOR A CHARACTER AVAILABLE FROM +* THE TERMINAL. THE SERIAL PORT IS CHECKED +* FOR READ READY. ALL REGISTERS ARE +* PRESERVED, AND THE "Z" BIT WILL BE +* CLEAR IF A CHARACTER CAN BE READ. +* +* +INCHEK PSHS A SAVE A ACCUM. + LDA [CPORT] FETCH PORT STATUS + BITA #1 TEST READY BIT, RDRF ? + PULS A RESTORE A ACCUM. + RTS ; +* +OUT2S BSR OUT1S OUTPUT 2 SPACES +OUT1S LDA #$20 OUTPUT 1 SPACE +* +* +* OUTCH +* +* OUTPUT CHARACTER TO TERMINAL. +* THE CHAR. TO BE OUTPUT IS +* PASSED IN THE A REGISTER. +* ALL REGISTERS ARE PRESERVED. +* +OUTCH PSHS A,X SAVE A ACCUM AND IX + LDX CPORT GET ADDR. OF TERMINAL +FETSTA LDA ,X FETCH PORT STATUS + BITA #2 TEST TDRE, OK TO XMIT ? + BEQ FETSTA IF NOT LOOP UNTIL RDY + PULS A GET CHAR. FOR XMIT + STA 1,X XMIT CHAR. + PULS X RESTORE IX + RTS ; +* +* +ACINIZ LDX CPORT POINT TO CONTROL PORT ADDRESS + LDA #3 RESET ACIA PORT CODE + STA ,X STORE IN CONTROL REGISTER + LDA #$11 SET 8 DATA, 2 STOP AN 0 PARITY + STA ,X STORE IN CONTROL REGISTER + TST 1,X ANYTHING IN DATA REGISTER? + LDA #$FF TURN ON ECHO FLAG + STA ECHO + RTS +* +* +* MONITOR KEYBOARD COMMAND JUMP TABLE +* +* +JMPTAB EQU * + FCB 1 " ^A " $F91D + FDB ALTRA + FCB 2 " ^B " $F90F + FDB ALTRB + FCB 3 " ^C " $F92B + FDB ALTRCC + FCB 4 " ^D " $F901 + FDB ALTRDP + FCB $10 " ^P " $F8C9 + FDB ALTRPC + FCB $15 " ^U " $F8D7 + FDB ALTRU + FCB $18 " ^X " $F8F3 + FDB ALTRX + FCB $19 " ^Y " $F8E5 + FDB ALTRY +* + FCC 'B' + FDB BRKPNT *$FA78 + FCC 'D' + FDB DBOOT *$FAF1 + FCC 'E' + FDB MEMDUMP *$F990 + FCC 'G' + FDB GO *$F89F + FCC 'L' + FDB LOAD *$FC09 + FCC 'M' + FDB MEMCHG *$F93B + FCC 'P' + FDB PUNCH *$FC64 + FCC 'Q' + FDB MEMTST *$F9EF + FCC 'R' + FDB REGSTR *$F8A2 + FCC 'S' + FDB DISSTK *$F984 + FCC 'U' + FDB MINBOOT *$FBB0 + FCC 'X' + FDB XBKPNT *$FAA4 +* +TABEND EQU * +* +* ** 6809 VECTOR ADDRESSES ** +* +* FOLLOWING ARE THE ADDRESSES OF THE VECTOR ROUTINES +* FOR THE 6809 PROCESSOR. DURING INITIALIZATION THEY +* ARE RELOCATED TO RAM FROM $DFC0 TO $DFCF. THEY ARE +* RELOCATED TO RAM SO THAT THE USER MAY REVECTOR TO +* HIS OWN ROUTINES IF HE SO DESIRES. +* +* +RAMVEC FDB SWIE USER-V + FDB RTI SWI3-V + FDB RTI SWI2-V + FDB RTI FIRQ-V + FDB RTI IRQ-V + FDB SWIE SWI-V + FDB $FFFF SVC-VO + FDB $FFFF SVC-VL +* +* PRINTABLE MESSAGE STRINGS +* +MSG1 FCB $0,$0,$0,$D,$A,$0,$0,$0 * 0, CR/LF, 0 + FCC 'S-BUG 1.8 - ' + FCB 4 +MSG2 FCB 'K,$D,$A,$0,$0,$0,4 K, * CR/LF + 3 NULS +MSG3 FCC '>' + FCB 4 +MSG4 FCC 'WHAT?' + FCB 4 +MSG5 FCC ' - ' + FCB 4' +MSG6 FCC ', PASS ' + FCB 4 +MSG7 FCC ', BITS IN ERROR: ' + FCB 4 +MSG8 FCC ' => ' + FCB 4 +MSG9 FCC '76543210' +MSG10 FCC ' SP=' + FCB 4 +MSG11 FCC ' PC=' + FCB 4 +MSG12 FCC ' US=' + FCB 4 +MSG13 FCC ' IY=' + FCB 4 +MSG14 FCC ' IX=' + FCB 4 +MSG15 FCC ' DP=' + FCB 4 +MSG16 FCC ' A=' + FCB 4 +MSG17 FCC ' B=' + FCB 4 +MSG18 FCC ' CC: ' + FCB 4 +MSG19 FCC 'EFHINZVC' +MSG20 FCC 'S1' + FCB 4 +* +* MESSAGE EXPANSION AREA +* + FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF + FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF +* +* POWER UP/ RESET/ NMI ENTRY POINT +* + ORG $FF00 +* +* +START LDX #IC11 POINT TO DAT RAM IC11 + LDA #$F GET COMPLIMENT OF ZERO +* +* +* INITIALIZE DAT RAM --- LOADS $F-$0 IN LOCATIONS $0-$F +* OF DAT RAM, THUS STORING COMPLEMENT OF MSB OF ADDRESS +* IN THE DAT RAM. THE COMPLEMENT IS REQUIRED BECAUSE THE +* OUTPUT OF IC11, A 74S189, IS THE INVERSE OF THE DATA +* STORED IN IT. +* +* +DATLP STA ,X+ STORE & POINT TO NEXT RAM LOCATION + DECA GET COMP. VALUE FOR NEXT LOCATION + BNE DATLP ALL 16 LOCATIONS INITIALIZED ? +* +* NOTE: IX NOW CONTAINS $0000, DAT RAM IS NO LONGER +* ADDRESSED, AND LOGICAL ADDRESSES NOW EQUAL +* PHYSICAL ADDRESSES. +* + LDA #$F0 + STA ,X STORE $F0 AT $FFFF + LDX #$D0A0 ASSUME RAM TO BE AT $D000-$DFFF + LDY #TSTPAT LOAD TEST DATA PATTERN INTO "Y" +TSTRAM LDU ,X SAVE DATA FROM TEST LOCATION + STY ,X STORE TEST PATTERN AT $D0A0 + CMPY ,X IS THERE RAM AT THIS LOCATION ? + BEQ CNVADR IF MATCH THERE'S RAM, SO SKIP + LEAX -$1000,X ELSE POINT 4K LOWER + CMPX #$F0A0 DECREMENTED PAST ZER0 YET ? + BNE TSTRAM IF NOT CONTINUE TESTING FOR RAM + BRA START ELSE START ALL OVER AGAIN +* +* +* THE FOLLOWING CODE STORES THE COMPLEMENT OF +* THE MS CHARACTER OF THE FOUR CHARACTER HEX +* ADDRESS OF THE FIRST 4K BLOCK OF RAM LOCATED +* BY THE ROUTINE "TSTRAM" INTO THE DAT RAM. IT +* IS STORED IN RAM IN THE LOCATION THAT IS +* ADDRESSED WHEN THE PROCESSOR ADDRESS IS $D---, +* THUS IF THE FIRST 4K BLOCK OF RAM IS FOUND +* WHEN TESTING LOCATION $70A0, MEANING THERE +* IS NO RAM PHYSICALLY ADDRESSED IN THE RANGE +* $8000-$DFFF, THEN THE COMPLEMENT OF THE +* "7" IN THE $70A0 WILL BE STORED IN +* THE DAT RAM. THUS WHEN THE PROCESSOR OUTPUTS +* AN ADDRESS OF $D---, THE DAT RAM WILL RESPOND +* BY RECOMPLEMENTING THE "7" AND OUTPUTTING THE +* 7 ONTO THE A12-A15 ADDRESS LINES. THUS THE +* RAM THAT IS PHYSICALLY ADDRESSED AT $7--- +* WILL RESPOND AND APPEAR TO THE 6809 THAT IT +* IS AT $D--- SINCE THAT IS THE ADDRESS THE +* 6809 WILL BE OUTPUTING WHEN THAT 4K BLOCK +* OF RAM RESPONDS. +* +* +CNVADR STU ,X RESTORE DATA AT TEST LOCATION + TFR X,D PUT ADDR. OF PRESENT 4K BLOCK IN D + COMA COMPLEMENT MSB OF THAT ADDRESS + LSRA PUT MS 4 BITS OF ADDRESS IN + LSRA LOCATION D0-D3 TO ALLOW STORING + LSRA IT IN THE DYNAMIC ADDRESS + LSRA TRANSLATION RAM. + STA $FFFD STORE XLATION FACTOR IN DAT "D" +* + LDS #STACK INITIALIZE STACK POINTER +* +* +* THE FOLLOWING CHECKS TO FIND THE REAL PHYSICAL ADDRESSES +* OF ALL 4K BLKS OF RAM IN THE SYSTEM. WHEN EACH 4K BLK +* OF RAM IS LOCATED, THE COMPLEMENT OF IT'S REAL ADDRESS +* IS THEN STORED IN A "LOGICAL" TO "REAL" ADDRESS XLATION +* TABLE THAT IS BUILT FROM $DFD0 TO $DFDF. FOR EXAMPLE IF +* THE SYSTEM HAS RAM THAT IS PHYSICALLY LOCATED (WIRED TO +* RESPOND) AT THE HEX LOCATIONS $0--- THRU $F---.... +* +* 0 1 2 3 4 5 6 7 8 9 A B C D E F +* 4K 4K 4K 4K 4K 4K 4K 4K -- 4K 4K 4K 4K -- -- -- +* +* ....FOR A TOTAL OF 48K OF RAM, THEN THE TRANSLATION TABLE +* CREATED FROM $DFD0 TO $DFDF WILL CONSIST OF THE FOLLOWING.... +* +* 0 1 2 3 4 5 6 7 8 9 A B C D E F +* 0F 0E 0D 0C 0B 0A 09 08 06 05 00 00 04 03 F1 F0 +* +* +* HERE WE SEE THE LOGICAL ADDRESSES OF MEMORY FROM $0000-$7FFF +* HAVE NOT BEEN SELECTED FOR RELOCATION SO THAT THEIR PHYSICAL +* ADDRESS WILL = THEIR LOGICAL ADDRESS; HOWEVER, THE 4K BLOCK +* PHYSICALLY AT $9000 WILL HAVE ITS ADDRESS TRANSLATED SO THAT +* IT WILL LOGICALLY RESPOND AT $8000. LIKEWISE $A,$B, AND $C000 +* WILL BE TRANSLATED TO RESPOND TO $9000,$C000, AND $D000 +* RESPECTIVELY. THE USER SYSTEM WILL LOGICALLY APPEAR TO HAVE +* MEMORY ADDRESSED AS FOLLOWS.... +* +* 0 1 2 3 4 5 6 7 8 9 A B C D E F +* 4K 4K 4K 4K 4K 4K 4K 4K 4K 4K -- -- 4K 4K -- -- +* +* + LDY #LRARAM POINT TO LOGICAL/REAL ADDR. TABLE + STA 13,Y STORE $D--- XLATION FACTOR AT $DFDD + CLR 14,Y CLEAR $DFDE + LDA #$F0 DESTINED FOR IC8 AN MEM EXPANSION ? + STA 15,Y STORE AT $DFDF + LDA #$0C PRESET NUMBER OF BYTES TO CLEAR +CLRLRT CLR A,Y CLEAR $DFDC THRU $DFD0 + DECA SUB. 1 FROM BYTES LEFT TO CLEAR + BPL CLRLRT CONTINUE IF NOT DONE CLEARING +FNDRAM LEAX -$1000,X POINT TO NEXT LOWER 4K OF RAM + CMPX #$F0A0 TEST FOR DECREMENT PAST ZERO + BEQ FINTAB SKIP IF FINISHED + LDU ,X SAVE DATA AT CURRENT TEST LOCATION + LDY #TSTPAT LOAD TEST DATA PATTERN INTO Y REG. + STY ,X STORE TEST PATT. INTO RAM TEST LOC. + CMPY ,X VERIFY RAM AT TEST LOCATION + BNE FNDRAM IF NO RAM GO LOOK 4K LOWER + STU ,X ELSE RESTORE DATA TO TEST LOCATION + LDY #LRARAM POINT TO LOGICAL/REAL ADDR. TABLE + TFR X,D PUT ADDR. OF PRESENT 4K BLOCK IN D + LSRA PUT MS 4 BITS OF ADDR. IN LOC. D0-D3 + LSRA TO ALLOW STORING IT IN THE DAT RAM. + LSRA + LSRA + TFR A,B SAVE OFFSET INTO LRARAM TABLE + EORA #$0F INVERT MSB OF ADDR. OF CURRENT 4K BLK + STA B,Y SAVE TRANSLATION FACTOR IN LRARAM TABLE + BRA FNDRAM GO TRANSLATE ADDR. OF NEXT 4K BLK +FINTAB LDA #$F1 DESTINED FOR IC8 AND MEM EXPANSION ? + LDY #LRARAM POINT TO LRARAM TABLE + STA 14,Y STORE $F1 AT $DFCE +* +* THE FOLLOWING CHECKS TO SEE IF THERE IS A 4K BLK OF +* RAM LOCATED AT $C000-$CFFF. IF NONE THERE IT LOCATES +* THE NEXT LOWER 4K BLK AN XLATES ITS ADDR SO IT +* LOGICALLY RESPONDS TO THE ADDRESS $C---. +* +* + LDA #$0C PRESET NUMBER HEX "C" +FINDC LDB A,Y GET ENTRY FROM LRARAM TABLE + BNE FOUNDC BRANCH IF RAM THIS PHYSICAL ADDR. + DECA ELSE POINT 4K LOWER + BPL FINDC GO TRY AGAIN + BRA XFERTF +FOUNDC CLR A,Y CLR XLATION FACTOR OF 4K BLOCK FOUND + STB $C,Y GIVE IT XLATION FACTOR MOVING IT TO $C--- +* +* THE FOLLOWING CODE ADJUSTS THE TRANSLATION +* FACTORS SUCH THAT ALL REMAINING RAM WILL +* RESPOND TO A CONTIGUOUS BLOCK OF LOGICAL +* ADDRESSES FROM $0000 AND UP.... +* + CLRA START AT ZERO + TFR Y,X START POINTER "X" START OF "LRARAM" TABLE. +COMPRS LDB A,Y GET ENTRY FROM "LRARAM" TABLE + BEQ PNTNXT IF IT'S ZER0 SKIP + CLR A,Y ELSE ERASE FROM TABLE + STB ,X+ AND ENTER ABOVE LAST ENTRY- BUMP +PNTNXT INCA GET OFFSET TO NEXT ENTRY + CMPA #$0C LAST ENTRY YET ? + BLT COMPRS +* +* THE FOLLOWING CODE TRANSFER THE TRANSLATION +* FACTORS FROM THE LRARAM TABLE TO IC11 ON +* THE MP-09 CPU CARD. +* +XFERTF LDX #IC11 POINT TO DAT RAM IC11 + LDB #$10 GET NO. OF BYTES TO MOVE +FETCH LDA ,Y+ GET BYTE AND POINT TO NEXT + STA ,X+ POKE XLATION FACTOR IN IC11 + DECB SUB 1 FROM BYTES TO MOVE + BNE FETCH CONTINUE UNTIL 16 MOVED + COMB SET "B" NON-ZERO + STB ECHO TURN ON ECHO FLAG + LBRA MONITOR INITIALIZATION IS COMPLETE +* +* +V1 JMP [STACK] +V2 JMP [SWI2] +V3 JMP [FIRQ] +V4 JMP [IRQ] +V5 JMP [SWI] +* +* SWI3 ENTRY POINT +* +SWI3E TFR S,U + LDX 10,U *$FFC8 + LDB ,X+ + STX 10,U + CLRA + ASLB + ROLA + LDX SVCVO + CMPX #$FFFF + BEQ SWI3Z + LEAX D,X + CMPX SVCVL + BHI SWI3Z + PSHS X + LDD ,U + LDX 4,U + JMP [,S++] +SWI3Z PULU A,B,X,CC,DP + LDU 2,U + JMP [SWI3] +* +* 6809 VECTORS +* + FDB V1 USER-V + FDB SWI3E SWI3-V + FDB V2 SWI2-V + FDB V3 FIRQ-V + FDB V4 IRQ-V + FDB V5 SWI-V + FDB V1 NMI-V + FDB START RESTART-V + END START Index: tags/V10/sw/sbug_src.lst =================================================================== --- tags/V10/sw/sbug_src.lst (nonexistent) +++ tags/V10/sw/sbug_src.lst (revision 3) @@ -0,0 +1,1412 @@ +0001 * NAM SBUG18 MP-09 MONITOR +0002 OPT l + sbug_src.txt page 2 +0004 * +0005 * MONITOR PROGRAM FOR THE SOUTHWEST TECHNICAL +0006 * PRODUCTS MP-09 CPU BOARD AS COMMENTED BY.... +0007 * +0008 * ALLEN CLARK WALLACE WATSON +0009 * 2502 REGAL OAKS LANE 4815 EAST 97th AVE. +0010 * LUTZ, FLA. 33549 TEMPLE TERRACE, FLA. 33617 +0011 * PH. 813-977-0347 PH. 813-985-1359 +0012 * +0013 * MODIFIED TO SBUG09 VER 1.8 BY: RANDY JARRETT +0014 * 2561 NANTUCKET DR APT. E +0015 * ATLANTA, GA 30345 +0016 * PH. 404-320-1043 +0017 * +0018 * +0019 * *** COMMANDS *** +0020 * +0021 * CONTROL A = ALTER THE "A" ACCUMULATOR +0022 * CONTROL B = ALTER THE "B" ACCUMULATOR +0023 * CONTROL C = ALTER THE CONDITION CODE REGISTER +0024 * CONTROL D = ALTER THE DIRECT PAGE REGISTER +0025 * CONTROL P = ALTER THE PROGRAM COUNTER +0026 * CONTROL U = ALTER USER STACK POINTER +0027 * CONTROL X = ALTER "X" INDEX REGISTER +0028 * CONTROL Y = ALTER "Y" INDEX REGISTER +0029 * B hhhh = SET BREAKPOINT AT LOCATION $hhhh +0030 * D = BOOT A SWTPC 8 INCH FLOPPY SYSTEM +0031 * U = BOOT A SWTPC 5 INCH FLOPPY SYSTEM +0032 * E ssss-eeee = EXAMINE MEMORY FROM STARTING ADDRESS ssss +0033 * -TO ENDING ADDRESS eeee. +0034 * G = CONTINUE EXECUTION FROM BREAKPOINT OR SWI +0035 * L = LOAD TAPE +0036 * M hhhh = EXAMINE AND CHANGE MEMORY LOCATION hhhh +0037 * P ssss-eeee = PUNCH TAPE, START ssss TO END eeee ADDR. +0038 * Q ssss-eeee = TEST MEMORY FROM ssss TO eeee +0039 * R = DISPLAY REGISTER CONTENTS +0040 * S = DISPLAY STACK FROM ssss TO $DFC0 +0041 * X = REMOVE ALL BREAKPOINTS +0042 * +0043 * +0044 55aa TSTPAT EQU $55AA TEST PATTERN +0045 * +0046 * +0047 * +0048 dfc0 ORG $DFC0 +0049 dfc0 STACK RMB 2 TOP OF INTERNAL STACK / USER VECTOR +0050 dfc2 SWI3 RMB 2 SOFTWARE INTERRUPT VECTOR #3 +0051 dfc4 SWI2 RMB 2 SOFTWARE INTERRUPT VECTOR #2 +0052 dfc6 FIRQ RMB 2 FAST INTERRUPT VECTOR +0053 dfc8 IRQ RMB 2 INTERRUPT VECTOR +0054 dfca SWI RMB 2 SOFTWARE INTERRUPT VECTOR +0055 dfcc SVCVO RMB 2 SUPERVISOR CALL VECTOR ORGIN +0056 dfce SVCVL RMB 2 SUPERVISOR CALL VECTOR LIMIT +0057 dfd0 LRARAM RMB 16 LRA ADDRESSES +0058 dfe0 CPORT RMB 2 RE-VECTORABLE CONTROL PORT +0059 dfe2 ECHO RMB 1 ECHO FLAG +0060 dfe3 BPTBL RMB 24 BREAKPOINT TABLE BASE ADDR +0061 e004 ACIAS EQU $E004 CONTROL PORT +0062 e018 Comreg EQU $E018 COMMAND REGISTER +0063 e014 Drvreg EQU $E014 DRIVE REGISTER +0064 e01a Secreg EQU $E01A SECTOR REGISTER +0065 e01b Datreg EQU $E01B DATA REGISTER +0066 * +0067 f000 ADDREG EQU $F000 ADDRESS REGISTER +0068 f002 CNTREG EQU $F002 COUNT REGISTER +0069 f010 CCREG EQU $F010 CHANNEL CONTROL REGISTER +0070 f014 PRIREG EQU $F014 DMA PRIORITY REGISTER +0071 f015 AAAREG EQU $F015 ??? +0072 f016 BBBREG EQU $F016 ??? +0073 f020 COMREG EQU $F020 1791 COMMAND REGISTER +0074 f022 SECREG EQU $F022 SECTOR REGISTER +0075 f024 DRVREG EQU $F024 DRIVE SELECT LATCH +0076 f040 CCCREG EQU $F040 ??? +0077 * +0078 fff0 IC11 EQU $FFF0 DAT RAM CHIP +0079 * +0080 f800 ORG $F800 +0081 f800 f8 14 FDB MONITOR +0082 f802 f8 61 FDB NEXTCMD +0083 f804 fd cf FDB INCH +0084 f806 fd c9 FDB INCHE +0085 f808 fd df FDB INCHEK +0086 f80a fd ee FDB OUTCH +0087 f80c fd bd FDB PDATA +0088 f80e fd b1 FDB PCRLF +0089 f810 fd ad FDB PSTRNG +0090 f812 fb 81 FDB LRA +0091 * +0092 * MONITOR +0093 * +0094 * VECTOR ADDRESS STRING IS..... +0095 * $F8A1-$F8A1-$F8A1-$F8A1-$F8A1-$FAB0-$FFFF-$FFFF +0096 * +0097 f814 8e fe 4f MONITOR LDX #RAMVEC POINT TO VECTOR ADDR. STRING +0098 f817 10 8e df c0 LDY #STACK POINT TO RAM VECTOR LOCATION +0099 f81b c6 10 LDB #$10 BYTES TO MOVE = 16 +0100 f81d a6 80 LOOPA LDA ,X+ GET VECTOR BYTE +0101 f81f a7 a0 STA ,Y+ PUT VECTORS IN RAM / $DFC0-$DFCF +0102 f821 5a DECB SUBTRACT 1 FROM NUMBER OF BYTES TO MOVE +0103 f822 26 f9 BNE LOOPA CONTINUE UNTIL ALL VECTORS MOVED +0104 * +0105 * CONTENTS FROM TO FUNCTION +0106 * $F8A1 $FE40 $DFC0 USER-V +0107 * $F8A1 $FE42 $DFC2 SWI3-V +0108 * $F8A1 $FE44 $DFC4 SWI2-V +0109 * $F8A1 $FE46 $DFC6 FIRQ-V +0110 * $F8A1 $FE48 $DFC8 IRQ-V +0111 * $FAB0 $FE4A $DFCA SWI-V +0112 * $FFFF $FE4C $DFCC SVC-VO +0113 * $FFFF $FE4E $DFCE SVC-VL +0114 * +0115 f824 8e e0 04 LDX #ACIAS GET CONTROL PORT ADDR. +0116 f827 bf df e0 STX CPORT STORE ADDR. IN RAM +0117 f82a 17 02 7a LBSR XBKPNT CLEAR OUTSTANDING BREAKPOINTS +0118 f82d c6 0c LDB #12 CLEAR 12 BYTES ON STACK +0119 f82f 6f e2 CLRSTK CLR ,-S +0120 f831 5a DECB +0121 f832 26 fb BNE CLRSTK +0122 f834 30 8c dd LEAX MONITOR,PCR SET PC TO SBUG-E ENTRY +0123 f837 af 6a STX 10,S ON STACK +0124 f839 86 d0 LDA #$D0 PRESET CONDITION CODES ON STACK +0125 f83b a7 e4 STA ,S +0126 f83d 1f 43 TFR S,U +0127 f83f 17 05 be LBSR ACINIZ INITIALIZE CONTROL PORT +0128 f842 8e fe 5f LDX #MSG1 POINT TO 'SBUG 1.8' MESSAGE +0129 f845 17 05 75 LBSR PDATA PRINT MSG +0130 f848 8e df d0 LDX #LRARAM POINT TO LRA RAM STORAGE AREA +0131 f84b 4f CLRA START TOTAL AT ZERO +0132 f84c c6 0d LDB #13 TOTAL UP ALL ACTIVE RAM MEMORY +0133 f84e 6d 85 FNDREL TST B,X TEST FOR RAM AT NEXT LOC. +0134 f850 27 03 BEQ RELPAS IF NO RAM GO TO NEXT LOC. +0135 f852 8b 04 ADDA #4 ELSE ADD 4K TO TOTAL +0136 f854 19 DAA ADJ. TOTAL FOR DECIMAL +0137 f855 5a RELPAS DECB SUB. 1 FROM LOCS. TO TEST +0138 f856 2a f6 BPL FNDREL PRINT TOTAL OF RAM +0139 f858 17 05 26 LBSR OUT2H OUTPUT HEX BYTE AS ASCII +0140 f85b 8e fe 74 LDX #MSG2 POINT TO MSG 'K' CR/LF + 3 NULS +0141 f85e 17 05 5c LBSR PDATA PRINT MSG +0142 * +0143 ***** NEXTCMD ***** +0144 * +0145 f861 8e fe 7b NEXTCMD LDX #MSG3 POINT TO MSG ">" +0146 f864 17 05 46 LBSR PSTRNG PRINT MSG +0147 f867 17 05 65 LBSR INCH GET ONE CHAR. FROM TERMINAL +0148 f86a 84 7f ANDA #$7F STRIP PARITY FROM CHAR. +0149 f86c 81 0d CMPA #$0D IS IT CARRIAGE RETURN ? +0150 f86e 27 f1 BEQ NEXTCMD IF CR THEN GET ANOTHER CHAR. +0151 f870 1f 89 TFR A,B PUT CHAR. IN "B" ACCUM. +0152 f872 81 20 CMPA #$20 IS IT CONTROL OR DATA CHAR ? +0153 f874 2c 09 BGE PRTCMD IF CMD CHAR IS DATA, PRNT IT +0154 f876 86 5e LDA #'^ ELSE CNTRL CHAR CMD SO... +0155 f878 17 05 73 LBSR OUTCH PRINT "^" +0156 f87b 1f 98 TFR B,A RECALL CNTRL CMD CHAR +0157 f87d 8b 40 ADDA #$40 CONVERT IT TO ASCII LETTER +0158 f87f 17 05 6c PRTCMD LBSR OUTCH PRNT CMD CHAR +0159 f882 17 05 67 LBSR OUT1S PRNT SPACE +0160 f885 c1 60 CMPB #$60 +0161 f887 2f 02 BLE NXTCH0 +0162 f889 c0 20 SUBB #$20 +0163 * +0164 * +0165 ***** DO TABLE LOOKUP ***** +0166 * FOR COMMAND FUNCTIONS +0167 * +0168 * +0169 f88b 8e fe 13 NXTCH0 LDX #JMPTAB POINT TO JUMP TABLE +0170 f88e e1 80 NXTCHR CMPB ,X+ DOES COMMAND MATCH TABLE ENTRY ? +0171 f890 27 0f BEQ JMPCMD BRANCH IF MATCH FOUND +0172 f892 30 02 LEAX 2,X POINT TO NEXT ENTRY IN TABLE +0173 f894 8c fe 4f CMPX #TABEND REACHED END OF TABLE YET ? +0174 f897 26 f5 BNE NXTCHR IF NOT END, CHECK NEXT ENTRY +0175 f899 8e fe 7d LDX #MSG4 POINT TO MSG "WHAT?" +0176 f89c 17 05 1e LBSR PDATA PRINT MSG +0177 f89f 20 c0 BRA NEXTCMD IF NO MATCH, PRMPT FOR NEW CMD +0178 f8a1 ad 94 JMPCMD JSR [,X] JUMP TO COMMAND ROUTINE +0179 f8a3 20 bc BRA NEXTCMD PROMPT FOR NEW COMMAND +0180 * +0181 * "G" GO OR CONTINUE +0182 * +0183 f8a5 1f 34 GO TFR U,S +0184 f8a7 3b RTI RTI +0185 * +0186 * "R" DISPLAY REGISTERS +0187 * +0188 f8a8 8e fe 83 REGSTR LDX #MSG5 POINT TO MSG " - " +0189 f8ab 17 04 ff LBSR PSTRNG PRINT MSG +0190 f8ae 17 04 11 LBSR PRTSP $FCBF +0191 f8b1 17 04 19 LBSR PRTUS $FCCA +0192 f8b4 17 04 21 LBSR PRTDP $FCD5 +0193 f8b7 17 04 29 LBSR PRTIX $FCE0 +0194 f8ba 17 04 31 LBSR PRTIY $FCEB +0195 f8bd 8e fe 83 LDX #MSG5 POINT TO MSG " - " +0196 f8c0 17 04 ea LBSR PSTRNG PRINT MSG +0197 f8c3 17 04 33 LBSR PRTPC $FCF5 +0198 f8c6 17 04 3a LBSR PRTA $FCFF +0199 f8c9 17 04 41 LBSR PRTB $FD09 +0200 f8cc 16 04 48 LBRA PRTCC $FD13 +0201 * +0202 * +0203 * ALTER "PC" PROGRAM COUNTER +0204 * +0205 * +0206 f8cf 17 04 27 ALTRPC LBSR PRTPC $FCF5 PRINT MSG " PC = " +0207 f8d2 17 05 17 LBSR OUT1S OUTPUT SPACE +0208 f8d5 17 04 57 LBSR IN1ADR GET NEW CONTENTS FOR "PC" +0209 f8d8 29 02 BVS ALTPCD EXIT IF INVALID HEX +0210 f8da af 4a STX 10,U POKE IN NEW CONTENTS +0211 f8dc 39 ALTPCD RTS ; +0212 * +0213 * +0214 * ALTER "U" USER STACK POINTER +0215 * +0216 * +0217 f8dd 17 03 ed ALTRU LBSR PRTUS $FCCA PRINT MSG " US = " +0218 f8e0 17 05 09 LBSR OUT1S OUTPUT SPACE +0219 f8e3 17 04 49 LBSR IN1ADR +0220 f8e6 29 02 BVS ALTUD +0221 f8e8 af 48 STX 8,U +0222 f8ea 39 ALTUD RTS ; +0223 * +0224 * +0225 * ALTER "Y" INDEX REGISTER +0226 * +0227 * +0228 f8eb 17 04 00 ALTRY LBSR PRTIY PRINT MSG " IY = " +0229 f8ee 17 04 fb LBSR OUT1S OUTPUT SPACE +0230 f8f1 17 04 3b LBSR IN1ADR +0231 f8f4 29 02 BVS ALTYD +0232 f8f6 af 46 STX 6,U $F8F0 +0233 f8f8 39 ALTYD RTS ; +0234 * +0235 * +0236 * ALTER "X" INDEX REGISTER +0237 * +0238 * +0239 f8f9 17 03 e7 ALTRX LBSR PRTIX $FCE0 PRINT MSG " IX = " +0240 f8fc 17 04 ed LBSR OUT1S OUTPUT SPACE +0241 f8ff 17 04 2d LBSR IN1ADR +0242 f902 29 02 BVS ALTXD +0243 f904 af 44 STX 4,U +0244 f906 39 ALTXD RTS ; +0245 * +0246 * +0247 * ALTER "DP" DIRECT PAGE REGISTER +0248 * +0249 * +0250 f907 17 03 ce ALTRDP LBSR PRTDP $FCD5 PRINT MSG " DP = " +0251 f90a 17 04 df LBSR OUT1S OUTPUT SPACE +0252 f90d 17 04 30 LBSR BYTE INPUT BYTE (2 HEX CHAR) +0253 f910 29 02 BVS ALTDPD +0254 f912 a7 43 STA 3,U +0255 f914 39 ALTDPD RTS ; +0256 * +0257 * +0258 * ALTER "B" ACCUMULATOR +0259 * +0260 * +0261 f915 17 03 f5 ALTRB LBSR PRTB $FD09 PRINT MSG " B = " +0262 f918 17 04 d1 LBSR OUT1S OUTPUT SPACE +0263 f91b 17 04 22 LBSR BYTE INPUT BYTE (2 HEX CHAR) +0264 f91e 29 02 BVS ALTBD +0265 f920 a7 42 STA 2,U +0266 f922 39 ALTBD RTS $F91C +0267 * +0268 * +0269 * ALTER "A" ACCUMULATOR +0270 * +0271 * +0272 f923 17 03 dd ALTRA LBSR PRTA $FCFF RINT MSG " A = " +0273 f926 17 04 c3 LBSR OUT1S OUTPUT SPACE +0274 f929 17 04 14 LBSR BYTE INPUT BYTE (2 HEX CHAR) +0275 f92c 29 02 BVS ALTAD +0276 f92e a7 41 STA 1,U +0277 f930 39 ALTAD RTS ; +0278 * +0279 * +0280 * ALTER "CC" REGISTER +0281 * +0282 * +0283 f931 17 03 e3 ALTRCC LBSR PRTCC $FD13 PRINT MSG " CC: " +0284 f934 17 04 b5 LBSR OUT1S OUTPUT SPACE +0285 f937 17 04 06 LBSR BYTE INPUT BYTE (2 HEX CHAR) +0286 f93a 29 04 BVS ALTCCD +0287 f93c 8a 80 ORA #$80 SETS "E" FLAG IN PRINT LIST +0288 f93e a7 c4 STA ,U +0289 f940 39 ALTCCD RTS ; +0290 * +0291 ***** "M" MEMORY EXAMINE AND CHANGE ***** +0292 * +0293 f941 17 03 eb MEMCHG LBSR IN1ADR INPUT ADDRESS +0294 f944 29 2d BVS CHRTN IF NOT HEX, RETURN +0295 f946 1f 12 TFR X,Y SAVE ADDR IN "Y" +0296 f948 8e fe 83 MEMC2 LDX #MSG5 POINT TO MSG " - " +0297 f94b 17 04 5f LBSR PSTRNG PRINT MSG +0298 f94e 1f 21 TFR Y,X FETCH ADDRESS +0299 f950 17 04 26 LBSR OUT4H PRINT ADDR IN HEX +0300 f953 17 04 96 LBSR OUT1S OUTPUT SPACE +0301 f956 a6 a4 LDA ,Y GET CONTENTS OF CURRENT ADDR. +0302 f958 17 04 26 LBSR OUT2H OUTPUT CONTENTS IN ASCII +0303 f95b 17 04 8e LBSR OUT1S OUTPUT SPACE +0304 f95e 17 03 df LBSR BYTE LOOP WAITING FOR OPERATOR INPUT +0305 f961 28 11 BVC CHANGE IF VALID HEX GO CHANGE MEM. LOC. +0306 f963 81 08 CMPA #8 IS IT A BACKSPACE (CNTRL H)? +0307 f965 27 e1 BEQ MEMC2 PROMPT OPERATOR AGAIN +0308 f967 81 18 CMPA #$18 IS IT A CANCEL (CNTRL X)? +0309 f969 27 dd BEQ MEMC2 PROMPT OPERATOR AGAIN +0310 f96b 81 5e CMPA #'^ IS IT AN UP ARROW? +0311 f96d 27 17 BEQ BACK DISPLAY PREVIOUS BYTE +0312 f96f 81 0d CMPA #$D IS IT A CR? +0313 f971 26 0f BNE FORWRD DISPLAY NEXT BYTE +0314 f973 39 CHRTN RTS EXIT ROUTINE +0315 * +0316 * +0317 f974 a7 a4 CHANGE STA ,Y CHANGE BYTE IN MEMORY +0318 f976 a1 a4 CMPA ,Y DID MEMORY BYTE CHANGE? +0319 f978 27 08 BEQ FORWRD $F972 +0320 f97a 17 04 6f LBSR OUT1S OUTPUT SPACE +0321 f97d 86 3f LDA #'? LOAD QUESTION MARK +0322 f97f 17 04 6c LBSR OUTCH PRINT IT +0323 f982 31 21 FORWRD LEAY 1,Y POINT TO NEXT HIGHER MEM LOCATION +0324 f984 20 c2 BRA MEMC2 PRINT LOCATION & CONTENTS +0325 f986 31 3f BACK LEAY -1,Y POINT TO LAST MEM LOCATION +0326 f988 20 be BRA MEMC2 PRINT LOCATION & CONTENTS +0327 * +0328 * "S" DISPLAY STACK +0329 * HEX-ASCII DISPLAY OF CURRENT STACK CONTENTS FROM +0330 ** CURRENT STACK POINTER TO INTERNAL STACK LIMIT. +0331 * +0332 f98a 17 03 35 DISSTK LBSR PRTSP PRINT CURRENT STACK POINTER +0333 f98d 1f 32 TFR U,Y +0334 f98f 8e df c0 LDX #STACK LOAD INTERNAL STACK AS UPPER LIMIT +0335 f992 30 1f LEAX -1,X POINT TO CURRENT STACK +0336 f994 20 05 BRA MDUMP1 ENTER MEMORY DUMP OF STACK CONTENTS +0337 * +0338 * "E" DUMP MEMORY FOR EXAMINE IN HEX AND ASCII +0339 * AFTER CALLING 'IN2ADR' LOWER ADDRESS IN Y-REG. +0340 * UPPER ADDRESS IN X-REG. +0341 * IF HEX ADDRESSES ARE INVALID (V)=1. +0342 * +0343 f996 17 03 8b MEMDUMP LBSR IN2ADR INPUT ADDRESS BOUNDRIES +0344 f999 29 06 BVS EDPRTN NEW COMMAND IF ILLEGAL HEX +0345 f99b 34 20 MDUMP1 PSHS Y COMPARE LOWER TO UPPER BOUNDS +0346 f99d ac e1 CMPX ,S++ LOWER BOUNDS > UPPER BOUNDS? +0347 f99f 24 01 BCC AJDUMP IF NOT, DUMP HEX AND ASCII +0348 f9a1 39 EDPRTN RTS ; +0349 * +0350 * ADJUST LOWER AND UPPER ADDRESS LIMITS +0351 * TO EVEN 16 BYTE BOUNDRIES. +0352 * +0353 * IF LOWER ADDR = $4532 +0354 * LOWER BOUNDS WILL BE ADJUSTED TO = $4530. +0355 * +0356 * IF UPPER ADDR = $4567 +0357 * UPPER BOUNDS WILL BE ADJUSTED TO = $4570. +0358 * +0359 * ENTER WITH LOWER ADDRESS IN X-REG. +0360 * -UPPER ADDRESS ON TOP OF STACK. +0361 * +0362 f9a2 1f 10 AJDUMP TFR X,D GET UPPER ADDR IN D-REG +0363 f9a4 c3 00 10 ADDD #$10 ADD 16 TO UPPER ADDRESS +0364 f9a7 c4 f0 ANDB #$F0 MASK TO EVEN 16 BYTE BOUNDRY +0365 f9a9 34 06 PSHS A,B SAVE ON STACK AS UPPER DUMP LIMIT +0366 f9ab 1f 20 TFR Y,D $F9A5 GET LOWER ADDRESS IN D-REG +0367 f9ad c4 f0 ANDB #$F0 MASK TO EVEN 16 BYTE BOUNDRY +0368 f9af 1f 01 TFR D,X PUT IN X-REG AS LOWER DUMP LIMIT +0369 f9b1 ac e4 NXTLIN CMPX ,S COMPARE LOWER TO UPPER LIMIT +0370 f9b3 27 05 BEQ SKPDMP IF EQUAL SKIP HEX-ASCII DUMP +0371 f9b5 17 04 27 LBSR INCHEK CHECK FOR INPUT FROM KEYBOARD +0372 f9b8 27 03 BEQ EDUMP IF NONE, CONTINUE WITH DUMP +0373 f9ba 32 62 SKPDMP LEAS 2,S READJUST STACK IF NOT DUMPING +0374 f9bc 39 RTS ; +0375 * +0376 * PRINT 16 HEX BYTES FOLLOWED BY 16 ASCII CHARACTERS +0377 * FOR EACH LINE THROUGHOUT ADDRESS LIMITS. +0378 * +0379 f9bd 34 10 EDUMP PSHS X PUSH LOWER ADDR LIMIT ON STACK +0380 f9bf 8e fe 83 LDX #MSG5 POINT TO MSG " - " +0381 f9c2 17 03 e8 LBSR PSTRNG PRINT MSG +0382 f9c5 ae e4 LDX ,S LOAD LOWER ADDR FROM TOP OF STACK +0383 f9c7 17 03 af LBSR OUT4H PRINT THE ADDRESS LBSR OUT2S PRINT 2 SPACES +0384 f9ca c6 10 LDB #$10 LOAD COUNT OF 16 BYTES TO DUMP +0385 f9cc a6 80 ELOOP LDA ,X+ GET FROM MEMORY HEX BYTE TO PRINT +0386 f9ce 17 03 b0 LBSR OUT2H OUTPUT HEX BYTE AS ASCII +0387 f9d1 17 04 18 LBSR OUT1S OUTPUT SPACE +0388 f9d4 5a DECB $F9D1 DECREMENT BYTE COUNT +0389 f9d5 26 f5 BNE ELOOP CONTINUE TIL 16 HEX BYTES PRINTED +0390 * +0391 * PRINT 16 ASCII CHARACTERS +0392 * IF NOT PRINTABLE OR NOT VALID +0393 * ASCII PRINT A PERIOD (.) +0394 f9d7 17 04 10 LBSR OUT2S 2 SPACES +0395 f9da ae e1 LDX ,S++ GET LOW LIMIT FRM STACK - ADJ STACK +0396 f9dc c6 10 LDB #$10 SET ASCII CHAR TO PRINT = 16 +0397 f9de a6 80 EDPASC LDA ,X+ GET CHARACTER FROM MEMORY +0398 f9e0 81 20 CMPA #$20 IF LESS THAN $20, NON-PRINTABLE? +0399 f9e2 25 04 BCS PERIOD IF SO, PRINT PERIOD INSTEAD +0400 f9e4 81 7e CMPA #$7E IS IT VALID ASCII? +0401 f9e6 23 02 BLS PRASC IF SO PRINT IT +0402 f9e8 86 2e PERIOD LDA #'. LOAD A PERIOD (.) +0403 f9ea 17 04 01 PRASC LBSR OUTCH PRINT ASCII CHARACTER +0404 f9ed 5a DECB DECREMENT COUNT +0405 f9ee 26 ee BNE EDPASC +0406 f9f0 20 bf BRA NXTLIN +0407 * +0408 ***** "Q" MEMORY TEST ***** +0409 * +0410 f9f2 6f e2 MEMTST CLR ,-S CLEAR BYTE ON STACK +0411 f9f4 6f e2 CLR ,-S CLEAR ANOTHER BYTE +0412 f9f6 17 03 2b LBSR IN2ADR GET BEGIN(Y) & END(X) ADDR. LIMITS +0413 f9f9 34 30 PSHS X,Y SAVE ADDRESSES ON STACK +0414 f9fb 29 7b BVS ADJSK6 EXIT IF NOT VALID HEX +0415 f9fd ac 62 CMPX 2,S COMPARE BEGIN TO END ADDR. +0416 f9ff 25 77 BCS ADJSK6 EXIT IF BEGIN > END ADDR. +0417 fa01 17 03 e8 LBSR OUT1S OUTPUT SPACE +0418 fa04 1f 20 MEMSET TFR Y,D PUT BEGIN ADDR. IN 'D'-ACCUM. +0419 fa06 e3 64 ADDD 4,S ADD PASS COUNT TO BEGIN ADDR +0420 fa08 34 04 PSHS B ADD LS BYTE TO MS BYTE OF BEGIN ADDR +0421 fa0a ab e0 ADDA ,S+ +0422 fa0c a7 a0 STA ,Y+ SAVE THIS DATA BYTE AT BEGIN ADDR +0423 fa0e 10 ac e4 CMPY ,S COMPARE END TO BEGIN ADDR +0424 fa11 25 f1 BCS MEMSET IF BEGIN LOWER, CONTINUE TO SET MEMORY +0425 fa13 10 ae 62 LDY 2,S RELOAD BEGIN ADDRESS +0426 fa16 1f 20 TEST1 TFR Y,D PUT BEGIN ADDR IN 'D'-ACC. +0427 fa18 e3 64 ADDD 4,S ADD PASS COUNT TO ADDRESS +0428 fa1a 34 02 PSHS A ADD MS BYTE TO LS BYTE OF ADDRESS +0429 fa1c eb e0 ADDB ,S+ +0430 fa1e e8 a0 EORB ,Y+ EX-OR THIS DATA WITH DATA IN MEMORY LOC. +0431 fa20 27 3c BEQ GUDPAS IF (Z) SET, MEMORY BYTE OK +0432 fa22 8e fe 83 LDX #MSG5 POINT TO MSG " - " +0433 fa25 17 03 85 LBSR PSTRNG PRINT MSG +0434 fa28 30 3f LEAX -1,Y GET ERROR ADDRESS IN X-REG +0435 fa2a 17 03 4c LBSR OUT4H OUTPUT IT +0436 fa2d 34 10 PSHS X PUSH ERROR ADDR ON STACK +0437 fa2f 8e fe a1 LDX #MSG8 POINT TO MSG " =>" +0438 fa32 17 03 88 LBSR PDATA PRINT MSG +0439 fa35 35 10 PULS X POP ERROR ADDR FROM STACK +0440 fa37 17 01 47 LBSR LRA GET PHYSICAL ADDR FROM LRA +0441 fa3a 17 03 50 LBSR XASCII OUTPUT EXTENDED 4 BITS OF PHYSICAL ADDR +0442 fa3d 17 03 39 LBSR OUT4H OUTPUT LS 16 BITS OF PHYSICAL ADDR +0443 fa40 8e fe 87 LDX #MSG6 POINT TO MSG ", PASS " +0444 fa43 17 03 77 LBSR PDATA PRINT MSG +0445 fa46 ae 64 LDX 4,S LOAD PASS COUNT +0446 fa48 17 03 2e LBSR OUT4H OUTPUT IT +0447 fa4b 8e fe 8f LDX #MSG7 POINT TO MSG ", BITS IN ERROR +0448 fa4e 17 03 6c LBSR PDATA PRINT MSG +0449 fa51 1f 98 TFR B,A GET ERROR BYTE INTO A-ACC +0450 fa53 8e fe a6 LDX #MSG9 POINT TO MSG "76543210" +0451 fa56 17 03 3e LBSR BIASCI OUTPUT IN BINARY/ASCII FORMAT +0452 fa59 17 03 83 LBSR INCHEK CHECK FOR INPUT FROM KEYBOARD $FA56 +0453 fa5c 26 1a BNE ADJSK6 IF SO, EXIT MEMORY TEST +0454 fa5e 10 ac e4 GUDPAS CMPY ,S COMPARE END ADDR TO BEGIN ADDR +0455 fa61 25 b3 BCS TEST1 +0456 fa63 86 2b LDA #'+ GET "PASS" SYMBOL IF MEMORY PASS OK +0457 fa65 17 03 86 LBSR OUTCH OUTPUT SYMBOL TO TERMINAL +0458 fa68 17 03 74 LBSR INCHEK INPUT FROM KEYBOARD? +0459 fa6b 26 0b BNE ADJSK6 IF SO, EXIT MEMORY TEST +0460 fa6d 10 ae 62 LDY 2,S LOAD BEGIN ADDRESS +0461 fa70 6c 65 INC 5,S INCREMENT LS BYTE OF PASS COUNT +0462 fa72 26 90 BNE MEMSET IF NOT ZERO, SET NEXT MEMORY BYTE +0463 fa74 6c 64 INC 4,S INCREMENT MS BYTE OF PASS COUNT +0464 fa76 26 8c BNE MEMSET DONE WITH 65,535 PASSES OF MEMORY? +0465 fa78 32 66 ADJSK6 LEAS 6,S ADJ STACK POINTER BY 6 +0466 fa7a 39 RTS +0467 * +0468 ***** "B" SET BREAKPOINT ***** +0469 * +0470 fa7b 17 02 b1 BRKPNT LBSR IN1ADR GET BREAKPOINT ADDRESS +0471 fa7e 29 1e BVS EXITBP EXIT IF INVALID HEX ADDR. +0472 fa80 8c df c0 CMPX #STACK ADDRESS ILLEGAL IF >=$DFC0 +0473 fa83 24 1a BCC BPERR IF ERROR PRINT (?), EXIT +0474 fa85 34 10 PSHS X $FA82 PUSH BP ADDRESS ON STACK +0475 fa87 8e ff ff LDX #$FFFF LOAD DUMMY ADDR TO TEST BP TABLE +0476 fa8a 8d 55 BSR BPTEST TEST BP TABLE FOR FREE SPACE +0477 fa8c 35 10 PULS X POP BP ADDRESS FROM STACK +0478 fa8e 27 0f BEQ BPERR (Z) SET, OUT OF BP TABLE SPACE +0479 fa90 a6 84 LDA ,X GET DATA AT BREAKPOINT ADDRESS +0480 fa92 81 3f CMPA #$3F IS IT A SWI? +0481 fa94 27 09 BEQ BPERR IF SWI ALREADY, INDICATE ERROR +0482 fa96 a7 a0 STA ,Y+ SAVE DATA BYTE IN BP TABLE +0483 fa98 af a4 STX ,Y SAVE BP ADDRESS IN BP TABLE +0484 fa9a 86 3f LDA #$3F LOAD A SWI ($3F) +0485 fa9c a7 84 STA ,X SAVE SWI AT BREAKPOINT ADDRESS +0486 fa9e 39 EXITBP RTS ; +0487 * +0488 * INDICATE ERROR SETTING BREAKPOINT +0489 * +0490 fa9f 17 03 4a BPERR LBSR OUT1S OUTPUT SPACE +0491 faa2 86 3f LDA #'? LOAD (?), INDICATE BREAKPOINT ERROR +0492 faa4 16 03 47 LBRA OUTCH PRINT "?" +0493 * +0494 *** "X" CLEAR OUTSTANDING BREAKPOINTS *** +0495 * +0496 faa7 10 8e df e3 XBKPNT LDY #BPTBL POINT TO BREAKPOINT TABLE +0497 faab c6 08 LDB #8 LOAD BREAKPOINT COUNTER +0498 faad 8d 18 XBPLP BSR RPLSWI REMOVE USED ENTRY IN BP TABLE +0499 faaf 5a DECB $FAAC DECREMENT BP COUNTER +0500 fab0 26 fb BNE XBPLP END OF BREAKPOINT TABLE? +0501 fab2 39 RTS +0502 * +0503 ***** SWI ENTRY POINT ***** +0504 * +0505 fab3 1f 43 SWIE TFR S,U TRANSFER STACK TO USER POINTER +0506 fab5 ae 4a LDX 10,U LOAD PC FROM STACK INTO X-REG +0507 fab7 30 1f LEAX -1,X ADJUST ADDR DOWN 1 BYTE. +0508 fab9 8d 26 BSR BPTEST FIND BREAKPOINT IN BP TABLE +0509 fabb 27 04 BEQ REGPR IF FOUND, REPLACE DATA AT BP ADDR +0510 fabd af 4a STX 10,U SAVE BREAKPOINT ADDR IN STACK +0511 fabf 8d 06 BSR RPLSWI GO REPLACE SWI WITH ORIGINAL DATA +0512 fac1 17 fd e4 REGPR LBSR REGSTR GO PRINT REGISTERS +0513 fac4 16 fd 9a LBRA NEXTCMD GET NEXT COMMAND +0514 fac7 ae 21 RPLSWI LDX 1,Y LOAD BP ADDRESS FROM BP TABLE +0515 fac9 8c df c0 CMPX #STACK COMPARE TO TOP AVAILABLE USER MEMORY +0516 facc 24 0a BCC FFSTBL GO RESET TABLE ENTRY TO $FF'S +0517 face a6 84 LDA ,X GET DATA FROM BP ADDRESS +0518 fad0 81 3f CMPA #$3F IS IT SWI? +0519 fad2 26 04 BNE FFSTBL IF NOT, RESET TABLE ENTRY TO $FF'S +0520 fad4 a6 a4 LDA ,Y GET ORIGINAL DATA FROM BP TABLE +0521 fad6 a7 84 STA ,X $FAD3 RESTORE DATA AT BP ADDRESS +0522 fad8 86 ff FFSTBL LDA #$FF LOAD $FF IN A-ACC +0523 fada a7 a0 STA ,Y+ RESET BREAKPOINT TABLE DATA TO $FF'S +0524 fadc a7 a0 STA ,Y+ RESET BREAKPOINT TABLE ADDR TO $FF'S +0525 fade a7 a0 STA ,Y+ +0526 fae0 39 RTS +0527 * +0528 ** SEARCH BREAKPOINT TABLE FOR MATCH ** +0529 * +0530 fae1 10 8e df e3 BPTEST LDY #BPTBL POINT TO BREAKPOINT TABLE +0531 fae5 c6 08 LDB #8 LOAD BREAKPOINT COUNTER +0532 fae7 a6 a0 FNDBP LDA ,Y+ LOAD DATA BYTE +0533 fae9 ac a1 CMPX ,Y++ COMPARE ADDRESS, IS IT SAME? +0534 faeb 27 04 BEQ BPADJ IF SO, ADJUST POINTER FOR TABLE ENTRY +0535 faed 5a DECB IF NOT, DECREMENT BREAKPOINT COUNTER +0536 faee 26 f7 BNE FNDBP AND LOOK FOR NEXT POSSIBLE MATCH +0537 faf0 39 RTS ; +0538 * +0539 * +0540 faf1 31 3d BPADJ LEAY -3,Y MOVE POINTER TO BEGIN OF BP ENTRY +0541 faf3 39 RTS +0542 * +0543 *** "D" DISK BOOT FOR DMAF2 *** +0544 * +0545 faf4 86 de DBOOT LDA #$DE +0546 faf6 b7 f0 24 STA DRVREG +0547 faf9 86 ff LDA #$FF +0548 fafb b7 f0 14 STA PRIREG $FAF8 +0549 fafe b7 f0 10 STA CCREG +0550 fb01 b7 f0 15 STA AAAREG +0551 fb04 b7 f0 16 STA BBBREG +0552 fb07 7d f0 10 TST CCREG +0553 fb0a 86 d8 LDA #$D8 +0554 fb0c b7 f0 20 STA COMREG +0555 fb0f 17 00 97 LBSR DLY +0556 fb12 b6 f0 20 DBOOT0 LDA COMREG +0557 fb15 2b fb BMI DBOOT0 +0558 fb17 86 09 LDA #$09 +0559 fb19 b7 f0 20 STA COMREG +0560 fb1c 17 00 8a LBSR DLY +0561 * +0562 fb1f b6 f0 20 DISKWT LDA COMREG FETCH DRIVE STATUS +0563 fb22 85 01 BITA #1 TEST BUSY BIT +0564 fb24 26 f9 BNE DISKWT LOOP UNTIL NOT BUSY +0565 * +0566 fb26 85 10 BITA #$10 +0567 fb28 26 ca BNE DBOOT +0568 * +0569 fb2a 8e c0 00 LDX #$C000 LOGICAL ADDR. = $C000 +0570 fb2d 8d 52 BSR LRA GET 20 BIT PHYSICAL ADDR. OF LOG. ADDR. +0571 fb2f 8a 10 ORA #$10 +0572 fb31 b7 f0 40 STA CCCREG +0573 fb34 1f 10 TFR X,D +0574 fb36 43 COMA ; +0575 fb37 53 COMB ; +0576 fb38 fd f0 00 STD ADDREG +0577 fb3b 8e fe ff LDX #$FEFF LOAD DMA BYTE COUNT = $100 +0578 fb3e bf f0 02 STX CNTREG STORE IN COUNT REGISTER +0579 fb41 86 ff LDA #$FF LOAD THE CHANNEL REGISTER +0580 fb43 b7 f0 10 STA CCREG +0581 fb46 86 fe LDA #$FE SET CHANNEL 0 +0582 fb48 b7 f0 14 STA PRIREG +0583 fb4b 86 01 LDA #1 SET SECTOR TO "1" +0584 fb4d b7 f0 22 STA SECREG ISSUE COMMAND +0585 fb50 86 8c LDA #$8C SET SINGLE SECTOR READ +0586 fb52 b7 f0 20 STA COMREG ISSUE COMMAND +0587 fb55 8d 52 BSR DLY +0588 * +0589 * THE FOLLOWING CODE TESTS THE STATUS OF THE +0590 * CHANNEL CONTROL REGISTER. IF "D7" IS NOT +0591 * ZERO THEN IT WILL LOOP WAITING FOR "D7" +0592 * TO GO TO ZERO. IF AFTER 65,536 TRIES IT +0593 * IS STILL A ONE THE BOOT OPERATION WILL +0594 * BE STARTED OVER FROM THE BEGINING. +0595 * +0596 fb57 5f CLRB ; +0597 fb58 34 04 DBOOT1 PSHS B $FB55 +0598 fb5a 5f CLRB ; +0599 fb5b 7d f0 10 DBOOT2 TST CCREG +0600 fb5e 2a 0a BPL DBOOT3 +0601 fb60 5a DECB ; +0602 fb61 26 f8 BNE DBOOT2 +0603 fb63 35 04 PULS B +0604 fb65 5a DECB +0605 fb66 26 f0 BNE DBOOT1 +0606 fb68 20 8a BRA DBOOT +0607 fb6a 35 04 DBOOT3 PULS B +0608 fb6c b6 f0 20 LDA COMREG +0609 fb6f 85 1c BITA #$1C +0610 fb71 27 01 BEQ DBOOT4 +0611 fb73 39 RTS ; +0612 * +0613 * +0614 fb74 c6 de DBOOT4 LDB #$DE +0615 fb76 f7 f0 24 STB DRVREG +0616 fb79 8e c0 00 LDX #$C000 +0617 fb7c af 4a STX 10,U +0618 fb7e 1f 34 TFR U,S $FB7B +0619 fb80 3b RTI ; +0620 * +0621 ***** LRA LOAD REAL ADDRESS ***** +0622 * +0623 * THE FOLLOWING CODE LOADS THE 20-BIT +0624 * PHYSICAL ADDRESS OF A MEMORY BYTE +0625 * INTO THE "A" AND "X" REGISTERS. THIS +0626 * ROUTINE IS ENTERED WITH THE LOGICAL +0627 * ADDRESS OF A MEMORY BYTE IN THE "IX" +0628 * REGISTER. EXIT IS MADE WITH THE HIGH- +0629 * ORDER FOUR BITS OF THE 20-BIT PHYSICAL +0630 * ADDRESS IN THE "A" REGISTER, AND THE +0631 * LOW-ORDER 16-BITS OF THE 20-BIT +0632 * PHYSICAL ADDRESS IN THE "IX" REGISTER. +0633 * ALL OTHER REGISTERS ARE PRESERVED. +0634 * THIS ROUTINE IS REQUIRED SINCE THE +0635 * DMAF1 AND DMAF2 DISK CONTROLLERS MUST +0636 * PRESENT PHYSICAL ADDRESSES ON THE +0637 * SYSTEM BUS. +0638 * +0639 fb81 34 36 LRA PSHS A,B,X,Y PUSH REGISTERS ON STACK +0640 fb83 a6 62 LDA 2,S GET MSB LOGICAL ADDR FRM X REG ON STACK +0641 fb85 44 LSRA ; +0642 fb86 44 LSRA ADJ FOR INDEXED INTO +0643 fb87 44 LSRA CORRESPONDING LOCATION +0644 fb88 44 LSRA IN LRA TABLE +0645 fb89 10 8e df d0 LDY #LRARAM LOAD LRA TABLE BASE ADDRESS +0646 fb8d e6 a6 LDB A,Y GET PHYSICAL ADDR. DATA FROM LRA TABLE +0647 fb8f 54 LSRB ADJ. REAL ADDR. TO REFLECT EXTENDED +0648 fb90 54 LSRB PHYSICAL ADDRESS. +0649 fb91 54 LSRB EXTENDED MS 4-BITS ARE RETURNED +0650 fb92 54 LSRB IN THE "A" ACCUMULATOR +0651 fb93 e7 e4 STB ,S MS 4 BITS IN A ACCUM. STORED ON STACK +0652 fb95 e6 a6 LDB A,Y LOAD REAL ADDRESS DATA FROM LRA TABLE +0653 fb97 53 COMB COMP TO ADJ FOR PHYSICAL ADDR. IN X REG +0654 fb98 58 ASLB ADJ DATA FOR RELOCATION IN X REG +0655 fb99 58 ASLB ; +0656 fb9a 58 ASLB $FB97 +0657 fb9b 58 ASLB ; +0658 fb9c a6 62 LDA 2,S GET MS BYTE OF LOGICAL ADDR. +0659 fb9e 84 0f ANDA #$0F MASK MS NIBBLE OF LOGICAL ADDRESS +0660 fba0 a7 62 STA 2,S SAVE IT IN X REG ON STACK +0661 fba2 ea 62 ORB 2,S SET MS BYTE IN X REG TO ADJ PHY ADDR. +0662 * +0663 * PLUS LS NIBBLE OF LOGICAL ADDRESS +0664 fba4 e7 62 STB 2,S SAVE AS LS 16 BITS OF PHY ADDR IN X REG +0665 * ON STACK +0666 fba6 35 36 PULS A,B,X,Y POP REGS. FROM STACK +0667 fba8 39 RTS ; +0668 * +0669 * DELAY LOOP +0670 * +0671 fba9 34 04 DLY PSHS B SAVE CONTENTS OF "B" +0672 fbab c6 20 LDB #$20 GET LOOP DELAY VALUE +0673 fbad 5a SUB1 DECB SUBTRACT ONE FROM VALUE +0674 fbae 26 fd BNE SUB1 LOOP UNTIL ZERO +0675 fbb0 35 04 PULS B RESTORE CONTENTS OF "B" +0676 fbb2 39 RTS ; +0677 * +0678 ***** "U" MINIDISK BOOT ***** +0679 * +0680 fbb3 7d e0 18 MINBOOT TST Comreg +0681 fbb6 7f e0 14 CLR Drvreg SELECT DRIVE 0 +0682 * +0683 * DELAY BEFORE ISSUING RESTORE COMMAND +0684 fbb9 c6 03 LDB #3 +0685 fbbb 8e 00 00 LDX #0 +0686 fbbe 30 01 LOOP LEAX 1,X $FBBB +0687 fbc0 8c 00 00 CMPX #0 +0688 fbc3 26 f9 BNE LOOP +0689 fbc5 5a DECB $FBC2 +0690 fbc6 26 f6 BNE LOOP +0691 * +0692 fbc8 86 0f LDA #$0F *LOAD HEAD, VERIFY, 20msec/step +0693 fbca b7 e0 18 STA Comreg ISSUE RESTORE COMMAND +0694 fbcd 8d 37 BSR DELAY +0695 fbcf f6 e0 18 LOOP1 LDB Comreg $FBCC +0696 fbd2 c5 01 BITB #1 +0697 fbd4 26 f9 BNE LOOP1 LOOP UNTIL THRU +0698 fbd6 86 01 LDA #1 +0699 fbd8 b7 e0 1a STA Secreg SET SECTOR REGISTER TO ONE +0700 fbdb 8d 29 BSR DELAY +0701 fbdd 86 8c LDA #$8C LOAD HEAD, DELAY 10msec, +0702 fbdf b7 e0 18 STA Comreg AND READ SINGLE RECORD +0703 fbe2 8d 22 BSR DELAY +0704 fbe4 8e c0 00 LDX #$C000 +0705 fbe7 20 09 BRA LOOP3 +0706 * +0707 fbe9 c5 02 LOOP2 BITB #2 $FBE6 DRQ? +0708 fbeb 27 05 BEQ LOOP3 +0709 fbed b6 e0 1b LDA Datreg +0710 fbf0 a7 80 STA ,X+ +0711 * +0712 fbf2 f6 e0 18 LOOP3 LDB Comreg FETCH STATUS +0713 fbf5 c5 01 BITB #1 BUSY? +0714 fbf7 26 f0 BNE LOOP2 +0715 fbf9 c5 2c BITB #$2C CRC ERROR OR LOST DATA? +0716 fbfb 27 01 BEQ LOOP4 +0717 fbfd 39 RTS ; +0718 fbfe 8e c0 00 LOOP4 LDX #$C000 $FBFB +0719 fc01 af 4a STX 10,U +0720 fc03 1f 34 TFR U,S +0721 fc05 3b RTI ; +0722 * +0723 * DELAY +0724 * +0725 fc06 c6 20 DELAY LDB #$20 +0726 fc08 5a LOOP5 DECB ; +0727 fc09 26 fd BNE LOOP5 +0728 fc0b 39 RTS ; +0729 * +0730 ***** "L" LOAD MIKBUG TAPE ***** +0731 * +0732 fc0c 86 11 LOAD LDA #$11 LOAD 'DC1' CASS. READ ON CODE +0733 fc0e 17 01 dd LBSR OUTCH OUTPUT IT TO TERMINAL PORT +0734 fc11 7f df e2 CLR ECHO TURN OFF ECHO FLAG +0735 fc14 17 01 ad LOAD1 LBSR ECHON INPUT 8 BIT BYTE WITH NO ECHO +0736 fc17 81 53 LOAD2 CMPA #'S IS IT AN "S", START CHARACTER ? +0737 fc19 26 f9 BNE LOAD1 IF NOT, DISCARD AND GET NEXT CHAR. +0738 fc1b 17 01 a6 LBSR ECHON +0739 fc1e 81 39 CMPA #'9 IS IT A "9" , END OF FILE CHAR ? +0740 fc20 27 3d BEQ LOAD21 IF SO, EXIT LOAD +0741 fc22 81 31 CMPA #'1 IS IT A "1" , FILE LOAD CHAR ? +0742 fc24 26 f1 BNE LOAD2 IF NOT, LOOK FOR START CHAR. +0743 fc26 17 01 17 LBSR BYTE INPUT BYTE COUNT +0744 fc29 34 02 PSHS A PUSH COUNT ON STACK +0745 fc2b 29 26 BVS LODERR (V) C-CODE SET, ILLEGAL HEX +0746 fc2d 17 00 ff LBSR IN1ADR INPUT LOAD ADDRESS +0747 fc30 29 21 BVS LODERR (V) C-CODE SET, ADDR NOT HEX +0748 fc32 34 10 PSHS X PUSH ADDR ON STACK +0749 fc34 e6 e0 LDB ,S+ LOAD MSB OF ADDR AS CHECKSUM BYTE +0750 fc36 eb e0 ADDB ,S+ ADD LSB OF ADDR TO CHECKSUM +0751 fc38 eb e4 ADDB ,S ADD BYTE COUNT BYTE TO CHECKSUM +0752 fc3a 6a e4 DEC ,S $FC37 DECREMENT BYTE COUNT 2 TO BYPASS +0753 fc3c 6a e4 DEC ,S ADDRESS BYTES. +0754 fc3e 34 04 LOAD10 PSHS B PUSH CHECKSUM ON STACK +0755 fc40 17 00 fd LBSR BYTE INPUT DATA BYTE (2 HEX CHAR) +0756 fc43 35 04 PULS B POP CHECKSUM FROM STACK +0757 fc45 29 0c BVS LODERR (V) SET, DATA BYTE NOT HEX +0758 fc47 34 02 PSHS A PUSH DATA BYTE ON STACK +0759 fc49 eb e0 ADDB ,S+ ADD DATA TO CHECKSUM, AUTO INC STACK +0760 fc4b 6a e4 DEC ,S DECREMENT BYTE COUNT 1 +0761 fc4d 27 05 BEQ LOAD16 IF BYTE COUNT ZERO, TEST CHECKSUM +0762 fc4f a7 80 STA ,X+ SAVE DATA BYTE IN MEMORY +0763 fc51 20 eb BRA LOAD10 GET NEXT DATA BYTE +0764 fc53 5f LODERR CLRB ;ERROR CONDITION, ZERO CHECKSUM ; +0765 fc54 35 02 LOAD16 PULS A ADJUST STACK (REMOVE BYTE COUNT) +0766 fc56 c1 ff CMPB #$FF CHECKSUM OK? +0767 fc58 27 b2 BEQ LOAD IF SO, LOAD NEXT LINE +0768 fc5a 86 3f LDA #'? LOAD (?) ERROR INDICATOR +0769 fc5c 17 01 8f LBSR OUTCH OUTPUT IT TO TERMINAL +0770 fc5f 73 df e2 LOAD21 COM ECHO TURN ECHO ON +0771 fc62 86 13 LDA #$13 $FC5F LOAD 'DC3' CASS. READ OFF CODE +0772 fc64 16 01 87 LBRA OUTCH OUTPUT IT +0773 * +0774 ***** "P" PUNCH MIKBUG TAPE ***** +0775 * +0776 fc67 6f e2 PUNCH CLR ,-S CLEAR RESERVED BYTE ON STACK +0777 fc69 17 00 b8 LBSR IN2ADR GET BEGIN AND END ADDRESS +0778 fc6c 34 30 PSHS X,Y SAVE ADDRESSES ON STACK +0779 fc6e 29 4a BVS PUNEXT (V) C-CODE SET, EXIT PUNCH +0780 fc70 ac 62 CMPX 2,S COMPARE BEGIN TO END ADDR +0781 fc72 25 46 BCS PUNEXT IF BEGIN GREATER THAN END, EXIT PUNCH +0782 fc74 30 01 LEAX 1,X INCREMENT END ADDRESS +0783 fc76 af e4 STX ,S STORE END ADDR ON STACK +0784 fc78 86 12 LDA #$12 LOAD 'DC2' PUNCH ON CODE +0785 fc7a 17 01 71 LBSR OUTCH OUTPUT IT TO TERMINAL +0786 fc7d ec e4 PUNCH2 LDD ,S LOAD END ADDR IN D-ACC +0787 fc7f a3 62 SUBD 2,S SUBTRACT BEGIN FROM END +0788 fc81 27 06 BEQ PUNCH3 SAME, PUNCH 32 BYTES DEFAULT +0789 fc83 10 83 00 20 CMPD #$20 LESS THAN 32 BYTES? +0790 fc87 23 02 BLS PUNCH4 PUNCH THAT MANY BYTES +0791 fc89 c6 20 PUNCH3 LDB #$20 LOAD BYTE COUNT OF 32. +0792 fc8b e7 64 PUNCH4 STB 4,S STORE ON STACK AS BYTE COUNT +0793 fc8d 8e fe eb LDX #MSG20 POINT TO MSG "S1" +0794 fc90 17 01 1a LBSR PSTRNG PRINT MSG +0795 fc93 cb 03 ADDB #3 ADD 3 BYTES TO BYTE COUNT +0796 fc95 1f 98 TFR B,A GET BYTE COUNT IN A-ACC TO PUNCH +0797 fc97 17 00 e7 LBSR OUT2H OUTPUT BYTE COUNT +0798 fc9a ae 62 LDX 2,S LOAD BEGIN ADDRESS +0799 fc9c 17 00 da LBSR OUT4H PUNCH ADDRESS +0800 fc9f eb 62 ADDB 2,S ADD ADDR MSB TO CHECKSUM +0801 fca1 eb 63 ADDB 3,S ADD ADDR LSB TO CHECKSUM +0802 fca3 eb 84 PUNCHL ADDB ,X ADD DATA BYTE TO CHECKSUM +0803 fca5 a6 80 LDA ,X+ LOAD DATA BYTE TO PUNCH +0804 fca7 17 00 d7 LBSR OUT2H OUTPUT DATA BYTE +0805 fcaa 6a 64 DEC 4,S DECREMENT BYTE COUNT +0806 fcac 26 f5 BNE PUNCHL NOT DONE, PUNCH NEXT BYTE +0807 fcae 53 COMB 1's COMPLIMENT CHECKSUM BYTE +0808 fcaf 1f 98 TFR B,A GET IT IN A-ACC TO PUNCH +0809 fcb1 17 00 cd LBSR OUT2H OUTPUT CHECKSUM BYTE +0810 fcb4 af 62 STX 2,S SAVE X-REG IN STACK AS NEW PUNCH ADDR +0811 fcb6 ac e4 CMPX ,S COMPARE IT TO END ADDR +0812 fcb8 26 c3 BNE PUNCH2 $FCB5 PUNCH NOT DONE, CONT. +0813 fcba 86 14 PUNEXT LDA #$14 LOAD 'DC4' PUNCH OFF CODE +0814 fcbc 17 01 2f LBSR OUTCH OUTPUT IT +0815 fcbf 32 65 LEAS 5,S READJUST STACK POINTER +0816 fcc1 39 RTS ; +0817 * +0818 * +0819 fcc2 8e fe ae PRTSP LDX #MSG10 POINT TO MSG "SP=" +0820 fcc5 17 00 f5 LBSR PDATA PRINT MSG +0821 fcc8 1f 31 TFR U,X +0822 fcca 16 00 ac LBRA OUT4H +0823 fccd 8e fe ba PRTUS LDX #MSG12 POINT TO MSG "US=" +0824 fcd0 17 00 ea LBSR PDATA PRINT MSG +0825 fcd3 ae 48 LDX 8,U +0826 fcd5 16 00 a1 LBRA OUT4H +0827 fcd8 8e fe cc PRTDP LDX #MSG15 POINT TO MSG "DP=" +0828 fcdb 17 00 df LBSR PDATA PRINT MSG +0829 fcde a6 43 LDA 3,U +0830 fce0 16 00 9e LBRA OUT2H OUTPUT HEX BYTE AS ASCII +0831 fce3 8e fe c6 PRTIX LDX #MSG14 POINT TO MSG "IX=" +0832 fce6 17 00 d4 LBSR PDATA PRINT MSG +0833 fce9 ae 44 LDX 4,U $FCE6 +0834 fceb 16 00 8b LBRA OUT4H +0835 fcee 8e fe c0 PRTIY LDX #MSG13 POINT TO MSG "IY=" +0836 fcf1 17 00 c9 LBSR PDATA PRINT MSG +0837 fcf4 ae 46 LDX 6,U +0838 fcf6 16 00 80 LBRA OUT4H +0839 fcf9 8e fe b4 PRTPC LDX #MSG11 POINT TO MSG "PC=" +0840 fcfc 17 00 be LBSR PDATA PRINT MSG +0841 fcff ae 4a LDX 10,U +0842 fd01 20 76 BRA OUT4H +0843 fd03 8e fe d2 PRTA LDX #MSG16 POINT TO MSG "A=" +0844 fd06 17 00 b4 LBSR PDATA PRINT MSG +0845 fd09 a6 41 LDA 1,U +0846 fd0b 20 74 BRA OUT2H OUTPUT HEX BYTE AS ASCII +0847 fd0d 8e fe d7 PRTB LDX #MSG17 POINT TO MSG "B=" +0848 fd10 17 00 aa LBSR PDATA PRINT MSG +0849 fd13 a6 42 LDA 2,U +0850 fd15 20 6a BRA OUT2H OUTPUT HEX BYTE AS ASCII +0851 fd17 8e fe dc PRTCC LDX #MSG18 POINT TO MSG "CC:" +0852 fd1a 17 00 a0 LBSR PDATA PRINT MSG +0853 fd1d a6 c4 LDA ,U +0854 fd1f 8e fe e3 LDX #MSG19 POINT TO MSG "EFHINZVC" +0855 fd22 20 73 BRA BIASCI OUTPUT IN BINARY/ASCII FORMAT +0856 * +0857 * THE FOLLOWING ROUTINE LOOPS WAITING FOR THE +0858 * OPERATOR TO INPUT TWO VALID HEX ADDRESSES. +0859 * THE FIRST ADDRESS INPUT IS RETURNED IN "IY". +0860 * THE SECOND IS RETURNED IN "IX". THE "V" BIT +0861 * IN THE C-CODE REG. IS SET IF AN INVALID HEX +0862 * ADDRESS IS INPUT. +0863 * +0864 fd24 8d 09 IN2ADR BSR IN1ADR GET FIRST ADDRESS +0865 fd26 29 4e BVS NOTHEX EXIT IF NOT VALID HEX +0866 fd28 1f 12 TFR X,Y SAVE FIRST ADDR. IN "IY" +0867 fd2a 86 2d LDA #'- +0868 fd2c 17 00 bf LBSR OUTCH PRINT " - " +0869 * +0870 * THE FOLLOWING ROUTINE LOOPS WAITING FOR THE +0871 * OPERATOR TO INPUT ONE VALID HEX ADDRESS. THE +0872 * ADDRESS IS RETURNED IN THE "X" REGISTER. +0873 * +0874 fd2f 8d 0f IN1ADR BSR BYTE INPUT BYTE (2 HEX CHAR) +0875 fd31 29 43 BVS NOTHEX EXIT IF NOT VALID HEX +0876 fd33 1f 01 TFR D,X +0877 fd35 8d 09 BSR BYTE INPUT BYTE (2 HEX CHAR) +0878 fd37 29 3d BVS NOTHEX +0879 fd39 34 10 PSHS X +0880 fd3b a7 61 STA 1,S +0881 fd3d 35 10 PULS X +0882 fd3f 39 RTS ; +0883 * +0884 ***** INPUT BYTE (2 HEX CHAR.) ***** +0885 * +0886 fd40 8d 11 BYTE BSR INHEX GET HEX LEFT +0887 fd42 29 32 BVS NOTHEX EXIT IF NOT VALID HEX +0888 fd44 48 ASLA ; +0889 fd45 48 ASLA ; +0890 fd46 48 ASLA ; SHIFT INTO LEFT NIBBLE +0891 fd47 48 ASLA ; +0892 fd48 1f 89 TFR A,B PUT HEXL IN "B" +0893 fd4a 8d 07 BSR INHEX GET HEX RIGHT +0894 fd4c 29 28 BVS NOTHEX EXIT IF NOT VALID HEX +0895 fd4e 34 04 PSHS B PUSH HEXL ON STACK +0896 fd50 ab e0 ADDA ,S+ ADD HEXL TO HEXR AND ADJ. STK +0897 fd52 39 RTS RETURN WITH HEX L&R IN "A" +0898 * +0899 * +0900 fd53 8d 6f INHEX BSR ECHON INPUT ASCII CHAR. +0901 fd55 81 30 CMPA #'0 IS IT > OR = "0" ? +0902 fd57 25 1d BCS NOTHEX IF LESS IT AIN'T HEX +0903 fd59 81 39 CMPA #'9 IS IT < OR = "9" ? +0904 fd5b 22 03 BHI INHEXA IF > MAYBE IT'S ALPHA +0905 fd5d 80 30 SUBA #$30 ASCII ADJ. NUMERIC +0906 fd5f 39 RTS ; +0907 * +0908 * +0909 fd60 81 41 INHEXA CMPA #'A IS IT > OR = "A" +0910 fd62 25 12 BCS NOTHEX IF LESS IT AIN'T HEX +0911 fd64 81 46 CMPA #'F IS IT < OR = "F" ? +0912 fd66 22 03 BHI INHEXL IF > IT AIN'T HEX +0913 fd68 80 37 SUBA #$37 ASCII ADJ. ALPHA +0914 fd6a 39 RTS ; +0915 * +0916 fd6b 81 61 INHEXL CMPA #'a IS IT > OR = "a" +0917 fd6d 25 07 BCS NOTHEX IF LESS IT AIN'T HEX +0918 fd6f 81 66 CMPA #'f IS IT < "f" +0919 fd71 22 03 BHI NOTHEX IF > IT AIN'T HEX +0920 fd73 80 57 SUBA #$57 ADJUST TO LOWER CASE +0921 fd75 39 RTS ; +0922 * +0923 * +0924 fd76 1a 02 NOTHEX ORCC #2 SET (V) FLAG IN C-CODES REGISTER +0925 fd78 39 RTS ; +0926 * +0927 * +0928 fd79 34 10 OUT4H PSHS X PUSH X-REG. ON THE STACK +0929 fd7b 35 02 PULS A POP MS BYTE OF X-REG INTO A-ACC. +0930 fd7d 8d 02 BSR OUTHL OUTPUT HEX LEFT +0931 fd7f 35 02 PULS A POP LS BYTE OF X-REG INTO A-ACC. +0932 fd81 OUTHL EQU * +0933 fd81 34 02 OUT2H PSHS A SAVE IT BACK ON STACK +0934 fd83 44 LSRA CONVERT UPPER HEX NIBBLE TO ASCII +0935 fd84 44 LSRA ; +0936 fd85 44 LSRA ; +0937 fd86 44 LSRA ; +0938 fd87 8d 04 BSR XASCII PRINT HEX NIBBLE AS ASCII +0939 fd89 35 02 OUTHR PULS A CONVERT LOWER HEX NIBBLE TO ASCII +0940 fd8b 84 0f ANDA #$0F STRIP LEFT NIBBLE +0941 fd8d 8b 30 XASCII ADDA #$30 ASCII ADJ +0942 fd8f 81 39 CMPA #$39 IS IT < OR = "9" ? +0943 fd91 2f 02 BLE OUTC IF LESS, OUTPUT IT +0944 fd93 8b 07 ADDA #7 IF > MAKE ASCII LETTER +0945 fd95 20 57 OUTC BRA OUTCH OUTPUT CHAR +0946 * +0947 * BINARY / ASCII --- THIS ROUTINE +0948 * OUTPUTS A BYTE IN ENHANCED +0949 * BINARY FORMAT. THE ENHANCEMENT +0950 * IS DONE BY SUBSTITUTING ASCII +0951 * LETTERS FOR THE ONES IN THE BYTE. +0952 * THE ASCII ENHANCEMENT LETTERS +0953 * ARE OBTAINED FROM THE STRING +0954 * POINTED TO BY THE INDEX REG. "X". +0955 * +0956 fd97 34 02 BIASCI PSHS A SAVE "A" ON STACK +0957 fd99 c6 08 LDB #8 PRESET LOOP# TO BITS PER BYTE +0958 fd9b a6 80 OUTBA LDA ,X+ GET LETTER FROM STRING +0959 fd9d 68 e4 ASL ,S TEST BYTE FOR "1" IN B7 +0960 fd9f 25 02 BCS PRTBA IF ONE PRINT LETTER +0961 fda1 86 2d LDA #'- IF ZERO PRINT "-" +0962 fda3 8d 49 PRTBA BSR OUTCH PRINT IT +0963 fda5 8d 45 BSR OUT1S PRINT SPACE +0964 fda7 5a DECB SUB 1 FROM #BITS YET TO PRINT +0965 fda8 26 f1 BNE OUTBA +0966 fdaa 35 02 PULS A +0967 fdac 39 RTS +0968 * +0969 * PRINT STRING PRECEEDED BY A CR & LF. +0970 * +0971 fdad 8d 02 PSTRNG BSR PCRLF PRINT CR/LF +0972 fdaf 20 0c BRA PDATA PRINT STRING POINTED TO BY IX +0973 * +0974 * PCRLF +0975 * +0976 fdb1 34 10 PCRLF PSHS X SAVE IX +0977 fdb3 8e fe 75 LDX #MSG2+1 POINT TO MSG CR/LF + 3 NULS +0978 fdb6 8d 05 BSR PDATA PRINT MSG +0979 fdb8 35 10 PULS X RESTORE IX +0980 fdba 39 RTS ; +0981 fdbb 8d 31 PRINT BSR OUTCH +0982 * +0983 * PDATA +0984 * +0985 fdbd a6 80 PDATA LDA ,X+ GET 1st CHAR. TO PRINT +0986 fdbf 81 04 CMPA #4 IS IT EOT? +0987 fdc1 26 f8 BNE PRINT IF NOT EOT PRINT IT +0988 fdc3 39 RTS ; +0989 * +0990 * +0991 fdc4 7d df e2 ECHON TST ECHO IS ECHO REQUIRED ? +0992 fdc7 27 06 BEQ INCH ECHO NOT REQ. IF CLEAR +0993 * +0994 * INCHE +0995 * +0996 * ---GETS CHARACTER FROM TERMINAL AND +0997 * ECHOS SAME. THE CHARACTER IS RETURNED +0998 * IN THE "A" ACCUMULATOR WITH THE PARITY +0999 * BIT MASKED OFF. ALL OTHER REGISTERS +1000 * ARE PRESERVED. +1001 * +1002 fdc9 8d 04 INCHE BSR INCH GET CHAR FROM TERMINAL +1003 fdcb 84 7f ANDA #$7F STRIP PARITY FROM CHAR. +1004 fdcd 20 1f BRA OUTCH ECHO CHAR TO TERMINAL +1005 * +1006 * INCH +1007 * +1008 * GET CHARACTER FROM TERMINAL. RETURN +1009 * CHARACTER IN "A" ACCUMULATOR AND PRESERVE +1010 * ALL OTHER REGISTERS. THE INPUT CHARACTER +1011 * IS 8 BITS AND IS NOT ECHOED. +1012 * +1013 * +1014 fdcf 34 10 INCH PSHS X SAVE IX +1015 fdd1 be df e0 LDX CPORT POINT TO TERMINAL PORT +1016 fdd4 a6 84 GETSTA LDA ,X FETCH PORT STATUS +1017 fdd6 85 01 BITA #1 TEST READY BIT, RDRF ? +1018 fdd8 27 fa BEQ GETSTA IF NOT RDY, THEN TRY AGAIN +1019 fdda a6 01 LDA 1,X FETCH CHAR +1020 fddc 35 10 PULS X RESTORE IX +1021 fdde 39 RTS ; +1022 * +1023 * INCHEK +1024 * +1025 * CHECK FOR A CHARACTER AVAILABLE FROM +1026 * THE TERMINAL. THE SERIAL PORT IS CHECKED +1027 * FOR READ READY. ALL REGISTERS ARE +1028 * PRESERVED, AND THE "Z" BIT WILL BE +1029 * CLEAR IF A CHARACTER CAN BE READ. +1030 * +1031 * +1032 fddf 34 02 INCHEK PSHS A SAVE A ACCUM. +1033 fde1 a6 9f df e0 LDA [CPORT] FETCH PORT STATUS +1034 fde5 85 01 BITA #1 TEST READY BIT, RDRF ? +1035 fde7 35 02 PULS A RESTORE A ACCUM. +1036 fde9 39 RTS ; +1037 * +1038 fdea 8d 00 OUT2S BSR OUT1S OUTPUT 2 SPACES +1039 fdec 86 20 OUT1S LDA #$20 OUTPUT 1 SPACE +1040 * +1041 * +1042 * OUTCH +1043 * +1044 * OUTPUT CHARACTER TO TERMINAL. +1045 * THE CHAR. TO BE OUTPUT IS +1046 * PASSED IN THE A REGISTER. +1047 * ALL REGISTERS ARE PRESERVED. +1048 * +1049 fdee 34 12 OUTCH PSHS A,X SAVE A ACCUM AND IX +1050 fdf0 be df e0 LDX CPORT GET ADDR. OF TERMINAL +1051 fdf3 a6 84 FETSTA LDA ,X FETCH PORT STATUS +1052 fdf5 85 02 BITA #2 TEST TDRE, OK TO XMIT ? +1053 fdf7 27 fa BEQ FETSTA IF NOT LOOP UNTIL RDY +1054 fdf9 35 02 PULS A GET CHAR. FOR XMIT +1055 fdfb a7 01 STA 1,X XMIT CHAR. +1056 fdfd 35 10 PULS X RESTORE IX +1057 fdff 39 RTS ; +1058 * +1059 * +1060 fe00 be df e0 ACINIZ LDX CPORT POINT TO CONTROL PORT ADDRESS +1061 fe03 86 03 LDA #3 RESET ACIA PORT CODE +1062 fe05 a7 84 STA ,X STORE IN CONTROL REGISTER +1063 fe07 86 11 LDA #$11 SET 8 DATA, 2 STOP AN 0 PARITY +1064 fe09 a7 84 STA ,X STORE IN CONTROL REGISTER +1065 fe0b 6d 01 TST 1,X ANYTHING IN DATA REGISTER? +1066 fe0d 86 ff LDA #$FF TURN ON ECHO FLAG +1067 fe0f b7 df e2 STA ECHO +1068 fe12 39 RTS +1069 * +1070 * +1071 * MONITOR KEYBOARD COMMAND JUMP TABLE +1072 * +1073 * +1074 fe13 JMPTAB EQU * +1075 fe13 01 FCB 1 " ^A " $F91D +1076 fe14 f9 23 FDB ALTRA +1077 fe16 02 FCB 2 " ^B " $F90F +1078 fe17 f9 15 FDB ALTRB +1079 fe19 03 FCB 3 " ^C " $F92B +1080 fe1a f9 31 FDB ALTRCC +1081 fe1c 04 FCB 4 " ^D " $F901 +1082 fe1d f9 07 FDB ALTRDP +1083 fe1f 10 FCB $10 " ^P " $F8C9 +1084 fe20 f8 cf FDB ALTRPC +1085 fe22 15 FCB $15 " ^U " $F8D7 +1086 fe23 f8 dd FDB ALTRU +1087 fe25 18 FCB $18 " ^X " $F8F3 +1088 fe26 f8 f9 FDB ALTRX +1089 fe28 19 FCB $19 " ^Y " $F8E5 +1090 fe29 f8 eb FDB ALTRY +1091 * +1092 fe2b 42 FCC 'B' +1093 fe2c fa 7b FDB BRKPNT *$FA78 +1094 fe2e 44 FCC 'D' +1095 fe2f fa f4 FDB DBOOT *$FAF1 +1096 fe31 45 FCC 'E' +1097 fe32 f9 96 FDB MEMDUMP *$F990 +1098 fe34 47 FCC 'G' +1099 fe35 f8 a5 FDB GO *$F89F +1100 fe37 4c FCC 'L' +1101 fe38 fc 0c FDB LOAD *$FC09 +1102 fe3a 4d FCC 'M' +1103 fe3b f9 41 FDB MEMCHG *$F93B +1104 fe3d 50 FCC 'P' +1105 fe3e fc 67 FDB PUNCH *$FC64 +1106 fe40 51 FCC 'Q' +1107 fe41 f9 f2 FDB MEMTST *$F9EF +1108 fe43 52 FCC 'R' +1109 fe44 f8 a8 FDB REGSTR *$F8A2 +1110 fe46 53 FCC 'S' +1111 fe47 f9 8a FDB DISSTK *$F984 +1112 fe49 55 FCC 'U' +1113 fe4a fb b3 FDB MINBOOT *$FBB0 +1114 fe4c 58 FCC 'X' +1115 fe4d fa a7 FDB XBKPNT *$FAA4 +1116 * +1117 fe4f TABEND EQU * +1118 * +1119 * ** 6809 VECTOR ADDRESSES ** +1120 * +1121 * FOLLOWING ARE THE ADDRESSES OF THE VECTOR ROUTINES +1122 * FOR THE 6809 PROCESSOR. DURING INITIALIZATION THEY +1123 * ARE RELOCATED TO RAM FROM $DFC0 TO $DFCF. THEY ARE +1124 * RELOCATED TO RAM SO THAT THE USER MAY REVECTOR TO +1125 * HIS OWN ROUTINES IF HE SO DESIRES. +1126 * +1127 * +1128 fe4f fa b3 RAMVEC FDB SWIE USER-V +1129 fe51 f8 a7 FDB RTI SWI3-V +1130 fe53 f8 a7 FDB RTI SWI2-V +1131 fe55 f8 a7 FDB RTI FIRQ-V +1132 fe57 f8 a7 FDB RTI IRQ-V +1133 fe59 fa b3 FDB SWIE SWI-V +1134 fe5b ff ff FDB $FFFF SVC-VO +1135 fe5d ff ff FDB $FFFF SVC-VL +1136 * +1137 * PRINTABLE MESSAGE STRINGS +1138 * +1139 fe5f 00 00 00 0d 0a 00 MSG1 FCB $0,$0,$0,$D,$A,$0,$0,$0 * 0, CR/LF, 0 + 00 00 +1140 fe67 53 2d 42 55 47 20 FCC 'S-BUG 1.8 - ' + 31 2e 38 20 2d 20 +1141 fe73 04 FCB 4 +1142 fe74 4b 0d 0a 00 00 00 MSG2 FCB 'K,$D,$A,$0,$0,$0,4 K, * CR/LF + 3 NULS + 04 +1143 fe7b 3e MSG3 FCC '>' +1144 fe7c 04 FCB 4 +1145 fe7d 57 48 41 54 3f MSG4 FCC 'WHAT?' +1146 fe82 04 FCB 4 +1147 fe83 20 2d 20 MSG5 FCC ' - ' +1148 fe86 04 FCB 4' +1149 fe87 2c 20 50 41 53 53 MSG6 FCC ', PASS ' + 20 +1150 fe8e 04 FCB 4 +1151 fe8f 2c 20 42 49 54 53 MSG7 FCC ', BITS IN ERROR: ' + 20 49 4e 20 45 52 + 52 4f 52 3a 20 +1152 fea0 04 FCB 4 +1153 fea1 20 3d 3e 20 MSG8 FCC ' => ' +1154 fea5 04 FCB 4 +1155 fea6 37 36 35 34 33 32 MSG9 FCC '76543210' + 31 30 +1156 feae 20 20 53 50 3d MSG10 FCC ' SP=' +1157 feb3 04 FCB 4 +1158 feb4 20 20 50 43 3d MSG11 FCC ' PC=' +1159 feb9 04 FCB 4 +1160 feba 20 20 55 53 3d MSG12 FCC ' US=' +1161 febf 04 FCB 4 +1162 fec0 20 20 49 59 3d MSG13 FCC ' IY=' +1163 fec5 04 FCB 4 +1164 fec6 20 20 49 58 3d MSG14 FCC ' IX=' +1165 fecb 04 FCB 4 +1166 fecc 20 20 44 50 3d MSG15 FCC ' DP=' +1167 fed1 04 FCB 4 +1168 fed2 20 20 41 3d MSG16 FCC ' A=' +1169 fed6 04 FCB 4 +1170 fed7 20 20 42 3d MSG17 FCC ' B=' +1171 fedb 04 FCB 4 +1172 fedc 20 20 43 43 3a 20 MSG18 FCC ' CC: ' +1173 fee2 04 FCB 4 +1174 fee3 45 46 48 49 4e 5a MSG19 FCC 'EFHINZVC' + 56 43 +1175 feeb 53 31 MSG20 FCC 'S1' +1176 feed 04 FCB 4 +1177 * +1178 * MESSAGE EXPANSION AREA +1179 * +1180 feee ff ff ff ff ff ff FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF + ff ff +1181 fef6 ff ff ff ff ff ff FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF + ff +1182 * +1183 * POWER UP/ RESET/ NMI ENTRY POINT +1184 * +1185 ff00 ORG $FF00 +1186 * +1187 * +1188 ff00 8e ff f0 START LDX #IC11 POINT TO DAT RAM IC11 +1189 ff03 86 0f LDA #$F GET COMPLIMENT OF ZERO +1190 * +1191 * +1192 * INITIALIZE DAT RAM --- LOADS $F-$0 IN LOCATIONS $0-$F +1193 * OF DAT RAM, THUS STORING COMPLEMENT OF MSB OF ADDRESS +1194 * IN THE DAT RAM. THE COMPLEMENT IS REQUIRED BECAUSE THE +1195 * OUTPUT OF IC11, A 74S189, IS THE INVERSE OF THE DATA +1196 * STORED IN IT. +1197 * +1198 * +1199 ff05 a7 80 DATLP STA ,X+ STORE & POINT TO NEXT RAM LOCATION +1200 ff07 4a DECA GET COMP. VALUE FOR NEXT LOCATION +1201 ff08 26 fb BNE DATLP ALL 16 LOCATIONS INITIALIZED ? +1202 * +1203 * NOTE: IX NOW CONTAINS $0000, DAT RAM IS NO LONGER +1204 * ADDRESSED, AND LOGICAL ADDRESSES NOW EQUAL +1205 * PHYSICAL ADDRESSES. +1206 * +1207 ff0a 86 f0 LDA #$F0 +1208 ff0c a7 84 STA ,X STORE $F0 AT $FFFF +1209 ff0e 8e d0 a0 LDX #$D0A0 ASSUME RAM TO BE AT $D000-$DFFF +1210 ff11 10 8e 55 aa LDY #TSTPAT LOAD TEST DATA PATTERN INTO "Y" +1211 ff15 ee 84 TSTRAM LDU ,X SAVE DATA FROM TEST LOCATION +1212 ff17 10 af 84 STY ,X STORE TEST PATTERN AT $D0A0 +1213 ff1a 10 ac 84 CMPY ,X IS THERE RAM AT THIS LOCATION ? +1214 ff1d 27 0b BEQ CNVADR IF MATCH THERE'S RAM, SO SKIP +1215 ff1f 30 89 f0 00 LEAX -$1000,X ELSE POINT 4K LOWER +1216 ff23 8c f0 a0 CMPX #$F0A0 DECREMENTED PAST ZER0 YET ? +1217 ff26 26 ed BNE TSTRAM IF NOT CONTINUE TESTING FOR RAM +1218 ff28 20 d6 BRA START ELSE START ALL OVER AGAIN +1219 * +1220 * +1221 * THE FOLLOWING CODE STORES THE COMPLEMENT OF +1222 * THE MS CHARACTER OF THE FOUR CHARACTER HEX +1223 * ADDRESS OF THE FIRST 4K BLOCK OF RAM LOCATED +1224 * BY THE ROUTINE "TSTRAM" INTO THE DAT RAM. IT +1225 * IS STORED IN RAM IN THE LOCATION THAT IS +1226 * ADDRESSED WHEN THE PROCESSOR ADDRESS IS $D---, +1227 * THUS IF THE FIRST 4K BLOCK OF RAM IS FOUND +1228 * WHEN TESTING LOCATION $70A0, MEANING THERE +1229 * IS NO RAM PHYSICALLY ADDRESSED IN THE RANGE +1230 * $8000-$DFFF, THEN THE COMPLEMENT OF THE +1231 * "7" IN THE $70A0 WILL BE STORED IN +1232 * THE DAT RAM. THUS WHEN THE PROCESSOR OUTPUTS +1233 * AN ADDRESS OF $D---, THE DAT RAM WILL RESPOND +1234 * BY RECOMPLEMENTING THE "7" AND OUTPUTTING THE +1235 * 7 ONTO THE A12-A15 ADDRESS LINES. THUS THE +1236 * RAM THAT IS PHYSICALLY ADDRESSED AT $7--- +1237 * WILL RESPOND AND APPEAR TO THE 6809 THAT IT +1238 * IS AT $D--- SINCE THAT IS THE ADDRESS THE +1239 * 6809 WILL BE OUTPUTING WHEN THAT 4K BLOCK +1240 * OF RAM RESPONDS. +1241 * +1242 * +1243 ff2a ef 84 CNVADR STU ,X RESTORE DATA AT TEST LOCATION +1244 ff2c 1f 10 TFR X,D PUT ADDR. OF PRESENT 4K BLOCK IN D +1245 ff2e 43 COMA COMPLEMENT MSB OF THAT ADDRESS +1246 ff2f 44 LSRA PUT MS 4 BITS OF ADDRESS IN +1247 ff30 44 LSRA LOCATION D0-D3 TO ALLOW STORING +1248 ff31 44 LSRA IT IN THE DYNAMIC ADDRESS +1249 ff32 44 LSRA TRANSLATION RAM. +1250 ff33 b7 ff fd STA $FFFD STORE XLATION FACTOR IN DAT "D" +1251 * +1252 ff36 10 ce df c0 LDS #STACK INITIALIZE STACK POINTER +1253 * +1254 * +1255 * THE FOLLOWING CHECKS TO FIND THE REAL PHYSICAL ADDRESSES +1256 * OF ALL 4K BLKS OF RAM IN THE SYSTEM. WHEN EACH 4K BLK +1257 * OF RAM IS LOCATED, THE COMPLEMENT OF IT'S REAL ADDRESS +1258 * IS THEN STORED IN A "LOGICAL" TO "REAL" ADDRESS XLATION +1259 * TABLE THAT IS BUILT FROM $DFD0 TO $DFDF. FOR EXAMPLE IF +1260 * THE SYSTEM HAS RAM THAT IS PHYSICALLY LOCATED (WIRED TO +1261 * RESPOND) AT THE HEX LOCATIONS $0--- THRU $F---.... +1262 * +1263 * 0 1 2 3 4 5 6 7 8 9 A B C D E F +1264 * 4K 4K 4K 4K 4K 4K 4K 4K -- 4K 4K 4K 4K -- -- -- +1265 * +1266 * ....FOR A TOTAL OF 48K OF RAM, THEN THE TRANSLATION TABLE +1267 * CREATED FROM $DFD0 TO $DFDF WILL CONSIST OF THE FOLLOWING.... +1268 * +1269 * 0 1 2 3 4 5 6 7 8 9 A B C D E F +1270 * 0F 0E 0D 0C 0B 0A 09 08 06 05 00 00 04 03 F1 F0 +1271 * +1272 * +1273 * HERE WE SEE THE LOGICAL ADDRESSES OF MEMORY FROM $0000-$7FFF +1274 * HAVE NOT BEEN SELECTED FOR RELOCATION SO THAT THEIR PHYSICAL +1275 * ADDRESS WILL = THEIR LOGICAL ADDRESS; HOWEVER, THE 4K BLOCK +1276 * PHYSICALLY AT $9000 WILL HAVE ITS ADDRESS TRANSLATED SO THAT +1277 * IT WILL LOGICALLY RESPOND AT $8000. LIKEWISE $A,$B, AND $C000 +1278 * WILL BE TRANSLATED TO RESPOND TO $9000,$C000, AND $D000 +1279 * RESPECTIVELY. THE USER SYSTEM WILL LOGICALLY APPEAR TO HAVE +1280 * MEMORY ADDRESSED AS FOLLOWS.... +1281 * +1282 * 0 1 2 3 4 5 6 7 8 9 A B C D E F +1283 * 4K 4K 4K 4K 4K 4K 4K 4K 4K 4K -- -- 4K 4K -- -- +1284 * +1285 * +1286 ff3a 10 8e df d0 LDY #LRARAM POINT TO LOGICAL/REAL ADDR. TABLE +1287 ff3e a7 2d STA 13,Y STORE $D--- XLATION FACTOR AT $DFDD +1288 ff40 6f 2e CLR 14,Y CLEAR $DFDE +1289 ff42 86 f0 LDA #$F0 DESTINED FOR IC8 AN MEM EXPANSION ? +1290 ff44 a7 2f STA 15,Y STORE AT $DFDF +1291 ff46 86 0c LDA #$0C PRESET NUMBER OF BYTES TO CLEAR +1292 ff48 6f a6 CLRLRT CLR A,Y CLEAR $DFDC THRU $DFD0 +1293 ff4a 4a DECA SUB. 1 FROM BYTES LEFT TO CLEAR +1294 ff4b 2a fb BPL CLRLRT CONTINUE IF NOT DONE CLEARING +1295 ff4d 30 89 f0 00 FNDRAM LEAX -$1000,X POINT TO NEXT LOWER 4K OF RAM +1296 ff51 8c f0 a0 CMPX #$F0A0 TEST FOR DECREMENT PAST ZERO +1297 ff54 27 22 BEQ FINTAB SKIP IF FINISHED +1298 ff56 ee 84 LDU ,X SAVE DATA AT CURRENT TEST LOCATION +1299 ff58 10 8e 55 aa LDY #TSTPAT LOAD TEST DATA PATTERN INTO Y REG. +1300 ff5c 10 af 84 STY ,X STORE TEST PATT. INTO RAM TEST LOC. +1301 ff5f 10 ac 84 CMPY ,X VERIFY RAM AT TEST LOCATION +1302 ff62 26 e9 BNE FNDRAM IF NO RAM GO LOOK 4K LOWER +1303 ff64 ef 84 STU ,X ELSE RESTORE DATA TO TEST LOCATION +1304 ff66 10 8e df d0 LDY #LRARAM POINT TO LOGICAL/REAL ADDR. TABLE +1305 ff6a 1f 10 TFR X,D PUT ADDR. OF PRESENT 4K BLOCK IN D +1306 ff6c 44 LSRA PUT MS 4 BITS OF ADDR. IN LOC. D0-D3 +1307 ff6d 44 LSRA TO ALLOW STORING IT IN THE DAT RAM. +1308 ff6e 44 LSRA +1309 ff6f 44 LSRA +1310 ff70 1f 89 TFR A,B SAVE OFFSET INTO LRARAM TABLE +1311 ff72 88 0f EORA #$0F INVERT MSB OF ADDR. OF CURRENT 4K BLK +1312 ff74 a7 a5 STA B,Y SAVE TRANSLATION FACTOR IN LRARAM TABLE +1313 ff76 20 d5 BRA FNDRAM GO TRANSLATE ADDR. OF NEXT 4K BLK +1314 ff78 86 f1 FINTAB LDA #$F1 DESTINED FOR IC8 AND MEM EXPANSION ? +1315 ff7a 10 8e df d0 LDY #LRARAM POINT TO LRARAM TABLE +1316 ff7e a7 2e STA 14,Y STORE $F1 AT $DFCE +1317 * +1318 * THE FOLLOWING CHECKS TO SEE IF THERE IS A 4K BLK OF +1319 * RAM LOCATED AT $C000-$CFFF. IF NONE THERE IT LOCATES +1320 * THE NEXT LOWER 4K BLK AN XLATES ITS ADDR SO IT +1321 * LOGICALLY RESPONDS TO THE ADDRESS $C---. +1322 * +1323 * +1324 ff80 86 0c LDA #$0C PRESET NUMBER HEX "C" +1325 ff82 e6 a6 FINDC LDB A,Y GET ENTRY FROM LRARAM TABLE +1326 ff84 26 05 BNE FOUNDC BRANCH IF RAM THIS PHYSICAL ADDR. +1327 ff86 4a DECA ELSE POINT 4K LOWER +1328 ff87 2a f9 BPL FINDC GO TRY AGAIN +1329 ff89 20 14 BRA XFERTF +1330 ff8b 6f a6 FOUNDC CLR A,Y CLR XLATION FACTOR OF 4K BLOCK FOUND +1331 ff8d e7 2c STB $C,Y GIVE IT XLATION FACTOR MOVING IT TO $C--- +1332 * +1333 * THE FOLLOWING CODE ADJUSTS THE TRANSLATION +1334 * FACTORS SUCH THAT ALL REMAINING RAM WILL +1335 * RESPOND TO A CONTIGUOUS BLOCK OF LOGICAL +1336 * ADDRESSES FROM $0000 AND UP.... +1337 * +1338 ff8f 4f CLRA START AT ZERO +1339 ff90 1f 21 TFR Y,X START POINTER "X" START OF "LRARAM" TABLE. +1340 ff92 e6 a6 COMPRS LDB A,Y GET ENTRY FROM "LRARAM" TABLE +1341 ff94 27 04 BEQ PNTNXT IF IT'S ZER0 SKIP +1342 ff96 6f a6 CLR A,Y ELSE ERASE FROM TABLE +1343 ff98 e7 80 STB ,X+ AND ENTER ABOVE LAST ENTRY- BUMP +1344 ff9a 4c PNTNXT INCA GET OFFSET TO NEXT ENTRY +1345 ff9b 81 0c CMPA #$0C LAST ENTRY YET ? +1346 ff9d 2d f3 BLT COMPRS +1347 * +1348 * THE FOLLOWING CODE TRANSFER THE TRANSLATION +1349 * FACTORS FROM THE LRARAM TABLE TO IC11 ON +1350 * THE MP-09 CPU CARD. +1351 * +1352 ff9f 8e ff f0 XFERTF LDX #IC11 POINT TO DAT RAM IC11 +1353 ffa2 c6 10 LDB #$10 GET NO. OF BYTES TO MOVE +1354 ffa4 a6 a0 FETCH LDA ,Y+ GET BYTE AND POINT TO NEXT +1355 ffa6 a7 80 STA ,X+ POKE XLATION FACTOR IN IC11 +1356 ffa8 5a DECB SUB 1 FROM BYTES TO MOVE +1357 ffa9 26 f9 BNE FETCH CONTINUE UNTIL 16 MOVED +1358 ffab 53 COMB SET "B" NON-ZERO +1359 ffac f7 df e2 STB ECHO TURN ON ECHO FLAG +1360 ffaf 16 f8 62 LBRA MONITOR INITIALIZATION IS COMPLETE +1361 * +1362 * +1363 ffb2 6e 9f df c0 V1 JMP [STACK] +1364 ffb6 6e 9f df c4 V2 JMP [SWI2] +1365 ffba 6e 9f df c6 V3 JMP [FIRQ] +1366 ffbe 6e 9f df c8 V4 JMP [IRQ] +1367 ffc2 6e 9f df ca V5 JMP [SWI] +1368 * +1369 * SWI3 ENTRY POINT +1370 * +1371 ffc6 1f 43 SWI3E TFR S,U +1372 ffc8 ae 4a LDX 10,U *$FFC8 +1373 ffca e6 80 LDB ,X+ +1374 ffcc af 4a STX 10,U +1375 ffce 4f CLRA +1376 ffcf 58 ASLB +1377 ffd0 49 ROLA +1378 ffd1 be df cc LDX SVCVO +1379 ffd4 8c ff ff CMPX #$FFFF +1380 ffd7 27 0f BEQ SWI3Z +1381 ffd9 30 8b LEAX D,X +1382 ffdb bc df ce CMPX SVCVL +1383 ffde 22 08 BHI SWI3Z +1384 ffe0 34 10 PSHS X +1385 ffe2 ec c4 LDD ,U +1386 ffe4 ae 44 LDX 4,U +1387 ffe6 6e f1 JMP [,S++] +1388 ffe8 37 1f SWI3Z PULU A,B,X,CC,DP +1389 ffea ee 42 LDU 2,U +1390 ffec 6e 9f df c2 JMP [SWI3] +1391 * +1392 * 6809 VECTORS +1393 * +1394 fff0 ff b2 FDB V1 USER-V +1395 fff2 ff c6 FDB SWI3E SWI3-V +1396 fff4 ff b6 FDB V2 SWI2-V +1397 fff6 ff ba FDB V3 FIRQ-V +1398 fff8 ff be FDB V4 IRQ-V +1399 fffa ff c2 FDB V5 SWI-V +1400 fffc ff b2 FDB V1 NMI-V +1401 fffe ff 00 FDB START RESTART-V +1402 END START Index: tags/V10/sw/asref.man =================================================================== --- tags/V10/sw/asref.man (nonexistent) +++ tags/V10/sw/asref.man (revision 3) @@ -0,0 +1,2245 @@ + + + + + + + + + + MOTOROLA + + FREEWARE + + 8-BIT CROSS ASSEMBLERS + + USER'S MANUAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + EDITED BY + + KEVIN ANDERSON + + FIELD APPLICATIONS ENGINEER + + + + + + + + + + + + + + + + TABLE OF CONTENTS + +CHAPTER 1......................................................... 1 + + 1.1 INTRODUCTION .......................................... 1 + 1.2 ASSEMBLY LANGUAGE ..................................... 1 + 1.3 OPERATING ENVIRONMENT ................................. 2 + 1.4 ASSEMBLER PROCESSING .................................. 2 + +CHAPTER 2 ........................................................ 3 + + 2.1 INTRODUCTION .......................................... 3 + 2.2 SOURCE STATEMENT FORMAT ............................... 3 + 2.2.1 Label Field .................................... 3 + 2.2.2 Operation Field ................................ 4 + 2.2.3 Operand Field .................................. 4 + 2.2.3.1 M6800/6801 Operand Syntax ................ 5 + 2.2.3.2 M6800/M68HC04 Operand Syntax ............. 5 + 2.2.3.3 M6805/M68HC05 Operand Syntax ............. 5 + 2.2.3.4 M6809 Operand Syntax ..................... 5 + 2.2.3.5 M68HC11 Operand Syntax ................... 6 + 2.2.3.6 Expressions .............................. 6 + 2.2.3.7 Operators ................................ 7 + 2.2.3.8 Symbols .................................. 7 + 2.2.3.9 Constants ................................ 7 + 2.2.4 Comment Field .................................. 8 + 2.3 ASSEMBLER OUTPUT ...................................... 9 + +CHAPTER 3 - RUNNING THE ASSEMBLERS ............................... 10 + + 3.1 ASSEMBLER INVOCATION .................................. 10 + 3.2 ERROR MESSAGES ........................................ 11 + +CHAPTER 4 - ASSEMBLER DIRECTIVES ................................. 12 + + 4.1 INTRODUCTION .......................................... 12 + 4.2 BSZ - BLOCK STORAGE OF ZEROS .......................... 12 + 4.3 EQU - EQUATE SYMBOL TO A VALUE ........................ 13 + 4.4 FCB - FORM CONSTANT BYTE .............................. 13 + 4.5 FCC - FORM CONSTANT CHARACTER STRING .................. 13 + 4.6 FDB - FROM DOUBLE BYTE CONSTANT ....................... 13 + 4.7 FILL - FILL MEMORY .................................... 14 + 4.8 OPT - ASSEMBLER OUTPUT OPTIONS ........................ 14 + 4.9 ORG - SET PROGRAM COUNTER TO ORIGIN ................... 14 + 4.10 PAGE - TOP OF PAGE ................................... 15 + 4.11 RMB - RESERVE MEMORY BYTES ........................... 15 + 4.12 ZMB - ZERO MEMORY BYTES .............................. 15 + +APPENDIX A - CHARACTER SET ....................................... 16 + +APPENDIX B - ADDRESSING MODES .................................... 18 + + B.1 M6800/M6801 ADDRESSING MODES .......................... 18 + B.2 M6804/68HC04 ADDRESSING MODES ......................... 19 + B.3 M6805/68HC05 ADDRESSING MODES ......................... 21 + + + + i + + + + + + + + TABLE OF CONTENTS + + B.4 M6809 ADDRESSING MODES ................................ 22 + B.5 M68HC11 ADDRESSING MODES .............................. 26 + +APPENDIX C - DIRECTIVE SUMMARY ................................... 28 + +APPENDIX D - ASSEMBLER LISTING FORMAT ............................ 29 + +APPENDIX E - S-RECORD INFORMATION ................................ 30 + + E.1 INTRODUCTION .......................................... 30 + E.2 S-RECORD CONTENT ...................................... 30 + E.3 S-RECORD TYPES ........................................ 30 + E.4 S-RECORD EXAMPLE ...................................... 31 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ii + + + + + + + + CHAPTER 1 + GENERAL INFORMATION + + +1.1 INTRODUCTION + +This is the user's reference manual for the IBM-PC hosted Motorola +Freeware 8 bit cross assemblers. It details the features and +capabilities of the cross assemblers, assembler syntax and directives, +options, and listings. It is intended as a detailed reference and an +introduction for those unfamiliar with Motorola assembler syntax and +format. Those experienced with Motorola assembler products may wish +to examine the file ASEMBLER.DOC available with the cross assemblers, +which briefly describes the differences between these assemblers and +earlier, non-pc based versions. + +Assemblers are programs that process assembly language source program +statements and translate them into executable machine language object +files. A programmer writes his source program using any text editor +or word processor that can produce an ASCII text output. With some +word processors this is known as "non document" mode. Non document +mode produces a file without the non-printable embedded control +characters that are used in document formating. (Caution: assembling +a file that has been formatted with embedded control characters may +produce assembler errors. The solution is to convert the source file +to ASCII text.) Once the source code is written, the source file is +assembled by processing the file via the assembler. + +Cross assemblers (such as the Motorola Freeware Assemblers) allow +source programs written and edited on one computer (the host) to +generate executable code for another computer (the target). The +executable object file can then be downloaded and run on the target +system. In this case the host is an IBM-PC or compatible and the +target system is based on a Motorola 8-bit microprocessor (6800, 6801, +6803, 6805, 68HC05, 6809, or 68HC11). + +The assemblers are the executable programs AS*.EXE where * is any of +0, 1, 4, 5, 9, or 11 depending on which microprocessor you are writing +code for. The details of executing the assembler programs are found +in Chapter 3. The assembly language format and syntax for the various +processors is very similar with slight variations due to varied +programming resources (instructions, addressing modes, and registers). +These variations are explained in Appendix B. + + +1.2 ASSEMBLY LANGUAGE + +The symbolic language used to code source programs to be processed by +the Assembler is called assembly language. The language is a +collection of mnemonic symbols representing: operations (i.e., machine +instruction mnemonics or directives to the assembler), symbolic names, +operators, and special symbols. The assembly language provides +mnemonic operation codes for all machine instructions in the +instruction set. The instructions are defined and explained in the +Programming Reference Manuals for the specific devices, available from +Motorola. The assembly language also contains mnemonic directives + + + + + + + + Freeware Assemblers User's Manual + + +which specify auxiliary actions to be performed by the Assembler. +These directives are not always translated into machine language. + + +1.3 OPERATING ENVIRONMENT + +These assemblers will run on any IBM-PC, XT, AT, PS-2, or true +compatible. The assemblers may be run off of a floppy disk drive or +they may be copied onto a hard drive for execution. DOS 2.0 or later +is required. + + +1.4 ASSEMBLER PROCESSING + +The Macro Assembler is a two-pass assembler. During the first pass, +the source program is read to develop the symbol table. During the +second pass, the object file is created (assembled) with reference to +the table developed in pass one. It is during the second pass that +the source program listing is also produced. + +Each source statement is processed completely before the next source +statement is read. As each statement is processed, the Assembler +examines the label, operation code, and operand fields. The operation +code table is scanned for a match with a known opcode. During the +processing of a standard operation code mnemonic, the standard +machine code is inserted into the object file. If an Assembler +directive is being processed, the proper action is taken. + +Any errors that are detected by the Assembler are displayed before the +actual line containing the error is printed. If no source listing is +being produced, error messages are still displayed to indicate that +the assembly process did not proceed normally. + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + Freeware Assemblers User's Manual + + + CHAPTER 2 + CODING ASSEMBLY LANGUAGE PROGRAMS + + +2.1 INTRODUCTION + +Programs written in assembly language consist of a sequence of source +statements. Each source statement consists of a sequence of ASCII +characters ending with a carriage return. Appendix A contains a list +of the supported character set. + + +2.2 SOURCE STATEMENT FORMAT + +Each source statement may include up to four fields: a label (or "*" +for a comment line), an operation (instruction mneumonic or assembler +directive), an operand, and a comment. + + +2.2.1 Label Field + +The label field occurs as the first field of a source statement. The +label field can take one of the following forms: + +1. An asterisk (*) as the first character in the label field indicates +that the rest of the source statement is a comment. Comments are +ignored by the Assembler, and are printed on the source listing only +for the programmer's information. + +2. A whitespace character (blank or tab) as the first character +indicates that the label field is empty. The line has no label and is +not a comment. + +3. A symbol character as the first character indicates that the line +has a label. Symbol characters are the upper or lower case letters a- +z, digits 0-9, and the special characters, period (.), dollar sign +($), and underscore (_). Symbols consist of one to 15 characters, the +first of which must be alphabetic or the special characters period (.) +or underscore (_). All characters are significant and upper and lower +case letters are distinct. + +A symbol may occur only once in the label field. If a symbol does +occur more than once in a label field, then each reference to that +symbol will be flagged with an error. + +With the exception of some directives, a label is assigned the value +of the program counter of the first byte of the instruction or data +being assembled. The value assigned to the label is absolute. +Labels may optionally be ended with a colon (:). If the colon is +used it is not part of the label but merely acts to set the label off +from the rest of the source line. Thus the following code fragments +are equivalent: + + here: deca + bne here + + + + 3 + + + + + Freeware Assemblers User's Manual + + + here deca + bne here + +A label may appear on a line by itself. The assembler interprets this +as set the value of the label equal to the current value of the +program counter. + +The symbol table has room for at least 2000 symbols of length 8 +characters or less. Additional characters up to 15 are permissible at +the expense of decreasing the maximum number of symbols possible in +the table. + + +2.2.2 Operation Field + +The operation field occurs after the label field, and must be preceded +by at least one whitespace character. The operation field must contain +a legal opcode mneumonic or an assembler directive. Upper case +characters in this field are converted to lower case before being +checked as a legal mneumonic. Thus 'nop', 'NOP', and 'NoP' are +recognized as the same mneumonic. Entries in the operation field may +be one of two types: + +Opcode. These correspond directly to the machine instructions. The +operation code includes any register name associated with the +instruction. These register names must not be separated from the +opcode with any whitespace characters. Thus 'clra' means clear +accumulator A, but 'clr a' means clear memory location identified by +the label 'a'. + +Directive. These are special operation codes known to the Assembler +which control the assembly process rather than being translated into +machine instructions. + + +2.2.3 Operand Field + +The operand field's interpretation is dependent on the contents of the +operation field. The operand field, if required, must follow the +operation field, and must be preceded by at least one whitespace +character. The operand field may contain a symbol, an expression, or a +combination of symbols and expressions separated by commas. + +The operand field of machine instructions is used to specify the +addressing mode of the instruction, as well as the operand of the +instruction. The following tables summarize the operand field +formats for the various processor families. (NOTE: in these tables +parenthesis "()" signify optional elements and angle brackets "<>" +denote an expression is inserted. These syntax elements are present +only for clarification of the format and are not inserted as part of +the actual source program. All other characters are significant and +must be used when required.) + + + + + + + 4 + + + + + Freeware Assemblers User's Manual + + +2.2.3.1 M6800/6801 Operand Syntax + +The format of the operand field for M6800/6801 instructions is: + + Operand Format M6800/M6801 Addressing Mode + -------------- --------------------------- + no operand accumulator and inherent + direct, extended, or relative + # immediate + ,X indexed + +Details of the M6800/6801 addressing modes may be found in Appendix B. + + +2.2.3.2 M6804/68HC Operand Syntax + +For the M6804/68HC04, the following operand formats exist: + + Operand Format M6804/68HC04 Addressing Mode + -------------- ---------------------------- + no operand accumulator and inherent + direct, extended, or relative + # immediate + bit set or clear + , bit test and branch + [ or ] register indirect + ,# move indirect + +Details of the M6804/68HC04 addressing modes may be found in Appendix +B. + + +2.2.3.3 M6805/M68HC05 Operand Syntax + +For the M6805/68HC05, the operand formats are: + + Operand Format M6805/68HC05 Addressing Mode + -------------- ---------------------------- + no operand accumulator and inherent + direct, extended, or relative + # immediate + ,X indexed + , bit set or clear + ,, bit test and branch + +Details of the M6805/68HC05 addressing modes may be found in Appendix +B. + + +2.2.3.4 M6809 Operand Syntax + +For the M6809, the following operand formats are used: + + + + + + + 5 + + + + + Freeware Assemblers User's Manual + + + Operand Format M6809 Addressing Mode + -------------- --------------------- + no operand accumulator and inherent + direct, extended, or relative + # immediate + ,X indexed + < forced direct + > forced extended + ] extended indirect + ,R indexed + <,R forced 8-bit offset indexed + >,R forced 16-bit offset indexed + [,R] indexed indirect + <[,R] forced 8-bit offset indexed indirect + >[,R] forced 16-bit offset indexed indirect + Q+ auto increment by 1 + Q++ auto increment by 2 + [Q++] auto increment indirect + -Q auto decrement by + --Q auto decrement by 2 + [--Q] auto decrement indirect + W1,[W2,...,Wn] immediate + +where R is one of the registers PCR, S, U, X, or Y, and Q is one of +the registers S, U, X, or Y. Wi (i=1 to n) is one of the symbols A, +B, CC, D, DP, PC, S, U, X, or Y. + +Details of the M6809 addressing modes may be found in Appendix B. + + +2.2.3.5 M68HC11 Operand Syntax + +For the M68HC11, the following operand formats exist: + + Operand Format M68HC11 Addressing Mode + -------------- ----------------------- + no operand accumulator and inherent + direct, extended, or relative + # immediate + ,X indexed with X register + ,Y indexed with Y register + bit set or clear + bit test and branch + +The bit manipulation instruction operands are separated by spaces in +this case since the HC11 allows bit manipulation instructions on +indexed addresses. Thus a ',X' or ',Y' may be added to the final two +formats above to form the indexed effective address calculation. + +Details of the M68HC11 addressing modes may be found in Appendix B. +The operand fields of assembler directives are described in Chapter 4. + + +2.2.3.6 Expressions. An expression is a combination of symbols, +constants, algebraic operators, and parentheses. The expression is +used to specify a value which is to be used as an operand. + + + 6 + + + + + Freeware Assemblers User's Manual + + +Expressions may consist of symbols, constants, or the character '*' +(denoting the current value of the program counter) joined together by +one of the operators: + - * / % & | ^ . + + +2.2.3.7 Operators. The operators are the same as in c: + + + add + - subtract + * multiply + / divide + % remainder after division + & bitwise and + | bitwise or + ^ bitwise exclusive or + +Expressions are evaluated left to right and there is no provision for +parenthesized expressions. Arithmetic is carried out in signed two- +complement integer precision (that's 16 bits on the IBM PC). + + +2.2.3.8 Symbols. Each symbol is associated with a 16-bit integer +value which is used in place of the symbol during the expression +evaluation. The asterisk (*) used in an expression as a symbol +represents the current value of the location counter (the first byte +of a multi-byte instruction). + + +2.2.3.9 Constants. Constants represent quantities of data that do +not vary in value during the execution of a program. Constants may be +presented to the assembler in one of five formats: decimal, +hexadecimal, binary, or octal, or ASCII. The programmer indicates the +number format to the assembler with the following prefixes: + + $ HEX + % BINARY + @ OCTAL + ' ASCII + +Unprefixed constants are interpreted as decimal. The assembler +converts all constants to binary machine code and are displayed in the +assembly listing as hex. + +A decimal constant consists of a string of numeric digits. The value +of a decimal constant must fall in the range 0-65535, inclusive. The +following example shows both valid and invalid decimal constants: + + VALID INVALID REASON INVALID + ----- ------- -------------- + 12 123456 more than 5 digits + 12345 12.3 invalid character + +A hexadecimal constant consists of a maximum of four characters from +the set of digits (0-9) and the upper case alphabetic letters (A-F), +and is preceded by a dollar sign ($). Hexadecimal constants must be + + + + 7 + + + + + Freeware Assemblers User's Manual + + +in the range $0000 to $FFFF. The following example shows both valid +and invalid hexadecimal constants: + + VALID INVALID REASON INVALID + ----- ------- -------------- + $12 ABCD no preceding "$" + $ABCD $G2A invalid character + $001F $2F018 too many digits + +A binary constant consists of a maximum of 16 ones or zeros preceded +by a percent sign (%). The following example shows both valid and +invalid binary constants: + + VALID INVALID REASON INVALID + ----- ------- -------------- + %00101 1010101 missing percent + %1 %10011000101010111 too many digits + %10100 %210101 invalid digit + +An octal constant consists of a maximum of six numeric digits, +excluding the digits 8 and 9, preceded by a commercial at-sign (@). +Octal constants must be in the ranges @0 to @177777. The following +example shows both valid and invalid octal constan +ts: + + VALID INVALID REASON INVALID + ----- ------- -------------- + @17634 @2317234 too many digits + @377 @277272 out of range + @177600 @23914 invalid character + +A single ASCII character can be used as a constant in expressions. +ASCII constants are preceded by a single quote ('). Any character, +including the single quote, can be used as a character constant. The +following example shows both valid and inval +id character constants: + + VALID INVALID REASON INVALID + ----- ------- -------------- + '* 'VALID too long + +For the invalid case above the assembler will not indicate an error. +Rather it will assemble the first character and ignore the remainder. + + +2.2.4 Comment Field + +The last field of an Assembler source statement is the comment field. +This field is optional and is only printed on the source listing for +documentation purposes. The comment field is separated from the +operand field (or from the operation field if no operand is required) +by at least one whitespace character. The comment field can contain +any printable ASCII characters. + + + + + + 8 + + + + + Freeware Assemblers User's Manual + + +2.3 ASSEMBLER OUTPUT + +The Assembler output includes an optional listing of the source +program and an object file which is in the Motorola S Record format. +Details of the S Record format may be found in Appendix E. The +Assembler will normally suppress the printing of the source listing. +This condition, as well as others, can be overridden via options +supplied on the command line that invoked the Assembler. + +Each line of the listing contains a reference line number, the address +and bytes assembled, and the original source input line. If an input +line causes more than 6 bytes to be output (e.g. a long FCC +directive), additional bytes (up to 64) are listed on succeeding lines +with no address preceding them. + +The assembly listing may optionally contain a symbol table or a cross +reference table of all symbols appearing in the program. These are +always printed at the end of the assembly listing if either the symbol +table or cross reference table options (Paragraph 4.8) are in effect. +The symbol table contains the name of each symbol, along with its +defined value. The cross reference table additionally contains the +assembler-maintained source line number of every reference to every +symbol. The format of the cross reference table is shown in Appendix +D. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + Freeware Assemblers User's Manual + + + CHAPTER 3 + RUNNING THE ASSEMBLERS + + +3.1 ASSEMBLER INVOCATION + +The Motorola Freeware Assembly programs are named as*.exe where '*' is +any of 0, 1, 4, 5, 9, or 11 depending on which processor family you +wish to assemble code for. For example, to generate M6800 code run +the as0.exe program. To generate M68HC05 code run the as5.exe +program, and so forth. To run the assembler enter the following +command line: + + as* file1 (file2 . . . ) ( - option1 option2 . . . ) + +where file1, file2, etc are the names of the source files you wish to +assemble. The source filenames may have extensions but the assembler +does not check for any particular extension ( however, do not use the +.S19 extension since that is the extension of the object file created +by the assembler. Its creation would overwrite the source file when +it is written to the disk). + +The options are one or more of the following: + + l enables output listing + no disables output listing (default). + cre enables the cross reference table generation + s enables the symbol table generation + c enables cycle counting + noc disables cycle counting + +The minus sign preceding the option should be separated from the last +file name by a space. These options may also be indicated to the +assembler by the use of the OPT directive in the source file. The OPT +directive is described in Paragraph 4.8. + +The object file created is written to disk and given the name +'FILENAME.S19' where 'FILENAME' is the name of the first source file +specified on the command line. Any errors and the optional listing +(if specified) are displayed on the screen. The listing and/or error +messages may be saved to a file for later examination or printing by +append an i/o redirection command to the command line. On the PC i/o +redirection is indicated with the greater-than ('>') symbol followed +by any new or existing file name. + +Command line examples: + +The command line + + as5 myfile + +would run the M6805/68HC05 assembler on the source file 'myfile'. The +object file would be written to 'myfile.s19' and any errors would +appear on the screen. + + + + + 10 + + + + + Freeware Assemblers User's Manual + + +The command line + + as9 test.asm nexttest.s -l + +would run the M6809 assembler on the source files 'test.asm' and +'nexttest.s'. The object file would be written to 'test.s19' and any +errors and the assembly listing would appear on the screen. + +The command line + + as9 test.asm nexttest.s -l cre s >test.lst + +would run the M6809 assembler on the source files 'test.asm' and +'nexttest.s'. The object file would be written to 'test.s19'. A +listing would be created followed by a symbol table and cross +reference which would all be written to the file test.lst +. + +3.2 ERROR MESSAGES + +Error diagnostic messages are placed in the listing file just before +the line containing the error. The format of the error line is: + + Line_number: Description of error + + or + + Line_number: Warning ---- Description of error + +Errors in pass one cause cancellation of pass two. Warning do not +cause cancellation of pass two but are indications of a possible +problem. Error messages are meant to be self-explanatory. + +If more than one file is being assembled, the file name precedes the +error: + + File_name,Line_number: Description of error + +Some errors are classed as fatal and cause an immediate termination of +the assembly. Generally this happens when a temporary file cannot be +created or is lost during assembly. + + + + + + + + + + + + + + + + + + 11 + + + + + Freeware Assemblers User's Manual + + + CHAPTER 4 + ASSEMBLER DIRECTIVES + + +4.1 INTRODUCTION + +The Assembler directives are instructions to the Assembler, rather +than instructions to be directly translated into object code. This +chapter describes the directives that are recognized by the Freeware +Assemblers. Detailed descriptions of each directive are arranged +alphabetically. The notations used in this chapter are: + + ( ) Parentheses denote an optional element. + + XYZ The names of the directives are printed in capital letters. + + < > The element names are printed in lower case and contained in +angle brackets. All elements outside of the angle brackets '<>' must +be specified as-is. For example, the syntactical element (,) +requires the comma to be specified if the optional element is +selected. The following elements are used in the subsequent +descriptions: + + + A statement's comment field +
tags/V10/sw/epedit.exe Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/V10/sw/as9.exe =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/V10/sw/as9.exe =================================================================== --- tags/V10/sw/as9.exe (nonexistent) +++ tags/V10/sw/as9.exe (revision 3)
tags/V10/sw/as9.exe Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.