Compare commits
2 Commits
5b2fc83dfb
...
ce3b197d52
| Author | SHA1 | Date | |
|---|---|---|---|
|
ce3b197d52
|
|||
|
309cc9c2df
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,5 +2,5 @@
|
|||||||
*.nes
|
*.nes
|
||||||
*.zip
|
*.zip
|
||||||
*.dmp
|
*.dmp
|
||||||
/wasm/
|
|
||||||
!/wasm/wasm.html
|
!/wasm/wasm.html
|
||||||
|
/wasm/*
|
||||||
|
|||||||
26
src/mem.rs
26
src/mem.rs
@@ -1,6 +1,7 @@
|
|||||||
use std::{fmt, sync::Arc};
|
use std::{fmt, sync::Arc};
|
||||||
|
|
||||||
use bitfield::bitfield;
|
use bitfield::bitfield;
|
||||||
|
use log::info;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CPUMMRegisters, PPU, apu::APU, controllers::Controllers, cpu::DmaState, ppu::PPUMMRegisters,
|
CPUMMRegisters, PPU, apu::APU, controllers::Controllers, cpu::DmaState, ppu::PPUMMRegisters,
|
||||||
@@ -303,6 +304,7 @@ enum SegmentId {
|
|||||||
ChrBank0,
|
ChrBank0,
|
||||||
ChrBank1,
|
ChrBank1,
|
||||||
|
|
||||||
|
PrgRam,
|
||||||
NVRam,
|
NVRam,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,12 +360,12 @@ impl Mapped {
|
|||||||
};
|
};
|
||||||
let (prg_rom, rom) = rom.split_at(mapper.prg_rom_size as usize * 0x4000);
|
let (prg_rom, rom) = rom.split_at(mapper.prg_rom_size as usize * 0x4000);
|
||||||
let (chr_rom, _rom) = rom.split_at(mapper.chr_rom_size as usize * 0x2000);
|
let (chr_rom, _rom) = rom.split_at(mapper.chr_rom_size as usize * 0x2000);
|
||||||
println!("Mapper: {}/{}", mapper.mapper, mapper.sub_mapper);
|
info!("Mapper: {}/{}", mapper.mapper, mapper.sub_mapper);
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
mapper.prg_nv_ram_size.low_count(),
|
// mapper.prg_nv_ram_size.low_count(),
|
||||||
0,
|
// 0,
|
||||||
"No support for PRG-RAM"
|
// "No support for PRG-RAM"
|
||||||
);
|
// );
|
||||||
// assert_eq!(
|
// assert_eq!(
|
||||||
// mapper.chr_nv_ram_size.low_count(),
|
// mapper.chr_nv_ram_size.low_count(),
|
||||||
// 0,
|
// 0,
|
||||||
@@ -394,6 +396,12 @@ impl Mapped {
|
|||||||
0x6000,
|
0x6000,
|
||||||
mapper.prg_nv_ram_size.high_count() as u16,
|
mapper.prg_nv_ram_size.high_count() as u16,
|
||||||
));
|
));
|
||||||
|
} else if mapper.prg_nv_ram_size.low_count() > 0 {
|
||||||
|
cpu_segments.push(Segment::ram(
|
||||||
|
SegmentId::PrgRam,
|
||||||
|
0x6000,
|
||||||
|
mapper.prg_nv_ram_size.low_count() as u16,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let mut ppu_segments = vec![
|
let mut ppu_segments = vec![
|
||||||
Segment::mirror(SegmentId::VramMirror, 0x3000, 0x0F00, 0x0000),
|
Segment::mirror(SegmentId::VramMirror, 0x3000, 0x0F00, 0x0000),
|
||||||
@@ -464,7 +472,7 @@ impl Mapped {
|
|||||||
let prg_banks: Vec<Arc<[u8]>> =
|
let prg_banks: Vec<Arc<[u8]>> =
|
||||||
prg_rom.chunks(0x4000).map(|ch| Arc::from(ch)).collect();
|
prg_rom.chunks(0x4000).map(|ch| Arc::from(ch)).collect();
|
||||||
for (i, b) in prg_banks.iter().enumerate() {
|
for (i, b) in prg_banks.iter().enumerate() {
|
||||||
println!("{i}: {:X?}", &b[0x3FF0..]);
|
info!("{i}: {:X?}", &b[0x3FF0..]);
|
||||||
}
|
}
|
||||||
cpu_segments.push(Segment::rom(
|
cpu_segments.push(Segment::rom(
|
||||||
SegmentId::PrgBank0,
|
SegmentId::PrgBank0,
|
||||||
@@ -476,7 +484,7 @@ impl Mapped {
|
|||||||
0xC000,
|
0xC000,
|
||||||
prg_banks.last().unwrap().clone(),
|
prg_banks.last().unwrap().clone(),
|
||||||
));
|
));
|
||||||
println!("CHR_ROM: {}", chr_rom.len());
|
info!("CHR_ROM: {}", chr_rom.len());
|
||||||
let chr_banks: Vec<Arc<[u8]>> =
|
let chr_banks: Vec<Arc<[u8]>> =
|
||||||
chr_rom.chunks(0x1000).map(|ch| Arc::from(ch)).collect();
|
chr_rom.chunks(0x1000).map(|ch| Arc::from(ch)).collect();
|
||||||
if chr_rom.len() == 0 {
|
if chr_rom.len() == 0 {
|
||||||
@@ -502,7 +510,7 @@ impl Mapped {
|
|||||||
cur_prg_bank: 0,
|
cur_prg_bank: 0,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
todo!("support mapper chip: {}/{}", mapper.mapper, mapper.sub_mapper)
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
cpu: MemoryMap {
|
cpu: MemoryMap {
|
||||||
|
|||||||
@@ -38,6 +38,23 @@
|
|||||||
<button id="load">Load ROM</button>
|
<button id="load">Load ROM</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<p>
|
||||||
|
A partially implemented NES emulator, implemented in Rust. It's compiled to web assembly and hosted
|
||||||
|
here for your enjoyment.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://gitea.loadingm.xyz/the10thwiz/nes-emu">Source is available for those interested.</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The APU isn't fully emulated yet, and many of the features implemented don't work properly yet. Audio
|
||||||
|
is disabled.
|
||||||
|
<!-- Run `window.play_audio = true;` in the dev console to enable audio -->
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This emulator has been primarily tested with Super Mario Bros, although the game hasn't been fully tested.
|
||||||
|
Very few mapper chips have actually been implemented, so it's quite likely many games will fail to
|
||||||
|
load at all.
|
||||||
|
</p>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import init from "./wasm.js";
|
import init from "./wasm.js";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user