From da980b8ae8689d7240c653fdfdc07aa9330c25fa Mon Sep 17 00:00:00 2001 From: transistor Date: Thu, 29 Sep 2022 20:21:00 -0700 Subject: [PATCH] Fixed regression when fixing interrupt handling in 68k Mortal Kombat 2 was working but somewhere while getting the harte tests to work, I fixed interrupts to change the flags before they're pushed to the stack, in order to match the expected behaviour from the tests when an address error occurs (sr is changed and the stack push causes the error). I correctly saved the state of sr in the function for group0 interrupts, to push to the stack later, but the normal interrupts was saving sr *after* the flags were changed... Now it saves sr beforehand I also included some changes to the gfx interface to allow taking frames, to fix a compile error introduced by the last commit. --- emulator/core/src/host/gfx.rs | 16 ++++++++++++++++ emulator/cpus/m68k/src/execute.rs | 2 +- todo.txt | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/emulator/core/src/host/gfx.rs b/emulator/core/src/host/gfx.rs index 97e09b8..aeb3ede 100644 --- a/emulator/core/src/host/gfx.rs +++ b/emulator/core/src/host/gfx.rs @@ -1,6 +1,8 @@ +use std::mem; use std::sync::{Arc, Mutex}; +use crate::Error; use crate::host::traits::{WindowUpdater, BlitableSurface}; @@ -75,6 +77,13 @@ impl WindowUpdater for FrameUpdateWrapper { } } + fn get_frame(&mut self) -> Result { + let mut current = self.0.lock().map_err(|_| Error::new("Lock error"))?; + let mut frame = Frame::new(current.width, current.height); + mem::swap(&mut *current, &mut frame); + Ok(frame) + } + fn update_frame(&mut self, width: u32, _height: u32, bitmap: &mut [u32]) { if let Ok(frame) = self.0.lock() { for y in 0..frame.height { @@ -124,6 +133,13 @@ impl WindowUpdater for FrameSwapper { } } + fn get_frame(&mut self) -> Result { + let mut previous = self.previous.lock().map_err(|_| Error::new("Lock error"))?; + let mut frame = Frame::new(previous.width, previous.height); + mem::swap(&mut *previous, &mut frame); + Ok(frame) + } + fn update_frame(&mut self, width: u32, _height: u32, bitmap: &mut [u32]) { if let Ok(frame) = self.previous.lock() { for y in 0..frame.height { diff --git a/emulator/cpus/m68k/src/execute.rs b/emulator/cpus/m68k/src/execute.rs index 4693af5..e615eeb 100644 --- a/emulator/cpus/m68k/src/execute.rs +++ b/emulator/cpus/m68k/src/execute.rs @@ -176,6 +176,7 @@ impl M68k { } pub fn setup_normal_exception(&mut self, number: u8, is_interrupt: bool) -> Result<(), Error> { + let sr = self.state.sr; self.state.request.i_n_bit = true; // Changes to the flags must happen after the previous value has been pushed to the stack @@ -185,7 +186,6 @@ impl M68k { self.state.sr = (self.state.sr & !(Flags::IntMask as u16)) | ((self.state.current_ipl as u16) << 8); } - let sr = self.state.sr; let offset = (number as u16) << 2; if self.cputype >= M68kType::MC68010 { self.push_word(offset)?; diff --git a/todo.txt b/todo.txt index c1bf7b4..6f5fc8c 100644 --- a/todo.txt +++ b/todo.txt @@ -1,10 +1,28 @@ +Web Assembly: +* the frame rate is pretty bad. It's definitely faster with a smaller window +* can you limit the size of the window that pixels generates? +* can you automatically adjust the speed based on the calculated framerate (if you moved that to Rust) +* can you limit the frame rate in pixels so that you if it were to run too fast, it would limit it to 60Hz +* the system run is taking 40 to 50ms per frame in web assembly. Can you cut that by 4 times? + +* add sound to web assembly +* add run/stop and ability to change speed through the web interface +* can you make the web interface nicer with like... a picture of a genesis or something + + +* EarthwormJim, Mortal Kombat 2, and a few others, that were working are now not working, possibly due to the tests (it fixed some things and broke others) + It's possible that some of the errors are coming from the Z80 and coprocessor interactions. Try running tests agains Z80 +* fix audio, and/or make it possible to disable audio processing/simulation for one or both sound chips (might be nice to have sn76489 but not ym2612) + + Harte Tests: * for every failing test in MOVEfromSR, it's caused by an exception where at 0x7F3 it should be 0xF5, it's actually 0xE5, which is the READ/WRITE flag not set correctly (1 = READ) * you could refactor the instruction loop into a series of functions, and test if there's a performance difference with and without #[inline(always)] * use the log crate instead of your own +* move parser into its own * make it possible to compile without audio support (minifb frontend requires it atm)