mirror of
https://github.com/transistorfet/moa.git
synced 2025-08-11 14:25:28 +00:00
Minor reorganization
This commit is contained in:
@@ -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,12 +475,17 @@ 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
for x in 0..(self.screen_size.0 * 8) {
|
||||||
let (vscrolling_a, vscrolling_b) = self.get_vscroll(x / 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 pixel_sprite = (0, 0);
|
||||||
let mut priority_sprite = false;
|
let mut priority_sprite = false;
|
||||||
for sprite_num in sprites_per_line[y].iter() {
|
for sprite_num in self.sprites_by_line[y].iter() {
|
||||||
let offset_x = x as i16 - sprites[*sprite_num].pos.0;
|
let sprite = &self.sprites[*sprite_num];
|
||||||
let offset_y = y as i16 - sprites[*sprite_num].pos.1;
|
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) {
|
if offset_x >= 0 && offset_x < (sprite.size.0 as i16 * 8) {
|
||||||
let pattern = sprites[*sprite_num].calculate_pattern(offset_x as usize / 8, offset_y as usize / 8);
|
let pattern = sprite.calculate_pattern(offset_x as usize / 8, offset_y as usize / 8);
|
||||||
priority_sprite = (pattern & 0x8000) != 0;
|
priority_sprite = (pattern & 0x8000) != 0;
|
||||||
|
|
||||||
pixel_sprite = self.get_pattern_pixel(pattern, offset_x as usize % 8, offset_y as usize % 8);
|
pixel_sprite = self.get_pattern_pixel(pattern, offset_x as usize % 8, offset_y as usize % 8);
|
||||||
@@ -561,7 +562,6 @@ impl Ym7101State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Sprite {
|
pub struct Sprite {
|
||||||
pub pos: (i16, i16),
|
pub pos: (i16, i16),
|
||||||
@@ -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
|
||||||
|
Reference in New Issue
Block a user