Update tests with basic init
This commit is contained in:
@@ -91,6 +91,10 @@ impl APU {
|
|||||||
self.pulse_2.enabled = val & 0b0000_0010 != 0;
|
self.pulse_2.enabled = val & 0b0000_0010 != 0;
|
||||||
self.pulse_1.enabled = val & 0b0000_0001 != 0;
|
self.pulse_1.enabled = val & 0b0000_0001 != 0;
|
||||||
}
|
}
|
||||||
|
0x10 => {
|
||||||
|
assert_eq!(val, 0x00);
|
||||||
|
// TODO: implement this value
|
||||||
|
}
|
||||||
0x11 => {
|
0x11 => {
|
||||||
// TODO: load dmc counter with (val & 7F)
|
// TODO: load dmc counter with (val & 7F)
|
||||||
}
|
}
|
||||||
|
|||||||
53
src/debug.rs
Normal file
53
src/debug.rs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
|
pub struct DebugLog {
|
||||||
|
current: String,
|
||||||
|
history: Vec<String>,
|
||||||
|
max_history: Option<NonZeroUsize>,
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugLog {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
current: String::new(),
|
||||||
|
history: vec![],
|
||||||
|
max_history: None,
|
||||||
|
pos: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rotate(&mut self) {
|
||||||
|
let rot = std::mem::take(&mut self.current);
|
||||||
|
if let Some(max) = self.max_history {
|
||||||
|
if self.history.len() < max.into() {
|
||||||
|
self.history.push(rot);
|
||||||
|
} else {
|
||||||
|
self.history[self.pos] = rot;
|
||||||
|
self.pos = (self.pos + 1) % max.get();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.history.push(rot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Write for DebugLog {
|
||||||
|
fn write_str(&mut self, s: &str) -> std::fmt::Result {
|
||||||
|
self.current.write_str(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_char(&mut self, c: char) -> std::fmt::Result {
|
||||||
|
self.current.write_char(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::fmt::Result {
|
||||||
|
self.current.write_fmt(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DebugLog {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
319
src/lib.rs
319
src/lib.rs
File diff suppressed because it is too large
Load Diff
@@ -96,7 +96,7 @@ enum Message {
|
|||||||
|
|
||||||
impl Emulator {
|
impl Emulator {
|
||||||
fn new() -> (Self, Task<Message>) {
|
fn new() -> (Self, Task<Message>) {
|
||||||
let rom_file = concat!(env!("ROM_DIR"), "/", "read_write.nes");
|
let rom_file = concat!(env!("ROM_DIR"), "/", "basic_init_1.nes");
|
||||||
// let rom_file = "./Super Mario Bros. (World).nes";
|
// let rom_file = "./Super Mario Bros. (World).nes";
|
||||||
let mut nes = nes_emu::NES::load_nes_file(rom_file)
|
let mut nes = nes_emu::NES::load_nes_file(rom_file)
|
||||||
.expect("Failed to load nes file");
|
.expect("Failed to load nes file");
|
||||||
|
|||||||
43
src/test_roms/basic_init_0.asm
Normal file
43
src/test_roms/basic_init_0.asm
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
.inesprg 2 ; 2 banks
|
||||||
|
.ineschr 1 ;
|
||||||
|
.inesmap 0 ; mapper 0 = NROM
|
||||||
|
.inesmir 0 ; background mirroring, horizontal
|
||||||
|
|
||||||
|
.org $8000
|
||||||
|
RESET:
|
||||||
|
sei ; Ignore IRQs while starting up
|
||||||
|
cld ; disabled decimal mode (iirc it doesn't work properly on NES anyway)
|
||||||
|
ldx #$40
|
||||||
|
stx $4017 ; Disable APU frame IRQ
|
||||||
|
ldx #$ff
|
||||||
|
txs ; Set stack pointer to 0x1ff
|
||||||
|
inx ; Set x to zero
|
||||||
|
stx $2000 ; Disable NMI (by writing zero)
|
||||||
|
stx $2001 ; Disable rendering
|
||||||
|
stx $4010 ; Disable DMC IRQs
|
||||||
|
|
||||||
|
bit $2002 ; Clear vblank flag by reading ppu status
|
||||||
|
; VBLANKWAIT1:
|
||||||
|
; bit $2002
|
||||||
|
; bpl VBLANKWAIT1
|
||||||
|
; VBLANKWAIT2:
|
||||||
|
; bit $2002
|
||||||
|
; bpl VBLANKWAIT2
|
||||||
|
hlt
|
||||||
|
hlt
|
||||||
|
|
||||||
|
ERROR_:
|
||||||
|
hlt
|
||||||
|
|
||||||
|
IGNORE:
|
||||||
|
rti
|
||||||
|
|
||||||
|
.org $FFFA ; Interrupt vectors go here:
|
||||||
|
.word IGNORE ; NMI
|
||||||
|
.word RESET ; Reset
|
||||||
|
.word IGNORE; IRQ
|
||||||
|
|
||||||
|
;;;; NESASM COMPILER STUFF, ADDING THE PATTERN DATA ;;;;
|
||||||
|
|
||||||
|
.incbin "Sprites.pcx"
|
||||||
|
.incbin "Tiles.pcx"
|
||||||
43
src/test_roms/basic_init_1.asm
Normal file
43
src/test_roms/basic_init_1.asm
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
.inesprg 2 ; 2 banks
|
||||||
|
.ineschr 1 ;
|
||||||
|
.inesmap 0 ; mapper 0 = NROM
|
||||||
|
.inesmir 0 ; background mirroring, horizontal
|
||||||
|
|
||||||
|
.org $8000
|
||||||
|
RESET:
|
||||||
|
sei ; Ignore IRQs while starting up
|
||||||
|
cld ; disabled decimal mode (iirc it doesn't work properly on NES anyway)
|
||||||
|
ldx #$40
|
||||||
|
stx $4017 ; Disable APU frame IRQ
|
||||||
|
ldx #$ff
|
||||||
|
txs ; Set stack pointer to 0x1ff
|
||||||
|
inx ; Set x to zero
|
||||||
|
stx $2000 ; Disable NMI (by writing zero)
|
||||||
|
stx $2001 ; Disable rendering
|
||||||
|
stx $4010 ; Disable DMC IRQs
|
||||||
|
|
||||||
|
bit $2002 ; Clear vblank flag by reading ppu status
|
||||||
|
VBLANKWAIT1:
|
||||||
|
bit $2002
|
||||||
|
bpl VBLANKWAIT1
|
||||||
|
; VBLANKWAIT2:
|
||||||
|
; bit $2002
|
||||||
|
; bpl VBLANKWAIT2
|
||||||
|
hlt
|
||||||
|
hlt
|
||||||
|
|
||||||
|
ERROR_:
|
||||||
|
hlt
|
||||||
|
|
||||||
|
IGNORE:
|
||||||
|
rti
|
||||||
|
|
||||||
|
.org $FFFA ; Interrupt vectors go here:
|
||||||
|
.word IGNORE ; NMI
|
||||||
|
.word RESET ; Reset
|
||||||
|
.word IGNORE; IRQ
|
||||||
|
|
||||||
|
;;;; NESASM COMPILER STUFF, ADDING THE PATTERN DATA ;;;;
|
||||||
|
|
||||||
|
.incbin "Sprites.pcx"
|
||||||
|
.incbin "Tiles.pcx"
|
||||||
@@ -2,12 +2,15 @@ use crate::{NES, hex_view::Memory};
|
|||||||
|
|
||||||
macro_rules! rom_test {
|
macro_rules! rom_test {
|
||||||
($name:ident, $rom:literal, |$nes:ident| $eval:expr) => {
|
($name:ident, $rom:literal, |$nes:ident| $eval:expr) => {
|
||||||
|
rom_test!($name, $rom, timeout = 10000000, |$nes| $eval);
|
||||||
|
};
|
||||||
|
($name:ident, $rom:literal, timeout = $timeout:expr, |$nes:ident| $eval:expr) => {
|
||||||
#[test]
|
#[test]
|
||||||
fn $name() {
|
fn $name() {
|
||||||
let rom_file = concat!(env!("ROM_DIR"), "/", $rom);
|
let rom_file = concat!(env!("ROM_DIR"), "/", $rom);
|
||||||
println!("{}: {}", stringify!($name), rom_file);
|
println!("{}: {}", stringify!($name), rom_file);
|
||||||
let mut $nes = NES::load_nes_file(rom_file).expect("Failed to create nes object");
|
let mut $nes = NES::load_nes_file(rom_file).expect("Failed to create nes object");
|
||||||
$nes.reset_and_run_with_timeout(1000000);
|
$nes.reset_and_run_with_timeout($timeout);
|
||||||
println!("Final: {:?}", $nes);
|
println!("Final: {:?}", $nes);
|
||||||
$eval
|
$eval
|
||||||
}
|
}
|
||||||
@@ -39,3 +42,23 @@ rom_test!(read_write, "read_write.nes", |nes| {
|
|||||||
assert_eq!(nes.cpu_mem().peek(0x0001).unwrap(), 0xAA);
|
assert_eq!(nes.cpu_mem().peek(0x0001).unwrap(), 0xAA);
|
||||||
assert_eq!(nes.cpu_mem().peek(0x0002).unwrap(), 0xAA);
|
assert_eq!(nes.cpu_mem().peek(0x0002).unwrap(), 0xAA);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
rom_test!(basic_init_0, "basic_init_0.nes", |nes| {
|
||||||
|
assert_eq!(nes.last_instruction, "0x8017 HLT :2 []");
|
||||||
|
assert_eq!(nes.cycle, 41);
|
||||||
|
assert_eq!(nes.cpu.pc, 0x8018);
|
||||||
|
assert_eq!(nes.cpu.sp, 0xFF);
|
||||||
|
assert_eq!(nes.cpu.a, 0x00);
|
||||||
|
assert_eq!(nes.cpu.x, 0x00);
|
||||||
|
assert_eq!(nes.cpu.y, 0x00);
|
||||||
|
});
|
||||||
|
|
||||||
|
rom_test!(basic_init_1, "basic_init_1.nes", |nes| {
|
||||||
|
assert_eq!(nes.last_instruction, "0x8017 HLT :2 []");
|
||||||
|
assert_eq!(nes.cycle, 41);
|
||||||
|
assert_eq!(nes.cpu.pc, 0x8018);
|
||||||
|
assert_eq!(nes.cpu.sp, 0xFF);
|
||||||
|
assert_eq!(nes.cpu.a, 0x00);
|
||||||
|
assert_eq!(nes.cpu.x, 0x00);
|
||||||
|
assert_eq!(nes.cpu.y, 0x00);
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
; FINAL = ""
|
|
||||||
|
|
||||||
.inesprg 2 ; 2 banks
|
.inesprg 2 ; 2 banks
|
||||||
.ineschr 1 ;
|
.ineschr 1 ;
|
||||||
.inesmap 0 ; mapper 0 = NROM
|
.inesmap 0 ; mapper 0 = NROM
|
||||||
|
|||||||
16888
test-emu/AccuracyCoin.asm
Normal file
16888
test-emu/AccuracyCoin.asm
Normal file
File diff suppressed because it is too large
Load Diff
BIN
test-emu/Sprites.pcx
Normal file
BIN
test-emu/Sprites.pcx
Normal file
Binary file not shown.
BIN
test-emu/Tiles.pcx
Normal file
BIN
test-emu/Tiles.pcx
Normal file
Binary file not shown.
26
test-rom/basic-cpu.asm
Normal file
26
test-rom/basic-cpu.asm
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
; FINAL = ""
|
||||||
|
|
||||||
|
.inesprg 2 ; 2 banks
|
||||||
|
.ineschr 1 ;
|
||||||
|
.inesmap 0 ; mapper 0 = NROM
|
||||||
|
.inesmir 0 ; background mirroring, horizontal
|
||||||
|
|
||||||
|
.org $8000
|
||||||
|
RESET:
|
||||||
|
sed
|
||||||
|
hlt
|
||||||
|
ERROR_:
|
||||||
|
hlt
|
||||||
|
|
||||||
|
IGNORE:
|
||||||
|
rti
|
||||||
|
|
||||||
|
.org $FFFA ; Interrupt vectors go here:
|
||||||
|
.word IGNORE ; NMI
|
||||||
|
.word RESET ; Reset
|
||||||
|
.word IGNORE; IRQ
|
||||||
|
|
||||||
|
;;;; NESASM COMPILER STUFF, ADDING THE PATTERN DATA ;;;;
|
||||||
|
|
||||||
|
; .incchr "Sprites.pcx"
|
||||||
|
; .incchr "Tiles.pcx"
|
||||||
Reference in New Issue
Block a user