further refactoring

This commit is contained in:
Thiago Auler 2017-11-13 01:02:14 -02:00
parent dfd4419db9
commit 8d7e748f68
5 changed files with 131 additions and 258 deletions

View File

@ -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();
} }
} }

View File

@ -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

View File

@ -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

View File

@ -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)
{ {

View File

@ -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: