diff --git a/.gitignore b/.gitignore index 9eca6c8..9be162f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +*.sw* *.a *.o diff --git a/src/do_cycle_word.c b/src/do_cycle_word.c index 2599d13..d743e59 100644 --- a/src/do_cycle_word.c +++ b/src/do_cycle_word.c @@ -116,13 +116,13 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode) // ADD uint32_t res = *src + *dst; uint16_t sr = 0; - if ((int16_t)res < 0) + if ((int16_t)(res & 0xFFFF) < 0) sr |= MSP430_SR_N; - if (res == 0) + if ((res & 0xFFFF) == 0) sr |= MSP430_SR_Z; if ((res & 0xFFFF0000) != 0) sr |= MSP430_SR_C; - if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) + if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) sr |= MSP430_SR_V; *dst = (uint16_t)res; state->reg[2] = sr; @@ -137,7 +137,7 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode) sr |= MSP430_SR_Z; if ((res & 0xFFFF0000) != 0) sr |= MSP430_SR_C; - if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) + if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) sr |= MSP430_SR_V; *dst = (uint16_t)res; state->reg[2] = sr; @@ -152,7 +152,7 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode) sr |= MSP430_SR_Z; if ((res & 0xFFFF0000) != 0) sr |= MSP430_SR_C; - if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) + if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) sr |= MSP430_SR_V; *dst = (uint16_t)res; state->reg[2] = sr; @@ -167,7 +167,7 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode) sr |= MSP430_SR_Z; if ((res & 0xFFFF0000) != 0) // TODO confirm sr |= MSP430_SR_C; - if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) + if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) sr |= MSP430_SR_V; *dst = (uint16_t)res; state->reg[2] = sr; @@ -182,7 +182,7 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode) sr |= MSP430_SR_Z; if ((res & 0xFFFF0000) != 0) sr |= MSP430_SR_C; - if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) + if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) sr |= MSP430_SR_V; state->reg[2] = sr; break; } diff --git a/tests/Makefile b/tests/Makefile index 43d4134..4d66f39 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -2,8 +2,13 @@ DEBUG := #-DDEBUG LIB430COREDIR = .. -TEST_CSRC = test.c -TEST_OUT = $(patsubst %.c,%.o,$(TEST_CSRC)) +TEST_CSRC = \ + mov_constants.s \ + mov_addressing_dest.s \ + mov_addressing_source.s \ + add.s + +TEST_OUT = $(patsubst %.c,%.o,$(patsubst %.s,%.o,$(TEST_CSRC))) all: $(LIB430COREDIR)/lib430core.a $(TEST_OUT) @@ -12,13 +17,26 @@ $(LIB430COREDIR)/lib430core.a: .c.o: @echo "Testing" $< "..." - @msp430-elf32-gcc -T../link.ld $< -o tmp.elf -nostdlib -lgcc -lc + @msp430-elf32-gcc -T../link.ld -O0 -ggdb -g3 $< -o tmp.elf -nostdlib -lgcc -lc + @msp430-elf32-objcopy -Obinary tmp.elf tmp.bin + @echo "#define TESTBIN \\" > test.h + @od -t x1 tmp.bin | awk '{for (i=2; i<=NF; i++) printf "0x" $$i ", "}' >> test.h + @printf "\n#define TESTSIZE %u \n" $$(msp430-elf32-objdump tmp.elf -Dj .text | grep -E "^\s+[0-9a-fA-F]+:" | wc -l) >> test.h + @echo >> test.h + @gcc -Os -ggdb -g3 -Wall -W -pedantic $(DEBUG) -I../src -o tmp \ + test_$< -L$(LIB430COREDIR) -l430core + @./tmp + @rm tmp.elf tmp.bin tmp test.h + +.s.o: + @echo "Testing" $< "..." + @msp430-elf32-gcc -T../link.ld -O0 $< -o tmp.elf -nostdlib -lgcc -lc @msp430-elf32-objcopy -Obinary tmp.elf tmp.bin @echo "#define TESTBIN \\" > test.h @od -t x1 tmp.bin | awk '{for (i=2; i<=NF; i++) printf "0x" $$i ", "}' >> test.h @printf "\n#define TESTSIZE %u \n" $$(msp430-elf32-objdump tmp.elf -Dj .text | grep -E "^\s+[0-9a-fA-F]+:" | wc -l) >> test.h @echo >> test.h @gcc -Os -ggdb -g3 -Wall -W -pedantic $(DEBUG) -I../src -o tmp \ - core_test.c -L$(LIB430COREDIR) -l430core - @./tmp > log - @rm log tmp.elf tmp.bin tmp test.h + test_$(patsubst %.s,%.c,$<) -L$(LIB430COREDIR) -l430core + @./tmp + @rm tmp.elf tmp.bin tmp test.h diff --git a/tests/add.s b/tests/add.s new file mode 100644 index 0000000..d811316 --- /dev/null +++ b/tests/add.s @@ -0,0 +1,16 @@ +main: + mov #13, r5 + add #15, r5 + mov r2, r12 + mov #-7, r6 + add #7, r6 + mov r2, r13 + mov #0xfffa, r7 + add #0x001e, r7 + mov r2, r14 + mov #-32700, r8 + add #-800, r8 + mov r2, r15 + mov #2, r9 + add #-5, r9 + ret diff --git a/tests/mov_addressing_dest.s b/tests/mov_addressing_dest.s new file mode 100644 index 0000000..8698a92 --- /dev/null +++ b/tests/mov_addressing_dest.s @@ -0,0 +1,11 @@ +main: + mov #64, r4 + mov r4, r5 + mov #42, r4 + mov r4, @r5 + mov r4, 4(r5) + mov #50, mem + mov &mem, &0x50 + ret + +mem: .byte 5 diff --git a/tests/mov_addressing_source.s b/tests/mov_addressing_source.s new file mode 100644 index 0000000..21f0cb3 --- /dev/null +++ b/tests/mov_addressing_source.s @@ -0,0 +1,14 @@ +main: + mov #42, &0x40 + mov #44, &0x42 + mov #46, &0x44 + mov #0x40, r4 + mov r4, r5 + mov 4(r5), r6 + mov @r5+, r7 + mov @r5, r8 + mov var, r9 + mov &0x44, r10 + ret + +var: .byte 13 diff --git a/tests/mov_constants.s b/tests/mov_constants.s new file mode 100644 index 0000000..d77eb51 --- /dev/null +++ b/tests/mov_constants.s @@ -0,0 +1,8 @@ +main: + mov #0, r4 + mov #1, r5 + mov #2, r6 + mov #-1, r7 + mov #4, r8 + mov #8, r9 + ret diff --git a/tests/test.c b/tests/test.c deleted file mode 100644 index 8eb344a..0000000 --- a/tests/test.c +++ /dev/null @@ -1,8 +0,0 @@ -int main() -{ - volatile int *mem = (int *)0x200; - *mem = 24; - for (int i = 0; i < 8; ++i) - *mem += 2; - return *mem; -} diff --git a/tests/test_add.c b/tests/test_add.c new file mode 100644 index 0000000..2f6bc00 --- /dev/null +++ b/tests/test_add.c @@ -0,0 +1,53 @@ +#include "core.h" +#include "test.h" + +#include + +static uint8_t mem[0x10000] = { + TESTBIN +}; + +static void dump_state(msp430_t *state) +{ + puts("MSP430 dump state:"); + printf("R0/PC: 0x%04x R1/SP: 0x%04x R2/SR: 0x%04x R3: 0x%04x\n", + state->reg[0], state->reg[1], state->reg[2], state->reg[3]); + printf("R4: 0x%04x R5: 0x%04x R6: 0x%04x R7: 0x%04x\n", + state->reg[4], state->reg[5], state->reg[6], state->reg[7]); + printf("R8: 0x%04x R9: 0x%04x R10: 0x%04x R11: 0x%04x\n", + state->reg[8], state->reg[9], state->reg[10], state->reg[11]); + printf("R12: 0x%04x R13: 0x%04x R14: 0x%04x R15: 0x%04x\n\n", + state->reg[12], state->reg[13], state->reg[14], state->reg[15]); +} + +int main() +{ + msp430_t state; + msp430_init_state(&state, mem); + + int r; + do { + r = msp430_do_cycle(&state); + if (r < 0) { + printf("Failed to execute near PC=0x%04x!\n", state.reg[0]); + return 1; + } + } while (r != 1); + + if (state.reg[5] != 28 || + state.reg[6] != 0 || + state.reg[7] != 0x18 || + state.reg[8] != 0x7d24 || + state.reg[9] != 0xfffd || + state.reg[12] != 0 || + state.reg[13] != 0x03 || + state.reg[14] != 0x01 || + state.reg[15] != 0x101) + { + dump_state(&state); + return 1; + } + + return 0; +} + diff --git a/tests/test_mov_addressing_dest.c b/tests/test_mov_addressing_dest.c new file mode 100644 index 0000000..5db3df7 --- /dev/null +++ b/tests/test_mov_addressing_dest.c @@ -0,0 +1,50 @@ +#include "core.h" +#include "test.h" + +#include + +static uint8_t mem[0x10000] = { + TESTBIN +}; +/* +static void dump_state(msp430_t *state) +{ + puts("MSP430 dump state:"); + printf("R0/PC: 0x%04x R1/SP: 0x%04x R2/SR: 0x%04x R3: 0x%04x\n", + state->reg[0], state->reg[1], state->reg[2], state->reg[3]); + printf("R4: 0x%04x R5: 0x%04x R6: 0x%04x R7: 0x%04x\n", + state->reg[4], state->reg[5], state->reg[6], state->reg[7]); + printf("R8: 0x%04x R9: 0x%04x R10: 0x%04x R11: 0x%04x\n", + state->reg[8], state->reg[9], state->reg[10], state->reg[11]); + printf("R12: 0x%04x R13: 0x%04x R14: 0x%04x R15: 0x%04x\n\n", + state->reg[12], state->reg[13], state->reg[14], state->reg[15]); +} +*/ +int main() +{ + msp430_t state; + msp430_init_state(&state, mem); + + int r; + do { + r = msp430_do_cycle(&state); + if (r < 0) { + printf("Failed to execute near PC=0x%04x!\n", state.reg[0]); + return 1; + } + } while (r != 1); + + if (state.reg[4] != 42 || + state.reg[5] != 64 || + *((uint16_t *)(state.mem + 64)) != 42 || + *((uint16_t *)(state.mem + 68)) != 42 || + *((uint16_t *)(state.mem + 0x50)) != 50) + { + return 1; + } + + //dump_state(&state); + + return 0; +} + diff --git a/tests/core_test.c b/tests/test_mov_addressing_source.c similarity index 82% rename from tests/core_test.c rename to tests/test_mov_addressing_source.c index 08e2650..c35421e 100644 --- a/tests/core_test.c +++ b/tests/test_mov_addressing_source.c @@ -3,9 +3,10 @@ #include -//#define DEBUG +static uint8_t mem[0x10000] = { + TESTBIN +}; -#ifdef DEBUG static void dump_state(msp430_t *state) { puts("MSP430 dump state:"); @@ -18,34 +19,33 @@ static void dump_state(msp430_t *state) printf("R12: 0x%04x R13: 0x%04x R14: 0x%04x R15: 0x%04x\n\n", state->reg[12], state->reg[13], state->reg[14], state->reg[15]); } -#endif // DEBUG - -static uint8_t mem[0x10000] = { - TESTBIN -}; int main() { msp430_t state; - msp430_init_state(&state, mem); -#ifdef DEBUG - dump_state(&state); -#endif // DEBUG int r; do { r = msp430_do_cycle(&state); if (r < 0) { printf("Failed to execute near PC=0x%04x!\n", state.reg[0]); return 1; - //break; } + } while (r != 1); -#ifdef DEBUG + if (state.reg[4] != 0x40 || + state.reg[5] != 0x42 || + state.reg[6] != 46 || + state.reg[7] != 42 || + state.reg[8] != 44 || + state.reg[9] != 13 || + state.reg[10] != 46) + { dump_state(&state); -#endif // DEBUG - } while (r != 1); + return 1; + } + return 0; } diff --git a/tests/test_mov_constants.c b/tests/test_mov_constants.c new file mode 100644 index 0000000..f52b5ee --- /dev/null +++ b/tests/test_mov_constants.c @@ -0,0 +1,36 @@ +#include "core.h" +#include "test.h" + +#include + +static uint8_t mem[0x10000] = { + TESTBIN +}; + +int main() +{ + msp430_t state; + msp430_init_state(&state, mem); + + int r; + do { + r = msp430_do_cycle(&state); + if (r < 0) { + printf("Failed to execute near PC=0x%04x!\n", state.reg[0]); + return 1; + } + } while (r != 1); + + if (state.reg[4] != 0 || + state.reg[5] != 1 || + state.reg[6] != 2 || + state.reg[7] != 0xFFFF || + state.reg[8] != 4 || + state.reg[9] != 8) + { + return 1; + } + + return 0; +} +