mirror of
https://github.com/koute/pinky.git
synced 2024-06-01 02:48:08 -04:00
Add a few unofficial instructions
This commit is contained in:
parent
8489c6388a
commit
b915572ccc
|
@ -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()
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue