broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    pc, priv, mie, mtvec, events = args
    mpie = mpp = mcause = mepc = 0
    log = []
    for ev in events:
        kind = ev[0]
        trap = None
        if kind == 'step':
            pc += 4
        elif kind == 'ecall':
            trap = 8 + priv
        elif kind == 'illegal':
            trap = 2
        elif kind == 'irq':
            if priv < 3 or mie:
                trap = (1 << 31) | ev[1]
        elif kind == 'mret':
            mie = mpie
            mpie = 1
            priv = mpp
            pc = mepc
        if trap is not None:
            mepc = pc
            mcause = trap
            mpie = mie
            mie = 0
            mpp = priv
            priv = 3
            base = mtvec & ~3
            pc = base + 4 * (trap & 0x7FFFFFFF) if (mtvec & 3) == 1 and trap >> 31 else base
        log.append([pc, priv, mie, mpie, mpp, mcause, mepc])
    return log
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('user ecall and return', [1028, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1032, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1032], [4100, 3, 0, 1, 0, 8, 1032], [1032, 0, 1, 1, 0, 8, 1032]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 10]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4136, 3, 0, 0, 0, 2147483658, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 4354, [['ecall'], ['mret']]], [[4352, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096]])], [('user ecall and return', [1032, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1036, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1036], [4100, 3, 0, 1, 0, 8, 1036], [1036, 0, 1, 1, 0, 8, 1036]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 11]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4140, 3, 0, 0, 0, 2147483659, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 4610, [['ecall'], ['mret']]], [[4608, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096], [4104, 0, 1, 1, 0, 2, 4096]])], [('user ecall and return', [1036, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1040, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1040], [4100, 3, 0, 1, 0, 8, 1040], [1040, 0, 1, 1, 0, 8, 1040]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 10]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4136, 3, 0, 0, 0, 2147483658, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 4866, [['ecall'], ['mret']]], [[4864, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step'], ['step'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096], [4104, 0, 1, 1, 0, 2, 4096], [4108, 0, 1, 1, 0, 2, 4096]])], [('user ecall and return', [1040, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1044, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1044], [4100, 3, 0, 1, 0, 8, 1044], [1044, 0, 1, 1, 0, 8, 1044]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 11]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4140, 3, 0, 0, 0, 2147483659, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 5122, [['ecall'], ['mret']]], [[5120, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step'], ['step'], ['step'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096], [4104, 0, 1, 1, 0, 2, 4096], [4108, 0, 1, 1, 0, 2, 4096], [4112, 0, 1, 1, 0, 2, 4096]])], [('user ecall and return', [1044, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1048, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1048], [4100, 3, 0, 1, 0, 8, 1048], [1048, 0, 1, 1, 0, 8, 1048]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 10]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4136, 3, 0, 0, 0, 2147483658, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 5378, [['ecall'], ['mret']]], [[5376, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step'], ['step'], ['step'], ['step'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096], [4104, 0, 1, 1, 0, 2, 4096], [4108, 0, 1, 1, 0, 2, 4096], [4112, 0, 1, 1, 0, 2, 4096], [4116, 0, 1, 1, 0, 2, 4096]])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    pc, priv, mie, mtvec, events = args
    mpie = mpp = mcause = mepc = 0
    log = []
    for ev in events:
        kind = ev[0]
        trap = None
        if kind == 'step':
            pc += 4
        elif kind == 'ecall':
            trap = 8 + priv
        elif kind == 'illegal':
            trap = 2
        elif kind == 'irq':
            if priv < 3 or mie:
                trap = (1 << 31) | ev[1]
        elif kind == 'mret':
            mie = mpie
            mpie = 1
            priv = mpp
            mpp = 3
            pc = mepc
        if trap is not None:
            mepc = pc
            mcause = trap
            mpie = mie
            mie = 0
            mpp = priv
            priv = 3
            base = mtvec & ~3
            pc = base + 4 * (trap & 0x7FFFFFFF) if (mtvec & 3) == 1 and trap >> 31 else base
        log.append([pc, priv, mie, mpie, mpp, mcause, mepc])
    return log
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('user ecall and return', [1028, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1032, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1032], [4100, 3, 0, 1, 0, 8, 1032], [1032, 0, 1, 1, 0, 8, 1032]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 10]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4136, 3, 0, 0, 0, 2147483658, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 4354, [['ecall'], ['mret']]], [[4352, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096]])], [('user ecall and return', [1032, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1036, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1036], [4100, 3, 0, 1, 0, 8, 1036], [1036, 0, 1, 1, 0, 8, 1036]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 11]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4140, 3, 0, 0, 0, 2147483659, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 4610, [['ecall'], ['mret']]], [[4608, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096], [4104, 0, 1, 1, 0, 2, 4096]])], [('user ecall and return', [1036, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1040, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1040], [4100, 3, 0, 1, 0, 8, 1040], [1040, 0, 1, 1, 0, 8, 1040]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 10]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4136, 3, 0, 0, 0, 2147483658, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 4866, [['ecall'], ['mret']]], [[4864, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step'], ['step'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096], [4104, 0, 1, 1, 0, 2, 4096], [4108, 0, 1, 1, 0, 2, 4096]])], [('user ecall and return', [1040, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1044, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1044], [4100, 3, 0, 1, 0, 8, 1044], [1044, 0, 1, 1, 0, 8, 1044]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 11]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4140, 3, 0, 0, 0, 2147483659, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 5122, [['ecall'], ['mret']]], [[5120, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step'], ['step'], ['step'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096], [4104, 0, 1, 1, 0, 2, 4096], [4108, 0, 1, 1, 0, 2, 4096], [4112, 0, 1, 1, 0, 2, 4096]])], [('user ecall and return', [1044, 0, 1, 4096, [['step'], ['ecall'], ['step'], ['mret']]], [[1048, 0, 1, 0, 0, 0, 0], [4096, 3, 0, 1, 0, 8, 1048], [4100, 3, 0, 1, 0, 8, 1048], [1048, 0, 1, 1, 0, 8, 1048]]), ('supervisor and machine ecall', [1024, 1, 0, 4096, [['ecall'], ['ecall'], ['mret'], ['mret']]], [[4096, 3, 0, 0, 1, 9, 1024], [4096, 3, 0, 0, 3, 11, 4096], [4096, 3, 0, 1, 0, 11, 4096], [4096, 0, 1, 1, 0, 11, 4096]]), ('supervisor interrupt with mie clear', [1280, 1, 0, 4097, [['irq', 7], ['mret'], ['step']]], [[4124, 3, 0, 0, 1, 2147483655, 1280], [1280, 1, 0, 1, 0, 2147483655, 1280], [1284, 1, 0, 1, 0, 2147483655, 1280]]), ('machine interrupt masked then enabled', [1536, 3, 0, 4097, [['irq', 3], ['step'], ['mret'], ['irq', 10]]], [[1536, 3, 0, 0, 0, 0, 0], [1540, 3, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [4136, 3, 0, 0, 0, 2147483658, 0]]), ('machine interrupt enabled saves mie', [1792, 3, 1, 8192, [['irq', 7], ['mret'], ['step']]], [[8192, 3, 0, 1, 3, 2147483655, 1792], [1792, 3, 1, 1, 0, 2147483655, 1792], [1796, 3, 1, 1, 0, 2147483655, 1792]]), ('vectored mode exceptions go to base', [2048, 0, 1, 12289, [['illegal'], ['mret'], ['ecall']]], [[12288, 3, 0, 1, 0, 2, 2048], [2048, 0, 1, 1, 0, 2, 2048], [12288, 3, 0, 1, 0, 8, 2048]]), ('reserved mode bits masked', [2560, 1, 1, 5378, [['ecall'], ['mret']]], [[5376, 3, 0, 1, 1, 9, 2560], [2560, 1, 1, 1, 0, 9, 2560]]), ('nested trap overwrites mpp', [2304, 0, 1, 4096, [['ecall'], ['illegal'], ['mret'], ['mret'], ['step'], ['step'], ['step'], ['step'], ['step']]], [[4096, 3, 0, 1, 0, 8, 2304], [4096, 3, 0, 0, 3, 2, 4096], [4096, 3, 0, 1, 0, 2, 4096], [4096, 0, 1, 1, 0, 2, 4096], [4100, 0, 1, 1, 0, 2, 4096], [4104, 0, 1, 1, 0, 2, 4096], [4108, 0, 1, 1, 0, 2, 4096], [4112, 0, 1, 1, 0, 2, 4096], [4116, 0, 1, 1, 0, 2, 4096]])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A second mret without an intervening trap returns to the old privilege instead of user mode.

Input [pc, priv, mie, mtvec, events]; MPIE, MPP, mcause, mepc start 0. step: pc += 4. ecall: exception cause 8 + priv (U 8, S 9, M 11). illegal: cause 2. irq k: interrupt cause 2^31 | k, taken only if priv < 3 or MIE. Trap: mepc = pc, mcause = cause, MPIE = MIE, MIE = 0, MPP = priv, priv = 3, pc = mtvec base (mtvec & ~3), plus 4*k for interrupts when mtvec mode (low 2 bits) is 1. mret: MIE = MPIE, MPIE = 1, priv = MPP, MPP = 0, pc = mepc. Return [pc, priv, MIE, MPIE, MPP, mcause, mepc] after each event.

split: open-access


meaning: Fixture-count band, not measured model difficulty

deps: stdlib

prompt:
rol feeds bit 7 back into bit 0 instead of the carry flag.

Input [a, c, ops] with ops asl, lsr, rol, ror, asr on an 8-bit value and a carry bit. asl: C = bit 7, shift left. lsr: C = bit 0, shift right with 0. rol: shift left, bit 0 = old C, new C = old bit 7. ror: shift right, bit 7 = old C, new C = old bit 0. asr: C = bit 0, shift right keeping bit 7. Report [A, C, Z, N] after each op.

split: open-access


prompt:
ror moves bit 0 into bit 7 rather than the old carry.

Input [a, c, ops] with ops asl, lsr, rol, ror, asr on an 8-bit value and a carry bit. asl: C = bit 7, shift left. lsr: C = bit 0, shift right with 0. rol: shift left, bit 0 = old C, new C = old bit 7. ror: shift right, bit 7 = old C, new C = old bit 0. asr: C = bit 0, shift right keeping bit 7. Report [A, C, Z, N] after each op.

split: open-access


prompt:
rol shifts the outgoing bit 7 back in because carry is updated first.

Input [a, c, ops] with ops asl, lsr, rol, ror, asr on an 8-bit value and a carry bit. asl: C = bit 7, shift left. lsr: C = bit 0, shift right with 0. rol: shift left, bit 0 = old C, new C = old bit 7. ror: shift right, bit 7 = old C, new C = old bit 0. asr: C = bit 0, shift right keeping bit 7. Report [A, C, Z, N] after each op.

split: open-access


prompt:
asr of a negative value turns it positive.

Input [a, c, ops] with ops asl, lsr, rol, ror, asr on an 8-bit value and a carry bit. asl: C = bit 7, shift left. lsr: C = bit 0, shift right with 0. rol: shift left, bit 0 = old C, new C = old bit 7. ror: shift right, bit 7 = old C, new C = old bit 0. asr: C = bit 0, shift right keeping bit 7. Report [A, C, Z, N] after each op.

split: open-access


prompt:
lsr reports bit 1 of the original value as carry.

Input [a, c, ops] with ops asl, lsr, rol, ror, asr on an 8-bit value and a carry bit. asl: C = bit 7, shift left. lsr: C = bit 0, shift right with 0. rol: shift left, bit 0 = old C, new C = old bit 7. ror: shift right, bit 7 = old C, new C = old bit 0. asr: C = bit 0, shift right keeping bit 7. Report [A, C, Z, N] after each op.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x1FFF
        elif addr < 0x4000: dev, key = ppu, addr & 7
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % rom_size
        if kind == 'w':
            bus = op[2] & 0xFF
            if dev is not None and dev != 'rom':
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            elif dev is not None: bus = dev.get(key, 0)
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0xFFF
        elif addr < 0x4000: dev, key = ppu, addr & 7
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % rom_size
        if kind == 'w':
            bus = op[2] & 0xFF
            if dev is not None and dev != 'rom':
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            elif dev is not None: bus = dev.get(key, 0)
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A byte written at 0x0801 is not visible at 0x0001.

Input [rom_size, sram_enabled, ops] with ops ['r', addr] or ['w', addr, value] on a 16-bit bus. 0x0000-0x1FFF: 2 KiB RAM mirrored every 0x800. 0x2000-0x3FFF: 8 video registers mirrored every 8 bytes. 0x4000-0x4017: I/O registers. 0x4018-0x5FFF: unmapped. 0x6000-0x7FFF: SRAM when enabled, else unmapped. 0x8000-0xFFFF: ROM of rom_size bytes mirrored to fill the window, byte at offset o = (7o + (o >> 8) + 3) & 0xFF, writes ignored. Every write drives its value onto the data bus; reads of unmapped space return the last bus value, other reads drive the bus. Unwritten RAM/register/SRAM bytes read 0. Writes yield None, reads the value.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x7FF
        elif addr < 0x4000: dev, key = ppu, addr - 0x2000
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % rom_size
        if kind == 'w':
            bus = op[2] & 0xFF
            if dev is not None and dev != 'rom':
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            elif dev is not None: bus = dev.get(key, 0)
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x7FF
        elif addr < 0x4000: dev, key = ppu, addr & 0xF
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % rom_size
        if kind == 'w':
            bus = op[2] & 0xFF
            if dev is not None and dev != 'rom':
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            elif dev is not None: bus = dev.get(key, 0)
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Writing 0x2008 does not affect register 0 and reading 0x3FF8 returns 0.

Input [rom_size, sram_enabled, ops] with ops ['r', addr] or ['w', addr, value] on a 16-bit bus. 0x0000-0x1FFF: 2 KiB RAM mirrored every 0x800. 0x2000-0x3FFF: 8 video registers mirrored every 8 bytes. 0x4000-0x4017: I/O registers. 0x4018-0x5FFF: unmapped. 0x6000-0x7FFF: SRAM when enabled, else unmapped. 0x8000-0xFFFF: ROM of rom_size bytes mirrored to fill the window, byte at offset o = (7o + (o >> 8) + 3) & 0xFF, writes ignored. Every write drives its value onto the data bus; reads of unmapped space return the last bus value, other reads drive the bus. Unwritten RAM/register/SRAM bytes read 0. Writes yield None, reads the value.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x7FF
        elif addr < 0x4000: dev, key = ppu, addr & 7
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % rom_size
        if kind == 'w':
            bus = op[2] & 0xFF
            if dev is not None and dev != 'rom':
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            else: bus = dev.get(key, 0) if dev is not None else 0
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x7FF
        elif addr < 0x4000: dev, key = ppu, addr & 7
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % rom_size
        if kind == 'w':
            bus = op[2] & 0xFF
            if dev is not None and dev != 'rom':
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            else: bus = dev.get(key, 0) if dev is not None else 0xFF
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Reading unmapped space returns 0 instead of the last value on the data bus.

Input [rom_size, sram_enabled, ops] with ops ['r', addr] or ['w', addr, value] on a 16-bit bus. 0x0000-0x1FFF: 2 KiB RAM mirrored every 0x800. 0x2000-0x3FFF: 8 video registers mirrored every 8 bytes. 0x4000-0x4017: I/O registers. 0x4018-0x5FFF: unmapped. 0x6000-0x7FFF: SRAM when enabled, else unmapped. 0x8000-0xFFFF: ROM of rom_size bytes mirrored to fill the window, byte at offset o = (7o + (o >> 8) + 3) & 0xFF, writes ignored. Every write drives its value onto the data bus; reads of unmapped space return the last bus value, other reads drive the bus. Unwritten RAM/register/SRAM bytes read 0. Writes yield None, reads the value.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x7FF
        elif addr < 0x4000: dev, key = ppu, addr & 7
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) & 0x7FFF
        if kind == 'w':
            bus = op[2] & 0xFF
            if dev is not None and dev != 'rom':
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            elif dev is not None: bus = dev.get(key, 0)
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x7FF
        elif addr < 0x4000: dev, key = ppu, addr & 7
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % 0x4000
        if kind == 'w':
            bus = op[2] & 0xFF
            if dev is not None and dev != 'rom':
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            elif dev is not None: bus = dev.get(key, 0)
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Reads from 0xC000 upward return bytes past the end of a 16 KiB ROM.

Input [rom_size, sram_enabled, ops] with ops ['r', addr] or ['w', addr, value] on a 16-bit bus. 0x0000-0x1FFF: 2 KiB RAM mirrored every 0x800. 0x2000-0x3FFF: 8 video registers mirrored every 8 bytes. 0x4000-0x4017: I/O registers. 0x4018-0x5FFF: unmapped. 0x6000-0x7FFF: SRAM when enabled, else unmapped. 0x8000-0xFFFF: ROM of rom_size bytes mirrored to fill the window, byte at offset o = (7o + (o >> 8) + 3) & 0xFF, writes ignored. Every write drives its value onto the data bus; reads of unmapped space return the last bus value, other reads drive the bus. Unwritten RAM/register/SRAM bytes read 0. Writes yield None, reads the value.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x7FF
        elif addr < 0x4000: dev, key = ppu, addr & 7
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % rom_size
        if kind == 'w':
            if dev is not None and dev != 'rom':
                bus = op[2] & 0xFF
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            elif dev is not None: bus = dev.get(key, 0)
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x7FF
        elif addr < 0x4000: dev, key = ppu, addr & 7
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % rom_size
        if kind == 'w':
            if dev is not None:
                bus = op[2] & 0xFF
                if dev != 'rom':
                    dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            elif dev is not None: bus = dev.get(key, 0)
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A read of unmapped space after an unmapped write returns an older bus value.

Input [rom_size, sram_enabled, ops] with ops ['r', addr] or ['w', addr, value] on a 16-bit bus. 0x0000-0x1FFF: 2 KiB RAM mirrored every 0x800. 0x2000-0x3FFF: 8 video registers mirrored every 8 bytes. 0x4000-0x4017: I/O registers. 0x4018-0x5FFF: unmapped. 0x6000-0x7FFF: SRAM when enabled, else unmapped. 0x8000-0xFFFF: ROM of rom_size bytes mirrored to fill the window, byte at offset o = (7o + (o >> 8) + 3) & 0xFF, writes ignored. Every write drives its value onto the data bus; reads of unmapped space return the last bus value, other reads drive the bus. Unwritten RAM/register/SRAM bytes read 0. Writes yield None, reads the value.

split: open-access


source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    rom_size, sram_en, ops = args
    ram, ppu, io, sram = {}, {}, {}, {}
    bus = 0
    out = []
    for op in ops:
        kind, addr = op[0], op[1] & 0xFFFF
        if addr < 0x2000: dev, key = ram, addr & 0x7FF
        elif addr < 0x4000: dev, key = ppu, addr & 7
        elif addr < 0x4018: dev, key = io, addr
        elif addr < 0x6000: dev, key = None, None
        elif addr < 0x8000: dev, key = (sram, addr - 0x6000) if sram_en or kind == 'r' else (None, None)
        else: dev, key = 'rom', (addr - 0x8000) % rom_size
        if kind == 'w':
            bus = op[2] & 0xFF
            if dev is not None and dev != 'rom':
                dev[key] = bus
            out.append(None)
        else:
            if dev == 'rom': bus = (key * 7 + (key >> 8) + 3) & 0xFF
            elif dev is not None: bus = dev.get(key, 0)
            out.append(bus)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ram mirrors', [32768, 1, [['w', 2049, 67], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 67, 67, 67]), ('video register mirrors', [32768, 1, [['w', 8201, 5], ['r', 16377], ['r', 8193]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 17], ['r', 16640]]], [None, 119, None, 17]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17665]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49158], ['r', 32774]]], [45, 45]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49158]]], [102, None, 109]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 152], ['r', 24576], ['r', 24577]]], [None, 152, 152]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 68], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 68, 68, 68]), ('video register mirrors', [32768, 1, [['w', 8202, 5], ['r', 16378], ['r', 8194]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 18], ['r', 16640]]], [None, 119, None, 18]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17666]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49159], ['r', 32775]]], [52, 52]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49159]]], [102, None, 116]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 151], ['r', 24576], ['r', 24577]]], [None, 151, 151]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 69], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 69, 69, 69]), ('video register mirrors', [32768, 1, [['w', 8203, 5], ['r', 16379], ['r', 8195]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 19], ['r', 16640]]], [None, 119, None, 19]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17667]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49160], ['r', 32776]]], [59, 59]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49160]]], [102, None, 123]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 150], ['r', 24576], ['r', 24577]]], [None, 150, 150]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 70], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 70, 70, 70]), ('video register mirrors', [32768, 1, [['w', 8204, 5], ['r', 16380], ['r', 8196]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 20], ['r', 16640]]], [None, 119, None, 20]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17668]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49161], ['r', 32777]]], [66, 66]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49161]]], [102, None, 130]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 149], ['r', 24576], ['r', 24577]]], [None, 149, 149]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])], [('ram mirrors', [32768, 1, [['w', 2049, 71], ['r', 1], ['r', 6145], ['r', 4097]]], [None, 71, 71, 71]), ('video register mirrors', [32768, 1, [['w', 8205, 5], ['r', 16381], ['r', 8197]]], [None, 5, 5]), ('open bus after unmapped write', [32768, 1, [['w', 16416, 119], ['r', 20480], ['w', 2, 21], ['r', 16640]]], [None, 119, None, 21]), ('open bus after read', [32768, 1, [['r', 32771], ['r', 17669]]], [24, 24]), ('small rom mirrors', [16384, 1, [['r', 49162], ['r', 32778]]], [73, 73]), ('large rom does not mirror', [32768, 0, [['r', 49157], ['w', 49157, 1], ['r', 49162]]], [102, None, 137]), ('io registers', [32768, 1, [['w', 16405, 15], ['r', 16405], ['r', 16406]]], [None, 15, 0]), ('disabled sram is open bus', [32768, 0, [['w', 28672, 148], ['r', 24576], ['r', 24577]]], [None, 148, 148]), ('enabled sram', [16384, 1, [['w', 28672, 18], ['r', 28672], ['r', 24576]]], [None, 18, 0])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
With SRAM disabled, reads of 0x6000-0x7FFF return memory contents instead of open bus.

Input [rom_size, sram_enabled, ops] with ops ['r', addr] or ['w', addr, value] on a 16-bit bus. 0x0000-0x1FFF: 2 KiB RAM mirrored every 0x800. 0x2000-0x3FFF: 8 video registers mirrored every 8 bytes. 0x4000-0x4017: I/O registers. 0x4018-0x5FFF: unmapped. 0x6000-0x7FFF: SRAM when enabled, else unmapped. 0x8000-0xFFFF: ROM of rom_size bytes mirrored to fill the window, byte at offset o = (7o + (o >> 8) + 3) & 0xFF, writes ignored. Every write drives its value onto the data bus; reads of unmapped space return the last bus value, other reads drive the bus. Unwritten RAM/register/SRAM bytes read 0. Writes yield None, reads the value.

split: open-access