1
0
mirror of https://github.com/jborza/emu6502.git synced 2024-06-01 04:41:41 +00:00

LDA + simple tests

This commit is contained in:
jborza 2019-04-14 10:57:25 +02:00
parent 686ba9b601
commit f47fed9d33
4 changed files with 165 additions and 26 deletions

46
cpu.c
View File

@ -85,7 +85,7 @@ int emulate_6502_op(State6502 * state) {
state->flags.b = 1;
break; //BRK
case NOP: break; //NOP
case ORA_IND_X: //ORA, indirect, x
case ORA_INDX: //ORA, indirect, x
//The address to be accessed by an instruction using X register indexed absolute addressing is computed by taking the 16 bit address
//from the instruction and added the contents of the X register.
//For example if X contains $92 then an STA $2000,X instruction will store the accumulator at $2092 (e.g. $2000 + $92). (STA)
@ -101,7 +101,7 @@ int emulate_6502_op(State6502 * state) {
ORA(state, state->memory[address]);
break;
}
case ORA_IND_Y: //ORA, indirect, y (post_indexed)
case ORA_INDY: //ORA, indirect, y (post_indexed)
{
word address_indirect = pop_word(state);
word address = get_word(state, address_indirect) + state->y;
@ -112,7 +112,7 @@ int emulate_6502_op(State6502 * state) {
case ORA_IMM:
ORA(state, pop_byte(state));
break;
case ORA_ZP_X:
case ORA_ZPX:
{
byte address = pop_byte(state) + state->x;
ORA(state, state->memory[address]);
@ -124,13 +124,13 @@ int emulate_6502_op(State6502 * state) {
ORA(state, state->memory[address]);
break;
}
case ORA_ABS_X:
case ORA_ABSX:
{
word address = pop_word(state) + state->x;
ORA(state, state->memory[address]);
break;
}
case ORA_ABS_Y:
case ORA_ABSY:
{
word address = pop_word(state) + state->y;
ORA(state, state->memory[address]);
@ -141,7 +141,41 @@ int emulate_6502_op(State6502 * state) {
LDA(state, pop_byte(state));
break;
}
break;
case LDA_ZP:
{
byte address = pop_byte(state);
LDA(state, state->memory[address]);
break;
}
case LDA_ZPX:
{
byte address = pop_byte(state) + state->x;
LDA(state, state->memory[address]);
break;
}
case LDA_ABS:
{
word address = pop_word(state);
LDA(state, state->memory[address]);
break;
}
case LDA_ABSX:
{
word address = pop_word(state) + state->x;
LDA(state, state->memory[address]);
break;
}
case LDA_ABSY:
{
word address = pop_word(state) + state->y;
LDA(state, state->memory[address]);
break;
}
case LDA_INDX:
{
}
case LDA_INDY:
default:
unimplemented_instruction(state); break;
}

View File

@ -1,21 +1,28 @@
#pragma once
#include "types.h"
#include "opcodes.h"
#include "disassembler.h"
void disassemble_6502(byte* buffer, word pc) {
printf("%04d ", pc);
byte* code = &buffer[pc];
switch (*code) {
case 0x00: printf("BRK"); break;
case ORA_IND_X: printf("ORA ($%02x,X)", code[1]); break;
case ORA_IND_Y: printf("ORA ($%02x),Y", code[1]); break;
case ORA_ZP: printf("ORA $%02x", code[1]); break;
case ORA_IMM: printf("ORA #$%02x", code[1]); break;
case ORA_ZP_X: printf("ORA $%02x,X", code[1]); break;
case ORA_ZP: printf("ORA $%02x", code[1]); break;
case ORA_ZPX: printf("ORA $%02x,X", code[1]); break;
case ORA_ABS: printf("ORA $%02x%02x", code[2], code[1]); break;
case ORA_ABS_X: printf("ORA $%02x%02x,X", code[2], code[1]); break;
case ORA_ABS_Y: printf("ORA $%02x%02x,Y", code[2], code[1]); break;
case ORA_ABSX: printf("ORA $%02x%02x,X", code[2], code[1]); break;
case ORA_ABSY: printf("ORA $%02x%02x,Y", code[2], code[1]); break;
case ORA_INDX: printf("ORA ($%02x,X)", code[1]); break;
case ORA_INDY: printf("ORA ($%02x),Y", code[1]); break;
case LDA_IMM: printf("LDA #$%02x", code[1]); break;
case LDA_ZP: printf("LDA $%02x", code[1]); break;
case LDA_ZPX: printf("LDA $%02x,X", code[1]); break;
case LDA_ABS: printf("LDA $%02x%02x", code[2], code[1]); break;
case LDA_ABSX: printf("LDA $%02x%02x,X", code[2], code[1]); break;
case LDA_ABSY: printf("LDA $%02x%02x,Y", code[2], code[1]); break;
case LDA_INDX: printf("LDA ($%02x,X)", code[1]); break;
case LDA_INDY: printf("LDA ($%02x),Y", code[1]); break;
case 0xEA: printf("NOP"); break;
default:

105
emu6502.c
View File

@ -2,9 +2,12 @@
//
#include <stdio.h>
#include <stdlib.h>
#include "state.h"
#include "cpu.h"
#include "disassembler.h"
#include <memory.h>
#include "opcodes.h"
byte* read_game() {
FILE* file = fopen("..\\bins\\tetris.bin", "r");
@ -17,33 +20,121 @@ byte* read_game() {
void print_all(State6502* state) {
print_state(state);
print_memory(state, 0);
print_memory(state, 0x20);
print_memory(state, 0x40);
print_memory(state, 0x80);
//print_memory(state, 0x20);
//print_memory(state, 0x40);
//print_memory(state, 0x80);
printf("\n");
}
State6502 create_blank_state() {
State6502 state;
clear_state(&state);
state.memory = malloc(4096);
memset(state.memory, 0, sizeof(byte) * 4096);
return state;
}
void assertA(State6502* state, byte expected) {
if (state->a != expected) {
printf("Unexpected value in A, was %02x, expected %02x", expected, state->a);
exit(1);
}
}
void test_LDA_IMM() {
//initialize
State6502 state = create_blank_state();
//arrange
char program[] = { LDA_IMM, 0xAA }; //LDA #$AA
memcpy(state.memory, program, sizeof(program));
//act
print_all(&state);
disassemble_6502(state.memory, state.pc);
emulate_6502_op(&state);
print_all(&state);
//assert
assertA(&state, 0xAA);
//cleanup
free(state.memory);
}
void test_LDA_ZP() {
//initialize
State6502 state = create_blank_state();
//arrange
char program[] = { LDA_ZP, 0x03, 0x00, 0xAA }; //LDA $3
memcpy(state.memory, program, sizeof(program));
//act
print_all(&state);
disassemble_6502(&state.memory, state.pc);
emulate_6502_op(&state);
print_all(&state);
//assert
assertA(&state, 0xAA);
//cleanup
free(state.memory);
}
void test_LDA_ZPX() {
//initialize
State6502 state = create_blank_state();
state.x = 0x01;
//arrange
char program[] = { LDA_ZPX, 0x02, 0x00, 0xAA }; //LDA $2,x
memcpy(state.memory, program, sizeof(program));
//act
print_all(&state);
disassemble_6502(&state.memory, state.pc);
emulate_6502_op(&state);
print_all(&state);
//assert
assertA(&state, 0xAA);
//cleanup
free(state.memory);
}
int main()
{
printf("Hello World!\n");
test_LDA_IMM();
//test_LDA_ZP();
//test_LDA_ZPX();
}
int emulate() {
State6502 state;
memset(&state.memory, 0, sizeof(State6502));
print_state(&state);
clear_state(&state);
byte* memory = read_game();
//state.memory = read_game();
state.memory = malloc(4096);
memset(state.memory, 0, sizeof(byte) * 4096);
state.memory[0] = 0xEA;
state.memory[1] = 0x05; //ORA $a0
state.memory[2] = 0xA0;
state.memory[3] = 0xEA; //NOP
state.memory[4] = 0x09; //ORA #$ff
state.memory[5] = 0xff;
state.memory[5] = 0xff;
state.memory[6] = 0xA9; //LDA
state.memory[7] = 0x00; //0
state.memory[8] = 0x0D; //ORA $1234
state.memory[9] = 0x34;
state.memory[10] = 0x12;
state.memory[10] = 0x02;
state.memory[0xA0] = 0x13;
state.memory[0x1234] = 0xAA;
state.memory[0x0234] = 0xAA;
for (int i = 0; i < 10; i++) {
print_all(&state);

View File

@ -3,11 +3,18 @@
#define BRK 0x00
#define ORA_IMM 0x09
#define ORA_ZP 0x05
#define ORA_ZP_X 0x15
#define ORA_ZPX 0x15
#define ORA_ABS 0x0D
#define ORA_ABS_X 0x1D
#define ORA_ABS_Y 0x19
#define ORA_IND_X 0x01
#define ORA_IND_Y 0x11
#define ORA_ABSX 0x1D
#define ORA_ABSY 0x19
#define ORA_INDX 0x01
#define ORA_INDY 0x11
#define NOP 0xEA
#define LDA_IMM 0xA9
#define LDA_IMM 0xA9
#define LDA_ZP 0xA5
#define LDA_ZPX 0xB5
#define LDA_ABS 0xAD
#define LDA_ABSX 0xBD
#define LDA_ABSY 0xB9
#define LDA_INDX 0xA1
#define LDA_INDY 0xB1