Skip to content

Commit

Permalink
Add drive1 functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
dbalsom committed Jun 1, 2023
1 parent 717654d commit 0394f87
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Thumbs.db
*.cfg
*.log

icon.png

# Assembly stuff
/asm
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

* Compiled for CGA only
* Fixed CGA cursor handling
* Rescan media folders when opening Media menu.
* Rescan media folders when opening Media menu
* Added barebones documentation
* Added icon resource for Windows build
* Added ROM override feature
* Added HDD drive1 functionality
* Known issues
** Floppy images are read-only.

Expand Down
9 changes: 6 additions & 3 deletions install/martypc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ video_frame_debug = false

[gui]
# ----------------------------------------------------------------------------
# GUI options options
# GUI options
# ----------------------------------------------------------------------------

# Disable the GUI entirely. Use autostart=true or you'll have no way to start
Expand All @@ -90,7 +90,7 @@ theme_color = 0x382D59 # Marty purple

[cpu]
# ----------------------------------------------------------------------------
# Various CPU related options.
# Various CPU related options
# ----------------------------------------------------------------------------

# Enable CPU wait states. This includes wait states from DMA, memory access
Expand Down Expand Up @@ -155,9 +155,12 @@ video = "CGA"
hdc = "None"
#hdc = "Xebec"

# VHD to mount into drive 0 (Typically C:)
# VHD to mount into drive0 (Typically C:)
#drive0 = "dos330.vhd"

# VHD to mount into drive1 (Typically D:)
#drive1 = "games.vhd"

# Options for the CPU Validator module.
# ----------------------------------------------------------------------------
# You must have an Arduino8088 connected via USB to utilize
Expand Down
16 changes: 16 additions & 0 deletions src/egui/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,27 @@ impl GuiState {
if ui.radio_value(&mut self.vhd_name0, name.clone(), name.to_str().unwrap()).clicked() {

log::debug!("Selected VHD filename: {:?}", name);

self.event_queue.push_back(GuiEvent::LoadVHD(0, name.clone()));
self.new_vhd_name0 = Some(name.clone());
ui.close_menu();
}
}
});

ui.menu_button("🖴 Load VHD in Drive 1:...", |ui| {
for name in &self.vhd_names {

if ui.radio_value(&mut self.vhd_name1, name.clone(), name.to_str().unwrap()).clicked() {

log::debug!("Selected VHD filename: {:?}", name);

self.event_queue.push_back(GuiEvent::LoadVHD(0, name.clone()));
self.new_vhd_name1 = Some(name.clone());
ui.close_menu();
}
}
});
});

if ui.button("🖹 Create new VHD...").clicked() {
Expand Down
5 changes: 2 additions & 3 deletions src/egui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,7 @@ pub enum GuiOption {
}

pub enum GuiEvent {
#[allow (dead_code)]
LoadVHD(u32,OsString),
LoadVHD(usize, OsString),
CreateVHD(OsString, HardDiskFormat),
LoadFloppy(usize, OsString),
EjectFloppy(usize),
Expand Down Expand Up @@ -602,7 +601,7 @@ impl GuiState {
}
1 => {
let got_str = self.new_vhd_name1.clone();
self.new_vhd_name0 = None;
self.new_vhd_name1 = None;
got_str
}
_ => {
Expand Down
45 changes: 41 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -675,10 +675,10 @@ fn main() {
}
}

// Try to load default vhd
// Try to load default vhd for drive0:
if let Some(vhd_name) = config.machine.drive0 {
let vhd_os_name: OsString = vhd_name.into();
match vhd_manager.get_vhd_file(&vhd_os_name) {
match vhd_manager.load_vhd_file(0, &vhd_os_name) {
Ok(vhd_file) => {
match VirtualHardDisk::from_file(vhd_file) {
Ok(vhd) => {
Expand All @@ -705,7 +705,40 @@ fn main() {
log::error!("Failed to load VHD image {:?}: {}", vhd_os_name, err);
}
}
}
}

// Try to load default vhd for drive1:
// TODO: refactor this to func or put in vhd_manager
if let Some(vhd_name) = config.machine.drive1 {
let vhd_os_name: OsString = vhd_name.into();
match vhd_manager.load_vhd_file(1, &vhd_os_name) {
Ok(vhd_file) => {
match VirtualHardDisk::from_file(vhd_file) {
Ok(vhd) => {
if let Some(hdc) = machine.hdc() {
match hdc.set_vhd(1_usize, vhd) {
Ok(_) => {
log::info!("VHD image {:?} successfully loaded into virtual drive: {}", vhd_os_name, 1);
}
Err(err) => {
log::error!("Error mounting VHD: {}", err);
}
}
}
else {
log::error!("Couldn't load VHD: No Hard Disk Controller present!");
}
},
Err(err) => {
log::error!("Error loading VHD: {}", err);
}
}
}
Err(err) => {
log::error!("Failed to load VHD image {:?}: {}", vhd_os_name, err);
}
}
}

// Start buffer playback
machine.play_sound_buffer();
Expand Down Expand Up @@ -1540,9 +1573,13 @@ fn main() {
// -- Do we have a new VHD image to load?
for i in 0..machine::NUM_HDDS {
if let Some(new_vhd_name) = framework.gui.get_new_vhd_name(i) {

log::debug!("Releasing VHD slot: {}", i);
vhd_manager.release_vhd(i as usize);

log::debug!("Load new VHD image: {:?} in device: {}", new_vhd_name, i);

match vhd_manager.get_vhd_file(&new_vhd_name) {
match vhd_manager.load_vhd_file(i as usize, &new_vhd_name) {
Ok(vhd_file) => {

match VirtualHardDisk::from_file(vhd_file) {
Expand Down
62 changes: 55 additions & 7 deletions src/vhd_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*/

const DRIVE_MAX: usize = 4;

use std::{
collections::HashMap,
path::{Path, PathBuf},
Expand All @@ -18,6 +20,8 @@ pub enum VHDManagerError {
DirNotFound,
FileNotFound,
FileReadError,
InvalidDrive,
DriveAlreadyLoaded,
}
impl std::error::Error for VHDManagerError{}
impl Display for VHDManagerError {
Expand All @@ -26,26 +30,31 @@ impl Display for VHDManagerError {
VHDManagerError::DirNotFound => write!(f, "The VHD directory was not found."),
VHDManagerError::FileNotFound => write!(f, "File not found error scanning VHD directory."),
VHDManagerError::FileReadError => write!(f, "File read error scanning VHD directory."),
VHDManagerError::InvalidDrive => write!(f, "Specified drive out of range."),
VHDManagerError::DriveAlreadyLoaded => write!(f, "Specified drive already loaded!"),
}
}
}

#[allow(dead_code)]
#[derive (Clone, Debug)]
pub struct VHDFile {
path: PathBuf,
size: u64
}

pub struct VHDManager {
file_vec: Vec<VHDFile>,
file_map: HashMap<OsString, VHDFile>
file_map: HashMap<OsString, VHDFile>,
files_loaded: [Option<OsString>; DRIVE_MAX]
}

impl VHDManager {
pub fn new() -> Self {
Self {
file_vec: Vec::new(),
file_map: HashMap::new()
file_map: HashMap::new(),
files_loaded: [ None, None, None, None ]
}
}

Expand Down Expand Up @@ -93,16 +102,51 @@ impl VHDManager {
vec
}

pub fn get_vhd_file(&self, name: &OsString ) -> Result<File, VHDManagerError> {
pub fn is_vhd_loaded(&self, name: &OsString) -> Option<usize> {

for i in 0..DRIVE_MAX {

if let Some(drive) = &self.files_loaded[i] {
if name.as_os_str() == drive.as_os_str() {

return Some(i)
}
}
}
None
}

pub fn load_vhd_file(&mut self, drive: usize, name: &OsString ) -> Result<File, VHDManagerError> {

if drive > 3 {
return Err(VHDManagerError::InvalidDrive);
}

if let Some(vhd) = self.file_map.get(name) {

let vhd_file_result = File::options()
.read(true)
.write(true)
.open(&vhd.path);
let vhd_file_result =
File::options()
.read(true)
.write(true)
.open(&vhd.path);

match vhd_file_result {
Ok(file) => {

log::debug!("Associating vhd: {} to drive: {}", name.to_string_lossy(), drive);

if let Some(_) = &self.files_loaded[drive] {
log::error!("VHD drive slot {} not empty!", drive);
return Err(VHDManagerError::DriveAlreadyLoaded);
}

if let Some(d) = self.is_vhd_loaded(name) {
log::error!("VHD already associated with drive {}! Release drive first.", d);
return Err(VHDManagerError::DriveAlreadyLoaded);
}

self.files_loaded[drive] = Some(name.clone());

return Ok(file);
}
Err(_e) => {
Expand All @@ -113,4 +157,8 @@ impl VHDManager {
Err(VHDManagerError::FileNotFound)
}

pub fn release_vhd(&mut self, drive: usize) {
self.files_loaded[drive] = None;
}

}

0 comments on commit 0394f87

Please sign in to comment.