//##########+++ Decode Format III Instructions +++########## //# Format III are double operand of the form: //# [CCCC][SSSS][ABaa][DDDD] //# //# Where C = Opcode, B = Byte/Word flag, //# A = Addressing mode for destination //# a = Addressing mode for source //# S = Source, D = Destination //######################################################## void decode_formatIII( unsigned short instruction ){ unsigned char opcode = ( instruction & 0xF000 ) >> 12; unsigned char source = ( instruction & 0x0F00 ) >> 8; unsigned char as_flag = (instruction & 0x0030 ) >> 4; unsigned char destination = ( instruction & 0x000F ); unsigned char ad_flag = (instruction & 0x0080 ) >> 7; unsigned char bw_flag = (instruction & 0x0040 ) >> 6; char source_reg[10], dest_reg[10]; printf("Source: %04X\nas_flag: %02X\nDest: %04X\nad_flag: %X\nbw_flag: %X\n", source, as_flag, destination, ad_flag, bw_flag); switch( opcode ){ //# MOV source to destination case 0x4:{ bw_flag == 0 ? printf("MOV ") : printf("MOV.B "); //# Both operands are register contents if( as_flag == 0 && ad_flag == 0 ){ reg_num_to_name(source, source_reg); reg_num_to_name(destination, dest_reg); printf("%s, %s\n", source_reg, dest_reg); short *source_reg = get_reg_ptr(source); short *dest_reg = get_reg_ptr(destination); *dest_reg = *source_reg; break; } //# Indexed mode X(Rn) (Rn+X) points to the operand //# X is stored in the next word else if( as_flag == 1 && ad_flag == 1 ){ unsigned short source_offset, dest_offset; reg_num_to_name(source, source_reg); reg_num_to_name(destination, dest_reg); source_offset = fetch(); dest_offset = fetch(); printf("0x%04X(%s), 0x%04X(%s)\n", source_offset, source_reg, dest_offset, dest_reg); break; } //# Indexed mode for only source operand else if( as_flag == 1 && ad_flag == 0 ){ unsigned short source_offset, source_contents; unsigned short* source_ptr; short* dest_ptr; reg_num_to_name(source, source_reg); reg_num_to_name(destination, dest_reg); source_offset = fetch(); printf("0x%04X(%s), %s\n", source_offset, source_reg, dest_reg); source_ptr = get_reg_ptr(source); dest_ptr = get_reg_ptr(destination); source_contents = *source_ptr; printf("Got contents 0x%04X\n", source_contents + source_offset); void* addr = (void*)MEMSPACE; addr += (source_contents + source_offset); *dest_ptr = *( (short*)addr ); break; } //# Indexed mode for only destination operand else if( as_flag == 0 && ad_flag == 1 ){ unsigned short dest_offset; reg_num_to_name(source, source_reg); reg_num_to_name(destination, dest_reg); dest_offset = fetch(); printf("%s, 0x%04X(%s)\n", source_reg, dest_offset, dest_reg); break; } //# Constant mode for only source operand else if( as_flag == 3 && ad_flag == 0 ){ short source_const; reg_num_to_name(destination, dest_reg); source_const = fetch(); printf("0x%04X, %s\n", source_const, dest_reg); break; } //# SRC = Constant, DST = Address else if( as_flag == 3 && ad_flag == 1 ){ short source_const; unsigned short dest_addr; source_const = fetch(); dest_addr = fetch(); printf("#0x%04X, &0x%04X\n", source_const, dest_addr); } //# Indirect register mode for only source operand else if( as_flag == 2 && ad_flag == 0 ){ short source_const; reg_num_to_name(destination, dest_reg); reg_num_to_name(source, source_reg); printf("@%s, %s\n", source_reg, dest_reg); break; } break; } //# ADD source to destination case 0x5:{ printf("ADD\n"); break; } //# ADDC Add w/ carry dst += (src+C) case 0x6:{ printf("ADDC\n"); break; } //# SUBC Sub w/carry dst -= (src+C) case 0x7:{ printf("SUBC\n"); break; } //# SUB dst -= src case 0x8:{ printf("SUB\n"); break; } //# CMP compare (dst-src) discard result case 0x9:{ printf("CMP\n"); break; } //# DADD Decimal addition dst += src case 0xA:{ printf("DADD\n"); break; } //# BIT Test bits dst & src, discard result case 0xB:{ printf("BIT\n"); break; } //# BIC, bit clear dest &= ~src case 0xC:{ printf("BIC\n"); break; } //# BIS Bit set - logical OR dest |= src case 0xD:{ printf("BIS\n"); break; } //# XOR, bitwise XOR; dst ^= src case 0xE:{ printf("XOR\n"); break; } //# AND, bitwise AND; dst &= src case 0xF:{ printf("AND\n"); break; } } //# End of switch }
void decode_formatI(Emulator *emu, uint16_t instruction, bool disassemble) { Cpu *cpu = emu->cpu; Debugger *debugger = emu->debugger; uint8_t opcode = (instruction & 0xF000) >> 12; uint8_t source = (instruction & 0x0F00) >> 8; uint8_t as_flag = (instruction & 0x0030) >> 4; uint8_t destination = (instruction & 0x000F); uint8_t ad_flag = (instruction & 0x0080) >> 7; uint8_t bw_flag = (instruction & 0x0040) >> 6; char s_reg_name[10], d_reg_name[10]; char mnemonic[100] = {0}; /* String to show hex value of instruction */ char hex_str[100] = {0}; char hex_str_part[10] = {0}; sprintf(hex_str, "%04X", instruction); /* Source Register pointer */ int16_t *s_reg = get_reg_ptr(emu, source); /* Destination Register pointer */ int16_t *d_reg = get_reg_ptr(emu, destination); reg_num_to_name(source, s_reg_name); /* Get source register name */ reg_num_to_name(destination, d_reg_name); /* Get destination register name */ uint8_t constant_generator_active = 0; /* Specifies if CG1/CG2 active */ int16_t immediate_constant = 0; /* Generated Constant */ /* Spot CG1 and CG2 Constant generator instructions */ if ( (source == 2 && as_flag > 1) || source == 3 ) { constant_generator_active = 1; immediate_constant = run_constant_generator(source, as_flag); } else { constant_generator_active = 0; } /* Identify the nature of instruction operand addressing modes */ int16_t source_value, source_offset; int16_t destination_offset; uint16_t *destination_addr; char asm_operands[20] = {0}, asm_op2[20] = {0}; /* Register - Register; Ex: MOV Rs, Rd */ /* Constant Gen - Register; Ex: MOV #C, Rd */ /* 0 */ if (as_flag == 0 && ad_flag == 0) { if (constant_generator_active) { /* Source Constant */ source_value = immediate_constant; sprintf(asm_operands, "#0x%04X, %s", (uint16_t) source_value, d_reg_name); } else { /* Source register */ source_value = *s_reg; sprintf(asm_operands, "%s, %s", s_reg_name, d_reg_name); } destination_addr = d_reg; /* Destination Register */ if (!disassemble) { bw_flag == BYTE ? *d_reg &= 0x00FF : 0; } } /* Register - Indexed; Ex: MOV Rs, 0x0(Rd) */ /* Register - Symbolic; Ex: MOV Rs, 0xD */ /* Register - Absolute; Ex: MOV Rs, &0xD */ /* Constant Gen - Indexed; Ex: MOV #C, 0x0(Rd) */ /* 0 */ /* Constant Gen - Symbolic; Ex: MOV #C, 0xD */ /* 0 */ /* Constant Gen - Absolute; Ex: MOV #C, &0xD */ /* 0 */ else if (as_flag == 0 && ad_flag == 1) { destination_offset = fetch(emu); sprintf(hex_str_part, "%04X", (uint16_t) destination_offset); strncat(hex_str, hex_str_part, sizeof hex_str); destination_addr = get_addr_ptr(*d_reg + destination_offset); if (constant_generator_active) { /* Source Constant */ source_value = immediate_constant; sprintf(asm_operands, "#0x%04X, ", source_value); } else { /* Source from register */ source_value = *s_reg; sprintf(asm_operands, "%s, ", s_reg_name); } if (destination == 0) { /* Destination Symbolic */ uint16_t virtual_addr = *d_reg + destination_offset - 2; destination_addr = get_addr_ptr(virtual_addr); sprintf(asm_op2, "0x%04X", (uint16_t) virtual_addr); } else if (destination == 2) { /* Destination Absolute */ destination_addr = get_addr_ptr(destination_offset); sprintf(asm_op2, "&0x%04X", (uint16_t) destination_offset); } else { /* Destination Indexed */ sprintf(asm_op2, "0x%04X(%s)", (uint16_t) destination_offset, d_reg_name); } strncat(asm_operands, asm_op2, sizeof asm_op2); } /* Indexed - Register; Ex: MOV 0x0(Rs), Rd */ /* Symbolic - Register; Ex: MOV 0xS, Rd */ /* Absolute - Register; Ex: MOV &0xS, Rd */ /* Constant Gen - Register; Ex: MOV #C, Rd */ /* 1 */ else if (as_flag == 1 && ad_flag == 0) { if (constant_generator_active) { /* Source Constant */ source_value = immediate_constant; sprintf(asm_operands, "#0x%04X, %s", source_value, d_reg_name); } else if (source == 0) { /* Source Symbolic */ source_offset = fetch(emu); uint16_t virtual_addr = *s_reg + source_offset - 2; source_value = *get_addr_ptr(virtual_addr); sprintf(hex_str_part, "%04X", (uint16_t) source_offset); strncat(hex_str, hex_str_part, sizeof hex_str); sprintf(asm_operands, "0x%04X, %s", virtual_addr, d_reg_name); } else if (source == 2) { /* Source Absolute */ source_offset = fetch(emu); source_value = *get_addr_ptr(source_offset); sprintf(hex_str_part, "%04X", (uint16_t) source_offset); strncat(hex_str, hex_str_part, sizeof hex_str); sprintf(asm_operands, "&0x%04X, %s", (uint16_t) source_offset, d_reg_name); } else { /* Source Indexed */ source_offset = fetch(emu); source_value = *get_addr_ptr(*s_reg + source_offset); sprintf(hex_str_part, "%04X", (uint16_t) source_offset); strncat(hex_str, hex_str_part, sizeof hex_str); sprintf(asm_operands, "0x%04X(%s), %s", (uint16_t) source_offset, s_reg_name, d_reg_name); } destination_addr = d_reg; /* Destination register */ if (!disassemble) { bw_flag == BYTE ? *d_reg &= 0x00FF : 0; } } /* Indexed - Indexed; Ex: MOV 0x0(Rs), 0x0(Rd) */ /* Symbolic - Indexed; Ex: MOV 0xS, 0x0(Rd) */ /* Indexed - Symbolic; Ex: MOV 0x0(Rd), 0xD */ /* Symbolic - Symbolic; Ex: MOV 0xS, 0xD */ /* Absolute - Indexed; Ex: MOV &0xS, 0x0(Rd) */ /* Indexed - Absolute; Ex: MOV 0x0(Rs), &0xD */ /* Absolute - Absolute; Ex: MOV &0xS, &0xD */ /* Absolute - Symbolic; Ex: MOV &0xS, 0xD */ /* Symbolic - Absolute; Ex: MOV 0xS, &0xD */ /* Constant Gen - Indexed; Ex: MOV #C, 0x0(Rd) */ /* 1 */ /* Constant Gen - Symbolic; Ex: MOV #C, 0xD */ /* 1 */ /* Constant Gen - Absolute; Ex: MOV #C, &0xD */ /* 1 */ else if (as_flag == 1 && ad_flag == 1) { if (constant_generator_active) { /* Source Constant */ source_value = immediate_constant; sprintf(asm_operands, "#0x%04X, ", source_value); } else if (source == 0) { /* Source Symbolic */ source_offset = fetch(emu); uint16_t virtual_addr = cpu->pc + source_offset - 4; source_value = *get_addr_ptr(virtual_addr); sprintf(hex_str_part, "%04X", (uint16_t) source_offset); strncat(hex_str, hex_str_part, sizeof hex_str); sprintf(asm_operands, "0x%04X, ", virtual_addr); } else if (source == 2) { /* Source Absolute */ source_offset = fetch(emu); source_value = *get_addr_ptr(source_offset); sprintf(hex_str_part, "%04X", (uint16_t) source_offset); strncat(hex_str, hex_str_part, sizeof hex_str); sprintf(asm_operands, "&0x%04X, ", (uint16_t) source_offset); } else { /* Source Indexed */ source_offset = fetch(emu); source_value = *get_addr_ptr(*s_reg + source_offset); sprintf(hex_str_part, "%04X", (uint16_t)source_offset); strncat(hex_str, hex_str_part, sizeof hex_str); sprintf(asm_operands, "0x%04X(%s), ", (uint16_t) source_offset, s_reg_name); } destination_offset = fetch(emu); sprintf(hex_str_part, "%04X", (uint16_t) destination_offset); strncat(hex_str, hex_str_part, sizeof hex_str); if (destination == 0) { /* Destination Symbolic */ uint16_t virtual_addr = cpu->pc + destination_offset - 2; destination_addr = get_addr_ptr(virtual_addr); sprintf(asm_op2, "0x%04X", virtual_addr); } else if (destination == 2) { /* Destination Absolute */ destination_addr = get_addr_ptr(destination_offset); sprintf(asm_op2, "&0x%04X", (uint16_t) destination_offset); } else { /* Destination indexed */ destination_addr = get_addr_ptr(*d_reg + destination_offset); sprintf(asm_op2, "0x%04X(%s)", (uint16_t)destination_offset, d_reg_name); } strncat(asm_operands, asm_op2, sizeof asm_op2); } /* Indirect - Register; Ex: MOV @Rs, Rd */ /* Constant Gen - Register; Ex: MOV #C, Rd */ /* 2, 4 */ else if (as_flag == 2 && ad_flag == 0) { if (constant_generator_active) { /* Source Constant */ source_value = immediate_constant; sprintf(asm_operands, "#0x%04X, %s", immediate_constant, d_reg_name); } else { /* Source Indirect */ source_value = *get_addr_ptr(*s_reg); sprintf(asm_operands, "@%s, %s", s_reg_name, d_reg_name); } destination_addr = d_reg; /* Destination Register */ if (!disassemble) { bw_flag == BYTE ? *d_reg &= 0x00FF : 0; } } /* Indirect - Indexed; Ex: MOV @Rs, 0x0(Rd) */ /* Indirect - Symbolic; Ex: MOV @Rs, 0xD */ /* Indirect - Absolute; Ex: MOV @Rs, &0xD */ /* Constant Gen - Indexed; Ex: MOV #C, 0x0(Rd) */ /* 2, 4 */ /* Constant Gen - Symbolic; Ex: MOV #C, 0xD */ /* 2, 4 */ /* Constant Gen - Absolute; Ex: MOV #C, &0xD */ /* 2, 4 */ else if (as_flag == 2 && ad_flag == 1) { destination_offset = fetch(emu); sprintf(hex_str_part, "%04X", (uint16_t) destination_offset); strncat(hex_str, hex_str_part, sizeof hex_str); if (constant_generator_active) { /* Source Constant */ source_value = immediate_constant; sprintf(asm_operands, "#0x%04X, ", source_value); } else { /* Source Indirect */ source_value = *get_addr_ptr(*s_reg); sprintf(asm_operands, "@%s, ", s_reg_name); } if (destination == 0) { /* Destination Symbolic */ uint16_t virtual_addr = cpu->pc + destination_offset - 2; destination_addr = get_addr_ptr(virtual_addr); sprintf(asm_op2, "0x%04X", virtual_addr); } else if (destination == 2) { /* Destination Absolute */ destination_addr = get_addr_ptr(destination_offset); sprintf(asm_op2, "&0x%04X", destination_offset); } else { /* Destination Indexed */ destination_addr = get_addr_ptr(*d_reg + destination_offset); sprintf(asm_op2, "0x%04X(%s)", (uint16_t)destination_offset, d_reg_name); } strncat(asm_operands, asm_op2, sizeof asm_op2); } /* Indirect Inc - Register; Ex: MOV @Rs+, Rd */ /* Immediate - Register; Ex: MOV #S, Rd */ /* Constant Gen - Register; Ex: MOV #C, Rd */ /* -1, 8 */ else if (as_flag == 3 && ad_flag == 0) { if (constant_generator_active) { /* Source Constant */ source_value = immediate_constant; sprintf(asm_operands, "#0x%04X, %s", (uint16_t) source_value, d_reg_name); } else if (source == 0) { /* Source Immediate */ source_value = fetch(emu); sprintf(hex_str_part, "%04X", (uint16_t) source_value); strncat(hex_str, hex_str_part, sizeof hex_str); if (bw_flag == WORD) { sprintf(asm_operands, "#0x%04X, %s", (uint16_t) source_value, d_reg_name); } else if (bw_flag == BYTE) { sprintf(asm_operands, "#0x%04X, %s", (uint8_t) source_value, d_reg_name); } } else { /* Source Indirect AutoIncrement */ source_value = *get_addr_ptr(*s_reg); sprintf(asm_operands, "@%s+, %s", s_reg_name, d_reg_name); if (!disassemble) { bw_flag == WORD ? *s_reg += 2 : (*s_reg += 1); } } destination_addr = d_reg; /* Destination Register */ if (!disassemble) { bw_flag == BYTE ? *d_reg &= 0x00FF : 0; } } /* Indirect Inc - Indexed; Ex: MOV @Rs+, 0x0(Rd) */ /* Indirect Inc - Symbolic; Ex: MOV @Rs+, 0xD */ /* Indirect Inc - Absolute; Ex: MOV @Rs+, &0xD */ /* Immediate - Indexed; Ex: MOV #S, 0x0(Rd) */ /* Immediate - Symbolic; Ex: MOV #S, 0xD */ /* Immediate - Absolute; Ex: MOV #S, &0xD */ /* Constant Gen - Indexed; Ex: MOV #C, 0x0(Rd) */ /* -1, 8 */ /* Constant Gen - Symbolic; Ex: MOV #C, 0xD */ /* -1, 8 */ /* Constant Gen - Absolute; Ex: MOV #C, &0xD */ /* -1, 8 */ else if (as_flag == 3 && ad_flag == 1) { if (constant_generator_active) { /* Source Constant */ source_value = immediate_constant; sprintf(asm_operands, "#0x%04X, ", (uint16_t)source_value); } else if (source == 0) { /* Source Immediate */ source_value = fetch(emu); sprintf(hex_str_part, "%04X", (uint16_t) source_value); strncat(hex_str, hex_str_part, sizeof hex_str); sprintf(asm_operands, "#0x%04X, ", (uint16_t)source_value); } else { /* Source Indirect Auto Increment */ source_value = *get_addr_ptr(*s_reg); sprintf(asm_operands, "@%s+, ", s_reg_name); if (!disassemble) { bw_flag == WORD ? *s_reg += 2 : (*s_reg += 1); } } destination_offset = fetch(emu); sprintf(hex_str_part, "%04X", (uint16_t) destination_offset); strncat(hex_str, hex_str_part, sizeof hex_str); if (destination == 0) { /* Destination Symbolic */ uint16_t virtual_addr = cpu->pc + destination_offset - 2; destination_addr = get_addr_ptr(virtual_addr); sprintf(asm_op2, "0x%04X", virtual_addr); } else if (destination == 2) { /* Destination Absolute */ destination_addr = get_addr_ptr(destination_offset); sprintf(asm_op2, "&0x%04X", (uint16_t) destination_offset); } else { /* Destination Indexed */ destination_addr = get_addr_ptr(*d_reg + destination_offset); sprintf(asm_op2, "0x%04X(%s)", (uint16_t) destination_offset, d_reg_name); } strncat(asm_operands, asm_op2, sizeof asm_op2); } if (!disassemble) { switch (opcode) { /* MOV SOURCE, DESTINATION * Ex: MOV #4, R6 * * SOURCE = DESTINATION * * The source operand is moved to the destination. The source operand is * not affected. The previous contents of the destination are lost. * */ case 0x4: { if (bw_flag == WORD) { *destination_addr = source_value; } else if (bw_flag == BYTE) { *((uint8_t *) destination_addr) = (uint8_t) source_value; } break; } /* ADD SOURCE, DESTINATION * Ex: ADD R5, R4 * * The source operand is added to the destination operand. The source op * is not affected. The previous contents of the destination are lost. * * DESTINATION = SOURCE + DESTINATION * * N: Set if result is negative, reset if positive * Z: Set if result is zero, reset otherwise * C: Set if there is a carry from the result, cleared if not * V: Set if an arithmetic overflow occurs, otherwise reset * */ case 0x5:{ uint16_t original_dst_value = *destination_addr; if (bw_flag == WORD) { *destination_addr += source_value; } else if (bw_flag == BYTE) { *((uint8_t *) destination_addr) += (uint8_t) source_value; } cpu->sr.zero = is_zero(destination_addr, bw_flag); cpu->sr.negative = is_negative(destination_addr, bw_flag); cpu->sr.carry = is_carried(original_dst_value, source_value, bw_flag); cpu->sr.overflow = is_overflowed(source_value, original_dst_value, destination_addr, bw_flag); break; } /* ADDC SOURCE, DESTINATION * Ex: ADDC R5, R4 * * DESTINATION += (SOURCE + C) * * N: Set if result is negative, reset if positive * Z: Set if result is zero, reset otherwise * C: Set if there is a carry from the result, cleared if not * V: Set if an arithmetic overflow occurs, otherwise reset * */ case 0x6:{ uint16_t original_dst_value = *destination_addr; if (bw_flag == WORD) { *destination_addr += source_value + cpu->sr.carry; } else if (bw_flag == BYTE) { *((uint8_t *) destination_addr) += (uint8_t) source_value + cpu->sr.carry; } cpu->sr.zero = is_zero(destination_addr, bw_flag); cpu->sr.negative = is_negative(destination_addr, bw_flag); cpu->sr.carry = is_carried(original_dst_value, source_value, bw_flag); cpu->sr.overflow = is_overflowed(source_value, original_dst_value, destination_addr, bw_flag); break; } /* SUBC SOURCE, DESTINATION * Ex: SUB R4, R5 * * DST += ~SRC + C * * N: Set if result is negative, reset if positive * Z: Set if result is zero, reset otherwise * C: Set if there is a carry from the MSB of the result, reset otherwise. * Set to 1 if no borrow, reset if borrow. * V: Set if an arithmetic overflow occurs, otherwise reset * * */ case 0x7:{ int16_t original_dst_value = *destination_addr; source_value = ~source_value; /* 1's comp */ if (bw_flag == WORD) { *(int16_t *)destination_addr += source_value + cpu->sr.carry; } else if (bw_flag == BYTE) { *(int8_t *)destination_addr += (int8_t) source_value + cpu->sr.carry; } cpu->sr.zero = is_zero(destination_addr, bw_flag); cpu->sr.negative = is_negative(destination_addr, bw_flag); cpu->sr.carry = is_carried(original_dst_value, source_value, bw_flag); cpu->sr.overflow = is_overflowed(source_value, original_dst_value, destination_addr, bw_flag); break; } /* SUB SOURCE, DESTINATION * Ex: SUB R4, R5 * * DST -= SRC * * N: Set if result is negative, reset if positive * Z: Set if result is zero, reset otherwise * C: Set if there is a carry from the MSB of the result, reset otherwise. * Set to 1 if no borrow, reset if borrow. * V: Set if an arithmetic overflow occurs, otherwise reset * TODO: SUBTRACTION OVERFLOW FLAG ERROR */ case 0x8:{ int16_t original_dst_value = *destination_addr; source_value = ~source_value + 1; if (bw_flag == WORD) { *(uint16_t *)destination_addr += source_value; } else if (bw_flag == BYTE) { *(uint8_t *)destination_addr += (uint8_t) source_value; } cpu->sr.zero = is_zero(destination_addr, bw_flag); cpu->sr.negative = is_negative(destination_addr, bw_flag); if ( is_carried(~source_value, 1, bw_flag) || is_carried(original_dst_value, source_value, bw_flag) ) { cpu->sr.carry = true; } cpu->sr.overflow = is_overflowed(source_value, original_dst_value, destination_addr, bw_flag); break; } /* CMP SOURCE, DESTINATION * * N: Set if result is negative, reset if positive (src ≥ dst) * Z: Set if result is zero, reset otherwise (src = dst) * C: Set if there is a carry from the MSB of the result, reset otherwise * V: Set if an arithmetic overflow occurs, otherwise reset * TODO: Fix overflow error */ case 0x9:{ int16_t original_dst_value = *destination_addr; uint16_t unsigned_source_value = ((uint16_t)~source_value + 1); int16_t result; bool early_carry = is_carried((uint16_t)~source_value, 1, bw_flag); if (bw_flag == WORD) { result = *destination_addr + (uint16_t) unsigned_source_value; } else if (bw_flag == BYTE) { result = *(uint8_t *)destination_addr + (uint8_t)unsigned_source_value; } cpu->sr.negative = is_negative(&result, bw_flag); cpu->sr.zero = is_zero(&result, bw_flag); /* Check if the carry happens durring conversion to 2's comp */ if (! early_carry) { cpu->sr.carry = is_carried(original_dst_value, unsigned_source_value, bw_flag); } else { cpu->sr.carry = true; } cpu->sr.overflow = is_overflowed(unsigned_source_value, original_dst_value, &result, bw_flag); break; } /* DADD SOURCE, DESTINATION * */ case 0xA:{ if (bw_flag == WORD) { } else if (bw_flag == BYTE) { } break; } /* BIT SOURCE, DESTINATION * * N: Set if MSB of result is set, reset otherwise * Z: Set if result is zero, reset otherwise * C: Set if result is not zero, reset otherwise (.NOT. Zero) * V: Reset */ case 0xB:{ if (bw_flag == WORD) { uint16_t result = ((uint16_t) source_value) & (*destination_addr); cpu->sr.zero = (result == 0); cpu->sr.negative = result >> 15; cpu->sr.carry = (result != 0); } else if (bw_flag == BYTE) { uint8_t result = ((uint8_t) source_value) & (*(uint8_t *) destination_addr); cpu->sr.zero = (result == 0); cpu->sr.negative = result >> 7; cpu->sr.carry = (result != 0); } cpu->sr.overflow = false; break; }