mirror of
				https://github.com/TomHarte/CLK.git
				synced 2025-10-31 20:16:07 +00:00 
			
		
		
		
	Name flags, remove closing underscores on exposed data fields.
This commit is contained in:
		| @@ -43,7 +43,7 @@ void Executor<model, BusHandler>::reset_processor() { | |||||||
| template <Model model, typename BusHandler> | template <Model model, typename BusHandler> | ||||||
| template <typename IntT> | template <typename IntT> | ||||||
| IntT Executor<model, BusHandler>::read(uint32_t address, bool is_from_pc) { | IntT Executor<model, BusHandler>::read(uint32_t address, bool is_from_pc) { | ||||||
| 	const auto code = FunctionCode((status_.is_supervisor_ << 2) | 1 << int(is_from_pc)); | 	const auto code = FunctionCode((status_.is_supervisor << 2) | 1 << int(is_from_pc)); | ||||||
| 	if(model == Model::M68000 && sizeof(IntT) > 1 && address & 1) { | 	if(model == Model::M68000 && sizeof(IntT) > 1 && address & 1) { | ||||||
| 		throw AccessException(code, address, Exception::AddressError | (int(is_from_pc) << 3) | (1 << 4)); | 		throw AccessException(code, address, Exception::AddressError | (int(is_from_pc) << 3) | (1 << 4)); | ||||||
| 	} | 	} | ||||||
| @@ -55,7 +55,7 @@ IntT Executor<model, BusHandler>::read(uint32_t address, bool is_from_pc) { | |||||||
| template <Model model, typename BusHandler> | template <Model model, typename BusHandler> | ||||||
| template <typename IntT> | template <typename IntT> | ||||||
| void Executor<model, BusHandler>::write(uint32_t address, IntT value) { | void Executor<model, BusHandler>::write(uint32_t address, IntT value) { | ||||||
| 	const auto code = FunctionCode((status_.is_supervisor_ << 2) | 1); | 	const auto code = FunctionCode((status_.is_supervisor << 2) | 1); | ||||||
| 	if(model == Model::M68000 && sizeof(IntT) > 1 && address & 1) { | 	if(model == Model::M68000 && sizeof(IntT) > 1 && address & 1) { | ||||||
| 		throw AccessException(code, address, Exception::AddressError); | 		throw AccessException(code, address, Exception::AddressError); | ||||||
| 	} | 	} | ||||||
| @@ -240,8 +240,8 @@ void Executor<model, BusHandler>::run_for_instructions(int count) { | |||||||
|  |  | ||||||
| 			// Grab the status to store, then switch into supervisor mode. | 			// Grab the status to store, then switch into supervisor mode. | ||||||
| 			const uint16_t status = status_.status(); | 			const uint16_t status = status_.status(); | ||||||
| 			status_.is_supervisor_ = 1; | 			status_.is_supervisor = 1; | ||||||
| 			status_.trace_flag_ = 0; | 			status_.trace_flag = 0; | ||||||
| 			did_update_status(); | 			did_update_status(); | ||||||
|  |  | ||||||
| 			// Push status and the program counter at instruction start. | 			// Push status and the program counter at instruction start. | ||||||
| @@ -271,14 +271,14 @@ void Executor<model, BusHandler>::run(int &count) { | |||||||
|  |  | ||||||
| 		// Capture the trace bit, indicating whether to trace | 		// Capture the trace bit, indicating whether to trace | ||||||
| 		// after this instruction. | 		// after this instruction. | ||||||
| 		const auto should_trace = status_.trace_flag_; | 		const auto should_trace = status_.trace_flag; | ||||||
|  |  | ||||||
| 		// Read the next instruction. | 		// Read the next instruction. | ||||||
| 		instruction_address_ = program_counter_.l; | 		instruction_address_ = program_counter_.l; | ||||||
| 		instruction_opcode_ = read_pc<uint16_t>(); | 		instruction_opcode_ = read_pc<uint16_t>(); | ||||||
| 		const Preinstruction instruction = decoder_.decode(instruction_opcode_); | 		const Preinstruction instruction = decoder_.decode(instruction_opcode_); | ||||||
|  |  | ||||||
| 		if(!status_.is_supervisor_ && instruction.requires_supervisor()) { | 		if(!status_.is_supervisor && instruction.requires_supervisor()) { | ||||||
| 			raise_exception(Exception::PrivilegeViolation); | 			raise_exception(Exception::PrivilegeViolation); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| @@ -369,7 +369,7 @@ typename Executor<model, BusHandler>::Registers Executor<model, BusHandler>::get | |||||||
| 	result.status = status_.status(); | 	result.status = status_.status(); | ||||||
| 	result.program_counter = program_counter_.l; | 	result.program_counter = program_counter_.l; | ||||||
|  |  | ||||||
| 	stack_pointers_[status_.is_supervisor_] = sp; | 	stack_pointers_[status_.is_supervisor] = sp; | ||||||
| 	result.user_stack_pointer = stack_pointers_[0].l; | 	result.user_stack_pointer = stack_pointers_[0].l; | ||||||
| 	result.supervisor_stack_pointer = stack_pointers_[1].l; | 	result.supervisor_stack_pointer = stack_pointers_[1].l; | ||||||
|  |  | ||||||
| @@ -389,7 +389,7 @@ void Executor<model, BusHandler>::set_state(const Registers &state) { | |||||||
|  |  | ||||||
| 	stack_pointers_[0].l = state.user_stack_pointer; | 	stack_pointers_[0].l = state.user_stack_pointer; | ||||||
| 	stack_pointers_[1].l = state.supervisor_stack_pointer; | 	stack_pointers_[1].l = state.supervisor_stack_pointer; | ||||||
| 	sp = stack_pointers_[status_.is_supervisor_]; | 	sp = stack_pointers_[status_.is_supervisor]; | ||||||
| } | } | ||||||
|  |  | ||||||
| // MARK: - Flow Control. | // MARK: - Flow Control. | ||||||
| @@ -402,8 +402,8 @@ void Executor<model, BusHandler>::raise_exception(int index) { | |||||||
| 	// Grab the status to store, then switch into supervisor mode | 	// Grab the status to store, then switch into supervisor mode | ||||||
| 	// and disable tracing. | 	// and disable tracing. | ||||||
| 	const uint16_t status = status_.status(); | 	const uint16_t status = status_.status(); | ||||||
| 	status_.is_supervisor_ = 1; | 	status_.is_supervisor = 1; | ||||||
| 	status_.trace_flag_ = 0; | 	status_.trace_flag = 0; | ||||||
| 	did_update_status(); | 	did_update_status(); | ||||||
|  |  | ||||||
| 	// Push status and the program counter at instruction start. | 	// Push status and the program counter at instruction start. | ||||||
| @@ -419,8 +419,8 @@ template <Model model, typename BusHandler> | |||||||
| void Executor<model, BusHandler>::did_update_status() { | void Executor<model, BusHandler>::did_update_status() { | ||||||
| 	// Shuffle the stack pointers. | 	// Shuffle the stack pointers. | ||||||
| 	stack_pointers_[active_stack_pointer_] = sp; | 	stack_pointers_[active_stack_pointer_] = sp; | ||||||
| 	sp = stack_pointers_[status_.is_supervisor_]; | 	sp = stack_pointers_[status_.is_supervisor]; | ||||||
| 	active_stack_pointer_ = status_.is_supervisor_; | 	active_stack_pointer_ = status_.is_supervisor; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <Model model, typename BusHandler> | template <Model model, typename BusHandler> | ||||||
| @@ -518,9 +518,9 @@ void Executor<model, BusHandler>::tas(Preinstruction instruction, uint32_t addre | |||||||
| 		Dn(instruction.reg<0>()).b = uint8_t(address | 0x80); | 		Dn(instruction.reg<0>()).b = uint8_t(address | 0x80); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	status_.overflow_flag_ = status_.carry_flag_ = 0; | 	status_.overflow_flag = status_.carry_flag = 0; | ||||||
| 	status_.zero_result_ = value; | 	status_.zero_result = value; | ||||||
| 	status_.negative_flag_ = value & 0x80; | 	status_.negative_flag = value & 0x80; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <Model model, typename BusHandler> | template <Model model, typename BusHandler> | ||||||
|   | |||||||
| @@ -39,17 +39,17 @@ template < | |||||||
| 			const uint8_t destination = dest.b; | 			const uint8_t destination = dest.b; | ||||||
|  |  | ||||||
| 			// Perform the BCD add by evaluating the two nibbles separately. | 			// Perform the BCD add by evaluating the two nibbles separately. | ||||||
| 			const int unadjusted_result = destination + source + (status.extend_flag_ ? 1 : 0); | 			const int unadjusted_result = destination + source + (status.extend_flag ? 1 : 0); | ||||||
| 			int result = (destination & 0xf) + (source & 0xf) + (status.extend_flag_ ? 1 : 0); | 			int result = (destination & 0xf) + (source & 0xf) + (status.extend_flag ? 1 : 0); | ||||||
| 			if(result > 0x09) result += 0x06; | 			if(result > 0x09) result += 0x06; | ||||||
| 			result += (destination & 0xf0) + (source & 0xf0); | 			result += (destination & 0xf0) + (source & 0xf0); | ||||||
| 			if(result > 0x9f) result += 0x60; | 			if(result > 0x9f) result += 0x60; | ||||||
|  |  | ||||||
| 			// Set all flags essentially as if this were normal addition. | 			// Set all flags essentially as if this were normal addition. | ||||||
| 			status.zero_result_ |= result & 0xff; | 			status.zero_result |= result & 0xff; | ||||||
| 			status.extend_flag_ = status.carry_flag_ = uint_fast32_t(result & ~0xff); | 			status.extend_flag = status.carry_flag = uint_fast32_t(result & ~0xff); | ||||||
| 			status.negative_flag_ = result & 0x80; | 			status.negative_flag = result & 0x80; | ||||||
| 			status.overflow_flag_ = ~unadjusted_result & result & 0x80; | 			status.overflow_flag = ~unadjusted_result & result & 0x80; | ||||||
|  |  | ||||||
| 			// Store the result. | 			// Store the result. | ||||||
| 			dest.b = uint8_t(result); | 			dest.b = uint8_t(result); | ||||||
| @@ -66,10 +66,10 @@ template < | |||||||
| 	const auto result = op(destination, source, x);	\ | 	const auto result = op(destination, source, x);	\ | ||||||
| 	\ | 	\ | ||||||
| 	b = uint8_t(result);	\ | 	b = uint8_t(result);	\ | ||||||
| 	zero_op(status.zero_result_, b);	\ | 	zero_op(status.zero_result, b);	\ | ||||||
| 	status.extend_flag_ = status.carry_flag_ = uint_fast32_t(result & ~0xff);	\ | 	status.extend_flag = status.carry_flag = uint_fast32_t(result & ~0xff);	\ | ||||||
| 	status.negative_flag_ = result & 0x80;	\ | 	status.negative_flag = result & 0x80;	\ | ||||||
| 	status.overflow_flag_ = overflow() & 0x80; | 	status.overflow_flag = overflow() & 0x80; | ||||||
|  |  | ||||||
| #define addsubw(a, b, op, overflow, x, zero_op)	\ | #define addsubw(a, b, op, overflow, x, zero_op)	\ | ||||||
| 	const int source = a;	\ | 	const int source = a;	\ | ||||||
| @@ -77,10 +77,10 @@ template < | |||||||
| 	const auto result = op(destination, source, x);	\ | 	const auto result = op(destination, source, x);	\ | ||||||
| 	\ | 	\ | ||||||
| 	b = uint16_t(result);	\ | 	b = uint16_t(result);	\ | ||||||
| 	zero_op(status.zero_result_, b);	\ | 	zero_op(status.zero_result, b);	\ | ||||||
| 	status.extend_flag_ = status.carry_flag_ = uint_fast32_t(result & ~0xffff);	\ | 	status.extend_flag = status.carry_flag = uint_fast32_t(result & ~0xffff);	\ | ||||||
| 	status.negative_flag_ = result & 0x8000;	\ | 	status.negative_flag = result & 0x8000;	\ | ||||||
| 	status.overflow_flag_ = overflow() & 0x8000; | 	status.overflow_flag = overflow() & 0x8000; | ||||||
|  |  | ||||||
| #define addsubl(a, b, op, overflow, x, zero_op)	\ | #define addsubl(a, b, op, overflow, x, zero_op)	\ | ||||||
| 	const uint64_t source = a;	\ | 	const uint64_t source = a;	\ | ||||||
| @@ -88,10 +88,10 @@ template < | |||||||
| 	const auto result = op(destination, source, x);	\ | 	const auto result = op(destination, source, x);	\ | ||||||
| 	\ | 	\ | ||||||
| 	b = uint32_t(result);	\ | 	b = uint32_t(result);	\ | ||||||
| 	zero_op(status.zero_result_, b);	\ | 	zero_op(status.zero_result, b);	\ | ||||||
| 	status.extend_flag_ = status.carry_flag_ = uint_fast32_t(result >> 32);	\ | 	status.extend_flag = status.carry_flag = uint_fast32_t(result >> 32);	\ | ||||||
| 	status.negative_flag_ = result & 0x80000000;	\ | 	status.negative_flag = result & 0x80000000;	\ | ||||||
| 	status.overflow_flag_ = overflow() & 0x80000000; | 	status.overflow_flag = overflow() & 0x80000000; | ||||||
|  |  | ||||||
| #define addb(a, b, x, z) addsubb(a, b, addop, add_overflow, x, z) | #define addb(a, b, x, z) addsubb(a, b, addop, add_overflow, x, z) | ||||||
| #define subb(a, b, x, z) addsubb(a, b, subop, sub_overflow, x, z) | #define subb(a, b, x, z) addsubb(a, b, subop, sub_overflow, x, z) | ||||||
| @@ -101,7 +101,7 @@ template < | |||||||
| #define subl(a, b, x, z) addsubl(a, b, subop, sub_overflow, x, z) | #define subl(a, b, x, z) addsubl(a, b, subop, sub_overflow, x, z) | ||||||
|  |  | ||||||
| #define no_extend(op, a, b)	op(a, b, 0, z_set) | #define no_extend(op, a, b)	op(a, b, 0, z_set) | ||||||
| #define extend(op, a, b)	op(a, b, status.extend_flag_, z_or) | #define extend(op, a, b)	op(a, b, status.extend_flag, z_or) | ||||||
|  |  | ||||||
| 		// ADD and ADDA add two quantities, the latter sign extending and without setting any flags; | 		// ADD and ADDA add two quantities, the latter sign extending and without setting any flags; | ||||||
| 		// ADDQ and SUBQ act as ADD and SUB, but taking the second argument from the instruction code. | 		// ADDQ and SUBQ act as ADD and SUB, but taking the second argument from the instruction code. | ||||||
| @@ -212,13 +212,13 @@ template < | |||||||
| 		// BTST/BCLR/etc: modulo for the mask depends on whether memory or a data register is the target. | 		// BTST/BCLR/etc: modulo for the mask depends on whether memory or a data register is the target. | ||||||
| 		case Operation::BTST: { | 		case Operation::BTST: { | ||||||
| 			const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; | 			const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; | ||||||
| 			status.zero_result_ = dest.l & (1 << (src.l & mask)); | 			status.zero_result = dest.l & (1 << (src.l & mask)); | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		case Operation::BCLR: { | 		case Operation::BCLR: { | ||||||
| 			const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; | 			const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; | ||||||
|  |  | ||||||
| 			status.zero_result_ = dest.l & (1 << (src.l & mask)); | 			status.zero_result = dest.l & (1 << (src.l & mask)); | ||||||
| 			dest.l &= ~(1 << (src.l & mask)); | 			dest.l &= ~(1 << (src.l & mask)); | ||||||
| 			flow_controller.did_bit_op(src.l & mask); | 			flow_controller.did_bit_op(src.l & mask); | ||||||
| 		} break; | 		} break; | ||||||
| @@ -226,7 +226,7 @@ template < | |||||||
| 		case Operation::BCHG: { | 		case Operation::BCHG: { | ||||||
| 			const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; | 			const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; | ||||||
|  |  | ||||||
| 			status.zero_result_ = dest.l & (1 << (src.l & mask)); | 			status.zero_result = dest.l & (1 << (src.l & mask)); | ||||||
| 			dest.l ^= 1 << (src.l & mask); | 			dest.l ^= 1 << (src.l & mask); | ||||||
| 			flow_controller.did_bit_op(src.l & mask); | 			flow_controller.did_bit_op(src.l & mask); | ||||||
| 		} break; | 		} break; | ||||||
| @@ -234,7 +234,7 @@ template < | |||||||
| 		case Operation::BSET: { | 		case Operation::BSET: { | ||||||
| 			const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; | 			const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; | ||||||
|  |  | ||||||
| 			status.zero_result_ = dest.l & (1 << (src.l & mask)); | 			status.zero_result = dest.l & (1 << (src.l & mask)); | ||||||
| 			dest.l |= 1 << (src.l & mask); | 			dest.l |= 1 << (src.l & mask); | ||||||
| 			flow_controller.did_bit_op(src.l & mask); | 			flow_controller.did_bit_op(src.l & mask); | ||||||
| 		} break; | 		} break; | ||||||
| @@ -294,17 +294,17 @@ template < | |||||||
| 		*/ | 		*/ | ||||||
| 		case Operation::CLRb: | 		case Operation::CLRb: | ||||||
| 			src.b = 0; | 			src.b = 0; | ||||||
| 			status.negative_flag_ = status.overflow_flag_ = status.carry_flag_ = status.zero_result_ = 0; | 			status.negative_flag = status.overflow_flag = status.carry_flag = status.zero_result = 0; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::CLRw: | 		case Operation::CLRw: | ||||||
| 			src.w = 0; | 			src.w = 0; | ||||||
| 			status.negative_flag_ = status.overflow_flag_ = status.carry_flag_ = status.zero_result_ = 0; | 			status.negative_flag = status.overflow_flag = status.carry_flag = status.zero_result = 0; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::CLRl: | 		case Operation::CLRl: | ||||||
| 			src.l = 0; | 			src.l = 0; | ||||||
| 			status.negative_flag_ = status.overflow_flag_ = status.carry_flag_ = status.zero_result_ = 0; | 			status.negative_flag = status.overflow_flag = status.carry_flag = status.zero_result = 0; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		/* | 		/* | ||||||
| @@ -316,10 +316,10 @@ template < | |||||||
| 			const uint8_t destination = dest.b; | 			const uint8_t destination = dest.b; | ||||||
| 			const int result = destination - source; | 			const int result = destination - source; | ||||||
|  |  | ||||||
| 			status.zero_result_ = result & 0xff; | 			status.zero_result = result & 0xff; | ||||||
| 			status.carry_flag_ = decltype(status.carry_flag_)(result & ~0xff); | 			status.carry_flag = decltype(status.carry_flag)(result & ~0xff); | ||||||
| 			status.negative_flag_ = result & 0x80; | 			status.negative_flag = result & 0x80; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x80; | 			status.overflow_flag = sub_overflow() & 0x80; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		case Operation::CMPw: { | 		case Operation::CMPw: { | ||||||
| @@ -327,10 +327,10 @@ template < | |||||||
| 			const uint16_t destination = dest.w; | 			const uint16_t destination = dest.w; | ||||||
| 			const int result = destination - source; | 			const int result = destination - source; | ||||||
|  |  | ||||||
| 			status.zero_result_ = result & 0xffff; | 			status.zero_result = result & 0xffff; | ||||||
| 			status.carry_flag_ = decltype(status.carry_flag_)(result & ~0xffff); | 			status.carry_flag = decltype(status.carry_flag)(result & ~0xffff); | ||||||
| 			status.negative_flag_ = result & 0x8000; | 			status.negative_flag = result & 0x8000; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x8000; | 			status.overflow_flag = sub_overflow() & 0x8000; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		case Operation::CMPAw: { | 		case Operation::CMPAw: { | ||||||
| @@ -338,10 +338,10 @@ template < | |||||||
| 			const uint64_t destination = dest.l; | 			const uint64_t destination = dest.l; | ||||||
| 			const auto result = destination - source; | 			const auto result = destination - source; | ||||||
|  |  | ||||||
| 			status.zero_result_ = uint32_t(result); | 			status.zero_result = uint32_t(result); | ||||||
| 			status.carry_flag_ = result >> 32; | 			status.carry_flag = result >> 32; | ||||||
| 			status.negative_flag_ = result & 0x80000000; | 			status.negative_flag = result & 0x80000000; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x80000000; | 			status.overflow_flag = sub_overflow() & 0x80000000; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		// TODO: is there any benefit to keeping both of these? | 		// TODO: is there any benefit to keeping both of these? | ||||||
| @@ -351,10 +351,10 @@ template < | |||||||
| 			const auto destination = uint64_t(dest.l); | 			const auto destination = uint64_t(dest.l); | ||||||
| 			const auto result = destination - source; | 			const auto result = destination - source; | ||||||
|  |  | ||||||
| 			status.zero_result_ = uint32_t(result); | 			status.zero_result = uint32_t(result); | ||||||
| 			status.carry_flag_ = result >> 32; | 			status.carry_flag = result >> 32; | ||||||
| 			status.negative_flag_ = result & 0x80000000; | 			status.negative_flag = result & 0x80000000; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x80000000; | 			status.overflow_flag = sub_overflow() & 0x80000000; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		// JMP: copies EA(0) to the program counter. | 		// JMP: copies EA(0) to the program counter. | ||||||
| @@ -372,21 +372,21 @@ template < | |||||||
| 			and set negative, zero, overflow and carry as appropriate. | 			and set negative, zero, overflow and carry as appropriate. | ||||||
| 		*/ | 		*/ | ||||||
| 		case Operation::MOVEb: | 		case Operation::MOVEb: | ||||||
| 			status.zero_result_ = dest.b = src.b; | 			status.zero_result = dest.b = src.b; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x80; | 			status.negative_flag = status.zero_result & 0x80; | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::MOVEw: | 		case Operation::MOVEw: | ||||||
| 			status.zero_result_ = dest.w = src.w; | 			status.zero_result = dest.w = src.w; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x8000; | 			status.negative_flag = status.zero_result & 0x8000; | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::MOVEl: | 		case Operation::MOVEl: | ||||||
| 			status.zero_result_ = dest.l = src.l; | 			status.zero_result = dest.l = src.l; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x80000000; | 			status.negative_flag = status.zero_result & 0x80000000; | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		/* | 		/* | ||||||
| @@ -437,16 +437,16 @@ template < | |||||||
|  |  | ||||||
| 		case Operation::EXTbtow: | 		case Operation::EXTbtow: | ||||||
| 			src.w = uint16_t(int8_t(src.b)); | 			src.w = uint16_t(int8_t(src.b)); | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 			status.zero_result_ = src.w; | 			status.zero_result = src.w; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x8000; | 			status.negative_flag = status.zero_result & 0x8000; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::EXTwtol: | 		case Operation::EXTwtol: | ||||||
| 			src.l = u_extend16(src.w); | 			src.l = u_extend16(src.w); | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 			status.zero_result_ = src.l; | 			status.zero_result = src.l; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x80000000; | 			status.negative_flag = status.zero_result & 0x80000000; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| #define and_op(a, b) a &= b | #define and_op(a, b) a &= b | ||||||
| @@ -488,18 +488,18 @@ template < | |||||||
|  |  | ||||||
| 		case Operation::MULU: | 		case Operation::MULU: | ||||||
| 			dest.l = dest.w * src.w; | 			dest.l = dest.w * src.w; | ||||||
| 			status.carry_flag_ = status.overflow_flag_ = 0; | 			status.carry_flag = status.overflow_flag = 0; | ||||||
| 			status.zero_result_ = dest.l; | 			status.zero_result = dest.l; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x80000000; | 			status.negative_flag = status.zero_result & 0x80000000; | ||||||
| 			flow_controller.did_mulu(src.w); | 			flow_controller.did_mulu(src.w); | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::MULS: | 		case Operation::MULS: | ||||||
| 			dest.l = | 			dest.l = | ||||||
| 				u_extend16(dest.w) * u_extend16(src.w); | 				u_extend16(dest.w) * u_extend16(src.w); | ||||||
| 			status.carry_flag_ = status.overflow_flag_ = 0; | 			status.carry_flag = status.overflow_flag = 0; | ||||||
| 			status.zero_result_ = dest.l; | 			status.zero_result = dest.l; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x80000000; | 			status.negative_flag = status.zero_result & 0x80000000; | ||||||
| 			flow_controller.did_muls(src.w); | 			flow_controller.did_muls(src.w); | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -508,12 +508,12 @@ template < | |||||||
| 		*/ | 		*/ | ||||||
|  |  | ||||||
| #define announce_divide_by_zero()									\ | #define announce_divide_by_zero()									\ | ||||||
| 	status.negative_flag_ = status.overflow_flag_ = 0;				\ | 	status.negative_flag = status.overflow_flag = 0;				\ | ||||||
| 	status.zero_result_ = 1;										\ | 	status.zero_result = 1;											\ | ||||||
| 	flow_controller.raise_exception(Exception::IntegerDivideByZero) | 	flow_controller.raise_exception(Exception::IntegerDivideByZero) | ||||||
|  |  | ||||||
| 		case Operation::DIVU: { | 		case Operation::DIVU: { | ||||||
| 			status.carry_flag_ = 0; | 			status.carry_flag = 0; | ||||||
|  |  | ||||||
| 			// An attempt to divide by zero schedules an exception. | 			// An attempt to divide by zero schedules an exception. | ||||||
| 			if(!src.w) { | 			if(!src.w) { | ||||||
| @@ -528,7 +528,7 @@ template < | |||||||
|  |  | ||||||
| 			// If overflow would occur, appropriate flags are set and the result is not written back. | 			// If overflow would occur, appropriate flags are set and the result is not written back. | ||||||
| 			if(quotient > 65535) { | 			if(quotient > 65535) { | ||||||
| 				status.overflow_flag_ = status.zero_result_ = status.negative_flag_ = 1; | 				status.overflow_flag = status.zero_result = status.negative_flag = 1; | ||||||
| 				flow_controller.template did_divu<true>(dividend, divisor); | 				flow_controller.template did_divu<true>(dividend, divisor); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| @@ -536,14 +536,14 @@ template < | |||||||
| 			const uint16_t remainder = uint16_t(dividend % divisor); | 			const uint16_t remainder = uint16_t(dividend % divisor); | ||||||
| 			dest.l = uint32_t((remainder << 16) | uint16_t(quotient)); | 			dest.l = uint32_t((remainder << 16) | uint16_t(quotient)); | ||||||
|  |  | ||||||
| 			status.overflow_flag_ = 0; | 			status.overflow_flag = 0; | ||||||
| 			status.zero_result_ = quotient; | 			status.zero_result = quotient; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x8000; | 			status.negative_flag = status.zero_result & 0x8000; | ||||||
| 			flow_controller.template did_divu<false>(dividend, divisor); | 			flow_controller.template did_divu<false>(dividend, divisor); | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		case Operation::DIVS: { | 		case Operation::DIVS: { | ||||||
| 			status.carry_flag_ = 0; | 			status.carry_flag = 0; | ||||||
|  |  | ||||||
| 			// An attempt to divide by zero schedules an exception. | 			// An attempt to divide by zero schedules an exception. | ||||||
| 			if(!src.w) { | 			if(!src.w) { | ||||||
| @@ -569,7 +569,7 @@ template < | |||||||
| 			// Check for overflow. If it exists, work here is already done. | 			// Check for overflow. If it exists, work here is already done. | ||||||
| 			const auto quotient = dividend / divisor; | 			const auto quotient = dividend / divisor; | ||||||
| 			if(quotient > 32767) { | 			if(quotient > 32767) { | ||||||
| 				status.overflow_flag_ = 1; | 				status.overflow_flag = 1; | ||||||
| 				flow_controller.template did_divs<true>(signed_dividend, signed_divisor); | 				flow_controller.template did_divs<true>(signed_dividend, signed_divisor); | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| @@ -578,9 +578,9 @@ template < | |||||||
| 			const int signed_quotient = result_sign*int(quotient); | 			const int signed_quotient = result_sign*int(quotient); | ||||||
| 			dest.l = uint32_t((remainder << 16) | uint16_t(signed_quotient)); | 			dest.l = uint32_t((remainder << 16) | uint16_t(signed_quotient)); | ||||||
|  |  | ||||||
| 			status.zero_result_ = decltype(status.zero_result_)(signed_quotient); | 			status.zero_result = decltype(status.zero_result)(signed_quotient); | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x8000; | 			status.negative_flag = status.zero_result & 0x8000; | ||||||
| 			status.overflow_flag_ = 0; | 			status.overflow_flag = 0; | ||||||
| 			flow_controller.template did_divs<false>(signed_dividend, signed_divisor); | 			flow_controller.template did_divs<false>(signed_dividend, signed_divisor); | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| @@ -592,7 +592,7 @@ template < | |||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::TRAPV: { | 		case Operation::TRAPV: { | ||||||
| 			if(status.overflow_flag_) { | 			if(status.overflow_flag) { | ||||||
| 				flow_controller.template raise_exception<false>(Exception::TRAPV); | 				flow_controller.template raise_exception<false>(Exception::TRAPV); | ||||||
| 			} | 			} | ||||||
| 		} break; | 		} break; | ||||||
| @@ -601,15 +601,15 @@ template < | |||||||
| 			const bool is_under = s_extend16(dest.w) < 0; | 			const bool is_under = s_extend16(dest.w) < 0; | ||||||
| 			const bool is_over = s_extend16(dest.w) > s_extend16(src.w); | 			const bool is_over = s_extend16(dest.w) > s_extend16(src.w); | ||||||
|  |  | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 			status.zero_result_ = dest.w; | 			status.zero_result = dest.w; | ||||||
|  |  | ||||||
| 			// Test applied for N: | 			// Test applied for N: | ||||||
| 			// | 			// | ||||||
| 			//	if Dn < 0, set negative flag; | 			//	if Dn < 0, set negative flag; | ||||||
| 			//	otherwise, if Dn > <ea>, reset negative flag. | 			//	otherwise, if Dn > <ea>, reset negative flag. | ||||||
| 			if(is_over)		status.negative_flag_ = 0; | 			if(is_over)		status.negative_flag = 0; | ||||||
| 			if(is_under)	status.negative_flag_ = 1; | 			if(is_under)	status.negative_flag = 1; | ||||||
|  |  | ||||||
| 			// No exception is the default course of action; deviate only if an | 			// No exception is the default course of action; deviate only if an | ||||||
| 			// exception is necessary. | 			// exception is necessary. | ||||||
| @@ -633,10 +633,10 @@ template < | |||||||
| 			const auto result = destination - source; | 			const auto result = destination - source; | ||||||
| 			src.b = uint8_t(result); | 			src.b = uint8_t(result); | ||||||
|  |  | ||||||
| 			status.zero_result_ = result & 0xff; | 			status.zero_result = result & 0xff; | ||||||
| 			status.extend_flag_ = status.carry_flag_ = decltype(status.carry_flag_)(result & ~0xff); | 			status.extend_flag = status.carry_flag = decltype(status.carry_flag)(result & ~0xff); | ||||||
| 			status.negative_flag_ = result & 0x80; | 			status.negative_flag = result & 0x80; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x80; | 			status.overflow_flag = sub_overflow() & 0x80; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		case Operation::NEGw: { | 		case Operation::NEGw: { | ||||||
| @@ -645,10 +645,10 @@ template < | |||||||
| 			const auto result = destination - source; | 			const auto result = destination - source; | ||||||
| 			src.w = uint16_t(result); | 			src.w = uint16_t(result); | ||||||
|  |  | ||||||
| 			status.zero_result_ = result & 0xffff; | 			status.zero_result = result & 0xffff; | ||||||
| 			status.extend_flag_ = status.carry_flag_ = decltype(status.carry_flag_)(result & ~0xffff); | 			status.extend_flag = status.carry_flag = decltype(status.carry_flag)(result & ~0xffff); | ||||||
| 			status.negative_flag_ = result & 0x8000; | 			status.negative_flag = result & 0x8000; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x8000; | 			status.overflow_flag = sub_overflow() & 0x8000; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		case Operation::NEGl: { | 		case Operation::NEGl: { | ||||||
| @@ -657,10 +657,10 @@ template < | |||||||
| 			const auto result = destination - source; | 			const auto result = destination - source; | ||||||
| 			src.l = uint32_t(result); | 			src.l = uint32_t(result); | ||||||
|  |  | ||||||
| 			status.zero_result_ = uint_fast32_t(result); | 			status.zero_result = uint_fast32_t(result); | ||||||
| 			status.extend_flag_ = status.carry_flag_ = result >> 32; | 			status.extend_flag = status.carry_flag = result >> 32; | ||||||
| 			status.negative_flag_ = result & 0x80000000; | 			status.negative_flag = result & 0x80000000; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x80000000; | 			status.overflow_flag = sub_overflow() & 0x80000000; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		/* | 		/* | ||||||
| @@ -669,37 +669,37 @@ template < | |||||||
| 		case Operation::NEGXb: { | 		case Operation::NEGXb: { | ||||||
| 			const int source = src.b; | 			const int source = src.b; | ||||||
| 			const int destination = 0; | 			const int destination = 0; | ||||||
| 			const auto result = destination - source - (status.extend_flag_ ? 1 : 0); | 			const auto result = destination - source - (status.extend_flag ? 1 : 0); | ||||||
| 			src.b = uint8_t(result); | 			src.b = uint8_t(result); | ||||||
|  |  | ||||||
| 			status.zero_result_ |= result & 0xff; | 			status.zero_result |= result & 0xff; | ||||||
| 			status.extend_flag_ = status.carry_flag_ = decltype(status.carry_flag_)(result & ~0xff); | 			status.extend_flag = status.carry_flag = decltype(status.carry_flag)(result & ~0xff); | ||||||
| 			status.negative_flag_ = result & 0x80; | 			status.negative_flag = result & 0x80; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x80; | 			status.overflow_flag = sub_overflow() & 0x80; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		case Operation::NEGXw: { | 		case Operation::NEGXw: { | ||||||
| 			const int source = src.w; | 			const int source = src.w; | ||||||
| 			const int destination = 0; | 			const int destination = 0; | ||||||
| 			const auto result = destination - source - (status.extend_flag_ ? 1 : 0); | 			const auto result = destination - source - (status.extend_flag ? 1 : 0); | ||||||
| 			src.w = uint16_t(result); | 			src.w = uint16_t(result); | ||||||
|  |  | ||||||
| 			status.zero_result_ |= result & 0xffff; | 			status.zero_result |= result & 0xffff; | ||||||
| 			status.extend_flag_ = status.carry_flag_ = decltype(status.carry_flag_)(result & ~0xffff); | 			status.extend_flag = status.carry_flag = decltype(status.carry_flag)(result & ~0xffff); | ||||||
| 			status.negative_flag_ = result & 0x8000; | 			status.negative_flag = result & 0x8000; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x8000; | 			status.overflow_flag = sub_overflow() & 0x8000; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		case Operation::NEGXl: { | 		case Operation::NEGXl: { | ||||||
| 			const uint64_t source = src.l; | 			const uint64_t source = src.l; | ||||||
| 			const uint64_t destination = 0; | 			const uint64_t destination = 0; | ||||||
| 			const auto result = destination - source - (status.extend_flag_ ? 1 : 0); | 			const auto result = destination - source - (status.extend_flag ? 1 : 0); | ||||||
| 			src.l = uint32_t(result); | 			src.l = uint32_t(result); | ||||||
|  |  | ||||||
| 			status.zero_result_ |= uint_fast32_t(result); | 			status.zero_result |= uint_fast32_t(result); | ||||||
| 			status.extend_flag_ = status.carry_flag_ = result >> 32; | 			status.extend_flag = status.carry_flag = result >> 32; | ||||||
| 			status.negative_flag_ = result & 0x80000000; | 			status.negative_flag = result & 0x80000000; | ||||||
| 			status.overflow_flag_ = sub_overflow() & 0x80000000; | 			status.overflow_flag = sub_overflow() & 0x80000000; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		/* | 		/* | ||||||
| @@ -739,9 +739,9 @@ template < | |||||||
|  |  | ||||||
| #define bitwise(source, dest, sign_mask, operator)	\ | #define bitwise(source, dest, sign_mask, operator)	\ | ||||||
| 	operator(dest, source);							\ | 	operator(dest, source);							\ | ||||||
| 	status.overflow_flag_ = status.carry_flag_ = 0;	\ | 	status.overflow_flag = status.carry_flag = 0;	\ | ||||||
| 	status.zero_result_ = dest;						\ | 	status.zero_result = dest;						\ | ||||||
| 	status.negative_flag_ = dest & sign_mask; | 	status.negative_flag = dest & sign_mask; | ||||||
|  |  | ||||||
| #define andx(source, dest, sign_mask)	bitwise(source, dest, sign_mask, op_and) | #define andx(source, dest, sign_mask)	bitwise(source, dest, sign_mask, op_and) | ||||||
| #define eorx(source, dest, sign_mask)	bitwise(source, dest, sign_mask, op_eor) | #define eorx(source, dest, sign_mask)	bitwise(source, dest, sign_mask, op_eor) | ||||||
| @@ -768,38 +768,38 @@ template < | |||||||
| 		// NOTs: take the logical inverse, affecting the negative and zero flags. | 		// NOTs: take the logical inverse, affecting the negative and zero flags. | ||||||
| 		case Operation::NOTb: | 		case Operation::NOTb: | ||||||
| 			src.b ^= 0xff; | 			src.b ^= 0xff; | ||||||
| 			status.zero_result_ = src.b; | 			status.zero_result = src.b; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x80; | 			status.negative_flag = status.zero_result & 0x80; | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::NOTw: | 		case Operation::NOTw: | ||||||
| 			src.w ^= 0xffff; | 			src.w ^= 0xffff; | ||||||
| 			status.zero_result_ = src.w; | 			status.zero_result = src.w; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x8000; | 			status.negative_flag = status.zero_result & 0x8000; | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::NOTl: | 		case Operation::NOTl: | ||||||
| 			src.l ^= 0xffffffff; | 			src.l ^= 0xffffffff; | ||||||
| 			status.zero_result_ = src.l; | 			status.zero_result = src.l; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x80000000; | 			status.negative_flag = status.zero_result & 0x80000000; | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| #define sbcd(d)																							\ | #define sbcd(d)																							\ | ||||||
| 	/* Perform the BCD arithmetic by evaluating the two nibbles separately. */							\ | 	/* Perform the BCD arithmetic by evaluating the two nibbles separately. */							\ | ||||||
| 	const int unadjusted_result = destination - source - (status.extend_flag_ ? 1 : 0);					\ | 	const int unadjusted_result = destination - source - (status.extend_flag ? 1 : 0);					\ | ||||||
| 	int result = (destination & 0xf) - (source & 0xf) - (status.extend_flag_ ? 1 : 0);					\ | 	int result = (destination & 0xf) - (source & 0xf) - (status.extend_flag ? 1 : 0);					\ | ||||||
| 	if(result & 0xf0) result -= 0x06;																	\ | 	if(result & 0xf0) result -= 0x06;																	\ | ||||||
| 	result += (destination & 0xf0) - (source & 0xf0);													\ | 	result += (destination & 0xf0) - (source & 0xf0);													\ | ||||||
| 	status.extend_flag_ = status.carry_flag_ = decltype(status.carry_flag_)((result & 0xff) > 0x9f);	\ | 	status.extend_flag = status.carry_flag = decltype(status.carry_flag)(unadjusted_result & 0x300);	\ | ||||||
| 	if(unadjusted_result & 0x100) result -= 0x60;																\ | 	if(unadjusted_result & 0x100) result -= 0x60;														\ | ||||||
| 																										\ | 																										\ | ||||||
| 	/* Set all flags essentially as if this were normal subtraction. */									\ | 	/* Set all flags essentially as if this were normal subtraction. */									\ | ||||||
| 	status.zero_result_ |= result & 0xff;																\ | 	status.zero_result |= result & 0xff;																\ | ||||||
| 	status.negative_flag_ = result & 0x80;																\ | 	status.negative_flag = result & 0x80;																\ | ||||||
| 	status.overflow_flag_ = unadjusted_result & ~result & 0x80;											\ | 	status.overflow_flag = unadjusted_result & ~result & 0x80;											\ | ||||||
| 																										\ | 																										\ | ||||||
| 	/* Store the result. */																				\ | 	/* Store the result. */																				\ | ||||||
| 	d = uint8_t(result); | 	d = uint8_t(result); | ||||||
| @@ -840,21 +840,21 @@ template < | |||||||
| 			words[0] = words[1]; | 			words[0] = words[1]; | ||||||
| 			words[1] = temporary; | 			words[1] = temporary; | ||||||
|  |  | ||||||
| 			status.zero_result_ = src.l; | 			status.zero_result = src.l; | ||||||
| 			status.negative_flag_ = temporary & 0x8000; | 			status.negative_flag = temporary & 0x8000; | ||||||
| 			status.overflow_flag_ = status.carry_flag_ = 0; | 			status.overflow_flag = status.carry_flag = 0; | ||||||
| 		} break; | 		} break; | ||||||
|  |  | ||||||
| 		/* | 		/* | ||||||
| 			Shifts and rotates. | 			Shifts and rotates. | ||||||
| 		*/ | 		*/ | ||||||
| #define set_neg_zero(v, m)											\ | #define set_neg_zero(v, m)														\ | ||||||
| 	status.zero_result_ = decltype(status.zero_result_)(v);						\ | 	status.zero_result = decltype(status.zero_result)(v);						\ | ||||||
| 	status.negative_flag_ = status.zero_result_ & decltype(status.negative_flag_)(m); | 	status.negative_flag = status.zero_result & decltype(status.negative_flag)(m); | ||||||
|  |  | ||||||
| #define set_neg_zero_overflow(v, m)									\ | #define set_neg_zero_overflow(v, m)									\ | ||||||
| 	set_neg_zero(v, m);												\ | 	set_neg_zero(v, m);												\ | ||||||
| 	status.overflow_flag_ = (decltype(status.zero_result_)(value) ^ status.zero_result_) & decltype(status.overflow_flag_)(m); | 	status.overflow_flag = (decltype(status.zero_result)(value) ^ status.zero_result) & decltype(status.overflow_flag)(m); | ||||||
|  |  | ||||||
| #define decode_shift_count()	\ | #define decode_shift_count()	\ | ||||||
| 	int shift_count = src.l & 63;	\ | 	int shift_count = src.l & 63;	\ | ||||||
| @@ -867,15 +867,15 @@ template < | |||||||
| 	const auto value = destination;	\ | 	const auto value = destination;	\ | ||||||
| 	\ | 	\ | ||||||
| 	if(!shift_count) {	\ | 	if(!shift_count) {	\ | ||||||
| 		status.carry_flag_ = status.overflow_flag_ = 0;	\ | 		status.carry_flag = status.overflow_flag = 0;	\ | ||||||
| 	} else {	\ | 	} else {	\ | ||||||
| 		destination = (shift_count < size) ? decltype(destination)(value << shift_count) : 0;	\ | 		destination = (shift_count < size) ? decltype(destination)(value << shift_count) : 0;	\ | ||||||
| 		status.extend_flag_ = status.carry_flag_ = decltype(status.carry_flag_)(value) & decltype(status.carry_flag_)( (1u << (size - 1)) >> (shift_count - 1) );	\ | 		status.extend_flag = status.carry_flag = decltype(status.carry_flag)(value) & decltype(status.carry_flag)( (1u << (size - 1)) >> (shift_count - 1) );	\ | ||||||
| 		\ | 		\ | ||||||
| 		if(shift_count >= size) status.overflow_flag_ = value && (value != decltype(value)(-1));	\ | 		if(shift_count >= size) status.overflow_flag = value && (value != decltype(value)(-1));	\ | ||||||
| 		else {	\ | 		else {	\ | ||||||
| 			const auto mask = decltype(destination)(0xffffffff << (size - shift_count));	\ | 			const auto mask = decltype(destination)(0xffffffff << (size - shift_count));	\ | ||||||
| 			status.overflow_flag_ = mask & value && ((mask & value) != mask);	\ | 			status.overflow_flag = mask & value && ((mask & value) != mask);	\ | ||||||
| 		}	\ | 		}	\ | ||||||
| 	}	\ | 	}	\ | ||||||
| 	\ | 	\ | ||||||
| @@ -885,7 +885,7 @@ template < | |||||||
| 		case Operation::ASLm: { | 		case Operation::ASLm: { | ||||||
| 			const auto value = src.w; | 			const auto value = src.w; | ||||||
| 			src.w = uint16_t(value << 1); | 			src.w = uint16_t(value << 1); | ||||||
| 			status.extend_flag_ = status.carry_flag_ = value & 0x8000; | 			status.extend_flag = status.carry_flag = value & 0x8000; | ||||||
| 			set_neg_zero_overflow(src.w, 0x8000); | 			set_neg_zero_overflow(src.w, 0x8000); | ||||||
| 		} break; | 		} break; | ||||||
| 		case Operation::ASLb: asl(dest.b, 8);	break; | 		case Operation::ASLb: asl(dest.b, 8);	break; | ||||||
| @@ -897,7 +897,7 @@ template < | |||||||
| 	const auto value = destination;	\ | 	const auto value = destination;	\ | ||||||
| 	\ | 	\ | ||||||
| 	if(!shift_count) {	\ | 	if(!shift_count) {	\ | ||||||
| 		status.carry_flag_ = 0;	\ | 		status.carry_flag = 0;	\ | ||||||
| 	} else {	\ | 	} else {	\ | ||||||
| 		destination = (shift_count < size) ?	\ | 		destination = (shift_count < size) ?	\ | ||||||
| 		decltype(destination)(\ | 		decltype(destination)(\ | ||||||
| @@ -907,7 +907,7 @@ template < | |||||||
| 			decltype(destination)(	\ | 			decltype(destination)(	\ | ||||||
| 			(value & decltype(value)(1 << (size - 1))) ? 0xffffffff : 0x000000000	\ | 			(value & decltype(value)(1 << (size - 1))) ? 0xffffffff : 0x000000000	\ | ||||||
| 		);	\ | 		);	\ | ||||||
| 		status.extend_flag_ = status.carry_flag_ = decltype(status.carry_flag_)(value) & decltype(status.carry_flag_)(1 << (shift_count - 1));	\ | 		status.extend_flag = status.carry_flag = decltype(status.carry_flag)(value) & decltype(status.carry_flag)(1 << (shift_count - 1));	\ | ||||||
| 	}	\ | 	}	\ | ||||||
| 	\ | 	\ | ||||||
| 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | ||||||
| @@ -916,7 +916,7 @@ template < | |||||||
| 		case Operation::ASRm: { | 		case Operation::ASRm: { | ||||||
| 			const auto value = src.w; | 			const auto value = src.w; | ||||||
| 			src.w = (value&0x8000) | (value >> 1); | 			src.w = (value&0x8000) | (value >> 1); | ||||||
| 			status.extend_flag_ = status.carry_flag_ = value & 1; | 			status.extend_flag = status.carry_flag = value & 1; | ||||||
| 			set_neg_zero_overflow(src.w, 0x8000); | 			set_neg_zero_overflow(src.w, 0x8000); | ||||||
| 		} break; | 		} break; | ||||||
| 		case Operation::ASRb: asr(dest.b, 8);	break; | 		case Operation::ASRb: asr(dest.b, 8);	break; | ||||||
| @@ -927,24 +927,24 @@ template < | |||||||
| #undef set_neg_zero_overflow | #undef set_neg_zero_overflow | ||||||
| #define set_neg_zero_overflow(v, m)	\ | #define set_neg_zero_overflow(v, m)	\ | ||||||
| 	set_neg_zero(v, m);	\ | 	set_neg_zero(v, m);	\ | ||||||
| 	status.overflow_flag_ = 0; | 	status.overflow_flag = 0; | ||||||
|  |  | ||||||
| #undef set_flags | #undef set_flags | ||||||
| #define set_flags(v, m, t)	\ | #define set_flags(v, m, t)	\ | ||||||
| 	status.zero_result_ = v;	\ | 	status.zero_result = v;	\ | ||||||
| 	status.negative_flag_ = status.zero_result_ & (m);	\ | 	status.negative_flag = status.zero_result & (m);	\ | ||||||
| 	status.overflow_flag_ = 0;	\ | 	status.overflow_flag = 0;	\ | ||||||
| 	status.carry_flag_ = value & (t); | 	status.carry_flag = value & (t); | ||||||
|  |  | ||||||
| #define lsl(destination, size)	{\ | #define lsl(destination, size)	{\ | ||||||
| 	decode_shift_count();	\ | 	decode_shift_count();	\ | ||||||
| 	const auto value = destination;	\ | 	const auto value = destination;	\ | ||||||
| 	\ | 	\ | ||||||
| 	if(!shift_count) {	\ | 	if(!shift_count) {	\ | ||||||
| 		status.carry_flag_ = 0;	\ | 		status.carry_flag = 0;	\ | ||||||
| 	} else {	\ | 	} else {	\ | ||||||
| 		destination = (shift_count < size) ? decltype(destination)(value << shift_count) : 0;	\ | 		destination = (shift_count < size) ? decltype(destination)(value << shift_count) : 0;	\ | ||||||
| 		status.extend_flag_ = status.carry_flag_ = decltype(status.carry_flag_)(value) & decltype(status.carry_flag_)( (1u << (size - 1)) >> (shift_count - 1) );	\ | 		status.extend_flag = status.carry_flag = decltype(status.carry_flag)(value) & decltype(status.carry_flag)( (1u << (size - 1)) >> (shift_count - 1) );	\ | ||||||
| 	}	\ | 	}	\ | ||||||
| 	\ | 	\ | ||||||
| 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | ||||||
| @@ -953,7 +953,7 @@ template < | |||||||
| 		case Operation::LSLm: { | 		case Operation::LSLm: { | ||||||
| 			const auto value = src.w; | 			const auto value = src.w; | ||||||
| 			src.w = uint16_t(value << 1); | 			src.w = uint16_t(value << 1); | ||||||
| 			status.extend_flag_ = status.carry_flag_ = value & 0x8000; | 			status.extend_flag = status.carry_flag = value & 0x8000; | ||||||
| 			set_neg_zero_overflow(src.w, 0x8000); | 			set_neg_zero_overflow(src.w, 0x8000); | ||||||
| 		} break; | 		} break; | ||||||
| 		case Operation::LSLb: lsl(dest.b, 8);	break; | 		case Operation::LSLb: lsl(dest.b, 8);	break; | ||||||
| @@ -965,10 +965,10 @@ template < | |||||||
| 	const auto value = destination;	\ | 	const auto value = destination;	\ | ||||||
| 	\ | 	\ | ||||||
| 	if(!shift_count) {	\ | 	if(!shift_count) {	\ | ||||||
| 		status.carry_flag_ = 0;	\ | 		status.carry_flag = 0;	\ | ||||||
| 	} else {	\ | 	} else {	\ | ||||||
| 		destination = (shift_count < size) ? (value >> shift_count) : 0;	\ | 		destination = (shift_count < size) ? (value >> shift_count) : 0;	\ | ||||||
| 		status.extend_flag_ = status.carry_flag_ = value & decltype(status.carry_flag_)(1 << (shift_count - 1));	\ | 		status.extend_flag = status.carry_flag = value & decltype(status.carry_flag)(1 << (shift_count - 1));	\ | ||||||
| 	}	\ | 	}	\ | ||||||
| 	\ | 	\ | ||||||
| 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | ||||||
| @@ -977,7 +977,7 @@ template < | |||||||
| 		case Operation::LSRm: { | 		case Operation::LSRm: { | ||||||
| 			const auto value = src.w; | 			const auto value = src.w; | ||||||
| 			src.w = value >> 1; | 			src.w = value >> 1; | ||||||
| 			status.extend_flag_ = status.carry_flag_ = value & 1; | 			status.extend_flag = status.carry_flag = value & 1; | ||||||
| 			set_neg_zero_overflow(src.w, 0x8000); | 			set_neg_zero_overflow(src.w, 0x8000); | ||||||
| 		} break; | 		} break; | ||||||
| 		case Operation::LSRb: lsr(dest.b, 8);	break; | 		case Operation::LSRb: lsr(dest.b, 8);	break; | ||||||
| @@ -989,14 +989,14 @@ template < | |||||||
| 	const auto value = destination;	\ | 	const auto value = destination;	\ | ||||||
| 	\ | 	\ | ||||||
| 	if(!shift_count) {	\ | 	if(!shift_count) {	\ | ||||||
| 		status.carry_flag_ = 0;	\ | 		status.carry_flag = 0;	\ | ||||||
| 	} else {	\ | 	} else {	\ | ||||||
| 		shift_count &= (size - 1);	\ | 		shift_count &= (size - 1);	\ | ||||||
| 		destination = decltype(destination)(	\ | 		destination = decltype(destination)(	\ | ||||||
| 			(value << shift_count) |	\ | 			(value << shift_count) |	\ | ||||||
| 			(value >> (size - shift_count))	\ | 			(value >> (size - shift_count))	\ | ||||||
| 		);	\ | 		);	\ | ||||||
| 		status.carry_flag_ = decltype(status.carry_flag_)(destination & 1);	\ | 		status.carry_flag = decltype(status.carry_flag)(destination & 1);	\ | ||||||
| 	}	\ | 	}	\ | ||||||
| 	\ | 	\ | ||||||
| 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | ||||||
| @@ -1005,7 +1005,7 @@ template < | |||||||
| 		case Operation::ROLm: { | 		case Operation::ROLm: { | ||||||
| 			const auto value = src.w; | 			const auto value = src.w; | ||||||
| 			src.w = uint16_t((value << 1) | (value >> 15)); | 			src.w = uint16_t((value << 1) | (value >> 15)); | ||||||
| 			status.carry_flag_ = src.w & 1; | 			status.carry_flag = src.w & 1; | ||||||
| 			set_neg_zero_overflow(src.w, 0x8000); | 			set_neg_zero_overflow(src.w, 0x8000); | ||||||
| 		} break; | 		} break; | ||||||
| 		case Operation::ROLb: rol(dest.b, 8);	break; | 		case Operation::ROLb: rol(dest.b, 8);	break; | ||||||
| @@ -1017,14 +1017,14 @@ template < | |||||||
| 	const auto value = destination;	\ | 	const auto value = destination;	\ | ||||||
| 	\ | 	\ | ||||||
| 	if(!shift_count) {	\ | 	if(!shift_count) {	\ | ||||||
| 		status.carry_flag_ = 0;	\ | 		status.carry_flag = 0;	\ | ||||||
| 	} else {	\ | 	} else {	\ | ||||||
| 		shift_count &= (size - 1);	\ | 		shift_count &= (size - 1);	\ | ||||||
| 		destination = decltype(destination)(\ | 		destination = decltype(destination)(\ | ||||||
| 			(value >> shift_count) |	\ | 			(value >> shift_count) |	\ | ||||||
| 			(value << (size - shift_count))	\ | 			(value << (size - shift_count))	\ | ||||||
| 		);\ | 		);\ | ||||||
| 		status.carry_flag_ = destination & decltype(status.carry_flag_)(1 << (size - 1));	\ | 		status.carry_flag = destination & decltype(status.carry_flag)(1 << (size - 1));	\ | ||||||
| 	}	\ | 	}	\ | ||||||
| 	\ | 	\ | ||||||
| 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | ||||||
| @@ -1033,7 +1033,7 @@ template < | |||||||
| 		case Operation::RORm: { | 		case Operation::RORm: { | ||||||
| 			const auto value = src.w; | 			const auto value = src.w; | ||||||
| 			src.w = uint16_t((value >> 1) | (value << 15)); | 			src.w = uint16_t((value >> 1) | (value << 15)); | ||||||
| 			status.carry_flag_ = src.w & 0x8000; | 			status.carry_flag = src.w & 0x8000; | ||||||
| 			set_neg_zero_overflow(src.w, 0x8000); | 			set_neg_zero_overflow(src.w, 0x8000); | ||||||
| 		} break; | 		} break; | ||||||
| 		case Operation::RORb: ror(dest.b, 8);	break; | 		case Operation::RORb: ror(dest.b, 8);	break; | ||||||
| @@ -1044,11 +1044,11 @@ template < | |||||||
| 	decode_shift_count();	\ | 	decode_shift_count();	\ | ||||||
| 	\ | 	\ | ||||||
| 	shift_count %= (size + 1);	\ | 	shift_count %= (size + 1);	\ | ||||||
| 	uint64_t compound = uint64_t(destination) | (status.extend_flag_ ? (1ull << size) : 0);	\ | 	uint64_t compound = uint64_t(destination) | (status.extend_flag ? (1ull << size) : 0);	\ | ||||||
| 	compound = \ | 	compound = \ | ||||||
| 		(compound << shift_count) |	\ | 		(compound << shift_count) |	\ | ||||||
| 		(compound >> (size + 1 - shift_count));	\ | 		(compound >> (size + 1 - shift_count));	\ | ||||||
| 	status.carry_flag_ = status.extend_flag_ = decltype(status.carry_flag_)((compound >> size) & 1);	\ | 	status.carry_flag = status.extend_flag = decltype(status.carry_flag)((compound >> size) & 1);	\ | ||||||
| 	destination = decltype(destination)(compound);	\ | 	destination = decltype(destination)(compound);	\ | ||||||
| 	\ | 	\ | ||||||
| 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | ||||||
| @@ -1056,8 +1056,8 @@ template < | |||||||
|  |  | ||||||
| 		case Operation::ROXLm: { | 		case Operation::ROXLm: { | ||||||
| 			const auto value = src.w; | 			const auto value = src.w; | ||||||
| 			src.w = uint16_t((value << 1) | (status.extend_flag_ ? 0x0001 : 0x0000)); | 			src.w = uint16_t((value << 1) | (status.extend_flag ? 0x0001 : 0x0000)); | ||||||
| 			status.extend_flag_ = value & 0x8000; | 			status.extend_flag = value & 0x8000; | ||||||
| 			set_flags_w(0x8000); | 			set_flags_w(0x8000); | ||||||
| 		} break; | 		} break; | ||||||
| 		case Operation::ROXLb: roxl(dest.b, 8);		break; | 		case Operation::ROXLb: roxl(dest.b, 8);		break; | ||||||
| @@ -1068,11 +1068,11 @@ template < | |||||||
| 	decode_shift_count();	\ | 	decode_shift_count();	\ | ||||||
| 	\ | 	\ | ||||||
| 	shift_count %= (size + 1);	\ | 	shift_count %= (size + 1);	\ | ||||||
| 	uint64_t compound = uint64_t(destination) | (status.extend_flag_ ? (1ull << size) : 0);	\ | 	uint64_t compound = uint64_t(destination) | (status.extend_flag ? (1ull << size) : 0);	\ | ||||||
| 	compound = \ | 	compound = \ | ||||||
| 		(compound >> shift_count) |	\ | 		(compound >> shift_count) |	\ | ||||||
| 		(compound << (size + 1 - shift_count));	\ | 		(compound << (size + 1 - shift_count));	\ | ||||||
| 		status.carry_flag_ = status.extend_flag_ = decltype(status.carry_flag_)((compound >> size) & 1);	\ | 		status.carry_flag = status.extend_flag = decltype(status.carry_flag)((compound >> size) & 1);	\ | ||||||
| 	destination = decltype(destination)(compound);	\ | 	destination = decltype(destination)(compound);	\ | ||||||
| 	\ | 	\ | ||||||
| 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | 	set_neg_zero_overflow(destination, 1 << (size - 1));	\ | ||||||
| @@ -1080,8 +1080,8 @@ template < | |||||||
|  |  | ||||||
| 		case Operation::ROXRm: { | 		case Operation::ROXRm: { | ||||||
| 			const auto value = src.w; | 			const auto value = src.w; | ||||||
| 			src.w = (value >> 1) | (status.extend_flag_ ? 0x8000 : 0x0000); | 			src.w = (value >> 1) | (status.extend_flag ? 0x8000 : 0x0000); | ||||||
| 			status.extend_flag_ = value & 0x0001; | 			status.extend_flag = value & 0x0001; | ||||||
| 			set_flags_w(0x0001); | 			set_flags_w(0x0001); | ||||||
| 		} break; | 		} break; | ||||||
| 		case Operation::ROXRb: roxr(dest.b, 8);		break; | 		case Operation::ROXRb: roxr(dest.b, 8);		break; | ||||||
| @@ -1147,21 +1147,21 @@ template < | |||||||
| 		*/ | 		*/ | ||||||
|  |  | ||||||
| 		case Operation::TSTb: | 		case Operation::TSTb: | ||||||
| 			status.carry_flag_ = status.overflow_flag_ = 0; | 			status.carry_flag = status.overflow_flag = 0; | ||||||
| 			status.zero_result_ = src.b; | 			status.zero_result = src.b; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x80; | 			status.negative_flag = status.zero_result & 0x80; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::TSTw: | 		case Operation::TSTw: | ||||||
| 			status.carry_flag_ = status.overflow_flag_ = 0; | 			status.carry_flag = status.overflow_flag = 0; | ||||||
| 			status.zero_result_ = src.w; | 			status.zero_result = src.w; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x8000; | 			status.negative_flag = status.zero_result & 0x8000; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::TSTl: | 		case Operation::TSTl: | ||||||
| 			status.carry_flag_ = status.overflow_flag_ = 0; | 			status.carry_flag = status.overflow_flag = 0; | ||||||
| 			status.zero_result_ = src.l; | 			status.zero_result = src.l; | ||||||
| 			status.negative_flag_ = status.zero_result_ & 0x80000000; | 			status.negative_flag = status.zero_result & 0x80000000; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case Operation::STOP: | 		case Operation::STOP: | ||||||
|   | |||||||
| @@ -15,61 +15,74 @@ namespace InstructionSet { | |||||||
| namespace M68k { | namespace M68k { | ||||||
|  |  | ||||||
| struct Status { | struct Status { | ||||||
|  | 	enum ConditionCode: uint16_t { | ||||||
|  | 		Carry		= (1 << 0), | ||||||
|  | 		Overflow	= (1 << 1), | ||||||
|  | 		Zero		= (1 << 2), | ||||||
|  | 		Negative	= (1 << 3), | ||||||
|  | 		Extend		= (1 << 4), | ||||||
|  |  | ||||||
|  | 		Supervisor	= (1 << 13), | ||||||
|  | 		Trace		= (1 << 15), | ||||||
|  |  | ||||||
|  | 		InterruptPriorityMask = (0b111 << 8), | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	/* b15 */ | 	/* b15 */ | ||||||
| 	uint_fast32_t trace_flag_ = 0;		// The trace flag is set if this value is non-zero. | 	uint_fast32_t trace_flag = 0;		// The trace flag is set if this value is non-zero. | ||||||
|  |  | ||||||
| 	/* b13 */ | 	/* b13 */ | ||||||
| 	int is_supervisor_ = 0;				// 1 => processor is in supervisor mode; 0 => it isn't. | 	int is_supervisor = 0;				// 1 => processor is in supervisor mode; 0 => it isn't. | ||||||
|  |  | ||||||
| 	/* b7–b9 */ | 	/* b7–b9 */ | ||||||
| 	int interrupt_level_ = 0;			// The direct integer value of the current interrupt level. | 	int interrupt_level = 0;			// The direct integer value of the current interrupt level. | ||||||
|  |  | ||||||
| 	/* b0–b4 */ | 	/* b0–b4 */ | ||||||
| 	uint_fast32_t zero_result_ = 0;		// The zero flag is set if this value is zero. | 	uint_fast32_t zero_result = 0;		// The zero flag is set if this value is zero. | ||||||
| 	uint_fast32_t carry_flag_ = 0;		// The carry flag is set if this value is non-zero. | 	uint_fast32_t carry_flag = 0;		// The carry flag is set if this value is non-zero. | ||||||
| 	uint_fast32_t extend_flag_ = 0;		// The extend flag is set if this value is non-zero. | 	uint_fast32_t extend_flag = 0;		// The extend flag is set if this value is non-zero. | ||||||
| 	uint_fast32_t overflow_flag_ = 0;	// The overflow flag is set if this value is non-zero. | 	uint_fast32_t overflow_flag = 0;	// The overflow flag is set if this value is non-zero. | ||||||
| 	uint_fast32_t negative_flag_ = 0;	// The negative flag is set if this value is non-zero. | 	uint_fast32_t negative_flag = 0;	// The negative flag is set if this value is non-zero. | ||||||
|  |  | ||||||
| 	/// Gets the current condition codes. | 	/// Gets the current condition codes. | ||||||
| 	constexpr uint16_t ccr() const { | 	constexpr uint16_t ccr() const { | ||||||
| 		return | 		return | ||||||
| 			(carry_flag_ 	? 0x0001 : 0x0000) | | 			(carry_flag 	? ConditionCode::Carry 		: 0) | | ||||||
| 			(overflow_flag_	? 0x0002 : 0x0000) | | 			(overflow_flag	? ConditionCode::Overflow	: 0) | | ||||||
| 			(zero_result_	? 0x0000 : 0x0004) | | 			(zero_result	? 0							: ConditionCode::Zero) | | ||||||
| 			(negative_flag_	? 0x0008 : 0x0000) | | 			(negative_flag	? ConditionCode::Negative	: 0) | | ||||||
| 			(extend_flag_	? 0x0010 : 0x0000); | 			(extend_flag	? ConditionCode::Extend		: 0); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/// Sets the current condition codes. | ||||||
|  | 	constexpr void set_ccr(uint16_t ccr) { | ||||||
|  | 		carry_flag		= ccr & ConditionCode::Carry; | ||||||
|  | 		overflow_flag	= ccr & ConditionCode::Overflow; | ||||||
|  | 		zero_result		= ~ccr & ConditionCode::Zero; | ||||||
|  | 		negative_flag	= ccr & ConditionCode::Negative; | ||||||
|  | 		extend_flag		= ccr & ConditionCode::Extend; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/// Gets the current value of the status register. | 	/// Gets the current value of the status register. | ||||||
| 	constexpr uint16_t status() const { | 	constexpr uint16_t status() const { | ||||||
| 		return uint16_t( | 		return uint16_t( | ||||||
| 			ccr() | | 			ccr() | | ||||||
| 			(interrupt_level_ << 8) | | 			(interrupt_level << 8) | | ||||||
| 			(trace_flag_ ? 0x8000 : 0x0000) | | 			(trace_flag ? ConditionCode::Trace : 0) | | ||||||
| 			(is_supervisor_ << 13) | 			(is_supervisor << 13) | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/// Sets the current condition codes. |  | ||||||
| 	constexpr void set_ccr(uint16_t ccr) { |  | ||||||
| 		carry_flag_			= (ccr) & 0x0001; |  | ||||||
| 		overflow_flag_		= (ccr) & 0x0002; |  | ||||||
| 		zero_result_		= ((ccr) & 0x0004) ^ 0x0004; |  | ||||||
| 		negative_flag_		= (ccr) & 0x0008; |  | ||||||
| 		extend_flag_		= (ccr) & 0x0010; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/// Sets the current value of the status register; | 	/// Sets the current value of the status register; | ||||||
| 	/// @returns @c true if the processor finishes in supervisor mode; @c false otherwise. | 	/// @returns @c true if the processor finishes in supervisor mode; @c false otherwise. | ||||||
| 	constexpr bool set_status(uint16_t status) { | 	constexpr bool set_status(uint16_t status) { | ||||||
| 		set_ccr(status); | 		set_ccr(status); | ||||||
|  |  | ||||||
| 		interrupt_level_ 	= (status >> 8) & 7; | 		interrupt_level	= (status >> 8) & 7; | ||||||
| 		trace_flag_			= status & 0x8000; | 		trace_flag		= status & ConditionCode::Trace; | ||||||
| 		is_supervisor_		= (status >> 13) & 1; | 		is_supervisor	= (status >> 13) & 1; | ||||||
|  |  | ||||||
| 		return is_supervisor_; | 		return is_supervisor; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/// Evaluates @c condition. | 	/// Evaluates @c condition. | ||||||
| @@ -78,24 +91,24 @@ struct Status { | |||||||
| 			default: | 			default: | ||||||
| 			case Condition::True:			return true; | 			case Condition::True:			return true; | ||||||
| 			case Condition::False:			return false; | 			case Condition::False:			return false; | ||||||
| 			case Condition::High:			return zero_result_ && !carry_flag_; | 			case Condition::High:			return zero_result && !carry_flag; | ||||||
| 			case Condition::LowOrSame:		return !zero_result_ || carry_flag_; | 			case Condition::LowOrSame:		return !zero_result || carry_flag; | ||||||
| 			case Condition::CarryClear:		return !carry_flag_; | 			case Condition::CarryClear:		return !carry_flag; | ||||||
| 			case Condition::CarrySet:		return carry_flag_; | 			case Condition::CarrySet:		return carry_flag; | ||||||
| 			case Condition::NotEqual:		return zero_result_; | 			case Condition::NotEqual:		return zero_result; | ||||||
| 			case Condition::Equal:			return !zero_result_; | 			case Condition::Equal:			return !zero_result; | ||||||
| 			case Condition::OverflowClear:	return !overflow_flag_; | 			case Condition::OverflowClear:	return !overflow_flag; | ||||||
| 			case Condition::OverflowSet:	return overflow_flag_; | 			case Condition::OverflowSet:	return overflow_flag; | ||||||
| 			case Condition::Positive:		return !negative_flag_; | 			case Condition::Positive:		return !negative_flag; | ||||||
| 			case Condition::Negative:		return negative_flag_; | 			case Condition::Negative:		return negative_flag; | ||||||
| 			case Condition::GreaterThanOrEqual: | 			case Condition::GreaterThanOrEqual: | ||||||
| 				return (negative_flag_ && overflow_flag_) || (!negative_flag_ && !overflow_flag_); | 				return (negative_flag && overflow_flag) || (!negative_flag && !overflow_flag); | ||||||
| 			case Condition::LessThan: | 			case Condition::LessThan: | ||||||
| 				return (negative_flag_ && !overflow_flag_) || (!negative_flag_ && overflow_flag_); | 				return (negative_flag && !overflow_flag) || (!negative_flag && overflow_flag); | ||||||
| 			case Condition::GreaterThan: | 			case Condition::GreaterThan: | ||||||
| 				return zero_result_ && ((negative_flag_ && overflow_flag_) || (!negative_flag_ && !overflow_flag_)); | 				return zero_result && ((negative_flag && overflow_flag) || (!negative_flag && !overflow_flag)); | ||||||
| 			case Condition::LessThanOrEqual: | 			case Condition::LessThanOrEqual: | ||||||
| 				return !zero_result_ || (negative_flag_ && !overflow_flag_) || (!negative_flag_ && overflow_flag_); | 				return !zero_result || (negative_flag && !overflow_flag) || (!negative_flag && overflow_flag); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -21,10 +21,10 @@ using namespace InstructionSet::M68k; | |||||||
|  |  | ||||||
| - (Status)statusWithflamewingFlags:(int)flags { | - (Status)statusWithflamewingFlags:(int)flags { | ||||||
| 	Status status; | 	Status status; | ||||||
| 	status.carry_flag_ = status.extend_flag_ = flags & 2; | 	status.carry_flag = status.extend_flag = flags & 2; | ||||||
| 	status.zero_result_ = ~flags & 1; | 	status.zero_result = ~flags & 1; | ||||||
| 	status.negative_flag_ = 0; | 	status.negative_flag = 0; | ||||||
| 	status.overflow_flag_ = 0; | 	status.overflow_flag = 0; | ||||||
| 	return status; | 	return status; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -86,6 +86,8 @@ using namespace InstructionSet::M68k; | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return; | ||||||
|  |  | ||||||
| 	// Test NBCD. | 	// Test NBCD. | ||||||
| 	for(int source = 0; source < 256; source++) { | 	for(int source = 0; source < 256; source++) { | ||||||
| 		for(int flags = 0; flags < 4; flags++) { | 		for(int flags = 0; flags < 4; flags++) { | ||||||
| @@ -97,7 +99,7 @@ using namespace InstructionSet::M68k; | |||||||
| 			perform<Model::M68000, NullFlowController, Operation::SBCD>( | 			perform<Model::M68000, NullFlowController, Operation::SBCD>( | ||||||
| 				Preinstruction(), s, d, status, flow_controller); | 				Preinstruction(), s, d, status, flow_controller); | ||||||
|  |  | ||||||
| 			[self validate:bytes source:source dest:0 flags:flags result:d.l status:status operation:@"NBCD"]; | 			[self validate:bytes source:source dest:0 flags:flags result:s.l status:status operation:@"NBCD"]; | ||||||
| 			bytes += 2; | 			bytes += 2; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user