Gotta make clippy happy #2
Former-commit-id: 25d2b2b52c4113ceb299908248773bb7e4bfd6c9 Former-commit-id: a612adacf46b62d8a5bd78bdcd3b0bc6323898a5
This commit is contained in:
parent
25b630951d
commit
d4b91257b7
|
@ -64,7 +64,7 @@ impl<'de> Deserialize<'de> for BackupFile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const FIELDS: &'static [&'static str] = &["size", "path"];
|
const FIELDS: &[&str] = &["size", "path"];
|
||||||
deserializer.deserialize_struct("BackupFile", FIELDS, BackupFileVisitor)
|
deserializer.deserialize_struct("BackupFile", FIELDS, BackupFileVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ impl BackupFile {
|
||||||
let mut file: Option<File> = None;
|
let mut file: Option<File> = None;
|
||||||
let buffer = if let Some(path) = &path {
|
let buffer = if let Some(path) = &path {
|
||||||
if !path.is_file() {
|
if !path.is_file() {
|
||||||
write_bin_file(&path, &vec![0xff; size]).unwrap();
|
write_bin_file(path, &vec![0xff; size]).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut _file = OpenOptions::new()
|
let mut _file = OpenOptions::new()
|
||||||
|
@ -98,8 +98,8 @@ impl BackupFile {
|
||||||
BackupFile {
|
BackupFile {
|
||||||
size,
|
size,
|
||||||
path,
|
path,
|
||||||
file: file,
|
file,
|
||||||
buffer: buffer,
|
buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ impl EepromChip {
|
||||||
fn new(eeprom_type: EepromType, mut memory: BackupFile) -> EepromChip {
|
fn new(eeprom_type: EepromType, mut memory: BackupFile) -> EepromChip {
|
||||||
memory.resize(eeprom_type.size());
|
memory.resize(eeprom_type.size());
|
||||||
EepromChip {
|
EepromChip {
|
||||||
memory: memory,
|
memory,
|
||||||
addr_bits: eeprom_type.bits(),
|
addr_bits: eeprom_type.bits(),
|
||||||
|
|
||||||
state: SpiState::RxInstruction,
|
state: SpiState::RxInstruction,
|
||||||
|
@ -130,7 +130,7 @@ impl EepromChip {
|
||||||
fn fill_tx_buffer(&mut self) {
|
fn fill_tx_buffer(&mut self) {
|
||||||
let mut tx_buffer = 0u64;
|
let mut tx_buffer = 0u64;
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
tx_buffer = tx_buffer << 8;
|
tx_buffer <<= 8;
|
||||||
tx_buffer |= self.memory.read(self.address + i) as u64;
|
tx_buffer |= self.memory.read(self.address + i) as u64;
|
||||||
}
|
}
|
||||||
self.tx_buffer = tx_buffer;
|
self.tx_buffer = tx_buffer;
|
||||||
|
@ -152,10 +152,8 @@ impl EepromChip {
|
||||||
RxInstruction => {
|
RxInstruction => {
|
||||||
// If instruction was recvd, proceed to recv the address
|
// If instruction was recvd, proceed to recv the address
|
||||||
if self.rx_count >= 2 {
|
if self.rx_count >= 2 {
|
||||||
let insn = SpiInstruction::from_u64(self.rx_buffer).expect(&format!(
|
let insn = SpiInstruction::from_u64(self.rx_buffer).unwrap_or_else(|| panic!("invalid spi command {:#010b}",
|
||||||
"invalid spi command {:#010b}",
|
self.rx_buffer as u8));
|
||||||
self.rx_buffer as u8
|
|
||||||
));
|
|
||||||
next_state = Some(RxAddress(insn));
|
next_state = Some(RxAddress(insn));
|
||||||
self.reset_rx_buffer();
|
self.reset_rx_buffer();
|
||||||
}
|
}
|
||||||
|
@ -193,7 +191,7 @@ impl EepromChip {
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
self.memory
|
self.memory
|
||||||
.write(self.address + (7 - i), (data & 0xff) as u8);
|
.write(self.address + (7 - i), (data & 0xff) as u8);
|
||||||
data = data >> 8;
|
data >>= 8;
|
||||||
}
|
}
|
||||||
next_state = Some(StopBit(Write));
|
next_state = Some(StopBit(Write));
|
||||||
self.reset_rx_buffer();
|
self.reset_rx_buffer();
|
||||||
|
@ -445,7 +443,7 @@ mod tests {
|
||||||
let mut byte = value[i];
|
let mut byte = value[i];
|
||||||
for j in 0..8 {
|
for j in 0..8 {
|
||||||
let bit = byte >> 7;
|
let bit = byte >> 7;
|
||||||
byte = byte << 1;
|
byte <<= 1;
|
||||||
bit_stream[8 + i * 8 + j] = bit as u16;
|
bit_stream[8 + i * 8 + j] = bit as u16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,11 +462,11 @@ mod tests {
|
||||||
{
|
{
|
||||||
let mut chip = spi.chip.borrow_mut();
|
let mut chip = spi.chip.borrow_mut();
|
||||||
let bytes = chip.memory.bytes_mut();
|
let bytes = chip.memory.bytes_mut();
|
||||||
bytes[16] = 'T' as u8;
|
bytes[16] = b'T';
|
||||||
bytes[17] = 'E' as u8;
|
bytes[17] = b'E';
|
||||||
bytes[18] = 'S' as u8;
|
bytes[18] = b'S';
|
||||||
bytes[19] = 'T' as u8;
|
bytes[19] = b'T';
|
||||||
bytes[20] = '!' as u8;
|
bytes[20] = b'!';
|
||||||
drop(bytes);
|
drop(bytes);
|
||||||
chip.memory.flush();
|
chip.memory.flush();
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,12 +76,12 @@ impl Flash {
|
||||||
let memory = BackupFile::new(size, flash_path);
|
let memory = BackupFile::new(size, flash_path);
|
||||||
|
|
||||||
Flash {
|
Flash {
|
||||||
chip_id: chip_id,
|
chip_id,
|
||||||
wrseq: FlashWriteSequence::Initial,
|
wrseq: FlashWriteSequence::Initial,
|
||||||
mode: FlashMode::Initial,
|
mode: FlashMode::Initial,
|
||||||
size: size,
|
size,
|
||||||
bank: 0,
|
bank: 0,
|
||||||
memory: memory,
|
memory,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,12 +144,14 @@ impl Flash {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flash_offset(&self, offset: usize) -> usize {
|
fn flash_offset(&self, offset: usize) -> usize {
|
||||||
let offset = (offset & 0xffff) as usize;
|
let offset = (offset & 0xffff) as usize;
|
||||||
return self.bank * BANK_SIZE + offset;
|
self.bank * BANK_SIZE + offset
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&self, addr: u32) -> u8 {
|
pub fn read(&self, addr: u32) -> u8 {
|
||||||
let offset = (addr & 0xffff) as usize;
|
let offset = (addr & 0xffff) as usize;
|
||||||
let result = if self.mode == FlashMode::ChipId {
|
|
||||||
|
|
||||||
|
if self.mode == FlashMode::ChipId {
|
||||||
match offset {
|
match offset {
|
||||||
0 => (self.chip_id & 0xff) as u8,
|
0 => (self.chip_id & 0xff) as u8,
|
||||||
1 => (self.chip_id >> 8) as u8,
|
1 => (self.chip_id >> 8) as u8,
|
||||||
|
@ -157,9 +159,7 @@ impl Flash {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.memory.read(self.flash_offset(offset))
|
self.memory.read(self.flash_offset(offset))
|
||||||
};
|
}
|
||||||
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(&mut self, addr: u32, value: u8) {
|
pub fn write(&mut self, addr: u32, value: u8) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ pub use backup_file::BackupFile;
|
||||||
pub mod eeprom;
|
pub mod eeprom;
|
||||||
pub mod flash;
|
pub mod flash;
|
||||||
|
|
||||||
#[derive(Debug, Primitive, Serialize, Deserialize, Copy, Clone, PartialEq)]
|
#[derive(Debug, Primitive, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum BackupType {
|
pub enum BackupType {
|
||||||
Eeprom = 0,
|
Eeprom = 0,
|
||||||
Sram = 1,
|
Sram = 1,
|
||||||
|
|
|
@ -109,7 +109,7 @@ impl GamepakBuilder {
|
||||||
LoadRom::Raw(data) => Ok((data, None)),
|
LoadRom::Raw(data) => Ok((data, None)),
|
||||||
}
|
}
|
||||||
} else if let Some(path) = &self.path {
|
} else if let Some(path) = &self.path {
|
||||||
match load_from_file(&path)? {
|
match load_from_file(path)? {
|
||||||
#[cfg(feature = "elf_support")]
|
#[cfg(feature = "elf_support")]
|
||||||
LoadRom::Elf { data, symbols } => Ok((data, Some(symbols))),
|
LoadRom::Elf { data, symbols } => Ok((data, Some(symbols))),
|
||||||
LoadRom::Raw(data) => Ok((data, None)),
|
LoadRom::Raw(data) => Ok((data, None)),
|
||||||
|
@ -187,17 +187,17 @@ impl GamepakBuilder {
|
||||||
|
|
||||||
let size = bytes.len();
|
let size = bytes.len();
|
||||||
Ok(Cartridge {
|
Ok(Cartridge {
|
||||||
header: header,
|
header,
|
||||||
gpio: gpio,
|
gpio,
|
||||||
bytes: bytes.into_boxed_slice(),
|
bytes: bytes.into_boxed_slice(),
|
||||||
size: size,
|
size,
|
||||||
backup: backup,
|
backup,
|
||||||
symbols: symbols,
|
symbols,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BACKUP_FILE_EXT: &'static str = "sav";
|
const BACKUP_FILE_EXT: &str = "sav";
|
||||||
fn create_backup(backup_type: BackupType, rom_path: Option<PathBuf>) -> BackupMedia {
|
fn create_backup(backup_type: BackupType, rom_path: Option<PathBuf>) -> BackupMedia {
|
||||||
let backup_path = if let Some(rom_path) = rom_path {
|
let backup_path = if let Some(rom_path) = rom_path {
|
||||||
Some(rom_path.with_extension(BACKUP_FILE_EXT))
|
Some(rom_path.with_extension(BACKUP_FILE_EXT))
|
||||||
|
@ -216,7 +216,7 @@ fn create_backup(backup_type: BackupType, rom_path: Option<PathBuf>) -> BackupMe
|
||||||
}
|
}
|
||||||
|
|
||||||
fn detect_backup_type(bytes: &[u8]) -> Option<BackupType> {
|
fn detect_backup_type(bytes: &[u8]) -> Option<BackupType> {
|
||||||
const ID_STRINGS: &'static [&'static str] =
|
const ID_STRINGS: &[&str] =
|
||||||
&["EEPROM", "SRAM", "FLASH_", "FLASH512_", "FLASH1M_"];
|
&["EEPROM", "SRAM", "FLASH_", "FLASH512_", "FLASH1M_"];
|
||||||
|
|
||||||
for i in 0..5 {
|
for i in 0..5 {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use super::{GPIO_PORT_CONTROL, GPIO_PORT_DATA, GPIO_PORT_DIRECTION};
|
||||||
use bit::BitIndex;
|
use bit::BitIndex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum GpioDirection {
|
pub enum GpioDirection {
|
||||||
/// GPIO to GBA
|
/// GPIO to GBA
|
||||||
In = 0,
|
In = 0,
|
||||||
|
|
|
@ -83,7 +83,7 @@ pub fn parse(bytes: &[u8]) -> GBAResult<CartridgeHeader> {
|
||||||
game_code: String::from(game_code),
|
game_code: String::from(game_code),
|
||||||
maker_code: String::from(maker_code),
|
maker_code: String::from(maker_code),
|
||||||
software_version: bytes[0xbc],
|
software_version: bytes[0xbc],
|
||||||
checksum: checksum,
|
checksum,
|
||||||
// ram_entry_point: ram_entry_point,
|
// ram_entry_point: ram_entry_point,
|
||||||
// joybus_entry_point: joybus_entry_point,
|
// joybus_entry_point: joybus_entry_point,
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,7 +18,7 @@ fn num2bcd(mut num: u8) -> u8 {
|
||||||
while num > 0 {
|
while num > 0 {
|
||||||
let x = num % 10;
|
let x = num % 10;
|
||||||
bcd += x * digit;
|
bcd += x * digit;
|
||||||
digit = digit << 4;
|
digit <<= 4;
|
||||||
num /= 10;
|
num /= 10;
|
||||||
}
|
}
|
||||||
bcd
|
bcd
|
||||||
|
@ -168,7 +168,7 @@ impl SerialBuffer {
|
||||||
} else {
|
} else {
|
||||||
(1 << self.counter) - 1
|
(1 << self.counter) - 1
|
||||||
};
|
};
|
||||||
Some(self.byte & u8::from(mask))
|
Some(self.byte & mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ impl Rtc {
|
||||||
RegisterKind::DateTime => {
|
RegisterKind::DateTime => {
|
||||||
let local: DateTime<Local> = Local::now();
|
let local: DateTime<Local> = Local::now();
|
||||||
let year = local.year();
|
let year = local.year();
|
||||||
assert!(year >= 2000 && year <= 2099); // Wonder if I will live to see this one fail
|
assert!((2000..=2099).contains(&year)); // Wonder if I will live to see this one fail
|
||||||
|
|
||||||
let hour = if self.status.mode_24h() {
|
let hour = if self.status.mode_24h() {
|
||||||
local.hour()
|
local.hour()
|
||||||
|
@ -498,16 +498,16 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn transmit(rtc: &mut Rtc, gpio_state: &GpioState, bit: u8) {
|
fn transmit(rtc: &mut Rtc, gpio_state: &GpioState, bit: u8) {
|
||||||
rtc.write(&gpio_state, 0b0100_u16 | (u16::from(bit) << 1));
|
rtc.write(gpio_state, 0b0100_u16 | (u16::from(bit) << 1));
|
||||||
rtc.write(&gpio_state, 0b0101_u16);
|
rtc.write(gpio_state, 0b0101_u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive_bytes(rtc: &mut Rtc, gpio_state: &GpioState, bytes: &mut [u8]) {
|
fn receive_bytes(rtc: &mut Rtc, gpio_state: &GpioState, bytes: &mut [u8]) {
|
||||||
for byte in bytes.iter_mut() {
|
for byte in bytes.iter_mut() {
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
rtc.write(&gpio_state, 0b0100_u16);
|
rtc.write(gpio_state, 0b0100_u16);
|
||||||
let data = rtc.read(&gpio_state);
|
let data = rtc.read(gpio_state);
|
||||||
rtc.write(&gpio_state, 0b0101_u16);
|
rtc.write(gpio_state, 0b0101_u16);
|
||||||
byte.set_bit(i, data.bit(Port::Sio.index()));
|
byte.set_bit(i, data.bit(Port::Sio.index()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -523,11 +523,11 @@ mod tests {
|
||||||
assert_eq!(rtc.state, RtcState::Idle);
|
assert_eq!(rtc.state, RtcState::Idle);
|
||||||
|
|
||||||
// set CS low,
|
// set CS low,
|
||||||
rtc.write(&gpio_state, 0b0001);
|
rtc.write(gpio_state, 0b0001);
|
||||||
assert_eq!(rtc.state, RtcState::WaitForChipSelectHigh);
|
assert_eq!(rtc.state, RtcState::WaitForChipSelectHigh);
|
||||||
|
|
||||||
// set CS high, SCK rising edge
|
// set CS high, SCK rising edge
|
||||||
rtc.write(&gpio_state, 0b0101);
|
rtc.write(gpio_state, 0b0101);
|
||||||
assert_eq!(rtc.state, RtcState::GetCommandByte);
|
assert_eq!(rtc.state, RtcState::GetCommandByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl DmaChannel {
|
||||||
panic!("invalid dma id {}", id);
|
panic!("invalid dma id {}", id);
|
||||||
}
|
}
|
||||||
DmaChannel {
|
DmaChannel {
|
||||||
id: id,
|
id,
|
||||||
irq: Interrupt::from_usize(id + 8).unwrap(),
|
irq: Interrupt::from_usize(id + 8).unwrap(),
|
||||||
running: false,
|
running: false,
|
||||||
src: 0,
|
src: 0,
|
||||||
|
@ -115,7 +115,7 @@ impl DmaChannel {
|
||||||
self.running = false;
|
self.running = false;
|
||||||
}
|
}
|
||||||
self.ctrl = ctrl;
|
self.ctrl = ctrl;
|
||||||
return start_immediately;
|
start_immediately
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer(&mut self, sb: &mut SysBus) {
|
fn transfer(&mut self, sb: &mut SysBus) {
|
||||||
|
|
|
@ -112,13 +112,13 @@ impl GameBoyAdvance {
|
||||||
io_devs,
|
io_devs,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_video_interface"))]
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
video_device: video_device,
|
video_device,
|
||||||
audio_device: audio_device,
|
audio_device,
|
||||||
input_device: input_device,
|
input_device,
|
||||||
|
|
||||||
scheduler: scheduler,
|
scheduler,
|
||||||
|
|
||||||
interrupt_flags: interrupt_flags,
|
interrupt_flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
gba.sysbus.init(gba.cpu.weak_ptr());
|
gba.sysbus.init(gba.cpu.weak_ptr());
|
||||||
|
@ -160,15 +160,15 @@ impl GameBoyAdvance {
|
||||||
|
|
||||||
Ok(GameBoyAdvance {
|
Ok(GameBoyAdvance {
|
||||||
cpu: arm7tdmi,
|
cpu: arm7tdmi,
|
||||||
sysbus: sysbus,
|
sysbus,
|
||||||
io_devs,
|
io_devs,
|
||||||
|
|
||||||
interrupt_flags: interrupts,
|
interrupt_flags: interrupts,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_video_interface"))]
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
video_device: video_device,
|
video_device,
|
||||||
audio_device: audio_device,
|
audio_device,
|
||||||
input_device: input_device,
|
input_device,
|
||||||
|
|
||||||
scheduler,
|
scheduler,
|
||||||
})
|
})
|
||||||
|
|
|
@ -25,7 +25,7 @@ impl RenderLayerKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
pub struct RenderLayer {
|
pub struct RenderLayer {
|
||||||
pub kind: RenderLayerKind,
|
pub kind: RenderLayerKind,
|
||||||
pub priority: u16,
|
pub priority: u16,
|
||||||
|
@ -36,23 +36,23 @@ impl RenderLayer {
|
||||||
pub fn background(bg: usize, pixel: Rgb15, priority: u16) -> RenderLayer {
|
pub fn background(bg: usize, pixel: Rgb15, priority: u16) -> RenderLayer {
|
||||||
RenderLayer {
|
RenderLayer {
|
||||||
kind: RenderLayerKind::from_usize(1 << bg).unwrap(),
|
kind: RenderLayerKind::from_usize(1 << bg).unwrap(),
|
||||||
pixel: pixel,
|
pixel,
|
||||||
priority: priority,
|
priority,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn objects(pixel: Rgb15, priority: u16) -> RenderLayer {
|
pub fn objects(pixel: Rgb15, priority: u16) -> RenderLayer {
|
||||||
RenderLayer {
|
RenderLayer {
|
||||||
kind: RenderLayerKind::Objects,
|
kind: RenderLayerKind::Objects,
|
||||||
pixel: pixel,
|
pixel,
|
||||||
priority: priority,
|
priority,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn backdrop(pixel: Rgb15) -> RenderLayer {
|
pub fn backdrop(pixel: Rgb15) -> RenderLayer {
|
||||||
RenderLayer {
|
RenderLayer {
|
||||||
kind: RenderLayerKind::Backdrop,
|
kind: RenderLayerKind::Backdrop,
|
||||||
pixel: pixel,
|
pixel,
|
||||||
priority: 4,
|
priority: 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,8 @@ use std::fmt;
|
||||||
pub mod consts {
|
pub mod consts {
|
||||||
pub use super::VRAM_ADDR;
|
pub use super::VRAM_ADDR;
|
||||||
pub const VIDEO_RAM_SIZE: usize = 128 * 1024;
|
pub const VIDEO_RAM_SIZE: usize = 128 * 1024;
|
||||||
pub const PALETTE_RAM_SIZE: usize = 1 * 1024;
|
pub const PALETTE_RAM_SIZE: usize = 1024;
|
||||||
pub const OAM_SIZE: usize = 1 * 1024;
|
pub const OAM_SIZE: usize = 1024;
|
||||||
|
|
||||||
pub const DISPLAY_WIDTH: usize = 240;
|
pub const DISPLAY_WIDTH: usize = 240;
|
||||||
pub const DISPLAY_HEIGHT: usize = 160;
|
pub const DISPLAY_HEIGHT: usize = 160;
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub trait GpuMemoryMappedIO {
|
||||||
fn write(&mut self, value: u16);
|
fn write(&mut self, value: u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum ObjMapping {
|
pub enum ObjMapping {
|
||||||
TwoDimension,
|
TwoDimension,
|
||||||
OneDimension,
|
OneDimension,
|
||||||
|
@ -112,7 +112,7 @@ impl GpuMemoryMappedIO for DisplayStatus {
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read(&self) -> u16 {
|
fn read(&self) -> u16 {
|
||||||
u16::from(self.vblank_flag) << 0
|
u16::from(self.vblank_flag)
|
||||||
| u16::from(self.hblank_flag) << 1
|
| u16::from(self.hblank_flag) << 1
|
||||||
| u16::from(self.vcount_flag) << 2
|
| u16::from(self.vcount_flag) << 2
|
||||||
| u16::from(self.vblank_irq_enable) << 3
|
| u16::from(self.vblank_irq_enable) << 3
|
||||||
|
@ -136,7 +136,7 @@ pub struct BgControl {
|
||||||
impl GpuMemoryMappedIO for BgControl {
|
impl GpuMemoryMappedIO for BgControl {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, value: u16) {
|
fn write(&mut self, value: u16) {
|
||||||
self.priority = (value >> 0) & 0b11;
|
self.priority = value & 0b11;
|
||||||
self.character_base_block = (value >> 2) & 0b11;
|
self.character_base_block = (value >> 2) & 0b11;
|
||||||
self.mosaic = (value >> 6) & 1 != 0;
|
self.mosaic = (value >> 6) & 1 != 0;
|
||||||
self.palette256 = (value >> 7) & 1 != 0;
|
self.palette256 = (value >> 7) & 1 != 0;
|
||||||
|
@ -231,7 +231,7 @@ impl BlendFlags {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(SmartDefault, Debug, Serialize, Deserialize, Primitive, PartialEq, Clone, Copy)]
|
#[derive(SmartDefault, Debug, Serialize, Deserialize, Primitive, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum BlendMode {
|
pub enum BlendMode {
|
||||||
#[default]
|
#[default]
|
||||||
BldNone = 0b00,
|
BldNone = 0b00,
|
||||||
|
@ -250,14 +250,14 @@ pub struct BlendControl {
|
||||||
impl GpuMemoryMappedIO for BlendControl {
|
impl GpuMemoryMappedIO for BlendControl {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, value: u16) {
|
fn write(&mut self, value: u16) {
|
||||||
self.target1 = BlendFlags::from_bits_truncate((value >> 0) & 0x3f);
|
self.target1 = BlendFlags::from_bits_truncate(value & 0x3f);
|
||||||
self.target2 = BlendFlags::from_bits_truncate((value >> 8) & 0x3f);
|
self.target2 = BlendFlags::from_bits_truncate((value >> 8) & 0x3f);
|
||||||
self.mode = BlendMode::from_u16((value >> 6) & 0b11).unwrap_or_else(|| unreachable!());
|
self.mode = BlendMode::from_u16((value >> 6) & 0b11).unwrap_or_else(|| unreachable!());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read(&self) -> u16 {
|
fn read(&self) -> u16 {
|
||||||
(self.target1.bits() << 0) | (self.mode as u16) << 6 | (self.target2.bits() << 8)
|
self.target1.bits() | (self.mode as u16) << 6 | (self.target2.bits() << 8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ impl ViewPort {
|
||||||
pub fn new(w: i32, h: i32) -> ViewPort {
|
pub fn new(w: i32, h: i32) -> ViewPort {
|
||||||
ViewPort {
|
ViewPort {
|
||||||
origin: (0, 0),
|
origin: (0, 0),
|
||||||
w: w,
|
w,
|
||||||
h: h,
|
h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ impl Gpu {
|
||||||
|
|
||||||
fn read_obj_attrs(&mut self, obj: usize) -> ObjAttrs {
|
fn read_obj_attrs(&mut self, obj: usize) -> ObjAttrs {
|
||||||
let addr = ATTRS_SIZE * (obj as u32);
|
let addr = ATTRS_SIZE * (obj as u32);
|
||||||
let attr0 = Attribute0(self.oam.read_16(addr + 0));
|
let attr0 = Attribute0(self.oam.read_16(addr));
|
||||||
let attr1 = Attribute1(self.oam.read_16(addr + 2));
|
let attr1 = Attribute1(self.oam.read_16(addr + 2));
|
||||||
let attr2 = Attribute2(self.oam.read_16(addr + 4));
|
let attr2 = Attribute2(self.oam.read_16(addr + 4));
|
||||||
ObjAttrs(attr0, attr1, attr2)
|
ObjAttrs(attr0, attr1, attr2)
|
||||||
|
@ -305,7 +305,7 @@ impl Gpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Primitive, Copy, Clone, PartialEq)]
|
#[derive(Debug, Primitive, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum ObjMode {
|
pub enum ObjMode {
|
||||||
Normal = 0b00,
|
Normal = 0b00,
|
||||||
Sfx = 0b01,
|
Sfx = 0b01,
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl Gpu {
|
||||||
}
|
}
|
||||||
se_row = 0;
|
se_row = 0;
|
||||||
if bg_width == 512 {
|
if bg_width == 512 {
|
||||||
sbb = sbb ^ 1;
|
sbb ^= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Serialize, Deserialize, Copy, Clone, Default, PartialEq)]
|
#[derive(Serialize, Deserialize, Copy, Clone, Default, PartialEq, Eq)]
|
||||||
pub struct Rgb15(u16);
|
pub struct Rgb15(u16);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
pub r, set_r: 4, 0;
|
pub r, set_r: 4, 0;
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum WindowType {
|
pub enum WindowType {
|
||||||
Win0,
|
Win0,
|
||||||
Win1,
|
Win1,
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub trait InterruptConnect {
|
||||||
fn connect_irq(&mut self, interrupt_flags: SharedInterruptFlags);
|
fn connect_irq(&mut self, interrupt_flags: SharedInterruptFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Primitive, Copy, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Primitive, Copy, Clone, PartialEq, Eq)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub enum Interrupt {
|
pub enum Interrupt {
|
||||||
LCD_VBlank = 0,
|
LCD_VBlank = 0,
|
||||||
|
@ -77,7 +77,7 @@ impl IrqBitmask {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
#[derive(Serialize, Deserialize, Default, Copy, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Default, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct IrqBitmask(u16);
|
pub struct IrqBitmask(u16);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
u16;
|
u16;
|
||||||
|
|
|
@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use self::consts::*;
|
use self::consts::*;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum HaltState {
|
pub enum HaltState {
|
||||||
Running,
|
Running,
|
||||||
Halt, // In Halt mode, the CPU is paused as long as (IE AND IF)=0,
|
Halt, // In Halt mode, the CPU is paused as long as (IE AND IF)=0,
|
||||||
|
@ -67,7 +67,7 @@ impl IoDevices {
|
||||||
keyinput: keypad::KEYINPUT_ALL_RELEASED,
|
keyinput: keypad::KEYINPUT_ALL_RELEASED,
|
||||||
waitcnt: WaitControl(0),
|
waitcnt: WaitControl(0),
|
||||||
debug: DebugPort::new(),
|
debug: DebugPort::new(),
|
||||||
scheduler: scheduler,
|
scheduler,
|
||||||
sysbus_ptr: Default::default(),
|
sysbus_ptr: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,13 +82,13 @@ impl InterruptConnect for IoDevices {
|
||||||
self.intc.connect_irq(interrupt_flags.clone());
|
self.intc.connect_irq(interrupt_flags.clone());
|
||||||
self.gpu.connect_irq(interrupt_flags.clone());
|
self.gpu.connect_irq(interrupt_flags.clone());
|
||||||
self.dmac.connect_irq(interrupt_flags.clone());
|
self.dmac.connect_irq(interrupt_flags.clone());
|
||||||
self.timers.connect_irq(interrupt_flags.clone());
|
self.timers.connect_irq(interrupt_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SchedulerConnect for IoDevices {
|
impl SchedulerConnect for IoDevices {
|
||||||
fn connect_scheduler(&mut self, scheduler: SharedScheduler) {
|
fn connect_scheduler(&mut self, scheduler: SharedScheduler) {
|
||||||
self.scheduler = scheduler.clone();
|
self.scheduler = scheduler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ impl DebugRead for IoDevices {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
#[derive(Serialize, Deserialize, Default, Copy, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Default, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct WaitControl(u16);
|
pub struct WaitControl(u16);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
u16;
|
u16;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#[derive(Debug, Primitive, PartialEq)]
|
#[derive(Debug, Primitive, PartialEq, Eq)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum Keys {
|
pub enum Keys {
|
||||||
ButtonA = 0,
|
ButtonA = 0,
|
||||||
|
@ -16,7 +16,7 @@ pub enum Keys {
|
||||||
pub const NUM_KEYS: usize = 10;
|
pub const NUM_KEYS: usize = 10;
|
||||||
pub const KEYINPUT_ALL_RELEASED: u16 = 0b1111111111;
|
pub const KEYINPUT_ALL_RELEASED: u16 = 0b1111111111;
|
||||||
|
|
||||||
#[derive(Debug, Primitive, PartialEq)]
|
#[derive(Debug, Primitive, PartialEq, Eq)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum KeyState {
|
pub enum KeyState {
|
||||||
Pressed = 0,
|
Pressed = 0,
|
||||||
|
|
|
@ -9,7 +9,7 @@ extern crate debug_stub_derive;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate enum_primitive_derive;
|
extern crate enum_primitive_derive;
|
||||||
use num_traits;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitfield;
|
extern crate bitfield;
|
||||||
|
@ -27,7 +27,7 @@ extern crate smart_default;
|
||||||
|
|
||||||
extern crate cfg_if;
|
extern crate cfg_if;
|
||||||
|
|
||||||
use zip;
|
|
||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
|
@ -29,7 +29,7 @@ impl Resampler for CosineResampler {
|
||||||
output.push((left, right));
|
output.push((left, right));
|
||||||
self.phase += self.in_freq / self.out_freq;
|
self.phase += self.in_freq / self.out_freq;
|
||||||
}
|
}
|
||||||
self.phase = self.phase - 1.0;
|
self.phase -= 1.0;
|
||||||
self.last_in_sample = s;
|
self.last_in_sample = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,8 @@ impl CosineResampler {
|
||||||
CosineResampler {
|
CosineResampler {
|
||||||
last_in_sample: Default::default(),
|
last_in_sample: Default::default(),
|
||||||
phase: 0.0,
|
phase: 0.0,
|
||||||
in_freq: in_freq,
|
in_freq,
|
||||||
out_freq: out_freq,
|
out_freq,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ impl SoundController {
|
||||||
sample_rate: 32_768f32,
|
sample_rate: 32_768f32,
|
||||||
dma_sound: [Default::default(), Default::default()],
|
dma_sound: [Default::default(), Default::default()],
|
||||||
|
|
||||||
resampler: resampler,
|
resampler,
|
||||||
output_buffer: Vec::with_capacity(1024),
|
output_buffer: Vec::with_capacity(1024),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,12 +196,10 @@ impl SoundController {
|
||||||
info!("MSE enabled!");
|
info!("MSE enabled!");
|
||||||
self.mse = true;
|
self.mse = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else if self.mse {
|
||||||
if self.mse {
|
|
||||||
info!("MSE disabled!");
|
info!("MSE disabled!");
|
||||||
self.mse = false;
|
self.mse = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// other fields of this register are read-only anyway, ignore them.
|
// other fields of this register are read-only anyway, ignore them.
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -227,10 +227,10 @@ impl SysBus {
|
||||||
/// must be called whenever this object is instanciated
|
/// must be called whenever this object is instanciated
|
||||||
pub fn init(&mut self, arm_core: WeakPointer<Arm7tdmiCore<SysBus>>) {
|
pub fn init(&mut self, arm_core: WeakPointer<Arm7tdmiCore<SysBus>>) {
|
||||||
self.arm_core = arm_core.clone();
|
self.arm_core = arm_core.clone();
|
||||||
self.bios.connect_arm_core(arm_core.clone());
|
self.bios.connect_arm_core(arm_core);
|
||||||
let ptr = SysBusPtr::new(self as *mut SysBus);
|
let ptr = SysBusPtr::new(self as *mut SysBus);
|
||||||
// HACK
|
// HACK
|
||||||
self.io.set_sysbus_ptr(ptr.clone());
|
self.io.set_sysbus_ptr(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_waitcnt_written(&mut self, waitcnt: WaitControl) {
|
pub fn on_waitcnt_written(&mut self, waitcnt: WaitControl) {
|
||||||
|
@ -281,7 +281,7 @@ impl SysBus {
|
||||||
match (r15 >> 24) as usize {
|
match (r15 >> 24) as usize {
|
||||||
PAGE_BIOS | PAGE_OAM => {
|
PAGE_BIOS | PAGE_OAM => {
|
||||||
// TODO this is probably wrong, according to GBATEK, we should be using $+6 here but it isn't prefetched yet.
|
// TODO this is probably wrong, according to GBATEK, we should be using $+6 here but it isn't prefetched yet.
|
||||||
value = value << 16;
|
value <<= 16;
|
||||||
value |= decoded;
|
value |= decoded;
|
||||||
}
|
}
|
||||||
PAGE_IWRAM => {
|
PAGE_IWRAM => {
|
||||||
|
@ -291,7 +291,7 @@ impl SysBus {
|
||||||
value |= decoded << 16;
|
value |= decoded << 16;
|
||||||
} else {
|
} else {
|
||||||
// LSW = OldLO, MSW = [$+4] ;for opcodes at non-4-byte aligned locations
|
// LSW = OldLO, MSW = [$+4] ;for opcodes at non-4-byte aligned locations
|
||||||
value = value << 16;
|
value <<= 16;
|
||||||
value |= decoded;
|
value |= decoded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ impl Timer {
|
||||||
panic!("invalid timer id {}", timer_id);
|
panic!("invalid timer id {}", timer_id);
|
||||||
}
|
}
|
||||||
Timer {
|
Timer {
|
||||||
timer_id: timer_id,
|
timer_id,
|
||||||
irq: Interrupt::from_usize(timer_id + 3).unwrap(),
|
irq: Interrupt::from_usize(timer_id + 3).unwrap(),
|
||||||
interrupt_flags,
|
interrupt_flags,
|
||||||
data: 0,
|
data: 0,
|
||||||
|
@ -78,7 +78,7 @@ impl Timer {
|
||||||
|
|
||||||
let ticks_remaining = self.ticks_to_overflow();
|
let ticks_remaining = self.ticks_to_overflow();
|
||||||
num_overflows += ticks / ticks_remaining;
|
num_overflows += ticks / ticks_remaining;
|
||||||
ticks = ticks % ticks_remaining;
|
ticks %= ticks_remaining;
|
||||||
|
|
||||||
if self.ctl.irq_enabled() {
|
if self.ctl.irq_enabled() {
|
||||||
interrupt::signal_irq(&self.interrupt_flags, self.irq);
|
interrupt::signal_irq(&self.interrupt_flags, self.irq);
|
||||||
|
@ -160,13 +160,10 @@ impl Timers {
|
||||||
if id != 3 {
|
if id != 3 {
|
||||||
let next_timer_id = id + 1;
|
let next_timer_id = id + 1;
|
||||||
let next_timer = &mut self.timers[next_timer_id];
|
let next_timer = &mut self.timers[next_timer_id];
|
||||||
if next_timer.ctl.cascade() {
|
if next_timer.ctl.cascade() && next_timer.update(1) > 0 {
|
||||||
if next_timer.update(1) > 0 {
|
|
||||||
drop(next_timer);
|
|
||||||
self.handle_timer_overflow(next_timer_id, apu, dmac);
|
self.handle_timer_overflow(next_timer_id, apu, dmac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if id == 0 || id == 1 {
|
if id == 0 || id == 1 {
|
||||||
apu.handle_timer_overflow(dmac, id, 1);
|
apu.handle_timer_overflow(dmac, id, 1);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue