diff --git a/avr.instr.tex b/avr.instr.tex index 88abc74..f563366 100644 --- a/avr.instr.tex +++ b/avr.instr.tex @@ -5,10 +5,14 @@ \def\avr@error#1{% \avr@dump% \errmessage{\the\avr@pc: #1}\bye% - } +\newcount\avr@instr@executed +\def\avr@instr@init{% + \avr@instr@executed=0% +} + % Execution Engine \def\avr@instr@step{% \avr@code@get{\avr@instr@current}% @@ -19,8 +23,7 @@ %\avr@debug{\avr@instr@current}% % Dispatch Instruction by prefix \expandafter\avr@instr@dispatch\avr@instr@current\@nnil% - \relax% - + \advance\avr@instr@executed by 1\relax% } \def\avr@singlestep{% @@ -367,10 +370,10 @@ \csdef{avr@instr@INCDEC@helper}#1#2{% \avr@reg@get{#1}{\avr@Rd}% \avr@debug{INCDEC #1(=\avr@Rd) +(#2)}% - \avr@bin@tocount{\avr@Rd}{\avr@count@tmpa}% - \advance \avr@count@tmpa by #2\relax% - \avr@count@modulo@byte{\avr@count@tmpa}% - \avr@count@tobin@b{\avr@count@tmpa}{\avr@Rx}% + \avr@bin@tocount{\avr@Rd}{\avr@accA}% + \advance \avr@accA by #2\relax% + \avr@count@modulo@byte{\avr@accA}% + \avr@count@tobin@b{\avr@accA}{\avr@Rx}% \ifdefstring{\avr@Rx}{01111111}{% \avr@flag@set V 1% }{% @@ -630,7 +633,7 @@ \avr@reg@get{\csuse{avr@r24}}{\@@A}% \avr@reg@get{\csuse{avr@r25}}{\@@B}% \avr@reg@get{\csuse{avr@r26}}{\@@C}% - \avr@debug{ICALL \the\avr@count@tmpa {r24:\@@A} {r25:\@@B} {r26:\@@C}}% + \avr@debug{RCALL \the\avr@count@tmpa {r24:\@@A} {r25:\@@B} {r26:\@@C}}% \avr@CALL@helper{\@@pc}% \avr@pc@add{\avr@count@tmpa}% } @@ -651,12 +654,12 @@ \def\avr@instr@IJMP#1{\avr@code@set{1001010000001001}{#1}} \csdef{avr@instr@1001010000001001}\@nnil{ \avr@count@tobin@w{\the\avr@pc}{\@@pc}% - \avr@regw@get{Z}{\@@addr} + \avr@regw@get{\csuse{avr@Z}}{\@@addr} \avr@bin@tocount{\@@addr}{\avr@addr}% - \avr@reg@get{\csuse{avr@r24}}{\@@A}% - \avr@reg@get{\csuse{avr@r25}}{\@@B}% - \avr@reg@get{\csuse{avr@r26}}{\@@C}% - \avr@debug{IJMP \the\avr@addr {r24:\@@A} {r25:\@@B} {r26:\@@C}}% + \avr@reg@get{\csuse{avr@r24}}{\@@a}% + \avr@reg@get{\csuse{avr@r25}}{\@@b}% + \avr@reg@get{\csuse{avr@r26}}{\@@c}% + \avr@debug{IJMP \the\avr@addr {r24:\@@a} {r25:\@@b} {r26:\@@c}}% \avr@pc=\avr@addr } @@ -1023,7 +1026,7 @@ } \csdef{avr@instr@1001010110011000}\@nnil{% - \avr@debug{BREAK}% + \avr@debug{BREAK: (\the\avr@instr@executed) instructions}% \avr@instr@steps=0\relax% \avr@pc@inc% } @@ -1276,7 +1279,7 @@ \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@debug{LSR #1(=\avr@Rr)}% \avr@bin@shiftright{\avr@Rr}{1}{\avr@Rx}{\@@carry}% \avr@bin@msb@get{\avr@Rx}{\@@N}% \avr@flag@set C \@@carry% diff --git a/avr.io.tex b/avr.io.tex index e00d958..0ca6977 100644 --- a/avr.io.tex +++ b/avr.io.tex @@ -22,6 +22,22 @@ \avr@pc@inc% } +% OUT +\def\avr@instr@IN#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{10110\@@a\@@b#3\@@A}{#1}% +} + +\csdef{avr@instr@10110}#1#2#3#4#5#6#7#8\@nnil{% + \avr@debug{IN #1#2#8 -> #3#4#5#6#7}% + \edef\@@IOA{#1#2#8}% + \avr@io@get{\@@IOA}{\avr@Rr}% + \avr@reg@set{\avr@Rr}{#3#4#5#6#7}% + \avr@pc@inc% +} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % IO Handlers @@ -36,6 +52,7 @@ } % #1=Addr, #2=\result \def\avr@io@get#1#2{% + \avr@debug{ IO R #1}% \ifcsdef{avr@io@#1@get}{% \csuse{avr@io@#1@get}{#2}% }{% @@ -48,21 +65,25 @@ } \def\avr@io@get@default#1#2{% - \avr@error{IO Port #1 is not defined (IN)}% + \avr@error{IO Port #1 is not defined (IN -> #2)}% } \csdef{avr@io@111111@set}#1{% \avr@debug{ SREG=#1}% \avr@sreg@set{#1}% } +\csdef{avr@io@111111@get}#1{\avr@sreg@get{#1}} +% Stackpointer IO Ports \csdef{avr@io@111110@set}#1{\avr@stack@SPH@set{#1}} \csdef{avr@io@111101@set}#1{\avr@stack@SPL@set{#1}} +\csdef{avr@io@111110@get}#1{\avr@stack@SPH@get{#1}} +\csdef{avr@io@111101@get}#1{\avr@stack@SPL@get{#1}} \csdef{avr@io@001100@set}#1{% \avr@bin@tocount{#1}{\avr@count@tmpa}% \avr@ascii{\the\avr@count@tmpa}{\@@char}% - \avr@debug{UDR: #1=\the\avr@count@tmpa}% + \avr@debug{UDR: \the\avr@count@tmpa}% \xdef\avr@UDR{\avr@UDR \@@char}% } diff --git a/avr.memory.tex b/avr.memory.tex index 5451a15..0fda7a5 100644 --- a/avr.memory.tex +++ b/avr.memory.tex @@ -8,6 +8,8 @@ \avr@stack@init% \avr@mem@init{1024}% \avr@io@init% + \avr@instr@init% + \avr@debug{Initialized AVR}% } \newcount\avr@accA diff --git a/avr.numbers.tex b/avr.numbers.tex index 66f135a..ef8c572 100644 --- a/avr.numbers.tex +++ b/avr.numbers.tex @@ -266,10 +266,10 @@ % \avr@count@tobin@b uint8_t count|integer, \result -> \result = bin(arg) \def\avr@count@tobin@b#1#2{% \ifnum #1 > 255 % - \avr@error{#1 to large value}% + \avr@error{#1 to large value (\the#1)}% \fi% \ifnum #1 < 0 % - \avr@error{#1 to small value}% + \avr@error{#1 to small value (\the#1)}% \fi% \avr@count@tmpa=#1% \ifcsdef{avr@bin@\the\avr@count@tmpa}{}{% @@ -371,9 +371,13 @@ \def\avr@count@modulo@byte#1{% \avr@count@tmpa=#1\relax% \avr@count@tmpb=#1\relax% + \divide \avr@count@tmpa by 256\relax% \multiply \avr@count@tmpa by 256\relax% \advance \avr@count@tmpb by -\avr@count@tmpa\relax% + \ifnum \avr@count@tmpb < 0% + \advance\avr@count@tmpb by 256% + \fi% #1 = \avr@count@tmpb\relax% } diff --git a/tests/float.c b/tests/float.c new file mode 100644 index 0000000..aebeb5a --- /dev/null +++ b/tests/float.c @@ -0,0 +1,47 @@ +#include +#include + +static int uart_putchar(char c, FILE *stream); +static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, + _FDEV_SETUP_WRITE); +static int +uart_putchar(char c, FILE *stream) +{ + UDR = c; + return 0; +} + +volatile uint16_t xxx = 65; + +int +main(void) +{ + stdout = &mystdout; + printf("Hello, world!"); + + asm volatile("break;"); + + + volatile float foo = 0.23; + printf("%.2f", foo); + + asm volatile("break;"); + + + return 0; +} + + +/** + check-name: Print to Stdout and Float + check-start: + + \avr@instr@stepn{100000} + \avr@test@UDR{Hello, world!} + \xdef\avr@UDR{} + + \avr@instr@stepn{100000} + \avr@test@UDR{0.23} + \def\avr@UDR{} + check-end: +**/ diff --git a/tests/mul.c b/tests/mul.c index 7fa25c2..b151383 100644 --- a/tests/mul.c +++ b/tests/mul.c @@ -13,6 +13,13 @@ int main() { foo[4] = foo[1] % foo[0]; + volatile uint16_t x = 1000; + volatile uint16_t y = 55; + + foo[5] = x * y; + + itoa(165, &foo[6], 10); + asm volatile ("break"); } @@ -28,5 +35,11 @@ int main() { \avr@test@MEM{99}{00000001} % 1 \avr@test@MEM{100}{00010011} % 19 + \avr@test@MEM{101}{11011000} % 216 + + \avr@test@MEM{102}{00110001} % '1' + \avr@test@MEM{103}{00110110} % '6' + \avr@test@MEM{104}{00110101} % '5' + check-end: */ diff --git a/tests/printf.c b/tests/printf.c new file mode 100644 index 0000000..fc255ba --- /dev/null +++ b/tests/printf.c @@ -0,0 +1,36 @@ +#include +#include + +volatile char buffer[30]; + +volatile uint16_t xxx = 165; + +int +main(void) +{ + asm volatile("break;"); + + // sprintf(buffer, "%d", xxx); + __ultoa_invert(xxx, buffer, 10); + + asm volatile("break;"); + + + return 0; +} + + +/** + check-name: Print to Stdout + check-start: + + \avr@instr@stepn{100000} + \avr@instr@executed=0 + \avr@instr@stepn{100000} + + \avr@test@MEM{96}{00110001} % '1' + \avr@test@MEM{97}{00110110} % '6' + \avr@test@MEM{98}{00110101} % '5' + + check-end: +**/ diff --git a/tests/test-suite b/tests/test-suite index 1544b0c..325c532 100755 --- a/tests/test-suite +++ b/tests/test-suite @@ -93,10 +93,10 @@ do_test() fi test_name=$last_result - echo "TEST $test_name ($file)" + echo -n "TEST $test_name ($file)" cp HEADER "$file".tex - echo "\avrloadc{$file}" >> "$file".tex + echo "\avrloadc[-lm -Os -mmcu=atmega8]{$file}" >> "$file".tex awk '/check-start/,/check-end/ {print}' $file \ | egrep -v 'check-(start|end)' >> "$file".tex @@ -109,6 +109,7 @@ do_test() rm -f *.log *.aux *.pdf if [ "$actual_exit_value" -ne 0 ]; then + echo error " Actual exit value does not match the expected one." error " expected 0, got $actual_exit_value" if [ x"$V" = x"1" ]; then @@ -117,6 +118,9 @@ do_test() tail -n 10 $file.output | sed 's/^/ /' fi test_failed=1 + else + get_value BREAK "$file".output + echo " ($last_result)" fi if [ "$test_failed" -eq "1" ]; then