\def\avr@debug#1{% \typeout{\the\avr@pc: #1}% } \def\avr@error#1{% \typeout{#1}\bye% } % Execution Engine \def\avr@instr@step{% \avr@code@get{\avr@instr@current}% % 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 \avr@error{Unkown Instruction: #1#2#3#4#5#6#7#8#9}% }}}}}}}}}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Helpers %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Arithmetic instructions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % ADD -- Add without Carry \def\avr@instr@ADD{\avr@instr@gen@tworegs{000011}} \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}% \def\avr@instr@adder@RrPreprocess{\avr@bit@id}% \csuse{avr@instr@adder@helper}% \avr@reg@set{\avr@Rx}{#2#3#4#5#6}% \avr@pc@inc% } % ADC -- Add with Carry \def\avr@instr@ADC{\avr@instr@gen@tworegs{000111}} \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}% \def\avr@instr@adder@RrPreprocess{\avr@bit@id}% \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 \def\avr@instr@SUB{\avr@instr@gen@tworegs{000110}} \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}% \def\avr@instr@adder@RrPreprocess{\avr@bit@negate}% \csuse{avr@instr@adder@helper}% % Set the result register \avr@reg@set{\avr@Rx}{#2#3#4#5#6}% \avr@pc@inc% } % SBC - Substract with Carry \def\avr@instr@SBC{\avr@instr@gen@tworegs{000010}} \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}% \def\avr@instr@adder@RrPreprocess{\avr@bit@negate}% \csuse{avr@instr@adder@helper}% % Set the result register \avr@reg@set{\avr@Rx}{#2#3#4#5#6}% \avr@pc@inc% } % 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}% \def\avr@instr@adder@RrPreprocess{\avr@bit@negate}% \csuse{avr@instr@adder@helper}% % Set the result register \avr@reg@set{\avr@Rx}{1#5#6#7#8}% \avr@pc@inc% } % SBCI - Substract Immediate \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}% \def\avr@instr@adder@RrPreprocess{\avr@bit@negate}% \csuse{avr@instr@adder@helper}% % 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}} \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)}% \def\avr@instr@adder@RrPreprocess{\avr@bit@negate}% \csuse{avr@instr@adder@helper}% % Do not set the output register \avr@pc@inc% } % CPC -- Compare with Carry \def\avr@instr@CPC{\avr@instr@gen@tworegs{000001}} \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)}% \def\avr@instr@adder@RrPreprocess{\avr@bit@negate}% \csuse{avr@instr@adder@helper}% % Do not set the output register \avr@pc@inc% } \csdef{avr@instr@adder@helper}{% % Convert the Bitstring to Integer values \avr@bin@tocount{\avr@Rd}{\avr@accA}% \avr@bin@map{\avr@instr@adder@RrPreprocess}{\avr@Rr}{\avr@Rr}% \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}% % \avr@debug{R: \@@R D: \@@D X:\@@X}% \def\avr@ADD@carry{% \@@or {\@@and \@@D {\@@not \@@X}}% {% \@@or{\@@and \@@R \@@D}% {\@@and \@@R {\@@not \@@X}}}}% \avr@flag@set C {\avr@instr@adder@RrPreprocess{\avr@ADD@carry}}% % 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}}}}% \avr@flag@set H {\avr@instr@adder@RrPreprocess{\avr@ADD@carry}}% %% Update Dependend Flags (N, Z, S) \avr@flags@update \avr@Rx% } % 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% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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% } % 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% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Data transfert instructions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % MOV \def\avr@instr@MOV{\avr@instr@gen@tworegs{001011}} \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% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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% } \def\avr@instr@NOP#1{% BREAK PC \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}} \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% } %%% Local Variables: %%% mode: latex %%% TeX-master: "avr.tex" %%% End: