mirror of
https://github.com/pevans/erc-c.git
synced 2024-08-21 00:29:00 +00:00
Moar documentation
This commit is contained in:
parent
fca069d5de
commit
ccd7a3f665
@ -5,44 +5,76 @@
|
||||
#include "mos6502.h"
|
||||
#include "mos6502.enums.h"
|
||||
|
||||
/*
|
||||
* This is just a minor convenience macro to wrap the logic we use in
|
||||
* branch situations, which is if `cond` is true, then we set the
|
||||
* program counter to the last effective address.
|
||||
*/
|
||||
#define JUMP_IF(cond) \
|
||||
if (cond) cpu->PC = cpu->last_addr
|
||||
|
||||
/*
|
||||
* Branch if the carry flag is clear.
|
||||
*/
|
||||
DEFINE_INST(bcc)
|
||||
{
|
||||
JUMP_IF(~cpu->P & CARRY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Branch if carry is set.
|
||||
*/
|
||||
DEFINE_INST(bcs)
|
||||
{
|
||||
JUMP_IF(cpu->P & CARRY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Branch if the zero flag is set (that is, if our last instruction
|
||||
* resulted in something being _equal to zero_).
|
||||
*/
|
||||
DEFINE_INST(beq)
|
||||
{
|
||||
JUMP_IF(cpu->P & ZERO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Branch if the negative ("minus") flag is set.
|
||||
*/
|
||||
DEFINE_INST(bmi)
|
||||
{
|
||||
JUMP_IF(cpu->P & NEGATIVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Branch if the zero flag is not set; which is to say, that the last
|
||||
* operation was _not equal_ to zero.
|
||||
*/
|
||||
DEFINE_INST(bne)
|
||||
{
|
||||
JUMP_IF(~cpu->P & ZERO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Branch if the negative flag is not set (meaning the last operation
|
||||
* was "plus", which includes zero).
|
||||
*/
|
||||
DEFINE_INST(bpl)
|
||||
{
|
||||
JUMP_IF(~cpu->P & NEGATIVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Branch if the overflow bit is clear.
|
||||
*/
|
||||
DEFINE_INST(bvc)
|
||||
{
|
||||
JUMP_IF(~cpu->P & OVERFLOW);
|
||||
}
|
||||
|
||||
/*
|
||||
* Branch if the overflow bit is set.
|
||||
*/
|
||||
DEFINE_INST(bvs)
|
||||
{
|
||||
JUMP_IF(cpu->P & OVERFLOW);
|
||||
|
@ -5,6 +5,10 @@
|
||||
#include "mos6502.h"
|
||||
#include "mos6502.enums.h"
|
||||
|
||||
/*
|
||||
* The BRK instruction will set the interrupt bit; will push the current
|
||||
* PC address to the stack; and will advance the counter by 2 positions.
|
||||
*/
|
||||
DEFINE_INST(brk)
|
||||
{
|
||||
cpu->P |= INTERRUPT;
|
||||
@ -12,27 +16,48 @@ DEFINE_INST(brk)
|
||||
cpu->PC += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* A jump is straight forward; whatever the effective address is, that
|
||||
* is now the new value of the PC register.
|
||||
*/
|
||||
DEFINE_INST(jmp)
|
||||
{
|
||||
cpu->PC = cpu->last_addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Meanwhile, a JSR (or jump to subroutine) is a little more nuanced. We
|
||||
* record our current position, plus two, to the stack, and jump the
|
||||
* effective address.
|
||||
*/
|
||||
DEFINE_INST(jsr)
|
||||
{
|
||||
mos6502_push_stack(cpu, cpu->PC + 2);
|
||||
cpu->PC = cpu->last_addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* The NOP instruction is short for no-operation. It does nothing except
|
||||
* waste cycles (which happens elsewhere).
|
||||
*/
|
||||
DEFINE_INST(nop)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we return from an interrupt, which effectively resets the PC
|
||||
* register to the last value on the stack.
|
||||
*/
|
||||
DEFINE_INST(rti)
|
||||
{
|
||||
cpu->PC = mos6502_pop_stack(cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
* The RTS instruction (return from subroutine) works the same as the
|
||||
* RTI instruction, which may or may not be a misconception on my part.
|
||||
*/
|
||||
DEFINE_INST(rts)
|
||||
{
|
||||
cpu->PC = mos6502_pop_stack(cpu);
|
||||
|
@ -5,89 +5,140 @@
|
||||
#include "mos6502.h"
|
||||
#include "mos6502.enums.h"
|
||||
|
||||
/*
|
||||
* The LDA instruction will assign ("load") an operand into the
|
||||
* accumulator.
|
||||
*/
|
||||
DEFINE_INST(lda)
|
||||
{
|
||||
mos6502_modify_status(cpu, ZERO | NEGATIVE, oper);
|
||||
cpu->A = oper;
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to LDA, except targeting X.
|
||||
*/
|
||||
DEFINE_INST(ldx)
|
||||
{
|
||||
mos6502_modify_status(cpu, ZERO | NEGATIVE, oper);
|
||||
cpu->X = oper;
|
||||
}
|
||||
|
||||
/*
|
||||
* Again similar to LDA, except with Y.
|
||||
*/
|
||||
DEFINE_INST(ldy)
|
||||
{
|
||||
mos6502_modify_status(cpu, ZERO | NEGATIVE, oper);
|
||||
cpu->Y = oper;
|
||||
}
|
||||
|
||||
/*
|
||||
* This instruction will "push" the A register onto the stack.
|
||||
*/
|
||||
DEFINE_INST(pha)
|
||||
{
|
||||
mos6502_push_stack(cpu, cpu->A);
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to above, but will push the P register.
|
||||
*/
|
||||
DEFINE_INST(php)
|
||||
{
|
||||
mos6502_push_stack(cpu, cpu->P);
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we pop the stack (or "pull" it), and assign to the accumulator.
|
||||
*/
|
||||
DEFINE_INST(pla)
|
||||
{
|
||||
cpu->A = mos6502_pop_stack(cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Again we pop from the stack, but assign to the P register.
|
||||
*/
|
||||
DEFINE_INST(plp)
|
||||
{
|
||||
cpu->P = mos6502_pop_stack(cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
* The STA instruction assigns the value of the accumulator to a given
|
||||
* address in memory. (That is to say, it "stores" it.)
|
||||
*/
|
||||
DEFINE_INST(sta)
|
||||
{
|
||||
vm_segment_set(cpu->memory, cpu->last_addr, cpu->A);
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to STA, but drawing from the X register.
|
||||
*/
|
||||
DEFINE_INST(stx)
|
||||
{
|
||||
vm_segment_set(cpu->memory, cpu->last_addr, cpu->X);
|
||||
}
|
||||
|
||||
/*
|
||||
* And, again, similar to STA, but with the Y register.
|
||||
*/
|
||||
DEFINE_INST(sty)
|
||||
{
|
||||
vm_segment_set(cpu->memory, cpu->last_addr, cpu->Y);
|
||||
}
|
||||
|
||||
/*
|
||||
* The TAX instruction taxes no one but your patience for my puns. What
|
||||
* it does do is transfer the contents of the A register to X.
|
||||
*/
|
||||
DEFINE_INST(tax)
|
||||
{
|
||||
mos6502_modify_status(cpu, ZERO | NEGATIVE, cpu->A);
|
||||
cpu->X = cpu->A;
|
||||
}
|
||||
|
||||
/*
|
||||
* This transfers from A to Y.
|
||||
*/
|
||||
DEFINE_INST(tay)
|
||||
{
|
||||
mos6502_modify_status(cpu, ZERO | NEGATIVE, cpu->A);
|
||||
cpu->Y = cpu->A;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transfer the stack pointer (S register) to X.
|
||||
*/
|
||||
DEFINE_INST(tsx)
|
||||
{
|
||||
mos6502_modify_status(cpu, ZERO | NEGATIVE, cpu->S);
|
||||
cpu->X = cpu->S;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transfer the X register to A.
|
||||
*/
|
||||
DEFINE_INST(txa)
|
||||
{
|
||||
mos6502_modify_status(cpu, ZERO | NEGATIVE, cpu->X);
|
||||
cpu->A = cpu->X;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transfer the X register to S.
|
||||
*/
|
||||
DEFINE_INST(txs)
|
||||
{
|
||||
mos6502_modify_status(cpu, ZERO | NEGATIVE, cpu->X);
|
||||
cpu->S = cpu->X;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transfer the Y register to A.
|
||||
*/
|
||||
DEFINE_INST(tya)
|
||||
{
|
||||
mos6502_modify_status(cpu, ZERO | NEGATIVE, cpu->Y);
|
||||
|
@ -5,36 +5,57 @@
|
||||
#include "mos6502.h"
|
||||
#include "mos6502.enums.h"
|
||||
|
||||
/*
|
||||
* Clear the carry bit in the status register.
|
||||
*/
|
||||
DEFINE_INST(clc)
|
||||
{
|
||||
cpu->P &= ~CARRY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the decimal bit.
|
||||
*/
|
||||
DEFINE_INST(cld)
|
||||
{
|
||||
cpu->P &= ~DECIMAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the interrupt bit.
|
||||
*/
|
||||
DEFINE_INST(cli)
|
||||
{
|
||||
cpu->P &= ~INTERRUPT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the overflow bit.
|
||||
*/
|
||||
DEFINE_INST(clv)
|
||||
{
|
||||
cpu->P &= ~OVERFLOW;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the carry bit.
|
||||
*/
|
||||
DEFINE_INST(sec)
|
||||
{
|
||||
cpu->P |= CARRY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the decimal bit.
|
||||
*/
|
||||
DEFINE_INST(sed)
|
||||
{
|
||||
cpu->P |= DECIMAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the interrupt bit.
|
||||
*/
|
||||
DEFINE_INST(sei)
|
||||
{
|
||||
cpu->P |= INTERRUPT;
|
||||
|
Loading…
Reference in New Issue
Block a user