aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/expected/runrom/stack.txt44
-rw-r--r--tests/runrom/stack.s44
-rw-r--r--tests/vnf-tests/Cargo.toml10
-rw-r--r--tests/vnf-tests/src/main.rs108
4 files changed, 206 insertions, 0 deletions
diff --git a/tests/expected/runrom/stack.txt b/tests/expected/runrom/stack.txt
new file mode 100644
index 0000000..f35ea16
--- /dev/null
+++ b/tests/expected/runrom/stack.txt
@@ -0,0 +1,44 @@
+<start> PC: $8000, cycles: 7, registers: [a: $00, x: $00, y: $00, sp: $FD], status: ----I--
+ [STACK]: 02 80 00 00
+ [STACK]: 34 02 80 00 00
+brk PC: $8003, cycles: 14, registers: [a: $00, x: $00, y: $00, sp: $FA], status: --B-I--
+ [STACK]: 00 34 02 80 00 00
+pha PC: $8004, cycles: 17, registers: [a: $00, x: $00, y: $00, sp: $F9], status: --B-I--
+txa PC: $8005, cycles: 19, registers: [a: $00, x: $00, y: $00, sp: $F9], status: --B-IZ-
+ [STACK]: 00 00 34 02 80 00 00
+pha PC: $8006, cycles: 22, registers: [a: $00, x: $00, y: $00, sp: $F8], status: --B-IZ-
+tya PC: $8007, cycles: 24, registers: [a: $00, x: $00, y: $00, sp: $F8], status: --B-IZ-
+ [STACK]: 00 00 00 34 02 80 00 00
+pha PC: $8008, cycles: 27, registers: [a: $00, x: $00, y: $00, sp: $F7], status: --B-IZ-
+ [STACK]: 36 00 00 00 34 02 80 00 00
+php PC: $8009, cycles: 30, registers: [a: $00, x: $00, y: $00, sp: $F6], status: --B-IZ-
+lda #$01 PC: $800B, cycles: 32, registers: [a: $01, x: $00, y: $00, sp: $F6], status: --B-I--
+ldy #$02 PC: $800D, cycles: 34, registers: [a: $01, x: $00, y: $02, sp: $F6], status: --B-I--
+ldx #$FF PC: $800F, cycles: 36, registers: [a: $01, x: $FF, y: $02, sp: $F6], status: N-B-I--
+inx PC: $8010, cycles: 38, registers: [a: $01, x: $00, y: $02, sp: $F6], status: --B-IZ-
+inx PC: $8011, cycles: 40, registers: [a: $01, x: $01, y: $02, sp: $F6], status: --B-I--
+ [STACK]: 00 00 00 34 02 80 00 00
+plp PC: $8012, cycles: 44, registers: [a: $01, x: $01, y: $02, sp: $F7], status: ----IZ-
+ [STACK]: 00 00 34 02 80 00 00
+pla PC: $8013, cycles: 48, registers: [a: $00, x: $01, y: $02, sp: $F8], status: ----IZ-
+tay PC: $8014, cycles: 50, registers: [a: $00, x: $01, y: $00, sp: $F8], status: ----IZ-
+ [STACK]: 00 34 02 80 00 00
+pla PC: $8015, cycles: 54, registers: [a: $00, x: $01, y: $00, sp: $F9], status: ----IZ-
+tax PC: $8016, cycles: 56, registers: [a: $00, x: $00, y: $00, sp: $F9], status: ----IZ-
+ [STACK]: 34 02 80 00 00
+pla PC: $8017, cycles: 60, registers: [a: $00, x: $00, y: $00, sp: $FA], status: ----IZ-
+ [STACK]: 02 80 00 00
+ [STACK]: 00 00
+rti PC: $8002, cycles: 66, registers: [a: $00, x: $00, y: $00, sp: $FD], status: ----I--
+rts PC: $8003, cycles: 72, registers: [a: $00, x: $00, y: $00, sp: $FD], status: ----I--
+<end>
+
+== Memory dump ==
+
+[$2F7] = $36 [reads=1, writes=1]
+[$2F8] = $00 [reads=1, writes=1]
+[$2F9] = $00 [reads=1, writes=1]
+[$2FA] = $00 [reads=1, writes=1]
+[$2FB] = $34 [reads=1, writes=1]
+[$2FC] = $02 [reads=1, writes=1]
+[$2FD] = $80 [reads=1, writes=1]
diff --git a/tests/runrom/stack.s b/tests/runrom/stack.s
new file mode 100644
index 0000000..ec15718
--- /dev/null
+++ b/tests/runrom/stack.s
@@ -0,0 +1,44 @@
+.segment "HEADER"
+ .byte 'N', 'E', 'S', $1A
+ .byte $02, $01
+ .byte $00
+ .byte $00
+
+.segment "CHARS"
+.byte 0
+
+.segment "CODE"
+;; asan:stack full
+
+.proc reset
+ brk
+ .byte $42
+ rts
+.endproc
+
+.proc irq
+ pha
+ txa
+ pha
+ tya
+ pha
+ php
+
+ lda #1
+ ldy #2
+ ldx #$FF
+ inx
+ inx
+
+ plp
+ pla
+ tay
+ pla
+ tax
+ pla
+
+ rti
+.endproc
+
+.segment "VECTORS"
+ .addr reset, reset, irq
diff --git a/tests/vnf-tests/Cargo.toml b/tests/vnf-tests/Cargo.toml
new file mode 100644
index 0000000..8ad6b70
--- /dev/null
+++ b/tests/vnf-tests/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "vnf-tests"
+version = "0.1.0"
+edition = "2024"
+license.workspace = true
+authors.workspace = true
+
+[dependencies]
+vnf.workspace = true
+xixanta.workspace = true
diff --git a/tests/vnf-tests/src/main.rs b/tests/vnf-tests/src/main.rs
new file mode 100644
index 0000000..6c62dbd
--- /dev/null
+++ b/tests/vnf-tests/src/main.rs
@@ -0,0 +1,108 @@
+use std::path::PathBuf;
+
+use vnf::{Machine, MemoryPolicy};
+use xixanta::opcodes::InstructionIdentifier;
+
+#[derive(Default)]
+struct Args {
+ file: String,
+}
+
+fn print_help() {
+ println!("End-to-end tests for the vnf library\n");
+ println!("usage: vnf-tests [OPTIONS] <tests/ directory>\n");
+ println!("Options:");
+ println!(" -h, --help\t\t\tPrint this message and quit.");
+ std::process::exit(0);
+}
+
+// Print the given `message` and exit(1).
+fn die(message: String) -> ! {
+ eprintln!("error: {message}");
+ std::process::exit(1);
+}
+
+fn parse_arguments() -> Args {
+ let mut args = std::env::args();
+ let mut res = Args::default();
+
+ // Skip command name.
+ args.next();
+
+ for arg in args {
+ match arg.as_str() {
+ "-h" | "--help" => print_help(),
+ _ => {
+ if arg.starts_with('-') {
+ die(format!("don't know how to handle the '{arg}' flag"));
+ }
+ if !res.file.is_empty() {
+ die("cannot have multiple paths".to_string());
+ }
+ res.file = arg;
+ }
+ }
+ }
+
+ if res.file.is_empty() {
+ die("you have to provide a path to the tests/ directory".to_string());
+ }
+
+ res
+}
+
+fn run_break_mark_test(path: &String) -> Result<(), String> {
+ let rom = PathBuf::from(path).join("out/stack.nes");
+ let roms: String = rom.to_string_lossy().into_owned().to_string();
+
+ let mut machine = Machine::from(&roms, 0x8000, MemoryPolicy::default())?;
+
+ // Get out of <start>
+ let _ = machine.next_iteration();
+
+ // Assert that we are at the expected location.
+ assert!(matches!(
+ machine.current_instruction.identifier,
+ InstructionIdentifier::Brk
+ ));
+
+ // Before vs after running 'brk'.
+ assert_eq!(machine.status_register.break_mark, 0);
+ assert!(!machine.status_register.brk);
+ let _ = machine.next_iteration();
+ assert_eq!(machine.status_register.break_mark, 0x42);
+ assert!(machine.status_register.brk);
+
+ // Skip instructions we don't care about here.
+ for _ in 0..11 {
+ let _ = machine.next_iteration();
+ }
+
+ // Before running 'plp', everything is still as expected.
+ assert!(matches!(
+ machine.current_instruction.identifier,
+ InstructionIdentifier::Plp
+ ));
+ assert_eq!(machine.status_register.break_mark, 0x42);
+ assert!(machine.status_register.brk);
+
+ // After running 'plp'.
+ let _ = machine.next_iteration();
+ assert_eq!(machine.status_register.break_mark, 0x00);
+ assert!(!machine.status_register.brk);
+
+ Ok(())
+}
+
+fn main() {
+ let args = parse_arguments();
+ let file = PathBuf::from(args.file.clone());
+
+ if !file.is_dir() {
+ die("you have to provide a path to the tests/ directory".to_string());
+ }
+
+ if let Err(e) = run_break_mark_test(&args.file) {
+ die(e)
+ }
+}