diff --git a/avr.instr.tex b/avr.instr.tex index 1770424..88abc74 100644 --- a/avr.instr.tex +++ b/avr.instr.tex @@ -16,7 +16,7 @@ %\avr@reg@get{\csuse{avr@r28}}{\@@B}% %\avr@reg@get{\csuse{avr@r29}}{\@@C}% %\avr@debug{{r24=\@@A} {r28=\@@B} {r29=\@@C}}% - \avr@debug{\avr@instr@current}% + %\avr@debug{\avr@instr@current}% % Dispatch Instruction by prefix \expandafter\avr@instr@dispatch\avr@instr@current\@nnil% \relax% @@ -381,15 +381,83 @@ \avr@pc@inc% } -% LDI -- Load Immediate Value -\def\avr@instr@LDI{\avr@instr@gen@regconst{1110}} -\def\avr@instr@SER#1#2{\avr@instr@gen@regconst{1110}{#1}{#2}{11111111}} -\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}% +% ADIW +\def\avr@instr@ADIW#1#2#3{% Reg, K + \edef\@@K{#3}% + \avr@bin@msb@del{\@@K}{\@@K}{\@@a}% + \avr@bin@msb@del{\@@K}{\@@K}{\@@b}% + \avr@code@set{10010110\@@a\@@b#2\@@K}{#1}% +} + +\csdef{avr@instr@10010110}#1#2#3#4#5\@nnil{% + \def\@@K{00#1#2#5}% + \avr@regw@get{11#3#4}{\avr@Rd}% + \avr@debug{ADIW #3#4 + \@@K}% + \avr@bin@tocount{\avr@Rd}{\avr@accA}% + \avr@bin@tocount{\@@K}{\avr@accB}% + \advance \avr@accA by \avr@accB\relax% + \avr@count@overflow{\avr@accA}% + \avr@count@tobin@w{\avr@accA}{\avr@Rx}% + % Calculate the Flags + \let\@@not=\avr@bit@negate% + \let\@@and=\avr@bit@and% + \let\@@xor=\avr@bit@xor% + \avr@bin@msb@get{\avr@Rx}{\@@X}% + \avr@bin@msb@get{\avr@Rd}{\@@D}% + % Zero Flag + \ifdefstring{\avr@Rx}{0000000000000000}{% + \avr@flag@set Z 1% + }{% + \avr@flag@set Z 0% + }% + \avr@flag@set C {\@@and {\@@not \@@X} \@@D}% + \avr@flag@set N \@@X% + \avr@flag@set V {\@@and {\@@not \@@D} \@@X}% + \avr@flag@set S {\@@xor \@@X {\@@and {\@@not \@@D} \@@X}}% + % Set the Result + \avr@regw@set{\avr@Rx}{11#3#4}% \avr@pc@inc% } +% Substract Immediate From Word +\def\avr@instr@SBIW#1#2#3{% Reg, K + \edef\@@K{#3}% + \avr@bin@msb@del{\@@K}{\@@K}{\@@a}% + \avr@bin@msb@del{\@@K}{\@@K}{\@@b}% + \avr@code@set{10010111\@@a\@@b#2\@@K}{#1}% +} + +\csdef{avr@instr@10010111}#1#2#3#4#5\@nnil{% + \def\@@K{00#1#2#5}% + \avr@regw@get{11#3#4}{\avr@Rd}% + \avr@debug{SBIW #3#4 + \@@K}% + \avr@bin@tocount{\avr@Rd}{\avr@accA}% + \avr@bin@tocount{\@@K}{\avr@accB}% + \advance \avr@accA by -\avr@accB\relax% + \avr@count@overflow{\avr@accA}% + \avr@count@tobin@w{\avr@accA}{\avr@Rx}% + % Calculate the Flags + \let\@@not=\avr@bit@negate% + \let\@@and=\avr@bit@and% + \let\@@xor=\avr@bit@xor% + \avr@bin@msb@get{\avr@Rx}{\@@X}% + \avr@bin@msb@get{\avr@Rd}{\@@D}% + % Zero Flag + \ifdefstring{\avr@Rx}{0000000000000000}{% + \avr@flag@set Z 1% + }{% + \avr@flag@set Z 0% + }% + \avr@flag@set C {\@@and \@@X {\@@not \@@D}}% + \avr@flag@set N \@@X% + \avr@flag@set V {\@@and {\@@not \@@X} \@@D}% + \avr@flag@set S {\@@xor \@@X {\@@and {\@@not \@@D} \@@X}}% + % Set the Result + \avr@regw@set{\avr@Rx}{11#3#4}% + \avr@pc@inc% +} + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Branch Instructions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -937,6 +1005,15 @@ \avr@pc@inc% } +% LDI -- Load Immediate Value +\def\avr@instr@LDI{\avr@instr@gen@regconst{1110}} +\def\avr@instr@SER#1#2{\avr@instr@gen@regconst{1110}{#1}{#2}{11111111}} +\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% +} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Misc @@ -1159,7 +1236,28 @@ \avr@skip@instr@eq{\avr@Rd}{\avr@Rr}% } +% Skip if Bit in IO-Register is Set (or not) +\def\avr@instr@SBIC#1#2#3{\avr@code@set{10011001#2#3}{#1}} +\def\avr@instr@SBIS#1#2#3{\avr@code@set{10011011#2#3}{#1}} +\csdef{avr@instr@10011011}{% + \def\@@required{1}% 1 if if set + \avr@SBI@helper% +} +\csdef{avr@instr@10011001}{% + \def\@@required{0}% 0 if if set + \avr@SBI@helper% +} +\def\avr@SBI@helper#1#2#3#4#5#6\@nnil{% + \avr@io@get{0#1#2#3#4#5}{\avr@Rr}% + \avr@bin@tocount{00000#6}{\avr@count@tmpa}% + \edef\@@bit{\the\avr@count@tmpa}% + \avr@bin@getbit{\avr@Rr}{\@@bit}{\@@found}% + \avr@debug{SBI[SC] Skip iff \avr@Rr:\@@bit(\@@found) == \@@required}% + \avr@skip@instr@eq{\@@required}{\@@found}% +} + +% Arithmetic Shift Right \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}% diff --git a/avr.io.tex b/avr.io.tex index dcfaa03..e00d958 100644 --- a/avr.io.tex +++ b/avr.io.tex @@ -7,6 +7,13 @@ } % OUT +\def\avr@instr@OUT#1#2#3{% A, R + \def\@@A{#2} + \avr@bin@msb@del{\@@A}{\@@A}{\@@a}% + \avr@bin@msb@del{\@@A}{\@@A}{\@@b}% + \avr@code@set{10111\@@a\@@b#3\@@A}{#1}% +} + \csdef{avr@instr@10111}#1#2#3#4#5#6#7#8\@nnil{% \def\@@A{#1#2#8}% \avr@reg@get{#3#4#5#6#7}{\avr@Rr}% @@ -29,8 +36,8 @@ } % #1=Addr, #2=\result \def\avr@io@get#1#2{% - \ifcsdef{avr@io@#2@get}{% - \csuse{avr@io@#2@get}{#2}% + \ifcsdef{avr@io@#1@get}{% + \csuse{avr@io@#1@get}{#2}% }{% \avr@io@get@default{#1}{#2}% }% @@ -40,6 +47,10 @@ \avr@error{IO Port #2 is not defined (OUT #1)}% } +\def\avr@io@get@default#1#2{% + \avr@error{IO Port #1 is not defined (IN)}% +} + \csdef{avr@io@111111@set}#1{% \avr@debug{ SREG=#1}% \avr@sreg@set{#1}% @@ -55,6 +66,14 @@ \xdef\avr@UDR{\avr@UDR \@@char}% } +% SPDR +\csdef{avr@io@001111@set}#1{% + \csdef{avr@io@001111}{#1}% +} + +\csdef{avr@io@001111@get}#1{% + \xdef#1{\csuse{avr@io@001111}}% +} %%% Local Variables: diff --git a/avr.numbers.tex b/avr.numbers.tex index ee95f81..66f135a 100644 --- a/avr.numbers.tex +++ b/avr.numbers.tex @@ -311,7 +311,7 @@ \def\avr@bin@tocount@helper#1#2#3#4#5#6#7#8#9\@nnil{% \multiply\avr@count@tmpa by 256\relax% \ifcsdef{avr@dec@#1#2#3#4#5#6#7#8}{}{% - \avr@error{Incorrect Number: #1}% + \avr@error{Incorrect Number: '#1'}% }% \advance\avr@count@tmpa by \csuse{avr@dec@#1#2#3#4#5#6#7#8}% \if &\else% @@ -359,11 +359,11 @@ \def\avr@count@overflow#1{% \def\avr@count@overflow@flag{0}% \ifnum #1 < 0% - \advance #1 by 65535% + \advance #1 by 65536% \def\avr@count@overflow@flag{1}% \fi% \ifnum #1 > 65535% - \advance #1 by -65535% + \advance #1 by -65536% \def\avr@count@overflow@flag{1}% \fi% } diff --git a/avr.testsuite.tex b/avr.testsuite.tex index ea9b968..acf1fbf 100644 --- a/avr.testsuite.tex +++ b/avr.testsuite.tex @@ -490,6 +490,48 @@ } \preto\avr@test{\avr@test@CPSE} +\def\avr@test@SBIC{% + \avr@test@setup{SBIC}% + \avr@instr@LDI{0}{\csuse{avr@r20}}{11110000}% + \avr@instr@OUT{1}{001111}{\csuse{avr@r20}}% + \avr@instr@SBIC{2}{01111}{111}% Skip never + \avr@instr@LDI{3}{\csuse{avr@r21}}{00001111}% + \avr@instr@NOP{4}% + + \avr@instr@stepn{5}% + \avr@test@REG{r21}{00001111} +} +\preto\avr@test{\avr@test@SBIC} + +\def\avr@test@ADIW{% + \avr@test@setup{SBIC}% + \avr@instr@LDI{0}{\csuse{avr@r31}}{11111111}% + \avr@instr@LDI{1}{\csuse{avr@r30}}{11000000}% + \avr@instr@ADIW{2}{11}{111111}% + \avr@instr@ADIW{3}{11}{000001}% + \avr@instr@SBIW{4}{11}{000010}% + + + + \avr@instr@stepn{3}% + \avr@test@REG{r30}{11111111} + \avr@test@REG{r31}{11111111} + \avr@test@SREG{00010100} + + \avr@instr@stepn{1}% + \avr@test@REG{r30}{00000000} + \avr@test@REG{r31}{00000000} + \avr@test@SREG{00000011} + + \avr@instr@stepn{1}% + \avr@test@REG{r30}{11111110} + \avr@test@REG{r31}{11111111} + \avr@test@SREG{00000101} + +} +\preto\avr@test{\avr@test@ADIW} + + %%% Local Variables: %%% mode: latex