URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 12 to Rev 13
- ↔ Reverse comparison
Rev 12 → Rev 13
/trunk/rtl/S2_B3_VDU/Sys09_B3_VDU.zip
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/rtl/S2E_B5_X300_VDU/Sys09_vdu_B5_X300.zip
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/rtl/S3_Starter_VDU/Sys09_VDU_Starter.zip
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/rtl/vhdl/cpu09.vhd
1,3 → 1,4
-- $Id: cpu09.vhd,v 1.4 2006-07-16 17:44:23 dilbert57 Exp $ |
--===========================================================================---- |
-- |
-- S Y N T H E Z I A B L E CPU09 - 6809 compatible CPU Core |
88,6 → 89,57
-- operand instructions using the MD register which is |
-- sign extended on the first 8 bit fetch. |
-- |
-- Version 1.10 - 13 September 2005 |
-- TFR & EXG instructions did not work for the Condition Code Register |
-- An extra case has been added to the ALU for the alu_tfr control |
-- to assign the left ALU input (alu_left) to the condition code |
-- outputs (cc_out). |
-- |
-- Version 1.11 - 16 September 2005 |
-- JSR ,X should not predecrement S before calculating the jump address. |
-- The reason is that JSR [0,S] needs S to point to the top of the stack |
-- to fetch a valid vector address. The solution is to have the addressing |
-- mode microcode called before decrementing S and then decrementing S in |
-- JSR_STATE. JSR_STATE in turn calls PUSH_RETURN_LO_STATE rather than |
-- PUSH_RETURN_HI_STATE so that both the High & Low halves of the PC are |
-- pushed on the stack. This adds one extra bus cycle, but resolves the |
-- addressing conflict. I've also removed the pre-decement S in |
-- JSR EXTENDED as it also calls JSR_STATE. |
-- |
-- Version 1.12 - 6th June 2006 |
-- 6809 Programming reference manual says V is not affected by ASR, LSR and ROR |
-- This is different to the 6800. CLR should reset the V bit. |
-- |
-- Version 1.13 - 7th July 2006 |
-- Disable NMI on reset until S Stack pointer has been loaded. |
-- Added nmi_enable signal in sp_reg process and nmi_handler process. |
-- |
-- Version 1.4 - 11th July 2006 |
-- 1. Added new state to RTI called rti_entire_state. |
-- This state tests the CC register after it has been loaded |
-- from the stack. Previously the current CC was tested which |
-- was incorrect. The Entire Flag should be set before the |
-- interrupt stacks the CC. |
-- 2. On bogus Interrupts, int_cc_state went to rti_state, |
-- which was an enumerated state, but not defined anywhere. |
-- rti_state has been changed to rti_cc_state so that bogus interrupt |
-- will perform an RTI after entering that state. |
-- 3. Sync should generate an interrupt if the interrupt masks |
-- are cleared. If the interrupt masks are set, then an interrupt |
-- will cause the the PC to advance to the next instruction. |
-- Note that I don't wait for an interrupt to be asserted for |
-- three clock cycles. |
-- 4. Added new ALU control state "alu_mul". "alu_mul" is used in |
-- the Multiply instruction replacing "alu_add16". This is similar |
-- to "alu_add16" except it sets the Carry bit to B7 of the result |
-- in ACCB, sets the Zero bit if the 16 bit result is zero, but |
-- does not affect The Half carry (H), Negative (N) or Overflow (V) |
-- flags. The logic was re-arranged so that it adds md or zero so |
-- that the Carry condition code is set on zero multiplicands. |
-- 5. DAA (Decimal Adjust Accumulator) should set the Negative (N) |
-- and Zero Flags. It will also affect the Overflow (V) flag although |
-- the operation is undefined. It's anyones guess what DAA does to V. |
-- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
183,9 → 235,9
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_cc_state, rti_entire_state, |
rti_acca_state, rti_accb_state, |
rti_dp_state, |
rti_ixl_state, rti_ixh_state, |
rti_iyl_state, rti_iyh_state, |
rti_upl_state, rti_uph_state, |
259,7 → 311,7
alu_and, alu_ora, alu_eor, |
alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com, |
alu_lsr16, alu_lsl16, |
alu_ror8, alu_rol8, |
alu_ror8, alu_rol8, alu_mul, |
alu_asr8, alu_asl8, alu_lsr8, |
alu_andcc, alu_orcc, alu_sex, alu_tfr, alu_abx, |
alu_seif, alu_sei, alu_see, alu_cle, |
285,6 → 337,7
signal iv: std_logic_vector(2 downto 0); |
signal nmi_req: std_logic; |
signal nmi_ack: std_logic; |
signal nmi_enable: std_logic; |
|
signal state: state_type; |
signal next_state: state_type; |
530,24 → 583,30
-- S stack pointer |
-- |
-------------------------------- |
sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in ) |
sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in, nmi_enable ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
sp <= sp; |
nmi_enable <= nmi_enable; |
else |
case sp_ctrl is |
when reset_sp => |
sp <= "0000000000000000"; |
nmi_enable <= '0'; |
when load_sp => |
sp <= out_alu(15 downto 0); |
nmi_enable <= '1'; |
when pull_hi_sp => |
sp(15 downto 8) <= data_in; |
nmi_enable <= nmi_enable; |
when pull_lo_sp => |
sp(7 downto 0) <= data_in; |
nmi_enable <= '1'; |
when others => |
-- when latch_sp => |
sp <= sp; |
nmi_enable <= nmi_enable; |
end case; |
end if; |
end if; |
811,13 → 870,13
-- |
------------------------------------ |
|
nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req ) |
nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req, nmi_enable ) |
begin |
if clk'event and clk='0' then |
if rst='1' then |
nmi_req <= '0'; |
else |
if (nmi='1') and (nmi_ack='0') then |
if (nmi='1') and (nmi_ack='0') and (nmi_enable='1') then |
nmi_req <= '1'; |
else |
if (nmi='0') and (nmi_ack='1') then |
1084,7 → 1143,7
|
case alu_ctrl is |
when alu_add8 | alu_inc | |
alu_add16 | alu_adc => |
alu_add16 | alu_adc | alu_mul => |
out_alu <= left + right + ("000000000000000" & carry_in); |
when alu_sub8 | alu_dec | |
alu_sub16 | alu_sbc => |
1153,7 → 1212,9
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); |
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0); |
when alu_mul => |
cc_out(CBIT) <= out_alu(7); |
when alu_daa => |
if ( daa_reg(7 downto 4) = "0110" ) then |
cc_out(CBIT) <= '1'; |
1164,6 → 1225,8
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; |
1177,10 → 1240,10
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 => |
alu_ld8 | alu_st8 | alu_sex | alu_daa => |
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 | |
when alu_add16 | alu_sub16 | alu_mul | |
alu_lsl16 | alu_lsr16 | |
alu_ld16 | alu_st16 | alu_lea => |
cc_out(ZBIT) <= not( out_alu(15) or out_alu(14) or out_alu(13) or out_alu(12) or |
1191,6 → 1254,8
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; |
1204,7 → 1269,7
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 => |
alu_ld8 | alu_st8 | alu_sex | alu_daa => |
cc_out(NBIT) <= out_alu(7); |
when alu_add16 | alu_sub16 | |
alu_lsl16 | alu_lsr16 | |
1214,6 → 1279,8
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; |
1226,6 → 1293,8
cc_out(IBIT) <= left(IBIT) and cc(IBIT); |
when alu_orcc => |
cc_out(IBIT) <= left(IBIT) or cc(IBIT); |
when alu_tfr => |
cc_out(IBIT) <= left(IBIT); |
when alu_seif | alu_sei => |
cc_out(IBIT) <= '1'; |
when others => |
1244,6 → 1313,8
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; |
1270,17 → 1341,30
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); |
-- 6809 Programming reference manual says |
-- V not affected by ASR, LSR and ROR |
-- This is different to the 6800 |
-- John Kent 6th June 2006 |
-- 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 => |
when alu_rol8 | alu_asl8 => |
cc_out(VBIT) <= left(7) xor left(6); |
when alu_and | alu_ora | alu_eor | alu_com | |
-- |
-- 11th July 2006 - John Kent |
-- What DAA does with V is anyones guess |
-- It is undefined in the 6809 programming manual |
-- |
when alu_daa => |
cc_out(VBIT) <= left(7) xor out_alu(7) xor cc(CBIT); |
-- CLR resets V Bit |
-- John Kent 6th June 2006 |
when alu_and | alu_ora | alu_eor | alu_com | alu_clr | |
alu_st8 | alu_st16 | alu_ld8 | alu_ld16 | alu_sex => |
cc_out(VBIT) <= '0'; |
when alu_andcc => |
1287,6 → 1371,8
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; |
1296,6 → 1382,8
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 => |
1307,6 → 1395,8
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 => |
3084,12 → 3174,12
next_state <= indexed_state; |
|
when "1101" => -- jsr ,x |
-- pre decrement SP |
-- DO NOT pre decrement SP |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= jsr_state; |
3158,12 → 3248,12
next_state <= extended_state; |
|
when "1101" => -- jsr >extended |
-- pre decrement sp |
-- DO NOT pre decrement sp |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= jsr_state; |
5122,8 → 5212,7
+ pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
@@ -5525,9 +5614,8 @@
--
-- jump to subroutine
- -- (sp)=pc_lo
-- sp=sp-1
- -- call push_return_hi_state to save hi pc
+ -- call push_return_lo_state to save pc
-- return to jmp_state
--
when jsr_state =>
@@ -5550,13 +5638,13 @@
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
sp_ctrl <= load_sp;
- -- write pc lo byte
- addr_ctrl <= pushs_ad;
+ -- idle bus
+ addr_ctrl <= idle_ad;
dout_ctrl <= pc_lo_dout;
- -- call second half of push_return_state
+ -- call push_return_state
st_ctrl <= push_st;
return_state <= jmp_state;
- next_state <= push_return_hi_state;
+ next_state <= push_return_lo_state;
--
-- Load pc with ea
@@ -6348,17 +6436,15 @@
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;
+ right_ctrl <= md_right;
else
- cc_ctrl <= latch_cc;
- acca_ctrl <= latch_acca;
- accb_ctrl <= latch_accb;
+ right_ctrl <= zero_right;
end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
md_ctrl <= shiftl_md;
-- idle bus
addr_ctrl <= idle_ad;
@@ -6383,17 +6469,15 @@
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;
+ right_ctrl <= md_right;
else
- cc_ctrl <= latch_cc;
- acca_ctrl <= latch_acca;
- accb_ctrl <= latch_accb;
+ right_ctrl <= zero_right;
end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
md_ctrl <= shiftl_md;
-- idle bus
addr_ctrl <= idle_ad;
@@ -6418,17 +6502,15 @@
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;
+ right_ctrl <= md_right;
else
- cc_ctrl <= latch_cc;
- acca_ctrl <= latch_acca;
- accb_ctrl <= latch_accb;
+ right_ctrl <= zero_right;
end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
md_ctrl <= shiftl_md;
-- idle bus
addr_ctrl <= idle_ad;
@@ -6453,17 +6535,15 @@
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;
+ right_ctrl <= md_right;
else
- cc_ctrl <= latch_cc;
- acca_ctrl <= latch_acca;
- accb_ctrl <= latch_accb;
+ right_ctrl <= zero_right;
end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
md_ctrl <= shiftl_md;
-- idle bus
addr_ctrl <= idle_ad;
@@ -6488,17 +6568,15 @@
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;
+ right_ctrl <= md_right;
else
- cc_ctrl <= latch_cc;
- acca_ctrl <= latch_acca;
- accb_ctrl <= latch_accb;
+ right_ctrl <= zero_right;
end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
md_ctrl <= shiftl_md;
-- idle bus
addr_ctrl <= idle_ad;
@@ -6523,17 +6601,15 @@
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;
+ right_ctrl <= md_right;
else
- cc_ctrl <= latch_cc;
- acca_ctrl <= latch_acca;
- accb_ctrl <= latch_accb;
+ right_ctrl <= zero_right;
end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
md_ctrl <= shiftl_md;
-- idle bus
addr_ctrl <= idle_ad;
@@ -6558,17 +6634,15 @@
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;
+ right_ctrl <= md_right;
else
- cc_ctrl <= latch_cc;
- acca_ctrl <= latch_acca;
- accb_ctrl <= latch_accb;
+ right_ctrl <= zero_right;
end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
md_ctrl <= shiftl_md;
-- idle bus
addr_ctrl <= idle_ad;
@@ -6593,17 +6667,15 @@
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;
+ right_ctrl <= md_right;
else
- cc_ctrl <= latch_cc;
- acca_ctrl <= latch_acca;
- accb_ctrl <= latch_accb;
+ right_ctrl <= zero_right;
end if;
+ alu_ctrl <= alu_mul;
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
md_ctrl <= shiftl_md;
-- idle bus
addr_ctrl <= idle_ad;
@@ -8556,6 +8628,9 @@
return_state <= fetch_state;
next_state <= fetch_state;
+ --
+ -- pop the Condition codes
+ --
when rti_cc_state =>
-- default registers
acca_ctrl <= latch_acca;
@@ -8583,13 +8658,44 @@
--
st_ctrl <= idle_st;
return_state <= fetch_state;
+ next_state <= rti_entire_state;
+
+ --
+ -- Added RTI cycle 11th July 2006 John Kent.
+ -- test the "Entire" Flag
+ -- that has just been popped off the stack
+ --
+ when rti_entire_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;
+ -- idle sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_nop;
+ sp_ctrl <= latch_sp;
+ -- idle cc
+ cc_ctrl <= latch_cc;
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= cc_dout;
--
- -- 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
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
--
+ -- The Entire flag must be recovered from the stack
+ -- before testing.
+ --
if cc(EBIT) = '1' then
next_state <= rti_acca_state;
else
@@ -9358,7 +9464,7 @@
if op_code = "00111100" then -- CWAI
next_state <= int_cwai_state;
else
- next_state <= rti_state;
+ next_state <= rti_cc_state; -- spurious interrupt, do a RTI
end if;
end case;
@@ -9458,6 +9564,17 @@
return_state <= fetch_state;
next_state <= vect_hi_state;
+ --
+ -- According to the 6809 programming manual:
+ -- If an interrupt is received and is masked
+ -- or lasts for less than three cycles, the PC
+ -- will advance to the next instruction.
+ -- If an interrupt is unmasked and lasts
+ -- for more than three cycles, an interrupt
+ -- will be generated.
+ -- Note that I don't wait 3 clock cycles.
+ -- John Kent 11th July 2006
+ --
when sync_state =>
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
@@ -9486,7 +9603,7 @@
if (nmi_req = '1') and (nmi_ack='0') then
iv_ctrl <= nmi_iv;
nmi_ctrl <= set_nmi;
- next_state <= fetch_state;
+ next_state <= int_decr_state;
else
--
-- nmi request is not cleared until nmi input goes low
@@ -9499,15 +9616,23 @@
--
-- IRQ is level sensitive
--
- if (irq = '1') and (cc(IBIT) = '0') then
+ if (irq = '1') then
iv_ctrl <= irq_iv;
- next_state <= fetch_state;
- elsif (firq = '1') and (cc(FBIT) = '0') then
+ if (cc(IBIT) = '0') then
+ next_state <= int_decr_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ elsif (firq = '1') then
--
-- FIRQ is level sensitive
--
iv_ctrl <= firq_iv;
- next_state <= fetch_state;
+ if (cc(FBIT) = '0') then
+ next_state <= int_decr_state;
+ else
+ next_state <= fetch_state;
+ end if;
else
iv_ctrl <= latch_iv;
next_state <= sync_state;
-- ea holds post byte |
when index16_2_state => |
op_ctrl <= latch_op; |