mirror of
https://github.com/transistorfet/moa.git
synced 2024-11-24 23:32:46 +00:00
Modified frame/frameswapper a bit
This commit is contained in:
parent
6dbae9620d
commit
8db32ab9b3
@ -11,6 +11,21 @@ pub struct Frame {
|
|||||||
pub bitmap: Vec<u32>,
|
pub bitmap: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Frame {
|
||||||
|
pub fn new(width: u32, height: u32) -> Self {
|
||||||
|
Self { width, height, bitmap: vec![0; (width * height) as usize] }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_shared(width: u32, height: u32) -> Arc<Mutex<Frame>> {
|
||||||
|
Arc::new(Mutex::new(Frame::new(width, height)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_updater(frame: Arc<Mutex<Frame>>) -> Box<dyn WindowUpdater> {
|
||||||
|
Box::new(FrameUpdateWrapper(frame))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl BlitableSurface for Frame {
|
impl BlitableSurface for Frame {
|
||||||
fn set_size(&mut self, width: u32, height: u32) {
|
fn set_size(&mut self, width: u32, height: u32) {
|
||||||
self.width = width;
|
self.width = width;
|
||||||
@ -38,55 +53,65 @@ impl BlitableSurface for Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct FrameUpdateWrapper(Arc<Mutex<Frame>>);
|
||||||
|
|
||||||
pub struct FrameSwapper {
|
impl WindowUpdater for FrameUpdateWrapper {
|
||||||
pub current: Frame,
|
fn get_size(&mut self) -> (u32, u32) {
|
||||||
//pub previous: Frame,
|
match self.0.lock() {
|
||||||
}
|
Ok(frame) => (frame.width, frame.height),
|
||||||
|
_ => (0, 0),
|
||||||
impl FrameSwapper {
|
|
||||||
pub fn new(width: u32, height: u32) -> FrameSwapper {
|
|
||||||
FrameSwapper {
|
|
||||||
current: Frame { width, height, bitmap: vec![0; (width * height) as usize] },
|
|
||||||
//previous: Frame { width, height, bitmap: vec![0; (width * height) as usize] },
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_shared(width: u32, height: u32) -> Arc<Mutex<FrameSwapper>> {
|
|
||||||
Arc::new(Mutex::new(FrameSwapper::new(width, height)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_boxed(swapper: Arc<Mutex<FrameSwapper>>) -> Box<dyn WindowUpdater> {
|
|
||||||
Box::new(FrameSwapperWrapper(swapper))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WindowUpdater for FrameSwapper {
|
|
||||||
fn get_size(&mut self) -> (u32, u32) {
|
|
||||||
(self.current.width, self.current.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_frame(&mut self, width: u32, _height: u32, bitmap: &mut [u32]) {
|
fn update_frame(&mut self, width: u32, _height: u32, bitmap: &mut [u32]) {
|
||||||
//std::mem::swap(&mut self.current, &mut self.previous);
|
if let Ok(frame) = self.0.lock() {
|
||||||
|
for y in 0..frame.height {
|
||||||
for y in 0..self.current.height {
|
for x in 0..frame.width {
|
||||||
for x in 0..self.current.width {
|
bitmap[(x + (y * width)) as usize] = frame.bitmap[(x + (y * frame.width)) as usize];
|
||||||
bitmap[(x + (y * width)) as usize] = self.current.bitmap[(x + (y * self.current.width)) as usize];
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FrameSwapperWrapper(Arc<Mutex<FrameSwapper>>);
|
|
||||||
|
|
||||||
impl WindowUpdater for FrameSwapperWrapper {
|
#[derive(Clone)]
|
||||||
fn get_size(&mut self) -> (u32, u32) {
|
pub struct FrameSwapper {
|
||||||
self.0.lock().map(|mut swapper| swapper.get_size()).unwrap_or((0, 0))
|
pub current: Arc<Mutex<Frame>>,
|
||||||
|
pub previous: Arc<Mutex<Frame>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FrameSwapper {
|
||||||
|
pub fn new(width: u32, height: u32) -> FrameSwapper {
|
||||||
|
FrameSwapper {
|
||||||
|
current: Arc::new(Mutex::new(Frame::new(width, height))),
|
||||||
|
previous: Arc::new(Mutex::new(Frame::new(width, height))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_frame(&mut self, width: u32, height: u32, bitmap: &mut [u32]) {
|
pub fn to_boxed(swapper: FrameSwapper) -> Box<dyn WindowUpdater> {
|
||||||
if let Ok(mut swapper) = self.0.lock() {
|
Box::new(swapper)
|
||||||
swapper.update_frame(width, height, bitmap);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowUpdater for FrameSwapper {
|
||||||
|
fn get_size(&mut self) -> (u32, u32) {
|
||||||
|
if let Ok(frame) = self.current.lock() {
|
||||||
|
(frame.width, frame.height)
|
||||||
|
} else {
|
||||||
|
(0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_frame(&mut self, width: u32, _height: u32, bitmap: &mut [u32]) {
|
||||||
|
std::mem::swap(&mut self.current.lock().unwrap().bitmap, &mut self.previous.lock().unwrap().bitmap);
|
||||||
|
|
||||||
|
if let Ok(frame) = self.previous.lock() {
|
||||||
|
for y in 0..frame.height {
|
||||||
|
for x in 0..frame.width {
|
||||||
|
bitmap[(x + (y * width)) as usize] = frame.bitmap[(x + (y * frame.width)) as usize];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,14 +539,14 @@ impl<'a> Iterator for PatternIterator<'a> {
|
|||||||
|
|
||||||
|
|
||||||
pub struct Ym7101 {
|
pub struct Ym7101 {
|
||||||
pub swapper: Arc<Mutex<FrameSwapper>>,
|
pub swapper: FrameSwapper,
|
||||||
pub state: Ym7101State,
|
pub state: Ym7101State,
|
||||||
pub external_interrupt: HostData<bool>,
|
pub external_interrupt: HostData<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ym7101 {
|
impl Ym7101 {
|
||||||
pub fn new<H: Host>(host: &mut H, external_interrupt: HostData<bool>) -> Ym7101 {
|
pub fn new<H: Host>(host: &mut H, external_interrupt: HostData<bool>) -> Ym7101 {
|
||||||
let swapper = FrameSwapper::new_shared(320, 224);
|
let swapper = FrameSwapper::new(320, 224);
|
||||||
|
|
||||||
host.add_window(FrameSwapper::to_boxed(swapper.clone())).unwrap();
|
host.add_window(FrameSwapper::to_boxed(swapper.clone())).unwrap();
|
||||||
|
|
||||||
@ -607,12 +607,12 @@ impl Steppable for Ym7101 {
|
|||||||
system.get_interrupt_controller().set(true, 6, 30)?;
|
system.get_interrupt_controller().set(true, 6, 30)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut swapper = self.swapper.lock().unwrap();
|
let mut frame = self.swapper.current.lock().unwrap();
|
||||||
self.state.draw_frame(&mut swapper.current);
|
self.state.draw_frame(&mut frame);
|
||||||
|
|
||||||
//let mut swapper = self.swapper.lock().unwrap();
|
//let mut frame = self.swapper.current.lock().unwrap();
|
||||||
//let iter = PatternIterator::new(&self.state, 0x260, 0, true, true);
|
//let iter = PatternIterator::new(&self.state, 0x260, 0, true, true);
|
||||||
//swapper.current.blit(0, 0, iter, 8, 8);
|
//frame.blit(0, 0, iter, 8, 8);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Print Palette
|
// Print Palette
|
||||||
@ -623,13 +623,13 @@ impl Steppable for Ym7101 {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
// Print Pattern Table
|
// Print Pattern Table
|
||||||
let mut swapper = self.swapper.lock().unwrap();
|
let mut frame = self.swapper.current.lock().unwrap();
|
||||||
let (cells_h, cells_v) = self.state.get_screen_size();
|
let (cells_h, cells_v) = self.state.get_screen_size();
|
||||||
for cell_y in 0..cells_v {
|
for cell_y in 0..cells_v {
|
||||||
for cell_x in 0..cells_h {
|
for cell_x in 0..cells_h {
|
||||||
let pattern_addr = (cell_x + (cell_y * cells_h)) * 32;
|
let pattern_addr = (cell_x + (cell_y * cells_h)) * 32;
|
||||||
let iter = PatternIterator::new(&self.state, pattern_addr as u32, 0, false, false);
|
let iter = PatternIterator::new(&self.state, pattern_addr as u32, 0, false, false);
|
||||||
swapper.current.blit((cell_x << 3) as u32, (cell_y << 3) as u32, iter, 8, 8);
|
frame.blit((cell_x << 3) as u32, (cell_y << 3) as u32, iter, 8, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -637,8 +637,8 @@ impl Steppable for Ym7101 {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
// Print Sprite
|
// Print Sprite
|
||||||
let mut swapper = self.swapper.lock().unwrap();
|
let mut frame = self.swapper.current.lock().unwrap();
|
||||||
self.state.draw_background(&mut swapper.current);
|
self.state.draw_background(&mut frame);
|
||||||
let sprite_table = self.get_vram_sprites_addr();
|
let sprite_table = self.get_vram_sprites_addr();
|
||||||
let (cells_h, cells_v) = self.state.get_screen_size();
|
let (cells_h, cells_v) = self.state.get_screen_size();
|
||||||
let sprite = 0;
|
let sprite = 0;
|
||||||
@ -654,18 +654,18 @@ impl Steppable for Ym7101 {
|
|||||||
let pattern_addr = (pattern_gen + (cell_y * size_h) + cell_x) as u32;
|
let pattern_addr = (pattern_gen + (cell_y * size_h) + cell_x) as u32;
|
||||||
println!("pattern: ({}, {}) {:x}", cell_x, cell_y, pattern_addr);
|
println!("pattern: ({}, {}) {:x}", cell_x, cell_y, pattern_addr);
|
||||||
let iter = PatternIterator::new(&self.state, pattern_addr * 32, 3, true, true);
|
let iter = PatternIterator::new(&self.state, pattern_addr * 32, 3, true, true);
|
||||||
swapper.current.blit((cell_x << 3) as u32, (cell_y << 3) as u32, iter, 8, 8);
|
frame.blit((cell_x << 3) as u32, (cell_y << 3) as u32, iter, 8, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//let mut swapper = self.swapper.lock().unwrap();
|
//let mut frame = self.swapper.current.lock().unwrap();
|
||||||
//swapper.current.blit(0, 0, PatternIterator::new(&self.state, 0x408 * 32, 3, false, false), 8, 8);
|
//frame.blit(0, 0, PatternIterator::new(&self.state, 0x408 * 32, 3, false, false), 8, 8);
|
||||||
//swapper.current.blit(0, 8, PatternIterator::new(&self.state, 0x409 * 32, 3, false, false), 8, 8);
|
//frame.blit(0, 8, PatternIterator::new(&self.state, 0x409 * 32, 3, false, false), 8, 8);
|
||||||
//swapper.current.blit(8, 0, PatternIterator::new(&self.state, 0x402 * 32, 3, false, false), 8, 8);
|
//frame.blit(8, 0, PatternIterator::new(&self.state, 0x402 * 32, 3, false, false), 8, 8);
|
||||||
//swapper.current.blit(8, 8, PatternIterator::new(&self.state, 0x403 * 32, 3, false, false), 8, 8);
|
//frame.blit(8, 8, PatternIterator::new(&self.state, 0x403 * 32, 3, false, false), 8, 8);
|
||||||
//swapper.current.blit(16, 0, PatternIterator::new(&self.state, 0x404 * 32, 3, false, false), 8, 8);
|
//frame.blit(16, 0, PatternIterator::new(&self.state, 0x404 * 32, 3, false, false), 8, 8);
|
||||||
//swapper.current.blit(16, 8, PatternIterator::new(&self.state, 0x405 * 32, 3, false, false), 8, 8);
|
//frame.blit(16, 8, PatternIterator::new(&self.state, 0x405 * 32, 3, false, false), 8, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.state.transfer_run != DmaType::None && (self.state.mode_2 & MODE2_BF_DMA_ENABLED) != 0 {
|
if self.state.transfer_run != DmaType::None && (self.state.mode_2 & MODE2_BF_DMA_ENABLED) != 0 {
|
||||||
|
@ -5,24 +5,24 @@ use crate::error::Error;
|
|||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable};
|
use crate::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable};
|
||||||
|
|
||||||
use crate::host::gfx::FrameSwapper;
|
use crate::host::gfx::Frame;
|
||||||
use crate::host::traits::{Host, BlitableSurface};
|
use crate::host::traits::{Host, BlitableSurface};
|
||||||
|
|
||||||
|
|
||||||
const SCRN_BASE: u32 = 0x07A700;
|
const SCRN_BASE: u32 = 0x07A700;
|
||||||
|
|
||||||
pub struct MacVideo {
|
pub struct MacVideo {
|
||||||
pub swapper: Arc<Mutex<FrameSwapper>>,
|
pub frame: Arc<Mutex<Frame>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MacVideo {
|
impl MacVideo {
|
||||||
pub fn create<H: Host>(host: &mut H) -> Result<Self, Error> {
|
pub fn create<H: Host>(host: &mut H) -> Result<Self, Error> {
|
||||||
let swapper = FrameSwapper::new_shared(512, 342);
|
let frame = Frame::new_shared(512, 342);
|
||||||
|
|
||||||
host.add_window(FrameSwapper::to_boxed(swapper.clone()))?;
|
host.add_window(Frame::new_updater(frame.clone()))?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
swapper,
|
frame,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,11 +63,11 @@ impl Iterator for BitIter {
|
|||||||
impl Steppable for MacVideo {
|
impl Steppable for MacVideo {
|
||||||
fn step(&mut self, system: &System) -> Result<ClockElapsed, Error> {
|
fn step(&mut self, system: &System) -> Result<ClockElapsed, Error> {
|
||||||
let mut memory = system.get_bus();
|
let mut memory = system.get_bus();
|
||||||
let mut swapper = self.swapper.lock().unwrap();
|
let mut frame = self.frame.lock().unwrap();
|
||||||
for y in 0..342 {
|
for y in 0..342 {
|
||||||
for x in 0..(512 / 16) {
|
for x in 0..(512 / 16) {
|
||||||
let word = memory.read_beu16((SCRN_BASE + (x * 2) + (y * (512 / 8))) as Address)?;
|
let word = memory.read_beu16((SCRN_BASE + (x * 2) + (y * (512 / 8))) as Address)?;
|
||||||
swapper.current.blit(x * 16, y, BitIter::new(word), 16, 1);
|
frame.blit(x * 16, y, BitIter::new(word), 16, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(16_600_000)
|
Ok(16_600_000)
|
||||||
|
@ -6,7 +6,7 @@ use crate::system::System;
|
|||||||
use crate::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable};
|
use crate::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable};
|
||||||
|
|
||||||
use crate::host::keys::Key;
|
use crate::host::keys::Key;
|
||||||
use crate::host::gfx::{FrameSwapper};
|
use crate::host::gfx::{Frame};
|
||||||
use crate::host::traits::{Host, BlitableSurface, KeyboardUpdater};
|
use crate::host::traits::{Host, BlitableSurface, KeyboardUpdater};
|
||||||
|
|
||||||
use super::keymap;
|
use super::keymap;
|
||||||
@ -16,21 +16,21 @@ use super::charset::CharacterGenerator;
|
|||||||
const DEV_NAME: &'static str = "model1";
|
const DEV_NAME: &'static str = "model1";
|
||||||
|
|
||||||
pub struct Model1Peripherals {
|
pub struct Model1Peripherals {
|
||||||
pub swapper: Arc<Mutex<FrameSwapper>>,
|
pub frame: Arc<Mutex<Frame>>,
|
||||||
pub keyboard_mem: Arc<Mutex<[u8; 8]>>,
|
pub keyboard_mem: Arc<Mutex<[u8; 8]>>,
|
||||||
pub video_mem: [u8; 1024],
|
pub video_mem: [u8; 1024],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Model1Peripherals {
|
impl Model1Peripherals {
|
||||||
pub fn create<H: Host>(host: &mut H) -> Result<Self, Error> {
|
pub fn create<H: Host>(host: &mut H) -> Result<Self, Error> {
|
||||||
let swapper = FrameSwapper::new_shared(384, 128);
|
let frame = Frame::new_shared(384, 128);
|
||||||
let keyboard_mem = Arc::new(Mutex::new([0; 8]));
|
let keyboard_mem = Arc::new(Mutex::new([0; 8]));
|
||||||
|
|
||||||
host.add_window(FrameSwapper::to_boxed(swapper.clone()))?;
|
host.add_window(Frame::new_updater(frame.clone()))?;
|
||||||
host.register_keyboard(Box::new(Model1KeyboardUpdater(keyboard_mem.clone())))?;
|
host.register_keyboard(Box::new(Model1KeyboardUpdater(keyboard_mem.clone())))?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
swapper,
|
frame,
|
||||||
keyboard_mem,
|
keyboard_mem,
|
||||||
video_mem: [0; 1024],
|
video_mem: [0; 1024],
|
||||||
})
|
})
|
||||||
@ -48,13 +48,13 @@ impl KeyboardUpdater for Model1KeyboardUpdater {
|
|||||||
|
|
||||||
impl Steppable for Model1Peripherals {
|
impl Steppable for Model1Peripherals {
|
||||||
fn step(&mut self, _system: &System) -> Result<ClockElapsed, Error> {
|
fn step(&mut self, _system: &System) -> Result<ClockElapsed, Error> {
|
||||||
let mut swapper = self.swapper.lock().unwrap();
|
let mut frame = self.frame.lock().unwrap();
|
||||||
swapper.current.clear(0);
|
frame.clear(0);
|
||||||
for y in 0..16 {
|
for y in 0..16 {
|
||||||
for x in 0..64 {
|
for x in 0..64 {
|
||||||
let ch = self.video_mem[x + (y * 64)];
|
let ch = self.video_mem[x + (y * 64)];
|
||||||
let iter = CharacterGenerator::new((ch - 0x20) % 64);
|
let iter = CharacterGenerator::new((ch - 0x20) % 64);
|
||||||
swapper.current.blit((x * 6) as u32, (y * 8) as u32, iter, 6, 8);
|
frame.blit((x * 6) as u32, (y * 8) as u32, iter, 6, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
70
todo.txt
70
todo.txt
@ -1,48 +1,66 @@
|
|||||||
|
|
||||||
|
* I'm trying to explore the alternative of having the frontend call a function and pass a closure that takes a frame (or buffer) and then draws
|
||||||
|
calls the update function from there...
|
||||||
|
* you can't put a closure into the WindowUpdate trait because you pass it in as Box<dyn WindowUpdater> which is a trait object, and you
|
||||||
|
can't mix generics and trait objects...
|
||||||
|
* you could maybe pass a closure in if you pass the updater as a generic WindowUpdater, although then you can only have one per application
|
||||||
|
* you could have a shared buffer that you submit to the frontend, and you both update it whenever (less synchronized which might not be good)
|
||||||
|
* you could make the sound device be an object that is passed back to the simulation section like SimplePty. You need to either register
|
||||||
|
a callback with the frontend sound system that is called when it needs data, or you write to a shared buffer which is passed back to the
|
||||||
|
frontend when it needs it, or it has a copy it can use directly
|
||||||
|
|
||||||
|
* can you make some kind of signal that goes high when a frame has been drawn, and also all the system to pause execution at that point
|
||||||
|
|
||||||
|
* for Signal/Register, you could possibly unify them, or you could distinguish them even more
|
||||||
|
* should you rename Register to AsyncSignal or something
|
||||||
|
* copy the callback over to Signal, or even make a trait that implements it for both? Or should you make a special object that is observable
|
||||||
|
which should always use the callback, and Signal would always be used when the callback wasn't used
|
||||||
|
* think more about what kinds of signals are used:
|
||||||
|
- one setter with multiple passive listeners
|
||||||
|
- one one-shot setter (no reset) with one active listener that resets the signal
|
||||||
|
-
|
||||||
|
|
||||||
|
* add sound
|
||||||
* should you rename devices.rs traits.rs?
|
* should you rename devices.rs traits.rs?
|
||||||
* should SharedData be HostData, or something else? I don't think the name is very informative
|
|
||||||
* rewrite the frame swapper thing to either not use the swapper or somethnig... it's just very sloppy and needs improving
|
* rewrite the frame swapper thing to either not use the swapper or somethnig... it's just very sloppy and needs improving
|
||||||
|
* modify the frame swapper and frontend to avoid the extra buffer copy
|
||||||
|
* add command line arguments to speed up or slow down either the frame rate limiter or the simulated time per frame
|
||||||
|
|
||||||
* can you make the connections between things (like memory adapters), be expressed in a way that's more similar to the electrical design?
|
* can you make the connections between things (like memory adapters), be expressed in a way that's more similar to the electrical design?
|
||||||
like specifying that address pins 10-7 should be ignored/unconnected, pin 11 will connect to "chip select", etc
|
like specifying that address pins 10-7 should be ignored/unconnected, pin 11 will connect to "chip select", etc
|
||||||
* can you make the address bus/repeating thing in the mac with the rom and ram, can you make it work for both the 128 and 512
|
|
||||||
|
|
||||||
* add sound
|
|
||||||
* should you simulate bus arbitration?
|
* should you simulate bus arbitration?
|
||||||
* interrupts could be done in a better way
|
* interrupts could be done in a better way
|
||||||
|
* need a better way of handling disparate reads/writes to I/O spaces, rather than having multiple devices or having a massive chunk of address space allocated, continuously
|
||||||
|
|
||||||
* modify the frame swapper and frontend to avoid the extra buffer copy
|
|
||||||
* add command line arguments to speed up or slow down either the frame rate limiter or the simulated time per frame
|
|
||||||
* need to implement the 1.5ms reset in the genesis controllers
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* how can you do devices that change their address map during operation, like mac which puts rom at 0 and ram at 600000 temporarily
|
|
||||||
* i need a better way of handling disperate reads/writes to I/O spaces, rather than having multiple devices or having a massive chunk of address space allocated, continuously
|
|
||||||
* should you modify Addressable to also take the absolute address as input? I'm thinking of how the same device could be mapped to multiple addresses in memory instead
|
* should you modify Addressable to also take the absolute address as input? I'm thinking of how the same device could be mapped to multiple addresses in memory instead
|
||||||
of taking up a whole range of addresses
|
of taking up a whole range of addresses
|
||||||
* could have a remapper device, which takes a big swath of addresses in and maps them to another set of addresses (for Mac VIA generic to bus-hookup-in-mac adapter)
|
|
||||||
* could you use a generic sharable signal thing for sharing data, such as the VIA in mac128 where a single output bit determines the video mode (which would be a separate device)
|
|
||||||
So both could share the same Signal, one setting it and the other reading it, but how would you actually configure/build that?
|
|
||||||
|
|
||||||
|
|
||||||
* add more m68k tests and try to test against a working impl
|
|
||||||
* you could modify read()/write() in Addressable to return the number of bytes read or written for dynamic bus sizing used by the MC68020+
|
* you could modify read()/write() in Addressable to return the number of bytes read or written for dynamic bus sizing used by the MC68020+
|
||||||
|
|
||||||
|
|
||||||
|
Debugger:
|
||||||
|
|
||||||
|
* how can you improve the debugger?
|
||||||
|
* the command line definitely needs to be fixed so it prints the prompt correctly
|
||||||
|
* debugger could maybe even allows arrows left/right for editing, and up/down for history
|
||||||
|
|
||||||
|
|
||||||
Genesis/Mega Drive:
|
Genesis/Mega Drive:
|
||||||
|
|
||||||
|
* need to implement the 1.5ms reset in the genesis controllers
|
||||||
* fix ym7101 to better handle V/H interrupts (right now it sets and then the next step will clear, but it'd be nice if it could 'edge trigger')
|
* fix ym7101 to better handle V/H interrupts (right now it sets and then the next step will clear, but it'd be nice if it could 'edge trigger')
|
||||||
* YM7101 timing is causing it to be very slow... speeding this up increasing rendering speed a lot, even though the frame shouldn't be drawn that often... not sure what's wrong with the timing
|
|
||||||
* make the ym7101 set/reset the v_int occurred flag based on the interrupt controller
|
* make the ym7101 set/reset the v_int occurred flag based on the interrupt controller
|
||||||
|
|
||||||
|
|
||||||
|
Macintosh:
|
||||||
|
|
||||||
|
* issues when booting the rom, attempt to write to rom during the driver init/open phase
|
||||||
|
* for the address bus/repeating thing in the mac with the rom and ram, can you make it work for both the 128 and 512
|
||||||
|
|
||||||
|
|
||||||
68000:
|
68000:
|
||||||
|
|
||||||
* add instruction timing to M68k
|
* add instruction timing to M68k
|
||||||
* make tests for each instruction
|
|
||||||
* check all instructions in the docs
|
* check all instructions in the docs
|
||||||
|
|
||||||
* unimplemented: BFFFO, BFINS, CHK, ILLEGAL, NBCD, NEGX, RTR, RTD
|
* unimplemented: BFFFO, BFINS, CHK, ILLEGAL, NBCD, NEGX, RTR, RTD
|
||||||
@ -52,13 +70,15 @@ Genesis/Mega Drive:
|
|||||||
* add support for FPU
|
* add support for FPU
|
||||||
* Coprocessor instructions: cpBcc, cpDBcc, cpGEN, cpScc, cpTRAPcc
|
* Coprocessor instructions: cpBcc, cpDBcc, cpGEN, cpScc, cpTRAPcc
|
||||||
|
|
||||||
|
* add more m68k tests and try to test against a working impl (m68k-test-suite project)
|
||||||
|
|
||||||
|
|
||||||
Z80:
|
Z80:
|
||||||
* add instruction timings to Z80
|
* add instruction timings to Z80
|
||||||
|
* unimplemented: CPD, CPDR, CPI, CPIR, DAA, IND, INDR, INI, INIR, INic, INx, OTDR, OTIR, OUTD, OUTI, OUTic, OUTx, RETI, RETN, RLD, RRD
|
||||||
|
|
||||||
|
|
||||||
* work on mac128/512
|
* work on mac128/512
|
||||||
* work on sega genesis
|
* work on sega genesis
|
||||||
|
|
||||||
* how can you have multiple CPUs
|
|
||||||
* can you eventually make the system connections all configurable via a config file?
|
* can you eventually make the system connections all configurable via a config file?
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user