Initally working!

This commit is contained in:
G2-Games 2025-01-27 15:28:35 -06:00
commit 20965bbafc
6 changed files with 418 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

109
Cargo.lock generated Normal file
View file

@ -0,0 +1,109 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bitflags"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
[[package]]
name = "cd_read"
version = "0.1.0"
dependencies = [
"nix",
"num-derive",
"num-traits",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "libc"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "nix"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags",
"cfg-if",
"cfg_aliases",
"libc",
]
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "2.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243"

9
Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "cd_read"
version = "0.1.0"
edition = "2021"
[dependencies]
nix = { version = "0.29.0", features = ["ioctl"] }
num-derive = "0.4.2"
num-traits = "0.2.19"

157
src/constants.rs Normal file
View file

@ -0,0 +1,157 @@
//! Read more about the meanings of the below bytes here:
//! <https://docs.kernel.org/userspace-api/ioctl/cdrom.html>
use num_traits::ToPrimitive;
/// CDROM ioctl byte, from <linux/cdrom.h>
pub const IOC_BYTE: u8 = 0x53;
#[repr(u8)]
#[derive(FromPrimitive, ToPrimitive)]
#[derive(Debug, Clone, Copy)]
pub enum Operations {
/// Pause Audio Operation
Pause = 0x01,
/// Resume paused Audio Operation
Resume = 0x02,
/// Play Audio MSF (struct cdrom_msf)
PlayMsf = 0x03,
/// Play Audio Track/index (struct cdrom_ti)
PlayTrackIndex = 0x04,
/// Read TOC header (struct cdrom_tochdr)
ReadTocHeader = 0x05,
/// Read TOC entry (struct cdrom_tocentry)
ReadTocEntry = 0x06,
/// Stop the cdrom drive
Stop = 0x07,
/// Start the cdrom drive
Start = 0x08,
/// Ejects the cdrom media
Eject = 0x09,
/// Control output volume (struct cdrom_volctrl)
VolumeControl = 0x0a,
/// Read subchannel data (struct cdrom_subchnl)
SubChannel = 0x0b,
/// Read CDROM mode 2 data (2336 Bytes) (struct cdrom_subchnl)
ReadMode2 = 0x0c,
/// Read CDROM mode 1 data (2048 Bytes) (struct cdrom_read)
ReadMode1 = 0x0d,
/// (struct cdrom_read_audio)
ReadAudio = 0x0e,
/// Enable (1)/Disable (0) auto-ejecting
EjectSoftware = 0x0f,
/// Obtain the start-of-last-session address of multi session disks (struct cdrom_multisession)
MultiSession = 0x10,
/// Obtain the "Universal Product Code" if available (struct cdrom_mcn)
GetMcn = 0x11,
/// Hard-reset the drive
Reset = 0x12,
/// Get the drive's volume setting (struct cdrom_volctrl)
VolumeRead = 0x13,
/// Read data in raw mode (2352 Bytes) (struct cdrom_read)
ReadRaw = 0x14,
// These ioctls are only used in aztcd.c and optcd.c
/// Read data in cooked mode (???)
ReadCooked = 0x15,
/// Seek msf address
Seek = 0x16,
// This ioctl is only used by the scsi-cd driver.
// It is for playing audio in logtal block addresing mode.
/// (struct cdrom_blk)
PlayBlock = 0x17,
// These ioctls are only used in optcd.c
/// Read all 2646 bytes
ReadAll = 0x18,
// These ioctls were only in (now removed) ide-cd.c for controlling
// drive spindown time. They should be implemented in the
// Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10,
// GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE...
// -Erik
GetSpindown = 0x1d,
SetSpindown = 0x1e,
// These ioctls are implemented through the uniform CD-ROM driver
// They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM
// drivers are eventually ported to the uniform CD-ROM driver interface.
/// Pendant of [`Operations::Eject`]
CloseTray = 0x19,
/// Set behavior options
SetOptions = 0x20,
/// Clear behavior options
ClearOptions = 0x21,
/// Set the CD-ROM speed
SelectSpeed = 0x22,
/// Select disc (for juke-boxes)
SelectDisk = 0x23,
/// Check is media changed
MediaChanged = 0x25,
/// Get tray position, etc
DriveStatus = 0x26,
/// Get disc type, etc
DiscStatus = 0x27,
/// Get number of slots
ChangerNslots = 0x28,
/// Lock or unlock door
LockDoor = 0x29,
/// Turn debug messages on/off
Debug = 0x30,
/// Get capabilities
GetCapability = 0x31,
// Note that scsi/scsi_ioctl.h also uses 0x5382 - 0x5386.
// Future CDROM ioctls should be kept below 0x537F
/// Set the audio buffer size
/// conflict with SCSI_IOCTL_GET_IDLUN
AudioBufferSize = 0x82,
// DVD-ROM Specific ioctls
/// Read structure
DvdReadStructure = 0x90,
/// Write structure
DvdWriteStructure = 0x91,
/// Authentication
DvdAuthenticate = 0x92,
/// Send a packet to the drive
SendPacket = 0x93,
/// Get next writable block
NextWritable = 0x94,
/// Get last block written on disc
LastWritten = 0x95,
/// Get the timestamp of the last media change
TimedMediaChange = 0x96,
}
impl Operations {
/// Turns the byte into its full IOCTL representation
pub fn to_full(&self) -> u64 {
let value = self.to_u8().unwrap();
((IOC_BYTE as u64) << 8) + value as u64
}
}
/// Drive status possibilities returned by CDROM_DRIVE_STATUS ioctl
#[derive(FromPrimitive, ToPrimitive)]
#[derive(Debug, Clone, Copy)]
pub enum Status {
NoInfo = 0,
NoDisc = 1,
TrayOpen = 2,
DriveNotReady = 3,
DiscOK = 4
}

65
src/main.rs Normal file
View file

@ -0,0 +1,65 @@
mod constants;
mod structures;
use std::os::{fd::IntoRawFd, unix::fs::OpenOptionsExt};
use std::fs::OpenOptions;
use constants::{Operations, IOC_BYTE};
use nix::{ioctl_none, ioctl_none_bad, ioctl_readwrite_bad, libc};
use nix::libc::c_int;
use num_traits::FromPrimitive as _;
use structures::{Addr, Msf0, ReadAudio};
#[macro_use]
extern crate num_derive;
ioctl_none_bad!(cdrom_stop, Operations::to_full(&Operations::Stop));
ioctl_none_bad!(cdrom_start, Operations::to_full(&Operations::Start));
ioctl_none_bad!(cdrom_eject, Operations::to_full(&Operations::Eject));
ioctl_none_bad!(cdrom_close_tray, Operations::to_full(&Operations::CloseTray));
ioctl_none_bad!(cdrom_status, Operations::to_full(&Operations::DriveStatus));
ioctl_readwrite_bad!(cdrom_read_audio, Operations::to_full(&Operations::ReadAudio), structures::ReadAudio);
fn main() {
const FRAMES: i32 = 75;
const BYTES_PER_FRAME: i32 = 2352;
let time = Msf0 {
minute: 2,
second: 45,
frame: 0,
};
let address = Addr {
msf: time,
};
let mut buff = [0u8; FRAMES as usize * BYTES_PER_FRAME as usize]; //Frames per second (75) * bytes per frame (2352)
let mut ra = ReadAudio {
addr: address,
addr_format: 0x02,
nframes: FRAMES,
buf: buff.as_mut_ptr()
};
let cdrom = OpenOptions::new()
.read(true)
.custom_flags(libc::O_NONBLOCK | libc::O_RDONLY)
.open("/dev/sr0")
.unwrap();
let cdrom_fd: c_int = cdrom.into_raw_fd();
unsafe {
let result = constants::Status::from_i32(cdrom_status(cdrom_fd).unwrap()).unwrap();
dbg!(result);
//dbg!(cdrom_start(cdrom_fd).unwrap_or_default());
//std::thread::sleep(std::time::Duration::from_secs(1));
dbg!(cdrom_read_audio(cdrom_fd, std::ptr::addr_of_mut!(ra)).unwrap());
}
println!("{:02X?}", &buff[0..10]);
}

77
src/structures.rs Normal file
View file

@ -0,0 +1,77 @@
use std::ffi::c_int;
/// Address in MSF format
#[repr(C)]
#[derive(Clone, Copy)]
pub struct Msf0 {
pub minute: u8,
pub second: u8,
pub frame: u8,
}
/// Address in either MSF or logical format
#[repr(C)]
#[derive(Clone, Copy)]
pub union Addr {
pub lba: c_int,
pub msf: Msf0,
}
/// This struct is used by [`crate::constants::PLAY_MSF`]
#[repr(C)]
#[derive(Clone, Copy)]
pub struct Msf {
/// Start minute
pub min0: u8,
/// Start second
pub sec0: u8,
/// Start frame
pub frame0: u8,
/// End minute
pub min1: u8,
/// End second
pub sec1: u8,
/// End frame
pub frame1: u8,
}
#[repr(C)]
pub union RawResult {
pub cdrom_msf: Msf,
pub buffer: [u8; 2646],
}
/// This struct is used by [`crate::constants::PLAY_TRACK_INDEX`]
struct TrackIndex {
/// Start track
trk0: u8,
/// Start index
ind0: u8,
/// End track
trk1: u8,
/// End index
ind1: u8,
}
/// This struct is used by [`crate::constants::READ_TOC_HEADER`]
struct TocHeader {
trk0: u8,
trk1: u8,
}
struct VolCtl {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct ReadAudio {
/// Frame address
pub addr: Addr,
/// CDROM_LBA or CDROM_MSF
pub addr_format: u8,
/// Number of 2352-byte-frames to read at once
pub nframes: i32,
/// Pointer to frame buffer (size: nframes*2352 bytes)
pub buf: *mut u8,
}