fox32+fox32rom: Use DMA for the disk controller
Instead of accessing one byte at a time, use a DMA-like system to read/write a whole sector at a time directly to/from memory.
This commit is contained in:
parent
998646cb80
commit
93d331bb07
22
src/bus.rs
22
src/bus.rs
|
@ -88,11 +88,8 @@ impl Bus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x20 => {
|
0x20 => {
|
||||||
// we're reading from the sector buffer
|
// we're getting the location of the memory sector buffer
|
||||||
if address_or_id > 512 {
|
self.disk_controller.buffer_pointer as u32
|
||||||
panic!("attempted to read past the end of the disk controller sector buffer");
|
|
||||||
}
|
|
||||||
self.disk_controller.sector_buffer[address_or_id] as u32
|
|
||||||
}
|
}
|
||||||
_ => panic!("invalid disk controller port"),
|
_ => panic!("invalid disk controller port"),
|
||||||
}
|
}
|
||||||
|
@ -174,27 +171,24 @@ impl Bus {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
0x20 => {
|
0x20 => {
|
||||||
// we're writing to the sector buffer
|
// we're setting the location of the memory sector buffer
|
||||||
if address_or_id > 512 {
|
self.disk_controller.buffer_pointer = word as usize;
|
||||||
panic!("attempted to read past the end of the disk controller sector buffer");
|
|
||||||
}
|
|
||||||
self.disk_controller.sector_buffer[address_or_id] = word as u8;
|
|
||||||
}
|
}
|
||||||
0x30 => {
|
0x30 => {
|
||||||
// we're reading the specified sector of the specified disk id into the sector buffer
|
// we're reading the specified sector of the specified disk id into the memory sector buffer
|
||||||
if address_or_id > 3 {
|
if address_or_id > 3 {
|
||||||
panic!("invalid disk ID");
|
panic!("invalid disk ID");
|
||||||
}
|
}
|
||||||
self.disk_controller.set_current_sector(address_or_id as u8, word);
|
self.disk_controller.set_current_sector(address_or_id as u8, word);
|
||||||
self.disk_controller.read_into_buffer(address_or_id as u8);
|
self.disk_controller.read_into_memory(address_or_id as u8, self.memory.ram());
|
||||||
}
|
}
|
||||||
0x40 => {
|
0x40 => {
|
||||||
// we're writing the specified sector to the specified disk id from the sector buffer
|
// we're writing the specified sector to the specified disk id from the memory sector buffer
|
||||||
if address_or_id > 3 {
|
if address_or_id > 3 {
|
||||||
panic!("invalid disk ID");
|
panic!("invalid disk ID");
|
||||||
}
|
}
|
||||||
self.disk_controller.set_current_sector(address_or_id as u8, word);
|
self.disk_controller.set_current_sector(address_or_id as u8, word);
|
||||||
self.disk_controller.write_from_buffer(address_or_id as u8);
|
self.disk_controller.write_from_memory(address_or_id as u8, self.memory.ram());
|
||||||
}
|
}
|
||||||
_ => panic!("invalid disk controller port"),
|
_ => panic!("invalid disk controller port"),
|
||||||
}
|
}
|
||||||
|
|
14
src/disk.rs
14
src/disk.rs
|
@ -1,5 +1,7 @@
|
||||||
// disk.rs
|
// disk.rs
|
||||||
|
|
||||||
|
use crate::memory::MemoryRam;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Seek, SeekFrom, Read, Write};
|
use std::io::{Seek, SeekFrom, Read, Write};
|
||||||
use rfd::FileDialog;
|
use rfd::FileDialog;
|
||||||
|
@ -22,14 +24,14 @@ impl Disk {
|
||||||
|
|
||||||
pub struct DiskController {
|
pub struct DiskController {
|
||||||
pub disk: [Option<Disk>; 4],
|
pub disk: [Option<Disk>; 4],
|
||||||
pub sector_buffer: [u8; 512],
|
pub buffer_pointer: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DiskController {
|
impl DiskController {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
DiskController {
|
DiskController {
|
||||||
disk: [None, None, None, None],
|
disk: [None, None, None, None],
|
||||||
sector_buffer: [0; 512]
|
buffer_pointer: 0x00000000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn select_file(&self) -> Option<File> {
|
pub fn select_file(&self) -> Option<File> {
|
||||||
|
@ -64,18 +66,18 @@ impl DiskController {
|
||||||
let disk = self.disk[disk_id as usize].as_mut().expect("attempted to access unmounted disk");
|
let disk = self.disk[disk_id as usize].as_mut().expect("attempted to access unmounted disk");
|
||||||
disk.current_sector
|
disk.current_sector
|
||||||
}
|
}
|
||||||
pub fn read_into_buffer(&mut self, disk_id: u8) -> usize {
|
pub fn read_into_memory(&mut self, disk_id: u8, ram: &mut MemoryRam) -> usize {
|
||||||
let disk = self.disk[disk_id as usize].as_mut().expect("attempted to access unmounted disk");
|
let disk = self.disk[disk_id as usize].as_mut().expect("attempted to access unmounted disk");
|
||||||
let mut temp_buffer = [0u8; 512];
|
let mut temp_buffer = [0u8; 512];
|
||||||
|
|
||||||
let number_of_bytes_read = disk.file.read(&mut temp_buffer).unwrap();
|
let number_of_bytes_read = disk.file.read(&mut temp_buffer).unwrap();
|
||||||
self.sector_buffer = temp_buffer;
|
ram[self.buffer_pointer..self.buffer_pointer+512].copy_from_slice(&temp_buffer);
|
||||||
number_of_bytes_read
|
number_of_bytes_read
|
||||||
}
|
}
|
||||||
pub fn write_from_buffer(&mut self, disk_id: u8) -> usize {
|
pub fn write_from_memory(&mut self, disk_id: u8, ram: &MemoryRam) -> usize {
|
||||||
let disk = self.disk[disk_id as usize].as_mut().expect("attempted to access unmounted disk");
|
let disk = self.disk[disk_id as usize].as_mut().expect("attempted to access unmounted disk");
|
||||||
|
|
||||||
let number_of_bytes_written = disk.file.write(&mut self.sector_buffer).unwrap();
|
let number_of_bytes_written = disk.file.write(ram.get(self.buffer_pointer..self.buffer_pointer+512).unwrap()).unwrap();
|
||||||
number_of_bytes_written
|
number_of_bytes_written
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user