mirror of
https://github.com/transistorfet/moa.git
synced 2025-02-08 04:30:44 +00:00
Refactored shift intsructions to not use direction
This commit is contained in:
parent
64b18662d5
commit
d87319b605
13
docs/log.txt
13
docs/log.txt
@ -428,3 +428,16 @@ General Work
|
||||
doesn't make a heck of a lot of sense to be changing the volume level but nothing else all the
|
||||
time. It doesn't seem to set the initial frequencies. So it's possible that a bug in the Z80
|
||||
code is making it run incorrectly and thus not producing correct register commands to the ym2612
|
||||
|
||||
2023-05-16
|
||||
- I spent a bunch of time getting the Z80 tests running and fixing bugs in the implementation. It's
|
||||
generally gone well. I started with 45% of the tests passing with all checks, 60% with the
|
||||
undocumented flags ignored, 83% with undocumented instructions also ignored, and timing wasn't
|
||||
even checked. It's now 98% passing with undocumented instructions and timing checks, but is still
|
||||
only 65% passing on all tests
|
||||
- Now that I added timings to the Z80, and fixed instructions, Sonic 1 has the drums in the intro,
|
||||
but there's still no bass, and it still sounds incorrect in spots. But most other games still
|
||||
have no sound which is baffling
|
||||
- it must be a problem with either the bus architecture in the genesis, or a probably with the
|
||||
CPU/coproc interface, banking, etc
|
||||
|
||||
|
@ -6,7 +6,6 @@ use super::instructions::{
|
||||
Size,
|
||||
Sign,
|
||||
Direction,
|
||||
ShiftDirection,
|
||||
XRegister,
|
||||
BaseRegister,
|
||||
IndexRegister,
|
||||
@ -583,10 +582,9 @@ impl M68kDecoder {
|
||||
}
|
||||
|
||||
fn decode_group_shift(&mut self, memory: &mut dyn Addressable, ins: u16) -> Result<Instruction, Error> {
|
||||
let dir = if (ins & 0x0100) == 0 { ShiftDirection::Right } else { ShiftDirection::Left };
|
||||
match get_size(ins) {
|
||||
Some(size) => {
|
||||
let reg = get_low_reg(ins);
|
||||
let target = Target::DirectDReg(get_low_reg(ins));
|
||||
let rotation = get_high_reg(ins);
|
||||
let count = if (ins & 0x0020) == 0 {
|
||||
Target::Immediate(if rotation != 0 { rotation as u32 } else { 8 })
|
||||
@ -594,24 +592,46 @@ impl M68kDecoder {
|
||||
Target::DirectDReg(rotation)
|
||||
};
|
||||
|
||||
match (ins & 0x0018) >> 3 {
|
||||
0b00 => Ok(Instruction::ASd(count, Target::DirectDReg(reg), size, dir)),
|
||||
0b01 => Ok(Instruction::LSd(count, Target::DirectDReg(reg), size, dir)),
|
||||
0b10 => Ok(Instruction::ROXd(count, Target::DirectDReg(reg), size, dir)),
|
||||
0b11 => Ok(Instruction::ROd(count, Target::DirectDReg(reg), size, dir)),
|
||||
_ => Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
||||
if (ins & 0x0100) == 0 {
|
||||
match (ins & 0x0018) >> 3 {
|
||||
0b00 => Ok(Instruction::ASR(count, target, size)),
|
||||
0b01 => Ok(Instruction::LSR(count, target, size)),
|
||||
0b10 => Ok(Instruction::ROXR(count, target, size)),
|
||||
0b11 => Ok(Instruction::ROR(count, target, size)),
|
||||
_ => Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
||||
}
|
||||
} else {
|
||||
match (ins & 0x0018) >> 3 {
|
||||
0b00 => Ok(Instruction::ASL(count, target, size)),
|
||||
0b01 => Ok(Instruction::LSL(count, target, size)),
|
||||
0b10 => Ok(Instruction::ROXL(count, target, size)),
|
||||
0b11 => Ok(Instruction::ROL(count, target, size)),
|
||||
_ => Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
if (ins & 0x800) == 0 {
|
||||
let target = self.decode_lower_effective_address(memory, ins, Some(Size::Word))?;
|
||||
let count = Target::Immediate(1);
|
||||
match (ins & 0x0600) >> 9 {
|
||||
0b00 => Ok(Instruction::ASd(count, target, Size::Word, dir)),
|
||||
0b01 => Ok(Instruction::LSd(count, target, Size::Word, dir)),
|
||||
0b10 => Ok(Instruction::ROXd(count, target, Size::Word, dir)),
|
||||
0b11 => Ok(Instruction::ROd(count, target, Size::Word, dir)),
|
||||
_ => Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
||||
let size = Size::Word;
|
||||
|
||||
if (ins & 0x0100) == 0 {
|
||||
match (ins & 0x0600) >> 9 {
|
||||
0b00 => Ok(Instruction::ASR(count, target, size)),
|
||||
0b01 => Ok(Instruction::LSR(count, target, size)),
|
||||
0b10 => Ok(Instruction::ROXR(count, target, size)),
|
||||
0b11 => Ok(Instruction::ROR(count, target, size)),
|
||||
_ => Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
||||
}
|
||||
} else {
|
||||
match (ins & 0x0600) >> 9 {
|
||||
0b00 => Ok(Instruction::ASL(count, target, size)),
|
||||
0b01 => Ok(Instruction::LSL(count, target, size)),
|
||||
0b10 => Ok(Instruction::ROXL(count, target, size)),
|
||||
0b11 => Ok(Instruction::ROL(count, target, size)),
|
||||
_ => Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
||||
}
|
||||
}
|
||||
} else if self.cputype > M68kType::MC68020 {
|
||||
// Bitfield instructions (MC68020+)
|
||||
|
@ -8,7 +8,6 @@ use crate::instructions::{
|
||||
Size,
|
||||
Sign,
|
||||
Direction,
|
||||
ShiftDirection,
|
||||
XRegister,
|
||||
BaseRegister,
|
||||
IndexRegister,
|
||||
@ -222,7 +221,8 @@ impl M68k {
|
||||
Instruction::AND(src, dest, size) => self.execute_and(src, dest, size),
|
||||
Instruction::ANDtoCCR(value) => self.execute_and_to_ccr(value),
|
||||
Instruction::ANDtoSR(value) => self.execute_and_to_sr(value),
|
||||
Instruction::ASd(count, target, size, shift_dir) => self.execute_asd(count, target, size, shift_dir),
|
||||
Instruction::ASL(count, target, size) => self.execute_asl(count, target, size),
|
||||
Instruction::ASR(count, target, size) => self.execute_asr(count, target, size),
|
||||
Instruction::Bcc(cond, offset) => self.execute_bcc(cond, offset),
|
||||
Instruction::BRA(offset) => self.execute_bra(offset),
|
||||
Instruction::BSR(offset) => self.execute_bsr(offset),
|
||||
@ -256,7 +256,8 @@ impl M68k {
|
||||
Instruction::JSR(target) => self.execute_jsr(target),
|
||||
Instruction::LEA(target, reg) => self.execute_lea(target, reg),
|
||||
Instruction::LINK(reg, offset) => self.execute_link(reg, offset),
|
||||
Instruction::LSd(count, target, size, shift_dir) => self.execute_lsd(count, target, size, shift_dir),
|
||||
Instruction::LSL(count, target, size) => self.execute_lsl(count, target, size),
|
||||
Instruction::LSR(count, target, size) => self.execute_lsr(count, target, size),
|
||||
Instruction::MOVE(src, dest, size) => self.execute_move(src, dest, size),
|
||||
Instruction::MOVEA(src, reg, size) => self.execute_movea(src, reg, size),
|
||||
Instruction::MOVEfromSR(target) => self.execute_move_from_sr(target),
|
||||
@ -279,8 +280,10 @@ impl M68k {
|
||||
Instruction::ORtoSR(value) => self.execute_or_to_sr(value),
|
||||
Instruction::PEA(target) => self.execute_pea(target),
|
||||
Instruction::RESET => self.execute_reset(),
|
||||
Instruction::ROd(count, target, size, shift_dir) => self.execute_rod(count, target, size, shift_dir),
|
||||
Instruction::ROXd(count, target, size, shift_dir) => self.execute_roxd(count, target, size, shift_dir),
|
||||
Instruction::ROL(count, target, size) => self.execute_rol(count, target, size),
|
||||
Instruction::ROR(count, target, size) => self.execute_rol(count, target, size),
|
||||
Instruction::ROXL(count, target, size) => self.execute_roxl(count, target, size),
|
||||
Instruction::ROXR(count, target, size) => self.execute_roxr(count, target, size),
|
||||
Instruction::RTE => self.execute_rte(),
|
||||
Instruction::RTR => self.execute_rtr(),
|
||||
Instruction::RTS => self.execute_rts(),
|
||||
@ -389,7 +392,7 @@ impl M68k {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_asd(&mut self, count: Target, target: Target, size: Size, shift_dir: ShiftDirection) -> Result<(), Error> {
|
||||
fn execute_asl(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||
let count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||
let value = self.get_target_value(target, size, Used::Twice)?;
|
||||
|
||||
@ -397,7 +400,7 @@ impl M68k {
|
||||
let mut pair = (value, false);
|
||||
let mut previous_msb = get_msb(pair.0, size);
|
||||
for _ in 0..count {
|
||||
pair = shift_operation(pair.0, size, shift_dir, true);
|
||||
pair = shift_left(pair.0, size, true);
|
||||
if get_msb(pair.0, size) != previous_msb {
|
||||
overflow = true;
|
||||
}
|
||||
@ -405,21 +408,40 @@ impl M68k {
|
||||
}
|
||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||
|
||||
let carry = match shift_dir {
|
||||
ShiftDirection::Left => pair.1,
|
||||
ShiftDirection::Right => if count < size.in_bits() { pair.1 } else { false }
|
||||
};
|
||||
self.set_arithmetic_shift_flags(pair.0, count, pair.1, overflow, size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Adjust flags
|
||||
self.set_logic_flags(pair.0, size);
|
||||
fn execute_asr(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||
let count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||
let value = self.get_target_value(target, size, Used::Twice)?;
|
||||
|
||||
let mut overflow = false;
|
||||
let mut pair = (value, false);
|
||||
let mut previous_msb = get_msb(pair.0, size);
|
||||
for _ in 0..count {
|
||||
pair = shift_right(pair.0, size, true);
|
||||
if get_msb(pair.0, size) != previous_msb {
|
||||
overflow = true;
|
||||
}
|
||||
previous_msb = get_msb(pair.0, size);
|
||||
}
|
||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||
|
||||
let last_bit = if count < size.in_bits() { pair.1 } else { false };
|
||||
self.set_arithmetic_shift_flags(pair.0, count, last_bit, overflow, size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_arithmetic_shift_flags(&mut self, result: u32, count: u32, last_bit_out: bool, overflow: bool, size: Size) {
|
||||
self.set_logic_flags(result, size);
|
||||
self.set_flag(Flags::Overflow, overflow);
|
||||
if count != 0 {
|
||||
self.set_flag(Flags::Extend, carry);
|
||||
self.set_flag(Flags::Carry, carry);
|
||||
self.set_flag(Flags::Extend, last_bit_out);
|
||||
self.set_flag(Flags::Carry, last_bit_out);
|
||||
} else {
|
||||
self.set_flag(Flags::Carry, false);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_bcc(&mut self, cond: Condition, offset: i32) -> Result<(), Error> {
|
||||
@ -772,24 +794,39 @@ impl M68k {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_lsd(&mut self, count: Target, target: Target, size: Size, shift_dir: ShiftDirection) -> Result<(), Error> {
|
||||
fn execute_lsl(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||
let count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
||||
for _ in 0..count {
|
||||
pair = shift_operation(pair.0, size, shift_dir, false);
|
||||
pair = shift_left(pair.0, size, false);
|
||||
}
|
||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||
|
||||
// Adjust flags
|
||||
self.set_logic_flags(pair.0, size);
|
||||
self.set_shift_flags(pair.0, count, pair.1, size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_lsr(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||
let count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
||||
for _ in 0..count {
|
||||
pair = shift_right(pair.0, size, false);
|
||||
}
|
||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||
|
||||
self.set_shift_flags(pair.0, count, pair.1, size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_shift_flags(&mut self, result: u32, count: u32, last_bit_out: bool, size: Size) {
|
||||
self.set_logic_flags(result, size);
|
||||
self.set_flag(Flags::Overflow, false);
|
||||
if count != 0 {
|
||||
self.set_flag(Flags::Extend, pair.1);
|
||||
self.set_flag(Flags::Carry, pair.1);
|
||||
self.set_flag(Flags::Extend, last_bit_out);
|
||||
self.set_flag(Flags::Carry, last_bit_out);
|
||||
} else {
|
||||
self.set_flag(Flags::Carry, false);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_move(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
|
||||
@ -1094,37 +1131,57 @@ impl M68k {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_rod(&mut self, count: Target, target: Target, size: Size, shift_dir: ShiftDirection) -> Result<(), Error> {
|
||||
fn execute_rol(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||
let count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
||||
for _ in 0..count {
|
||||
pair = rotate_operation(pair.0, size, shift_dir, None);
|
||||
pair = rotate_left(pair.0, size, None);
|
||||
}
|
||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||
|
||||
// Adjust flags
|
||||
self.set_logic_flags(pair.0, size);
|
||||
if pair.1 {
|
||||
self.set_flag(Flags::Carry, true);
|
||||
}
|
||||
self.set_rotate_flags(pair.0, pair.1, size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_roxd(&mut self, count: Target, target: Target, size: Size, shift_dir: ShiftDirection) -> Result<(), Error> {
|
||||
fn execute_ror(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||
let count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
||||
for _ in 0..count {
|
||||
pair = rotate_operation(pair.0, size, shift_dir, Some(self.get_flag(Flags::Extend)));
|
||||
pair = rotate_right(pair.0, size, None);
|
||||
}
|
||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||
self.set_rotate_flags(pair.0, pair.1, size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_roxl(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||
let count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
||||
for _ in 0..count {
|
||||
pair = rotate_left(pair.0, size, Some(self.get_flag(Flags::Extend)));
|
||||
self.set_flag(Flags::Extend, pair.1);
|
||||
}
|
||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||
self.set_rotate_flags(pair.0, pair.1, size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Adjust flags
|
||||
self.set_logic_flags(pair.0, size);
|
||||
if pair.1 {
|
||||
fn execute_roxr(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||
let count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
||||
for _ in 0..count {
|
||||
pair = rotate_right(pair.0, size, Some(self.get_flag(Flags::Extend)));
|
||||
self.set_flag(Flags::Extend, pair.1);
|
||||
}
|
||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||
self.set_rotate_flags(pair.0, pair.1, size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_rotate_flags(&mut self, result: u32, last_bit_out: bool, size: Size) {
|
||||
self.set_logic_flags(result, size);
|
||||
if last_bit_out {
|
||||
self.set_flag(Flags::Carry, true);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_rte(&mut self) -> Result<(), Error> {
|
||||
@ -1747,42 +1804,36 @@ fn overflowing_sub_signed_sized(operand1: u32, operand2: u32, size: Size) -> (u3
|
||||
}
|
||||
}
|
||||
|
||||
fn shift_operation(value: u32, size: Size, dir: ShiftDirection, arithmetic: bool) -> (u32, bool) {
|
||||
match dir {
|
||||
ShiftDirection::Left => {
|
||||
let bit = get_msb(value, size);
|
||||
match size {
|
||||
Size::Byte => (((value as u8) << 1) as u32, bit),
|
||||
Size::Word => (((value as u16) << 1) as u32, bit),
|
||||
Size::Long => (value << 1, bit),
|
||||
}
|
||||
},
|
||||
ShiftDirection::Right => {
|
||||
let mask = if arithmetic { get_msb_mask(value, size) } else { 0 };
|
||||
((value >> 1) | mask, (value & 0x1) != 0)
|
||||
},
|
||||
fn shift_left(value: u32, size: Size, arithmetic: bool) -> (u32, bool) {
|
||||
let bit = get_msb(value, size);
|
||||
match size {
|
||||
Size::Byte => (((value as u8) << 1) as u32, bit),
|
||||
Size::Word => (((value as u16) << 1) as u32, bit),
|
||||
Size::Long => (value << 1, bit),
|
||||
}
|
||||
}
|
||||
|
||||
fn rotate_operation(value: u32, size: Size, dir: ShiftDirection, use_extend: Option<bool>) -> (u32, bool) {
|
||||
match dir {
|
||||
ShiftDirection::Left => {
|
||||
let bit = get_msb(value, size);
|
||||
let mask = if use_extend.unwrap_or(bit) { 0x01 } else { 0x00 };
|
||||
match size {
|
||||
Size::Byte => (mask | ((value as u8) << 1) as u32, bit),
|
||||
Size::Word => (mask | ((value as u16) << 1) as u32, bit),
|
||||
Size::Long => (mask | value << 1, bit),
|
||||
}
|
||||
},
|
||||
ShiftDirection::Right => {
|
||||
let bit = (value & 0x01) != 0;
|
||||
let mask = if use_extend.unwrap_or(bit) { get_msb_mask(0xffffffff, size) } else { 0x0 };
|
||||
((value >> 1) | mask, bit)
|
||||
},
|
||||
fn shift_right(value: u32, size: Size, arithmetic: bool) -> (u32, bool) {
|
||||
let mask = if arithmetic { get_msb_mask(value, size) } else { 0 };
|
||||
((value >> 1) | mask, (value & 0x1) != 0)
|
||||
}
|
||||
|
||||
fn rotate_left(value: u32, size: Size, use_extend: Option<bool>) -> (u32, bool) {
|
||||
let bit = get_msb(value, size);
|
||||
let mask = if use_extend.unwrap_or(bit) { 0x01 } else { 0x00 };
|
||||
match size {
|
||||
Size::Byte => (mask | ((value as u8) << 1) as u32, bit),
|
||||
Size::Word => (mask | ((value as u16) << 1) as u32, bit),
|
||||
Size::Long => (mask | value << 1, bit),
|
||||
}
|
||||
}
|
||||
|
||||
fn rotate_right(value: u32, size: Size, use_extend: Option<bool>) -> (u32, bool) {
|
||||
let bit = (value & 0x01) != 0;
|
||||
let mask = if use_extend.unwrap_or(bit) { get_msb_mask(0xffffffff, size) } else { 0x0 };
|
||||
((value >> 1) | mask, bit)
|
||||
}
|
||||
|
||||
fn get_nibbles_from_byte(value: u32) -> (u32, u32) {
|
||||
(value & 0xF0, value & 0x0F)
|
||||
}
|
||||
|
@ -23,12 +23,6 @@ pub enum Direction {
|
||||
ToTarget,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum ShiftDirection {
|
||||
Right,
|
||||
Left,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum XRegister {
|
||||
DReg(u8),
|
||||
@ -103,7 +97,8 @@ pub enum Instruction {
|
||||
AND(Target, Target, Size),
|
||||
ANDtoCCR(u8),
|
||||
ANDtoSR(u16),
|
||||
ASd(Target, Target, Size, ShiftDirection),
|
||||
ASL(Target, Target, Size),
|
||||
ASR(Target, Target, Size),
|
||||
|
||||
Bcc(Condition, i32),
|
||||
BRA(i32),
|
||||
@ -144,7 +139,8 @@ pub enum Instruction {
|
||||
|
||||
LEA(Target, Register),
|
||||
LINK(Register, i32),
|
||||
LSd(Target, Target, Size, ShiftDirection),
|
||||
LSL(Target, Target, Size),
|
||||
LSR(Target, Target, Size),
|
||||
|
||||
MOVE(Target, Target, Size),
|
||||
MOVEA(Target, Register, Size),
|
||||
@ -174,8 +170,10 @@ pub enum Instruction {
|
||||
PEA(Target),
|
||||
|
||||
RESET,
|
||||
ROd(Target, Target, Size, ShiftDirection),
|
||||
ROXd(Target, Target, Size, ShiftDirection),
|
||||
ROL(Target, Target, Size),
|
||||
ROR(Target, Target, Size),
|
||||
ROXL(Target, Target, Size),
|
||||
ROXR(Target, Target, Size),
|
||||
RTE,
|
||||
RTR,
|
||||
RTS,
|
||||
@ -235,15 +233,6 @@ impl fmt::Display for Sign {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ShiftDirection {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ShiftDirection::Right => write!(f, "r"),
|
||||
ShiftDirection::Left => write!(f, "l"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Size {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
@ -405,7 +394,8 @@ impl fmt::Display for Instruction {
|
||||
Instruction::AND(src, dest, size) => write!(f, "and{}\t{}, {}", size, src, dest),
|
||||
Instruction::ANDtoCCR(value) => write!(f, "andib\t#{:#02x}, %ccr", value),
|
||||
Instruction::ANDtoSR(value) => write!(f, "andiw\t#{:#04x}, %sr", value),
|
||||
Instruction::ASd(src, dest, size, dir) => write!(f, "as{}{}\t{}, {}", dir, size, src, dest),
|
||||
Instruction::ASL(src, dest, size) => write!(f, "asl{}\t{}, {}", size, src, dest),
|
||||
Instruction::ASR(src, dest, size) => write!(f, "asr{}\t{}, {}", size, src, dest),
|
||||
|
||||
Instruction::Bcc(cond, offset) => write!(f, "b{}\t{}", cond, offset),
|
||||
Instruction::BRA(offset) => write!(f, "bra\t{}", offset),
|
||||
@ -451,7 +441,8 @@ impl fmt::Display for Instruction {
|
||||
|
||||
Instruction::LEA(target, reg) => write!(f, "lea\t{}, %a{}", target, reg),
|
||||
Instruction::LINK(reg, offset) => write!(f, "link\t%a{}, {}", reg, offset),
|
||||
Instruction::LSd(src, dest, size, dir) => write!(f, "ls{}{}\t{}, {}", dir, size, src, dest),
|
||||
Instruction::LSL(src, dest, size) => write!(f, "lsl{}\t{}, {}", size, src, dest),
|
||||
Instruction::LSR(src, dest, size) => write!(f, "lsr{}\t{}, {}", size, src, dest),
|
||||
|
||||
Instruction::MOVE(src, dest, size) => write!(f, "move{}\t{}, {}", size, src, dest),
|
||||
Instruction::MOVEA(target, reg, size) => write!(f, "movea{}\t{}, %a{}", size, target, reg),
|
||||
@ -497,8 +488,10 @@ impl fmt::Display for Instruction {
|
||||
Instruction::PEA(target) => write!(f, "pea\t{}", target),
|
||||
|
||||
Instruction::RESET => write!(f, "reset"),
|
||||
Instruction::ROd(src, dest, size, dir) => write!(f, "ro{}{}\t{}, {}", dir, size, src, dest),
|
||||
Instruction::ROXd(src, dest, size, dir) => write!(f, "rox{}{}\t{}, {}", dir, size, src, dest),
|
||||
Instruction::ROL(src, dest, size) => write!(f, "rol{}\t{}, {}", size, src, dest),
|
||||
Instruction::ROR(src, dest, size) => write!(f, "ror{}\t{}, {}", size, src, dest),
|
||||
Instruction::ROXL(src, dest, size) => write!(f, "roxl{}\t{}, {}", size, src, dest),
|
||||
Instruction::ROXR(src, dest, size) => write!(f, "roxr{}\t{}, {}", size, src, dest),
|
||||
Instruction::RTE => write!(f, "rte"),
|
||||
Instruction::RTR => write!(f, "rtr"),
|
||||
Instruction::RTS => write!(f, "rts"),
|
||||
|
@ -204,7 +204,8 @@ impl M68kInstructionTiming {
|
||||
Instruction::ANDtoCCR(_) => self.add_internal(20),
|
||||
Instruction::ANDtoSR(_) => self.add_internal(20),
|
||||
|
||||
Instruction::ASd(_, target, size, _) => self.add_word_v_long(*size, 6, 8).add_per_rep(2).add_target(*size, target),
|
||||
Instruction::ASL(_, target, size) |
|
||||
Instruction::ASR(_, target, size) => self.add_word_v_long(*size, 6, 8).add_per_rep(2).add_target(*size, target),
|
||||
|
||||
Instruction::Bcc(_, _) => self.add_internal(8).add_on_branch(2),
|
||||
Instruction::BRA(_) => self.add_internal(10),
|
||||
@ -255,7 +256,8 @@ impl M68kInstructionTiming {
|
||||
|
||||
Instruction::LEA(target, _) => self.add_indirect_set(target, 4, 8, 12, 8, 12),
|
||||
Instruction::LINK(_, _) => self.add_internal(16),
|
||||
Instruction::LSd(_, target, size, _) => self.add_word_v_long(*size, 6, 8).add_per_rep(2).add_target(*size, target),
|
||||
Instruction::LSL(_, target, size) |
|
||||
Instruction::LSR(_, target, size) => self.add_word_v_long(*size, 6, 8).add_per_rep(2).add_target(*size, target),
|
||||
|
||||
Instruction::MOVE(src, dest, size) => self.add_internal(4).add_two_targets(*size, src, dest),
|
||||
Instruction::MOVEA(target, _, size) => self.add_internal(4).add_target(*size, target),
|
||||
@ -287,8 +289,10 @@ impl M68kInstructionTiming {
|
||||
|
||||
Instruction::RESET => self.add_internal(132),
|
||||
|
||||
Instruction::ROd(_, target, size, _) => self.add_word_v_long(*size, 6, 8).add_per_rep(2).add_target(*size, target),
|
||||
Instruction::ROXd(_, target, size, _) => self.add_word_v_long(*size, 6, 8).add_per_rep(2).add_target(*size, target),
|
||||
Instruction::ROL(_, target, size) |
|
||||
Instruction::ROR(_, target, size) => self.add_word_v_long(*size, 6, 8).add_per_rep(2).add_target(*size, target),
|
||||
Instruction::ROXL(_, target, size) |
|
||||
Instruction::ROXR(_, target, size) => self.add_word_v_long(*size, 6, 8).add_per_rep(2).add_target(*size, target),
|
||||
|
||||
Instruction::RTE => self.add_internal(20),
|
||||
Instruction::RTR => self.add_internal(20),
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
use cpal::{Stream, SampleRate, SampleFormat, StreamConfig, StreamInstant, OutputCallbackInfo, traits::{DeviceTrait, HostTrait, StreamTrait}};
|
||||
|
||||
use moa_core::{warn, error};
|
||||
use moa_core::{debug, error};
|
||||
|
||||
use crate::audio::{AudioOutput, SAMPLE_RATE};
|
||||
|
||||
@ -41,7 +41,7 @@ impl CpalAudioOutput {
|
||||
output.put_back(clock, frame);
|
||||
}
|
||||
} else {
|
||||
warn!("missed an audio frame");
|
||||
debug!("missed an audio frame");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4,62 +4,77 @@ use moa_core::{System, Error, EdgeSignal, ClockTime, ClockDuration, Frequency, S
|
||||
use moa_core::host::{self, Host, Pixel, PixelEncoding, Frame, FrameSender};
|
||||
|
||||
|
||||
const REG_MODE_SET_1: usize = 0x00;
|
||||
const REG_MODE_SET_2: usize = 0x01;
|
||||
const REG_SCROLL_A_ADDR: usize = 0x02;
|
||||
const REG_WINDOW_ADDR: usize = 0x03;
|
||||
const REG_SCROLL_B_ADDR: usize = 0x04;
|
||||
const REG_SPRITES_ADDR: usize = 0x05;
|
||||
// Register 0x06 Unused
|
||||
const REG_BACKGROUND: usize = 0x07;
|
||||
// Register 0x08 Unused
|
||||
// Register 0x09 Unused
|
||||
const REG_H_INTERRUPT: usize = 0x0A;
|
||||
const REG_MODE_SET_3: usize = 0x0B;
|
||||
const REG_MODE_SET_4: usize = 0x0C;
|
||||
const REG_HSCROLL_ADDR: usize = 0x0D;
|
||||
// Register 0x0E Unused
|
||||
const REG_AUTO_INCREMENT: usize = 0x0F;
|
||||
const REG_SCROLL_SIZE: usize = 0x10;
|
||||
const REG_WINDOW_H_POS: usize = 0x11;
|
||||
const REG_WINDOW_V_POS: usize = 0x12;
|
||||
const REG_DMA_COUNTER_LOW: usize = 0x13;
|
||||
const REG_DMA_COUNTER_HIGH: usize = 0x14;
|
||||
const REG_DMA_ADDR_LOW: usize = 0x15;
|
||||
const REG_DMA_ADDR_MID: usize = 0x16;
|
||||
const REG_DMA_ADDR_HIGH: usize = 0x17;
|
||||
|
||||
|
||||
//const STATUS_PAL_MODE: u16 = 0x0001;
|
||||
const STATUS_DMA_BUSY: u16 = 0x0002;
|
||||
const STATUS_IN_HBLANK: u16 = 0x0004;
|
||||
const STATUS_IN_VBLANK: u16 = 0x0008;
|
||||
//const STATUS_ODD_FRAME: u16 = 0x0010;
|
||||
//const STATUS_SPRITE_COLLISION: u16 = 0x0020;
|
||||
//const STATUS_SPRITE_OVERFLOW: u16 = 0x0040;
|
||||
//const STATUS_V_INTERRUPT: u16 = 0x0080;
|
||||
//const STATUS_FIFO_FULL: u16 = 0x0100;
|
||||
const STATUS_FIFO_EMPTY: u16 = 0x0200;
|
||||
|
||||
const MODE1_BF_DISABLE_DISPLAY: u8 = 0x01;
|
||||
//const MODE1_BF_ENABLE_HV_COUNTER: u8 = 0x02;
|
||||
const MODE1_BF_HSYNC_INTERRUPT: u8 = 0x10;
|
||||
|
||||
const MODE2_BF_V_CELL_MODE: u8 = 0x08;
|
||||
const MODE2_BF_DMA_ENABLED: u8 = 0x10;
|
||||
const MODE2_BF_VSYNC_INTERRUPT: u8 = 0x20;
|
||||
|
||||
const MODE3_BF_EXTERNAL_INTERRUPT: u8 = 0x08;
|
||||
const MODE3_BF_V_SCROLL_MODE: u8 = 0x04;
|
||||
const MODE3_BF_H_SCROLL_MODE: u8 = 0x03;
|
||||
|
||||
const MODE4_BF_H_CELL_MODE: u8 = 0x01;
|
||||
const MODE4_BF_SHADOW_HIGHLIGHT: u8 = 0x08;
|
||||
|
||||
|
||||
|
||||
const DEV_NAME: &str = "ym7101";
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod reg {
|
||||
pub(super) const MODE_SET_1: usize = 0x00;
|
||||
pub(super) const MODE_SET_2: usize = 0x01;
|
||||
pub(super) const SCROLL_A_ADDR: usize = 0x02;
|
||||
pub(super) const WINDOW_ADDR: usize = 0x03;
|
||||
pub(super) const SCROLL_B_ADDR: usize = 0x04;
|
||||
pub(super) const SPRITES_ADDR: usize = 0x05;
|
||||
// Register 0x06 Unused
|
||||
pub(super) const BACKGROUND: usize = 0x07;
|
||||
// Register 0x08 Unused
|
||||
// Register 0x09 Unused
|
||||
pub(super) const H_INTERRUPT: usize = 0x0A;
|
||||
pub(super) const MODE_SET_3: usize = 0x0B;
|
||||
pub(super) const MODE_SET_4: usize = 0x0C;
|
||||
pub(super) const HSCROLL_ADDR: usize = 0x0D;
|
||||
// Register 0x0E Unused
|
||||
pub(super) const AUTO_INCREMENT: usize = 0x0F;
|
||||
pub(super) const SCROLL_SIZE: usize = 0x10;
|
||||
pub(super) const WINDOW_H_POS: usize = 0x11;
|
||||
pub(super) const WINDOW_V_POS: usize = 0x12;
|
||||
pub(super) const DMA_COUNTER_LOW: usize = 0x13;
|
||||
pub(super) const DMA_COUNTER_HIGH: usize = 0x14;
|
||||
pub(super) const DMA_ADDR_LOW: usize = 0x15;
|
||||
pub(super) const DMA_ADDR_MID: usize = 0x16;
|
||||
pub(super) const DMA_ADDR_HIGH: usize = 0x17;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod status {
|
||||
//pub(super) const PAL_MODE: u16 = 0x0001;
|
||||
pub(super) const DMA_BUSY: u16 = 0x0002;
|
||||
pub(super) const IN_HBLANK: u16 = 0x0004;
|
||||
pub(super) const IN_VBLANK: u16 = 0x0008;
|
||||
//pub(super) const ODD_FRAME: u16 = 0x0010;
|
||||
//pub(super) const SPRITE_COLLISION: u16 = 0x0020;
|
||||
//pub(super) const SPRITE_OVERFLOW: u16 = 0x0040;
|
||||
//pub(super) const V_INTERRUPT: u16 = 0x0080;
|
||||
//pub(super) const FIFO_FULL: u16 = 0x0100;
|
||||
pub(super) const FIFO_EMPTY: u16 = 0x0200;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod mode1 {
|
||||
pub(super) const BF_DISABLE_DISPLAY: u8 = 0x01;
|
||||
//const BF_ENABLE_HV_COUNTER: u8 = 0x02;
|
||||
pub(super) const BF_HSYNC_INTERRUPT: u8 = 0x10;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod mode2 {
|
||||
pub(super) const BF_V_CELL_MODE: u8 = 0x08;
|
||||
pub(super) const BF_DMA_ENABLED: u8 = 0x10;
|
||||
pub(super) const BF_VSYNC_INTERRUPT: u8 = 0x20;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod mode3 {
|
||||
pub(super) const BF_EXTERNAL_INTERRUPT: u8 = 0x08;
|
||||
pub(super) const BF_V_SCROLL_MODE: u8 = 0x04;
|
||||
pub(super) const BF_H_SCROLL_MODE: u8 = 0x03;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod mode4 {
|
||||
pub(super) const BF_H_CELL_MODE: u8 = 0x01;
|
||||
pub(super) const BF_SHADOW_HIGHLIGHT: u8 = 0x08;
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
enum DmaType {
|
||||
@ -134,12 +149,12 @@ impl Ym7101Memory {
|
||||
fn set_dma_mode(&mut self, mode: DmaType) {
|
||||
match mode {
|
||||
DmaType::None => {
|
||||
//self.status &= !STATUS_DMA_BUSY;
|
||||
//self.status &= !status::DMA_BUSY;
|
||||
self.transfer_dma_busy = false;
|
||||
self.transfer_run = DmaType::None;
|
||||
},
|
||||
_ => {
|
||||
//self.status |= STATUS_DMA_BUSY;
|
||||
//self.status |= status::DMA_BUSY;
|
||||
self.transfer_dma_busy = true;
|
||||
self.transfer_run = mode;
|
||||
},
|
||||
@ -328,7 +343,7 @@ struct Ym7101State {
|
||||
impl Default for Ym7101State {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
status: 0x3400 | STATUS_FIFO_EMPTY,
|
||||
status: 0x3400 | status::FIFO_EMPTY,
|
||||
memory: Ym7101Memory::default(),
|
||||
|
||||
mode_1: 0,
|
||||
@ -365,22 +380,22 @@ impl Default for Ym7101State {
|
||||
impl Ym7101State {
|
||||
#[inline(always)]
|
||||
fn hsync_int_enabled(&self) -> bool {
|
||||
(self.mode_1 & MODE1_BF_HSYNC_INTERRUPT) != 0
|
||||
(self.mode_1 & mode1::BF_HSYNC_INTERRUPT) != 0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn vsync_int_enabled(&self) -> bool {
|
||||
(self.mode_2 & MODE2_BF_VSYNC_INTERRUPT) != 0
|
||||
(self.mode_2 & mode2::BF_VSYNC_INTERRUPT) != 0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn external_int_enabled(&self) -> bool {
|
||||
(self.mode_3 & MODE3_BF_EXTERNAL_INTERRUPT) != 0
|
||||
(self.mode_3 & mode3::BF_EXTERNAL_INTERRUPT) != 0
|
||||
}
|
||||
|
||||
fn update_screen_size(&mut self) {
|
||||
let h_cells = if (self.mode_4 & MODE4_BF_H_CELL_MODE) == 0 { 32 } else { 40 };
|
||||
let v_cells = if (self.mode_2 & MODE2_BF_V_CELL_MODE) == 0 { 28 } else { 30 };
|
||||
let h_cells = if (self.mode_4 & mode4::BF_H_CELL_MODE) == 0 { 32 } else { 40 };
|
||||
let v_cells = if (self.mode_2 & mode2::BF_V_CELL_MODE) == 0 { 28 } else { 30 };
|
||||
self.screen_size = (h_cells, v_cells);
|
||||
}
|
||||
|
||||
@ -404,7 +419,7 @@ impl Ym7101State {
|
||||
}
|
||||
|
||||
fn get_palette_colour(&self, palette: u8, colour: u8, mode: ColourMode, encoding: PixelEncoding) -> u32 {
|
||||
let shift_enabled = (self.mode_4 & MODE4_BF_SHADOW_HIGHLIGHT) != 0;
|
||||
let shift_enabled = (self.mode_4 & mode4::BF_SHADOW_HIGHLIGHT) != 0;
|
||||
let rgb = self.memory.read_beu16(Memory::Cram, (((palette * 16) + colour) * 2) as usize);
|
||||
if !shift_enabled || mode == ColourMode::Normal {
|
||||
Pixel::Rgb(((rgb & 0x00F) << 4) as u8, (rgb & 0x0F0) as u8, ((rgb & 0xF00) >> 4) as u8).encode(encoding)
|
||||
@ -415,7 +430,7 @@ impl Ym7101State {
|
||||
}
|
||||
|
||||
fn get_hscroll(&self, hcell: usize, line: usize) -> (usize, usize) {
|
||||
let scroll_addr = match self.mode_3 & MODE3_BF_H_SCROLL_MODE {
|
||||
let scroll_addr = match self.mode_3 & mode3::BF_H_SCROLL_MODE {
|
||||
0 => self.hscroll_addr,
|
||||
2 => self.hscroll_addr + (hcell << 5),
|
||||
3 => self.hscroll_addr + (hcell << 5) + (line * 2 * 2),
|
||||
@ -428,7 +443,7 @@ impl Ym7101State {
|
||||
}
|
||||
|
||||
fn get_vscroll(&self, vcell: usize) -> (usize, usize) {
|
||||
let scroll_addr = if (self.mode_3 & MODE3_BF_V_SCROLL_MODE) == 0 {
|
||||
let scroll_addr = if (self.mode_3 & mode3::BF_V_SCROLL_MODE) == 0 {
|
||||
0
|
||||
} else {
|
||||
vcell >> 1
|
||||
@ -505,19 +520,29 @@ impl Ym7101State {
|
||||
for x in 0..(self.screen_size.0 * 8) {
|
||||
let (vscrolling_a, vscrolling_b) = self.get_vscroll(x / 8);
|
||||
|
||||
let pixel_b_x = (x - hscrolling_b) % (self.scroll_size.0 * 8);
|
||||
let pixel_b_y = (y + vscrolling_b) % (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_b_word = self.memory.read_beu16(Memory::Vram, pattern_b_addr);
|
||||
let priority_b = (pattern_b_word & 0x8000) != 0;
|
||||
let pixel_b = self.get_pattern_pixel(pattern_b_word, pixel_b_x % 8, pixel_b_y % 8);
|
||||
let (priority_b, pixel_b) = if self.scroll_size != (0, 0) {
|
||||
let pixel_b_x = (x - hscrolling_b) % (self.scroll_size.0 * 8);
|
||||
let pixel_b_y = (y + vscrolling_b) % (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_b_word = self.memory.read_beu16(Memory::Vram, pattern_b_addr);
|
||||
let priority_b = (pattern_b_word & 0x8000) != 0;
|
||||
let pixel_b = self.get_pattern_pixel(pattern_b_word, pixel_b_x % 8, pixel_b_y % 8);
|
||||
(priority_b, pixel_b)
|
||||
} else {
|
||||
(false, (0, 0))
|
||||
};
|
||||
|
||||
let pixel_a_x = (x - hscrolling_a) % (self.scroll_size.0 * 8);
|
||||
let pixel_a_y = (y + vscrolling_a) % (self.scroll_size.1 * 8);
|
||||
let pattern_a_addr = self.get_pattern_addr(self.scroll_a_addr, pixel_a_x / 8, pixel_a_y / 8);
|
||||
let pattern_a_word = self.memory.read_beu16(Memory::Vram, pattern_a_addr);
|
||||
let mut priority_a = (pattern_a_word & 0x8000) != 0;
|
||||
let mut pixel_a = self.get_pattern_pixel(pattern_a_word, pixel_a_x % 8, pixel_a_y % 8);
|
||||
let (mut priority_a, mut pixel_a) = if self.scroll_size != (0, 0) {
|
||||
let pixel_a_x = (x - hscrolling_a) % (self.scroll_size.0 * 8);
|
||||
let pixel_a_y = (y + vscrolling_a) % (self.scroll_size.1 * 8);
|
||||
let pattern_a_addr = self.get_pattern_addr(self.scroll_a_addr, pixel_a_x / 8, pixel_a_y / 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);
|
||||
(priority_a, pixel_a)
|
||||
} else {
|
||||
(false, (0, 0))
|
||||
};
|
||||
|
||||
if self.window_addr != 0 && self.is_inside_window(x, y) {
|
||||
let pixel_win_x = x - self.window_pos.0.0 * 8;
|
||||
@ -548,6 +573,7 @@ impl Ym7101State {
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
let pixels = match (priority_sprite, priority_a, priority_b) {
|
||||
(false, false, true) => [ pixel_b, pixel_sprite, pixel_a, bg_colour ],
|
||||
(true, false, true) => [ pixel_sprite, pixel_b, pixel_a, bg_colour ],
|
||||
@ -628,12 +654,12 @@ impl Steppable for Ym7101 {
|
||||
}
|
||||
|
||||
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 >= 2_340 && self.state.h_clock <= 61_160 {
|
||||
self.state.status &= !status::IN_HBLANK;
|
||||
self.state.current_x = 0;
|
||||
}
|
||||
if (self.state.status & STATUS_IN_HBLANK) == 0 && 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.current_y += 1;
|
||||
|
||||
self.state.h_scanlines = self.state.h_scanlines.wrapping_sub(1);
|
||||
@ -647,18 +673,18 @@ impl Steppable for Ym7101 {
|
||||
}
|
||||
|
||||
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 >= 1_205_992 && self.state.v_clock <= 15_424_008 {
|
||||
self.state.status &= !status::IN_VBLANK;
|
||||
self.state.current_y = 0;
|
||||
}
|
||||
if (self.state.status & STATUS_IN_VBLANK) == 0 && 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)?;
|
||||
}
|
||||
|
||||
if (self.state.mode_1 & MODE1_BF_DISABLE_DISPLAY) == 0 {
|
||||
if (self.state.mode_1 & mode1::BF_DISABLE_DISPLAY) == 0 && self.state.screen_size != (0, 0) {
|
||||
let mut frame = Frame::new(self.state.screen_size.0 as u32 * 8, self.state.screen_size.1 as u32 * 8, self.sender.encoding());
|
||||
self.state.draw_frame(&mut frame);
|
||||
self.sender.add(system.clock, frame);
|
||||
@ -670,9 +696,9 @@ impl Steppable for Ym7101 {
|
||||
self.state.v_clock -= 16_630_000;
|
||||
}
|
||||
|
||||
if (self.state.mode_2 & MODE2_BF_DMA_ENABLED) != 0 {
|
||||
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 });
|
||||
self.state.status = (self.state.status & !status::DMA_BUSY) | (if self.state.memory.transfer_dma_busy { status::DMA_BUSY } else { 0 });
|
||||
}
|
||||
|
||||
Ok(Frequency::from_hz(13_423_294).period_duration() * 4)
|
||||
@ -712,52 +738,52 @@ impl Ym7101 {
|
||||
|
||||
fn update_register_value(&mut self, reg: usize, data: u8) {
|
||||
match reg {
|
||||
REG_MODE_SET_1 => { self.state.mode_1 = data; },
|
||||
REG_MODE_SET_2 => {
|
||||
reg::MODE_SET_1 => { self.state.mode_1 = data; },
|
||||
reg::MODE_SET_2 => {
|
||||
self.state.mode_2 = data;
|
||||
self.state.update_screen_size();
|
||||
},
|
||||
REG_SCROLL_A_ADDR => { self.state.scroll_a_addr = (data as usize) << 10; },
|
||||
REG_WINDOW_ADDR => { self.state.window_addr = (data as usize) << 10; },
|
||||
REG_SCROLL_B_ADDR => { self.state.scroll_b_addr = (data as usize) << 13; },
|
||||
REG_SPRITES_ADDR => { self.state.sprites_addr = (data as usize) << 9; },
|
||||
REG_BACKGROUND => { self.state.background = data; },
|
||||
REG_H_INTERRUPT => { self.state.h_int_lines = data; },
|
||||
REG_MODE_SET_3 => { self.state.mode_3 = data; },
|
||||
REG_MODE_SET_4 => {
|
||||
reg::SCROLL_A_ADDR => { self.state.scroll_a_addr = (data as usize) << 10; },
|
||||
reg::WINDOW_ADDR => { self.state.window_addr = (data as usize) << 10; },
|
||||
reg::SCROLL_B_ADDR => { self.state.scroll_b_addr = (data as usize) << 13; },
|
||||
reg::SPRITES_ADDR => { self.state.sprites_addr = (data as usize) << 9; },
|
||||
reg::BACKGROUND => { self.state.background = data; },
|
||||
reg::H_INTERRUPT => { self.state.h_int_lines = data; },
|
||||
reg::MODE_SET_3 => { self.state.mode_3 = data; },
|
||||
reg::MODE_SET_4 => {
|
||||
self.state.mode_4 = data;
|
||||
self.state.update_screen_size();
|
||||
},
|
||||
REG_HSCROLL_ADDR => { self.state.hscroll_addr = (data as usize) << 10; },
|
||||
REG_AUTO_INCREMENT => { self.state.memory.transfer_auto_inc = data as u32; },
|
||||
REG_SCROLL_SIZE => {
|
||||
reg::HSCROLL_ADDR => { self.state.hscroll_addr = (data as usize) << 10; },
|
||||
reg::AUTO_INCREMENT => { self.state.memory.transfer_auto_inc = data as u32; },
|
||||
reg::SCROLL_SIZE => {
|
||||
let h = decode_scroll_size(data & 0x03);
|
||||
let v = decode_scroll_size((data >> 4) & 0x03);
|
||||
self.state.scroll_size = (h, v);
|
||||
},
|
||||
REG_WINDOW_H_POS => {
|
||||
reg::WINDOW_H_POS => {
|
||||
self.state.window_values.0 = data;
|
||||
self.state.update_window_position();
|
||||
},
|
||||
REG_WINDOW_V_POS => {
|
||||
reg::WINDOW_V_POS => {
|
||||
self.state.window_values.1 = data;
|
||||
self.state.update_window_position();
|
||||
},
|
||||
REG_DMA_COUNTER_LOW => {
|
||||
reg::DMA_COUNTER_LOW => {
|
||||
self.state.memory.transfer_count = (self.state.memory.transfer_count & 0xFF00) | data as u32;
|
||||
self.state.memory.transfer_remain = self.state.memory.transfer_count;
|
||||
},
|
||||
REG_DMA_COUNTER_HIGH => {
|
||||
reg::DMA_COUNTER_HIGH => {
|
||||
self.state.memory.transfer_count = (self.state.memory.transfer_count & 0x00FF) | ((data as u32) << 8);
|
||||
self.state.memory.transfer_remain = self.state.memory.transfer_count;
|
||||
},
|
||||
REG_DMA_ADDR_LOW => {
|
||||
reg::DMA_ADDR_LOW => {
|
||||
self.state.memory.transfer_src_addr = (self.state.memory.transfer_src_addr & 0xFFFE00) | ((data as u32) << 1);
|
||||
},
|
||||
REG_DMA_ADDR_MID => {
|
||||
reg::DMA_ADDR_MID => {
|
||||
self.state.memory.transfer_src_addr = (self.state.memory.transfer_src_addr & 0xFE01FF) | ((data as u32) << 9);
|
||||
},
|
||||
REG_DMA_ADDR_HIGH => {
|
||||
reg::DMA_ADDR_HIGH => {
|
||||
let mask = if (data & 0x80) == 0 { 0x7F } else { 0x3F };
|
||||
self.state.memory.transfer_bits = data & 0xC0;
|
||||
self.state.memory.transfer_src_addr = (self.state.memory.transfer_src_addr & 0x01FFFF) | (((data & mask) as u32) << 17);
|
||||
@ -834,7 +860,7 @@ impl Addressable for Ym7101 {
|
||||
}
|
||||
} else {
|
||||
self.state.memory.write_control_port(data)?;
|
||||
self.state.status = (self.state.status & !STATUS_DMA_BUSY) | (if self.state.memory.transfer_dma_busy { STATUS_DMA_BUSY } else { 0 });
|
||||
self.state.status = (self.state.status & !status::DMA_BUSY) | (if self.state.memory.transfer_dma_busy { status::DMA_BUSY } else { 0 });
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
const DEFAULT_HARTE_TESTS: &str = "tests/ProcessorTests/680x0/68000/v1/";
|
||||
|
||||
use std::io::prelude::*;
|
||||
use std::fmt::Debug;
|
||||
use std::fmt::{Debug, UpperHex};
|
||||
use std::path::PathBuf;
|
||||
use std::time::SystemTime;
|
||||
use std::fs::{self, File};
|
||||
@ -157,11 +157,14 @@ fn init_execute_test(cputype: M68kType, state: &TestState) -> Result<(M68k, Syst
|
||||
Ok((cpu, system))
|
||||
}
|
||||
|
||||
fn assert_value<T: PartialEq + Debug>(actual: T, expected: T, message: &str) -> Result<(), Error> {
|
||||
fn assert_value<T>(actual: T, expected: T, message: &str) -> Result<(), Error>
|
||||
where
|
||||
T: PartialEq + Debug + UpperHex
|
||||
{
|
||||
if actual == expected {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::assertion(&format!("{:?} != {:?}, {}", actual, expected, message)))
|
||||
Err(Error::assertion(&format!("{:#X} != {:#X}, {}", actual, expected, message)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,647 @@
|
||||
Last run on 2023-05-15 at commit f205e231b62d62c72186c1d9f5277e2bce693380
|
||||
|
||||
00.json completed, all passed!
|
||||
01.json completed, all passed!
|
||||
02.json completed, all passed!
|
||||
03.json completed, all passed!
|
||||
04.json completed, all passed!
|
||||
05.json completed, all passed!
|
||||
06.json completed, all passed!
|
||||
07.json completed, all passed!
|
||||
08.json completed, all passed!
|
||||
09.json completed, all passed!
|
||||
0a.json completed, all passed!
|
||||
0b.json completed, all passed!
|
||||
0c.json completed, all passed!
|
||||
0d.json completed, all passed!
|
||||
0e.json completed, all passed!
|
||||
0f.json completed, all passed!
|
||||
10.json completed, all passed!
|
||||
100.json completed, all passed!
|
||||
101.json completed, all passed!
|
||||
11.json completed, all passed!
|
||||
12.json completed, all passed!
|
||||
13.json completed, all passed!
|
||||
14.json completed, all passed!
|
||||
15.json completed, all passed!
|
||||
16.json completed, all passed!
|
||||
17.json completed, all passed!
|
||||
18.json completed, all passed!
|
||||
19.json completed, all passed!
|
||||
1a.json completed, all passed!
|
||||
1b.json completed, all passed!
|
||||
1c.json completed, all passed!
|
||||
1d.json completed, all passed!
|
||||
1e.json completed, all passed!
|
||||
1f.json completed, all passed!
|
||||
20.json completed, all passed!
|
||||
21.json completed, all passed!
|
||||
22.json completed, all passed!
|
||||
23.json completed, all passed!
|
||||
24.json completed, all passed!
|
||||
25.json completed, all passed!
|
||||
26.json completed, all passed!
|
||||
27.json completed: 547 passed, 453 FAILED
|
||||
28.json completed, all passed!
|
||||
29.json completed, all passed!
|
||||
2a.json completed, all passed!
|
||||
2b.json completed, all passed!
|
||||
2c.json completed, all passed!
|
||||
2d.json completed, all passed!
|
||||
2e.json completed, all passed!
|
||||
2f.json completed, all passed!
|
||||
30.json completed, all passed!
|
||||
31.json completed, all passed!
|
||||
32.json completed, all passed!
|
||||
33.json completed, all passed!
|
||||
34.json completed, all passed!
|
||||
35.json completed, all passed!
|
||||
36.json completed, all passed!
|
||||
37.json completed, all passed!
|
||||
38.json completed, all passed!
|
||||
39.json completed, all passed!
|
||||
3a.json completed, all passed!
|
||||
3b.json completed, all passed!
|
||||
3c.json completed, all passed!
|
||||
3d.json completed, all passed!
|
||||
3e.json completed, all passed!
|
||||
3f.json completed, all passed!
|
||||
40.json completed, all passed!
|
||||
41.json completed, all passed!
|
||||
42.json completed, all passed!
|
||||
43.json completed, all passed!
|
||||
44.json completed, all passed!
|
||||
45.json completed, all passed!
|
||||
46.json completed, all passed!
|
||||
47.json completed, all passed!
|
||||
48.json completed, all passed!
|
||||
49.json completed, all passed!
|
||||
4a.json completed, all passed!
|
||||
4b.json completed, all passed!
|
||||
4c.json completed, all passed!
|
||||
4d.json completed, all passed!
|
||||
4e.json completed, all passed!
|
||||
4f.json completed, all passed!
|
||||
50.json completed, all passed!
|
||||
51.json completed, all passed!
|
||||
52.json completed, all passed!
|
||||
53.json completed, all passed!
|
||||
54.json completed, all passed!
|
||||
55.json completed, all passed!
|
||||
56.json completed, all passed!
|
||||
57.json completed, all passed!
|
||||
58.json completed, all passed!
|
||||
59.json completed, all passed!
|
||||
5a.json completed, all passed!
|
||||
5b.json completed, all passed!
|
||||
5c.json completed, all passed!
|
||||
5d.json completed, all passed!
|
||||
5e.json completed, all passed!
|
||||
5f.json completed, all passed!
|
||||
60.json completed, all passed!
|
||||
61.json completed, all passed!
|
||||
62.json completed, all passed!
|
||||
63.json completed, all passed!
|
||||
64.json completed, all passed!
|
||||
65.json completed, all passed!
|
||||
66.json completed, all passed!
|
||||
67.json completed, all passed!
|
||||
68.json completed, all passed!
|
||||
69.json completed, all passed!
|
||||
6a.json completed, all passed!
|
||||
6b.json completed, all passed!
|
||||
6c.json completed, all passed!
|
||||
6d.json completed, all passed!
|
||||
6e.json completed, all passed!
|
||||
6f.json completed, all passed!
|
||||
70.json completed, all passed!
|
||||
71.json completed, all passed!
|
||||
72.json completed, all passed!
|
||||
73.json completed, all passed!
|
||||
74.json completed, all passed!
|
||||
75.json completed, all passed!
|
||||
76.json completed, all passed!
|
||||
77.json completed, all passed!
|
||||
78.json completed, all passed!
|
||||
79.json completed, all passed!
|
||||
7a.json completed, all passed!
|
||||
7b.json completed, all passed!
|
||||
7c.json completed, all passed!
|
||||
7d.json completed, all passed!
|
||||
7e.json completed, all passed!
|
||||
7f.json completed, all passed!
|
||||
80.json completed, all passed!
|
||||
81.json completed, all passed!
|
||||
82.json completed, all passed!
|
||||
83.json completed, all passed!
|
||||
84.json completed, all passed!
|
||||
85.json completed, all passed!
|
||||
86.json completed, all passed!
|
||||
87.json completed, all passed!
|
||||
88.json completed, all passed!
|
||||
89.json completed, all passed!
|
||||
8a.json completed, all passed!
|
||||
8b.json completed, all passed!
|
||||
8c.json completed, all passed!
|
||||
8d.json completed, all passed!
|
||||
8e.json completed, all passed!
|
||||
8f.json completed, all passed!
|
||||
90.json completed, all passed!
|
||||
91.json completed, all passed!
|
||||
92.json completed, all passed!
|
||||
93.json completed, all passed!
|
||||
94.json completed, all passed!
|
||||
95.json completed, all passed!
|
||||
96.json completed, all passed!
|
||||
97.json completed, all passed!
|
||||
98.json completed, all passed!
|
||||
99.json completed, all passed!
|
||||
9a.json completed, all passed!
|
||||
9b.json completed, all passed!
|
||||
9c.json completed, all passed!
|
||||
9d.json completed, all passed!
|
||||
9e.json completed, all passed!
|
||||
9f.json completed, all passed!
|
||||
a0.json completed, all passed!
|
||||
a1.json completed, all passed!
|
||||
a2.json completed, all passed!
|
||||
a3.json completed, all passed!
|
||||
a4.json completed, all passed!
|
||||
a5.json completed, all passed!
|
||||
a6.json completed, all passed!
|
||||
a7.json completed, all passed!
|
||||
a8.json completed, all passed!
|
||||
a9.json completed, all passed!
|
||||
aa.json completed, all passed!
|
||||
ab.json completed, all passed!
|
||||
ac.json completed, all passed!
|
||||
ad.json completed, all passed!
|
||||
ae.json completed, all passed!
|
||||
af.json completed, all passed!
|
||||
b0.json completed, all passed!
|
||||
b1.json completed, all passed!
|
||||
b2.json completed, all passed!
|
||||
b3.json completed, all passed!
|
||||
b4.json completed, all passed!
|
||||
b5.json completed, all passed!
|
||||
b6.json completed, all passed!
|
||||
b7.json completed, all passed!
|
||||
b8.json completed, all passed!
|
||||
b9.json completed, all passed!
|
||||
ba.json completed, all passed!
|
||||
bb.json completed, all passed!
|
||||
bc.json completed, all passed!
|
||||
bd.json completed, all passed!
|
||||
be.json completed, all passed!
|
||||
bf.json completed, all passed!
|
||||
c0.json completed, all passed!
|
||||
c1.json completed, all passed!
|
||||
c2.json completed, all passed!
|
||||
c3.json completed, all passed!
|
||||
c4.json completed, all passed!
|
||||
c5.json completed, all passed!
|
||||
c6.json completed, all passed!
|
||||
c7.json completed, all passed!
|
||||
c8.json completed, all passed!
|
||||
c9.json completed, all passed!
|
||||
ca.json completed, all passed!
|
||||
cb 00.json completed, all passed!
|
||||
cb 01.json completed, all passed!
|
||||
cb 02.json completed, all passed!
|
||||
cb 03.json completed, all passed!
|
||||
cb 04.json completed, all passed!
|
||||
cb 05.json completed, all passed!
|
||||
cb 06.json completed, all passed!
|
||||
cb 07.json completed, all passed!
|
||||
cb 08.json completed, all passed!
|
||||
cb 09.json completed, all passed!
|
||||
cb 0a.json completed, all passed!
|
||||
cb 0b.json completed, all passed!
|
||||
cb 0c.json completed, all passed!
|
||||
cb 0d.json completed, all passed!
|
||||
cb 0e.json completed, all passed!
|
||||
cb 0f.json completed, all passed!
|
||||
cb 10.json completed, all passed!
|
||||
cb 11.json completed, all passed!
|
||||
cb 12.json completed, all passed!
|
||||
cb 13.json completed, all passed!
|
||||
cb 14.json completed, all passed!
|
||||
cb 15.json completed, all passed!
|
||||
cb 16.json completed, all passed!
|
||||
cb 17.json completed, all passed!
|
||||
cb 18.json completed, all passed!
|
||||
cb 19.json completed, all passed!
|
||||
cb 1a.json completed, all passed!
|
||||
cb 1b.json completed, all passed!
|
||||
cb 1c.json completed, all passed!
|
||||
cb 1d.json completed, all passed!
|
||||
cb 1e.json completed, all passed!
|
||||
cb 1f.json completed, all passed!
|
||||
cb 20.json completed, all passed!
|
||||
cb 21.json completed, all passed!
|
||||
cb 22.json completed, all passed!
|
||||
cb 23.json completed, all passed!
|
||||
cb 24.json completed, all passed!
|
||||
cb 25.json completed, all passed!
|
||||
cb 26.json completed, all passed!
|
||||
cb 27.json completed, all passed!
|
||||
cb 28.json completed, all passed!
|
||||
cb 29.json completed, all passed!
|
||||
cb 2a.json completed, all passed!
|
||||
cb 2b.json completed, all passed!
|
||||
cb 2c.json completed, all passed!
|
||||
cb 2d.json completed, all passed!
|
||||
cb 2e.json completed, all passed!
|
||||
cb 2f.json completed, all passed!
|
||||
cb 38.json completed, all passed!
|
||||
cb 39.json completed, all passed!
|
||||
cb 3a.json completed, all passed!
|
||||
cb 3b.json completed, all passed!
|
||||
cb 3c.json completed, all passed!
|
||||
cb 3d.json completed, all passed!
|
||||
cb 3e.json completed, all passed!
|
||||
cb 3f.json completed, all passed!
|
||||
cb 40.json completed, all passed!
|
||||
cb 41.json completed, all passed!
|
||||
cb 42.json completed, all passed!
|
||||
cb 43.json completed, all passed!
|
||||
cb 44.json completed, all passed!
|
||||
cb 45.json completed, all passed!
|
||||
cb 46.json completed, all passed!
|
||||
cb 47.json completed, all passed!
|
||||
cb 48.json completed, all passed!
|
||||
cb 49.json completed, all passed!
|
||||
cb 4a.json completed, all passed!
|
||||
cb 4b.json completed, all passed!
|
||||
cb 4c.json completed, all passed!
|
||||
cb 4d.json completed, all passed!
|
||||
cb 4e.json completed, all passed!
|
||||
cb 4f.json completed, all passed!
|
||||
cb 50.json completed, all passed!
|
||||
cb 51.json completed, all passed!
|
||||
cb 52.json completed, all passed!
|
||||
cb 53.json completed, all passed!
|
||||
cb 54.json completed, all passed!
|
||||
cb 55.json completed, all passed!
|
||||
cb 56.json completed, all passed!
|
||||
cb 57.json completed, all passed!
|
||||
cb 58.json completed, all passed!
|
||||
cb 59.json completed, all passed!
|
||||
cb 5a.json completed, all passed!
|
||||
cb 5b.json completed, all passed!
|
||||
cb 5c.json completed, all passed!
|
||||
cb 5d.json completed, all passed!
|
||||
cb 5e.json completed, all passed!
|
||||
cb 5f.json completed, all passed!
|
||||
cb 60.json completed, all passed!
|
||||
cb 61.json completed, all passed!
|
||||
cb 62.json completed, all passed!
|
||||
cb 63.json completed, all passed!
|
||||
cb 64.json completed, all passed!
|
||||
cb 65.json completed, all passed!
|
||||
cb 66.json completed, all passed!
|
||||
cb 67.json completed, all passed!
|
||||
cb 68.json completed, all passed!
|
||||
cb 69.json completed, all passed!
|
||||
cb 6a.json completed, all passed!
|
||||
cb 6b.json completed, all passed!
|
||||
cb 6c.json completed, all passed!
|
||||
cb 6d.json completed, all passed!
|
||||
cb 6e.json completed, all passed!
|
||||
cb 6f.json completed, all passed!
|
||||
cb 70.json completed, all passed!
|
||||
cb 71.json completed, all passed!
|
||||
cb 72.json completed, all passed!
|
||||
cb 73.json completed, all passed!
|
||||
cb 74.json completed, all passed!
|
||||
cb 75.json completed, all passed!
|
||||
cb 76.json completed, all passed!
|
||||
cb 77.json completed, all passed!
|
||||
cb 78.json completed, all passed!
|
||||
cb 79.json completed, all passed!
|
||||
cb 7a.json completed, all passed!
|
||||
cb 7b.json completed, all passed!
|
||||
cb 7c.json completed, all passed!
|
||||
cb 7d.json completed, all passed!
|
||||
cb 7e.json completed, all passed!
|
||||
cb 7f.json completed, all passed!
|
||||
cb 80.json completed, all passed!
|
||||
cb 81.json completed, all passed!
|
||||
cb 82.json completed, all passed!
|
||||
cb 83.json completed, all passed!
|
||||
cb 84.json completed, all passed!
|
||||
cb 85.json completed, all passed!
|
||||
cb 86.json completed, all passed!
|
||||
cb 87.json completed, all passed!
|
||||
cb 88.json completed, all passed!
|
||||
cb 89.json completed, all passed!
|
||||
cb 8a.json completed, all passed!
|
||||
cb 8b.json completed, all passed!
|
||||
cb 8c.json completed, all passed!
|
||||
cb 8d.json completed, all passed!
|
||||
cb 8e.json completed, all passed!
|
||||
cb 8f.json completed, all passed!
|
||||
cb 90.json completed, all passed!
|
||||
cb 91.json completed, all passed!
|
||||
cb 92.json completed, all passed!
|
||||
cb 93.json completed, all passed!
|
||||
cb 94.json completed, all passed!
|
||||
cb 95.json completed, all passed!
|
||||
cb 96.json completed, all passed!
|
||||
cb 97.json completed, all passed!
|
||||
cb 98.json completed, all passed!
|
||||
cb 99.json completed, all passed!
|
||||
cb 9a.json completed, all passed!
|
||||
cb 9b.json completed, all passed!
|
||||
cb 9c.json completed, all passed!
|
||||
cb 9d.json completed, all passed!
|
||||
cb 9e.json completed, all passed!
|
||||
cb 9f.json completed, all passed!
|
||||
cb a0.json completed, all passed!
|
||||
cb a1.json completed, all passed!
|
||||
cb a2.json completed, all passed!
|
||||
cb a3.json completed, all passed!
|
||||
cb a4.json completed, all passed!
|
||||
cb a5.json completed, all passed!
|
||||
cb a6.json completed, all passed!
|
||||
cb a7.json completed, all passed!
|
||||
cb a8.json completed, all passed!
|
||||
cb a9.json completed, all passed!
|
||||
cb aa.json completed, all passed!
|
||||
cb ab.json completed, all passed!
|
||||
cb ac.json completed, all passed!
|
||||
cb ad.json completed, all passed!
|
||||
cb ae.json completed, all passed!
|
||||
cb af.json completed, all passed!
|
||||
cb b0.json completed, all passed!
|
||||
cb b1.json completed, all passed!
|
||||
cb b2.json completed, all passed!
|
||||
cb b3.json completed, all passed!
|
||||
cb b4.json completed, all passed!
|
||||
cb b5.json completed, all passed!
|
||||
cb b6.json completed, all passed!
|
||||
cb b7.json completed, all passed!
|
||||
cb b8.json completed, all passed!
|
||||
cb b9.json completed, all passed!
|
||||
cb ba.json completed, all passed!
|
||||
cb bb.json completed, all passed!
|
||||
cb bc.json completed, all passed!
|
||||
cb bd.json completed, all passed!
|
||||
cb be.json completed, all passed!
|
||||
cb bf.json completed, all passed!
|
||||
cb c0.json completed, all passed!
|
||||
cb c1.json completed, all passed!
|
||||
cb c2.json completed, all passed!
|
||||
cb c3.json completed, all passed!
|
||||
cb c4.json completed, all passed!
|
||||
cb c5.json completed, all passed!
|
||||
cb c6.json completed, all passed!
|
||||
cb c7.json completed, all passed!
|
||||
cb c8.json completed, all passed!
|
||||
cb c9.json completed, all passed!
|
||||
cb ca.json completed, all passed!
|
||||
cb cb.json completed, all passed!
|
||||
cb cc.json completed, all passed!
|
||||
cb cd.json completed, all passed!
|
||||
cb ce.json completed, all passed!
|
||||
cb cf.json completed, all passed!
|
||||
cb d0.json completed, all passed!
|
||||
cb d1.json completed, all passed!
|
||||
cb d2.json completed, all passed!
|
||||
cb d3.json completed, all passed!
|
||||
cb d4.json completed, all passed!
|
||||
cb d5.json completed, all passed!
|
||||
cb d6.json completed, all passed!
|
||||
cb d7.json completed, all passed!
|
||||
cb d8.json completed, all passed!
|
||||
cb d9.json completed, all passed!
|
||||
cb da.json completed, all passed!
|
||||
cb db.json completed, all passed!
|
||||
cb dc.json completed, all passed!
|
||||
cb dd.json completed, all passed!
|
||||
cb de.json completed, all passed!
|
||||
cb df.json completed, all passed!
|
||||
cb e0.json completed, all passed!
|
||||
cb e1.json completed, all passed!
|
||||
cb e2.json completed, all passed!
|
||||
cb e3.json completed, all passed!
|
||||
cb e4.json completed, all passed!
|
||||
cb e5.json completed, all passed!
|
||||
cb e6.json completed, all passed!
|
||||
cb e7.json completed, all passed!
|
||||
cb e8.json completed, all passed!
|
||||
cb e9.json completed, all passed!
|
||||
cb ea.json completed, all passed!
|
||||
cb eb.json completed, all passed!
|
||||
cb ec.json completed, all passed!
|
||||
cb ed.json completed, all passed!
|
||||
cb ee.json completed, all passed!
|
||||
cb ef.json completed, all passed!
|
||||
cb f0.json completed, all passed!
|
||||
cb f1.json completed, all passed!
|
||||
cb f2.json completed, all passed!
|
||||
cb f3.json completed, all passed!
|
||||
cb f4.json completed, all passed!
|
||||
cb f5.json completed, all passed!
|
||||
cb f6.json completed, all passed!
|
||||
cb f7.json completed, all passed!
|
||||
cb f8.json completed, all passed!
|
||||
cb f9.json completed, all passed!
|
||||
cb fa.json completed, all passed!
|
||||
cb fb.json completed, all passed!
|
||||
cb fc.json completed, all passed!
|
||||
cb fd.json completed, all passed!
|
||||
cb fe.json completed, all passed!
|
||||
cb ff.json completed, all passed!
|
||||
cc.json completed, all passed!
|
||||
cd.json completed, all passed!
|
||||
ce.json completed, all passed!
|
||||
cf.json completed, all passed!
|
||||
d0.json completed, all passed!
|
||||
d1.json completed, all passed!
|
||||
d2.json completed, all passed!
|
||||
d3.json completed, all passed!
|
||||
d4.json completed, all passed!
|
||||
d5.json completed, all passed!
|
||||
d6.json completed, all passed!
|
||||
d7.json completed, all passed!
|
||||
d8.json completed, all passed!
|
||||
d9.json completed, all passed!
|
||||
da.json completed, all passed!
|
||||
db.json completed, all passed!
|
||||
dc.json completed, all passed!
|
||||
dd 09.json completed, all passed!
|
||||
dd 19.json completed, all passed!
|
||||
dd 29.json completed, all passed!
|
||||
dd 36.json completed, all passed!
|
||||
dd 39.json completed, all passed!
|
||||
dd 46.json completed, all passed!
|
||||
dd 4e.json completed, all passed!
|
||||
dd 56.json completed, all passed!
|
||||
dd 5e.json completed, all passed!
|
||||
dd 66.json completed, all passed!
|
||||
dd 6e.json completed, all passed!
|
||||
dd 70.json completed, all passed!
|
||||
dd 71.json completed, all passed!
|
||||
dd 72.json completed, all passed!
|
||||
dd 73.json completed, all passed!
|
||||
dd 74.json completed, all passed!
|
||||
dd 75.json completed, all passed!
|
||||
dd 77.json completed, all passed!
|
||||
dd 7e.json completed, all passed!
|
||||
dd 86.json completed, all passed!
|
||||
dd 8e.json completed, all passed!
|
||||
dd 96.json completed, all passed!
|
||||
dd 9e.json completed, all passed!
|
||||
dd a6.json completed, all passed!
|
||||
dd ae.json completed, all passed!
|
||||
dd b6.json completed, all passed!
|
||||
dd be.json completed, all passed!
|
||||
dd e1.json completed, all passed!
|
||||
dd e3.json completed, all passed!
|
||||
dd e5.json completed, all passed!
|
||||
dd e9.json completed, all passed!
|
||||
dd f9.json completed, all passed!
|
||||
de.json completed, all passed!
|
||||
df.json completed, all passed!
|
||||
e0.json completed, all passed!
|
||||
e1.json completed, all passed!
|
||||
e2.json completed, all passed!
|
||||
e3.json completed, all passed!
|
||||
e4.json completed, all passed!
|
||||
e5.json completed, all passed!
|
||||
e6.json completed, all passed!
|
||||
e7.json completed, all passed!
|
||||
e8.json completed, all passed!
|
||||
e9.json completed, all passed!
|
||||
ea.json completed, all passed!
|
||||
eb.json completed, all passed!
|
||||
ec.json completed, all passed!
|
||||
ed 40.json completed, all passed!
|
||||
ed 41.json completed, all passed!
|
||||
ed 42.json completed, all passed!
|
||||
ed 43.json completed, all passed!
|
||||
ed 44.json completed, all passed!
|
||||
ed 45.json completed, all passed!
|
||||
ed 46.json completed, all passed!
|
||||
ed 47.json completed, all passed!
|
||||
ed 48.json completed, all passed!
|
||||
ed 49.json completed, all passed!
|
||||
ed 4a.json completed, all passed!
|
||||
ed 4b.json completed, all passed!
|
||||
ed 4c.json completed, all passed!
|
||||
ed 4d.json completed, all passed!
|
||||
ed 4e.json completed, all passed!
|
||||
ed 4f.json completed, all passed!
|
||||
ed 50.json completed, all passed!
|
||||
ed 51.json completed, all passed!
|
||||
ed 52.json completed, all passed!
|
||||
ed 53.json completed, all passed!
|
||||
ed 54.json completed, all passed!
|
||||
ed 55.json completed, all passed!
|
||||
ed 56.json completed, all passed!
|
||||
ed 57.json completed, all passed!
|
||||
ed 58.json completed, all passed!
|
||||
ed 59.json completed, all passed!
|
||||
ed 5a.json completed, all passed!
|
||||
ed 5b.json completed, all passed!
|
||||
ed 5c.json completed, all passed!
|
||||
ed 5d.json completed, all passed!
|
||||
ed 5e.json completed, all passed!
|
||||
ed 5f.json completed, all passed!
|
||||
ed 60.json completed, all passed!
|
||||
ed 61.json completed, all passed!
|
||||
ed 62.json completed, all passed!
|
||||
ed 64.json completed, all passed!
|
||||
ed 65.json completed, all passed!
|
||||
ed 66.json completed, all passed!
|
||||
ed 67.json completed, all passed!
|
||||
ed 68.json completed, all passed!
|
||||
ed 69.json completed, all passed!
|
||||
ed 6a.json completed, all passed!
|
||||
ed 6c.json completed, all passed!
|
||||
ed 6d.json completed, all passed!
|
||||
ed 6e.json completed, all passed!
|
||||
ed 6f.json completed, all passed!
|
||||
ed 72.json completed, all passed!
|
||||
ed 73.json completed, all passed!
|
||||
ed 74.json completed, all passed!
|
||||
ed 75.json completed, all passed!
|
||||
ed 76.json completed, all passed!
|
||||
ed 77.json completed: 0 passed, 1000 FAILED
|
||||
ed 78.json completed, all passed!
|
||||
ed 79.json completed, all passed!
|
||||
ed 7a.json completed, all passed!
|
||||
ed 7b.json completed, all passed!
|
||||
ed 7c.json completed, all passed!
|
||||
ed 7d.json completed, all passed!
|
||||
ed 7e.json completed, all passed!
|
||||
ed 7f.json completed: 0 passed, 1000 FAILED
|
||||
ed a0.json completed, all passed!
|
||||
ed a1.json completed: 0 passed, 1000 FAILED
|
||||
ed a2.json completed: 13 passed, 987 FAILED
|
||||
ed a3.json completed: 0 passed, 1000 FAILED
|
||||
ed a8.json completed, all passed!
|
||||
ed a9.json completed: 0 passed, 1000 FAILED
|
||||
ed aa.json completed: 0 passed, 1000 FAILED
|
||||
ed ab.json completed: 0 passed, 1000 FAILED
|
||||
ed b0.json completed, all passed!
|
||||
ed b1.json completed: 0 passed, 1000 FAILED
|
||||
ed b2.json completed: 0 passed, 1000 FAILED
|
||||
ed b3.json completed: 0 passed, 1000 FAILED
|
||||
ed b8.json completed, all passed!
|
||||
ed b9.json completed: 0 passed, 1000 FAILED
|
||||
ed ba.json completed: 0 passed, 1000 FAILED
|
||||
ed bb.json completed: 0 passed, 1000 FAILED
|
||||
ee.json completed, all passed!
|
||||
ef.json completed, all passed!
|
||||
f0.json completed, all passed!
|
||||
f1.json completed, all passed!
|
||||
f2.json completed, all passed!
|
||||
f3.json completed, all passed!
|
||||
f4.json completed, all passed!
|
||||
f5.json completed, all passed!
|
||||
f6.json completed, all passed!
|
||||
f7.json completed, all passed!
|
||||
f8.json completed, all passed!
|
||||
f9.json completed, all passed!
|
||||
fa.json completed, all passed!
|
||||
fb.json completed, all passed!
|
||||
fc.json completed, all passed!
|
||||
fd 09.json completed, all passed!
|
||||
fd 19.json completed, all passed!
|
||||
fd 29.json completed, all passed!
|
||||
fd 36.json completed, all passed!
|
||||
fd 39.json completed, all passed!
|
||||
fd 46.json completed, all passed!
|
||||
fd 4e.json completed, all passed!
|
||||
fd 56.json completed, all passed!
|
||||
fd 5e.json completed, all passed!
|
||||
fd 66.json completed, all passed!
|
||||
fd 6e.json completed, all passed!
|
||||
fd 70.json completed, all passed!
|
||||
fd 71.json completed, all passed!
|
||||
fd 72.json completed, all passed!
|
||||
fd 73.json completed, all passed!
|
||||
fd 74.json completed, all passed!
|
||||
fd 75.json completed, all passed!
|
||||
fd 77.json completed, all passed!
|
||||
fd 7e.json completed, all passed!
|
||||
fd 86.json completed, all passed!
|
||||
fd 8e.json completed, all passed!
|
||||
fd 96.json completed, all passed!
|
||||
fd 9e.json completed, all passed!
|
||||
fd a6.json completed, all passed!
|
||||
fd ae.json completed, all passed!
|
||||
fd b6.json completed, all passed!
|
||||
fd be.json completed, all passed!
|
||||
fd e1.json completed, all passed!
|
||||
fd e3.json completed, all passed!
|
||||
fd e5.json completed, all passed!
|
||||
fd e9.json completed, all passed!
|
||||
fd f9.json completed, all passed!
|
||||
fe.json completed, all passed!
|
||||
ff.json completed, all passed!
|
||||
|
||||
passed: 627560, failed: 14440, total 98%
|
||||
completed in 0m 35s
|
6
todo.txt
6
todo.txt
@ -1,4 +1,8 @@
|
||||
|
||||
* the way you're doing debugging is so bad, and something's broken with the Z80
|
||||
* debugger should return a breakpoint error to the frontend, so that the frontend still runs, instead of suspending the current execution
|
||||
* can you make the debugger workable in the web ui in some way? So you can have a debug window open while playing the game or something
|
||||
|
||||
* I like making address adapters like this (below)
|
||||
* you could have busport take a closure or something which translates the address, and returns an error that will be passed up if it occurs
|
||||
in order to implement the correct behaviour for address exceptions in 68k, transparently
|
||||
@ -12,6 +16,8 @@
|
||||
* should you make Address a newtype and add From impls for each type of numeric, and add utils to wrap address at certain boundaries and such
|
||||
* should you make a means of storing different kinds of buses?
|
||||
* should you make buses hide their RcRefCell?
|
||||
* make functions for creating a processor instance from the cpu type (M68k::from_type()), ie. initialize the busport internally with the correct
|
||||
bitwidths, but it would still be possible to initialize the CPU manually to create one that never existed as such
|
||||
|
||||
|
||||
* address repeater on ym2612 doesn't seem to work the same, when it's on the 68000 device. The Z80 device doesn't have an affect, but maybe it's not being used
|
||||
|
Loading…
x
Reference in New Issue
Block a user