mirror of
https://github.com/transistorfet/moa.git
synced 2024-10-31 19:04:37 +00:00
Minor reorganization
This commit is contained in:
parent
a67c7bf56e
commit
cdbc93bb8a
@ -68,7 +68,7 @@ pub fn build_genesis<H: Host>(host: &mut H, options: SegaGenesisOptions) -> Resu
|
|||||||
let coproc_register = wrap_transmutable(CoprocessorBankRegister::new(bank_register.clone()));
|
let coproc_register = wrap_transmutable(CoprocessorBankRegister::new(bank_register.clone()));
|
||||||
let coproc_area = wrap_transmutable(CoprocessorBankArea::new(bank_register, system.bus.clone()));
|
let coproc_area = wrap_transmutable(CoprocessorBankArea::new(bank_register, system.bus.clone()));
|
||||||
|
|
||||||
let mut coproc_bus = Rc::new(RefCell::new(Bus::new()));
|
let coproc_bus = Rc::new(RefCell::new(Bus::new()));
|
||||||
coproc_bus.borrow_mut().set_ignore_unmapped(true);
|
coproc_bus.borrow_mut().set_ignore_unmapped(true);
|
||||||
coproc_bus.borrow_mut().insert(0x0000, coproc_ram.clone());
|
coproc_bus.borrow_mut().insert(0x0000, coproc_ram.clone());
|
||||||
coproc_bus.borrow_mut().insert(0x4000, coproc_ym_sound.clone());
|
coproc_bus.borrow_mut().insert(0x4000, coproc_ym_sound.clone());
|
||||||
|
@ -7,7 +7,7 @@ use crate::memory::dump_slice;
|
|||||||
use crate::signals::{EdgeSignal};
|
use crate::signals::{EdgeSignal};
|
||||||
use crate::devices::{Clock, ClockElapsed, Address, Addressable, Steppable, Inspectable, Transmutable, read_beu16};
|
use crate::devices::{Clock, ClockElapsed, Address, Addressable, Steppable, Inspectable, Transmutable, read_beu16};
|
||||||
use crate::host::traits::{Host, BlitableSurface, HostData};
|
use crate::host::traits::{Host, BlitableSurface, HostData};
|
||||||
use crate::host::gfx::{Frame, FrameSwapper, MASK_COLOUR};
|
use crate::host::gfx::{Frame, FrameSwapper};
|
||||||
|
|
||||||
|
|
||||||
const REG_MODE_SET_1: usize = 0x00;
|
const REG_MODE_SET_1: usize = 0x00;
|
||||||
@ -135,15 +135,6 @@ impl Ym7101Memory {
|
|||||||
read_beu16(addr)
|
read_beu16(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn read_u8(&self, target: Memory, addr: usize) -> u8 {
|
|
||||||
match target {
|
|
||||||
Memory::Vram => self.vram[addr],
|
|
||||||
Memory::Cram => self.cram[addr],
|
|
||||||
Memory::Vsram => self.vsram[addr],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_dma_mode(&mut self, mode: DmaType) {
|
pub fn set_dma_mode(&mut self, mode: DmaType) {
|
||||||
match mode {
|
match mode {
|
||||||
DmaType::None => {
|
DmaType::None => {
|
||||||
@ -316,6 +307,9 @@ pub struct Ym7101State {
|
|||||||
pub sprites_addr: usize,
|
pub sprites_addr: usize,
|
||||||
pub hscroll_addr: usize,
|
pub hscroll_addr: usize,
|
||||||
|
|
||||||
|
pub sprites: Vec<Sprite>,
|
||||||
|
pub sprites_by_line: Vec<Vec<usize>>,
|
||||||
|
|
||||||
pub last_clock: Clock,
|
pub last_clock: Clock,
|
||||||
pub h_clock: u32,
|
pub h_clock: u32,
|
||||||
pub v_clock: u32,
|
pub v_clock: u32,
|
||||||
@ -344,6 +338,9 @@ impl Ym7101State {
|
|||||||
sprites_addr: 0,
|
sprites_addr: 0,
|
||||||
hscroll_addr: 0,
|
hscroll_addr: 0,
|
||||||
|
|
||||||
|
sprites: vec![],
|
||||||
|
sprites_by_line: vec![],
|
||||||
|
|
||||||
last_clock: 0,
|
last_clock: 0,
|
||||||
h_clock: 0,
|
h_clock: 0,
|
||||||
v_clock: 0,
|
v_clock: 0,
|
||||||
@ -432,12 +429,12 @@ impl Ym7101State {
|
|||||||
cell_table + ((cell_x + (cell_y * self.scroll_size.0 as usize)) << 1)
|
cell_table + ((cell_x + (cell_y * self.scroll_size.0 as usize)) << 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_sprites_lists(&mut self) -> (Vec<Sprite>, Vec<Vec<usize>>) {
|
pub fn build_sprites_lists(&mut self) {
|
||||||
let sprite_table = self.sprites_addr;
|
let sprite_table = self.sprites_addr;
|
||||||
let max_lines = self.screen_size.1 * 8;
|
let max_lines = self.screen_size.1 * 8;
|
||||||
|
|
||||||
let mut sprites = vec![];
|
self.sprites.clear();
|
||||||
let mut lines = vec![vec![]; max_lines];
|
self.sprites_by_line = vec![vec![]; max_lines];
|
||||||
|
|
||||||
let mut link = 0;
|
let mut link = 0;
|
||||||
loop {
|
loop {
|
||||||
@ -447,19 +444,17 @@ impl Ym7101State {
|
|||||||
for y in 0..(sprite.size.1 as i16 * 8) {
|
for y in 0..(sprite.size.1 as i16 * 8) {
|
||||||
let pos_y = start_y + y;
|
let pos_y = start_y + y;
|
||||||
if pos_y >= 0 && pos_y < max_lines as i16 {
|
if pos_y >= 0 && pos_y < max_lines as i16 {
|
||||||
lines[pos_y as usize].push(sprites.len());
|
self.sprites_by_line[pos_y as usize].push(self.sprites.len());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
link = sprite.link as usize;
|
link = sprite.link as usize;
|
||||||
sprites.push(sprite);
|
self.sprites.push(sprite);
|
||||||
|
|
||||||
if link == 0 {
|
if link == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(sprites, lines)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pattern_pixel(&self, pattern_word: u16, x: usize, y: usize) -> (u8, u8) {
|
pub fn get_pattern_pixel(&self, pattern_word: u16, x: usize, y: usize) -> (u8, u8) {
|
||||||
@ -480,85 +475,90 @@ impl Ym7101State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_frame(&mut self, frame: &mut Frame) {
|
pub fn draw_frame(&mut self, frame: &mut Frame) {
|
||||||
let bg_colour = ((self.background & 0x30) >> 4, self.background & 0x0f);
|
self.build_sprites_lists();
|
||||||
let (sprites, sprites_per_line) = self.build_sprites_lists();
|
|
||||||
|
|
||||||
for y in 0..(self.screen_size.1 * 8) {
|
for y in 0..(self.screen_size.1 * 8) {
|
||||||
let (hscrolling_a, hscrolling_b) = self.get_hscroll(y / 8, y % 8);
|
self.draw_frame_line(frame, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for x in 0..(self.screen_size.0 * 8) {
|
pub fn draw_frame_line(&mut self, frame: &mut Frame, y: usize) {
|
||||||
let (vscrolling_a, vscrolling_b) = self.get_vscroll(x / 8);
|
let bg_colour = ((self.background & 0x30) >> 4, self.background & 0x0f);
|
||||||
|
|
||||||
let pixel_a_x = (x - hscrolling_a) % (self.scroll_size.0 * 8);
|
let (hscrolling_a, hscrolling_b) = self.get_hscroll(y / 8, y % 8);
|
||||||
let pixel_a_y = (y + vscrolling_a) % (self.scroll_size.1 * 8);
|
for x in 0..(self.screen_size.0 * 8) {
|
||||||
let pattern_a_addr = self.get_pattern_addr(self.scroll_a_addr, pixel_a_x / 8, pixel_a_y / 8);
|
let (vscrolling_a, vscrolling_b) = self.get_vscroll(x / 8);
|
||||||
let pattern_a_word = self.memory.read_beu16(Memory::Vram, pattern_a_addr);
|
|
||||||
let priority_a = (pattern_a_word & 0x8000) != 0;
|
|
||||||
let pixel_a = self.get_pattern_pixel(pattern_a_word, pixel_a_x % 8, pixel_a_y % 8);
|
|
||||||
|
|
||||||
let pixel_b_x = (x - hscrolling_b) % (self.scroll_size.0 * 8);
|
let pixel_a_x = (x - hscrolling_a) % (self.scroll_size.0 * 8);
|
||||||
let pixel_b_y = (y + vscrolling_b) % (self.scroll_size.1 * 8);
|
let pixel_a_y = (y + vscrolling_a) % (self.scroll_size.1 * 8);
|
||||||
let pattern_b_addr = self.get_pattern_addr(self.scroll_b_addr, pixel_b_x / 8, pixel_b_y / 8);
|
let pattern_a_addr = self.get_pattern_addr(self.scroll_a_addr, pixel_a_x / 8, pixel_a_y / 8);
|
||||||
let pattern_b_word = self.memory.read_beu16(Memory::Vram, pattern_b_addr);
|
let pattern_a_word = self.memory.read_beu16(Memory::Vram, pattern_a_addr);
|
||||||
let priority_b = (pattern_b_word & 0x8000) != 0;
|
let priority_a = (pattern_a_word & 0x8000) != 0;
|
||||||
let pixel_b = self.get_pattern_pixel(pattern_b_word, pixel_b_x % 8, pixel_b_y % 8);
|
let pixel_a = self.get_pattern_pixel(pattern_a_word, pixel_a_x % 8, pixel_a_y % 8);
|
||||||
|
|
||||||
let pixel_win = if self.window_addr != 0 && self.is_inside_window(x, y) {
|
let pixel_b_x = (x - hscrolling_b) % (self.scroll_size.0 * 8);
|
||||||
let pixel_win_x = x - self.window_pos.0.0 * 8;
|
let pixel_b_y = (y + vscrolling_b) % (self.scroll_size.1 * 8);
|
||||||
let pixel_win_y = y - self.window_pos.0.1 * 8;
|
let pattern_b_addr = self.get_pattern_addr(self.scroll_b_addr, pixel_b_x / 8, pixel_b_y / 8);
|
||||||
let pattern_win_addr = self.get_pattern_addr(self.window_addr, pixel_win_x / 8, pixel_win_y / 8);
|
let pattern_b_word = self.memory.read_beu16(Memory::Vram, pattern_b_addr);
|
||||||
let pattern_win_word = self.memory.read_beu16(Memory::Vram, pattern_win_addr);
|
let priority_b = (pattern_b_word & 0x8000) != 0;
|
||||||
//let priority_win = (pattern_win_word & 0x8000) != 0;
|
let pixel_b = self.get_pattern_pixel(pattern_b_word, pixel_b_x % 8, pixel_b_y % 8);
|
||||||
self.get_pattern_pixel(pattern_win_word, pixel_win_x % 8, pixel_win_y % 8)
|
|
||||||
} else {
|
|
||||||
(0, 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut pixel_sprite = (0, 0);
|
let pixel_win = if self.window_addr != 0 && self.is_inside_window(x, y) {
|
||||||
let mut priority_sprite = false;
|
let pixel_win_x = x - self.window_pos.0.0 * 8;
|
||||||
for sprite_num in sprites_per_line[y].iter() {
|
let pixel_win_y = y - self.window_pos.0.1 * 8;
|
||||||
let offset_x = x as i16 - sprites[*sprite_num].pos.0;
|
let pattern_win_addr = self.get_pattern_addr(self.window_addr, pixel_win_x / 8, pixel_win_y / 8);
|
||||||
let offset_y = y as i16 - sprites[*sprite_num].pos.1;
|
let pattern_win_word = self.memory.read_beu16(Memory::Vram, pattern_win_addr);
|
||||||
|
//let priority_win = (pattern_win_word & 0x8000) != 0;
|
||||||
|
self.get_pattern_pixel(pattern_win_word, pixel_win_x % 8, pixel_win_y % 8)
|
||||||
|
} else {
|
||||||
|
(0, 0)
|
||||||
|
};
|
||||||
|
|
||||||
if offset_x >= 0 && offset_x < (sprites[*sprite_num].size.0 as i16 * 8) {
|
let mut pixel_sprite = (0, 0);
|
||||||
let pattern = sprites[*sprite_num].calculate_pattern(offset_x as usize / 8, offset_y as usize / 8);
|
let mut priority_sprite = false;
|
||||||
priority_sprite = (pattern & 0x8000) != 0;
|
for sprite_num in self.sprites_by_line[y].iter() {
|
||||||
|
let sprite = &self.sprites[*sprite_num];
|
||||||
|
let offset_x = x as i16 - sprite.pos.0;
|
||||||
|
let offset_y = y as i16 - sprite.pos.1;
|
||||||
|
|
||||||
pixel_sprite = self.get_pattern_pixel(pattern, offset_x as usize % 8, offset_y as usize % 8);
|
if offset_x >= 0 && offset_x < (sprite.size.0 as i16 * 8) {
|
||||||
if pixel_sprite.1 != 0 {
|
let pattern = sprite.calculate_pattern(offset_x as usize / 8, offset_y as usize / 8);
|
||||||
break;
|
priority_sprite = (pattern & 0x8000) != 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let pixels = match (priority_sprite, priority_a, priority_b) {
|
pixel_sprite = self.get_pattern_pixel(pattern, offset_x as usize % 8, offset_y as usize % 8);
|
||||||
(false, false, true) =>
|
if pixel_sprite.1 != 0 {
|
||||||
[ pixel_win, pixel_b, pixel_sprite, pixel_a, bg_colour ],
|
|
||||||
(true, false, true) =>
|
|
||||||
[ pixel_win, pixel_sprite, pixel_b, pixel_a, bg_colour ],
|
|
||||||
(false, true, false) =>
|
|
||||||
[ pixel_win, pixel_a, pixel_sprite, pixel_b, bg_colour ],
|
|
||||||
(false, true, true) =>
|
|
||||||
[ pixel_win, pixel_a, pixel_b, pixel_sprite, bg_colour ],
|
|
||||||
_ =>
|
|
||||||
[ pixel_win, pixel_sprite, pixel_a, pixel_b, bg_colour ],
|
|
||||||
};
|
|
||||||
|
|
||||||
for i in 0..pixels.len() {
|
|
||||||
if pixels[i].1 != 0 || i == pixels.len() - 1 {
|
|
||||||
let mode = if pixels[i] == (3, 14) {
|
|
||||||
ColourMode::Highlight
|
|
||||||
} else if (!priority_a && !priority_b) || pixels[i] == (3, 15) {
|
|
||||||
ColourMode::Shadow
|
|
||||||
} else {
|
|
||||||
ColourMode::Normal
|
|
||||||
};
|
|
||||||
|
|
||||||
frame.set_pixel(x as u32, y as u32, self.get_palette_colour(pixels[i].0, pixels[i].1, mode));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pixels = match (priority_sprite, priority_a, priority_b) {
|
||||||
|
(false, false, true) =>
|
||||||
|
[ pixel_win, pixel_b, pixel_sprite, pixel_a, bg_colour ],
|
||||||
|
(true, false, true) =>
|
||||||
|
[ pixel_win, pixel_sprite, pixel_b, pixel_a, bg_colour ],
|
||||||
|
(false, true, false) =>
|
||||||
|
[ pixel_win, pixel_a, pixel_sprite, pixel_b, bg_colour ],
|
||||||
|
(false, true, true) =>
|
||||||
|
[ pixel_win, pixel_a, pixel_b, pixel_sprite, bg_colour ],
|
||||||
|
_ =>
|
||||||
|
[ pixel_win, pixel_sprite, pixel_a, pixel_b, bg_colour ],
|
||||||
|
};
|
||||||
|
|
||||||
|
for i in 0..pixels.len() {
|
||||||
|
if pixels[i].1 != 0 || i == pixels.len() - 1 {
|
||||||
|
let mode = if pixels[i] == (3, 14) {
|
||||||
|
ColourMode::Highlight
|
||||||
|
} else if (!priority_a && !priority_b) || pixels[i] == (3, 15) {
|
||||||
|
ColourMode::Shadow
|
||||||
|
} else {
|
||||||
|
ColourMode::Normal
|
||||||
|
};
|
||||||
|
|
||||||
|
frame.set_pixel(x as u32, y as u32, self.get_palette_colour(pixels[i].0, pixels[i].1, mode));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -598,6 +598,64 @@ impl Sprite {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Steppable for Ym7101 {
|
||||||
|
fn step(&mut self, system: &System) -> Result<ClockElapsed, Error> {
|
||||||
|
let diff = (system.clock - self.state.last_clock) as u32;
|
||||||
|
self.state.last_clock = system.clock;
|
||||||
|
|
||||||
|
if self.state.external_int_enabled() && self.external_interrupt.get() {
|
||||||
|
self.external_interrupt.set(false);
|
||||||
|
system.get_interrupt_controller().set(true, 2, 26)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state.h_clock += diff;
|
||||||
|
if (self.state.status & STATUS_IN_HBLANK) != 0 && self.state.h_clock >= 2_340 && self.state.h_clock <= 61_160 {
|
||||||
|
self.state.status &= !STATUS_IN_HBLANK;
|
||||||
|
}
|
||||||
|
if (self.state.status & STATUS_IN_HBLANK) == 0 && self.state.h_clock >= 61_160 {
|
||||||
|
self.state.status |= STATUS_IN_HBLANK;
|
||||||
|
|
||||||
|
self.state.h_scanlines = self.state.h_scanlines.wrapping_sub(1);
|
||||||
|
if self.state.hsync_int_enabled() && self.state.h_scanlines == 0 {
|
||||||
|
self.state.h_scanlines = self.state.h_int_lines;
|
||||||
|
system.get_interrupt_controller().set(true, 4, 28)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.state.h_clock > 63_500 {
|
||||||
|
self.state.h_clock -= 63_500;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state.v_clock += diff;
|
||||||
|
if (self.state.status & STATUS_IN_VBLANK) != 0 && self.state.v_clock >= 1_205_992 && self.state.v_clock <= 15_424_008 {
|
||||||
|
self.state.status &= !STATUS_IN_VBLANK;
|
||||||
|
}
|
||||||
|
if (self.state.status & STATUS_IN_VBLANK) == 0 && self.state.v_clock >= 15_424_008 {
|
||||||
|
self.state.status |= STATUS_IN_VBLANK;
|
||||||
|
|
||||||
|
if self.state.vsync_int_enabled() {
|
||||||
|
system.get_interrupt_controller().set(true, 6, 30)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.swapper.swap();
|
||||||
|
let mut frame = self.swapper.current.lock().unwrap();
|
||||||
|
self.state.draw_frame(&mut frame);
|
||||||
|
|
||||||
|
self.frame_complete.signal();
|
||||||
|
}
|
||||||
|
if self.state.v_clock > 16_630_000 {
|
||||||
|
self.state.v_clock -= 16_630_000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.state.mode_2 & MODE2_BF_DMA_ENABLED) != 0 {
|
||||||
|
self.state.memory.step_dma(system)?;
|
||||||
|
self.state.status = (self.state.status & !STATUS_DMA_BUSY) | (if self.state.memory.transfer_dma_busy { STATUS_DMA_BUSY } else { 0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((1_000_000_000 / 13_423_294) * 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub struct Ym7101 {
|
pub struct Ym7101 {
|
||||||
swapper: FrameSwapper,
|
swapper: FrameSwapper,
|
||||||
@ -695,63 +753,6 @@ fn decode_scroll_size(size: u8) -> usize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Steppable for Ym7101 {
|
|
||||||
fn step(&mut self, system: &System) -> Result<ClockElapsed, Error> {
|
|
||||||
let diff = (system.clock - self.state.last_clock) as u32;
|
|
||||||
self.state.last_clock = system.clock;
|
|
||||||
|
|
||||||
if self.state.external_int_enabled() && self.external_interrupt.get() {
|
|
||||||
self.external_interrupt.set(false);
|
|
||||||
system.get_interrupt_controller().set(true, 2, 26)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.state.h_clock += diff;
|
|
||||||
if (self.state.status & STATUS_IN_HBLANK) != 0 && self.state.h_clock >= 2_340 && self.state.h_clock <= 61_160 {
|
|
||||||
self.state.status &= !STATUS_IN_HBLANK;
|
|
||||||
}
|
|
||||||
if (self.state.status & STATUS_IN_HBLANK) == 0 && self.state.h_clock >= 61_160 {
|
|
||||||
self.state.status |= STATUS_IN_HBLANK;
|
|
||||||
|
|
||||||
self.state.h_scanlines = self.state.h_scanlines.wrapping_sub(1);
|
|
||||||
if self.state.hsync_int_enabled() && self.state.h_scanlines == 0 {
|
|
||||||
self.state.h_scanlines = self.state.h_int_lines;
|
|
||||||
system.get_interrupt_controller().set(true, 4, 28)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if self.state.h_clock > 63_500 {
|
|
||||||
self.state.h_clock -= 63_500;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.state.v_clock += diff;
|
|
||||||
if (self.state.status & STATUS_IN_VBLANK) != 0 && self.state.v_clock >= 1_205_992 && self.state.v_clock <= 15_424_008 {
|
|
||||||
self.state.status &= !STATUS_IN_VBLANK;
|
|
||||||
}
|
|
||||||
if (self.state.status & STATUS_IN_VBLANK) == 0 && self.state.v_clock >= 15_424_008 {
|
|
||||||
self.state.status |= STATUS_IN_VBLANK;
|
|
||||||
|
|
||||||
if self.state.vsync_int_enabled() {
|
|
||||||
system.get_interrupt_controller().set(true, 6, 30)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.swapper.swap();
|
|
||||||
let mut frame = self.swapper.current.lock().unwrap();
|
|
||||||
self.state.draw_frame(&mut frame);
|
|
||||||
|
|
||||||
self.frame_complete.signal();
|
|
||||||
}
|
|
||||||
if self.state.v_clock > 16_630_000 {
|
|
||||||
self.state.v_clock -= 16_630_000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.state.mode_2 & MODE2_BF_DMA_ENABLED) != 0 {
|
|
||||||
self.state.memory.step_dma(system)?;
|
|
||||||
self.state.status = (self.state.status & !STATUS_DMA_BUSY) | (if self.state.memory.transfer_dma_busy { STATUS_DMA_BUSY } else { 0 });
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((1_000_000_000 / 13_423_294) * 4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Addressable for Ym7101 {
|
impl Addressable for Ym7101 {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
0x20
|
0x20
|
||||||
|
Loading…
Reference in New Issue
Block a user