mirror of
https://github.com/transistorfet/moa.git
synced 2025-01-02 22:29:40 +00:00
Added LDI, LDD, and LDDR instructions for Z80
This commit is contained in:
parent
427c79b7b4
commit
e41970391e
@ -100,6 +100,13 @@ General Options
|
||||
By default, the minifb frontend will scale the window by 2. This can be
|
||||
changed with the `--scale [1,2,4]` option.
|
||||
|
||||
The `-t` or `--threaded` options will run the simulated hardware in a separate
|
||||
thread from the frontend, which will run as fast as possible, faster than
|
||||
real-time. By default, the simulated hardware is run inline with the frontend's
|
||||
update cycle, which is limited to 60Hz. The simulation will be run for 16.6ms of
|
||||
simulated time for each frame the frontend draws. But the simulated time is not
|
||||
accurate and Sega Genesis games will run slower than they should.
|
||||
|
||||
The `-d` or `--debugger` option will make the emulator start the debugger
|
||||
before running. There is a simple built-in debugger for stepping through
|
||||
the rom instructions being emulated. The state of the CPU registers will
|
||||
|
@ -53,7 +53,6 @@ impl Transmutable for Z80 {
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl Z80 {
|
||||
pub fn step_internal(&mut self, system: &System) -> Result<(), Error> {
|
||||
match self.state.status {
|
||||
@ -62,7 +61,6 @@ impl Z80 {
|
||||
Status::Running => {
|
||||
match self.cycle_one(system) {
|
||||
Ok(()) => Ok(()),
|
||||
//Err(Error { err: ErrorType::Processor, native, .. }) => {
|
||||
Err(Error { err: ErrorType::Processor, .. }) => {
|
||||
//self.exception(system, native as u8, false)?;
|
||||
Ok(())
|
||||
@ -80,30 +78,15 @@ impl Z80 {
|
||||
}
|
||||
|
||||
pub fn cycle_one(&mut self, system: &System) -> Result<(), Error> {
|
||||
//self.timer.cycle.start();
|
||||
self.decode_next()?;
|
||||
self.execute_current()?;
|
||||
//self.timer.cycle.end();
|
||||
|
||||
//if (self.timer.cycle.events % 500) == 0 {
|
||||
// println!("{}", self.timer);
|
||||
//}
|
||||
|
||||
//self.check_pending_interrupts(system)?;
|
||||
self.check_breakpoints(system);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode_next(&mut self) -> Result<(), Error> {
|
||||
//self.timer.decode.start();
|
||||
self.decoder.decode_at(&mut self.port, self.state.pc)?;
|
||||
//self.timer.decode.end();
|
||||
|
||||
//if self.debugger.use_tracing {
|
||||
//self.decoder.dump_decoded(&mut self.port);
|
||||
//self.dump_state();
|
||||
//}
|
||||
|
||||
self.state.pc = self.decoder.end;
|
||||
Ok(())
|
||||
}
|
||||
@ -329,24 +312,27 @@ impl Z80 {
|
||||
Direction::ToAcc => { self.state.reg[Register::A as usize] = *addr; },
|
||||
}
|
||||
}
|
||||
//Instruction::LDD => {
|
||||
//},
|
||||
//Instruction::LDDR => {
|
||||
//},
|
||||
//Instruction::LDI => {
|
||||
//},
|
||||
Instruction::LDIR => {
|
||||
Instruction::LDD | Instruction::LDDR | Instruction::LDI | Instruction::LDIR => {
|
||||
let diff = if self.decoder.instruction == Instruction::LDI || self.decoder.instruction == Instruction::LDIR {
|
||||
1
|
||||
} else {
|
||||
-1
|
||||
};
|
||||
|
||||
let src_value = self.get_load_target_value(LoadTarget::IndirectRegByte(RegisterPair::HL))?;
|
||||
self.set_load_target_value(LoadTarget::IndirectRegByte(RegisterPair::DE), src_value)?;
|
||||
self.add_to_regpair(RegisterPair::DE, 1);
|
||||
self.add_to_regpair(RegisterPair::HL, 1);
|
||||
self.add_to_regpair(RegisterPair::DE, diff);
|
||||
self.add_to_regpair(RegisterPair::HL, diff);
|
||||
let count = self.add_to_regpair(RegisterPair::BC, -1);
|
||||
if count != 0 {
|
||||
self.state.pc -= 2;
|
||||
}
|
||||
let mask = (Flags::AddSubtract as u8) | (Flags::HalfCarry as u8) | (Flags::Parity as u8);
|
||||
let parity = if count != 0 { Flags::Parity as u8 } else { 0 };
|
||||
self.set_flags(mask, parity);
|
||||
|
||||
if self.decoder.instruction == Instruction::LDIR || self.decoder.instruction == Instruction::LDDR {
|
||||
if count != 0 {
|
||||
self.state.pc -= 2;
|
||||
}
|
||||
}
|
||||
},
|
||||
Instruction::NEG => {
|
||||
let acc = self.get_register_value(Register::A);
|
||||
|
@ -62,18 +62,19 @@ pub fn build_genesis<H: Host>(host: &mut H, options: SegaGenesisOptions) -> Resu
|
||||
|
||||
// Build the Coprocessor's Bus
|
||||
let bank_register = Signal::new(0);
|
||||
let coproc_bus = Rc::new(RefCell::new(Bus::new()));
|
||||
let coproc_ram = wrap_transmutable(MemoryBlock::new(vec![0; 0x00002000]));
|
||||
let coproc_ym_sound = wrap_transmutable(YM2612::new());
|
||||
let coproc_sn_sound = wrap_transmutable(SN76489::new());
|
||||
let coproc_register = wrap_transmutable(CoprocessorBankRegister::new(bank_register.clone()));
|
||||
let coproc_area = wrap_transmutable(CoprocessorBankArea::new(bank_register, system.bus.clone()));
|
||||
|
||||
let coproc_bus = Rc::new(RefCell::new(Bus::new()));
|
||||
coproc_bus.borrow_mut().insert(0x0000, coproc_ram.clone());
|
||||
coproc_bus.borrow_mut().insert(0x4000, coproc_ym_sound.clone());
|
||||
coproc_bus.borrow_mut().insert(0x6000, coproc_register.clone());
|
||||
coproc_bus.borrow_mut().insert(0x7f11, coproc_sn_sound.clone());
|
||||
coproc_bus.borrow_mut().insert(0x8000, coproc_area);
|
||||
let mut coproc = Z80::new(Z80Type::Z80, 3_579_545, BusPort::new(0, 16, 8, coproc_bus.clone()));
|
||||
let coproc = Z80::new(Z80Type::Z80, 3_579_545, BusPort::new(0, 16, 8, coproc_bus.clone()));
|
||||
let reset = coproc.reset.clone();
|
||||
let bus_request = coproc.bus_request.clone();
|
||||
|
||||
|
3
todo.txt
3
todo.txt
@ -1,4 +1,5 @@
|
||||
|
||||
* add command line arguments to speed up or slow down either the frame rate limiter or the simulated time per frame
|
||||
* currently you need to implement the 1.5ms reset in the genesis controllers
|
||||
* should SharedData be HostData, or something else? I don't think the name is very informative
|
||||
* can you make the connections between things (like memory adapters), be expressed in a way that's more similar to the electrical design?
|
||||
@ -41,7 +42,7 @@ Genesis/Mega Drive:
|
||||
* make tests for each instruction
|
||||
* check all instructions in the docs
|
||||
|
||||
* unimplemented: ABCD, ADDX, BFFFO, BFINS, BKPT, CHK, ILLEGAL, MOVEfromCCR,, RTR, RTD, SBCD, SUBX
|
||||
* unimplemented: ABCD, ADDX, BFFFO, BFINS, BKPT, CHK, ILLEGAL, RTR, RTD, SBCD, SUBX
|
||||
* >=MC68020 undecoded & unimplemented: CALLM, CAS, CAS2, CHK2, CMP2, RTM, PACK, TRAPcc, UNPK
|
||||
|
||||
* add support for MMU
|
||||
|
Loading…
Reference in New Issue
Block a user