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/opcodes.h"
oc1 opcode_decoded_1;
oc2 opcode_decoded_2;
ocl opcode_decoded_1;
oct opcode_decoded_2;
void init()
{
// pc is set using 0xFFFC-0xFFFD
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;
// pc is set using 0xFFFC
pc = read_word(0xFFFC);
}
void fetch()
{
ir = read_memory(pc);
ir = read_byte(pc);
pc = pc + 1;
}
@ -40,34 +29,35 @@ void decode()
db aaacc = (aaa << 2) | cc;
opcode_decoded_1 = aaacc;
opcode_decoded_2 = ir;
opcode_decoded_1 = ir;
opcode_decoded_2 = aaacc;
addressing_mode = bbb;
address_mode = bbb;
if (cc == 0b01)
{
// correct the addressing mode for '01' opcodetype
if (bbb == 0b000)
{
addressing_mode = indirect_x;
address_mode = indirect_x;
}
if (bbb == 0b010)
{
addressing_mode = immediate;
address_mode = immediate;
}
}
if (cc == 0b10)
{
// 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_2 = XXX;
addressing_mode = XXX;
address_mode = XXX;
}
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_2 = XXX;
addressing_mode = XXX;
address_mode = XXX;
}
}
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)
{
case BIT:
return bit();
case JMP:
return jmp();
case JPA: // JMP (absolute)
return jmp();
case STY:
return sty();
case LDY:
return ldy();
case CPY:
return cpy();
case CPX:
return cpx();
case ORA:
return ora();
case AND:
return and();
case EOR:
return eor();
case ADC:
return adc();
case STA:
return sta();
case LDA:
return lda();
case CMP:
return cmp();
case SBC:
return sbc();
case ASL:
return asl();
case ROL:
return rol();
case LSR:
return lsr();
case ROR:
return ror();
case STX:
return stx();
case LDX:
return ldx();
case DEC:
return dec();
case INC:
return inc();
case XXX:
return xxx();
case BCC: return bcc();
case BCS: return bcs();
case BEQ: return beq();
case BMI: return bmi();
case BNE: return bne();
case BPL: return bpl();
case BRK: return brk();
case BVC: return bvc();
case BVS: return bvs();
case CLC: return clc();
case CLD: return cld();
case CLI: return cli();
case CLV: return clv();
case DEX: return dex();
case DEY: return dey();
case INX: return inx();
case INY: return iny();
case JSR: return jsr();
case NOP: return nop();
case PHA: return pha();
case PHP: return php();
case PLA: return pla();
case PLP: return plp();
case RTI: return rti();
case RTS: return rts();
case SEC: return sec();
case SED: return sed();
case SEI: return sei();
case TAX: return tax();
case TAY: return tay();
case TSX: return tsx();
case TXA: return txa();
case TXS: return txs();
case TYA: return tya();
case XXX: return xxx();
}
switch (opcode_decoded_2)
{
case ADC: return adc();
case AND: return and();
case ASL: return asl();
case BIT: return bit();
case CMP: return cmp();
case CPX: return cpx();
case CPY: return cpy();
case DEC: return dec();
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"
db read_memory(dw address);
void write_memory(dw address, db data);
db read_byte(dw address);
dw read_word(dw address);
void write_mem(dw address, db data);
#endif

View File

@ -10,74 +10,26 @@ db y; // y register
db sp; // stack pointer
db ir; // intruction register
enum opcodes
{
BIT = 0b00100,
JMP = 0b01000,
JPA = 0b01100,
STY = 0b10000,
LDY = 0b10100,
CPY = 0b11000,
CPX = 0b11100,
ORA = 0b00001,
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_table
{ /// aaa00 aaa01 aaa10
/* aaa *///================================================
/* 000 */ ORA = 0b00001, ASL = 0b00010,
/* 001 */ BIT = 0b00100, AND = 0b00101, ROL = 0b00110,
/* 010 */ JMP = 0b01000, EOR = 0b01001, LSR = 0b01010,
/* 011 */ JPA = 0b01100, ADC = 0b01101, ROR = 0b01110,
/* 100 */ STY = 0b10000, STA = 0b10001, STX = 0b10010,
/* 101 */ LDY = 0b10100, LDA = 0b10101, LDX = 0b10110,
/* 110 */ CPY = 0b11000, CMP = 0b11001, DEC = 0b11010,
/* 111 */ CPX = 0b11100, SBC = 0b11101, INC = 0b11110
};
enum opcodes_comp
enum opcodes_list
{
BRK = 0x00,
BPL = 0x10,
JSR = 0x20,
BMI = 0x30,
RTI = 0x40,
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,
BRK = 0x00, BPL = 0x10, JSR = 0x20, BMI = 0x30, RTI = 0x40, 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
};
@ -95,11 +47,11 @@ enum address_mode
zero_page_y
};
typedef enum opcodes oc1;
typedef enum opcodes_comp oc2;
typedef enum address_mode am;
typedef enum opcodes_table oct;
typedef enum opcodes_list ocl;
typedef enum address_mode am;
am addressing_mode;
am address_mode;
void xxx(); // invalid opcode
void adc(); // add memory to accumalator with carry

View File

@ -34,7 +34,7 @@
db ram_memory[4096]; // total memory: 4KB
db read_memory(dw address)
db read_byte(dw address)
{
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)
{

View File

@ -1,56 +1,29 @@
#include <stdio.h>
#include "inc/opcodes.h"
#include "inc/memory.h"
dw fetch_address()
{
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 fetch_operand()
{
db operand;
db byte;
dw word;
switch (addressing_mode)
switch (address_mode)
{
case immediate:
operand = read_memory(pc);
operand = read_byte(pc);
pc = pc + 1;
break;
case zero_page:
byte = read_memory(pc);
word = 0x0000 | byte;
operand = read_memory(word);
operand = read_byte(pc);
operand = read_byte(operand);
pc = pc + 1;
break;
case zero_page_x:
byte = read_memory(pc);
word = 0x0000 | byte;
word = word + x;
operand = read_memory(word);
operand = read_byte(pc);
operand = read_byte(operand + x);
pc = pc + 1;
break;
case zero_page_y:
byte = read_memory(pc);
word = 0x0000 | byte;
word = word + y;
operand = read_memory(word);
operand = read_byte(pc);
operand = read_byte(operand + y);
pc = pc + 1;
break;
case accumulator: