mirror of
https://github.com/sehugg/rustyapple.git
synced 2024-12-26 08:32:27 +00:00
diagnosed compiler bugs, fixed stuff
This commit is contained in:
parent
c6ef3b4ddb
commit
92ba23e8b3
4
Makefile
4
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
|
||||
|
||||
|
||||
|
4
README.md
Normal file
4
README.md
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
Rust version of an Apple II emulator.
|
||||
|
||||
CPU simulation heavily borrowed from https://github.com/pcwalton/sprocketnes
|
12
a2.rs
12
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");
|
||||
}
|
||||
}
|
||||
|
46
diskii.rs
46
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<Drive> = None;
|
||||
|
||||
pub struct DiskController
|
||||
{
|
||||
drives: [Option<Drive>, ..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())
|
||||
|
4
tests.rs
4
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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user