2014-09-20 20:09:39 +02:00
|
|
|
\def\avr@debug#1{%
|
|
|
|
\typeout{\the\avr@pc: #1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@error#1{%
|
2014-09-27 00:49:58 +02:00
|
|
|
\errmessage{\the\avr@pc: #1}\bye%
|
2014-09-20 20:09:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
% Execution Engine
|
|
|
|
\def\avr@instr@step{%
|
|
|
|
\avr@code@get{\avr@instr@current}%
|
2014-09-27 00:49:58 +02:00
|
|
|
%\avr@reg@get{\csuse{avr@r24}}{\@@A}%
|
|
|
|
%\avr@reg@get{\csuse{avr@r28}}{\@@B}%
|
|
|
|
%\avr@reg@get{\csuse{avr@r29}}{\@@C}%
|
|
|
|
%\avr@debug{{r24=\@@A} {r28=\@@B} {r29=\@@C}}%
|
2014-09-20 20:09:39 +02:00
|
|
|
% Dispatch Instruction by prefix
|
|
|
|
\expandafter\avr@instr@dispatch\avr@instr@current\@nnil%
|
|
|
|
\relax%
|
|
|
|
}
|
|
|
|
|
|
|
|
\newcount\avr@instr@steps
|
|
|
|
\def\avr@instr@stepn#1{%
|
|
|
|
\avr@instr@steps=#1%
|
|
|
|
\def\avr@instr@stepn@helper{
|
|
|
|
\ifnum \avr@instr@steps > 0%
|
|
|
|
\advance \avr@instr@steps by -1\relax%
|
|
|
|
\avr@instr@step%
|
|
|
|
\avr@instr@stepn@helper%
|
|
|
|
\fi%
|
|
|
|
}%
|
|
|
|
\avr@instr@stepn@helper%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@dispatch#1#2#3#4#5#6#7#8#9\@nnil{%
|
|
|
|
\ifcsdef{avr@instr@#1#2#3#4#5#6#7#8#9}{%
|
|
|
|
\csuse{avr@instr@#1#2#3#4#5#6#7#8#9}\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1#2#3#4#5#6#7#8}{%
|
|
|
|
\csuse{avr@instr@#1#2#3#4#5#6#7#8}#9\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1#2#3#4#5#6#7}{%
|
|
|
|
\csuse{avr@instr@#1#2#3#4#5#6#7}#8#9\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1#2#3#4#5#6}{%
|
|
|
|
\csuse{avr@instr@#1#2#3#4#5#6}#7#8#9\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1#2#3#4#5}{%
|
|
|
|
\csuse{avr@instr@#1#2#3#4#5}#6#7#8#9\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1#2#3#4}{%
|
|
|
|
\csuse{avr@instr@#1#2#3#4}#5#6#7#8#9\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1#2#3}{%
|
|
|
|
\csuse{avr@instr@#1#2#3}#4#5#6#7#8#9\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1#2}{%
|
|
|
|
\csuse{avr@instr@#1#2}#3#4#5#6#7#8#9\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1}{%
|
|
|
|
\csuse{avr@instr@#1}#2#3#4#5#6#7#8#9\@nnil%
|
|
|
|
}{% Not found
|
2014-09-28 16:12:53 +02:00
|
|
|
\avr@instr@matchspecial{#1#2#3#4#5#6#7#8#9}%
|
2014-09-20 20:09:39 +02:00
|
|
|
}}}}}}}}}%
|
|
|
|
}
|
|
|
|
|
2014-09-26 16:00:45 +02:00
|
|
|
\def\avr@instr@matchend#1#2#3#4#5#6#7#8#9\@nnil{%
|
|
|
|
\ifcsdef{avr@instr@#1:#2#3#4#5#6#7#8#9}{%
|
|
|
|
\csuse{avr@instr@#1:#2#3#4#5#6#7#8#9}\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1:#3#4#5#6#7#8#9}{%
|
|
|
|
\csuse{avr@instr@#1:#3#4#5#6#7#8#9}#2\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1:#4#5#6#7#8#9}{%
|
|
|
|
\csuse{avr@instr@#1:#4#5#6#7#8#9}#2#3\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1:#5#6#7#8#9}{%
|
|
|
|
\csuse{avr@instr@#1:#5#6#7#8#9}#2#3#4\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1:#6#7#8#9}{%
|
|
|
|
\csuse{avr@instr@#1:#6#7#8#9}#2#3#4#5\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1:#7#8#9}{%
|
|
|
|
\csuse{avr@instr@#1:#7#8#9}#2#3#4#5#6\@nnil%
|
|
|
|
}{\ifcsdef{avr@instr@#1:#9}{%
|
|
|
|
\csuse{avr@instr@#1:#9}#2#3#4#5#6#7#8\@nnil%
|
|
|
|
}{% Not found
|
2014-09-28 16:12:53 +02:00
|
|
|
\avr@instr@matchspecial{#1#2#3#4#5#6#7#8#9}%
|
2014-09-26 16:00:45 +02:00
|
|
|
}}}}}}}%
|
|
|
|
}
|
2014-09-28 16:12:53 +02:00
|
|
|
|
|
|
|
\def\avr@instr@matchspecial#1{%
|
|
|
|
\avr@bin@mask{#1}{1101001000001000}{\@@masked}%
|
|
|
|
\avr@bin@mask{#1}{0010110111110111}{\@@args}%
|
|
|
|
|
|
|
|
\ifcsdef{avr@instr@special@\@@masked}{%
|
|
|
|
\def\@tempa{\csuse{avr@instr@special@\@@masked}}%
|
|
|
|
\expandafter\@tempa\@@args\@nnil%
|
|
|
|
}{%
|
|
|
|
\avr@error{Unkown Instruction: #1}%
|
|
|
|
}%
|
|
|
|
}
|
2014-09-26 16:00:45 +02:00
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% Match also from end for these prefixes
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
\csdef{avr@instr@1001010}{\avr@instr@matchend{1001010}}
|
2014-09-27 00:49:58 +02:00
|
|
|
% POP/PUSH
|
|
|
|
\csdef{avr@instr@1001000}{\avr@instr@matchend{1001000}}
|
|
|
|
\csdef{avr@instr@1001001}{\avr@instr@matchend{1001001}}
|
2014-09-28 16:12:53 +02:00
|
|
|
% LD(XYZ)
|
|
|
|
\csdef{avr@instr@1000000}{\avr@instr@matchend{1000000}}
|
|
|
|
\csdef{avr@instr@1000001}{\avr@instr@matchend{1000001}}
|
2014-09-26 16:00:45 +02:00
|
|
|
|
2014-09-20 20:09:39 +02:00
|
|
|
|
2014-09-20 21:02:32 +02:00
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% Helpers
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2014-09-20 20:09:39 +02:00
|
|
|
|
2014-09-20 21:02:32 +02:00
|
|
|
\def\avr@instr@gen@tworegs#1#2#3#4{%
|
|
|
|
\avr@bin@msb@del{#3}{\avr@ADD@dddd}{\avr@ADD@d}%
|
|
|
|
\avr@bin@msb@del{#4}{\avr@ADD@rrrr}{\avr@ADD@r}%
|
|
|
|
\avr@code@set{#1\avr@ADD@r\avr@ADD@d\avr@ADD@dddd\avr@ADD@rrrr}{#2}%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@gen@regconst#1#2#3#4{%
|
|
|
|
\avr@bin@msb@del{#3}{\avr@LDI@dddd}{\avr@LDI@d}%
|
|
|
|
\avr@bin@nibble@high{#4}{\avr@LDI@H}%
|
|
|
|
\avr@bin@nibble@low{#4}{\avr@LDI@L}%
|
|
|
|
\avr@code@set{#1\avr@LDI@H\avr@LDI@dddd\avr@LDI@L}{#2}%
|
2014-09-20 20:09:39 +02:00
|
|
|
}
|
|
|
|
|
2014-09-28 16:12:53 +02:00
|
|
|
\def\avr@instr@gen@onereg#1#2#3#4{%
|
|
|
|
\avr@code@set{#1#4#2}{#3}%
|
|
|
|
}
|
|
|
|
|
2014-09-20 21:02:32 +02:00
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% Arithmetic instructions
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% ADD -- Add without Carry
|
|
|
|
\def\avr@instr@ADD{\avr@instr@gen@tworegs{000011}}
|
2014-09-26 16:00:45 +02:00
|
|
|
\def\avr@instr@LSL#1#2{\avr@instr@gen@tworegs{000011}{#1}{#2}{#2}}
|
2014-09-20 20:09:39 +02:00
|
|
|
\csdef{avr@instr@000011}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\def\avr@instr@extracarry{0}%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
|
|
|
|
\avr@debug{ADD - \%#2#3#4#5#6 <- #2#3#4#5#6 + \%#1#7}%
|
|
|
|
\avr@debug{ADD - \avr@Rd <- \avr@Rd + \avr@Rr}%
|
|
|
|
\csuse{avr@instr@adder@helper}%
|
|
|
|
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% ADC -- Add with Carry
|
2014-09-20 21:02:32 +02:00
|
|
|
\def\avr@instr@ADC{\avr@instr@gen@tworegs{000111}}
|
2014-09-26 16:00:45 +02:00
|
|
|
\def\avr@instr@ROL#1#2{\avr@instr@ADC{#1}{#2}{#2}}
|
2014-09-20 20:09:39 +02:00
|
|
|
\csdef{avr@instr@000111}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
|
|
|
|
\avr@flag@get C \avr@instr@extracarry%
|
|
|
|
\avr@debug{ADC - \%#2#3#4#5#6 <- #2#3#4#5#6 + \%#1#7}%
|
|
|
|
\avr@debug{ADC - \avr@Rd <- \avr@Rd + \avr@Rr + \avr@instr@extracarry}%
|
|
|
|
\csuse{avr@instr@adder@helper}%
|
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% SUB -- Substract without carry
|
2014-09-20 21:02:32 +02:00
|
|
|
\def\avr@instr@SUB{\avr@instr@gen@tworegs{000110}}
|
2014-09-20 20:09:39 +02:00
|
|
|
\csdef{avr@instr@000110}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
|
|
|
|
\def\avr@instr@extracarry{1}%
|
|
|
|
\avr@debug{SUB - \%#2#3#4#5#6 <- #2#3#4#5#6 + \%#1#7}%
|
|
|
|
\avr@debug{SUB - \avr@Rd <- \avr@Rd - \avr@Rr}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\csuse{avr@instr@subber@helper}%
|
2014-09-20 20:09:39 +02:00
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
% SBC - Substract with Carry
|
2014-09-20 21:02:32 +02:00
|
|
|
\def\avr@instr@SBC{\avr@instr@gen@tworegs{000010}}
|
2014-09-20 20:09:39 +02:00
|
|
|
\csdef{avr@instr@000010}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
|
|
|
|
\avr@flag@get C \@@carry%
|
|
|
|
\xdef \avr@instr@extracarry {\avr@bit@negate \@@carry}%
|
|
|
|
\avr@debug{SBC - \%#2#3#4#5#6 <- #2#3#4#5#6 + \%#1#7}%
|
|
|
|
\avr@debug{SBC - \avr@Rd <- \avr@Rd - \avr@Rr - \@@carry}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\csuse{avr@instr@subber@helper}%
|
2014-09-20 20:09:39 +02:00
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
2014-09-20 21:02:32 +02:00
|
|
|
% SUBI - Substract Immediate
|
|
|
|
\def\avr@instr@SUBI{\avr@instr@gen@regconst{0101}}
|
|
|
|
\csdef{avr@instr@0101}#1#2#3#4#5#6#7#8#9\@nnil{%
|
|
|
|
\avr@reg@get{1#5#6#7#8}{\avr@Rd}%
|
|
|
|
\def\avr@Rr{#1#2#3#4#9}%
|
|
|
|
\def\avr@instr@extracarry{1}%
|
|
|
|
\avr@debug{SUBI - \%#2#3#4#5#6 <- #2#3#4#5#6(=\avr@Rd) - \avr@Rr}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\csuse{avr@instr@subber@helper}%
|
2014-09-20 21:02:32 +02:00
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{1#5#6#7#8}%
|
|
|
|
\avr@pc@inc%
|
2014-09-20 20:09:39 +02:00
|
|
|
}
|
|
|
|
|
2014-09-27 00:49:58 +02:00
|
|
|
% SBCI - Substract Immediate with Carry
|
2014-09-20 21:02:32 +02:00
|
|
|
\def\avr@instr@SBCI{\avr@instr@gen@regconst{0100}}
|
|
|
|
\csdef{avr@instr@0100}#1#2#3#4#5#6#7#8#9\@nnil{%
|
|
|
|
\avr@reg@get{1#5#6#7#8}{\avr@Rd}%
|
|
|
|
\def\avr@Rr{#1#2#3#4#9}%
|
|
|
|
\avr@flag@get C \@@carry%
|
|
|
|
\xdef \avr@instr@extracarry {\avr@bit@negate \@@carry}%
|
|
|
|
\avr@debug{SBCI - \%#2#3#4#5#6 <- #2#3#4#5#6(=\avr@Rd) - \avr@Rr -\@@carry}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\csuse{avr@instr@subber@helper}%
|
2014-09-20 21:02:32 +02:00
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{1#5#6#7#8}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% CP -- Compare without Carry
|
|
|
|
\def\avr@instr@CP{\avr@instr@gen@tworegs{000101}}
|
2014-09-20 20:09:39 +02:00
|
|
|
\csdef{avr@instr@000101}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
|
|
|
|
\def\avr@instr@extracarry{1}%
|
|
|
|
\avr@debug{CP - #2#3#4#5#6(=\avr@Rd) - \%#1#7(=\avr@Rr)}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\csuse{avr@instr@subber@helper}%
|
2014-09-20 20:09:39 +02:00
|
|
|
% Do not set the output register
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% CPC -- Compare with Carry
|
2014-09-20 21:02:32 +02:00
|
|
|
\def\avr@instr@CPC{\avr@instr@gen@tworegs{000001}}
|
2014-09-20 20:09:39 +02:00
|
|
|
\csdef{avr@instr@000001}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
|
|
|
|
\avr@flag@get C \@@carry%
|
|
|
|
\xdef \avr@instr@extracarry {\avr@bit@negate \@@carry}%
|
|
|
|
\avr@debug{CP - #2#3#4#5#6(=\avr@Rd) - \%#1#7(=\avr@Rr)}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\csuse{avr@instr@subber@helper}%
|
2014-09-20 20:09:39 +02:00
|
|
|
% Do not set the output register
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
2014-09-26 16:00:45 +02:00
|
|
|
% CPI - Compare Immediate
|
|
|
|
\def\avr@instr@CPI{\avr@instr@gen@regconst{0011}}
|
|
|
|
\csdef{avr@instr@0011}#1#2#3#4#5#6#7#8#9\@nnil{%
|
|
|
|
\avr@reg@get{1#5#6#7#8}{\avr@Rd}%
|
|
|
|
\def\avr@Rr{#1#2#3#4#9}%
|
|
|
|
\avr@flag@get C \@@carry%
|
2014-09-27 00:49:58 +02:00
|
|
|
\xdef \avr@instr@extracarry{1}%
|
2014-09-26 16:00:45 +02:00
|
|
|
\avr@debug{CPI - \%#2#3#4#5#6 <- #2#3#4#5#6(=\avr@Rd) - \avr@Rr -\@@carry}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\csuse{avr@instr@subber@helper}%
|
2014-09-26 16:00:45 +02:00
|
|
|
% Set the result register
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
2014-09-20 20:09:39 +02:00
|
|
|
\csdef{avr@instr@adder@helper}{%
|
|
|
|
% Convert the Bitstring to Integer values
|
|
|
|
\avr@bin@tocount{\avr@Rd}{\avr@accA}%
|
|
|
|
\avr@bin@tocount{\avr@Rr}{\avr@accB}%
|
|
|
|
\advance \avr@accA by \avr@accB\relax%
|
|
|
|
\advance \avr@accA by \avr@instr@extracarry\relax%
|
|
|
|
\avr@count@modulo@byte{\avr@accA}%
|
|
|
|
\avr@count@tobin@b{\avr@accA}{\avr@Rx}%
|
|
|
|
% Calculate the Flags
|
|
|
|
\let\@@not=\avr@bit@negate%
|
|
|
|
\let\@@and=\avr@bit@and%
|
|
|
|
\let\@@or=\avr@bit@or%
|
|
|
|
%% Carry
|
|
|
|
\avr@bin@msb@get{\avr@Rr}{\@@R}%
|
|
|
|
\avr@bin@msb@get{\avr@Rd}{\@@D}%
|
|
|
|
\avr@bin@msb@get{\avr@Rx}{\@@X}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\avr@debug{{Rr7:\@@R} {Rd7:\@@D} {R7:\@@X}}%
|
2014-09-20 20:09:39 +02:00
|
|
|
% \avr@debug{R: \@@R D: \@@D X:\@@X}%
|
|
|
|
\def\avr@ADD@carry{%
|
2014-09-27 00:49:58 +02:00
|
|
|
\@@or {\@@and \@@R \@@D}%
|
2014-09-20 20:09:39 +02:00
|
|
|
{%
|
2014-09-27 00:49:58 +02:00
|
|
|
\@@or{\@@and \@@R {\@@not \@@X}}%
|
|
|
|
{\@@and \@@X {\@@not \@@D}}}}%
|
|
|
|
\avr@flag@set C {\avr@ADD@carry}%
|
2014-09-20 20:09:39 +02:00
|
|
|
% Two's Complement Overflow
|
|
|
|
\def\@@tmp{\@@or%
|
|
|
|
{\@@and \@@D {\@@and \@@R {\@@not \@@X}}}%
|
|
|
|
{\@@and {\@@not \@@D} {\@@and {\@@not \@@R} \@@X}}}%
|
|
|
|
\avr@flag@set V \@@tmp%
|
|
|
|
% Half Carry
|
|
|
|
\avr@bin@getbit{\avr@Rr}{3}{\@@R}%
|
|
|
|
\avr@bin@getbit{\avr@Rd}{3}{\@@D}%
|
|
|
|
\avr@bin@getbit{\avr@Rx}{3}{\@@X}%
|
|
|
|
\def\avr@ADD@carry{%
|
|
|
|
\@@or {\@@and \@@D {\@@not \@@X}}%
|
|
|
|
{%
|
|
|
|
\@@or{\@@and \@@R \@@D}%
|
|
|
|
{\@@and \@@R {\@@not \@@X}}}}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\avr@flag@set H {\avr@ADD@carry}%
|
|
|
|
%% Update Dependend Flags (N, Z, S)
|
|
|
|
\avr@flags@update \avr@Rx%
|
|
|
|
}
|
|
|
|
|
|
|
|
\csdef{avr@instr@subber@helper}{%
|
|
|
|
% Convert the Bitstring to Integer values
|
|
|
|
\avr@bin@tocount{\avr@Rd}{\avr@accA}%
|
|
|
|
\avr@bin@negate{\avr@Rr}{\@@Rr}%
|
|
|
|
\avr@bin@tocount{\@@Rr}{\avr@accB}%
|
|
|
|
\advance \avr@accA by \avr@accB\relax%
|
|
|
|
\advance \avr@accA by \avr@instr@extracarry\relax%
|
|
|
|
\avr@count@modulo@byte{\avr@accA}%
|
|
|
|
\avr@count@tobin@b{\avr@accA}{\avr@Rx}%
|
|
|
|
% Calculate the Flags
|
|
|
|
\let\@@not=\avr@bit@negate%
|
|
|
|
\let\@@and=\avr@bit@and%
|
|
|
|
\let\@@or=\avr@bit@or%
|
|
|
|
%% Carry
|
|
|
|
\avr@bin@msb@get{\avr@Rr}{\@@R}%
|
|
|
|
\avr@bin@msb@get{\avr@Rd}{\@@D}%
|
|
|
|
\avr@bin@msb@get{\avr@Rx}{\@@X}%
|
|
|
|
\avr@debug{{Rr7:\@@R} {Rd7:\@@D} {R7:\@@X}}%
|
|
|
|
\def\avr@ADD@carry{%
|
|
|
|
\@@or {\@@and {\@@not \@@D} \@@R}%
|
|
|
|
{%
|
|
|
|
\@@or{\@@and \@@R \@@X}%
|
|
|
|
{\@@and \@@X {\@@not \@@D}}}}%
|
|
|
|
\avr@flag@set C {\avr@ADD@carry}%
|
|
|
|
% Two's Complement Overflow
|
|
|
|
\def\@@tmp{\@@or%
|
|
|
|
{\@@and \@@D {\@@and {\@@not \@@R} {\@@not \@@X}}}%
|
|
|
|
{\@@and {\@@not \@@D} {\@@and \@@R \@@X}}}%
|
|
|
|
\avr@flag@set V \@@tmp%
|
|
|
|
% Half Carry
|
|
|
|
\avr@bin@getbit{\avr@Rr}{3}{\@@R}%
|
|
|
|
\avr@bin@getbit{\avr@Rd}{3}{\@@D}%
|
|
|
|
\avr@bin@getbit{\avr@Rx}{3}{\@@X}%
|
|
|
|
\def\avr@ADD@carry{%
|
|
|
|
\@@or {\@@and {\@@not \@@D} \@@R}%
|
|
|
|
{%
|
|
|
|
\@@or{\@@and \@@R \@@X}%
|
|
|
|
{\@@and \@@X {\@@not \@@D}}}}%
|
|
|
|
\avr@flag@set H {\avr@ADD@carry}%
|
2014-09-20 20:09:39 +02:00
|
|
|
%% Update Dependend Flags (N, Z, S)
|
|
|
|
\avr@flags@update \avr@Rx%
|
|
|
|
}
|
|
|
|
|
2014-09-27 00:49:58 +02:00
|
|
|
|
2014-09-20 20:09:39 +02:00
|
|
|
% LDI -- Load Immediate Value
|
2014-09-20 21:02:32 +02:00
|
|
|
\def\avr@instr@LDI{\avr@instr@gen@regconst{1110}}
|
|
|
|
\def\avr@instr@SER#1#2{\avr@instr@gen@regconst{1110}{#1}{#2}{11111111}}
|
2014-09-20 20:09:39 +02:00
|
|
|
\csdef{avr@instr@1110}#1#2#3#4#5#6#7#8#9\@nnil{%
|
|
|
|
\avr@debug{LDI - \%1#5#6#7#8 <- #1#2#3#4#9}%
|
|
|
|
\avr@reg@set{#1#2#3#4#9}{1#5#6#7#8}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% Branch Instructions
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% Encode 6 Bit Value to PC Offset
|
|
|
|
\def\avr@instr@jump@enc#1#2{%
|
|
|
|
\avr@count@tmpa=#1%
|
|
|
|
\ifnum #1 < 0%
|
|
|
|
\avr@count@tmpb=\avr@count@tmpa%
|
|
|
|
\avr@count@tmpa=255%
|
|
|
|
\advance \avr@count@tmpa by \avr@count@tmpb\relax%
|
|
|
|
\advance \avr@count@tmpa by 1\relax%
|
|
|
|
\fi%
|
|
|
|
\avr@count@tobin@b{\avr@count@tmpa}{\@@res}%
|
|
|
|
\avr@bin@msb@del{\@@res}{#2}{\@tempa}
|
|
|
|
}
|
|
|
|
\def\avr@instr@jump@dec#1#2{%
|
|
|
|
\avr@bin@tocount{0#1}{\avr@count@tmpa}%
|
|
|
|
\ifnum \avr@count@tmpa > 63%
|
|
|
|
\avr@count@tmpb=\avr@count@tmpa%
|
|
|
|
\avr@count@tmpa=-128%
|
|
|
|
\advance \avr@count@tmpa by \avr@count@tmpb\relax%
|
|
|
|
\fi%
|
|
|
|
#2=\avr@count@tmpa\relax%
|
|
|
|
}
|
|
|
|
|
2014-09-27 00:49:58 +02:00
|
|
|
\def\avr@instr@rjump@dec#1#2{%
|
|
|
|
\avr@bin@tocount{0000#1}{\avr@count@tmpa}%
|
|
|
|
\ifnum \avr@count@tmpa > 2047%
|
|
|
|
\avr@count@tmpb=\avr@count@tmpa%
|
|
|
|
\avr@count@tmpa=-4096%
|
|
|
|
\advance \avr@count@tmpa by \avr@count@tmpb\relax%
|
|
|
|
\fi%
|
|
|
|
#2=\avr@count@tmpa\relax%
|
|
|
|
}
|
|
|
|
|
2014-09-20 20:09:39 +02:00
|
|
|
% BRBC -- Branch if Bit in SREG is cleared
|
|
|
|
\def\avr@instr@BRBC#1#2#3{% ADD PC, Bit, Offset
|
|
|
|
\avr@instr@jump@enc{#3}{\@@offset}%
|
|
|
|
\avr@code@set{111101\@@offset#2}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% BRBS -- Branch if Bit in SREG is set
|
|
|
|
\def\avr@instr@BRBS#1#2#3{% ADD PC, Bit, Offset
|
|
|
|
\avr@instr@jump@enc{#3}{\@@offset}%
|
|
|
|
\avr@code@set{111100\@@offset#2}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% BRCC - Branch if Carry Cleared
|
|
|
|
\def\avr@instr@BRCC#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBC{#1}{000}{#2}%
|
|
|
|
}
|
|
|
|
% BRSH - Branch if Same or Higher
|
|
|
|
\def\avr@instr@BRSH{\avr@instr@BRCC}
|
|
|
|
|
|
|
|
% BRCS - Branch if Carry Set
|
|
|
|
\def\avr@instr@BRCS#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBS{#1}{000}{#2}%
|
|
|
|
}
|
|
|
|
% BRSH - Branch if Lower
|
|
|
|
\def\avr@instr@BRLO{\avr@instr@BRCS}
|
|
|
|
|
|
|
|
|
|
|
|
% BRHC - Branch if Half Carry Cleared
|
|
|
|
\def\avr@instr@BRHC#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBC{#1}{101}{#2}%
|
|
|
|
}
|
|
|
|
% BRHS - Branch if Half Carry Set
|
|
|
|
\def\avr@instr@BRHS#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBS{#1}{101}{#2}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% BRID - Branch if Global Interrupt Disabled
|
|
|
|
\def\avr@instr@BRID#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBC{#1}{111}{#2}%
|
|
|
|
}
|
|
|
|
% BRIE - Branch if Global Interrupt Enabled
|
|
|
|
\def\avr@instr@BRIE#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBS{#1}{111}{#2}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% BRMI - Branch if Minus
|
|
|
|
\def\avr@instr@BRMI#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBS{#1}{010}{#2}%
|
|
|
|
}
|
|
|
|
% BRPL - Branch if Plus
|
|
|
|
\def\avr@instr@BRPL#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBC{#1}{010}{#2}%
|
|
|
|
}
|
|
|
|
% BRNE - Branch if Not Equal
|
|
|
|
\def\avr@instr@BRNE#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBC{#1}{001}{#2}%
|
|
|
|
}
|
|
|
|
% BREQ - Branch if Equal
|
|
|
|
\def\avr@instr@BREQ#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBS{#1}{001}{#2}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% BRTC - Branch if T flag cleared
|
|
|
|
\def\avr@instr@BRTC#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRTC{#1}{110}{#2}%
|
|
|
|
}
|
|
|
|
% BRTS - Branch if T flag set
|
|
|
|
\def\avr@instr@BRTS#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRTS{#1}{110}{#2}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% BRVC - Branch if Overflow flag cleared
|
|
|
|
\def\avr@instr@BRVC#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBC{#1}{011}{#2}%
|
|
|
|
}
|
|
|
|
% BRVS - Branch if Overflow flag set
|
|
|
|
\def\avr@instr@BRVS#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBS{#1}{011}{#2}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% BRGE - Branch if greater Equal (signed)
|
|
|
|
\def\avr@instr@BRGE#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBC{#1}{100}{#2}%
|
|
|
|
}
|
|
|
|
% BRLT - Branch if less than (signed)
|
|
|
|
\def\avr@instr@BRLT#1#2{% PC, Offset
|
|
|
|
\avr@instr@BRBS{#1}{100}{#2}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% #1 = Value to be reached
|
|
|
|
\csdef{avr@instr@11110}#1#2#3#4#5#6#7#8#9\@nnil{
|
|
|
|
\edef\@@required{\avr@bit@negate #1}%
|
|
|
|
\def\@@offset{#2#3#4#5#6#7#8}%
|
|
|
|
\def\@@bit{00000#9}%
|
|
|
|
\avr@sreg@get{\@@sreg}%
|
|
|
|
\avr@bin@tocount{\@@bit}{\avr@count@tmpa}%
|
|
|
|
\edef\@@bit{\the\avr@count@tmpa}%
|
|
|
|
\avr@bin@getbit{\@@sreg}{\@@bit}{\@@found}%
|
|
|
|
\avr@count@tmpa=\@@required%
|
|
|
|
\avr@count@tmpb=\@@found\relax%
|
|
|
|
\avr@debug{BRB{CS} - (\@@sreg[\@@bit] == \@@required) ? +\@@offset : +0}
|
|
|
|
\ifnum \avr@count@tmpa = \avr@count@tmpb%
|
|
|
|
\avr@instr@jump@dec{\@@offset}{\avr@count@tmpa}%
|
|
|
|
\avr@debug{BRB -- JUMP \the\avr@count@tmpa}%
|
|
|
|
\avr@pc@add{\avr@count@tmpa}%
|
|
|
|
\fi%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
2014-09-27 00:49:58 +02:00
|
|
|
% RJMP
|
|
|
|
% #1 = Offset
|
|
|
|
% FIXME latex assembler
|
|
|
|
\csdef{avr@instr@1100}#1\@nnil{
|
|
|
|
\avr@instr@rjump@dec{#1}{\avr@count@tmpa}%
|
|
|
|
\avr@debug{RJMP \the\avr@count@tmpa}%
|
|
|
|
\avr@pc@add{\avr@count@tmpa}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% RCALL
|
|
|
|
\csdef{avr@instr@1101}#1\@nnil{
|
|
|
|
\avr@count@tobin@w{\the\avr@pc}{\@@pc}%
|
|
|
|
\avr@instr@rjump@dec{#1}{\avr@count@tmpa}%
|
|
|
|
\avr@reg@get{\csuse{avr@r24}}{\@@A}%
|
|
|
|
\avr@reg@get{\csuse{avr@r25}}{\@@B}%
|
|
|
|
\avr@reg@get{\csuse{avr@r26}}{\@@C}%
|
|
|
|
\avr@debug{RCALL \the\avr@count@tmpa {r24:\@@A} {r25:\@@B} {r26:\@@C}}%
|
|
|
|
\avr@pc@add{\avr@count@tmpa}%
|
|
|
|
\avr@bin@word@low{\@@pc}{\@@low}%
|
|
|
|
\avr@bin@word@high{\@@pc}{\@@high}%
|
|
|
|
\avr@mem@set{\@@low}{\the\avr@stackptr}%
|
|
|
|
\advance\avr@stackptr by -1\relax%
|
|
|
|
\avr@mem@set{\@@high}{\the\avr@stackptr}%
|
|
|
|
\advance\avr@stackptr by -1\relax%
|
|
|
|
\avr@pc@inc%
|
|
|
|
\avr@debug{ done}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% RET
|
|
|
|
\def\avr@instr@RET#1{%
|
|
|
|
\avr@code@set{1001010100001000}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001010100001000}\@nnil{%
|
|
|
|
\avr@reg@get{\csuse{avr@r24}}{\@@X}%
|
|
|
|
\avr@debug{RET (r24=\@@X)}%
|
|
|
|
\advance\avr@stackptr by 1\relax
|
|
|
|
\avr@mem@get{\the\avr@stackptr}{\@@high}%
|
|
|
|
\advance\avr@stackptr by 1\relax
|
|
|
|
\avr@mem@get{\the\avr@stackptr}{\@@low}%
|
|
|
|
\avr@bin@tocount{\@@high \@@low}{\avr@pc}%
|
|
|
|
\avr@pc@inc\relax%
|
|
|
|
\avr@debug{ done }%
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-09-20 20:09:39 +02:00
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% Data transfert instructions
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% MOV
|
2014-09-20 21:02:32 +02:00
|
|
|
\def\avr@instr@MOV{\avr@instr@gen@tworegs{001011}}
|
2014-09-20 20:09:39 +02:00
|
|
|
\csdef{avr@instr@001011}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@set{\avr@Rr}{#2#3#4#5#6}%
|
|
|
|
\avr@debug{MOV - #2#3#4#5#6 <- #1#7(=\avr@Rr)}
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
2014-09-26 16:00:45 +02:00
|
|
|
% MOVW
|
|
|
|
\def\avr@instr@MOVW#1#2#3{%
|
|
|
|
\avr@bin@lsb@del{#2}{\avr@LDI@dddd}{\avr@LDI@d}%
|
|
|
|
\avr@bin@lsb@del{#3}{\avr@LDI@rrrr}{\avr@LDI@r}%
|
|
|
|
\avr@code@set{00000001\avr@LDI@dddd\avr@LDI@rrrr}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@00000001}#1#2#3#4#5\@nnil{%
|
|
|
|
\avr@reg@get{#50}{\avr@Rr}%
|
|
|
|
\avr@reg@set{\avr@Rr}{#1#2#3#40}%
|
|
|
|
\avr@reg@get{#51}{\avr@Rd}%
|
|
|
|
\avr@reg@set{\avr@Rd}{#1#2#3#41}%
|
|
|
|
\avr@debug{MOV - #1#2#3#4[01] <- #5[01](=\avr@Rr:\avr@Rd)}
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
2014-09-27 00:49:58 +02:00
|
|
|
% PUSH
|
|
|
|
\def\avr@instr@PUSH#1#2{% PC, Reg
|
|
|
|
\avr@code@set{1001001#21111}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
\csdef{avr@instr@1001001:1111}#1\@nnil{%
|
|
|
|
\avr@reg@get{#1}{\avr@Rr}%
|
|
|
|
\avr@debug{PUSH #1(=\avr@Rr)}%
|
|
|
|
\avr@mem@set{\avr@Rr}{\the\avr@stackptr}%
|
|
|
|
\advance\avr@stackptr by -1\relax%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% POP
|
|
|
|
\def\avr@instr@POP#1#2{% PC, Reg
|
|
|
|
\avr@code@set{1001000#21111}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001000:1111}#1\@nnil{%
|
|
|
|
\advance\avr@stackptr by 1\relax%
|
|
|
|
\avr@debug{POP #1}%
|
|
|
|
\avr@mem@get{\the\avr@stackptr}{\avr@Rr}%
|
|
|
|
\avr@reg@set{\avr@Rr}{#1}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
2014-09-26 16:00:45 +02:00
|
|
|
|
2014-09-28 16:12:53 +02:00
|
|
|
\newcount\avr@addr
|
|
|
|
\def\avr@instr@LDD@helper#1#2#3#4{%
|
|
|
|
% PreIncrement, RegisterW, PostIncrement, Target
|
|
|
|
\avr@regw@get{\csuse{avr@#2}}{\@@addr}%
|
|
|
|
\avr@debug{LD *(#1:#2:#3,#2=\@@addr)}%
|
|
|
|
\avr@bin@tocount{\@@addr}{\avr@addr}%
|
|
|
|
\advance \avr@addr by #1\relax%
|
|
|
|
\avr@count@overflow{\avr@addr}\relax%
|
|
|
|
\avr@mem@get{\the\avr@addr}{\avr@Rx}%
|
|
|
|
\advance \avr@addr by #3\relax%
|
|
|
|
\avr@count@overflow{\avr@addr}\relax%
|
|
|
|
\avr@count@tobin@w{\avr@addr}{\@@addr}%
|
|
|
|
\avr@regw@set{\@@addr}{\csuse{avr@#2}}%
|
|
|
|
\avr@reg@set{\avr@Rx}{#4}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@STS@helper#1#2#3#4{%
|
|
|
|
% PreIncrement, RegisterW, PostIncrement, SourceReg
|
|
|
|
\avr@regw@get{\csuse{avr@#2}}{\@@addr}%
|
|
|
|
\avr@reg@get{#4}{\avr@Rd}%
|
|
|
|
\avr@debug{ST *(#1:#2:#3,#2=\@@addr)}%
|
|
|
|
\avr@bin@tocount{\@@addr}{\avr@addr}%
|
|
|
|
\advance \avr@addr by #1\relax%
|
|
|
|
\avr@count@overflow{\avr@addr}\relax%
|
|
|
|
\avr@mem@set{\avr@Rd}{\the\avr@addr}%
|
|
|
|
\advance \avr@addr by #3\relax%
|
|
|
|
\avr@count@overflow{\avr@addr}\relax%
|
|
|
|
\avr@count@tobin@w{\avr@addr}{\@@addr}%
|
|
|
|
\avr@regw@set{\@@addr}{\csuse{avr@#2}}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% LD(X)
|
|
|
|
\def\avr@instr@LDX{\avr@instr@gen@onereg{1001000}{1100}}
|
|
|
|
\def\avr@instr@LDXp{\avr@instr@gen@onereg{1001000}{1101}}
|
|
|
|
\def\avr@instr@LDmX{\avr@instr@gen@onereg{1001000}{1110}}
|
|
|
|
|
|
|
|
\csdef{avr@instr@1001000:1100}#1\@nnil{%
|
|
|
|
\avr@instr@LDD@helper{0}{X}{0}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001000:1101}#1\@nnil{%
|
|
|
|
\avr@instr@LDD@helper{0}{X}{1}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001000:1110}#1\@nnil{%
|
|
|
|
\avr@instr@LDD@helper{-1}{X}{0}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% LD(Y)
|
|
|
|
\def\avr@instr@LDY{\avr@instr@gen@onereg{1000000}{1000}}
|
|
|
|
\def\avr@instr@LDYp{\avr@instr@gen@onereg{1001000}{1001}}
|
|
|
|
\def\avr@instr@LDmY{\avr@instr@gen@onereg{1001000}{1010}}
|
|
|
|
|
|
|
|
\csdef{avr@instr@1000000:1000}#1\@nnil{%
|
|
|
|
\avr@instr@LDD@helper{0}{Y}{0}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001000:1001}#1\@nnil{%
|
|
|
|
\avr@instr@LDD@helper{0}{Y}{1}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001000:1010}#1\@nnil{%
|
|
|
|
\avr@instr@LDD@helper{-1}{Y}{0}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% LD(Z)
|
|
|
|
\def\avr@instr@LDZ{\avr@instr@gen@onereg{1000000}{0000}}
|
|
|
|
\def\avr@instr@LDZp{\avr@instr@gen@onereg{1001000}{0001}}
|
|
|
|
\def\avr@instr@LDmZ{\avr@instr@gen@onereg{1001000}{0010}}
|
|
|
|
|
|
|
|
\csdef{avr@instr@1000000:0000}#1\@nnil{%
|
|
|
|
\avr@instr@LDD@helper{0}{Z}{0}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001000:0001}#1\@nnil{%
|
|
|
|
\avr@instr@LDD@helper{0}{Z}{1}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001000:0010}#1\@nnil{%
|
|
|
|
\avr@instr@LDD@helper{-1}{Z}{0}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% ST(X,Y,Z)
|
|
|
|
\def\avr@instr@STX{\avr@instr@gen@onereg{1001001}{1100}}
|
|
|
|
\def\avr@instr@STXp{\avr@instr@gen@onereg{1001001}{1101}}
|
|
|
|
\def\avr@instr@STmX{\avr@instr@gen@onereg{1001001}{1110}}
|
|
|
|
|
|
|
|
\csdef{avr@instr@1001001:1100}#1\@nnil{%
|
|
|
|
\avr@instr@STS@helper{0}{X}{0}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001001:1101}#1\@nnil{%
|
|
|
|
\avr@instr@STS@helper{0}{X}{1}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001001:1110}#1\@nnil{%
|
|
|
|
\avr@instr@STS@helper{-1}{X}{0}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@STY{\avr@instr@gen@onereg{1000001}{1000}}
|
|
|
|
\def\avr@instr@STYp{\avr@instr@gen@onereg{1001001}{1001}}
|
|
|
|
\def\avr@instr@STmY{\avr@instr@gen@onereg{1001001}{1010}}
|
|
|
|
|
|
|
|
\csdef{avr@instr@1000001:1000}#1\@nnil{%
|
|
|
|
\avr@instr@STS@helper{0}{Y}{0}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001001:1001}#1\@nnil{%
|
|
|
|
\avr@instr@STS@helper{0}{Y}{1}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001001:1010}#1\@nnil{%
|
|
|
|
\avr@instr@STS@helper{-1}{Y}{0}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@STZ{\avr@instr@gen@onereg{1000001}{0000}}
|
|
|
|
\def\avr@instr@STZp{\avr@instr@gen@onereg{1001001}{0001}}
|
|
|
|
\def\avr@instr@STmZ{\avr@instr@gen@onereg{1001001}{0010}}
|
|
|
|
|
|
|
|
\csdef{avr@instr@1000001:0000}#1\@nnil{%
|
|
|
|
\avr@instr@STS@helper{0}{Z}{0}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001001:0001}#1\@nnil{%
|
|
|
|
\avr@instr@STS@helper{0}{Z}{1}{#1}%
|
|
|
|
}
|
|
|
|
\csdef{avr@instr@1001001:0010}#1\@nnil{%
|
|
|
|
\avr@instr@STS@helper{-1}{Z}{0}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
% Special Stores & Loads
|
|
|
|
|
|
|
|
% LD R <- Y+q
|
|
|
|
\csdef{avr@instr@special@10.0..0.....1...}..#1.#2.#3.#4\@nnil{%
|
|
|
|
\avr@debug{LD reg(#3) <- Y+#1#2#4}%
|
|
|
|
\avr@regw@get{\csuse{avr@Y}}{\@@addr}%
|
|
|
|
\avr@bin@tocount{\@@addr}{\avr@addr}%
|
|
|
|
\avr@bin@tocount{00#1#2#4}{\avr@count@tmpa}%
|
|
|
|
\advance \avr@addr by \avr@count@tmpa\relax%
|
|
|
|
\avr@count@overflow{\avr@addr}\relax%
|
|
|
|
\avr@mem@get{\the\avr@addr}{\avr@Rd}%
|
|
|
|
\avr@reg@set{\avr@Rd}{#3}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% LD R <- Z+q
|
|
|
|
\csdef{avr@instr@special@10.0..0.....0...}..#1.#2.#3.#4\@nnil{%
|
|
|
|
\avr@debug{LD reg(#3) <- Z+#1#2#4}%
|
|
|
|
\avr@regw@get{\csuse{avr@Z}}{\@@addr}%
|
|
|
|
\avr@bin@tocount{\@@addr}{\avr@addr}%
|
|
|
|
\avr@bin@tocount{00#1#2#4}{\avr@count@tmpa}%
|
|
|
|
\advance \avr@addr by \avr@count@tmpa\relax%
|
|
|
|
\avr@count@overflow{\avr@addr}\relax%
|
|
|
|
\avr@mem@get{\the\avr@addr}{\avr@Rd}%
|
|
|
|
\avr@reg@set{\avr@Rd}{#3}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% ST Y+q <- R
|
|
|
|
\csdef{avr@instr@special@10.0..1.....1...}..#1.#2.#3.#4\@nnil{%
|
|
|
|
\avr@debug{ST Y+#1#2#4 <- reg(#3)}%
|
|
|
|
\avr@regw@get{\csuse{avr@Y}}{\@@addr}%
|
|
|
|
\avr@reg@get{#3}{\avr@Rd}%
|
|
|
|
\avr@bin@tocount{\@@addr}{\avr@addr}%
|
|
|
|
\avr@bin@tocount{00#1#2#4}{\avr@count@tmpa}%
|
|
|
|
\advance \avr@addr by \avr@count@tmpa\relax%
|
|
|
|
\avr@count@overflow{\avr@addr}\relax%
|
|
|
|
\avr@mem@set{\avr@Rd}{\the\avr@addr}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% ST Z+q <- R
|
|
|
|
\csdef{avr@instr@special@10.0..1.....0...}..#1.#2.#3.#4\@nnil{%
|
|
|
|
\avr@debug{ST Z+#1#2#4 <- reg(#3)}%
|
|
|
|
\avr@regw@get{\csuse{avr@Z}}{\@@addr}%
|
|
|
|
\avr@reg@get{#3}{\avr@Rd}%
|
|
|
|
\avr@bin@tocount{\@@addr}{\avr@addr}%
|
|
|
|
\avr@bin@tocount{00#1#2#4}{\avr@count@tmpa}%
|
|
|
|
\advance \avr@addr by \avr@count@tmpa\relax%
|
|
|
|
\avr@count@overflow{\avr@addr}\relax%
|
|
|
|
\avr@mem@set{\avr@Rd}{\the\avr@addr}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
2014-09-26 16:00:45 +02:00
|
|
|
|
2014-09-20 20:09:39 +02:00
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% Misc
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
\def\avr@instr@BREAK#1{% BREAK PC
|
|
|
|
\avr@code@set{1001010110011000}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
\csdef{avr@instr@1001010110011000}\@nnil{%
|
|
|
|
\avr@debug{BREAK}%
|
|
|
|
\avr@instr@steps=0\relax%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
2014-09-26 16:00:45 +02:00
|
|
|
\def\avr@instr@NOP#1{%
|
2014-09-20 21:02:32 +02:00
|
|
|
\avr@code@set{0000000000000000}{#1}%
|
|
|
|
}
|
|
|
|
|
|
|
|
\csdef{avr@instr@0000000000000000}\@nnil{%
|
|
|
|
\avr@debug{NOP}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
% Logical Instructions
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
\def\avr@instr@bitop@helper{%
|
|
|
|
\avr@debug{\avr@instr@bitop - {\avr@Rd} AND {\avr@Rr}}%
|
|
|
|
\csuse{avr@bin@\avr@instr@bitop}{\avr@Rr}{\avr@Rd}{\avr@Rx}%
|
|
|
|
\avr@flag@set V 0%
|
|
|
|
\avr@flags@update \avr@Rx%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@AND{\avr@instr@gen@tworegs{001000}}
|
|
|
|
\def\avr@instr@TST#1#2{\avr@instr@gen@tworegs{001000}{#1}{#2}{#2}}
|
|
|
|
\csdef{avr@instr@001000}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
|
|
|
|
\def\avr@instr@bitop{and}%
|
|
|
|
\avr@instr@bitop@helper%
|
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@ANDI{\avr@instr@gen@regconst{0111}}
|
|
|
|
\csdef{avr@instr@0111}#1#2#3#4#5#6#7#8#9\@nnil{%
|
|
|
|
\avr@reg@get{1#5#6#7#8}{\avr@Rd}%
|
|
|
|
\def\avr@Rr{#1#2#3#4#9}%
|
|
|
|
\def\avr@instr@bitop{and}%
|
|
|
|
\avr@instr@bitop@helper%
|
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{1#5#6#7#8}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
\def\avr@instr@OR{\avr@instr@gen@tworegs{001010}}
|
|
|
|
\csdef{avr@instr@001010}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
|
|
|
|
\def\avr@instr@bitop{or}%
|
|
|
|
\avr@instr@bitop@helper%
|
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@ORI{\avr@instr@gen@regconst{0110}}
|
2014-09-26 16:00:45 +02:00
|
|
|
\def\avr@instr@SBR{\avr@instr@ORI}
|
2014-09-20 21:02:32 +02:00
|
|
|
\csdef{avr@instr@0110}#1#2#3#4#5#6#7#8#9\@nnil{%
|
|
|
|
\avr@reg@get{1#5#6#7#8}{\avr@Rd}%
|
|
|
|
\def\avr@Rr{#1#2#3#4#9}%
|
|
|
|
\def\avr@instr@bitop{or}%
|
|
|
|
\avr@instr@bitop@helper%
|
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{1#5#6#7#8}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@EOR{\avr@instr@gen@tworegs{001001}}
|
|
|
|
\def\avr@instr@CLR#1#2{\avr@instr@EOR{#1}{#2}{#2}}
|
|
|
|
\csdef{avr@instr@001001}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\avr@reg@get{#1#7}{\avr@Rr}%
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
|
|
|
|
\def\avr@instr@bitop{xor}%
|
|
|
|
\avr@instr@bitop@helper%
|
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
2014-09-26 16:00:45 +02:00
|
|
|
\def\avr@instr@BSET#1#2{%
|
|
|
|
\avr@code@set{100101000#21000}{#1}%
|
|
|
|
}
|
|
|
|
\def\avr@instr@SEC#1{\avr@instr@BSET{#1}{000}}
|
|
|
|
\def\avr@instr@SEZ#1{\avr@instr@BSET{#1}{001}}
|
|
|
|
\def\avr@instr@SEN#1{\avr@instr@BSET{#1}{010}}
|
|
|
|
\def\avr@instr@SEV#1{\avr@instr@BSET{#1}{011}}
|
|
|
|
\def\avr@instr@SES#1{\avr@instr@BSET{#1}{100}}
|
|
|
|
\def\avr@instr@SEH#1{\avr@instr@BSET{#1}{101}}
|
|
|
|
\def\avr@instr@SET#1{\avr@instr@BSET{#1}{110}}
|
|
|
|
\def\avr@instr@SEI#1{\avr@instr@BSET{#1}{111}}
|
|
|
|
|
|
|
|
|
|
|
|
\def\avr@instr@BCLR#1#2{%
|
|
|
|
\avr@code@set{100101001#21000}{#1}%
|
|
|
|
}
|
|
|
|
\def\avr@instr@CLC#1{\avr@instr@BCLR{#1}{000}}
|
|
|
|
\def\avr@instr@CLZ#1{\avr@instr@BCLR{#1}{001}}
|
|
|
|
\def\avr@instr@CLN#1{\avr@instr@BCLR{#1}{010}}
|
|
|
|
\def\avr@instr@CLV#1{\avr@instr@BCLR{#1}{011}}
|
|
|
|
\def\avr@instr@CLS#1{\avr@instr@BCLR{#1}{100}}
|
|
|
|
\def\avr@instr@CLH#1{\avr@instr@BCLR{#1}{101}}
|
|
|
|
\def\avr@instr@CLT#1{\avr@instr@BCLR{#1}{110}}
|
|
|
|
\def\avr@instr@CLI#1{\avr@instr@BCLR{#1}{111}}
|
|
|
|
|
2014-09-20 20:09:39 +02:00
|
|
|
|
|
|
|
|
2014-09-26 16:00:45 +02:00
|
|
|
\def\avr@instr@BSET@helper#1#2{%
|
|
|
|
% BSET
|
|
|
|
\csdef{avr@instr@100101000#11000}\@nnil{%
|
|
|
|
\avr@debug{BSET #1 #2}%
|
|
|
|
\avr@flag@set #2 1%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}%
|
|
|
|
\csdef{avr@instr@100101001#11000}\@nnil{%
|
|
|
|
\avr@debug{BCLR #2}%
|
|
|
|
\avr@flag@set #2 0%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}\relax%
|
|
|
|
}
|
|
|
|
\avr@instr@BSET@helper{000}{C}
|
|
|
|
\avr@instr@BSET@helper{001}{Z}
|
|
|
|
\avr@instr@BSET@helper{010}{N}
|
|
|
|
\avr@instr@BSET@helper{011}{V}
|
|
|
|
\avr@instr@BSET@helper{100}{S}
|
|
|
|
\avr@instr@BSET@helper{101}{H}
|
|
|
|
\avr@instr@BSET@helper{110}{T}
|
|
|
|
\avr@instr@BSET@helper{111}{I}
|
|
|
|
|
|
|
|
\def\avr@instr@BST#1#2#3{\avr@code@set{1111101#20#3}{#1}}
|
|
|
|
\csdef{avr@instr@1111101}#1#2#3#4#5#6\@nnil{%
|
|
|
|
\avr@reg@get{#1#2#3#4#5}{\avr@Rd}%
|
|
|
|
\avr@bin@tocount{0000#6}{\avr@count@tmpa}%
|
|
|
|
\edef\@@X{\the\avr@count@tmpa}%
|
|
|
|
\avr@debug{BST T <- #1#2#3#4#5(=\avr@Rd):\@@X}%
|
|
|
|
\avr@bin@getbit{\avr@Rd}{\@@X}{\@@T}%
|
|
|
|
\avr@flag@set T \@@T%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@BLD#1#2#3{\avr@code@set{1111100#20#3}{#1}}
|
|
|
|
\csdef{avr@instr@1111100}#1#2#3#4#5#6\@nnil{%
|
|
|
|
\avr@bin@tocount{0000#6}{\avr@count@tmpa}%
|
|
|
|
\avr@reg@get{#1#2#3#4#5}{\avr@Rd}%
|
|
|
|
\edef\@@X{\the\avr@count@tmpa}%
|
|
|
|
\avr@flag@get T \@@T%
|
|
|
|
\avr@debug{BLD #1#2#3#4#5(=\avr@Rd) |= \@@T<<\@@X}%
|
|
|
|
\avr@bin@setbit{\avr@Rd}{\@@X}{\@@T}{\avr@Rd}%
|
|
|
|
\avr@reg@set{\avr@Rd}{#1#2#3#4#5}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@NEG#1#2{\avr@code@set{1001010#20001}{#1}}
|
|
|
|
\csdef{avr@instr@1001010:0001}#1\@nnil{%
|
|
|
|
\avr@reg@get{#1}{\avr@Rr}%
|
|
|
|
\avr@debug{NEG: #1(=\avr@Rr)}%
|
|
|
|
\def\avr@Rd{00000000}%
|
|
|
|
\def\avr@instr@extracarry{1}%
|
2014-09-27 00:49:58 +02:00
|
|
|
\csuse{avr@instr@subber@helper}%
|
2014-09-26 16:00:45 +02:00
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{#1}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@COM#1#2{\avr@code@set{1001010#20000}{#1}}
|
|
|
|
\csdef{avr@instr@1001010:0000}#1\@nnil{%
|
|
|
|
\avr@reg@get{#1}{\avr@Rr}%
|
|
|
|
\avr@debug{COM: #1(=\avr@Rr)}%
|
|
|
|
\avr@bin@negate{\avr@Rr}{\avr@Rx}%
|
|
|
|
\avr@flag@set C 1%
|
|
|
|
\avr@flag@set V 0%
|
|
|
|
\avr@flags@update \avr@Rx%
|
|
|
|
% Set the result register
|
|
|
|
\avr@reg@set{\avr@Rx}{#1}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% Skip if Bit in Register is Set (or not)
|
|
|
|
\def\avr@instr@SBRC#1#2#3{\avr@code@set{1111110#20#3}{#1}}
|
|
|
|
\def\avr@instr@SBRS#1#2#3{\avr@code@set{1111111#20#3}{#1}}
|
|
|
|
|
|
|
|
\csdef{avr@instr@111111}#1#2#3#4#5#6#7\@nnil{%
|
|
|
|
\def\@@required{#1}% 1 if if set
|
|
|
|
\avr@reg@get{#2#3#4#5#6}{\avr@Rr}%
|
|
|
|
\avr@bin@tocount{0000#7}{\avr@count@tmpa}%
|
|
|
|
\edef\@@bit{\the\avr@count@tmpa}%
|
|
|
|
\avr@bin@getbit{\avr@Rr}{\@@bit}{\@@found}%
|
|
|
|
\avr@debug{SBR[SC] Skip iff \avr@Rr:\@@bit(\@@found) == \@@required}%
|
|
|
|
\avr@count@tmpa=\@@found%
|
|
|
|
\avr@count@tmpb=\@@required\relax%
|
|
|
|
\ifnum \avr@count@tmpa = \avr@count@tmpb%
|
|
|
|
\avr@debug{SKIP one instruction}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
\fi%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
\def\avr@instr@ASR#1#2{\avr@code@set{1001010#20101}{#1}}
|
|
|
|
\csdef{avr@instr@1001010:0101}#1\@nnil{%
|
|
|
|
\avr@reg@get{#1}{\avr@Rr}%
|
|
|
|
\avr@debug{ASR: #1(=\avr@Rr)}%
|
|
|
|
\avr@bin@shiftright@arith{\avr@Rr}{1}{\avr@Rx}{\@@carry}%
|
|
|
|
\avr@bin@msb@get{\avr@Rx}{\@@N}%
|
|
|
|
\avr@flag@set C \@@carry%
|
|
|
|
\avr@flag@set V {\avr@bit@xor \@@carry \@@N}%
|
|
|
|
\avr@flags@update \avr@Rx%
|
|
|
|
\avr@reg@set{\avr@Rx}{#1}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
% LSL is implemented as ADD
|
|
|
|
\def\avr@instr@LSR#1#2{\avr@code@set{1001010#20110}{#1}}
|
|
|
|
\csdef{avr@instr@1001010:0110}#1\@nnil{%
|
|
|
|
\avr@reg@get{#1}{\avr@Rr}%
|
|
|
|
\avr@debug{LSL: #1(=\avr@Rr)}%
|
|
|
|
\avr@bin@shiftright{\avr@Rr}{1}{\avr@Rx}{\@@carry}%
|
|
|
|
\avr@bin@msb@get{\avr@Rx}{\@@N}%
|
|
|
|
\avr@flag@set C \@@carry%
|
|
|
|
\avr@flag@set V {\avr@bit@xor \@@carry \@@N}%
|
|
|
|
\avr@flags@update \avr@Rx%
|
|
|
|
\avr@reg@set{\avr@Rx}{#1}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
|
|
|
% ROL is implemented as ADD
|
|
|
|
\def\avr@instr@ROR#1#2{\avr@code@set{1001010#20111}{#1}}
|
|
|
|
\csdef{avr@instr@1001010:0111}#1\@nnil{%
|
|
|
|
\avr@reg@get{#1}{\avr@Rr}%
|
|
|
|
\avr@flag@get C \@@carry%
|
|
|
|
\avr@debug{ROR: #1(=\@@carry:\avr@Rr)}%
|
|
|
|
\avr@bin@lsb@del{\@@carry\avr@Rr}{\avr@Rx}{\@@carry}%
|
|
|
|
\avr@bin@msb@get{\avr@Rx}{\@@N}%
|
|
|
|
\avr@flag@set C \@@carry%
|
|
|
|
\avr@flag@set V {\avr@bit@xor \@@carry \@@N}%
|
|
|
|
\avr@flags@update \avr@Rx%
|
|
|
|
\avr@reg@set{\avr@Rx}{#1}%
|
|
|
|
\avr@pc@inc%
|
|
|
|
}
|
|
|
|
|
2014-09-20 20:09:39 +02:00
|
|
|
%%% Local Variables:
|
|
|
|
%%% mode: latex
|
|
|
|
%%% TeX-master: "avr.tex"
|
|
|
|
%%% End:
|