implementation of all opcodes

This commit is contained in:
Thiago Auler dos Santos 2017-11-16 22:09:03 -02:00
parent d67f57b752
commit 5392839714
2 changed files with 152 additions and 14 deletions

View File

@ -9,6 +9,7 @@ void init()
{ {
// pc is set using 0xFFFC // pc is set using 0xFFFC
pc = read_word(0xFFFC); pc = read_word(0xFFFC);
sp = 0xFF;
} }
void fetch() void fetch()
@ -28,6 +29,7 @@ void decode()
db cc = (ir & 0b00000011); db cc = (ir & 0b00000011);
db aaacc = (aaa << 2) | cc; db aaacc = (aaa << 2) | cc;
db bbbcc = (bbb << 2) | cc;
opcode_in_list = ir; opcode_in_list = ir;
opcode_in_table = aaacc; opcode_in_table = aaacc;
@ -60,7 +62,7 @@ void decode()
} }
} }
if ((ir & 0b00011111) == 0b00010000) if (bbbcc == 0b10000)
{ {
// adjust the addressing mode for branch intructions // adjust the addressing mode for branch intructions
address_mode = relative; address_mode = relative;

View File

@ -76,14 +76,14 @@ void fetch_operand()
pc = pc + 1; pc = pc + 1;
break; break;
case relative: case relative:
address = read_byte(pc); operand = read_byte(pc);
if ((address >> 7) == 0) if ((operand >> 7) == 0)
{ {
address = pc + address; address = pc + operand;
} }
else else
{ {
address = pc - address; address = pc - operand;
} }
break; break;
} }
@ -98,14 +98,13 @@ void adjustNZ(db r)
db adder(db a, db b) db adder(db a, db b)
{ {
db r = a + b; db r = a + b;
db c = (a + b) >> 8; db c = (a + b) >> 8;
a = a & 0x7F; a = a & 0b01111111;
b = b & 0x7F; b = b & 0b01111111;
db cc = (a + b) >> 7; db cc = (a + b) >> 7;
db v = c ^ cc;
db v = c ^ cc;
if (c == 1) { C_SET; } else { C_UNSET;} if (c == 1) { C_SET; } else { C_UNSET;}
if (v == 1) { V_SET; } else { V_UNSET; } if (v == 1) { V_SET; } else { V_UNSET; }
@ -124,6 +123,37 @@ db subtractor(db a, db b)
return adder(a, b); return adder(a, b);
} }
void push_byte(db data)
{
write_mem(sp, data);
sp = sp - 1;
}
void push_word(dw data)
{
db high = data & 0xFF;
db low = data >> 8;
push_byte(high);
push_byte(low);
}
db pull_byte()
{
sp = sp + 1;
return read_byte(sp);
}
dw pull_word()
{
dw data;
data = pull_byte() << 8;
data = data | pull_byte();
return data;
}
void adc() void adc()
{ {
// add memory to accumulator with carry // add memory to accumulator with carry
@ -143,7 +173,19 @@ void asl()
{ {
// shift left one bit (memory or accumulator) // shift left one bit (memory or accumulator)
fetch_operand(); fetch_operand();
if (operand >> 7) { C_SET; } else { C_UNSET; }
operand = operand << 1; operand = operand << 1;
if (address_mode == accumulator)
{
ac = operand;
}
else
{
write_mem(address, operand);
}
adjustNZ(operand); adjustNZ(operand);
} }
@ -180,6 +222,10 @@ void beq()
void bit() void bit()
{ {
// test bits in memory with accumulator // test bits in memory with accumulator
fetch_operand();
if (operand & 0b10000000) { N_SET; } else { N_UNSET; }
if (operand & 0b01000000) { V_SET; } else { V_UNSET; }
if (operand & ac) { Z_SET; } else { Z_UNSET; }
} }
void bmi() void bmi()
@ -215,6 +261,9 @@ void bpl()
void brk() void brk()
{ {
// force break // force break
I_SET;
push_word(pc);
push_byte(sr);
} }
void bvc() void bvc()
@ -264,21 +313,28 @@ void clv()
void cmp() void cmp()
{ {
// compare memory with accumulator // compare memory with accumulator
fetch_operand();
subtractor(ac, operand);
} }
void cpx() void cpx()
{ {
// compare memory and index x // compare memory and index x
fetch_operand();
subtractor(x, operand);
} }
void cpy() void cpy()
{ {
// compare memory and index y // compare memory and index y
fetch_operand();
subtractor(y, operand);
} }
void dec() void dec()
{ {
// decrement memory by one // decrement memory by one
fetch_operand();
operand = operand - 1; operand = operand - 1;
write_mem(address, operand); write_mem(address, operand);
adjustNZ(operand); adjustNZ(operand);
@ -301,13 +357,18 @@ void dey()
void eor() void eor()
{ {
// exclusive-or memory with accumulator // exclusive-or memory with accumulator
fetch_operand();
ac = ac ^ operand;
adjustNZ(ac);
} }
void inc() void inc()
{ {
// increment memory by one // increment memory by one
fetch_operand();
operand = operand + 1; operand = operand + 1;
write_mem(address, operand); write_mem(address, operand);
adjustNZ(operand);
} }
void inx() void inx()
@ -342,29 +403,53 @@ void jpa()
void jsr() void jsr()
{ {
// jump to new location saving return address // jump to new location saving return address
push_word(pc);
address = read_word(pc);
pc = address;
} }
void lda() void lda()
{ {
// load accumulator with memory // load accumulator with memory
fetch_operand();
ac = operand; ac = operand;
adjustNZ(ac);
} }
void ldx() void ldx()
{ {
// load index x with memory // load index x with memory
fetch_operand();
x = operand; x = operand;
adjustNZ(x);
} }
void ldy() void ldy()
{ {
// load index y with memory // load index y with memory
fetch_operand();
y = operand; y = operand;
adjustNZ(y);
} }
void lsr() void lsr()
{ {
// shift one bit right (memory or accumulator) // shift one bit right (memory or accumulator)
fetch_operand();
if (operand & 1) { C_SET; } else { C_UNSET; }
operand = operand >> 1;
if (address_mode == accumulator)
{
ac = operand;
}
else
{
write_mem(address, operand);
}
adjustNZ(operand);
} }
void nop() void nop()
@ -375,51 +460,99 @@ void nop()
void ora() void ora()
{ {
// or memory with accumulator // or memory with accumulator
fetch_operand();
ac = ac | operand;
adjustNZ(ac);
} }
void pha() void pha()
{ {
// push accumulator on stack // push accumulator on stack
push_byte(ac);
} }
void php() void php()
{ {
// push processor status on stack // push processor status on stack
push_byte(sr);
} }
void pla() void pla()
{ {
// pull accumulator from stack // pull accumulator from stack
ac = pull_byte();
} }
void plp() void plp()
{ {
// pull processor status from stack // pull processor status from stack
sr = pull_byte();
} }
void rol() void rol()
{ {
// rotate on bit left (memory or accumulator) // rotate on bit left (memory or accumulator)
db carry = C_IS_SET;
fetch_operand();
if (operand >> 7) { C_SET; } else { C_UNSET; }
operand = operand << 1;
operand = operand | carry;
if (address_mode == accumulator)
{
ac = operand;
}
else
{
write_mem(address, operand);
}
adjustNZ(operand);
} }
void ror() void ror()
{ {
// rotate on bit right (memory or accumulator) // rotate on bit right (memory or accumulator)
db carry = C_IS_SET << 7;
fetch_operand();
if (operand & 1) { C_SET; } else { C_UNSET; }
operand = operand >> 1;
operand = operand | carry;
if (address_mode == accumulator)
{
ac = operand;
}
else
{
write_mem(address, operand);
}
adjustNZ(operand);
} }
void rti() void rti()
{ {
// return from interrupt // return from interrupt
sr = pull_byte();
pc = pull_word();
} }
void rts() void rts()
{ {
// retrun from subroutine // retrun from subroutine
pc = pull_word();
} }
void sbc() void sbc()
{ {
// subtract memory from accumulator with borrow // subtract memory from accumulator with borrow
fetch_operand();
ac = subtractor(ac, operand - C_IS_SET);
} }
void sec() void sec()
@ -443,22 +576,25 @@ void sei()
void sta() void sta()
{ {
// store accumulator in memory // store accumulator in memory
fetch_operand();
write_mem(address, ac); write_mem(address, ac);
adjustNZ(y); //adjustNZ(y);
} }
void stx() void stx()
{ {
// store index x in memory // store index x in memory
fetch_operand();
write_mem(address, x); write_mem(address, x);
adjustNZ(x); //adjustNZ(x);
} }
void sty() void sty()
{ {
// store index y in memory // store index y in memory
fetch_operand();
write_mem(address, y); write_mem(address, y);
adjustNZ(y); //adjustNZ(y);
} }
void tax() void tax()