From 8d7e748f685c9a4368af0a19556c0aedac187ee0 Mon Sep 17 00:00:00 2001 From: Thiago Auler Date: Mon, 13 Nov 2017 01:02:14 -0200 Subject: [PATCH] further refactoring --- src/6502.c | 229 ++++++++++++++++------------------------------ src/inc/memory.h | 5 +- src/inc/opcodes.h | 90 +++++------------- src/memory.c | 20 +++- src/opcodes.c | 45 ++------- 5 files changed, 131 insertions(+), 258 deletions(-) diff --git a/src/6502.c b/src/6502.c index 52a5feb..fc7b0c3 100644 --- a/src/6502.c +++ b/src/6502.c @@ -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(); } } diff --git a/src/inc/memory.h b/src/inc/memory.h index f881881..9bd623b 100644 --- a/src/inc/memory.h +++ b/src/inc/memory.h @@ -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 diff --git a/src/inc/opcodes.h b/src/inc/opcodes.h index ec93406..b260a00 100644 --- a/src/inc/opcodes.h +++ b/src/inc/opcodes.h @@ -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 diff --git a/src/memory.c b/src/memory.c index f7a7368..85fa906 100644 --- a/src/memory.c +++ b/src/memory.c @@ -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) { diff --git a/src/opcodes.c b/src/opcodes.c index c7f7990..afd6bbd 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -1,56 +1,29 @@ -#include - #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: