Mmc3Mapper.java

1
package com.rox.cartridge;
2
3
import com.rox.mem.RAM;
4
5
import java.util.LinkedHashMap;
6
import java.util.Map;
7
8
import static com.rox.ByteUtil.BYTE_MASK;
9
10
/**
11
 * iNES mapper 4 (MMC3). Four register pairs at {@code $8000-$FFFF}, even address selects the "low"
12
 * register of the pair, odd selects the "high" one:
13
 * <ul>
14
 *     <li>{@code $8000}/{@code $8001} - bank select / bank data: {@code $8000} picks which of 8
15
 *     internal bank registers (R0-R7) the next {@code $8001} write latches into, plus the PRG bank
16
 *     mode (bit 6) and CHR A12 inversion (bit 7) bits.</li>
17
 *     <li>{@code $A000}/{@code $A001} - nametable mirroring / PRG-RAM write-protect. The protect bits
18
 *     are deliberately not modeled - real MMC3 boards use them to write-protect save RAM during
19
 *     power-off, not something a running emulator needs, and modeling them risks the same MMC6
20
 *     register-meaning incompatibility real emulators avoid by skipping this too.</li>
21
 *     <li>{@code $C000}/{@code $C001} - IRQ latch / IRQ reload.</li>
22
 *     <li>{@code $E000}/{@code $E001} - IRQ disable(+acknowledge) / IRQ enable.</li>
23
 * </ul>
24
 *
25
 * PRG-ROM: four 8KB windows ({@code $8000-$9FFF}, {@code $A000-$BFFF}, {@code $C000-$DFFF},
26
 * {@code $E000-$FFFF}). R7 always drives {@code $A000-$BFFF} and the last bank is always fixed at
27
 * {@code $E000-$FFFF}; the bank-mode bit swaps which of {@code $8000-$9FFF}/{@code $C000-$DFFF} is
28
 * R6-switchable and which is fixed to the second-last bank. 8KB PRG-RAM at {@code $6000-$7FFF},
29
 * always readable/writable - this codebase doesn't model the PRG-RAM chip-enable bit (see above),
30
 * matching {@link Mmc1Mapper}'s own equivalent simplification.
31
 *
32
 * CHR: two 2KB windows (R0, R1) and four 1KB windows (R2-R5) tiling {@code $0000-$1FFF}; the CHR A12
33
 * inversion bit swaps which half ({@code $0000-$0FFF} or {@code $1000-$1FFF}) holds the 2KB windows
34
 * versus the 1KB ones - verified against nesdev.org's own bulleted "PPU $0000-$07FF (or $1000-$17FF)"
35
 * listing (not its separately-rendered summary table, which garbles this exact mapping - re-checked
36
 * directly against the page's raw HTML after that discrepancy surfaced). CHR-RAM (a single fixed 8KB
37
 * bank, banking registers simply ignored) on boards with no CHR-ROM in the file, same convention as
38
 * {@link NromMapper}/{@link Mmc1Mapper}.
39
 *
40
 * IRQ: a scanline counter clocked by a rising edge on the PPU address bus's A12 line (bit 12 going
41
 * 0→1) - on real hardware, filtered to require the line was low for a few PPU cycles first, to reject
42
 * spurious mid-fetch toggles. That filter is deliberately not modeled here: this codebase's PPU
43
 * ({@code PPU.readMemory}) drives every pattern-table fetch - background and sprite alike - through
44
 * {@link #readChr}, at the same real per-dot cadence real hardware uses, so a plain, unfiltered
45
 * 0→1 edge on {@link #readChr}'s own address already reproduces the intended "once per scanline"
46
 * signal for the standard (and by far most common) configuration nesdev itself documents as required
47
 * for the counter to work at all: background and sprites drawn from different pattern-table halves.
48
 * Counter semantics (verified against nesdev.org's "Counter operation"/"Important points" sections):
49
 * clocked on that edge, the counter reloads from the IRQ latch if it's currently zero or a reload was
50
 * requested (via {@code $C001}), otherwise it decrements; an IRQ is asserted whenever the
51
 * (post-clock) counter is zero and IRQs are enabled. The counter itself is never gated by the
52
 * enable/disable registers - only whether reaching zero actually asserts the IRQ line is.
53
 *
54
 * <p><b>Known limitation</b> (flagged by CodeRabbit review on PR #37, not yet fixed): the "no filter
55
 * needed" reasoning above only holds when every sprite fetched on a scanline reads from the same
56
 * pattern-table half - true for the standard background-at-{@code $0000}/sprites-at-{@code $1000}
57
 * (or vice versa) configuration nesdev documents as required for the counter to work at all, but not
58
 * for 8x16 sprites, where each sprite's own tile index (not a single shared PPUCTRL bit) picks its
59
 * pattern-table half. A frame mixing even- and odd-indexed 8x16 sprites can toggle A12 more than once
60
 * within one scanline's sprite-fetch phase, which this unfiltered edge detector would (incorrectly)
61
 * clock as multiple rises. Compounding this, {@code PPU.fetchSpritesForNextScanline()} still fetches
62
 * all 8 sprite slots (real and dummy) in one collapsed step at dot 257 rather than real hardware's
63
 * spread across dots 257-320, so even a correctly-filtered edge could land at the wrong simulated
64
 * instant relative to the scanline. Properly fixing this needs two coordinated changes neither made
65
 * here: PPU-cycle-aware low-time qualification in this class (real hardware requires A12 low for a
66
 * few PPU cycles before counting a rise), and un-collapsing the PPU's sprite fetch back into its own
67
 * per-slot dots so that timing information actually exists to qualify against - a bigger change than
68
 * this simplification was worth making speculatively, since no ROM this codebase currently runs
69
 * exercises 8x16-sprite MMC3 IRQ timing (Shadowgate's own mapper-4 conversion doesn't use the IRQ
70
 * mechanism at all, verified by instrumenting every {@code $8000-$FFFF} register write across full
71
 * playthroughs). Revisit if/when a ROM actually depends on this.
72
 */
73
public final class Mmc3Mapper implements Mapper {
74
    private static final int PRG_RAM_SIZE = 0x2000;
75
    private static final int PRG_ROM_START_ADDRESS = 0x8000;
76
    private static final int PRG_BANK_SIZE = 0x2000;
77
    private static final int CHR_WINDOW_SIZE = 0x2000;
78
    private static final int CHR_BANK_1KB = 0x400;
79
    private static final int CHR_A12_BIT = 0x1000;
80
81
    private static final int BANK_SELECT_REGISTER_MASK = 0x07;
82
    private static final int PRG_MODE_BIT = 0x40;
83
    private static final int CHR_INVERSION_BIT = 0x80;
84
    private static final int PRG_BANK_NUMBER_MASK = 0x3F; //MMC3 has only 6 PRG ROM address lines
85
    private static final int MIRRORING_REGISTER_START = 0xA000;
86
    private static final int IRQ_LATCH_REGISTER_START = 0xC000;
87
    private static final int IRQ_ENABLE_REGISTER_START = 0xE000;
88
89
    private final byte[] prgRom;
90
    private final RAM prgRam = new RAM(PRG_RAM_SIZE, "PRG-RAM");
91
92
    private final ChrMemory chr;
93
94
    /** R0-R7 - unspecified at power-on, same as real hardware */
95
    private final int[] bankRegister = new int[8];
96
    /** last value written to $8000: register-select bits, PRG mode bit, CHR inversion bit */
97
    private int bankSelect;
98
    private boolean horizontalMirroring;
99
100
    private int irqLatch;
101
    private int irqCounter;
102
    private boolean irqReloadRequested;
103
    private boolean irqEnabled;
104
    private boolean irqPending;
105
    private boolean lastChrAddressA12High;
106
107
    public Mmc3Mapper(final INesRom rom){
108
        this.prgRom = rom.prgRom();
109 2 1. <init> : negated conditional → KILLED
2. <init> : changed conditional boundary → KILLED
        if (prgRom.length < PRG_BANK_SIZE * 2){
110
            throw new IllegalArgumentException("MMC3 requires at least 16KB of PRG-ROM, got " + prgRom.length + " bytes");
111
        }
112
113
        this.chr = ChrMemory.of(rom, CHR_WINDOW_SIZE);
114
115
        //a reasonable initial hint, immediately overridden by the game's own $A000 write - real MMC3
116
        //hardware has no defined power-on mirroring state of its own (see class doc's "$8000... is
117
        //unspecified at power on" quote, equally true here)
118 1 1. <init> : negated conditional → KILLED
        this.horizontalMirroring = !rom.isVerticalMirroring();
119
    }
120
121
    /** Contract: only ever called with {@code address} in {@code $6000-$FFFF} (see {@link Mapper}'s class doc). */
122
    @Override
123
    public int read(final int address){
124 2 1. read : changed conditional boundary → KILLED
2. read : negated conditional → KILLED
        if (address >= PRG_ROM_START_ADDRESS){
125 2 1. read : replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::read → KILLED
2. read : Replaced bitwise AND with OR → KILLED
            return prgRom[prgRomOffset(address)] & BYTE_MASK;
126
        }
127 1 1. read : replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::read → KILLED
        return prgRam.read(address);
128
    }
129
130
    /** Contract: only ever called with {@code address} in {@code $6000-$FFFF} (see {@link Mapper}'s class doc). */
131
    @Override
132
    public void write(final int address, final int value){
133 2 1. write : changed conditional boundary → KILLED
2. write : negated conditional → KILLED
        if (address < PRG_ROM_START_ADDRESS){
134 1 1. write : removed call to com/rox/mem/RAM::write → KILLED
            prgRam.write(address, value);
135
            return;
136
        }
137 2 1. write : Replaced bitwise AND with OR → KILLED
2. write : negated conditional → KILLED
        final boolean even = (address & 1) == 0;
138 2 1. write : changed conditional boundary → KILLED
2. write : negated conditional → KILLED
        if (address < MIRRORING_REGISTER_START){
139 1 1. write : negated conditional → KILLED
            if (even){
140 1 1. write : Replaced bitwise AND with OR → KILLED
                bankSelect = value & BYTE_MASK;
141
            } else {
142 1 1. write : removed call to com/rox/cartridge/Mmc3Mapper::writeBankData → KILLED
                writeBankData(value);
143
            }
144 2 1. write : changed conditional boundary → KILLED
2. write : negated conditional → KILLED
        } else if (address < IRQ_LATCH_REGISTER_START){
145 1 1. write : negated conditional → KILLED
            if (even){
146 2 1. write : Replaced bitwise AND with OR → KILLED
2. write : negated conditional → KILLED
                horizontalMirroring = (value & 1) == 0;
147
            }
148
            //odd ($A001): PRG-RAM write-protect - deliberately not modeled, see class doc
149 2 1. write : negated conditional → KILLED
2. write : changed conditional boundary → KILLED
        } else if (address < IRQ_ENABLE_REGISTER_START){
150 1 1. write : negated conditional → KILLED
            if (even){
151 1 1. write : Replaced bitwise AND with OR → KILLED
                irqLatch = value & BYTE_MASK;
152
            } else {
153
                //"clears the MMC3 IRQ counter immediately, and then reloads it at the NEXT rising edge"
154
                irqCounter = 0;
155
                irqReloadRequested = true;
156
            }
157
        } else {
158 1 1. write : negated conditional → KILLED
            if (even){
159
                irqEnabled = false;
160
                irqPending = false; //"acknowledge any pending interrupts"
161
            } else {
162
                irqEnabled = true; //"the counter remains unaffected" - only future IRQ assertion is gated
163
            }
164
        }
165
    }
166
167
    private void writeBankData(final int value){
168 1 1. writeBankData : Replaced bitwise AND with OR → KILLED
        final int register = bankSelect & BANK_SELECT_REGISTER_MASK;
169
        final int masked = switch (register){
170 1 1. writeBankData : Replaced bitwise AND with OR → KILLED
            case 0, 1 -> value & ~1; //R0/R1: 2KB CHR banks - bottom bit ignored, always an even bank number
171 1 1. writeBankData : Replaced bitwise AND with OR → KILLED
            case 6, 7 -> value & PRG_BANK_NUMBER_MASK;
172 1 1. writeBankData : Replaced bitwise AND with OR → KILLED
            default -> value & BYTE_MASK;
173
        };
174
        bankRegister[register] = masked;
175
    }
176
177
    private int prgRomOffset(final int address){
178 1 1. prgRomOffset : Replaced integer subtraction with addition → KILLED
        final int windowOffset = address - PRG_ROM_START_ADDRESS; //0..0x7FFF
179 1 1. prgRomOffset : Replaced integer division with multiplication → KILLED
        final int window = windowOffset / PRG_BANK_SIZE; //0-3
180 1 1. prgRomOffset : Replaced integer division with multiplication → KILLED
        final int totalBanks = prgRom.length / PRG_BANK_SIZE;
181 2 1. prgRomOffset : Replaced bitwise AND with OR → KILLED
2. prgRomOffset : negated conditional → KILLED
        final boolean prgMode1 = (bankSelect & PRG_MODE_BIT) != 0;
182
        final int bank = switch (window){
183 3 1. prgRomOffset : Replaced integer modulus with multiplication → KILLED
2. prgRomOffset : Replaced integer subtraction with addition → KILLED
3. prgRomOffset : negated conditional → KILLED
            case 0 -> prgMode1 ? totalBanks - 2 : bankRegister[6] % totalBanks;
184 1 1. prgRomOffset : Replaced integer modulus with multiplication → KILLED
            case 1 -> bankRegister[7] % totalBanks;
185 3 1. prgRomOffset : negated conditional → KILLED
2. prgRomOffset : Replaced integer subtraction with addition → KILLED
3. prgRomOffset : Replaced integer modulus with multiplication → KILLED
            case 2 -> prgMode1 ? bankRegister[6] % totalBanks : totalBanks - 2;
186 1 1. prgRomOffset : Replaced integer subtraction with addition → KILLED
            default -> totalBanks - 1; //$E000-$FFFF: always the last bank
187
        };
188 4 1. prgRomOffset : Replaced integer multiplication with division → KILLED
2. prgRomOffset : replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::prgRomOffset → KILLED
3. prgRomOffset : Replaced integer addition with subtraction → KILLED
4. prgRomOffset : Replaced bitwise AND with OR → KILLED
        return bank * PRG_BANK_SIZE + (windowOffset & (PRG_BANK_SIZE - 1));
189
    }
190
191
    @Override
192
    public int readChr(final int address){
193 1 1. readChr : removed call to com/rox/cartridge/Mmc3Mapper::clockScanlineCounterOnA12RisingEdge → KILLED
        clockScanlineCounterOnA12RisingEdge(address);
194 1 1. readChr : replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::readChr → KILLED
        return chr.read(chrOffset(address));
195
    }
196
197
    /** No-op if Chr is ROM/Read-Only */
198
    @Override
199
    public void writeChr(final int address, final int value){
200 1 1. writeChr : removed call to com/rox/cartridge/ChrMemory::write → KILLED
        chr.write(chrOffset(address), value);
201
    }
202
203
    private void clockScanlineCounterOnA12RisingEdge(final int address){
204 2 1. clockScanlineCounterOnA12RisingEdge : negated conditional → KILLED
2. clockScanlineCounterOnA12RisingEdge : Replaced bitwise AND with OR → KILLED
        final boolean a12High = (address & CHR_A12_BIT) != 0;
205 2 1. clockScanlineCounterOnA12RisingEdge : negated conditional → KILLED
2. clockScanlineCounterOnA12RisingEdge : negated conditional → KILLED
        if (a12High && !lastChrAddressA12High){
206 2 1. clockScanlineCounterOnA12RisingEdge : negated conditional → KILLED
2. clockScanlineCounterOnA12RisingEdge : negated conditional → KILLED
            if (irqCounter == 0 || irqReloadRequested){
207
                irqCounter = irqLatch;
208
            } else {
209 1 1. clockScanlineCounterOnA12RisingEdge : Replaced integer subtraction with addition → KILLED
                irqCounter--;
210
            }
211
            irqReloadRequested = false;
212 2 1. clockScanlineCounterOnA12RisingEdge : negated conditional → KILLED
2. clockScanlineCounterOnA12RisingEdge : negated conditional → KILLED
            if (irqCounter == 0 && irqEnabled){
213
                irqPending = true;
214
            }
215
        }
216
        lastChrAddressA12High = a12High;
217
    }
218
219
    private int chrOffset(final int address){
220 1 1. chrOffset : Replaced bitwise AND with OR → KILLED
        final int a = address & (CHR_WINDOW_SIZE - 1);
221 2 1. chrOffset : negated conditional → KILLED
2. chrOffset : Replaced bitwise AND with OR → KILLED
        final boolean inverted = (bankSelect & CHR_INVERSION_BIT) != 0;
222 2 1. chrOffset : negated conditional → KILLED
2. chrOffset : Replaced XOR with AND → KILLED
        final int effective = inverted ? a ^ CHR_A12_BIT : a;
223 1 1. chrOffset : Replaced integer division with multiplication → KILLED
        final int region = effective / CHR_BANK_1KB; //0-7
224
        final int bank1k = switch (region){
225
            case 0 -> bankRegister[0];
226 1 1. chrOffset : Replaced integer addition with subtraction → KILLED
            case 1 -> bankRegister[0] + 1;
227
            case 2 -> bankRegister[1];
228 1 1. chrOffset : Replaced integer addition with subtraction → KILLED
            case 3 -> bankRegister[1] + 1;
229
            case 4 -> bankRegister[2];
230
            case 5 -> bankRegister[3];
231
            case 6 -> bankRegister[4];
232
            default -> bankRegister[5]; //region 7
233
        };
234
        //no separate "bank1k % totalKbBanks" wraparound step needed here: chrSize is always an exact
235
        //multiple of CHR_BANK_1KB, so the trailing "% chrSize" below already produces the identical
236
        //result on its own - (bank1k % n)*k % (n*k) == bank1k*k % (n*k) for any non-negative bank1k
237 1 1. chrOffset : Replaced bitwise AND with OR → KILLED
        final int offsetWithinBank = effective & (CHR_BANK_1KB - 1);
238 4 1. chrOffset : replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::chrOffset → KILLED
2. chrOffset : Replaced integer modulus with multiplication → KILLED
3. chrOffset : Replaced integer addition with subtraction → KILLED
4. chrOffset : Replaced integer multiplication with division → KILLED
        return (bank1k * CHR_BANK_1KB + offsetWithinBank) % chr.size();
239
    }
240
241
    @Override
242
    public Mirroring nametableMirroring(){
243 2 1. nametableMirroring : replaced return value with null for com/rox/cartridge/Mmc3Mapper::nametableMirroring → KILLED
2. nametableMirroring : negated conditional → KILLED
        return horizontalMirroring ? Mirroring.HORIZONTAL : Mirroring.VERTICAL;
244
    }
245
246
    @Override
247
    public boolean isIrqAsserted(){
248 2 1. isIrqAsserted : replaced boolean return with false for com/rox/cartridge/Mmc3Mapper::isIrqAsserted → KILLED
2. isIrqAsserted : replaced boolean return with true for com/rox/cartridge/Mmc3Mapper::isIrqAsserted → KILLED
        return irqPending;
249
    }
250
251
    @Override
252
    public int[] prgRam(){
253 1 1. prgRam : replaced return value with null for com/rox/cartridge/Mmc3Mapper::prgRam → KILLED
        return prgRam.snapshot();
254
    }
255
256
    @Override
257
    public void restorePrgRam(final int[] prgRam){
258 1 1. restorePrgRam : removed call to com/rox/mem/RAM::restore → KILLED
        this.prgRam.restore(prgRam);
259
    }
260
261
    int bankRegister(final int index){
262 1 1. bankRegister : replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::bankRegister → KILLED
        return bankRegister[index];
263
    }
264
265
    int bankSelect(){
266 1 1. bankSelect : replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::bankSelect → KILLED
        return bankSelect;
267
    }
268
269
    int irqCounter(){
270 1 1. irqCounter : replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::irqCounter → KILLED
        return irqCounter;
271
    }
272
273
    int irqLatch(){
274 1 1. irqLatch : replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::irqLatch → KILLED
        return irqLatch;
275
    }
276
277
    boolean irqEnabled(){
278 2 1. irqEnabled : replaced boolean return with false for com/rox/cartridge/Mmc3Mapper::irqEnabled → KILLED
2. irqEnabled : replaced boolean return with true for com/rox/cartridge/Mmc3Mapper::irqEnabled → KILLED
        return irqEnabled;
279
    }
280
281
    @Override
282
    public Map<String, String> debugState(){
283
        final Map<String, String> state = new LinkedHashMap<>();
284
        state.put("Bank select", String.format("$%02X", bankSelect));
285 2 1. debugState : negated conditional → KILLED
2. debugState : changed conditional boundary → KILLED
        for (int i = 0; i < bankRegister.length; i++){
286
            state.put("R" + i, String.format("$%02X", bankRegister[i]));
287
        }
288
        state.put("IRQ latch", String.format("$%02X", irqLatch));
289
        state.put("IRQ counter", String.format("$%02X", irqCounter));
290
        state.put("IRQ enabled", String.valueOf(irqEnabled));
291 1 1. debugState : replaced return value with Collections.emptyMap for com/rox/cartridge/Mmc3Mapper::debugState → KILLED
        return state;
292
    }
293
294
    @Override
295
    public MapperSnapshot snapshot(){
296 1 1. snapshot : replaced return value with null for com/rox/cartridge/Mmc3Mapper::snapshot → KILLED
        return new Mmc3MapperSnapshot(prgRam.snapshot(), chr.snapshot(), bankRegister.clone(), bankSelect,
297
                horizontalMirroring, irqLatch, irqCounter, irqReloadRequested, irqEnabled, irqPending,
298
                lastChrAddressA12High);
299
    }
300
301
    @Override
302
    public void checkRestorable(final MapperSnapshot snapshot){
303
        final Mmc3MapperSnapshot mmc3 = SnapshotArrays.expect(snapshot, Mmc3MapperSnapshot.class);
304 1 1. checkRestorable : removed call to com/rox/mem/RAM::checkRestorable → KILLED
        prgRam.checkRestorable(mmc3.prgRam());
305 1 1. checkRestorable : removed call to com/rox/cartridge/ChrMemory::checkRestorable → KILLED
        chr.checkRestorable(mmc3.chrRam());
306 1 1. checkRestorable : removed call to com/rox/cartridge/SnapshotArrays::requireSameSize → KILLED
        SnapshotArrays.requireSameSize(mmc3.bankRegisters(), bankRegister, "bank registers");
307
    }
308
309
    @Override
310
    public void restore(final MapperSnapshot snapshot){
311 1 1. restore : removed call to com/rox/cartridge/Mmc3Mapper::checkRestorable → KILLED
        checkRestorable(snapshot);
312
        final Mmc3MapperSnapshot mmc3 = (Mmc3MapperSnapshot) snapshot;
313 1 1. restore : removed call to com/rox/mem/RAM::restore → KILLED
        prgRam.restore(mmc3.prgRam());
314 1 1. restore : removed call to com/rox/cartridge/ChrMemory::restore → KILLED
        chr.restore(mmc3.chrRam());
315 1 1. restore : removed call to com/rox/cartridge/SnapshotArrays::copy → KILLED
        SnapshotArrays.copy(mmc3.bankRegisters(), bankRegister);
316
        bankSelect = mmc3.bankSelect();
317
        horizontalMirroring = mmc3.horizontalMirroring();
318
        irqLatch = mmc3.irqLatch();
319
        irqCounter = mmc3.irqCounter();
320
        irqReloadRequested = mmc3.irqReloadRequested();
321
        irqEnabled = mmc3.irqEnabled();
322
        irqPending = mmc3.irqPending();
323
        lastChrAddressA12High = mmc3.lastChrAddressA12High();
324
    }
325
}

Mutations

109

1.1
Location : <init>
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:rejectsPrgRomSmallerThan16Kb()]
negated conditional → KILLED

2.2
Location : <init>
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:acceptsPrgRomOfExactly16Kb()]
changed conditional boundary → KILLED

118

1.1
Location : <init>
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringDefaultsFromTheHeaderBitBeforeAnyA000Write()]
negated conditional → KILLED

124

1.1
Location : read
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
changed conditional boundary → KILLED

2.2
Location : read
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:writeMasksValueTo8Bits()]
negated conditional → KILLED

125

1.1
Location : read
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::read → KILLED

2.2
Location : read
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
Replaced bitwise AND with OR → KILLED

127

1.1
Location : read
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:writeMasksValueTo8Bits()]
replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::read → KILLED

133

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:bankSelectStoresTheRawWrittenValueIncludingModeAndInversionBits()]
changed conditional boundary → KILLED

2.2
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringBitOneMeansVertical()]
negated conditional → KILLED

134

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgRamReadsBackWhatWasWritten()]
removed call to com/rox/mem/RAM::write → KILLED

137

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringBitOneMeansVertical()]
Replaced bitwise AND with OR → KILLED

2.2
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringBitOneMeansVertical()]
negated conditional → KILLED

138

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringBitOneMeansVertical()]
changed conditional boundary → KILLED

2.2
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringBitOneMeansVertical()]
negated conditional → KILLED

139

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:bankSelectStoresTheRawWrittenValueIncludingModeAndInversionBits()]
negated conditional → KILLED

140

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:bankSelectStoresTheRawWrittenValueIncludingModeAndInversionBits()]
Replaced bitwise AND with OR → KILLED

142

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:r6AndR7IgnoreTheTopTwoBitsOfTheWrittenValue()]
removed call to com/rox/cartridge/Mmc3Mapper::writeBankData → KILLED

144

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqLatchStoresTheWrittenValue()]
changed conditional boundary → KILLED

2.2
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringBitOneMeansVertical()]
negated conditional → KILLED

145

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringBitOneMeansVertical()]
negated conditional → KILLED

146

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringBitZeroMeansHorizontal()]
Replaced bitwise AND with OR → KILLED

2.2
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringBitZeroMeansHorizontal()]
negated conditional → KILLED

149

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqEnableAndDisableToggleTheEnabledFlag()]
negated conditional → KILLED

2.2
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqEnableAndDisableToggleTheEnabledFlag()]
changed conditional boundary → KILLED

150

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqLatchStoresTheWrittenValue()]
negated conditional → KILLED

151

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqLatchStoresTheWrittenValue()]
Replaced bitwise AND with OR → KILLED

158

1.1
Location : write
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqEnableAndDisableToggleTheEnabledFlag()]
negated conditional → KILLED

168

1.1
Location : writeBankData
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:r6AndR7IgnoreTheTopTwoBitsOfTheWrittenValue()]
Replaced bitwise AND with OR → KILLED

170

1.1
Location : writeBankData
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:twoKbChrRegistersIgnoreTheBottomBit()]
Replaced bitwise AND with OR → KILLED

171

1.1
Location : writeBankData
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:r6AndR7IgnoreTheTopTwoBitsOfTheWrittenValue()]
Replaced bitwise AND with OR → KILLED

172

1.1
Location : writeBankData
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrInversionOneSwapsWhichHalfHoldsTheTwoKbWindows()]
Replaced bitwise AND with OR → KILLED

178

1.1
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
Replaced integer subtraction with addition → KILLED

179

1.1
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
Replaced integer division with multiplication → KILLED

180

1.1
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
Replaced integer division with multiplication → KILLED

181

1.1
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:bankNumbersWrapModuloTheRomsActualBankCount()]
Replaced bitwise AND with OR → KILLED

2.2
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
negated conditional → KILLED

183

1.1
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:bankNumbersWrapModuloTheRomsActualBankCount()]
Replaced integer modulus with multiplication → KILLED

2.2
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
Replaced integer subtraction with addition → KILLED

3.3
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
negated conditional → KILLED

184

1.1
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:r7AlwaysDrivesA000RegardlessOfPrgMode()]
Replaced integer modulus with multiplication → KILLED

185

1.1
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
negated conditional → KILLED

2.2
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeZeroPutsR6At8000AndFixesCDfffToSecondLast()]
Replaced integer subtraction with addition → KILLED

3.3
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
Replaced integer modulus with multiplication → KILLED

186

1.1
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
Replaced integer subtraction with addition → KILLED

188

1.1
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
Replaced integer multiplication with division → KILLED

2.2
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::prgRomOffset → KILLED

3.3
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgReadsRespectTheOffsetWithinTheSelectedBankNotJustItsFirstByte()]
Replaced integer addition with subtraction → KILLED

4.4
Location : prgRomOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgModeOnePutsR6AtC000AndFixes8000To9fffToSecondLast()]
Replaced bitwise AND with OR → KILLED

193

1.1
Location : readChr
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:counterReloadsWhenClockedWhileAlreadyZero()]
removed call to com/rox/cartridge/Mmc3Mapper::clockScanlineCounterOnA12RisingEdge → KILLED

194

1.1
Location : readChr
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:noChrBanksMeansWritableChrRam()]
replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::readChr → KILLED

200

1.1
Location : writeChr
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:noChrBanksMeansWritableChrRam()]
removed call to com/rox/cartridge/ChrMemory::write → KILLED

204

1.1
Location : clockScanlineCounterOnA12RisingEdge
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:counterReloadsWhenClockedWhileAlreadyZero()]
negated conditional → KILLED

2.2
Location : clockScanlineCounterOnA12RisingEdge
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:aRisingEdgeOnA12DecrementsANonZeroCounter()]
Replaced bitwise AND with OR → KILLED

205

1.1
Location : clockScanlineCounterOnA12RisingEdge
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:counterReloadsWhenClockedWhileAlreadyZero()]
negated conditional → KILLED

2.2
Location : clockScanlineCounterOnA12RisingEdge
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:counterReloadsWhenClockedWhileAlreadyZero()]
negated conditional → KILLED

206

1.1
Location : clockScanlineCounterOnA12RisingEdge
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:aRisingEdgeOnA12DecrementsANonZeroCounter()]
negated conditional → KILLED

2.2
Location : clockScanlineCounterOnA12RisingEdge
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:counterReloadsWhenClockedWhileAlreadyZero()]
negated conditional → KILLED

209

1.1
Location : clockScanlineCounterOnA12RisingEdge
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:aRisingEdgeOnA12DecrementsANonZeroCounter()]
Replaced integer subtraction with addition → KILLED

212

1.1
Location : clockScanlineCounterOnA12RisingEdge
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqDisableAcknowledgesAPendingInterrupt()]
negated conditional → KILLED

2.2
Location : clockScanlineCounterOnA12RisingEdge
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqDisableAcknowledgesAPendingInterrupt()]
negated conditional → KILLED

220

1.1
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrBankNumbersWrapModuloTheRomsActualBankCount()]
Replaced bitwise AND with OR → KILLED

221

1.1
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrBankNumbersWrapModuloTheRomsActualBankCount()]
negated conditional → KILLED

2.2
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrBankNumbersWrapModuloTheRomsActualBankCount()]
Replaced bitwise AND with OR → KILLED

222

1.1
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrBankNumbersWrapModuloTheRomsActualBankCount()]
negated conditional → KILLED

2.2
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrInversionOneSwapsWhichHalfHoldsTheTwoKbWindows()]
Replaced XOR with AND → KILLED

223

1.1
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrBankNumbersWrapModuloTheRomsActualBankCount()]
Replaced integer division with multiplication → KILLED

226

1.1
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrInversionZeroPutsTheTwoKbWindowsAt0000And0800()]
Replaced integer addition with subtraction → KILLED

228

1.1
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrInversionZeroPutsTheTwoKbWindowsAt0000And0800()]
Replaced integer addition with subtraction → KILLED

237

1.1
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrBankNumbersWrapModuloTheRomsActualBankCount()]
Replaced bitwise AND with OR → KILLED

238

1.1
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrBankNumbersWrapModuloTheRomsActualBankCount()]
replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::chrOffset → KILLED

2.2
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:noChrBanksMeansWritableChrRam()]
Replaced integer modulus with multiplication → KILLED

3.3
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:noChrBanksMeansWritableChrRam()]
Replaced integer addition with subtraction → KILLED

4.4
Location : chrOffset
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:chrBankNumbersWrapModuloTheRomsActualBankCount()]
Replaced integer multiplication with division → KILLED

243

1.1
Location : nametableMirroring
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringDefaultsFromTheHeaderBitBeforeAnyA000Write()]
replaced return value with null for com/rox/cartridge/Mmc3Mapper::nametableMirroring → KILLED

2.2
Location : nametableMirroring
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:mirroringDefaultsFromTheHeaderBitBeforeAnyA000Write()]
negated conditional → KILLED

248

1.1
Location : isIrqAsserted
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqDisableAcknowledgesAPendingInterrupt()]
replaced boolean return with false for com/rox/cartridge/Mmc3Mapper::isIrqAsserted → KILLED

2.2
Location : isIrqAsserted
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqDisableAcknowledgesAPendingInterrupt()]
replaced boolean return with true for com/rox/cartridge/Mmc3Mapper::isIrqAsserted → KILLED

253

1.1
Location : prgRam
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:prgRamRoundTripsThroughRestore()]
replaced return value with null for com/rox/cartridge/Mmc3Mapper::prgRam → KILLED

258

1.1
Location : restorePrgRam
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:restorePrgRamRejectsTheWrongLength()]
removed call to com/rox/mem/RAM::restore → KILLED

262

1.1
Location : bankRegister
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:r6AndR7IgnoreTheTopTwoBitsOfTheWrittenValue()]
replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::bankRegister → KILLED

266

1.1
Location : bankSelect
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:bankSelectStoresTheRawWrittenValueIncludingModeAndInversionBits()]
replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::bankSelect → KILLED

270

1.1
Location : irqCounter
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:counterReloadsWhenClockedWhileAlreadyZero()]
replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::irqCounter → KILLED

274

1.1
Location : irqLatch
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqLatchStoresTheWrittenValue()]
replaced int return with 0 for com/rox/cartridge/Mmc3Mapper::irqLatch → KILLED

278

1.1
Location : irqEnabled
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqEnableAndDisableToggleTheEnabledFlag()]
replaced boolean return with false for com/rox/cartridge/Mmc3Mapper::irqEnabled → KILLED

2.2
Location : irqEnabled
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:irqEnableAndDisableToggleTheEnabledFlag()]
replaced boolean return with true for com/rox/cartridge/Mmc3Mapper::irqEnabled → KILLED

285

1.1
Location : debugState
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:debugStateReportsBankSelectAllEightBankRegistersAndIrqState()]
negated conditional → KILLED

2.2
Location : debugState
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:debugStateReportsBankSelectAllEightBankRegistersAndIrqState()]
changed conditional boundary → KILLED

291

1.1
Location : debugState
Killed by : com.rox.cartridge.Mmc3MapperTest.[engine:junit-jupiter]/[class:com.rox.cartridge.Mmc3MapperTest]/[method:debugStateReportsBankSelectAllEightBankRegistersAndIrqState()]
replaced return value with Collections.emptyMap for com/rox/cartridge/Mmc3Mapper::debugState → KILLED

296

1.1
Location : snapshot
Killed by : com.rox.cartridge.MapperSnapshotTest.[engine:junit-jupiter]/[class:com.rox.cartridge.MapperSnapshotTest]/[method:mmc3RejectsTheWrongNumberOfBankRegisters()]
replaced return value with null for com/rox/cartridge/Mmc3Mapper::snapshot → KILLED

304

1.1
Location : checkRestorable
Killed by : com.rox.cartridge.MapperSnapshotTest.[engine:junit-jupiter]/[class:com.rox.cartridge.MapperSnapshotTest]/[test-template:checkRestorableRejectsWhicheverArrayIsWrong(java.lang.String, java.lang.String)]/[test-template-invocation:#5]
removed call to com/rox/mem/RAM::checkRestorable → KILLED

305

1.1
Location : checkRestorable
Killed by : com.rox.cartridge.MapperSnapshotTest.[engine:junit-jupiter]/[class:com.rox.cartridge.MapperSnapshotTest]/[test-template:checkRestorableRejectsWhicheverArrayIsWrong(java.lang.String, java.lang.String)]/[test-template-invocation:#6]
removed call to com/rox/cartridge/ChrMemory::checkRestorable → KILLED

306

1.1
Location : checkRestorable
Killed by : com.rox.cartridge.MapperSnapshotTest.[engine:junit-jupiter]/[class:com.rox.cartridge.MapperSnapshotTest]/[method:mmc3RejectsTheWrongNumberOfBankRegisters()]
removed call to com/rox/cartridge/SnapshotArrays::requireSameSize → KILLED

311

1.1
Location : restore
Killed by : com.rox.cartridge.MapperSnapshotTest.[engine:junit-jupiter]/[class:com.rox.cartridge.MapperSnapshotTest]/[method:mmc3RejectsTheWrongNumberOfBankRegisters()]
removed call to com/rox/cartridge/Mmc3Mapper::checkRestorable → KILLED

313

1.1
Location : restore
Killed by : com.rox.cartridge.MapperSnapshotTest.[engine:junit-jupiter]/[class:com.rox.cartridge.MapperSnapshotTest]/[method:mmc3RoundTripsAPendingIrqAndAReloadRequest()]
removed call to com/rox/mem/RAM::restore → KILLED

314

1.1
Location : restore
Killed by : com.rox.cartridge.MapperSnapshotTest.[engine:junit-jupiter]/[class:com.rox.cartridge.MapperSnapshotTest]/[method:mmc3RoundTripsAPendingIrqAndAReloadRequest()]
removed call to com/rox/cartridge/ChrMemory::restore → KILLED

315

1.1
Location : restore
Killed by : com.rox.cartridge.MapperSnapshotTest.[engine:junit-jupiter]/[class:com.rox.cartridge.MapperSnapshotTest]/[method:mmc3RoundTripsAPendingIrqAndAReloadRequest()]
removed call to com/rox/cartridge/SnapshotArrays::copy → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1