Add a few unofficial instructions

This commit is contained in:
Jan Bujak 2017-12-31 15:09:41 +01:00
parent 8489c6388a
commit b915572ccc
3 changed files with 100 additions and 19 deletions

View file

@ -167,3 +167,18 @@
0x8A R txa reg_x mov2reg( A )
0x9A R txs _ txs()
0x98 R tya reg_y mov2reg( A )
# Unofficial opcodes.
0xA7 R lax abs_zp mov2reg( A ); mov2reg( X )
0xB7 R lax addy_zp mov2reg( A ); mov2reg( X )
0xA3 R lax indirect_indexed mov2reg( A ); mov2reg( X )
0xB3 R lax indexed_indirect mov2reg( A ); mov2reg( X )
0xAF R lax abs mov2reg( A ); mov2reg( X )
0xBF R lax addy mov2reg( A ); mov2reg( X )
0x87 W sax abs_zp reg2mem_and( A, X )
0x97 W sax addx_zp reg2mem_and( A, X )
0x83 W sax indirect_indexed reg2mem_and( A, X )
0x8F W sax abs reg2mem_and( A, X )
# Alternative name: SBX, SAX
0xCB R axs imm8 axs()

View file

@ -343,6 +343,11 @@ impl fmt::Debug for Opcode {
TXA => write!( fmt, "A <- X" ),
TXS => write!( fmt, "SP <- X" ),
TYA => write!( fmt, "A <- Y" ),
// Unofficial instructions.
LAX( arg ) => write!( fmt, "A, X <- {:?}", arg ),
SAX( arg ) => write!( fmt, "{:?} <- A & X", arg ),
AXS( arg ) => write!( fmt, "X <- (A & X) - {:?}", arg ),
UNK( opc ) => write!( fmt, "UNK [{:02X}]", opc )
}
}
@ -520,6 +525,27 @@ trait Private: Sized + Context {
Ok( EmulationStatus::Normal )
}
fn reg2mem_and( &mut self, src_1: Register8, src_2: Register8 ) -> Result< EmulationStatus, EmulationError > {
let value_1 = match src_1 {
A => self.state().a,
X => self.state().x,
Y => self.state().y,
_ => unsafe { fast_unreachable!() }
};
let value_2 = match src_2 {
A => self.state().a,
X => self.state().x,
Y => self.state().y,
_ => unsafe { fast_unreachable!() }
};
let value = value_1 & value_2;
self.write_to_operand( value );
Ok( EmulationStatus::Normal )
}
fn txs( &mut self ) -> Result< EmulationStatus, EmulationError > {
self.state_mut().sp = self.state().x;
Ok( EmulationStatus::Normal )
@ -897,6 +923,19 @@ trait Private: Sized + Context {
Err( EmulationError::InvalidInstruction( self.state().pc, self.state().decoded.opcode ) )
}
/* UNOFFICIAL INSTRUCTIONS */
fn axs( &mut self ) -> Result< EmulationStatus, EmulationError > {
let value = self.state().a & self.state().x;
let diff = ( value as u16 ).wrapping_sub( self.state().decoded.operand as u16 );
self.set_flags( StatusFlag::Carry, diff < 0x100 );
self.set_SZ( diff as u8 );
self.state_mut().x = diff as u8;
Ok( EmulationStatus::Normal )
}
/* OTHER */
fn reset( &mut self ) {
self.dummy_fetch( 0x00FF );

View file

@ -62,6 +62,9 @@ macro_rules! decoding_logic {
TXA,
TXS,
TYA,
LAX( Location ),
SAX( Location ),
AXS( u8 ),
UNK( u8 )
}
@ -144,19 +147,23 @@ macro_rules! decoding_logic {
0x7D => ADC( Indexed( X, arg16 ) ),
0x7E => ROR( Indexed( X, arg16 ) ),
0x81 => STA( IndirectIndexed( arg_lo ) ),
0x83 => SAX( IndirectIndexed( arg_lo ) ),
0x84 => STY( AbsZP( arg_lo ) ),
0x85 => STA( AbsZP( arg_lo ) ),
0x86 => STX( AbsZP( arg_lo ) ),
0x87 => SAX( AbsZP( arg_lo ) ),
0x88 => DEY,
0x8A => TXA,
0x8C => STY( Abs( arg16 ) ),
0x8D => STA( Abs( arg16 ) ),
0x8E => STX( Abs( arg16 ) ),
0x8F => SAX( Abs( arg16 ) ),
0x90 => BCC( arg_lo ),
0x91 => STA( IndexedIndirect( arg_lo ) ),
0x94 => STY( IndexedZP( X, arg_lo ) ),
0x95 => STA( IndexedZP( X, arg_lo ) ),
0x96 => STX( IndexedZP( Y, arg_lo ) ),
0x97 => SAX( IndexedZP( X, arg_lo ) ),
0x98 => TYA,
0x99 => STA( Indexed( Y, arg16 ) ),
0x9A => TXS,
@ -164,26 +171,32 @@ macro_rules! decoding_logic {
0xA0 => LDY( Imm8( arg_lo ) ),
0xA1 => LDA( IndirectIndexed( arg_lo ) ),
0xA2 => LDX( Imm8( arg_lo ) ),
0xA3 => LAX( IndirectIndexed( arg_lo ) ),
0xA4 => LDY( AbsZP( arg_lo ) ),
0xA5 => LDA( AbsZP( arg_lo ) ),
0xA6 => LDX( AbsZP( arg_lo ) ),
0xA7 => LAX( AbsZP( arg_lo ) ),
0xA8 => TAY,
0xA9 => LDA( Imm8( arg_lo ) ),
0xAA => TAX,
0xAC => LDY( Abs( arg16 ) ),
0xAD => LDA( Abs( arg16 ) ),
0xAE => LDX( Abs( arg16 ) ),
0xAF => LAX( Abs( arg16 ) ),
0xB0 => BCS( arg_lo ),
0xB1 => LDA( IndexedIndirect( arg_lo ) ),
0xB3 => LAX( IndexedIndirect( arg_lo ) ),
0xB4 => LDY( IndexedZP( X, arg_lo ) ),
0xB5 => LDA( IndexedZP( X, arg_lo ) ),
0xB6 => LDX( IndexedZP( Y, arg_lo ) ),
0xB7 => LAX( IndexedZP( Y, arg_lo ) ),
0xB8 => CLV,
0xB9 => LDA( Indexed( Y, arg16 ) ),
0xBA => TSX,
0xBC => LDY( Indexed( X, arg16 ) ),
0xBD => LDA( Indexed( X, arg16 ) ),
0xBE => LDX( Indexed( Y, arg16 ) ),
0xBF => LAX( Indexed( Y, arg16 ) ),
0xC0 => CPY( Imm8( arg_lo ) ),
0xC1 => CMP( IndirectIndexed( arg_lo ) ),
0xC4 => CPY( AbsZP( arg_lo ) ),
@ -192,6 +205,7 @@ macro_rules! decoding_logic {
0xC8 => INY,
0xC9 => CMP( Imm8( arg_lo ) ),
0xCA => DEX,
0xCB => AXS( arg_lo ),
0xCC => CPY( Abs( arg16 ) ),
0xCD => CMP( Abs( arg16 ) ),
0xCE => DEC( Abs( arg16 ) ),
@ -422,6 +436,19 @@ macro_rules! decoding_logic {
cpu.txs()
}
fn exec_mov2reg_a_mov2reg_x< T: Private >( cpu: &mut T ) -> Result< EmulationStatus, EmulationError > {
cpu.mov2reg( A )?;
cpu.mov2reg( X )
}
fn exec_reg2mem_and_a_x< T: Private >( cpu: &mut T ) -> Result< EmulationStatus, EmulationError > {
cpu.reg2mem_and( A, X )
}
fn exec_axs< T: Private >( cpu: &mut T ) -> Result< EmulationStatus, EmulationError > {
cpu.axs()
}
fn instruction_for_opcode< T: Private >( opcode: u8 ) -> fn( &mut T ) -> Result< EmulationStatus, EmulationError > {
match opcode {
0 => exec_brk,
@ -555,11 +582,11 @@ macro_rules! decoding_logic {
128 => exec_unk,
129 => exec_reg2mem_a,
130 => exec_unk,
131 => exec_unk,
131 => exec_reg2mem_and_a_x,
132 => exec_reg2mem_y,
133 => exec_reg2mem_a,
134 => exec_reg2mem_x,
135 => exec_unk,
135 => exec_reg2mem_and_a_x,
136 => exec_incdec_neg_1,
137 => exec_unk,
138 => exec_mov2reg_a,
@ -567,7 +594,7 @@ macro_rules! decoding_logic {
140 => exec_reg2mem_y,
141 => exec_reg2mem_a,
142 => exec_reg2mem_x,
143 => exec_unk,
143 => exec_reg2mem_and_a_x,
144 => exec_branch_statusflag_carry_false,
145 => exec_reg2mem_a,
146 => exec_unk,
@ -575,7 +602,7 @@ macro_rules! decoding_logic {
148 => exec_reg2mem_y,
149 => exec_reg2mem_a,
150 => exec_reg2mem_x,
151 => exec_unk,
151 => exec_reg2mem_and_a_x,
152 => exec_mov2reg_a,
153 => exec_reg2mem_a,
154 => exec_txs,
@ -587,11 +614,11 @@ macro_rules! decoding_logic {
160 => exec_mov2reg_y,
161 => exec_mov2reg_a,
162 => exec_mov2reg_x,
163 => exec_unk,
163 => exec_mov2reg_a_mov2reg_x,
164 => exec_mov2reg_y,
165 => exec_mov2reg_a,
166 => exec_mov2reg_x,
167 => exec_unk,
167 => exec_mov2reg_a_mov2reg_x,
168 => exec_mov2reg_y,
169 => exec_mov2reg_a,
170 => exec_mov2reg_x,
@ -599,15 +626,15 @@ macro_rules! decoding_logic {
172 => exec_mov2reg_y,
173 => exec_mov2reg_a,
174 => exec_mov2reg_x,
175 => exec_unk,
175 => exec_mov2reg_a_mov2reg_x,
176 => exec_branch_statusflag_carry_true,
177 => exec_mov2reg_a,
178 => exec_unk,
179 => exec_unk,
179 => exec_mov2reg_a_mov2reg_x,
180 => exec_mov2reg_y,
181 => exec_mov2reg_a,
182 => exec_mov2reg_x,
183 => exec_unk,
183 => exec_mov2reg_a_mov2reg_x,
184 => exec_clr_statusflag_overflow,
185 => exec_mov2reg_a,
186 => exec_mov2reg_x,
@ -615,7 +642,7 @@ macro_rules! decoding_logic {
188 => exec_mov2reg_y,
189 => exec_mov2reg_a,
190 => exec_mov2reg_x,
191 => exec_unk,
191 => exec_mov2reg_a_mov2reg_x,
192 => exec_compare_y,
193 => exec_compare_a,
194 => exec_unk,
@ -627,7 +654,7 @@ macro_rules! decoding_logic {
200 => exec_incdec_1,
201 => exec_compare_a,
202 => exec_incdec_neg_1,
203 => exec_unk,
203 => exec_axs,
204 => exec_compare_y,
205 => exec_compare_a,
206 => exec_incdec_neg_1,
@ -775,16 +802,16 @@ macro_rules! decoding_logic {
0x80, 0x00, 0x87, 0x80, 0x00, 0x41, 0x41, 0x80,
0x00, 0x45, 0x80, 0x80, 0x80, 0x4B, 0x4B, 0x80,
0x80, 0x54, 0x80, 0x80, 0x80, 0x4C, 0x6C, 0x80,
0x80, 0x26, 0x80, 0x80, 0x02, 0x02, 0x02, 0x80,
0x97, 0x80, 0x8F, 0x80, 0x01, 0x01, 0x01, 0x80,
0x00, 0x25, 0x80, 0x80, 0x0B, 0x0B, 0x13, 0x80,
0x80, 0x26, 0x80, 0x06, 0x02, 0x02, 0x02, 0x02,
0x97, 0x80, 0x8F, 0x80, 0x01, 0x01, 0x01, 0x01,
0x00, 0x25, 0x80, 0x80, 0x0B, 0x0B, 0x13, 0x0B,
0x97, 0x34, 0x80, 0x80, 0x80, 0x2C, 0x80, 0x80,
0x00, 0x46, 0x00, 0x80, 0x42, 0x42, 0x42, 0x80,
0x87, 0x00, 0x87, 0x80, 0x41, 0x41, 0x41, 0x80,
0x00, 0x45, 0x80, 0x80, 0x4B, 0x4B, 0x53, 0x80,
0x80, 0x54, 0x9F, 0x80, 0x4C, 0x4C, 0x54, 0x80,
0x00, 0x46, 0x00, 0x46, 0x42, 0x42, 0x42, 0x42,
0x87, 0x00, 0x87, 0x80, 0x41, 0x41, 0x41, 0x41,
0x00, 0x45, 0x80, 0x45, 0x4B, 0x4B, 0x53, 0x53,
0x80, 0x54, 0x9F, 0x80, 0x4C, 0x4C, 0x54, 0x54,
0x00, 0x46, 0x80, 0x80, 0x42, 0x42, 0x42, 0x80,
0x97, 0x00, 0x8F, 0x80, 0x41, 0x41, 0x41, 0x80,
0x97, 0x00, 0x8F, 0x00, 0x41, 0x41, 0x41, 0x80,
0x00, 0x45, 0x80, 0x80, 0x80, 0x4B, 0x4B, 0x80,
0x80, 0x54, 0x80, 0x80, 0x80, 0x4C, 0x6C, 0x80,
0x00, 0x46, 0x80, 0x80, 0x42, 0x42, 0x42, 0x80,