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:
parent
686ba9b601
commit
f47fed9d33
46
cpu.c
46
cpu.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
105
emu6502.c
|
@ -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);
|
||||
|
|
19
opcodes.h
19
opcodes.h
|
@ -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
|
Loading…
Reference in New Issue
Block a user