void test_mcu_callf(void) { uint32_t address = 0x556677; uint8_t length = 4; SET_PC(0x12BBCC); mcu_callf( address, length); //12BBCC + 4 = 12BBDO TEST_ASSERT_EQUAL_INT8(0xD0, MEM_READ_BYTE(inputSP) ); // test is pcl store in the address TEST_ASSERT_EQUAL_INT8(0xBB, MEM_READ_BYTE(sp_minus1) ); // test is pch store in the address ( sp decrement) TEST_ASSERT_EQUAL_INT8(0x12, MEM_READ_BYTE(sp_minus2) ); // test is pce store in the address ( sp decrement) TEST_ASSERT_EQUAL_INT32( address , *pcToLoad ); TEST_ASSERT_EQUAL_INT8(inputSP -3, SP ); // test is sp decreament 3 time }
void test_pushw_y(void) { YH = 0xAA; YL = 0xBB; SET_Y(0xAABB); uint8_t instr[] = {0XAB}; uint8_t length = pushw_y(instr); TEST_ASSERT_EQUAL_INT8(0xBB, MEM_READ_BYTE(inputSP) ); TEST_ASSERT_EQUAL_INT8(0xAA, MEM_READ_BYTE(inputSP_DEC) ); TEST_ASSERT_EQUAL_INT16( inputSP-2 , SP ); // test is SP decreament 2 time TEST_ASSERT_EQUAL_INT8( 2, length ); }
//Assembly : (Y) | ld A,(Y) void test_ld_a_to_y(void){ SET_Y(0X102B); uint8_t instr[] = {0XFB}; TEST_ASSERT_EQUAL_INT8(2, ld_a_to_y(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(0X102B)); }
void mcu_cpl(uint16_t addr){ uint8_t result = 0xFF - MEM_READ_BYTE(addr); MEM_WRITE_BYTE( addr, result); UPDATE_Z_N_FLAG(result); C = 1; }
//Assembly : shortmem | ld A,$10 void test_ld_a_to_shortmem(void){ uint8_t shortMEM = 0xAD; uint8_t instr[] = {0XBB, shortMEM}; TEST_ASSERT_EQUAL_INT8(2, ld_a_to_shortmem(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(shortMEM)); }
//Assembly : longmem | ld A,$1000 void test_ld_a_to_longmem(void){ uint16_t longmem = 0x1101; uint8_t instr[] = {0XBB, 0x11, 0x01}; TEST_ASSERT_EQUAL_INT8(3, ld_a_to_longmem(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(longmem)); }
void mcu_neg(uint16_t addr){ uint8_t result = 0 - MEM_READ_BYTE(addr); MEM_WRITE_BYTE( addr, result); UPDATE_Z_N_FLAG(result); C = ~Z; V = (result == 0x80 ? 1 : 0); }
//Assembly : (shortoff,X) | ld A,($10,X) void test_ld_a_to_shortoff_x(void){ SET_X(0X2B11); uint8_t instr[] = {0XFB, 0X11}; //0x2B11 + 0X11 = 0X2B22 TEST_ASSERT_EQUAL_INT8(2, ld_a_to_shortoff_x(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(0X2B22)); }
/* 0000 | 0100 -------- 0100 -------- */ void test_bset_longmem_pos_2(void){ uint16_t longmem = 0x1101; MEM_WRITE_BYTE(longmem, 0); uint8_t instr[] = {0XBB, 0x11, 0x01}; TEST_ASSERT_EQUAL_INT8(4, bset_longmem_pos_2(instr)); TEST_ASSERT_EQUAL_INT8(0x4, MEM_READ_BYTE(longmem) ); }
/* 0100 | 0001 -------- 0101 -------- */ void test_bset_longmem_pos_0_given_value_is_4(void){ uint16_t longmem = 0x1101; MEM_WRITE_BYTE(longmem, 0x4); uint8_t instr[] = {0XBB, 0x11, 0x01}; TEST_ASSERT_EQUAL_INT8(4, bset_longmem_pos_0(instr)); TEST_ASSERT_EQUAL_INT8(0x5, MEM_READ_BYTE(longmem) ); }
//Assembly : (longoff,Y) | ld A,($1000,Y) void test_ld_a_to_longoff_y(void){ SET_Y(0X2B11); uint8_t instr[] = {0XFB, 0X11, 0x11}; //0x2B11 + 0X1111 = 0X3c22 TEST_ASSERT_EQUAL_INT8(4, ld_a_to_longoff_y(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(0X3c22)); }
//Assembly : [shortptr.w] | ld A,[$10.w] // Please refer this instruction in page 46 of stm8 programming manual void test_ld_a_to_shortptr_w(void){ uint8_t instr[] = {0XFB, 0X13}; MEM_WRITE_BYTE(0X13 , 0xAA); MEM_WRITE_BYTE(0X14 , 0xBB); TEST_ASSERT_EQUAL_INT8(3, ld_a_to_shortptr_w(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(0xAABB)); }
//Assembly : [longptr.w] | ld A,[$1000.w] // Please refer this instruction in page 47 of stm8 programming manual void test_ld_a_to_longptr_w(void){ uint8_t instr[] = {0XFB, 0X13, 0X15}; MEM_WRITE_BYTE(0X1315 , 0xAA); MEM_WRITE_BYTE(0X1316 , 0xBB); TEST_ASSERT_EQUAL_INT8(4, ld_a_to_longptr_w(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(0xAABB)); }
void mcu_dec(uint16_t addr){ uint8_t a = MEM_READ_BYTE(addr); uint8_t value = 1 ; uint8_t result = a - value; MEM_WRITE_BYTE( addr, result); UPDATE_Z_N_FLAG(result); V = (A7 & M7 | M7 & _R7 | _R7 & A7) ^ ( A6 & M6 | M6 & _R6 | _R6 & A6 ); }
//Assembly : ([shortptr.w],Y) ld A,([$10.w],Y) // Please refer this instruction in page 50 of stm8 programming manual void test_ld_a_to_shortptr_w_y(void){ SET_Y(0X0011); uint8_t instr[] = {0XFB, 0X13}; MEM_WRITE_BYTE(0X13 , 0x11); MEM_WRITE_BYTE(0X14 , 0x11); // 0X1111 + 0X11 = 0X1122 TEST_ASSERT_EQUAL_INT8(3, ld_a_to_shortptr_w_y(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(0X1122)); }
// Assembly : ([longptr.w],X) | ld A,([$1000.w],X) // Please refer this instruction in page 50 of stm8 programming manual void test_ld_a_to_longptr_w_x(void){ SET_X(0X0011); uint8_t instr[] = {0XFB, 0X13, 0X00}; MEM_WRITE_BYTE(0X1300 , 0xAA); MEM_WRITE_BYTE(0X1301 , 0xBB); // 0XAABB + 0X11 = 0XAACC TEST_ASSERT_EQUAL_INT8(4, ld_a_to_longptr_w_x(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(0XAACC)); }
/** overflow occur when sum of 2 positive number and get negative number, */ void test_mcu_inc_set_V_flag(void){ MEM_WRITE_BYTE(0x1133,0x7F); mcu_inc(0x1133); TEST_ASSERT_EQUAL_INT8(0x80, MEM_READ_BYTE(0x1133)); TEST_ASSERT_EQUAL(1, V); // 0x7F(+value) + 0x1(+value) = 0x80(-value) TEST_ASSERT_EQUAL(0, I1); TEST_ASSERT_EQUAL(0, H); TEST_ASSERT_EQUAL(0, I0); TEST_ASSERT_EQUAL(1, N); // bit 7 is 1 TEST_ASSERT_EQUAL(0, Z); TEST_ASSERT_EQUAL(0, C); }
void test_mcu_inc_set_Z_flag(void){ MEM_WRITE_BYTE(0x1133,-1); mcu_inc(0x1133); TEST_ASSERT_EQUAL_INT8(0, MEM_READ_BYTE(0x1133)); TEST_ASSERT_EQUAL(0, V); TEST_ASSERT_EQUAL(0, I1); TEST_ASSERT_EQUAL(0, H); TEST_ASSERT_EQUAL(0, I0); TEST_ASSERT_EQUAL(0, N); TEST_ASSERT_EQUAL(1, Z); TEST_ASSERT_EQUAL(0, C); }
void test_mcu_inc_set_incative_flag_carry_flag(void){ MEM_WRITE_BYTE(0x1133 ,0x81); mcu_inc(0x1133); TEST_ASSERT_EQUAL_INT8(0x82, MEM_READ_BYTE(0x1133)); TEST_ASSERT_EQUAL(0, V); TEST_ASSERT_EQUAL(0, I1); TEST_ASSERT_EQUAL(0, H); TEST_ASSERT_EQUAL(0, I0); TEST_ASSERT_EQUAL(1, N); // bit 7 is 1 TEST_ASSERT_EQUAL(0, Z); TEST_ASSERT_EQUAL(0, C); }
/* generic memory access function, it's safe because alignments and permissions are checked, handles any natural transfer sizes; note, faults out if nbytes is not a power-of-two or larger then MD_PAGE_SIZE */ enum md_fault_type mem_access(struct mem_t *mem, /* memory space to access */ enum mem_cmd cmd, /* Read (from sim mem) or Write */ md_addr_t addr, /* target address to access */ void *vp, /* host memory address to access */ int nbytes) /* number of bytes to access */ { byte_t *p = vp; /* check alignments */ if (/* check size */(nbytes & (nbytes-1)) != 0 || /* check max size */nbytes > MD_PAGE_SIZE) return md_fault_access; if (/* check natural alignment */(addr & (nbytes-1)) != 0) return md_fault_alignment; /* perform the copy */ switch (nbytes) { case 1: if (cmd == Read) *((byte_t *)p) = MEM_READ_BYTE(mem, addr); else MEM_WRITE_BYTE(mem, addr, *((byte_t *)p)); break; case 2: if (cmd == Read) *((half_t *)p) = MEM_READ_HALF(mem, addr); else MEM_WRITE_HALF(mem, addr, *((half_t *)p)); break; case 4: if (cmd == Read) *((word_t *)p) = MEM_READ_WORD(mem, addr); else MEM_WRITE_WORD(mem, addr, *((word_t *)p)); break; #ifdef HOST_HAS_QUAD case 8: if (cmd == Read) *((quad_t *)p) = MEM_READ_QUAD(mem, addr); else MEM_WRITE_QUAD(mem, addr, *((quad_t *)p)); break; #endif /* HOST_HAS_QUAD */ default: { /* nbytes >= 8/16 and power of two */ unsigned words = nbytes >> 2; if (cmd == Read) { while (words-- > 0) { *((word_t *)p) = MEM_READ_WORD(mem, addr); p += sizeof(word_t); addr += sizeof(word_t); } } else { while (words-- > 0) { MEM_WRITE_WORD(mem, addr, *((word_t *)p)); p += sizeof(word_t); addr += sizeof(word_t); } } } break; } /* no fault... */ return md_fault_none; }
uint8_t mcu_pop(void){ sp_increment(); uint8_t value = MEM_READ_BYTE(SP); return value; }