// 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;
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;
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;
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;
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; }
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)
.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
--- /dev/null
+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
+++ /dev/null
-#include "core.h"
-#include "test.h"
-
-#include <stdio.h>
-
-//#define DEBUG
-
-#ifdef DEBUG
-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]);
-}
-#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;
- }
-
-#ifdef DEBUG
- dump_state(&state);
-#endif // DEBUG
- } while (r != 1);
-
- return 0;
-}
-
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+main:
+ mov #0, r4
+ mov #1, r5
+ mov #2, r6
+ mov #-1, r7
+ mov #4, r8
+ mov #8, r9
+ ret
+++ /dev/null
-int main()
-{
- volatile int *mem = (int *)0x200;
- *mem = 24;
- for (int i = 0; i < 8; ++i)
- *mem += 2;
- return *mem;
-}
--- /dev/null
+#include "core.h"
+#include "test.h"
+
+#include <stdio.h>
+
+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;
+}
+
--- /dev/null
+#include "core.h"
+#include "test.h"
+
+#include <stdio.h>
+
+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;
+}
+
--- /dev/null
+#include "core.h"
+#include "test.h"
+
+#include <stdio.h>
+
+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] != 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);
+ return 1;
+ }
+
+
+ return 0;
+}
+
--- /dev/null
+#include "core.h"
+#include "test.h"
+
+#include <stdio.h>
+
+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;
+}
+