📄 mc8051.vhd
字号:
-- and the new data come in at s1p1 of next cycle
pc <= (acc+pc);
WAIT UNTIL cycle_state = s2p1;
acc <= pmem_s1_byte;
pc <= temp1 & temp2 + 1;
-- MOVX A, @Ri
WHEN 16#E2# TO 16#E3# =>
temp1 := get_reg("00"&opcode(0)); -- the addr
p0_latch <= "11111111"; -- reset the p0 sfr
p0_addr <= temp1; -- send out addr when p0_ctrl
WAIT UNTIL cycle_state = s3p1;
port_req <= '1';
WAIT UNTIL cycle_state = s4p2;
ale_dm <= '1';
WAIT UNTIL cycle_state = s5p1;
p0_ctrl <= '1';
p3_ctrl(7) <= '1';
WAIT UNTIL cycle_state = s5p2;
ale_dm <= '0';
WAIT UNTIL cycle_state = s1p1;
rd_n_internal <= '0';
p0_ctrl <= 'Z';
WAIT UNTIL cycle_state = s3p1;
-- read into the accumulator
acc <= bvec(to_X01(P0));
WAIT UNTIL cycle_state = s4p1;
rd_n_internal <= '1';
port_req <= '0';
p3_ctrl(7) <= 'Z';
p0_addr <= "ZZZZZZZZ";
pc <= pc + 1;
-- MOVX A, @DPTR
WHEN 16#E0# =>
p0_latch <= "11111111"; -- reset the p0 latch
WAIT UNTIL cycle_state = s3p1;
port_req <= '1';
WAIT UNTIL cycle_state = s4p2;
ale_dm <= '1';
WAIT UNTIL cycle_state = s5p1;
p0_addr <= dpl; -- send out the addr
p2_addr <= dph; -- send out the addr
p0_ctrl <= '1';
p2_ctrl <= '1';
p3_ctrl(7) <= '1';
WAIT UNTIL cycle_state = s5p2;
ale_dm <= '0';
WAIT UNTIL cycle_state = s1p1;
rd_n_internal <= '0';
p0_ctrl <= 'Z';
WAIT UNTIL cycle_state = s3p1;
-- read into the accumulator
acc <= bvec(to_X01(P0));
WAIT UNTIL cycle_state = s4p1;
rd_n_internal <= '1';
port_req <= '0';
p0_addr <= "ZZZZZZZZ";
p2_ctrl <= 'Z';
p3_ctrl(7) <= 'Z';
pc <= pc + 1;
-- MOVX @Ri, A
WHEN 16#F2# TO 16#F3# =>
temp1 := get_reg("00"&opcode(0)); -- the addr
p0_latch <= "11111111"; -- reset the p0 latch
WAIT UNTIL cycle_state = s3p1;
port_req <= '1';
WAIT UNTIL cycle_state = s4p2;
ale_dm <= '1';
WAIT UNTIL cycle_state = s5p1;
p0_addr <= temp1; -- send out the addr
p0_ctrl <= '1';
p3_ctrl(6) <= '1';
WAIT UNTIL cycle_state = s5p2;
ale_dm <= '0';
WAIT UNTIL cycle_state = s6p2;
p0_addr <= acc; -- output the data
WAIT UNTIL cycle_state = s1p1;
wr_n_internal <= '0';
WAIT UNTIL cycle_state = s4p1;
wr_n_internal <= '1';
port_req <= '0'; -- shouldn't have any effect until s4p2
p0_ctrl <= 'Z';
p3_ctrl(6) <= 'Z';
p0_addr <= "ZZZZZZZZ";
pc <= pc + 1;
-- MOVX @DPTR, A
WHEN 16#F0# =>
p0_latch <= "11111111"; -- reset the p0 latch
WAIT UNTIL cycle_state = s3p1;
port_req <= '1';
WAIT UNTIL cycle_state = s4p2;
ale_dm <= '1';
WAIT UNTIL cycle_state = s5p1;
p0_addr <= dpl; -- send out the addr
p2_addr <= dph; -- send out the addr
p0_ctrl <= '1';
p2_ctrl <= '1';
p3_ctrl(6) <= '1';
WAIT UNTIL cycle_state = s5p2;
ale_dm <= '0';
WAIT UNTIL cycle_state = s6p2;
p0_addr <= acc; -- output the data
WAIT UNTIL cycle_state = s1p1;
wr_n_internal <= '0';
WAIT UNTIL cycle_state = s4p1;
wr_n_internal <= '1';
port_req <= '0'; -- shouldn't have any effect until s4p2
p0_ctrl <= 'Z';
p2_ctrl <= 'Z';
p3_ctrl(6) <= 'Z';
p0_addr <= "ZZZZZZZZ";
p2_addr <= "ZZZZZZZZ";
pc <= pc + 1;
-- LJMP: Long Jump
WHEN 16#02# =>
--cycle cycles := 2;
WAIT UNTIL cycle_state = s2p1; -- wait for the next cycle
pc <= pmem_s4_byte & pmem_s1_byte;
-- RR: Rotate acc right
WHEN 16#03# =>
--cycle cycles := 1;
pc <= pc + 1;
acc <= acc(0) & acc(7 DOWNTO 1);
-- INC: Acc
WHEN 16#04# =>
--cycle cycles := 1;
pc <= pc + 1;
acc <= acc + 1;
-- INC: direct address
WHEN 16#05# =>
--cycle cycles := 1;
pc <= pc + 2;
WAIT UNTIL cycle_state = s5p1;
temp1 := get_byte_dmem(pmem_s4_byte, direct, read_latch => TRUE);
set_byte_dmem(pmem_s4_byte, temp1 + 1, direct);
-- INC: @Ri
WHEN 16#06# TO 16#07# =>
--cycle cycles := 1;
pc <= pc + 1;
temp1 := get_reg("00"&opcode(0)); -- the indirect address
temp2 := get_byte_dmem(temp1, indirect); -- the data at indirect addr
set_byte_dmem(temp1, temp2 + 1, indirect);
-- INC: Reg
WHEN 16#08# TO 16#0F# =>
--cycle cycles := 1;
pc <= pc + 1;
set_reg(opcode(2 DOWNTO 0), get_reg(opcode(2 DOWNTO 0)) + 1);
-- JBC: Jump if Bit set and Clear bit
WHEN 16#10# =>
--cycle cycles := 2;
WAIT UNTIL cycle_state = s2p1; -- wait for the next cycle
IF get_bit_dmem(pmem_s4_byte, read_latch => TRUE) = '1' THEN
temp_int := conv_signed_to_int(pmem_s1_byte);
pc <= pc + 3 + temp_int;
ELSE
pc <= pc + 3;
END IF;
set_bit_dmem(pmem_s4_byte, '0');
-- LCALL: long call
WHEN 16#12# =>
--cycle cycles := 2;
WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
temp_pc := pc + 3;
set_byte_dmem(sp + 1, temp_pc(7 DOWNTO 0), indirect);
set_byte_dmem(sp + 2, temp_pc(15 DOWNTO 8), indirect);
sp <= sp + 2; -- update stack pointer to point to the new data
pc <= pmem_s4_byte & pmem_s1_byte;
-- RRC: Rotate acc right through carry flag
WHEN 16#13# =>
--cycle cycles := 1;
pc <= pc + 1;
acc <= cy & acc(7 DOWNTO 1);
cy <= acc(0);
-- DEC: Acc
WHEN 16#14# =>
--cycle cycles := 1;
pc <= pc + 1;
acc <= acc - 1;
-- DEC: direct address
WHEN 16#15# =>
--cycle cycles := 1;
pc <= pc + 2;
WAIT UNTIL cycle_state = s5p1;
temp1 := get_byte_dmem(pmem_s4_byte, direct, read_latch => TRUE);
set_byte_dmem(pmem_s4_byte, temp1 - 1, direct);
-- DEC: @Ri
WHEN 16#16# TO 16#17# =>
--cycle cycles := 1;
pc <= pc + 1;
temp1 := get_reg("00"&opcode(0)); -- indirect addr
temp2 := get_byte_dmem(temp1, indirect);
set_byte_dmem(temp1, temp2 - 1, indirect);
-- DEC: Reg
WHEN 16#18# TO 16#1F# =>
--cycle cycles := 1;
pc <= pc + 1;
set_reg(opcode(2 DOWNTO 0), get_reg(opcode(2 DOWNTO 0)) - 1);
-- JB: Jump if bit set
WHEN 16#20# =>
--cycle cycles := 2;
WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
IF get_bit_dmem(pmem_s4_byte) = '1' THEN
temp_int := conv_signed_to_int(pmem_s1_byte);
pc <= pc + 3 + temp_int;
ELSE
pc <= pc + 3;
END IF;
-- RET: Return from subroutine
WHEN 16#22# =>
--cycle cycles := 2;
WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
pc(15 DOWNTO 8) <= get_byte_dmem(sp, indirect); -- Take from the stack
pc(7 DOWNTO 0) <= get_byte_dmem(sp-1, indirect);
sp <= sp - 2; -- Update stack pointer to point to the new data
-- RL: Rotate accumulator left
WHEN 16#23# =>
--cycle cycles := 1;
pc <= pc + 1;
acc <= acc(6 DOWNTO 0) & acc(7);
-- ADD Acc
WHEN 16#24# TO 16#2F# =>
--cycle cycles := 1;
handle_add(opcode,'0'); -- Use a separate procedure, ignoring cy bit
-- JNB: Jump if bit not set
WHEN 16#30# =>
--cycle cycles := 2;
WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
IF get_bit_dmem(pmem_s4_byte) = '0' THEN
temp_int := conv_signed_to_int(pmem_s1_byte);
pc <= pc + 3 + temp_int;
ELSE
pc <= pc + 3;
END IF;
-- RETI: Return from interrupt
WHEN 16#32# =>
--cycle cycles := 2;
WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
pc(15 DOWNTO 8) <= get_byte_dmem(sp, indirect); -- Take from the stack
pc(7 DOWNTO 0) <= get_byte_dmem(sp-1, indirect);
sp <= sp - 2; -- Update stack pointer to point to the new data
-- ALSO NEEDS TO TURN INTERRUPTS BACK ON
-- If the micro is at low priority, then it must go back
-- to no priority, otherwise, it needs to go back to whatever
-- was previous.
IF current_priority = "01" THEN
current_priority <= "00";
ELSE
current_priority <= previous_priority;
END IF;
-- RLC Acc: Rotate Left through Carry
WHEN 16#33# =>
--cycle cycles := 1;
pc <= pc + 1;
acc <= acc(6 DOWNTO 0) & cy;
cy <= acc(7);
-- ADDC: Add to the acc with carry
WHEN 16#34# TO 16#3F# =>
--cycle cycles := 1;
handle_add(opcode,cy); -- Use a separate procedure, using cy bit
-- JC: Jump if carry is set
WHEN 16#40# =>
--cycle cycles := 2;
WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
IF cy='1' THEN
temp_int := conv_signed_to_int(pmem_s4_byte);
pc <= pc + 2 + temp_int;
ELSE
pc <= pc + 2;
END IF;
-- ORL to data mem from acc
WHEN 16#42# =>
--cycle cycles := 1;
pc <= pc + 2;
WAIT UNTIL cycle_state = s5p1;
temp1 := get_byte_dmem(pmem_s4_byte, direct, read_latch => TRUE);
set_byte_dmem(pmem_s4_byte, temp1 OR acc, direct);
-- ORL to data mem from immediate data
WHEN 16#43# =>
--cycle cycles := 2;
WAIT UNTIL cycle_state = s2p1; -- wait for next cycle
temp1 := get_byte_dmem(pmem_s4_byte, direct, read_latch => TRUE); -- the data value
set_byte_dmem(pmem_s4_byte, temp1 OR pmem_s1_byte, direct);
pc <= pc + 3;
-- ORL to acc
WHEN 16#44#
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -