From 92ba23e8b38e957e56869ba1d78e1f5633314c14 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Wed, 15 Jan 2014 20:11:36 -0500 Subject: [PATCH] diagnosed compiler bugs, fixed stuff --- Makefile | 4 +++- README.md | 4 ++++ a2.rs | 12 +++++++----- diskii.rs | 48 +++++++++++++++++++++++++----------------------- tests.rs | 4 +++- 5 files changed, 42 insertions(+), 30 deletions(-) create mode 100644 README.md diff --git a/Makefile b/Makefile index 7b39a9b..128ba7a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ +RUSTC=rustc + test: - rustc -Z debug-info -o appletest --test apple.rs + $(RUSTC) -Z debug-info -o appletest --test apple.rs ./appletest diff --git a/README.md b/README.md new file mode 100644 index 0000000..6e11179 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ + +Rust version of an Apple II emulator. + +CPU simulation heavily borrowed from https://github.com/pcwalton/sprocketnes diff --git a/a2.rs b/a2.rs index 05867e6..01dd814 100644 --- a/a2.rs +++ b/a2.rs @@ -68,7 +68,6 @@ impl Mem for AppleII { fn loadb(&mut self, addr: u16) -> u8 { - debug!("Read {:x}", addr); self.nreads += 1; let val = // see if it's from main memory (0x0000-0xbfff) @@ -84,7 +83,8 @@ impl Mem for AppleII } // it must be an I/O location (0xc000-0xcfff) else if (addr < HW_LO + 0x100) { - self.doIO(addr, 0) + let noise = self.noise(); // when reading, pass noise as value (we might get it back) + self.doIO(addr, noise) } else { match self.slots[(addr >> 8) & 7] { None => self.noise(), @@ -97,7 +97,7 @@ impl Mem for AppleII fn storeb(&mut self, addr: u16, val: u8) { - debug!("write {:x} = {:x}", addr, val); + debug!("Write {:x} = {:x}", addr, val); // see if it's from main memory (0x0000-0xbfff) if (addr < HW_LO) { @@ -140,9 +140,11 @@ impl AppleII nreads: 0 } } - pub fn set_slot(&mut self, slot: uint, p: ~Peripheral) + pub fn set_slot(&mut self, slot: uint, mut p: ~Peripheral) { + //p.doIO(0,0); self.slots[slot] = Some(p); + //self.slots[slot].get_mut_ref().doIO(0,0); } fn noise(&mut self) -> u8 { self.mem[self.nreads & 0xffff] } @@ -237,6 +239,6 @@ impl AppleII use std::vec::bytes::copy_memory; let ap2rom = File::open(&Path::new("apple2.rom")).read_bytes(0x3000); copy_memory(self.mem.mut_slice(0xd000, 0xd000+0x3000), ap2rom); - debug!("loaded apple2.rom"); + info!("loaded apple2.rom"); } } diff --git a/diskii.rs b/diskii.rs index f829f1c..1b3a25c 100644 --- a/diskii.rs +++ b/diskii.rs @@ -19,15 +19,13 @@ struct Drive { disk_data: RawDiskData, // disk data track_data: RawTrackData, // array of track data - track: uint, // current track # + half_track: uint, // current track # track_index: uint, // position of read head along track } -static NoDisk: Option = None; - pub struct DiskController { - drives: [Option, ..NUM_DRIVES], + drives: [Option<~Drive>, ..NUM_DRIVES], selected: u8, // selected drive (0 or 1) motor: bool, // is motor on? read_mode: bool, @@ -37,7 +35,7 @@ pub struct DiskController impl DiskController { pub fn new() -> DiskController { DiskController { - drives: [NoDisk, NoDisk], + drives: [None, None], selected: 0, motor: false, read_mode: false, @@ -55,14 +53,19 @@ impl DiskController f.read(disk_image[track]); disk_data[track] = nibblizeTrack(254, track as u8, disk_image); } - self.drives[disknum] = Some(Drive { + self.drives[disknum] = Some(~Drive { disk_data: disk_data, track_data: [0, ..RAW_TRACK_SIZE], - track: 0, + half_track: NUM_TRACKS+1, track_index: 0, }); - debug!("loaded disk image {}", imagefilename); - + assert!(self.has_disk(disknum)); + info!("loaded disk image {} into drive {}", imagefilename, disknum); + } + + pub fn has_disk(&self, disknum: int) -> bool + { + return self.drives[disknum].is_some(); } // fn drive<'r>(&'r self) -> &'r Option<~Drive> { &self.drives[self.selected] } @@ -72,21 +75,21 @@ impl Drive { fn read_latch(&mut self) -> u8 { - debug!("read latch @ {:x} track {}", self.track_index, self.track) + debug!("read latch @ {:x} track*2 {}", self.track_index, self.half_track) self.track_index = (self.track_index + 1) % RAW_TRACK_SIZE; return self.track_data[self.track_index]; } fn write_latch(&mut self, value: u8) { - debug!("write latch @ {:x} track {}", self.track_index, self.track) + debug!("write latch @ {:x} track*2 {}", self.track_index, self.half_track) self.track_index = (self.track_index + 1) % RAW_TRACK_SIZE; self.track_data[self.track_index] = value; } fn servo_phase(&mut self, phase: uint) { - let mut new_track = self.track; + let mut new_track = self.half_track; // if new phase is even and current phase is odd if (phase == ((new_track - 1) & 3)) @@ -108,8 +111,8 @@ impl Drive } else { // TODO: self.track_data = None; } - self.track = new_track; - debug!("phase {:x} track = {}", phase, self.track as f32*0.5); + self.half_track = new_track; + info!("phase {:x} track = {}", phase, self.half_track as f32*0.5); } } @@ -127,8 +130,8 @@ impl Peripheral for DiskController fn doIO(&mut self, addr: u16, val: u8) -> u8 { - //debug!("disk IO {:x} -> {:x}", addr, val); - let &mut drive = &self.drives[self.selected]; + let ref mut drive = self.drives[self.selected]; + debug!("disk {} IO {:x} -> {:x} {}", self.selected, addr, val, drive.is_some()); match addr & 0xf { /* @@ -138,7 +141,7 @@ impl Peripheral for DiskController * considered to be adjacent. The previous phase number can be * computed as the track number % 4. */ - 1|3|5|7 if drive.is_some() => { drive.unwrap().servo_phase(((addr>>1) & 3) as uint); } + 1|3|5|7 if drive.is_some() => { drive.get_mut_ref().servo_phase(((addr>>1) & 3) as uint); } /* * Turn drive motor off. */ @@ -162,7 +165,7 @@ impl Peripheral for DiskController /* * Read a disk byte if read mode is active. */ - 0xc if self.read_mode && drive.is_some() => { return drive.unwrap().read_latch(); } + 0xc if self.read_mode && drive.is_some() => { return drive.get_mut_ref().read_latch(); } /* * Select read mode and read the write protect status. */ @@ -171,15 +174,14 @@ impl Peripheral for DiskController * Write a disk byte if write mode is active and the disk is not * write protected. */ - 0xd if !self.read_mode && !self.write_protect && drive.is_some() => { drive.unwrap().write_latch(val); } + 0xd if !self.read_mode && !self.write_protect && drive.is_some() => { drive.get_mut_ref().write_latch(val); } /* * Read the write protect status only. */ 0xd if self.write_protect => { return 0x80; } - 0xd => { return 0; } - _ => { return 0; } + _ => { } } - return 0; //emu.noise(); + return val; } @@ -327,7 +329,7 @@ impl Peripheral for DiskController let startindex = skewing_table[sector] as uint << 8; return nibblizeSector(vol, trk, sector as u8, disk[trk].slice(startindex, startindex+256)); }).concat_vec(); - debug!("track {} converted to {:x} raw bytes", trk, arr.len()); + info!("track {} converted to {:x} raw bytes", trk, arr.len()); assert!(arr.len() == RAW_SECTOR_SIZE*16); let mut fixarr: RawTrackData = [0xff_u8, ..RAW_TRACK_SIZE]; for i in range(0, arr.len()) diff --git a/tests.rs b/tests.rs index bafb968..b7512fd 100644 --- a/tests.rs +++ b/tests.rs @@ -2,6 +2,7 @@ use cpu::Cpu; use mem::Mem; use a2::AppleII; +use a2::Peripheral; use diskii::DiskController; // @@ -40,10 +41,11 @@ fn test_a2() a2.read_roms(); let mut dc: DiskController = DiskController::new(); dc.load_disk(0, "JUNK4.DSK"); + assert!(dc.has_disk(0)); a2.set_slot(6, ~dc); let mut cpu = Cpu::new(a2); cpu.reset(); - for i in range(0,100000) { + for i in range(0,10*1000000) { cpu.step(); } }