Zesty - a pin-accurate, cycle-accurate NES emulator written in Zig
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292//! Various addressing mode tests.const std = @import("std");const cpu = @import("../cpu.zig");
// Implicitly-addressed instructions and// branch instructions are separately tested.
test "immediate" { var z = cpu.testZes(.{ .rom = &.{ .{ 0x8000, cpu.assemble( \\LDA #$42 ), }, }, });
// Cycle 0. Fetch operand z.stepCpu(); try std.testing.expectEqual(0x8001, z.cpu.pc); try std.testing.expectEqual(0x8001, z.pins.cpu_addr); try std.testing.expectEqual(0x42, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 1. Load operand into register z.stepCpu(); try std.testing.expectEqual(0x8002, z.cpu.pc); try std.testing.expectEqual(0x8002, z.pins.cpu_addr); try std.testing.expectEqual(0x42, z.cpu.a); try std.testing.expectEqual(.read, z.pins.cpu_rw); try std.testing.expect(!z.cpu.status.negative); try std.testing.expect(!z.cpu.status.zero);}
test "zeropage" { var z = cpu.testZes(.{ .ram = &.{ .{ 0x42, &.{0xcc} }, }, .rom = &.{ .{ 0x8000, cpu.assemble( \\LDX <$42 ), }, }, });
// Cycle 0. Fetch address z.stepCpu(); try std.testing.expectEqual(0x8001, z.cpu.pc); try std.testing.expectEqual(0x8001, z.pins.cpu_addr); try std.testing.expectEqual(0x42, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 1. Fetch operand at address z.stepCpu(); try std.testing.expectEqual(0x8001, z.cpu.pc); try std.testing.expectEqual(0x0042, z.pins.cpu_addr); try std.testing.expectEqual(0xcc, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 2. Load operand into register z.stepCpu(); try std.testing.expectEqual(0x8002, z.cpu.pc); try std.testing.expectEqual(0x8002, z.pins.cpu_addr); try std.testing.expectEqual(0xcc, z.cpu.x); try std.testing.expectEqual(.read, z.pins.cpu_rw); try std.testing.expect(z.cpu.status.negative); try std.testing.expect(!z.cpu.status.zero);}
test "zeropage indexed" { var z = cpu.testZes(.{ .ram = &.{ .{ 0x40, &.{ 0xcc, 0xdd, 0xee } }, .{ 0xdd, &.{ 0xff, 0x77 } }, }, .rom = &.{ .{ 0x8000, cpu.assemble( \\LDX <$40,Y \\LDA <$01,X ), }, }, }); // Assume Y=1 z.cpu.y = 1;
//---------------------- // zp,Y
// Cycle 0. Fetch address z.stepCpu(); try std.testing.expectEqual(0x8001, z.cpu.pc); try std.testing.expectEqual(0x8001, z.pins.cpu_addr); try std.testing.expectEqual(0x40, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 1. Dummy read at address z.stepCpu(); try std.testing.expectEqual(0x8001, z.cpu.pc); try std.testing.expectEqual(0x0040, z.pins.cpu_addr); try std.testing.expectEqual(0xcc, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 2. Fetch operand at (address + Y) z.stepCpu(); try std.testing.expectEqual(0x8001, z.cpu.pc); try std.testing.expectEqual(0x0041, z.pins.cpu_addr); try std.testing.expectEqual(0xdd, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 3. Load operand into register z.stepCpu(); try std.testing.expectEqual(0x8002, z.cpu.pc); try std.testing.expectEqual(0x8002, z.pins.cpu_addr); try std.testing.expectEqual(0xdd, z.cpu.x); try std.testing.expectEqual(.read, z.pins.cpu_rw); try std.testing.expect(z.cpu.status.negative); try std.testing.expect(!z.cpu.status.zero);
//---------------------- // zp,X
// Cycle 0. Fetch address z.stepCpu(); try std.testing.expectEqual(0x8003, z.cpu.pc); try std.testing.expectEqual(0x8003, z.pins.cpu_addr); try std.testing.expectEqual(0x01, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 1. Dummy read at address z.stepCpu(); try std.testing.expectEqual(0x8003, z.cpu.pc); try std.testing.expectEqual(0x0001, z.pins.cpu_addr); // Uninit try std.testing.expectEqual(0xaa, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 2. Fetch operand at (address + X) z.stepCpu(); try std.testing.expectEqual(0x8003, z.cpu.pc); try std.testing.expectEqual(0x00de, z.pins.cpu_addr); try std.testing.expectEqual(0x77, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 3. Load operand into register z.stepCpu(); try std.testing.expectEqual(0x8004, z.cpu.pc); try std.testing.expectEqual(0x8004, z.pins.cpu_addr); try std.testing.expectEqual(0x77, z.cpu.a); try std.testing.expectEqual(.read, z.pins.cpu_rw); try std.testing.expect(!z.cpu.status.negative); try std.testing.expect(!z.cpu.status.zero);}
test "absolute" { var z = cpu.testZes(.{ .rom = &.{ .{ 0x8000, cpu.assemble( \\LDY $8964 ), }, .{ 0x8964, &.{0x00} }, }, });
// Cycle 0. Fetch address lo byte z.stepCpu(); try std.testing.expectEqual(0x8001, z.cpu.pc); try std.testing.expectEqual(0x8001, z.pins.cpu_addr); try std.testing.expectEqual(0x64, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 1. Fetch address hi byte z.stepCpu(); try std.testing.expectEqual(0x8002, z.cpu.pc); try std.testing.expectEqual(0x8002, z.pins.cpu_addr); try std.testing.expectEqual(0x89, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 2. Fetch operand at address z.stepCpu(); try std.testing.expectEqual(0x8002, z.cpu.pc); try std.testing.expectEqual(0x8964, z.pins.cpu_addr); try std.testing.expectEqual(0x00, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 3. Load operand into register z.stepCpu(); try std.testing.expectEqual(0x8003, z.cpu.pc); try std.testing.expectEqual(0x8003, z.pins.cpu_addr); try std.testing.expectEqual(0x00, z.cpu.y); try std.testing.expect(!z.cpu.status.negative); try std.testing.expect(z.cpu.status.zero);}
test "absolute indexed" { var z = cpu.testZes(.{ .rom = &.{ .{ 0x8000, cpu.assemble( \\LDX $cc40, Y \\LDA $dd01, X ), }, .{ 0xcc40, &.{ 0x22, 0x33, 0x44 } }, .{ 0xdd33, &.{ 0x1f, 0x00 } }, }, }); // Assume Y=1 z.cpu.y = 1;
//---------------------- // abs,Y
// Cycle 0. Fetch address lo z.stepCpu(); try std.testing.expectEqual(0x8001, z.cpu.pc); try std.testing.expectEqual(0x8001, z.pins.cpu_addr); try std.testing.expectEqual(0x40, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 1. Fetch address hi z.stepCpu(); try std.testing.expectEqual(0x8002, z.cpu.pc); try std.testing.expectEqual(0x8002, z.pins.cpu_addr); try std.testing.expectEqual(0xcc, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 2. Fetch operand at (address + Y) z.stepCpu(); try std.testing.expectEqual(0x8002, z.cpu.pc); try std.testing.expectEqual(0xcc41, z.pins.cpu_addr); try std.testing.expectEqual(0x33, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 3. Load operand into register z.stepCpu(); try std.testing.expectEqual(0x8003, z.cpu.pc); try std.testing.expectEqual(0x8003, z.pins.cpu_addr); try std.testing.expectEqual(0x33, z.cpu.x); try std.testing.expectEqual(.read, z.pins.cpu_rw); try std.testing.expect(!z.cpu.status.negative); try std.testing.expect(!z.cpu.status.zero);
//---------------------- // abs,X
// Cycle 0. Fetch address lo z.stepCpu(); try std.testing.expectEqual(0x8004, z.cpu.pc); try std.testing.expectEqual(0x8004, z.pins.cpu_addr); try std.testing.expectEqual(0x01, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 1. Fetch address hi z.stepCpu(); try std.testing.expectEqual(0x8005, z.cpu.pc); try std.testing.expectEqual(0x8005, z.pins.cpu_addr); try std.testing.expectEqual(0xdd, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 2. Fetch operand at (address + X) z.stepCpu(); try std.testing.expectEqual(0x8005, z.cpu.pc); try std.testing.expectEqual(0xdd34, z.pins.cpu_addr); try std.testing.expectEqual(0x00, z.pins.cpu_data); try std.testing.expectEqual(.read, z.pins.cpu_rw);
// Cycle 3. Load operand into register z.stepCpu(); try std.testing.expectEqual(0x8006, z.cpu.pc); try std.testing.expectEqual(0x8006, z.pins.cpu_addr); try std.testing.expectEqual(0x00, z.cpu.a); try std.testing.expectEqual(.read, z.pins.cpu_rw); try std.testing.expect(!z.cpu.status.negative); try std.testing.expect(z.cpu.status.zero);}
test "relative" {}
test "indirect" {}
test "indexed indirect" {}
test "indirect indexed" {}