mirror of
https://github.com/transistorfet/moa.git
synced 2024-05-28 13:41:30 +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
|
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
|
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
|
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,
|
Size,
|
||||||
Sign,
|
Sign,
|
||||||
Direction,
|
Direction,
|
||||||
ShiftDirection,
|
|
||||||
XRegister,
|
XRegister,
|
||||||
BaseRegister,
|
BaseRegister,
|
||||||
IndexRegister,
|
IndexRegister,
|
||||||
|
@ -583,10 +582,9 @@ impl M68kDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_group_shift(&mut self, memory: &mut dyn Addressable, ins: u16) -> Result<Instruction, Error> {
|
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) {
|
match get_size(ins) {
|
||||||
Some(size) => {
|
Some(size) => {
|
||||||
let reg = get_low_reg(ins);
|
let target = Target::DirectDReg(get_low_reg(ins));
|
||||||
let rotation = get_high_reg(ins);
|
let rotation = get_high_reg(ins);
|
||||||
let count = if (ins & 0x0020) == 0 {
|
let count = if (ins & 0x0020) == 0 {
|
||||||
Target::Immediate(if rotation != 0 { rotation as u32 } else { 8 })
|
Target::Immediate(if rotation != 0 { rotation as u32 } else { 8 })
|
||||||
|
@ -594,24 +592,46 @@ impl M68kDecoder {
|
||||||
Target::DirectDReg(rotation)
|
Target::DirectDReg(rotation)
|
||||||
};
|
};
|
||||||
|
|
||||||
match (ins & 0x0018) >> 3 {
|
if (ins & 0x0100) == 0 {
|
||||||
0b00 => Ok(Instruction::ASd(count, Target::DirectDReg(reg), size, dir)),
|
match (ins & 0x0018) >> 3 {
|
||||||
0b01 => Ok(Instruction::LSd(count, Target::DirectDReg(reg), size, dir)),
|
0b00 => Ok(Instruction::ASR(count, target, size)),
|
||||||
0b10 => Ok(Instruction::ROXd(count, Target::DirectDReg(reg), size, dir)),
|
0b01 => Ok(Instruction::LSR(count, target, size)),
|
||||||
0b11 => Ok(Instruction::ROd(count, Target::DirectDReg(reg), size, dir)),
|
0b10 => Ok(Instruction::ROXR(count, target, size)),
|
||||||
_ => Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
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 => {
|
None => {
|
||||||
if (ins & 0x800) == 0 {
|
if (ins & 0x800) == 0 {
|
||||||
let target = self.decode_lower_effective_address(memory, ins, Some(Size::Word))?;
|
let target = self.decode_lower_effective_address(memory, ins, Some(Size::Word))?;
|
||||||
let count = Target::Immediate(1);
|
let count = Target::Immediate(1);
|
||||||
match (ins & 0x0600) >> 9 {
|
let size = Size::Word;
|
||||||
0b00 => Ok(Instruction::ASd(count, target, Size::Word, dir)),
|
|
||||||
0b01 => Ok(Instruction::LSd(count, target, Size::Word, dir)),
|
if (ins & 0x0100) == 0 {
|
||||||
0b10 => Ok(Instruction::ROXd(count, target, Size::Word, dir)),
|
match (ins & 0x0600) >> 9 {
|
||||||
0b11 => Ok(Instruction::ROd(count, target, Size::Word, dir)),
|
0b00 => Ok(Instruction::ASR(count, target, size)),
|
||||||
_ => Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
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 {
|
} else if self.cputype > M68kType::MC68020 {
|
||||||
// Bitfield instructions (MC68020+)
|
// Bitfield instructions (MC68020+)
|
||||||
|
|
|
@ -8,7 +8,6 @@ use crate::instructions::{
|
||||||
Size,
|
Size,
|
||||||
Sign,
|
Sign,
|
||||||
Direction,
|
Direction,
|
||||||
ShiftDirection,
|
|
||||||
XRegister,
|
XRegister,
|
||||||
BaseRegister,
|
BaseRegister,
|
||||||
IndexRegister,
|
IndexRegister,
|
||||||
|
@ -222,7 +221,8 @@ impl M68k {
|
||||||
Instruction::AND(src, dest, size) => self.execute_and(src, dest, size),
|
Instruction::AND(src, dest, size) => self.execute_and(src, dest, size),
|
||||||
Instruction::ANDtoCCR(value) => self.execute_and_to_ccr(value),
|
Instruction::ANDtoCCR(value) => self.execute_and_to_ccr(value),
|
||||||
Instruction::ANDtoSR(value) => self.execute_and_to_sr(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::Bcc(cond, offset) => self.execute_bcc(cond, offset),
|
||||||
Instruction::BRA(offset) => self.execute_bra(offset),
|
Instruction::BRA(offset) => self.execute_bra(offset),
|
||||||
Instruction::BSR(offset) => self.execute_bsr(offset),
|
Instruction::BSR(offset) => self.execute_bsr(offset),
|
||||||
|
@ -256,7 +256,8 @@ impl M68k {
|
||||||
Instruction::JSR(target) => self.execute_jsr(target),
|
Instruction::JSR(target) => self.execute_jsr(target),
|
||||||
Instruction::LEA(target, reg) => self.execute_lea(target, reg),
|
Instruction::LEA(target, reg) => self.execute_lea(target, reg),
|
||||||
Instruction::LINK(reg, offset) => self.execute_link(reg, offset),
|
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::MOVE(src, dest, size) => self.execute_move(src, dest, size),
|
||||||
Instruction::MOVEA(src, reg, size) => self.execute_movea(src, reg, size),
|
Instruction::MOVEA(src, reg, size) => self.execute_movea(src, reg, size),
|
||||||
Instruction::MOVEfromSR(target) => self.execute_move_from_sr(target),
|
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::ORtoSR(value) => self.execute_or_to_sr(value),
|
||||||
Instruction::PEA(target) => self.execute_pea(target),
|
Instruction::PEA(target) => self.execute_pea(target),
|
||||||
Instruction::RESET => self.execute_reset(),
|
Instruction::RESET => self.execute_reset(),
|
||||||
Instruction::ROd(count, target, size, shift_dir) => self.execute_rod(count, target, size, shift_dir),
|
Instruction::ROL(count, target, size) => self.execute_rol(count, target, size),
|
||||||
Instruction::ROXd(count, target, size, shift_dir) => self.execute_roxd(count, target, size, shift_dir),
|
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::RTE => self.execute_rte(),
|
||||||
Instruction::RTR => self.execute_rtr(),
|
Instruction::RTR => self.execute_rtr(),
|
||||||
Instruction::RTS => self.execute_rts(),
|
Instruction::RTS => self.execute_rts(),
|
||||||
|
@ -389,7 +392,7 @@ impl M68k {
|
||||||
Ok(())
|
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 count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||||
let value = self.get_target_value(target, size, Used::Twice)?;
|
let value = self.get_target_value(target, size, Used::Twice)?;
|
||||||
|
|
||||||
|
@ -397,7 +400,7 @@ impl M68k {
|
||||||
let mut pair = (value, false);
|
let mut pair = (value, false);
|
||||||
let mut previous_msb = get_msb(pair.0, size);
|
let mut previous_msb = get_msb(pair.0, size);
|
||||||
for _ in 0..count {
|
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 {
|
if get_msb(pair.0, size) != previous_msb {
|
||||||
overflow = true;
|
overflow = true;
|
||||||
}
|
}
|
||||||
|
@ -405,21 +408,40 @@ impl M68k {
|
||||||
}
|
}
|
||||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||||
|
|
||||||
let carry = match shift_dir {
|
self.set_arithmetic_shift_flags(pair.0, count, pair.1, overflow, size);
|
||||||
ShiftDirection::Left => pair.1,
|
Ok(())
|
||||||
ShiftDirection::Right => if count < size.in_bits() { pair.1 } else { false }
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// Adjust flags
|
fn execute_asr(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||||
self.set_logic_flags(pair.0, size);
|
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);
|
self.set_flag(Flags::Overflow, overflow);
|
||||||
if count != 0 {
|
if count != 0 {
|
||||||
self.set_flag(Flags::Extend, carry);
|
self.set_flag(Flags::Extend, last_bit_out);
|
||||||
self.set_flag(Flags::Carry, carry);
|
self.set_flag(Flags::Carry, last_bit_out);
|
||||||
} else {
|
} else {
|
||||||
self.set_flag(Flags::Carry, false);
|
self.set_flag(Flags::Carry, false);
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_bcc(&mut self, cond: Condition, offset: i32) -> Result<(), Error> {
|
fn execute_bcc(&mut self, cond: Condition, offset: i32) -> Result<(), Error> {
|
||||||
|
@ -772,24 +794,39 @@ impl M68k {
|
||||||
Ok(())
|
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 count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||||
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
||||||
for _ in 0..count {
|
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)?;
|
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||||
|
|
||||||
// Adjust flags
|
self.set_shift_flags(pair.0, count, pair.1, size);
|
||||||
self.set_logic_flags(pair.0, 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);
|
self.set_flag(Flags::Overflow, false);
|
||||||
if count != 0 {
|
if count != 0 {
|
||||||
self.set_flag(Flags::Extend, pair.1);
|
self.set_flag(Flags::Extend, last_bit_out);
|
||||||
self.set_flag(Flags::Carry, pair.1);
|
self.set_flag(Flags::Carry, last_bit_out);
|
||||||
} else {
|
} else {
|
||||||
self.set_flag(Flags::Carry, false);
|
self.set_flag(Flags::Carry, false);
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_move(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
|
fn execute_move(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
|
||||||
|
@ -1094,37 +1131,57 @@ impl M68k {
|
||||||
Ok(())
|
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 count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||||
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
||||||
for _ in 0..count {
|
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)?;
|
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||||
|
self.set_rotate_flags(pair.0, pair.1, size);
|
||||||
// Adjust flags
|
|
||||||
self.set_logic_flags(pair.0, size);
|
|
||||||
if pair.1 {
|
|
||||||
self.set_flag(Flags::Carry, true);
|
|
||||||
}
|
|
||||||
Ok(())
|
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 count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||||
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
|
||||||
for _ in 0..count {
|
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_flag(Flags::Extend, pair.1);
|
||||||
}
|
}
|
||||||
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
self.set_target_value(target, pair.0, size, Used::Twice)?;
|
||||||
|
self.set_rotate_flags(pair.0, pair.1, size);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust flags
|
fn execute_roxr(&mut self, count: Target, target: Target, size: Size) -> Result<(), Error> {
|
||||||
self.set_logic_flags(pair.0, size);
|
let count = self.get_target_value(count, size, Used::Once)? % 64;
|
||||||
if pair.1 {
|
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);
|
self.set_flag(Flags::Carry, true);
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_rte(&mut self) -> Result<(), Error> {
|
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) {
|
fn shift_left(value: u32, size: Size, arithmetic: bool) -> (u32, bool) {
|
||||||
match dir {
|
let bit = get_msb(value, size);
|
||||||
ShiftDirection::Left => {
|
match size {
|
||||||
let bit = get_msb(value, size);
|
Size::Byte => (((value as u8) << 1) as u32, bit),
|
||||||
match size {
|
Size::Word => (((value as u16) << 1) as u32, bit),
|
||||||
Size::Byte => (((value as u8) << 1) as u32, bit),
|
Size::Long => (value << 1, 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 rotate_operation(value: u32, size: Size, dir: ShiftDirection, use_extend: Option<bool>) -> (u32, bool) {
|
fn shift_right(value: u32, size: Size, arithmetic: bool) -> (u32, bool) {
|
||||||
match dir {
|
let mask = if arithmetic { get_msb_mask(value, size) } else { 0 };
|
||||||
ShiftDirection::Left => {
|
((value >> 1) | mask, (value & 0x1) != 0)
|
||||||
let bit = get_msb(value, size);
|
}
|
||||||
let mask = if use_extend.unwrap_or(bit) { 0x01 } else { 0x00 };
|
|
||||||
match size {
|
fn rotate_left(value: u32, size: Size, use_extend: Option<bool>) -> (u32, bool) {
|
||||||
Size::Byte => (mask | ((value as u8) << 1) as u32, bit),
|
let bit = get_msb(value, size);
|
||||||
Size::Word => (mask | ((value as u16) << 1) as u32, bit),
|
let mask = if use_extend.unwrap_or(bit) { 0x01 } else { 0x00 };
|
||||||
Size::Long => (mask | value << 1, bit),
|
match size {
|
||||||
}
|
Size::Byte => (mask | ((value as u8) << 1) as u32, bit),
|
||||||
},
|
Size::Word => (mask | ((value as u16) << 1) as u32, bit),
|
||||||
ShiftDirection::Right => {
|
Size::Long => (mask | value << 1, bit),
|
||||||
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 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) {
|
fn get_nibbles_from_byte(value: u32) -> (u32, u32) {
|
||||||
(value & 0xF0, value & 0x0F)
|
(value & 0xF0, value & 0x0F)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,6 @@ pub enum Direction {
|
||||||
ToTarget,
|
ToTarget,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub enum ShiftDirection {
|
|
||||||
Right,
|
|
||||||
Left,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum XRegister {
|
pub enum XRegister {
|
||||||
DReg(u8),
|
DReg(u8),
|
||||||
|
@ -103,7 +97,8 @@ pub enum Instruction {
|
||||||
AND(Target, Target, Size),
|
AND(Target, Target, Size),
|
||||||
ANDtoCCR(u8),
|
ANDtoCCR(u8),
|
||||||
ANDtoSR(u16),
|
ANDtoSR(u16),
|
||||||
ASd(Target, Target, Size, ShiftDirection),
|
ASL(Target, Target, Size),
|
||||||
|
ASR(Target, Target, Size),
|
||||||
|
|
||||||
Bcc(Condition, i32),
|
Bcc(Condition, i32),
|
||||||
BRA(i32),
|
BRA(i32),
|
||||||
|
@ -144,7 +139,8 @@ pub enum Instruction {
|
||||||
|
|
||||||
LEA(Target, Register),
|
LEA(Target, Register),
|
||||||
LINK(Register, i32),
|
LINK(Register, i32),
|
||||||
LSd(Target, Target, Size, ShiftDirection),
|
LSL(Target, Target, Size),
|
||||||
|
LSR(Target, Target, Size),
|
||||||
|
|
||||||
MOVE(Target, Target, Size),
|
MOVE(Target, Target, Size),
|
||||||
MOVEA(Target, Register, Size),
|
MOVEA(Target, Register, Size),
|
||||||
|
@ -174,8 +170,10 @@ pub enum Instruction {
|
||||||
PEA(Target),
|
PEA(Target),
|
||||||
|
|
||||||
RESET,
|
RESET,
|
||||||
ROd(Target, Target, Size, ShiftDirection),
|
ROL(Target, Target, Size),
|
||||||
ROXd(Target, Target, Size, ShiftDirection),
|
ROR(Target, Target, Size),
|
||||||
|
ROXL(Target, Target, Size),
|
||||||
|
ROXR(Target, Target, Size),
|
||||||
RTE,
|
RTE,
|
||||||
RTR,
|
RTR,
|
||||||
RTS,
|
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 {
|
impl fmt::Display for Size {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -405,7 +394,8 @@ impl fmt::Display for Instruction {
|
||||||
Instruction::AND(src, dest, size) => write!(f, "and{}\t{}, {}", size, src, dest),
|
Instruction::AND(src, dest, size) => write!(f, "and{}\t{}, {}", size, src, dest),
|
||||||
Instruction::ANDtoCCR(value) => write!(f, "andib\t#{:#02x}, %ccr", value),
|
Instruction::ANDtoCCR(value) => write!(f, "andib\t#{:#02x}, %ccr", value),
|
||||||
Instruction::ANDtoSR(value) => write!(f, "andiw\t#{:#04x}, %sr", 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::Bcc(cond, offset) => write!(f, "b{}\t{}", cond, offset),
|
||||||
Instruction::BRA(offset) => write!(f, "bra\t{}", 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::LEA(target, reg) => write!(f, "lea\t{}, %a{}", target, reg),
|
||||||
Instruction::LINK(reg, offset) => write!(f, "link\t%a{}, {}", reg, offset),
|
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::MOVE(src, dest, size) => write!(f, "move{}\t{}, {}", size, src, dest),
|
||||||
Instruction::MOVEA(target, reg, size) => write!(f, "movea{}\t{}, %a{}", size, target, reg),
|
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::PEA(target) => write!(f, "pea\t{}", target),
|
||||||
|
|
||||||
Instruction::RESET => write!(f, "reset"),
|
Instruction::RESET => write!(f, "reset"),
|
||||||
Instruction::ROd(src, dest, size, dir) => write!(f, "ro{}{}\t{}, {}", dir, size, src, dest),
|
Instruction::ROL(src, dest, size) => write!(f, "rol{}\t{}, {}", size, src, dest),
|
||||||
Instruction::ROXd(src, dest, size, dir) => write!(f, "rox{}{}\t{}, {}", dir, 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::RTE => write!(f, "rte"),
|
||||||
Instruction::RTR => write!(f, "rtr"),
|
Instruction::RTR => write!(f, "rtr"),
|
||||||
Instruction::RTS => write!(f, "rts"),
|
Instruction::RTS => write!(f, "rts"),
|
||||||
|
|
|
@ -204,7 +204,8 @@ impl M68kInstructionTiming {
|
||||||
Instruction::ANDtoCCR(_) => self.add_internal(20),
|
Instruction::ANDtoCCR(_) => self.add_internal(20),
|
||||||
Instruction::ANDtoSR(_) => 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::Bcc(_, _) => self.add_internal(8).add_on_branch(2),
|
||||||
Instruction::BRA(_) => self.add_internal(10),
|
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::LEA(target, _) => self.add_indirect_set(target, 4, 8, 12, 8, 12),
|
||||||
Instruction::LINK(_, _) => self.add_internal(16),
|
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::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),
|
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::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::ROL(_, target, size) |
|
||||||
Instruction::ROXd(_, target, size, _) => self.add_word_v_long(*size, 6, 8).add_per_rep(2).add_target(*size, target),
|
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::RTE => self.add_internal(20),
|
||||||
Instruction::RTR => 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 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};
|
use crate::audio::{AudioOutput, SAMPLE_RATE};
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ impl CpalAudioOutput {
|
||||||
output.put_back(clock, frame);
|
output.put_back(clock, frame);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!("missed an audio frame");
|
debug!("missed an audio frame");
|
||||||
break;
|
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};
|
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";
|
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)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
enum DmaType {
|
enum DmaType {
|
||||||
|
@ -134,12 +149,12 @@ impl Ym7101Memory {
|
||||||
fn set_dma_mode(&mut self, mode: DmaType) {
|
fn set_dma_mode(&mut self, mode: DmaType) {
|
||||||
match mode {
|
match mode {
|
||||||
DmaType::None => {
|
DmaType::None => {
|
||||||
//self.status &= !STATUS_DMA_BUSY;
|
//self.status &= !status::DMA_BUSY;
|
||||||
self.transfer_dma_busy = false;
|
self.transfer_dma_busy = false;
|
||||||
self.transfer_run = DmaType::None;
|
self.transfer_run = DmaType::None;
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
//self.status |= STATUS_DMA_BUSY;
|
//self.status |= status::DMA_BUSY;
|
||||||
self.transfer_dma_busy = true;
|
self.transfer_dma_busy = true;
|
||||||
self.transfer_run = mode;
|
self.transfer_run = mode;
|
||||||
},
|
},
|
||||||
|
@ -328,7 +343,7 @@ struct Ym7101State {
|
||||||
impl Default for Ym7101State {
|
impl Default for Ym7101State {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
status: 0x3400 | STATUS_FIFO_EMPTY,
|
status: 0x3400 | status::FIFO_EMPTY,
|
||||||
memory: Ym7101Memory::default(),
|
memory: Ym7101Memory::default(),
|
||||||
|
|
||||||
mode_1: 0,
|
mode_1: 0,
|
||||||
|
@ -365,22 +380,22 @@ impl Default for Ym7101State {
|
||||||
impl Ym7101State {
|
impl Ym7101State {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn hsync_int_enabled(&self) -> bool {
|
fn hsync_int_enabled(&self) -> bool {
|
||||||
(self.mode_1 & MODE1_BF_HSYNC_INTERRUPT) != 0
|
(self.mode_1 & mode1::BF_HSYNC_INTERRUPT) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn vsync_int_enabled(&self) -> bool {
|
fn vsync_int_enabled(&self) -> bool {
|
||||||
(self.mode_2 & MODE2_BF_VSYNC_INTERRUPT) != 0
|
(self.mode_2 & mode2::BF_VSYNC_INTERRUPT) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn external_int_enabled(&self) -> bool {
|
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) {
|
fn update_screen_size(&mut self) {
|
||||||
let h_cells = if (self.mode_4 & MODE4_BF_H_CELL_MODE) == 0 { 32 } else { 40 };
|
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 v_cells = if (self.mode_2 & mode2::BF_V_CELL_MODE) == 0 { 28 } else { 30 };
|
||||||
self.screen_size = (h_cells, v_cells);
|
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 {
|
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);
|
let rgb = self.memory.read_beu16(Memory::Cram, (((palette * 16) + colour) * 2) as usize);
|
||||||
if !shift_enabled || mode == ColourMode::Normal {
|
if !shift_enabled || mode == ColourMode::Normal {
|
||||||
Pixel::Rgb(((rgb & 0x00F) << 4) as u8, (rgb & 0x0F0) as u8, ((rgb & 0xF00) >> 4) as u8).encode(encoding)
|
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) {
|
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,
|
0 => self.hscroll_addr,
|
||||||
2 => self.hscroll_addr + (hcell << 5),
|
2 => self.hscroll_addr + (hcell << 5),
|
||||||
3 => self.hscroll_addr + (hcell << 5) + (line * 2 * 2),
|
3 => self.hscroll_addr + (hcell << 5) + (line * 2 * 2),
|
||||||
|
@ -428,7 +443,7 @@ impl Ym7101State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_vscroll(&self, vcell: usize) -> (usize, usize) {
|
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
|
0
|
||||||
} else {
|
} else {
|
||||||
vcell >> 1
|
vcell >> 1
|
||||||
|
@ -505,19 +520,29 @@ impl Ym7101State {
|
||||||
for x in 0..(self.screen_size.0 * 8) {
|
for x in 0..(self.screen_size.0 * 8) {
|
||||||
let (vscrolling_a, vscrolling_b) = self.get_vscroll(x / 8);
|
let (vscrolling_a, vscrolling_b) = self.get_vscroll(x / 8);
|
||||||
|
|
||||||
let pixel_b_x = (x - hscrolling_b) % (self.scroll_size.0 * 8);
|
let (priority_b, pixel_b) = if self.scroll_size != (0, 0) {
|
||||||
let pixel_b_y = (y + vscrolling_b) % (self.scroll_size.1 * 8);
|
let pixel_b_x = (x - hscrolling_b) % (self.scroll_size.0 * 8);
|
||||||
let pattern_b_addr = self.get_pattern_addr(self.scroll_b_addr, pixel_b_x / 8, pixel_b_y / 8);
|
let pixel_b_y = (y + vscrolling_b) % (self.scroll_size.1 * 8);
|
||||||
let pattern_b_word = self.memory.read_beu16(Memory::Vram, pattern_b_addr);
|
let pattern_b_addr = self.get_pattern_addr(self.scroll_b_addr, pixel_b_x / 8, pixel_b_y / 8);
|
||||||
let priority_b = (pattern_b_word & 0x8000) != 0;
|
let pattern_b_word = self.memory.read_beu16(Memory::Vram, pattern_b_addr);
|
||||||
let pixel_b = self.get_pattern_pixel(pattern_b_word, pixel_b_x % 8, pixel_b_y % 8);
|
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 (mut priority_a, mut pixel_a) = if self.scroll_size != (0, 0) {
|
||||||
let pixel_a_y = (y + vscrolling_a) % (self.scroll_size.1 * 8);
|
let pixel_a_x = (x - hscrolling_a) % (self.scroll_size.0 * 8);
|
||||||
let pattern_a_addr = self.get_pattern_addr(self.scroll_a_addr, pixel_a_x / 8, pixel_a_y / 8);
|
let pixel_a_y = (y + vscrolling_a) % (self.scroll_size.1 * 8);
|
||||||
let pattern_a_word = self.memory.read_beu16(Memory::Vram, pattern_a_addr);
|
let pattern_a_addr = self.get_pattern_addr(self.scroll_a_addr, pixel_a_x / 8, pixel_a_y / 8);
|
||||||
let mut priority_a = (pattern_a_word & 0x8000) != 0;
|
let pattern_a_word = self.memory.read_beu16(Memory::Vram, pattern_a_addr);
|
||||||
let mut pixel_a = self.get_pattern_pixel(pattern_a_word, pixel_a_x % 8, pixel_a_y % 8);
|
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) {
|
if self.window_addr != 0 && self.is_inside_window(x, y) {
|
||||||
let pixel_win_x = x - self.window_pos.0.0 * 8;
|
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) {
|
let pixels = match (priority_sprite, priority_a, priority_b) {
|
||||||
(false, false, true) => [ pixel_b, pixel_sprite, pixel_a, bg_colour ],
|
(false, false, true) => [ pixel_b, pixel_sprite, pixel_a, bg_colour ],
|
||||||
(true, false, true) => [ pixel_sprite, pixel_b, 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;
|
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 {
|
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.status &= !status::IN_HBLANK;
|
||||||
self.state.current_x = 0;
|
self.state.current_x = 0;
|
||||||
}
|
}
|
||||||
if (self.state.status & STATUS_IN_HBLANK) == 0 && self.state.h_clock >= 61_160 {
|
if (self.state.status & status::IN_HBLANK) == 0 && self.state.h_clock >= 61_160 {
|
||||||
self.state.status |= STATUS_IN_HBLANK;
|
self.state.status |= status::IN_HBLANK;
|
||||||
self.state.current_y += 1;
|
self.state.current_y += 1;
|
||||||
|
|
||||||
self.state.h_scanlines = self.state.h_scanlines.wrapping_sub(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;
|
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 {
|
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.status &= !status::IN_VBLANK;
|
||||||
self.state.current_y = 0;
|
self.state.current_y = 0;
|
||||||
}
|
}
|
||||||
if (self.state.status & STATUS_IN_VBLANK) == 0 && self.state.v_clock >= 15_424_008 {
|
if (self.state.status & status::IN_VBLANK) == 0 && self.state.v_clock >= 15_424_008 {
|
||||||
self.state.status |= STATUS_IN_VBLANK;
|
self.state.status |= status::IN_VBLANK;
|
||||||
|
|
||||||
if self.state.vsync_int_enabled() {
|
if self.state.vsync_int_enabled() {
|
||||||
system.get_interrupt_controller().set(true, 6, 30)?;
|
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());
|
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.state.draw_frame(&mut frame);
|
||||||
self.sender.add(system.clock, frame);
|
self.sender.add(system.clock, frame);
|
||||||
|
@ -670,9 +696,9 @@ impl Steppable for Ym7101 {
|
||||||
self.state.v_clock -= 16_630_000;
|
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.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)
|
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) {
|
fn update_register_value(&mut self, reg: usize, data: u8) {
|
||||||
match reg {
|
match reg {
|
||||||
REG_MODE_SET_1 => { self.state.mode_1 = data; },
|
reg::MODE_SET_1 => { self.state.mode_1 = data; },
|
||||||
REG_MODE_SET_2 => {
|
reg::MODE_SET_2 => {
|
||||||
self.state.mode_2 = data;
|
self.state.mode_2 = data;
|
||||||
self.state.update_screen_size();
|
self.state.update_screen_size();
|
||||||
},
|
},
|
||||||
REG_SCROLL_A_ADDR => { self.state.scroll_a_addr = (data as usize) << 10; },
|
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::WINDOW_ADDR => { self.state.window_addr = (data as usize) << 10; },
|
||||||
REG_SCROLL_B_ADDR => { self.state.scroll_b_addr = (data as usize) << 13; },
|
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::SPRITES_ADDR => { self.state.sprites_addr = (data as usize) << 9; },
|
||||||
REG_BACKGROUND => { self.state.background = data; },
|
reg::BACKGROUND => { self.state.background = data; },
|
||||||
REG_H_INTERRUPT => { self.state.h_int_lines = data; },
|
reg::H_INTERRUPT => { self.state.h_int_lines = data; },
|
||||||
REG_MODE_SET_3 => { self.state.mode_3 = data; },
|
reg::MODE_SET_3 => { self.state.mode_3 = data; },
|
||||||
REG_MODE_SET_4 => {
|
reg::MODE_SET_4 => {
|
||||||
self.state.mode_4 = data;
|
self.state.mode_4 = data;
|
||||||
self.state.update_screen_size();
|
self.state.update_screen_size();
|
||||||
},
|
},
|
||||||
REG_HSCROLL_ADDR => { self.state.hscroll_addr = (data as usize) << 10; },
|
reg::HSCROLL_ADDR => { self.state.hscroll_addr = (data as usize) << 10; },
|
||||||
REG_AUTO_INCREMENT => { self.state.memory.transfer_auto_inc = data as u32; },
|
reg::AUTO_INCREMENT => { self.state.memory.transfer_auto_inc = data as u32; },
|
||||||
REG_SCROLL_SIZE => {
|
reg::SCROLL_SIZE => {
|
||||||
let h = decode_scroll_size(data & 0x03);
|
let h = decode_scroll_size(data & 0x03);
|
||||||
let v = decode_scroll_size((data >> 4) & 0x03);
|
let v = decode_scroll_size((data >> 4) & 0x03);
|
||||||
self.state.scroll_size = (h, v);
|
self.state.scroll_size = (h, v);
|
||||||
},
|
},
|
||||||
REG_WINDOW_H_POS => {
|
reg::WINDOW_H_POS => {
|
||||||
self.state.window_values.0 = data;
|
self.state.window_values.0 = data;
|
||||||
self.state.update_window_position();
|
self.state.update_window_position();
|
||||||
},
|
},
|
||||||
REG_WINDOW_V_POS => {
|
reg::WINDOW_V_POS => {
|
||||||
self.state.window_values.1 = data;
|
self.state.window_values.1 = data;
|
||||||
self.state.update_window_position();
|
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_count = (self.state.memory.transfer_count & 0xFF00) | data as u32;
|
||||||
self.state.memory.transfer_remain = self.state.memory.transfer_count;
|
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_count = (self.state.memory.transfer_count & 0x00FF) | ((data as u32) << 8);
|
||||||
self.state.memory.transfer_remain = self.state.memory.transfer_count;
|
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);
|
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);
|
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 };
|
let mask = if (data & 0x80) == 0 { 0x7F } else { 0x3F };
|
||||||
self.state.memory.transfer_bits = data & 0xC0;
|
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);
|
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 {
|
} else {
|
||||||
self.state.memory.write_control_port(data)?;
|
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/";
|
const DEFAULT_HARTE_TESTS: &str = "tests/ProcessorTests/680x0/68000/v1/";
|
||||||
|
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::fmt::Debug;
|
use std::fmt::{Debug, UpperHex};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
|
@ -157,11 +157,14 @@ fn init_execute_test(cputype: M68kType, state: &TestState) -> Result<(M68k, Syst
|
||||||
Ok((cpu, system))
|
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 {
|
if actual == expected {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} 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)
|
* 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
|
* 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
|
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 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 a means of storing different kinds of buses?
|
||||||
* should you make buses hide their RcRefCell?
|
* 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
|
* 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…
Reference in New Issue
Block a user