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_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().insert(0x0000, coproc_ram.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::devices::{Clock, ClockElapsed, Address, Addressable, Steppable, Inspectable, Transmutable, read_beu16};
|
||||
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;
|
||||
@ -135,15 +135,6 @@ impl Ym7101Memory {
|
||||
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) {
|
||||
match mode {
|
||||
DmaType::None => {
|
||||
@ -316,6 +307,9 @@ pub struct Ym7101State {
|
||||
pub sprites_addr: usize,
|
||||
pub hscroll_addr: usize,
|
||||
|
||||
pub sprites: Vec<Sprite>,
|
||||
pub sprites_by_line: Vec<Vec<usize>>,
|
||||
|
||||
pub last_clock: Clock,
|
||||
pub h_clock: u32,
|
||||
pub v_clock: u32,
|
||||
@ -344,6 +338,9 @@ impl Ym7101State {
|
||||
sprites_addr: 0,
|
||||
hscroll_addr: 0,
|
||||
|
||||
sprites: vec![],
|
||||
sprites_by_line: vec![],
|
||||
|
||||
last_clock: 0,
|
||||
h_clock: 0,
|
||||
v_clock: 0,
|
||||
@ -432,12 +429,12 @@ impl Ym7101State {
|
||||
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 max_lines = self.screen_size.1 * 8;
|
||||
|
||||
let mut sprites = vec![];
|
||||
let mut lines = vec![vec![]; max_lines];
|
||||
self.sprites.clear();
|
||||
self.sprites_by_line = vec![vec![]; max_lines];
|
||||
|
||||
let mut link = 0;
|
||||
loop {
|
||||
@ -447,19 +444,17 @@ impl Ym7101State {
|
||||
for y in 0..(sprite.size.1 as i16 * 8) {
|
||||
let pos_y = start_y + y;
|
||||
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;
|
||||
sprites.push(sprite);
|
||||
self.sprites.push(sprite);
|
||||
|
||||
if link == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(sprites, lines)
|
||||
}
|
||||
|
||||
pub fn get_pattern_pixel(&self, pattern_word: u16, x: usize, y: usize) -> (u8, u8) {
|
||||
@ -480,12 +475,17 @@ impl Ym7101State {
|
||||
}
|
||||
|
||||
pub fn draw_frame(&mut self, frame: &mut Frame) {
|
||||
let bg_colour = ((self.background & 0x30) >> 4, self.background & 0x0f);
|
||||
let (sprites, sprites_per_line) = self.build_sprites_lists();
|
||||
self.build_sprites_lists();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_frame_line(&mut self, frame: &mut Frame, y: usize) {
|
||||
let bg_colour = ((self.background & 0x30) >> 4, self.background & 0x0f);
|
||||
|
||||
let (hscrolling_a, hscrolling_b) = self.get_hscroll(y / 8, y % 8);
|
||||
for x in 0..(self.screen_size.0 * 8) {
|
||||
let (vscrolling_a, vscrolling_b) = self.get_vscroll(x / 8);
|
||||
|
||||
@ -516,12 +516,13 @@ impl Ym7101State {
|
||||
|
||||
let mut pixel_sprite = (0, 0);
|
||||
let mut priority_sprite = false;
|
||||
for sprite_num in sprites_per_line[y].iter() {
|
||||
let offset_x = x as i16 - sprites[*sprite_num].pos.0;
|
||||
let offset_y = y as i16 - sprites[*sprite_num].pos.1;
|
||||
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;
|
||||
|
||||
if offset_x >= 0 && offset_x < (sprites[*sprite_num].size.0 as i16 * 8) {
|
||||
let pattern = sprites[*sprite_num].calculate_pattern(offset_x as usize / 8, offset_y as usize / 8);
|
||||
if offset_x >= 0 && offset_x < (sprite.size.0 as i16 * 8) {
|
||||
let pattern = sprite.calculate_pattern(offset_x as usize / 8, offset_y as usize / 8);
|
||||
priority_sprite = (pattern & 0x8000) != 0;
|
||||
|
||||
pixel_sprite = self.get_pattern_pixel(pattern, offset_x as usize % 8, offset_y as usize % 8);
|
||||
@ -560,7 +561,6 @@ impl Ym7101State {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Sprite {
|
||||
@ -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 {
|
||||
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 {
|
||||
fn len(&self) -> usize {
|
||||
0x20
|
||||
|
Loading…
Reference in New Issue
Block a user