correcting pc on branches and jumps

This commit is contained in:
Thiago Auler 2017-11-17 09:23:46 -02:00 committed by GitHub
parent 3cfe0390b8
commit 6eb4aaa858
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 21 additions and 48 deletions

View File

@ -77,12 +77,16 @@ void fetch_operand()
break; break;
case relative: case relative:
operand = read_byte(pc); operand = read_byte(pc);
pc = pc + 1;
if ((operand >> 7) == 0) if ((operand >> 7) == 0)
{ {
address = pc + operand; address = pc + operand;
} }
else else
{ {
// negate b operand using 2's complement
operand = operand ^ 0xFF;
operand = operand + 1;
address = pc - operand; address = pc - operand;
} }
break; break;
@ -131,11 +135,11 @@ void push_byte(db data)
void push_word(dw data) void push_word(dw data)
{ {
db high = data & 0xFF; db low = data & 0xFF;
db low = data >> 8; db high = data >> 8;
push_byte(high);
push_byte(low); push_byte(low);
push_byte(high);
} }
db pull_byte() db pull_byte()
@ -146,10 +150,9 @@ db pull_byte()
dw pull_word() dw pull_word()
{ {
dw data; db high = pull_byte() << 8;
db low = pull_byte();
data = pull_byte() << 8; dw data = high | low;
data = data | pull_byte();
return data; return data;
} }
@ -192,43 +195,31 @@ void asl()
void bcc() void bcc()
{ {
// branch on carry clear // branch on carry clear
fetch_operand();
if(!C_IS_SET) if(!C_IS_SET)
{ {
fetch_operand();
pc = address; pc = address;
} }
else
{
pc = pc + 1;
}
} }
void bcs() void bcs()
{ {
// branch on carry set // branch on carry set
fetch_operand();
if(C_IS_SET) if(C_IS_SET)
{ {
fetch_operand();
pc = address; pc = address;
} }
else
{
pc = pc + 1;
}
} }
void beq() void beq()
{ {
// branch on result zero // branch on result zero
fetch_operand();
if(Z_IS_SET) if(Z_IS_SET)
{ {
fetch_operand();
pc = address; pc = address;
} }
else
{
pc = pc + 1;
}
} }
void bit() void bit()
@ -243,43 +234,31 @@ void bit()
void bmi() void bmi()
{ {
// branch on result minus // branch on result minus
fetch_operand();
if(N_IS_SET) if(N_IS_SET)
{ {
fetch_operand();
pc = address; pc = address;
} }
else
{
pc = pc + 1;
}
} }
void bne() void bne()
{ {
// branch on result not zero // branch on result not zero
fetch_operand();
if(!Z_IS_SET) if(!Z_IS_SET)
{ {
fetch_operand();
pc = address; pc = address;
} }
else
{
pc = pc + 1;
}
} }
void bpl() void bpl()
{ {
// branch on result plus // branch on result plus
fetch_operand();
if(!N_IS_SET) if(!N_IS_SET)
{ {
fetch_operand();
pc = address; pc = address;
} }
else
{
pc = pc + 1;
}
} }
void brk() void brk()
@ -293,29 +272,21 @@ void brk()
void bvc() void bvc()
{ {
// branch on overflow clear // branch on overflow clear
fetch_operand();
if(!V_IS_SET) if(!V_IS_SET)
{ {
fetch_operand();
pc = address; pc = address;
} }
else
{
pc = pc + 1;
}
} }
void bvs() void bvs()
{ {
// branch on overflow set // branch on overflow set
fetch_operand();
if(V_IS_SET) if(V_IS_SET)
{ {
fetch_operand();
pc = address; pc = address;
} }
else
{
pc = pc + 1;
}
} }
void clc() void clc()
@ -435,8 +406,10 @@ 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); address = read_word(pc);
pc = pc + 2;
push_word(pc);
pc = address; pc = address;
} }