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_1.enabled = val & 0b0000_0001 != 0;
|
||||
}
|
||||
0x10 => {
|
||||
assert_eq!(val, 0x00);
|
||||
// TODO: implement this value
|
||||
}
|
||||
0x11 => {
|
||||
// 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 {
|
||||
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 mut nes = nes_emu::NES::load_nes_file(rom_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 {
|
||||
($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]
|
||||
fn $name() {
|
||||
let rom_file = concat!(env!("ROM_DIR"), "/", $rom);
|
||||
println!("{}: {}", stringify!($name), rom_file);
|
||||
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);
|
||||
$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(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
|
||||
.ineschr 1 ;
|
||||
.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