2017-11-17 22:54:19 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2017-11-12 02:31:55 +00:00
|
|
|
#include "inc/types.h"
|
|
|
|
#include "inc/memory.h"
|
|
|
|
#include "inc/opcodes.h"
|
|
|
|
|
2017-11-13 03:26:29 +00:00
|
|
|
ocl opcode_in_list;
|
|
|
|
oct opcode_in_table;
|
2017-11-12 02:31:55 +00:00
|
|
|
|
|
|
|
void init()
|
|
|
|
{
|
2017-11-13 03:02:14 +00:00
|
|
|
// pc is set using 0xFFFC
|
|
|
|
pc = read_word(0xFFFC);
|
2017-11-17 00:09:03 +00:00
|
|
|
sp = 0xFF;
|
2017-11-12 02:31:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void fetch()
|
|
|
|
{
|
2017-11-13 03:02:14 +00:00
|
|
|
ir = read_byte(pc);
|
2017-11-13 01:00:52 +00:00
|
|
|
pc = pc + 1;
|
2017-11-12 02:31:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void decode()
|
|
|
|
{
|
|
|
|
// instruction pattern is "aaabbbccc" where:
|
|
|
|
// aaa cc determines the opcode
|
|
|
|
// bbb determines the addressing mode
|
|
|
|
|
|
|
|
db aaa = (ir & 0b11100000) >> 5;
|
|
|
|
db bbb = (ir & 0b00011100) >> 2;
|
|
|
|
db cc = (ir & 0b00000011);
|
|
|
|
|
|
|
|
db aaacc = (aaa << 2) | cc;
|
2017-11-17 00:09:03 +00:00
|
|
|
db bbbcc = (bbb << 2) | cc;
|
2017-11-12 02:31:55 +00:00
|
|
|
|
2017-11-17 01:21:21 +00:00
|
|
|
opcode_in_list = ir;
|
2017-11-13 03:26:29 +00:00
|
|
|
opcode_in_table = aaacc;
|
2017-11-13 03:02:14 +00:00
|
|
|
|
|
|
|
address_mode = bbb;
|
2017-11-12 16:02:30 +00:00
|
|
|
|
|
|
|
if (cc == 0b01)
|
|
|
|
{
|
2017-11-14 21:42:36 +00:00
|
|
|
// correct the addressing mode for '01' opcode type
|
2017-11-12 16:02:30 +00:00
|
|
|
if (bbb == 0b000)
|
|
|
|
{
|
2017-11-13 03:02:14 +00:00
|
|
|
address_mode = indirect_x;
|
2017-11-12 16:02:30 +00:00
|
|
|
}
|
|
|
|
if (bbb == 0b010)
|
|
|
|
{
|
2017-11-13 03:02:14 +00:00
|
|
|
address_mode = immediate;
|
2017-11-12 16:02:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cc == 0b10)
|
|
|
|
{
|
|
|
|
// adjust the addressing mode for STX and LDX
|
2017-11-13 03:02:14 +00:00
|
|
|
if ((aaacc == STX || aaacc == LDX) && address_mode == zero_page_x)
|
2017-11-12 16:02:30 +00:00
|
|
|
{
|
2017-11-13 03:02:14 +00:00
|
|
|
address_mode = zero_page_y;
|
2017-11-12 16:02:30 +00:00
|
|
|
}
|
2017-11-13 03:02:14 +00:00
|
|
|
if (aaacc == LDX && address_mode == absolute_x)
|
2017-11-12 16:02:30 +00:00
|
|
|
{
|
2017-11-13 03:02:14 +00:00
|
|
|
address_mode = absolute_y;
|
2017-11-12 16:02:30 +00:00
|
|
|
}
|
|
|
|
}
|
2017-11-16 22:12:06 +00:00
|
|
|
|
2017-11-17 00:09:03 +00:00
|
|
|
if (bbbcc == 0b10000)
|
2017-11-16 22:12:06 +00:00
|
|
|
{
|
|
|
|
// adjust the addressing mode for branch intructions
|
|
|
|
address_mode = relative;
|
|
|
|
}
|
2017-11-12 02:31:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void execute()
|
|
|
|
{
|
2017-11-13 03:26:29 +00:00
|
|
|
switch (opcode_in_list)
|
2017-11-12 02:31:55 +00:00
|
|
|
{
|
2017-11-13 03:02:14 +00:00
|
|
|
case BCC: return bcc();
|
|
|
|
case BCS: return bcs();
|
|
|
|
case BEQ: return beq();
|
|
|
|
case BMI: return bmi();
|
|
|
|
case BNE: return bne();
|
|
|
|
case BPL: return bpl();
|
2017-11-17 22:54:19 +00:00
|
|
|
case BRK: return bkk();
|
2017-11-13 03:02:14 +00:00
|
|
|
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();
|
2017-11-12 02:31:55 +00:00
|
|
|
}
|
|
|
|
|
2017-11-13 03:26:29 +00:00
|
|
|
switch (opcode_in_table)
|
2017-11-12 02:31:55 +00:00
|
|
|
{
|
2017-11-13 03:02:14 +00:00
|
|
|
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();
|
2017-11-13 23:13:20 +00:00
|
|
|
case JPA: return jpa();
|
2017-11-13 03:02:14 +00:00
|
|
|
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();
|
2017-11-12 02:31:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-17 22:54:19 +00:00
|
|
|
void display()
|
|
|
|
{
|
|
|
|
//if (display_control == 0xA7)
|
|
|
|
{
|
|
|
|
// display is ready to ouptup
|
|
|
|
if (display_buffer & 0x80)
|
|
|
|
{
|
|
|
|
// outputs the buffer character
|
|
|
|
display_buffer = display_buffer & 0x7F;
|
|
|
|
printf("%c", display_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void read_input()
|
|
|
|
{
|
|
|
|
// verifies if the keyboard is being pressed...
|
|
|
|
}
|
|
|
|
|
2017-11-12 02:31:55 +00:00
|
|
|
void run()
|
|
|
|
{
|
2017-11-13 23:13:20 +00:00
|
|
|
while (1)
|
2017-11-12 02:31:55 +00:00
|
|
|
{
|
2017-11-13 00:27:51 +00:00
|
|
|
fetch();
|
|
|
|
decode();
|
|
|
|
execute();
|
2017-11-17 22:54:19 +00:00
|
|
|
|
|
|
|
display();
|
|
|
|
read_input();
|
2017-11-12 02:31:55 +00:00
|
|
|
}
|
2017-11-12 16:02:30 +00:00
|
|
|
|
2017-11-12 02:31:55 +00:00
|
|
|
}
|