further refactoring
This commit is contained in:
parent
dfd4419db9
commit
8d7e748f68
229
src/6502.c
229
src/6502.c
|
@ -2,29 +2,18 @@
|
||||||
#include "inc/memory.h"
|
#include "inc/memory.h"
|
||||||
#include "inc/opcodes.h"
|
#include "inc/opcodes.h"
|
||||||
|
|
||||||
oc1 opcode_decoded_1;
|
ocl opcode_decoded_1;
|
||||||
oc2 opcode_decoded_2;
|
oct opcode_decoded_2;
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
// pc is set using 0xFFFC-0xFFFD
|
// pc is set using 0xFFFC
|
||||||
|
pc = read_word(0xFFFC);
|
||||||
dw word;
|
|
||||||
db low_byte;
|
|
||||||
db high_byte;
|
|
||||||
|
|
||||||
low_byte = read_memory(0xFFFD);
|
|
||||||
high_byte = read_memory(0xFFFC);
|
|
||||||
|
|
||||||
word = high_byte << 8; // shifts high byte to its place
|
|
||||||
word = word | low_byte; // appends low byte to form the complete word
|
|
||||||
|
|
||||||
pc = word;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetch()
|
void fetch()
|
||||||
{
|
{
|
||||||
ir = read_memory(pc);
|
ir = read_byte(pc);
|
||||||
pc = pc + 1;
|
pc = pc + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,34 +29,35 @@ void decode()
|
||||||
|
|
||||||
db aaacc = (aaa << 2) | cc;
|
db aaacc = (aaa << 2) | cc;
|
||||||
|
|
||||||
opcode_decoded_1 = aaacc;
|
opcode_decoded_1 = ir;
|
||||||
opcode_decoded_2 = ir;
|
opcode_decoded_2 = aaacc;
|
||||||
|
|
||||||
addressing_mode = bbb;
|
|
||||||
|
address_mode = bbb;
|
||||||
|
|
||||||
if (cc == 0b01)
|
if (cc == 0b01)
|
||||||
{
|
{
|
||||||
// correct the addressing mode for '01' opcodetype
|
// correct the addressing mode for '01' opcodetype
|
||||||
if (bbb == 0b000)
|
if (bbb == 0b000)
|
||||||
{
|
{
|
||||||
addressing_mode = indirect_x;
|
address_mode = indirect_x;
|
||||||
}
|
}
|
||||||
if (bbb == 0b010)
|
if (bbb == 0b010)
|
||||||
{
|
{
|
||||||
addressing_mode = immediate;
|
address_mode = immediate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cc == 0b10)
|
if (cc == 0b10)
|
||||||
{
|
{
|
||||||
// adjust the addressing mode for STX and LDX
|
// adjust the addressing mode for STX and LDX
|
||||||
if ((opcode_decoded_1 == STX || opcode_decoded_1 == LDX) && addressing_mode == zero_page_x)
|
if ((aaacc == STX || aaacc == LDX) && address_mode == zero_page_x)
|
||||||
{
|
{
|
||||||
addressing_mode = zero_page_y;
|
address_mode = zero_page_y;
|
||||||
}
|
}
|
||||||
if (opcode_decoded_1 == LDX && addressing_mode == absolute_x)
|
if (aaacc == LDX && address_mode == absolute_x)
|
||||||
{
|
{
|
||||||
addressing_mode = absolute_y;
|
address_mode = absolute_y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +68,7 @@ void decode()
|
||||||
{
|
{
|
||||||
opcode_decoded_1 = XXX;
|
opcode_decoded_1 = XXX;
|
||||||
opcode_decoded_2 = XXX;
|
opcode_decoded_2 = XXX;
|
||||||
addressing_mode = XXX;
|
address_mode = XXX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ir == 0x04 || ir == 0x0C || ir == 0x14 || ir == 0x1A || ir == 0x1C || ir == 0x34 || ir == 0x3A ||
|
if (ir == 0x04 || ir == 0x0C || ir == 0x14 || ir == 0x1A || ir == 0x1C || ir == 0x34 || ir == 0x3A ||
|
||||||
|
@ -88,136 +78,77 @@ void decode()
|
||||||
{
|
{
|
||||||
opcode_decoded_1 = XXX;
|
opcode_decoded_1 = XXX;
|
||||||
opcode_decoded_2 = XXX;
|
opcode_decoded_2 = XXX;
|
||||||
addressing_mode = XXX;
|
address_mode = XXX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute()
|
void execute()
|
||||||
{
|
{
|
||||||
switch (opcode_decoded_2)
|
|
||||||
{
|
|
||||||
case BRK:
|
|
||||||
return brk();
|
|
||||||
case BPL:
|
|
||||||
return bpl();
|
|
||||||
case JSR:
|
|
||||||
return jsr();
|
|
||||||
case BMI:
|
|
||||||
return bmi();
|
|
||||||
case RTI:
|
|
||||||
return rti();
|
|
||||||
case BVC:
|
|
||||||
return bvc();
|
|
||||||
case RTS:
|
|
||||||
return rts();
|
|
||||||
case BVS:
|
|
||||||
return bvs();
|
|
||||||
case BCC:
|
|
||||||
return bcc();
|
|
||||||
case BCS:
|
|
||||||
return bcs();
|
|
||||||
case BNE:
|
|
||||||
return bne();
|
|
||||||
case BEQ:
|
|
||||||
return beq();
|
|
||||||
case PHP:
|
|
||||||
return php();
|
|
||||||
case CLC:
|
|
||||||
return clc();
|
|
||||||
case PLP:
|
|
||||||
return plp();
|
|
||||||
case SEC:
|
|
||||||
return sec();
|
|
||||||
case PHA:
|
|
||||||
return pha();
|
|
||||||
case CLI:
|
|
||||||
return cli();
|
|
||||||
case PLA:
|
|
||||||
return pla();
|
|
||||||
case SEI:
|
|
||||||
return sei();
|
|
||||||
case DEY:
|
|
||||||
return dey();
|
|
||||||
case TYA:
|
|
||||||
return tya();
|
|
||||||
case TAY:
|
|
||||||
return tay();
|
|
||||||
case CLV:
|
|
||||||
return clv();
|
|
||||||
case INY:
|
|
||||||
return iny();
|
|
||||||
case CLD:
|
|
||||||
return cld();
|
|
||||||
case INX:
|
|
||||||
return inx();
|
|
||||||
case SED:
|
|
||||||
return sed();
|
|
||||||
case TXA:
|
|
||||||
return txa();
|
|
||||||
case TXS:
|
|
||||||
return txs();
|
|
||||||
case TAX:
|
|
||||||
return tax();
|
|
||||||
case TSX:
|
|
||||||
return tsx();
|
|
||||||
case DEX:
|
|
||||||
return dex();
|
|
||||||
case NOP:
|
|
||||||
return nop();
|
|
||||||
case XXX:
|
|
||||||
return xxx();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (opcode_decoded_1)
|
switch (opcode_decoded_1)
|
||||||
{
|
{
|
||||||
case BIT:
|
case BCC: return bcc();
|
||||||
return bit();
|
case BCS: return bcs();
|
||||||
case JMP:
|
case BEQ: return beq();
|
||||||
return jmp();
|
case BMI: return bmi();
|
||||||
case JPA: // JMP (absolute)
|
case BNE: return bne();
|
||||||
return jmp();
|
case BPL: return bpl();
|
||||||
case STY:
|
case BRK: return brk();
|
||||||
return sty();
|
case BVC: return bvc();
|
||||||
case LDY:
|
case BVS: return bvs();
|
||||||
return ldy();
|
case CLC: return clc();
|
||||||
case CPY:
|
case CLD: return cld();
|
||||||
return cpy();
|
case CLI: return cli();
|
||||||
case CPX:
|
case CLV: return clv();
|
||||||
return cpx();
|
case DEX: return dex();
|
||||||
case ORA:
|
case DEY: return dey();
|
||||||
return ora();
|
case INX: return inx();
|
||||||
case AND:
|
case INY: return iny();
|
||||||
return and();
|
case JSR: return jsr();
|
||||||
case EOR:
|
case NOP: return nop();
|
||||||
return eor();
|
case PHA: return pha();
|
||||||
case ADC:
|
case PHP: return php();
|
||||||
return adc();
|
case PLA: return pla();
|
||||||
case STA:
|
case PLP: return plp();
|
||||||
return sta();
|
case RTI: return rti();
|
||||||
case LDA:
|
case RTS: return rts();
|
||||||
return lda();
|
case SEC: return sec();
|
||||||
case CMP:
|
case SED: return sed();
|
||||||
return cmp();
|
case SEI: return sei();
|
||||||
case SBC:
|
case TAX: return tax();
|
||||||
return sbc();
|
case TAY: return tay();
|
||||||
case ASL:
|
case TSX: return tsx();
|
||||||
return asl();
|
case TXA: return txa();
|
||||||
case ROL:
|
case TXS: return txs();
|
||||||
return rol();
|
case TYA: return tya();
|
||||||
case LSR:
|
case XXX: return xxx();
|
||||||
return lsr();
|
}
|
||||||
case ROR:
|
|
||||||
return ror();
|
switch (opcode_decoded_2)
|
||||||
case STX:
|
{
|
||||||
return stx();
|
case ADC: return adc();
|
||||||
case LDX:
|
case AND: return and();
|
||||||
return ldx();
|
case ASL: return asl();
|
||||||
case DEC:
|
case BIT: return bit();
|
||||||
return dec();
|
case CMP: return cmp();
|
||||||
case INC:
|
case CPX: return cpx();
|
||||||
return inc();
|
case CPY: return cpy();
|
||||||
case XXX:
|
case DEC: return dec();
|
||||||
return xxx();
|
case EOR: return eor();
|
||||||
|
case INC: return inc();
|
||||||
|
case JMP: return jmp();
|
||||||
|
case JPA: return jmp();
|
||||||
|
case LDA: return lda();
|
||||||
|
case LDX: return ldx();
|
||||||
|
case LDY: return ldy();
|
||||||
|
case LSR: return lsr();
|
||||||
|
case ORA: return ora();
|
||||||
|
case ROL: return rol();
|
||||||
|
case ROR: return ror();
|
||||||
|
case SBC: return sbc();
|
||||||
|
case STA: return sta();
|
||||||
|
case STX: return stx();
|
||||||
|
case STY: return sty();
|
||||||
|
case XXX: return xxx();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
db read_memory(dw address);
|
db read_byte(dw address);
|
||||||
void write_memory(dw address, db data);
|
dw read_word(dw address);
|
||||||
|
void write_mem(dw address, db data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,74 +10,26 @@ db y; // y register
|
||||||
db sp; // stack pointer
|
db sp; // stack pointer
|
||||||
db ir; // intruction register
|
db ir; // intruction register
|
||||||
|
|
||||||
enum opcodes
|
enum opcodes_table
|
||||||
{
|
{ /// aaa00 aaa01 aaa10
|
||||||
BIT = 0b00100,
|
/* aaa *///================================================
|
||||||
JMP = 0b01000,
|
/* 000 */ ORA = 0b00001, ASL = 0b00010,
|
||||||
JPA = 0b01100,
|
/* 001 */ BIT = 0b00100, AND = 0b00101, ROL = 0b00110,
|
||||||
STY = 0b10000,
|
/* 010 */ JMP = 0b01000, EOR = 0b01001, LSR = 0b01010,
|
||||||
LDY = 0b10100,
|
/* 011 */ JPA = 0b01100, ADC = 0b01101, ROR = 0b01110,
|
||||||
CPY = 0b11000,
|
/* 100 */ STY = 0b10000, STA = 0b10001, STX = 0b10010,
|
||||||
CPX = 0b11100,
|
/* 101 */ LDY = 0b10100, LDA = 0b10101, LDX = 0b10110,
|
||||||
|
/* 110 */ CPY = 0b11000, CMP = 0b11001, DEC = 0b11010,
|
||||||
ORA = 0b00001,
|
/* 111 */ CPX = 0b11100, SBC = 0b11101, INC = 0b11110
|
||||||
AND = 0b00101,
|
|
||||||
EOR = 0b01001,
|
|
||||||
ADC = 0b01101,
|
|
||||||
STA = 0b10001,
|
|
||||||
LDA = 0b10101,
|
|
||||||
CMP = 0b11001,
|
|
||||||
SBC = 0b11101,
|
|
||||||
|
|
||||||
ASL = 0b00010,
|
|
||||||
ROL = 0b00110,
|
|
||||||
LSR = 0b01010,
|
|
||||||
ROR = 0b01110,
|
|
||||||
STX = 0b10010,
|
|
||||||
LDX = 0b10110,
|
|
||||||
DEC = 0b11010,
|
|
||||||
INC = 0b11110,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum opcodes_comp
|
enum opcodes_list
|
||||||
{
|
{
|
||||||
BRK = 0x00,
|
BRK = 0x00, BPL = 0x10, JSR = 0x20, BMI = 0x30, RTI = 0x40, BVC = 0x50,
|
||||||
BPL = 0x10,
|
RTS = 0x60, BVS = 0x70, BCC = 0x90, BCS = 0xB0, BNE = 0xD0, BEQ = 0xF0,
|
||||||
JSR = 0x20,
|
PHP = 0x08, CLC = 0x18, PLP = 0x28, SEC = 0x38, PHA = 0x48, CLI = 0x58, PLA = 0x68, SEI = 0x78,
|
||||||
BMI = 0x30,
|
DEY = 0x88, TYA = 0x98, TAY = 0xA8, CLV = 0xB8, INY = 0xC8, CLD = 0xD8, INX = 0xE8, SED = 0xF8,
|
||||||
RTI = 0x40,
|
TXA = 0x8A, TXS = 0x9A, TAX = 0xAA, TSX = 0xBA, DEX = 0xCA, NOP = 0xEA,
|
||||||
BVC = 0x50,
|
|
||||||
RTS = 0x60,
|
|
||||||
BVS = 0x70,
|
|
||||||
BCC = 0x90,
|
|
||||||
BCS = 0xB0,
|
|
||||||
BNE = 0xD0,
|
|
||||||
BEQ = 0xF0,
|
|
||||||
|
|
||||||
PHP = 0x08,
|
|
||||||
CLC = 0x18,
|
|
||||||
PLP = 0x28,
|
|
||||||
SEC = 0x38,
|
|
||||||
PHA = 0x48,
|
|
||||||
CLI = 0x58,
|
|
||||||
PLA = 0x68,
|
|
||||||
SEI = 0x78,
|
|
||||||
DEY = 0x88,
|
|
||||||
TYA = 0x98,
|
|
||||||
TAY = 0xA8,
|
|
||||||
CLV = 0xB8,
|
|
||||||
INY = 0xC8,
|
|
||||||
CLD = 0xD8,
|
|
||||||
INX = 0xE8,
|
|
||||||
SED = 0xF8,
|
|
||||||
|
|
||||||
TXA = 0x8A,
|
|
||||||
TXS = 0x9A,
|
|
||||||
TAX = 0xAA,
|
|
||||||
TSX = 0xBA,
|
|
||||||
DEX = 0xCA,
|
|
||||||
NOP = 0xEA,
|
|
||||||
|
|
||||||
XXX = 0xFF
|
XXX = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,11 +47,11 @@ enum address_mode
|
||||||
zero_page_y
|
zero_page_y
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum opcodes oc1;
|
typedef enum opcodes_table oct;
|
||||||
typedef enum opcodes_comp oc2;
|
typedef enum opcodes_list ocl;
|
||||||
typedef enum address_mode am;
|
typedef enum address_mode am;
|
||||||
|
|
||||||
am addressing_mode;
|
am address_mode;
|
||||||
|
|
||||||
void xxx(); // invalid opcode
|
void xxx(); // invalid opcode
|
||||||
void adc(); // add memory to accumalator with carry
|
void adc(); // add memory to accumalator with carry
|
||||||
|
|
20
src/memory.c
20
src/memory.c
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
db ram_memory[4096]; // total memory: 4KB
|
db ram_memory[4096]; // total memory: 4KB
|
||||||
|
|
||||||
db read_memory(dw address)
|
db read_byte(dw address)
|
||||||
{
|
{
|
||||||
if (address >= 0x0000 && address <= 0x0FFF)
|
if (address >= 0x0000 && address <= 0x0FFF)
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,23 @@ db read_memory(dw address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_memory(dw address, db data)
|
dw read_word(dw address)
|
||||||
|
{
|
||||||
|
dw word;
|
||||||
|
db low_byte;
|
||||||
|
db high_byte;
|
||||||
|
|
||||||
|
low_byte = read_byte(address);
|
||||||
|
high_byte = read_byte(address + 1);
|
||||||
|
|
||||||
|
word = high_byte << 8; // shifts high byte to its place
|
||||||
|
word = word | low_byte; // appends low byte to form the complete word
|
||||||
|
|
||||||
|
// the word is store in little-endian format on the memory
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_mem(dw address, db data)
|
||||||
{
|
{
|
||||||
if (address >= 0x0000 && address <= 0x0FFF)
|
if (address >= 0x0000 && address <= 0x0FFF)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,56 +1,29 @@
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "inc/opcodes.h"
|
#include "inc/opcodes.h"
|
||||||
#include "inc/memory.h"
|
#include "inc/memory.h"
|
||||||
|
|
||||||
dw fetch_address()
|
db fetch_operand()
|
||||||
{
|
|
||||||
dw word;
|
|
||||||
db low_byte;
|
|
||||||
db high_byte;
|
|
||||||
|
|
||||||
low_byte = read_memory(pc);
|
|
||||||
pc = pc + 1;
|
|
||||||
|
|
||||||
high_byte = read_memory(pc);
|
|
||||||
pc = pc + 1;
|
|
||||||
|
|
||||||
word = high_byte << 8; // shifts high byte to its place
|
|
||||||
word = word | low_byte; // appends low byte to form the complete word
|
|
||||||
|
|
||||||
return word;
|
|
||||||
}
|
|
||||||
|
|
||||||
db decode_operand()
|
|
||||||
{
|
{
|
||||||
db operand;
|
db operand;
|
||||||
db byte;
|
|
||||||
dw word;
|
|
||||||
|
|
||||||
switch (addressing_mode)
|
switch (address_mode)
|
||||||
{
|
{
|
||||||
case immediate:
|
case immediate:
|
||||||
operand = read_memory(pc);
|
operand = read_byte(pc);
|
||||||
pc = pc + 1;
|
pc = pc + 1;
|
||||||
break;
|
break;
|
||||||
case zero_page:
|
case zero_page:
|
||||||
byte = read_memory(pc);
|
operand = read_byte(pc);
|
||||||
word = 0x0000 | byte;
|
operand = read_byte(operand);
|
||||||
operand = read_memory(word);
|
|
||||||
pc = pc + 1;
|
pc = pc + 1;
|
||||||
break;
|
break;
|
||||||
case zero_page_x:
|
case zero_page_x:
|
||||||
byte = read_memory(pc);
|
operand = read_byte(pc);
|
||||||
word = 0x0000 | byte;
|
operand = read_byte(operand + x);
|
||||||
word = word + x;
|
|
||||||
operand = read_memory(word);
|
|
||||||
pc = pc + 1;
|
pc = pc + 1;
|
||||||
break;
|
break;
|
||||||
case zero_page_y:
|
case zero_page_y:
|
||||||
byte = read_memory(pc);
|
operand = read_byte(pc);
|
||||||
word = 0x0000 | byte;
|
operand = read_byte(operand + y);
|
||||||
word = word + y;
|
|
||||||
operand = read_memory(word);
|
|
||||||
pc = pc + 1;
|
pc = pc + 1;
|
||||||
break;
|
break;
|
||||||
case accumulator:
|
case accumulator:
|
||||||
|
|
Loading…
Reference in New Issue