2019-04-13 20:00:37 +00:00
# include "state.h"
# include "cpu.h"
2019-04-13 21:59:48 +00:00
# include "opcodes.h"
# include <stdio.h>
2019-04-14 10:39:56 +00:00
# include <memory.h>
2019-04-14 11:24:02 +00:00
# include <stdlib.h>
2019-04-13 20:00:37 +00:00
void * unimplemented_instruction ( State6502 * state ) {
printf ( " Error: unimplemented instruction \n " ) ;
exit ( 1 ) ;
}
2019-04-19 08:34:07 +00:00
int is_negative ( byte value ) {
return ( ( 1 < < 7 ) & value ) ! = 0 ;
}
2019-04-20 06:49:28 +00:00
void set_z_flag ( State6502 * state , byte value ) {
state - > flags . z = value = = 0 ;
}
2019-04-19 08:34:07 +00:00
void set_NV_flags ( State6502 * state , byte value ) {
2019-04-14 21:40:53 +00:00
//N flag
2019-04-19 08:34:07 +00:00
state - > flags . n = is_negative ( value ) ;
2019-04-14 21:40:53 +00:00
//TODO implement NV flags
}
void set_NZ_flags ( State6502 * state , byte value ) {
2019-04-20 06:49:28 +00:00
set_z_flag ( state , value ) ;
2019-04-14 21:40:53 +00:00
//N flag
2019-04-19 08:34:07 +00:00
state - > flags . n = is_negative ( value ) ;
2019-04-13 21:59:48 +00:00
}
2019-04-14 21:40:53 +00:00
void clear_flags ( State6502 * state ) {
2019-04-16 20:46:28 +00:00
state - > flags . b =
state - > flags . c =
state - > flags . d =
state - > flags . i =
state - > flags . n =
state - > flags . v =
state - > flags . z = 0 ;
state - > flags . pad = 1 ; //unused is supposed to be 1
2019-04-13 21:59:48 +00:00
}
2019-04-14 21:40:53 +00:00
void clear_state ( State6502 * state ) {
2019-04-13 21:59:48 +00:00
state - > a = 0 ;
state - > x = 0 ;
state - > y = 0 ;
state - > pc = 0 ;
state - > sp = 0 ;
clear_flags ( state ) ;
state - > running = 1 ;
}
2019-04-14 21:40:53 +00:00
byte pop_byte ( State6502 * state ) {
2019-04-13 21:59:48 +00:00
return state - > memory [ state - > pc + + ] ;
}
2019-04-16 20:46:28 +00:00
void push_byte_to_stack ( State6502 * state , byte value ) {
//stack located between $0100 to $01FF
state - > memory [ STACK_HOME + state - > sp - - ] = value ;
}
byte pop_byte_from_stack ( State6502 * state ) {
2019-04-19 08:34:07 +00:00
return state - > memory [ STACK_HOME + + + ( state - > sp ) ] ;
2019-04-16 20:46:28 +00:00
}
2019-04-13 21:59:48 +00:00
//bitwise or with accumulator
2019-04-14 21:40:53 +00:00
void ORA ( State6502 * state , byte operand ) {
2019-04-13 23:51:50 +00:00
byte result = state - > a | operand ;
2019-04-13 21:59:48 +00:00
set_NV_flags ( state , result ) ;
2019-04-13 23:51:50 +00:00
state - > a = result ;
}
2019-04-14 18:45:24 +00:00
//bitwise and with accumulator
2019-04-14 21:40:53 +00:00
void AND ( State6502 * state , byte operand ) {
2019-04-14 18:45:24 +00:00
byte result = state - > a & operand ;
set_NV_flags ( state , result ) ;
state - > a = result ;
}
2019-04-13 23:51:50 +00:00
//load accumulator
2019-04-14 21:40:53 +00:00
void LDA ( State6502 * state , byte operand ) {
2019-04-13 23:51:50 +00:00
state - > a = operand ;
set_NV_flags ( state , state - > a ) ;
}
2019-04-14 21:40:53 +00:00
void LDX ( State6502 * state , byte operand ) {
2019-04-14 20:04:16 +00:00
state - > x = operand ;
set_NV_flags ( state , state - > x ) ;
}
2019-04-14 21:40:53 +00:00
void LDY ( State6502 * state , byte operand ) {
2019-04-14 20:20:32 +00:00
state - > y = operand ;
set_NV_flags ( state , state - > y ) ;
}
2019-04-15 22:09:55 +00:00
void STA ( State6502 * state , word address ) {
state - > memory [ address ] = state - > a ;
}
2019-04-14 21:40:53 +00:00
void STX ( State6502 * state , word address ) {
2019-04-14 21:05:37 +00:00
state - > memory [ address ] = state - > x ;
}
2019-04-14 21:40:53 +00:00
void STY ( State6502 * state , word address ) {
2019-04-14 21:05:37 +00:00
state - > memory [ address ] = state - > y ;
}
2019-04-15 21:34:21 +00:00
void INC ( State6502 * state , word address ) {
state - > memory [ address ] + = 1 ;
set_NZ_flags ( state , state - > memory [ address ] ) ;
}
void DEC ( State6502 * state , word address ) {
state - > memory [ address ] - = 1 ;
set_NZ_flags ( state , state - > memory [ address ] ) ;
}
2019-04-15 22:03:48 +00:00
void EOR ( State6502 * state , byte operand ) {
state - > a = state - > a ^ operand ;
set_NV_flags ( state , state - > a ) ;
}
2019-04-17 17:46:56 +00:00
void JMP ( State6502 * state , word address ) {
state - > pc = address ;
}
2019-04-19 09:38:52 +00:00
void SBC ( State6502 * state , byte operand ) {
//subtract operand from A
word operand_word = operand ;
//borrow 0x100 from the carry flag if set
if ( state - > flags . c = = 1 ) {
operand_word + = 0x100 ;
state - > flags . c = 0 ;
}
word result = state - > a - operand_word ;
state - > a - = result ;
state - > flags . n = is_negative ( state - > a ) ;
state - > flags . z = state - > a = = 0 ;
2019-04-21 07:28:07 +00:00
//todo set overflow flag
//state->flags.v = ??? ;
}
void ADC ( State6502 * state , byte operand ) {
//add operand to A
word result_word = operand + state - > a + state - > flags . c ? 1 : 0 ;
state - > a = state - > a & 0xFF ;
state - > flags . n = is_negative ( state - > a ) ;
state - > flags . z = state - > a = = 0 ;
state - > flags . c = result_word > 0xFF ;
//todo set overflow flag if the result's sign would change - the result doesn't fit into a signed byte
//!((M^N) & 0x80) && ((M^result) & 0x80) - there is overflow if the inputs do not have different signs and the input sign is different from the output sign
//state->flags.v = ??? ;
2019-04-19 09:38:52 +00:00
}
2019-04-19 08:34:07 +00:00
void cmp_internal ( State6502 * state , byte register_value , byte operand ) {
//set carry flag if A >= M
state - > flags . c = register_value > = operand ;
//set zero flag if A == M
state - > flags . z = register_value = = operand ;
//set negative flag if A - M is negative
state - > flags . n = is_negative ( register_value - operand ) ;
}
void CMP ( State6502 * state , byte operand ) {
cmp_internal ( state , state - > a , operand ) ;
}
void CPX ( State6502 * state , byte operand ) {
cmp_internal ( state , state - > x , operand ) ;
}
void CPY ( State6502 * state , byte operand ) {
cmp_internal ( state , state - > y , operand ) ;
}
2019-04-19 09:38:52 +00:00
byte asl ( State6502 * state , byte operand ) {
byte result = operand < < 1 ;
state - > flags . c = operand > 0x80 ;
2019-04-20 06:49:28 +00:00
set_NZ_flags ( state , result ) ;
2019-04-19 09:38:52 +00:00
return result ;
}
void ASL_A ( State6502 * state ) {
state - > a = asl ( state , state - > a ) ;
}
void ASL_MEM ( State6502 * state , word address ) {
byte operand = state - > memory [ address ] ;
state - > memory [ address ] = operand ;
state - > memory [ address ] = asl ( state , operand ) ;
}
2019-04-19 09:44:20 +00:00
byte lsr ( State6502 * state , byte operand ) {
byte result = operand > > 1 ;
state - > flags . c = ( operand & 0x01 ) ! = 0 ;
2019-04-20 06:49:28 +00:00
set_NZ_flags ( state , result ) ;
2019-04-19 09:44:20 +00:00
return result ;
}
void LSR_A ( State6502 * state ) {
state - > a = lsr ( state , state - > a ) ;
}
void LSR_MEM ( State6502 * state , word address ) {
byte operand = state - > memory [ address ] ;
state - > memory [ address ] = lsr ( state , operand ) ;
}
2019-04-19 09:55:17 +00:00
byte rol ( State6502 * state , byte operand ) {
word result_word = ( operand < < 1 ) | state - > flags . c ;
state - > flags . c = result_word > 0xFF ;
byte result = result_word & 0xFF ;
2019-04-20 06:49:28 +00:00
set_NZ_flags ( state , result ) ;
2019-04-19 09:55:17 +00:00
return result ;
}
void ROL_A ( State6502 * state ) {
state - > a = rol ( state , state - > a ) ;
}
void ROL_MEM ( State6502 * state , word address ) {
byte operand = state - > memory [ address ] ;
state - > memory [ address ] = rol ( state , operand ) ;
}
2019-04-20 06:49:28 +00:00
byte ror ( State6502 * state , byte operand ) {
word result_word = ( operand > > 1 ) | ( state - > flags . c < < 7 ) ;
state - > flags . c = ( result_word & 0x01 ) ! = 0 ;
byte result = result_word & 0xFF ;
set_NZ_flags ( state , result ) ;
return result ;
}
void ROR_A ( State6502 * state ) {
state - > a = rol ( state , state - > a ) ;
}
void ROR_MEM ( State6502 * state , word address ) {
byte operand = state - > memory [ address ] ;
state - > memory [ address ] = ror ( state , operand ) ;
}
2019-04-14 21:40:53 +00:00
word pop_word ( State6502 * state ) {
2019-04-13 23:51:50 +00:00
byte low = pop_byte ( state ) ;
byte high = pop_byte ( state ) ;
word result = ( high < < 8 ) | low ;
return result ;
}
2019-04-14 09:55:35 +00:00
word read_word ( State6502 * state , word address ) {
2019-04-14 09:49:24 +00:00
return state - > memory [ address ] | state - > memory [ address + 1 ] < < 8 ;
2019-04-13 21:59:48 +00:00
}
2019-04-14 21:40:53 +00:00
word get_address_zero_page ( State6502 * state ) {
2019-04-14 21:05:37 +00:00
return pop_byte ( state ) ;
}
2019-04-14 18:45:24 +00:00
byte get_byte_zero_page ( State6502 * state ) {
2019-04-14 19:25:23 +00:00
//8 bit addressing, only the first 256 bytes of the memory
2019-04-15 21:34:21 +00:00
return state - > memory [ get_address_zero_page ( state ) ] ;
2019-04-14 18:45:24 +00:00
}
2019-04-14 21:40:53 +00:00
word get_address_zero_page_x ( State6502 * state ) {
2019-04-14 21:05:37 +00:00
//address is zero page, so wraparound byte
byte address = pop_byte ( state ) + state - > x ;
return address ;
}
2019-04-14 18:45:24 +00:00
byte get_byte_zero_page_x ( State6502 * state ) {
2019-04-15 21:34:21 +00:00
return state - > memory [ get_address_zero_page_x ( state ) ] ;
2019-04-14 18:45:24 +00:00
}
2019-04-14 21:40:53 +00:00
word get_address_zero_page_y ( State6502 * state ) {
2019-04-14 21:05:37 +00:00
//address is zero page, so wraparound byte
2019-04-14 18:45:24 +00:00
byte address = pop_byte ( state ) + state - > y ;
2019-04-14 21:05:37 +00:00
return address ;
}
byte get_byte_zero_page_y ( State6502 * state ) {
return state - > memory [ get_address_zero_page_y ( state ) ] ;
}
word get_address_absolute ( State6502 * state ) {
//absolute indexed, 16 bits
word address = pop_word ( state ) ;
return address ;
2019-04-14 18:45:24 +00:00
}
byte get_byte_absolute ( State6502 * state )
{
2019-04-14 19:25:23 +00:00
//absolute indexed, 16 bits
2019-04-14 21:05:37 +00:00
return state - > memory [ get_address_absolute ( state ) ] ;
2019-04-14 18:45:24 +00:00
}
2019-04-15 22:03:48 +00:00
word get_address_absolute_x ( State6502 * state ) {
2019-04-14 19:25:23 +00:00
//absolute added with the contents of x register
2019-04-14 18:45:24 +00:00
word address = pop_word ( state ) + state - > x ;
2019-04-15 21:34:21 +00:00
return address ;
}
byte get_byte_absolute_x ( State6502 * state ) {
return state - > memory [ get_address_absolute_x ( state ) ] ;
}
2019-04-15 22:03:48 +00:00
word get_address_absolute_y ( State6502 * state ) {
2019-04-15 21:34:21 +00:00
//absolute added with the contents of x register
word address = pop_word ( state ) + state - > y ;
return address ;
2019-04-14 18:45:24 +00:00
}
byte get_byte_absolute_y ( State6502 * state ) {
2019-04-14 19:25:23 +00:00
//absolute added with the contents of y register
2019-04-15 21:34:21 +00:00
return state - > memory [ get_address_absolute_y ( state ) ] ;
2019-04-14 18:45:24 +00:00
}
2019-04-17 17:46:56 +00:00
word get_address_indirect_jmp ( State6502 * state ) {
//AN INDIRECT JUMP MUST NEVER USE A VECTOR BEGINNING ON THE LAST BYTE OF A PAGE
2019-04-19 08:34:07 +00:00
word indirect_address = pop_word ( state ) ;
2019-04-17 17:46:56 +00:00
if ( ( indirect_address & 0xFF ) = = 0xFF ) {
//avoid crossing the page boundary
2019-04-19 08:34:07 +00:00
return state - > memory [ indirect_address ] | state - > memory [ indirect_address - 0xFF ] < < 8 ;
2019-04-17 17:46:56 +00:00
}
else {
return read_word ( state , indirect_address ) ;
}
}
2019-04-15 22:09:55 +00:00
word get_address_indirect_x ( State6502 * state ) {
2019-04-14 19:25:23 +00:00
//pre-indexed indirect with the X register
//zero-page address is added to x register
byte indirect_address = pop_byte ( state ) + state - > x ;
//pointing to address of a word holding the address of the operand
word address = read_word ( state , indirect_address ) ;
2019-04-15 22:09:55 +00:00
return address ;
2019-04-14 19:25:23 +00:00
}
2019-04-15 22:09:55 +00:00
byte get_byte_indirect_x ( State6502 * state ) {
//pre-indexed indirect with the X register
return state - > memory [ get_address_indirect_x ( state ) ] ;
}
word get_address_indirect_y ( State6502 * state ) {
2019-04-14 19:25:23 +00:00
//post-indexed indirect
//zero-page address as an argument
byte indirect_address = pop_byte ( state ) ;
//the address and the following byte is read as a word, adding Y register
word address = read_word ( state , indirect_address ) + state - > y ;
2019-04-15 22:09:55 +00:00
return address ;
}
byte get_byte_indirect_y ( State6502 * state ) {
return state - > memory [ get_address_indirect_y ( state ) ] ;
2019-04-14 19:25:23 +00:00
}
2019-04-13 21:59:48 +00:00
int emulate_6502_op ( State6502 * state ) {
byte * opcode = & state - > memory [ state - > pc + + ] ;
2019-04-13 20:00:37 +00:00
switch ( * opcode ) {
2019-04-21 07:28:07 +00:00
case ADC_IMM : ADC ( state , pop_byte ( state ) ) ; break ;
case ADC_ZP : ADC ( state , get_byte_zero_page ( state ) ) ; break ;
case ADC_ZPX : ADC ( state , get_byte_zero_page_x ( state ) ) ; break ;
case ADC_ABS : ADC ( state , get_byte_absolute ( state ) ) ; break ;
case ADC_ABSX : ADC ( state , get_byte_absolute_x ( state ) ) ; break ;
case ADC_ABSY : ADC ( state , get_byte_absolute_y ( state ) ) ; break ;
case ADC_INDX : ADC ( state , get_byte_indirect_x ( state ) ) ; break ;
case ADC_INDY : ADC ( state , get_byte_indirect_y ( state ) ) ; break ;
2019-04-14 18:45:24 +00:00
case AND_IMM : AND ( state , pop_byte ( state ) ) ; break ;
case AND_ZP : AND ( state , get_byte_zero_page ( state ) ) ; break ;
case AND_ZPX : AND ( state , get_byte_zero_page_x ( state ) ) ; break ;
case AND_ABS : AND ( state , get_byte_absolute ( state ) ) ; break ;
case AND_ABSX : AND ( state , get_byte_absolute_x ( state ) ) ; break ;
case AND_ABSY : AND ( state , get_byte_absolute_y ( state ) ) ; break ;
2019-04-14 19:25:23 +00:00
case AND_INDX : AND ( state , get_byte_indirect_x ( state ) ) ; break ;
case AND_INDY : AND ( state , get_byte_indirect_y ( state ) ) ; break ;
2019-04-19 09:38:52 +00:00
case ASL_ACC : ASL_A ( state ) ; break ;
case ASL_ZP : ASL_MEM ( state , get_address_zero_page ( state ) ) ; break ;
case ASL_ZPX : ASL_MEM ( state , get_address_zero_page_x ( state ) ) ; break ;
case ASL_ABS : ASL_MEM ( state , get_address_absolute ( state ) ) ; break ;
case ASL_ABSX : ASL_MEM ( state , get_address_absolute_x ( state ) ) ; break ;
2019-04-14 13:15:15 +00:00
case BCC_REL : unimplemented_instruction ( state ) ; break ;
case BCS_REL : unimplemented_instruction ( state ) ; break ;
case BEQ_REL : unimplemented_instruction ( state ) ; break ;
case BMI_REL : unimplemented_instruction ( state ) ; break ;
case BNE_REL : unimplemented_instruction ( state ) ; break ;
case BPL_REL : unimplemented_instruction ( state ) ; break ;
case BVC_REL : unimplemented_instruction ( state ) ; break ;
case BVS_REL : unimplemented_instruction ( state ) ; break ;
case BIT_ZP : unimplemented_instruction ( state ) ; break ;
case BIT_ABS : unimplemented_instruction ( state ) ; break ;
2019-04-14 07:38:09 +00:00
case BRK : state - > running = 0 ;
2019-04-13 23:51:50 +00:00
state - > flags . b = 1 ;
break ; //BRK
2019-04-15 21:44:07 +00:00
case CLC : state - > flags . c = 0 ; break ;
case CLD : state - > flags . d = 0 ; break ;
case CLI : state - > flags . i = 0 ; break ;
case CLV : state - > flags . v = 0 ; break ;
2019-04-13 23:51:50 +00:00
case NOP : break ; //NOP
2019-04-16 20:46:28 +00:00
case PHA : push_byte_to_stack ( state , state - > a ) ; break ; //push accumulator to stack
case PLA : state - > a = pop_byte_from_stack ( state ) ; break ; //pull accumulator from stack
case PHP : {
byte flags_value ;
memcpy ( & flags_value , & state - > flags , sizeof ( Flags ) ) ;
push_byte_to_stack ( state , flags_value ) ;
break ; //push processor status
}
case PLP : {
byte value = pop_byte_from_stack ( state ) ;
memset ( & state - > flags , value , 1 ) ;
break ;
} //pull procesor status
2019-04-14 13:15:15 +00:00
case RTI : unimplemented_instruction ( state ) ; break ;
case RTS : unimplemented_instruction ( state ) ; break ;
2019-04-15 21:44:07 +00:00
case SEC : state - > flags . c = 1 ; break ;
case SED : state - > flags . d = 1 ; break ;
case SEI : state - > flags . i = 1 ; break ;
2019-04-16 20:46:28 +00:00
case TAX : state - > x = state - > a ; set_NZ_flags ( state , state - > x ) ; break ;
case TXA : state - > a = state - > x ; set_NZ_flags ( state , state - > a ) ; break ;
case TAY : state - > y = state - > a ; set_NZ_flags ( state , state - > y ) ; break ;
case TYA : state - > a = state - > y ; set_NZ_flags ( state , state - > a ) ; break ;
2019-04-19 08:34:07 +00:00
case TSX : state - > x = state - > sp ; set_NZ_flags ( state , state - > x ) ; break ;
case TXS : state - > sp = state - > x ; set_NZ_flags ( state , state - > x ) ; break ;
2019-04-19 08:36:14 +00:00
case CMP_IMM : CMP ( state , pop_byte ( state ) ) ; break ; //TODO test
case CMP_ZP : CMP ( state , get_byte_zero_page ( state ) ) ; break ; //TODO test
2019-04-19 08:34:07 +00:00
case CMP_ZPX : CMP ( state , get_byte_zero_page_x ( state ) ) ; break ; //TODO test
2019-04-19 08:36:14 +00:00
case CMP_ABS : CMP ( state , get_byte_absolute ( state ) ) ; break ;
2019-04-19 08:34:07 +00:00
case CMP_ABSX : CMP ( state , get_byte_absolute_x ( state ) ) ; break ; //TODO test
case CMP_ABSY : CMP ( state , get_byte_absolute_y ( state ) ) ; break ; //TODO test
case CMP_INDX : CMP ( state , get_byte_indirect_x ( state ) ) ; break ; //TODO test
case CMP_INDY : CMP ( state , get_byte_indirect_y ( state ) ) ; break ; //TODO test
case CPX_IMM : CPX ( state , pop_byte ( state ) ) ; break ; //TODO test
case CPX_ZP : CPX ( state , get_byte_zero_page ( state ) ) ; break ; //TODO test
case CPX_ABS : CPX ( state , get_byte_absolute ( state ) ) ; break ; //TODO test
case CPY_IMM : CPY ( state , pop_byte ( state ) ) ; break ; //TODO test
case CPY_ZP : CPY ( state , get_byte_zero_page ( state ) ) ; break ; //TODO test
case CPY_ABS : CPY ( state , get_byte_absolute ( state ) ) ; break ; //TODO test
2019-04-15 21:34:21 +00:00
case DEC_ZP : DEC ( state , get_address_zero_page ( state ) ) ; break ;
case DEC_ZPX : DEC ( state , get_address_zero_page_x ( state ) ) ; break ;
case DEC_ABS : DEC ( state , get_address_absolute ( state ) ) ; break ;
case DEC_ABSX : DEC ( state , get_address_absolute_x ( state ) ) ; break ;
2019-04-14 21:40:53 +00:00
case DEX : state - > x - = 1 ; set_NZ_flags ( state , state - > x ) ; break ;
case DEY : state - > y - = 1 ; set_NZ_flags ( state , state - > y ) ; break ;
case INX : state - > x + = 1 ; set_NZ_flags ( state , state - > x ) ; break ;
case INY : state - > y + = 1 ; set_NZ_flags ( state , state - > y ) ; break ;
2019-04-15 22:03:48 +00:00
case EOR_IMM : EOR ( state , pop_byte ( state ) ) ; break ;
case EOR_ZP : EOR ( state , get_byte_zero_page ( state ) ) ; break ;
case EOR_ZPX : EOR ( state , get_byte_zero_page_x ( state ) ) ; break ;
case EOR_ABS : EOR ( state , get_byte_absolute ( state ) ) ; break ;
case EOR_ABSX : EOR ( state , get_byte_absolute_x ( state ) ) ; break ;
case EOR_ABSY : EOR ( state , get_byte_absolute_y ( state ) ) ; break ;
case EOR_INDX : EOR ( state , get_byte_indirect_x ( state ) ) ; break ;
case EOR_INDY : EOR ( state , get_byte_indirect_y ( state ) ) ; break ;
2019-04-15 21:34:21 +00:00
case INC_ZP : INC ( state , get_address_zero_page ( state ) ) ; break ;
case INC_ZPX : INC ( state , get_address_zero_page_x ( state ) ) ; break ;
case INC_ABS : INC ( state , get_address_absolute ( state ) ) ; break ;
case INC_ABSX : INC ( state , get_address_absolute_x ( state ) ) ; break ;
2019-04-17 17:46:56 +00:00
case JMP_ABS : JMP ( state , get_address_absolute ( state ) ) ; break ;
case JMP_IND : JMP ( state , get_address_indirect_jmp ( state ) ) ; break ;
2019-04-14 13:15:15 +00:00
case JSR_ABS : unimplemented_instruction ( state ) ; break ;
2019-04-14 18:45:24 +00:00
case LDA_IMM : LDA ( state , pop_byte ( state ) ) ; break ;
case LDA_ZP : LDA ( state , get_byte_zero_page ( state ) ) ; break ;
case LDA_ZPX : LDA ( state , get_byte_zero_page_x ( state ) ) ; break ;
case LDA_ABS : LDA ( state , get_byte_absolute ( state ) ) ; break ;
case LDA_ABSX : LDA ( state , get_byte_absolute_x ( state ) ) ; break ;
case LDA_ABSY : LDA ( state , get_byte_absolute_y ( state ) ) ; break ;
2019-04-14 19:25:23 +00:00
case LDA_INDX : LDA ( state , get_byte_indirect_x ( state ) ) ; break ;
case LDA_INDY : LDA ( state , get_byte_indirect_y ( state ) ) ; break ;
2019-04-14 20:04:16 +00:00
case LDX_IMM : LDX ( state , pop_byte ( state ) ) ; break ;
case LDX_ZP : LDX ( state , get_byte_zero_page ( state ) ) ; break ;
case LDX_ZPY : LDX ( state , get_byte_zero_page_y ( state ) ) ; break ;
2019-04-14 20:20:32 +00:00
case LDX_ABS : LDX ( state , get_byte_absolute ( state ) ) ; break ;
2019-04-14 20:04:16 +00:00
case LDX_ABSY : LDX ( state , get_byte_absolute_y ( state ) ) ; break ;
2019-04-14 20:20:32 +00:00
case LDY_IMM : LDY ( state , pop_byte ( state ) ) ; break ;
case LDY_ZP : LDY ( state , get_byte_zero_page ( state ) ) ; break ;
case LDY_ZPX : LDY ( state , get_byte_zero_page_x ( state ) ) ; break ;
case LDY_ABS : LDY ( state , get_byte_absolute ( state ) ) ; break ;
case LDY_ABSX : LDY ( state , get_byte_absolute_x ( state ) ) ; break ;
2019-04-19 09:44:20 +00:00
case LSR_ACC : LSR_A ( state ) ; break ;
case LSR_ZP : LSR_MEM ( state , get_address_zero_page ( state ) ) ; break ;
case LSR_ZPX : LSR_MEM ( state , get_address_zero_page_x ( state ) ) ; break ;
case LSR_ABS : LSR_MEM ( state , get_address_absolute ( state ) ) ; break ;
case LSR_ABSX : LSR_MEM ( state , get_address_absolute_x ( state ) ) ; break ;
2019-04-14 18:45:24 +00:00
case ORA_IMM : ORA ( state , pop_byte ( state ) ) ; break ;
case ORA_ZP : ORA ( state , get_byte_zero_page ( state ) ) ; break ;
case ORA_ZPX : ORA ( state , get_byte_zero_page_x ( state ) ) ; break ;
case ORA_ABS : ORA ( state , get_byte_absolute ( state ) ) ; break ;
case ORA_ABSX : ORA ( state , get_byte_absolute_x ( state ) ) ; break ;
case ORA_ABSY : ORA ( state , get_byte_absolute_y ( state ) ) ; break ;
2019-04-14 19:25:23 +00:00
case ORA_INDX : ORA ( state , get_byte_indirect_x ( state ) ) ; break ;
case ORA_INDY : ORA ( state , get_byte_indirect_y ( state ) ) ; break ;
2019-04-19 09:55:17 +00:00
case ROL_ACC : ROL_A ( state ) ; break ;
case ROL_ZP : ROL_MEM ( state , get_address_zero_page ( state ) ) ; break ;
case ROL_ZPX : ROL_MEM ( state , get_address_zero_page_x ( state ) ) ; break ;
case ROL_ABS : ROL_MEM ( state , get_address_absolute ( state ) ) ; break ;
case ROL_ABSX : ROL_MEM ( state , get_address_absolute_x ( state ) ) ; break ;
2019-04-20 06:49:28 +00:00
case ROR_ACC : ROR_A ( state ) ; break ;
case ROR_ZP : ROR_MEM ( state , get_address_zero_page ( state ) ) ; break ;
case ROR_ZPX : ROR_MEM ( state , get_address_zero_page_x ( state ) ) ; break ;
case ROR_ABS : ROR_MEM ( state , get_address_absolute ( state ) ) ; break ;
case ROR_ABSX : ROR_MEM ( state , get_address_absolute_x ( state ) ) ; break ;
2019-04-19 09:38:52 +00:00
case SBC_IMM : SBC ( state , pop_byte ( state ) ) ; break ;
case SBC_ZP : SBC ( state , get_byte_zero_page ( state ) ) ; break ;
case SBC_ZPX : SBC ( state , get_byte_zero_page_x ( state ) ) ; break ;
case SBC_ABS : SBC ( state , get_byte_absolute ( state ) ) ; break ;
case SBC_ABSX : SBC ( state , get_byte_absolute_x ( state ) ) ; break ;
case SBC_ABSY : SBC ( state , get_byte_absolute_y ( state ) ) ; break ;
case SBC_INDX : SBC ( state , get_byte_indirect_x ( state ) ) ; break ;
case SBC_INDY : SBC ( state , get_byte_indirect_y ( state ) ) ; break ;
2019-04-15 22:09:55 +00:00
case STA_ZP : STA ( state , get_address_zero_page ( state ) ) ; break ;
case STA_ZPX : STA ( state , get_address_zero_page_x ( state ) ) ; break ;
case STA_ABS : STA ( state , get_address_absolute ( state ) ) ; break ;
case STA_ABSX : STA ( state , get_address_absolute_x ( state ) ) ; break ;
case STA_ABSY : STA ( state , get_address_absolute_y ( state ) ) ; break ;
case STA_INDX : STA ( state , get_address_indirect_x ( state ) ) ; break ;
case STA_INDY : STA ( state , get_address_indirect_y ( state ) ) ; break ;
2019-04-14 21:05:37 +00:00
case STX_ZP : STX ( state , get_address_zero_page ( state ) ) ; break ;
case STX_ZPY : STX ( state , get_address_zero_page_y ( state ) ) ; break ;
case STX_ABS : STX ( state , get_address_absolute ( state ) ) ; break ;
case STY_ZP : STY ( state , get_address_zero_page ( state ) ) ; break ;
case STY_ZPX : STY ( state , get_address_zero_page_x ( state ) ) ; break ;
case STY_ABS : STY ( state , get_address_absolute ( state ) ) ; break ;
2019-04-14 13:15:15 +00:00
2019-04-13 21:59:48 +00:00
default :
unimplemented_instruction ( state ) ; break ;
2019-04-13 20:00:37 +00:00
}
return 0 ;
2019-04-20 06:49:28 +00:00
}