| 1 | package com.rox.debug.cpu; | |
| 2 | ||
| 3 | import com.rox.cpu.mos6502.assembler.DisassembledInstruction; | |
| 4 | ||
| 5 | import java.util.List; | |
| 6 | import java.util.function.LongSupplier; | |
| 7 | ||
| 8 | /** | |
| 9 | * Whether to flash the current instruction's address: for {@link #FLASH_MILLIS} after a step lands on it by a | |
| 10 | * jump - any way control moves other than to the next instruction (JMP, JSR, RTS/RTI, a taken branch, an | |
| 11 | * interrupt) - while it's still the current instruction. Only while paused: running, nearly every refresh | |
| 12 | * follows some jump, so it would never stop. | |
| 13 | */ | |
| 14 | public final class JumpFlash { | |
| 15 | static final long FLASH_MILLIS = 600; | |
| 16 | private static final int ADDRESS_MASK = 0xFFFF; | |
| 17 | ||
| 18 | private final LongSupplier clockMillis; | |
| 19 | private long lastInstructionCount; | |
| 20 | private boolean pausedLastTime; | |
| 21 | private long flashUntil = Long.MIN_VALUE; | |
| 22 | ||
| 23 | /** @param clockMillis e.g. {@code System::currentTimeMillis} */ | |
| 24 | public JumpFlash(final LongSupplier clockMillis){ | |
| 25 | this.clockMillis = clockMillis; | |
| 26 | } | |
| 27 | ||
| 28 | /** | |
| 29 | * @param instructionCount see {@link CpuDebugSource#instructionCount()} - a rise while paused is a step | |
| 30 | * @param recent recently executed instructions, oldest first - see {@link CpuDebugSource#recentInstructions()} | |
| 31 | * @param currentAddress where the current instruction starts | |
| 32 | * @return whether the address should be flashing now | |
| 33 | */ | |
| 34 | public boolean update(final long instructionCount, final boolean paused, final List<DisassembledInstruction> recent, | |
| 35 | final int currentAddress){ | |
| 36 | final long now = clockMillis.getAsLong(); | |
| 37 |
1
1. update : negated conditional → KILLED |
if (!paused){ |
| 38 | flashUntil = Long.MIN_VALUE; | |
| 39 | pausedLastTime = false; | |
| 40 | lastInstructionCount = instructionCount; | |
| 41 |
1
1. update : replaced boolean return with true for com/rox/debug/cpu/JumpFlash::update → KILLED |
return false; |
| 42 | } | |
| 43 | //an instruction run while already paused is a step; the first look after pausing is not | |
| 44 |
2
1. update : negated conditional → KILLED 2. update : negated conditional → KILLED |
if (pausedLastTime && instructionCount != lastInstructionCount){ |
| 45 | //a step that didn't jump ends any flash still showing for the instruction before it | |
| 46 |
2
1. update : Replaced long addition with subtraction → KILLED 2. update : negated conditional → KILLED |
flashUntil = landedByJump(recent, currentAddress) ? now + FLASH_MILLIS : Long.MIN_VALUE; |
| 47 | } | |
| 48 | pausedLastTime = true; | |
| 49 | lastInstructionCount = instructionCount; | |
| 50 |
3
1. update : negated conditional → KILLED 2. update : changed conditional boundary → KILLED 3. update : replaced boolean return with true for com/rox/debug/cpu/JumpFlash::update → KILLED |
return now < flashUntil; |
| 51 | } | |
| 52 | ||
| 53 | /** True unless {@code currentAddress} directly follows the last executed instruction. */ | |
| 54 | static boolean landedByJump(final List<DisassembledInstruction> recent, final int currentAddress){ | |
| 55 |
1
1. landedByJump : negated conditional → KILLED |
if (recent.isEmpty()){ |
| 56 |
1
1. landedByJump : replaced boolean return with true for com/rox/debug/cpu/JumpFlash::landedByJump → KILLED |
return false; |
| 57 | } | |
| 58 |
1
1. landedByJump : Replaced integer subtraction with addition → KILLED |
final DisassembledInstruction previous = recent.get(recent.size() - 1); |
| 59 |
4
1. landedByJump : Replaced integer addition with subtraction → KILLED 2. landedByJump : Replaced bitwise AND with OR → KILLED 3. landedByJump : negated conditional → KILLED 4. landedByJump : replaced boolean return with true for com/rox/debug/cpu/JumpFlash::landedByJump → KILLED |
return ((previous.address() + previous.length()) & ADDRESS_MASK) != currentAddress; |
| 60 | } | |
| 61 | } | |
Mutations | ||
| 37 |
1.1 |
|
| 41 |
1.1 |
|
| 44 |
1.1 2.2 |
|
| 46 |
1.1 2.2 |
|
| 50 |
1.1 2.2 3.3 |
|
| 55 |
1.1 |
|
| 56 |
1.1 |
|
| 58 |
1.1 |
|
| 59 |
1.1 2.2 3.3 4.4 |