📄 mc8051.vhd
字号:
current_priority(1) <= IP(2); current_priority(0) <= '1'; pc <= "0000000000010011"; -- 13 WAIT UNTIL cycle_state = s4p1; ELSIF ea = '1' AND (en_t1 = '1' AND TF1 = '1') AND -- timer 1 (current_priority = "00" OR (current_priority = "01" AND IP(3) = '1')) THEN -- LCALL WAIT UNTIL cycle_state = s2p1; -- wait for next cycle temp_pc := pc; 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 previous_priority <= current_priority; current_priority(1) <= IP(3); current_priority(0) <= '1'; pc <= "0000000000011011"; -- 1B -- Interrupt flag cleared in hardware TF1_main <= '0'; WAIT UNTIL cycle_state = s4p1; ELSIF ea = '1' AND (en_serial = '1' AND (trans_int = '1' OR recv_int = '1')) AND (current_priority = "00" OR (current_priority = "01" AND IP(4) = '1')) THEN -- LCALL WAIT UNTIL cycle_state = s2p1; -- wait for next cycle temp_pc := pc; 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 previous_priority <= current_priority; current_priority(1) <= IP(4); current_priority(0) <= '1'; pc <= "0000000000100011"; -- 23 WAIT UNTIL cycle_state = s4p1; ELSE -- NO INTERRUPTS -- Read in the next opcode (at s2p1) opcode := pmem_s1_byte; IF bad_data = '1' THEN pc_int := conv_integer(pc); REPORT "ERROR: COULD NOT READ OPCODE - X's read from memory. PC is " & integer'image(pc_int) & "d" SEVERITY error; END IF; -- The opcode is converted to an 8bit integer CASE smallint(conv_integer(opcode)) IS -- ACALL: absolute call WHEN 16#11# | 16#31# | 16#51# | 16#71# | 16#91# | 16#B1# | 16#D1# | 16#F1# => --cycle cycles := 2; pc <= pc + 2; WAIT UNTIL cycle_state = s2p1; -- wait for next cycle set_byte_dmem(sp + 1, pc(7 DOWNTO 0), indirect); set_byte_dmem(sp + 2, pc(15 DOWNTO 8), indirect); sp <= sp + 2; pc <= pc(15 DOWNTO 11) & opcode(7 DOWNTO 5) & pmem_s4_byte; -- AJMP: Absolute Jump WHEN 16#01# | 16#21# | 16#41# | 16#61# | 16#81# | 16#A1# | 16#C1# | 16#E1# => --cycle cycles := 2; pc <= pc + 2; WAIT UNTIL cycle_state = s2p1; -- wait for the next cycle pc <= pc(15 DOWNTO 11) & opcode(7 DOWNTO 5) & pmem_s4_byte; -- NOP: No operation WHEN 16#00# => --cycle cycles := 1; pc <= pc + 1; -- MOV A, Rn WHEN 16#E8# to 16#EF# => --cycle cycles := 1; pc <= pc + 1; acc <= get_reg(opcode(2 DOWNTO 0)); -- MOV A, data addr WHEN 16#E5# => --cycle cycles := 1; pc <= pc + 2; WAIT UNTIL cycle_state = s5p1; if pmem_s4_byte = 16#E0# then report "MOV A, ACC is not a legal instruction on many 8051 variants" severity warning; end if; acc <= get_byte_dmem(pmem_s4_byte, direct); -- MOV A, @Ri WHEN 16#E6# TO 16#E7# => --cycle cycles := 1; pc <= pc + 1; temp1 := get_reg("00"&opcode(0)); -- indirect src addr acc <= get_byte_dmem(temp1, indirect); -- MOV A, #data WHEN 16#74# => --cycle cycles := 1; pc <= pc + 2; WAIT UNTIL cycle_state = s5p1; acc <= pmem_s4_byte; -- MOV Rn, A WHEN 16#F8# TO 16#FF# => --cycle cycles := 1; pc <= pc + 1; set_reg(opcode(2 DOWNTO 0), acc); -- MOV Rn, data addr WHEN 16#A8# TO 16#AF# => --cycle cycles := 2; WAIT UNTIL cycle_state = s2p1; -- wait to next cycle pc <= pc + 2; temp1 := get_byte_dmem(pmem_s4_byte, direct); -- src data set_reg(opcode(2 DOWNTO 0), temp1); -- set to reg. -- MOV Rn, #data WHEN 16#78# TO 16#7F# => --cycle cycles := 1; pc <= pc + 2; WAIT UNTIL cycle_state = s5p1; set_reg(opcode(2 DOWNTO 0), pmem_s4_byte); -- MOV data addr, A WHEN 16#F5# => --cycle cycles := 1; pc <= pc + 2; WAIT UNTIL cycle_state = s5p1; set_byte_dmem(pmem_s4_byte, acc, direct); -- MOV data addr, Rn WHEN 16#88# TO 16#8F# => --cycle cycles := 2; WAIT UNTIL cycle_state = s2p1; -- wait to next cycle pc <= pc + 2; temp1 := get_reg(opcode(2 DOWNTO 0)); -- src data from Rn set_byte_dmem(pmem_s4_byte, temp1, direct); -- MOV direct, direct WHEN 16#85# => --cycle cycles := 2; WAIT UNTIL cycle_state = s2p1; -- wait for next cycle pc <= pc + 3; temp1 := get_byte_dmem(pmem_s4_byte, direct); -- the data at source addr set_byte_dmem(pmem_s1_byte, temp1, direct); -- set to dest addr -- MOV direct, @Ri WHEN 16#86# TO 16#87# => --cycle cycles := 2; WAIT UNTIL cycle_state = s2p1; -- wait for next cycle pc <= pc + 2; temp1 := get_reg("00" & opcode(0)); -- indirect src addr temp2 := get_byte_dmem(temp1, indirect); -- src data at addr @Ri set_byte_dmem(pmem_s4_byte, temp2, direct); -- MOV direct, #data WHEN 16#75# => --cycle cycles := 2; WAIT UNTIL cycle_state = s2p1; -- wait for next cycle pc <= pc + 3; set_byte_dmem(pmem_s4_byte, pmem_s1_byte, direct); -- MOV @Ri, A WHEN 16#F6# TO 16#F7# => --cycle cycles := 1; pc <= pc + 1; temp1 := get_reg("00"&opcode(0)); -- indirect dest addr set_byte_dmem(temp1, acc, indirect); -- MOV @Ri, direct WHEN 16#A6# TO 16#A7# => --cycle cycles := 2; WAIT UNTIL cycle_state = s2p1; -- wait for the next cycle pc <= pc + 2; temp1 := get_reg("00"&opcode(0)); -- the indirect dest addr temp2 := get_byte_dmem(pmem_s4_byte, direct); -- the src byte set_byte_dmem(temp1, temp2, indirect); -- MOV @Ri, #data WHEN 16#76# TO 16#77# => --cycle cycles := 1; pc <= pc + 2; WAIT UNTIL cycle_state = s5p1; -- wait for data temp1 := get_reg("00"&opcode(0)); -- the indirect dest addr set_byte_dmem(temp1, pmem_s4_byte, indirect); -- MOV DPTR, #data16 WHEN 16#90# => --cycle cycles := 2; WAIT UNTIL cycle_state = s2p1; -- wait for next cycle pc <= pc + 3; dph <= pmem_s4_byte; dpl <= pmem_s1_byte; -- MOV bit addr, C WHEN 16#92# => --cycle cycles := 2 WAIT UNTIL cycle_state = s2p1; -- wait for next cycle pc <= pc + 2; set_bit_dmem(pmem_s4_byte,cy); -- MOV C, bit addr WHEN 16#A2# => --cycle cycles := 1 pc <= pc + 2; WAIT UNTIL cycle_state = s5p1; cy <= get_bit_dmem(pmem_s4_byte); -- MOVC A, @A + DPTR WHEN 16#93# => --cycle cycles := 2; temp1 := PC(15 DOWNTO 8); temp2 := PC(7 DOWNTO 0); -- Set the program counter, so that the addr will go out at s4p2, -- and the new data come in at s1p1 of next cycle pc(7 DOWNTO 0) <= acc + dpl; IF conv_integer(acc)+conv_integer(dpl) > 255 THEN pc(15 DOWNTO 8) <= dph + 1; ELSE pc(15 DOWNTO 8) <= dph; END IF; WAIT UNTIL cycle_state = s2p1; acc <= pmem_s1_byte; pc <= temp1 & temp2 + 1; -- MOVC A, @A + PC WHEN 16#83# => --cycle cycles := 2; temp1 := PC(15 DOWNTO 8); temp2 := PC(7 DOWNTO 0); -- Set the program counter, so that the addr will go out at s4p2, -- and the new data come in at s1p1 of next cycle pc <= (acc+pc+1); 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'; 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"; 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'; 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_addr <= "ZZZZZZZZ"; p2_ctrl <= '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'; 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'; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -