Skip to content

Commit

Permalink
better merlin folds
Browse files Browse the repository at this point in the history
  • Loading branch information
dfgordon committed Aug 18, 2024
1 parent 33312e4 commit ae6b172
Show file tree
Hide file tree
Showing 24 changed files with 434 additions and 180 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixes

* More complete handling of Merlin folding ranges
* ProDOS and FAT glob patterns are automatically prefixed when necessary
* CP/M generic catalog includes user numbers when there are users other than user 0
* Disk server write operations will actually write
* Fix an issue with the head map in IMD and TD0 images

## [3.0.0] - 2024-08-11

### New Features
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "a2kit"
version = "3.0.0"
version = "3.0.1"
edition = "2021"
readme = "README.md"
license = "MIT"
Expand Down
10 changes: 10 additions & 0 deletions src/bin/server-applesoft/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ pub fn handle_notification(
//connection.sender.send(resp.into())?;
}
},
lsp::notification::SetTrace::METHOD => {
if let Ok(_params) = serde_json::from_value::<lsp::SetTraceParams>(note.params) {
logger(&connection,"ignoring the SetTrace notification");
}
}
lsp::notification::DidChangeWatchedFiles::METHOD => {
if let Ok(_params) = serde_json::from_value::<lsp::DidChangeWatchedFilesParams>(note.params) {
logger(&connection,"ignoring the DidChangeWatchedFiles notification");
}
}
which_method => {
logger(&connection,&format!("unhandled notification {}",which_method))
}
Expand Down
10 changes: 10 additions & 0 deletions src/bin/server-integerbasic/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ pub fn handle_notification(
//connection.sender.send(resp.into())?;
}
},
lsp::notification::SetTrace::METHOD => {
if let Ok(_params) = serde_json::from_value::<lsp::SetTraceParams>(note.params) {
logger(&connection,"ignoring the SetTrace notification");
}
},
lsp::notification::DidChangeWatchedFiles::METHOD => {
if let Ok(_params) = serde_json::from_value::<lsp::DidChangeWatchedFilesParams>(note.params) {
logger(&connection,"ignoring the DidChangeWatchedFiles notification");
}
},
which_method => {
logger(&connection,&format!("unhandled notification {}",which_method))
}
Expand Down
4 changes: 2 additions & 2 deletions src/bin/server-merlin/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ pub fn handle_notification(
if let Ok(_params) = serde_json::from_value::<lsp::SetTraceParams>(note.params) {
logger(&connection,"ignoring the SetTrace notification");
}
}
},
lsp::notification::DidChangeWatchedFiles::METHOD => {
if let Ok(_params) = serde_json::from_value::<lsp::DidChangeWatchedFilesParams>(note.params) {
logger(&connection,"ignoring the DidChangeWatchedFiles notification");
}
}
},
lsp::notification::Cancel::METHOD => {
// TODO: figure out when this needs to be handled specially
if let Ok(params) = serde_json::from_value::<lsp::CancelParams>(note.params) {
Expand Down
4 changes: 2 additions & 2 deletions src/bios/bpb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ impl BPBFoundation {
u16::from_be_bytes(self.root_ent_cnt) as u64
}
pub fn sec_per_clus(&self) -> u8 {
// TODO: why is this often/always erroneously set to 2 for 160K and 180K disks?
// for now we override it in the FS layer when such disks are detected.
// Early DOS had a bug that erroneously set this to 2 for 160K and 180K disks.
// Therefore we override it in the FS layer when such disks are detected.
self.sec_per_clus
}
}
Expand Down
15 changes: 12 additions & 3 deletions src/fs/cpm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,8 +625,17 @@ impl super::DiskFS for Disk {
match dir.build_files(&self.dpb, [3,0,0]) {
Ok(files) => {
let mut ans = Vec::new();
for (_,info) in files {
ans.push(super::universal_row(&info.typ,info.blocks_allocated,&info.name));
let mut multi_user = false;
for (_,info) in &files {
if info.user != 0 {
multi_user = true;
}
}
for (name,info) in files {
match multi_user {
true => ans.push(super::universal_row(&info.typ,info.blocks_allocated,&name)),
false => ans.push(super::universal_row(&info.typ, info.blocks_allocated, &info.name))
}
}
Ok(ans)
},
Expand All @@ -641,7 +650,7 @@ impl super::DiskFS for Disk {
};
let dir = self.get_directory();
let files = dir.build_files(&self.dpb, self.cpm_vers)?;
for (name,info) in files {
for (name,_info) in files {
let name = match case_sensitive {
true => name.clone(),
false => name.to_uppercase()
Expand Down
6 changes: 5 additions & 1 deletion src/fs/fat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,11 @@ impl super::DiskFS for Disk {
fn glob(&mut self,pattern: &str,case_sensitive: bool) -> Result<Vec<String>,DYNERR> {
let (_,dir) = self.get_root_dir()?;
self.curr_path = vec!["/".to_string()];
self.glob_node(pattern, &dir,case_sensitive)
if pattern.starts_with("/") {
self.glob_node(pattern, &dir,case_sensitive)
} else {
self.glob_node(&["/",pattern].concat(), &dir, case_sensitive)
}
}
fn tree(&mut self,include_meta: bool,indent: Option<u16>) -> Result<String,DYNERR> {
let (vol,dir) = self.get_root_dir()?;
Expand Down
9 changes: 7 additions & 2 deletions src/fs/prodos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,8 +1015,13 @@ impl super::DiskFS for Disk {
fn glob(&mut self,pattern: &str,case_sensitive: bool) -> Result<Vec<String>,DYNERR> {
let vhdr = self.get_vol_header()?;
let dir_block = self.find_dir_key_block("/")?;
self.curr_path = vec![["/",&vhdr.name(),"/"].concat()];
self.glob_node(pattern, dir_block, case_sensitive)
let vol_path = ["/",&vhdr.name(),"/"].concat();
self.curr_path = vec![vol_path.clone()];
if pattern.starts_with("/") {
self.glob_node(pattern, dir_block, case_sensitive)
} else {
self.glob_node(&(vol_path + pattern), dir_block, case_sensitive)
}
}
fn tree(&mut self,include_meta: bool,indent: Option<u16>) -> Result<String,DYNERR> {
let vhdr = self.get_vol_header()?;
Expand Down
13 changes: 9 additions & 4 deletions src/img/imd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,10 @@ impl Imd {
fn check_user_area_up_to_cyl(&self,cyl: usize,off: u16) -> STDRESULT {
let sectors = self.tracks[off as usize].sectors;
let sector_shift = self.tracks[off as usize].sector_shift;
if cyl*self.heads >= self.tracks.len() {
log::error!("track {} was requested, max is {}",cyl*self.heads,self.tracks.len()-1);
return Err(Box::new(super::Error::TrackCountMismatch));
}
for i in off as usize..cyl*self.heads+1 {
let trk = &self.tracks[i];
if trk.sectors!=sectors || trk.sector_shift!=sector_shift {
Expand Down Expand Up @@ -414,11 +418,11 @@ impl img::DiskImage for Imd {
self.heads
}
fn track_2_ch(&self,track: usize) -> [usize;2] {
[self.tracks[track].cylinder as usize,self.tracks[track].head as usize]
[self.tracks[track].cylinder as usize,(self.tracks[track].head & HEAD_MASK) as usize]
}
fn ch_2_track(&self,ch: [usize;2]) -> usize {
for i in 0..self.tracks.len() {
if self.tracks[i].cylinder as usize==ch[0] && self.tracks[i].head as usize==ch[1] {
if self.tracks[i].cylinder as usize==ch[0] && (self.tracks[i].head & HEAD_MASK) as usize==ch[1] {
return i
}
}
Expand Down Expand Up @@ -689,15 +693,16 @@ impl img::DiskImage for Imd {
Some(Mode::Mfm250Kbps) | Some(Mode::Mfm300Kbps) | Some(Mode::Mfm500Kbps) => img::FluxCode::MFM,
None => img::FluxCode::None
};
let phys_head = (trk_obj.head & HEAD_MASK) as usize;
let mut chss_map: Vec<[usize;4]> = Vec::new();
for i in 0..trk_obj.sectors as usize {
let c = match trk_obj.cylinder_map.len()>i { true=>trk_obj.cylinder_map[i] as usize, false=>trk_obj.cylinder as usize };
let h = match trk_obj.head_map.len()>i { true=>trk_obj.head_map[i] as usize, false=>trk_obj.head as usize };
let h = match trk_obj.head_map.len()>i { true=>trk_obj.head_map[i] as usize, false=>phys_head };
chss_map.push([c,h,trk_obj.sector_map[i] as usize,SECTOR_SIZE_BASE << trk_obj.sector_shift]);
}
Ok(Some(img::TrackSolution {
cylinder: trk_obj.cylinder as usize,
head: trk_obj.head as usize,
head: phys_head,
flux_code,
nib_code: img::NibbleCode::None,
chss_map
Expand Down
4 changes: 0 additions & 4 deletions src/img/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@
//! These functions have to be able to take a `Block` and transform it into whatever disk
//! addressing the image uses. The tables in `bios::skew` are accessible to any image.

// TODO: the DiskStruct trait, defined in separate derive_macro crates, should be revised
// to return a Result, so we can error out instead of panicking if the image is bad.
// Also revise it to accept slices.

pub mod disk35;
pub mod disk525;
pub mod dsk_d13;
Expand Down
14 changes: 9 additions & 5 deletions src/img/td0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,10 @@ impl Td0 {
fn check_user_area_up_to_cyl(&self,cyl: usize,off: u16) -> STDRESULT {
let sector_count = self.tracks[off as usize].sectors.len();
let mut sector_shift: Option<u8> = None;
if cyl*self.heads >= self.tracks.len() {
log::error!("track {} was requested, max is {}",cyl*self.heads,self.tracks.len()-1);
return Err(Box::new(super::Error::TrackCountMismatch));
}
for i in off as usize..cyl*self.heads+1 {
let trk = &self.tracks[i];
if trk.sectors.len()!=sector_count {
Expand Down Expand Up @@ -606,11 +610,11 @@ impl img::DiskImage for Td0 {
self.heads
}
fn track_2_ch(&self,track: usize) -> [usize;2] {
[self.tracks[track].header.cylinder as usize,self.tracks[track].header.head as usize]
[self.tracks[track].header.cylinder as usize,(self.tracks[track].header.head & HEAD_MASK) as usize]
}
fn ch_2_track(&self,ch: [usize;2]) -> usize {
for i in 0..self.tracks.len() {
if self.tracks[i].header.cylinder as usize==ch[0] && self.tracks[i].header.head as usize==ch[1] {
if self.tracks[i].header.cylinder as usize==ch[0] && (self.tracks[i].header.head & HEAD_MASK) as usize==ch[1] {
return i
}
}
Expand Down Expand Up @@ -809,14 +813,14 @@ impl img::DiskImage for Td0 {
// We will not stop for bad track CRC, but do warn
let expected_track_crc = crc16(0,&header.to_bytes()[0..3]);
if header.crc != (expected_track_crc & 0xff) as u8{
warn!("track header CRC mismatch at cyl {} head {}",header.cylinder,header.head);
warn!("track header CRC mismatch at cyl {} head {}",header.cylinder,header.head & HEAD_MASK);
}
let mut trk = Track {
header,
sectors: Vec::new(),
head_pos: 0
};
trace!("found cyl {} head {} with {} sectors",trk.header.cylinder,trk.header.head,trk.header.sectors);
trace!("found cyl {} head {} with {} sectors",trk.header.cylinder,trk.header.head & HEAD_MASK,trk.header.sectors);
for i in 0..trk.header.sectors {
let mut sec = Sector::new();
sec.header = SectorHeader::from_bytes(&optional_get_slice!(expanded,ptr,6,"sector header").to_vec()).expect("unreachable");
Expand Down Expand Up @@ -940,7 +944,7 @@ impl img::DiskImage for Td0 {
}
Ok(Some(img::TrackSolution {
cylinder: trk_obj.header.cylinder as usize,
head: trk_obj.header.head as usize,
head: (trk_obj.header.head & HEAD_MASK) as usize,
flux_code,
nib_code: img::NibbleCode::None,
chss_map
Expand Down
2 changes: 2 additions & 0 deletions src/lang/disk_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,11 @@ impl DiskServer {
let mut fimg = disk.new_fimg(None, true, path)?;
match typ {
ItemType::IntegerTokens | ItemType::ApplesoftTokens => fimg.pack_tok(dat,typ,None)?,
ItemType::MerlinTokens => fimg.pack_raw(dat)?,
ItemType::Text => fimg.pack_raw(dat)?,
_ => return Err(Box::new(CommandError::UnsupportedFormat))
};
disk.put(&fimg)?;
crate::save_img(disk, &self.path_to_img)?;
Ok(())
} else {
Expand Down
Loading

0 comments on commit ae6b172

Please sign in to comment.