mirror of
https://github.com/jborza/emu6502.git
synced 2025-02-19 07:30:57 +00:00
implemented SBC, ASL
This commit is contained in:
parent
1c4e2f45b5
commit
411d4e8241
59
cpu.c
59
cpu.c
@ -127,6 +127,22 @@ void JMP(State6502 * state, word address) {
|
||||
state->pc = address;
|
||||
}
|
||||
|
||||
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;
|
||||
//state->flags.v = ??? ; //
|
||||
}
|
||||
|
||||
void cmp_internal(State6502 * state, byte register_value, byte operand) {
|
||||
//set carry flag if A >= M
|
||||
state->flags.c = register_value >= operand;
|
||||
@ -148,6 +164,23 @@ void CPY(State6502 * state, byte operand) {
|
||||
cmp_internal(state, state->y, operand);
|
||||
}
|
||||
|
||||
byte asl(State6502* state, byte operand) {
|
||||
byte result = operand << 1;
|
||||
state->flags.c = operand > 0x80;
|
||||
set_NV_flags(state, result);
|
||||
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);
|
||||
}
|
||||
|
||||
word pop_word(State6502 * state) {
|
||||
byte low = pop_byte(state);
|
||||
byte high = pop_byte(state);
|
||||
@ -279,11 +312,11 @@ int emulate_6502_op(State6502 * state) {
|
||||
case AND_ABSY: AND(state, get_byte_absolute_y(state)); break;
|
||||
case AND_INDX: AND(state, get_byte_indirect_x(state)); break;
|
||||
case AND_INDY: AND(state, get_byte_indirect_y(state)); break;
|
||||
case ASL_ACC: unimplemented_instruction(state); break;
|
||||
case ASL_ZP: unimplemented_instruction(state); break;
|
||||
case ASL_ZPX: unimplemented_instruction(state); break;
|
||||
case ASL_ABS: unimplemented_instruction(state); break;
|
||||
case ASL_ABSX: unimplemented_instruction(state); break;
|
||||
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;
|
||||
case BCC_REL: unimplemented_instruction(state); break;
|
||||
case BCS_REL: unimplemented_instruction(state); break;
|
||||
case BEQ_REL: unimplemented_instruction(state); break;
|
||||
@ -404,14 +437,14 @@ int emulate_6502_op(State6502 * state) {
|
||||
case ROR_ZPX: unimplemented_instruction(state); break;
|
||||
case ROR_ABS: unimplemented_instruction(state); break;
|
||||
case ROR_ABSX: unimplemented_instruction(state); break;
|
||||
case SBC_IMM: unimplemented_instruction(state); break;
|
||||
case SBC_ZP: unimplemented_instruction(state); break;
|
||||
case SBC_ZPX: unimplemented_instruction(state); break;
|
||||
case SBC_ABS: unimplemented_instruction(state); break;
|
||||
case SBC_ABSX: unimplemented_instruction(state); break;
|
||||
case SBC_ABSY: unimplemented_instruction(state); break;
|
||||
case SBC_INDX: unimplemented_instruction(state); break;
|
||||
case SBC_INDY: unimplemented_instruction(state); break;
|
||||
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;
|
||||
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;
|
||||
|
25
emu6502.c
25
emu6502.c
@ -12,24 +12,33 @@
|
||||
|
||||
byte* read_game() {
|
||||
FILE* file = fopen("..\\bins\\tetris.bin", "r");
|
||||
byte* buffer = malloc(0x800);
|
||||
fread(buffer, 1, 0x800, file);
|
||||
//byte* buffer = malloc(0x800);
|
||||
byte buffer[32];
|
||||
int read = fread(&buffer, sizeof(byte), 32, file);
|
||||
fclose(file);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void emulate_game() {
|
||||
State6502 state;
|
||||
//FILE* file = fopen("..\\bins\\tetris.bin", "r");
|
||||
clear_state(&state);
|
||||
state.memory = read_game();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
disassemble_6502(state.memory, i);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
//emulate_game();
|
||||
run_tests();
|
||||
printf("All tests succeeded.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void emulate_game() {
|
||||
FILE* file = fopen("..\\bins\\tetris.bin", "r");
|
||||
|
||||
}
|
||||
|
||||
//void emulate() {
|
||||
// State6502 state;
|
||||
// memset(&state.memory, 0, sizeof(State6502));
|
||||
|
BIN
monopole.prg
Normal file
BIN
monopole.prg
Normal file
Binary file not shown.
41
test6502.c
41
test6502.c
@ -1984,6 +1984,45 @@ void test_CPY_ABS() {
|
||||
test_cleanup(&state);
|
||||
}
|
||||
|
||||
//// SBC
|
||||
|
||||
void test_SBC_IMM() {
|
||||
State6502 state = create_blank_state();
|
||||
state.a = 0x08;
|
||||
|
||||
char program[] = { SBC_IMM, 0x06};
|
||||
memcpy(state.memory, program, sizeof(program));
|
||||
test_step(&state);
|
||||
|
||||
assertA(&state, 0x02);
|
||||
assert_flag_z(&state, 0);
|
||||
assert_flag_n(&state, 0);
|
||||
assert_flag_c(&state, 1);
|
||||
assert_flag_v(&state, 0);
|
||||
|
||||
test_cleanup(&state);
|
||||
}
|
||||
|
||||
void test_SBC_IMM_carry() {
|
||||
State6502 state = create_blank_state();
|
||||
state.a = 0x40;
|
||||
state.flags.c = 1;
|
||||
|
||||
char program[] = { SBC_IMM, 0x60 };
|
||||
memcpy(state.memory, program, sizeof(program));
|
||||
test_step(&state);
|
||||
|
||||
//0x100 + 0x40 - 0x60 = 0xE0
|
||||
assertA(&state, 0xE0);
|
||||
assert_flag_z(&state, 0);
|
||||
assert_flag_n(&state, 0);
|
||||
assert_flag_c(&state, 1);
|
||||
assert_flag_v(&state, 0);
|
||||
|
||||
test_cleanup(&state);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
|
||||
typedef void fp();
|
||||
@ -2005,6 +2044,7 @@ fp* tests_txs_tsx[] = { test_TXS, test_TSX };
|
||||
fp* tests_php_plp[] = { test_PHP, test_PLP };
|
||||
fp* tests_jmp[] = { test_JMP, test_JMP_IND, test_JMP_IND_wrap };
|
||||
fp* tests_cmp[] = { test_CMP_ABS_equal, test_CMP_ABS_greater, test_CMP_ABS_greater_2, test_CMP_ABS_less_than, test_CPX_ABS, test_CPY_ABS };
|
||||
fp* tests_sbc[] = { test_SBC_IMM };
|
||||
|
||||
#define RUN(suite) run_suite(suite, sizeof(suite)/sizeof(fp*))
|
||||
|
||||
@ -2014,6 +2054,7 @@ void run_suite(fp * *suite, int size) {
|
||||
}
|
||||
|
||||
void run_tests() {
|
||||
RUN(tests_sbc);
|
||||
RUN(tests_lda);
|
||||
RUN(tests_ora);
|
||||
RUN(tests_and);
|
||||
|
Loading…
x
Reference in New Issue
Block a user