2019-10-02 16:41:02 -04:00
|
|
|
use crate::system::MemoryFd;
|
|
|
|
use crate::util::BitSet;
|
2019-09-11 15:58:04 -04:00
|
|
|
use crate::disk::{Result, Error, SECTOR_SIZE, DiskImage};
|
|
|
|
use std::io::SeekFrom;
|
|
|
|
|
|
|
|
pub struct MemoryOverlay {
|
|
|
|
memory: MemoryFd,
|
2019-10-02 16:41:02 -04:00
|
|
|
written_sectors: BitSet,
|
2019-09-11 15:58:04 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl MemoryOverlay {
|
|
|
|
pub fn new() -> Result<Self> {
|
|
|
|
let memory = MemoryFd::new_memfd(0, false)
|
|
|
|
.map_err(Error::MemoryOverlayCreate)?;
|
2019-10-02 16:41:02 -04:00
|
|
|
let written_sectors = BitSet::new();
|
2019-09-11 15:58:04 -04:00
|
|
|
Ok(MemoryOverlay { memory, written_sectors })
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn write_sectors(&mut self, start: u64, buffer: &[u8]) -> Result<()> {
|
|
|
|
let sector_count = buffer.len() / SECTOR_SIZE;
|
|
|
|
let len = sector_count * SECTOR_SIZE;
|
|
|
|
let seek_offset = SeekFrom::Start(start * SECTOR_SIZE as u64);
|
|
|
|
|
|
|
|
self.memory.fd_mut()
|
|
|
|
.seek(seek_offset)
|
|
|
|
.map_err(Error::DiskSeek)?;
|
|
|
|
|
|
|
|
self.memory.fd_mut()
|
|
|
|
.write_all(&buffer[..len])
|
|
|
|
.map_err(Error::DiskWrite)?;
|
|
|
|
|
|
|
|
for n in 0..sector_count {
|
|
|
|
let idx = start as usize + n;
|
2019-10-02 16:41:02 -04:00
|
|
|
self.written_sectors.insert(idx);
|
2019-09-11 15:58:04 -04:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn read_sectors<D: DiskImage>(&mut self, disk: &mut D, start: u64, buffer: &mut [u8]) -> Result<()> {
|
|
|
|
let sector_count = buffer.len() / SECTOR_SIZE;
|
2019-10-02 16:41:02 -04:00
|
|
|
if (0..sector_count).all(|i| !self.written_sectors.get(i)) {
|
2019-09-11 15:58:04 -04:00
|
|
|
return disk.read_sectors(start, buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
for n in 0..sector_count {
|
|
|
|
let sector = start + n as u64;
|
|
|
|
let offset = n * SECTOR_SIZE;
|
|
|
|
let sector_buffer = &mut buffer[offset..offset+SECTOR_SIZE];
|
2019-10-02 16:41:02 -04:00
|
|
|
if self.written_sectors.get(sector as usize) {
|
2019-09-11 15:58:04 -04:00
|
|
|
self.read_single_sector(sector, sector_buffer)?;
|
|
|
|
} else {
|
|
|
|
disk.read_sectors(sector, sector_buffer)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_single_sector(&mut self, sector: u64, buffer: &mut [u8]) -> Result<()> {
|
|
|
|
assert_eq!(buffer.len(), SECTOR_SIZE);
|
|
|
|
let offset = SeekFrom::Start(sector * SECTOR_SIZE as u64);
|
|
|
|
self.memory.fd_mut().seek(offset)
|
|
|
|
.map_err(Error::DiskSeek)?;
|
|
|
|
self.memory.fd_mut().read_exact(buffer)
|
|
|
|
.map_err(Error::DiskRead)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|