mirror of
https://github.com/bradford-hamilton/apple-1.git
synced 2024-06-12 00:29:26 +00:00
internal/vm/{cpu,exec_funcs,opcodes,vm}: rename op -> operation for clarity (I hope), also general refactors
This commit is contained in:
parent
1b3f1f5b1f
commit
b7a3ec4a6c
|
@ -71,7 +71,7 @@ const (
|
||||||
// StackBottom represents the start of the stack
|
// StackBottom represents the start of the stack
|
||||||
const StackBottom uint16 = 0x0100 // 256
|
const StackBottom uint16 = 0x0100 // 256
|
||||||
|
|
||||||
// Mos6502 TODO: docs
|
// Mos6502 represents the cpu's registers
|
||||||
type Mos6502 struct {
|
type Mos6502 struct {
|
||||||
sp byte // register - stack pointer
|
sp byte // register - stack pointer
|
||||||
pc uint16 // register - program counter
|
pc uint16 // register - program counter
|
||||||
|
|
|
@ -2,7 +2,7 @@ package vm
|
||||||
|
|
||||||
// interrupt, N Z C I D V
|
// interrupt, N Z C I D V
|
||||||
// push PC+2, push SR - - - 1 - -
|
// push PC+2, push SR - - - 1 - -
|
||||||
func execBRK(a *Appleone, o op) error {
|
func execBRK(a *Appleone, o operation) error {
|
||||||
// set processer status flag to BRK
|
// set processer status flag to BRK
|
||||||
a.cpu.ps = flagBreak
|
a.cpu.ps = flagBreak
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ func execBRK(a *Appleone, o op) error {
|
||||||
|
|
||||||
// pull SR, pull PC N Z C I D V
|
// pull SR, pull PC N Z C I D V
|
||||||
// from stack
|
// from stack
|
||||||
func execRTI(a *Appleone, o op) error {
|
func execRTI(a *Appleone, o operation) error {
|
||||||
a.cpu.ps = a.popStackWord()
|
a.cpu.ps = a.popStackWord()
|
||||||
a.cpu.pc = a.popStackDWord()
|
a.cpu.pc = a.popStackDWord()
|
||||||
return nil
|
return nil
|
||||||
|
@ -25,7 +25,7 @@ func execRTI(a *Appleone, o op) error {
|
||||||
|
|
||||||
// M - 1 -> M N Z C I D V
|
// M - 1 -> M N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execDEC(a *Appleone, o op) error {
|
func execDEC(a *Appleone, o operation) error {
|
||||||
addr, err := a.getAddr(o)
|
addr, err := a.getAddr(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -40,7 +40,7 @@ func execDEC(a *Appleone, o op) error {
|
||||||
|
|
||||||
// M + 1 -> M N Z C I D V
|
// M + 1 -> M N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execINC(a *Appleone, o op) error {
|
func execINC(a *Appleone, o operation) error {
|
||||||
addr, err := a.getAddr(o)
|
addr, err := a.getAddr(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -55,7 +55,7 @@ func execINC(a *Appleone, o op) error {
|
||||||
|
|
||||||
// X + 1 -> X N Z C I D V
|
// X + 1 -> X N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execINX(a *Appleone, o op) error {
|
func execINX(a *Appleone, o operation) error {
|
||||||
a.cpu.x++
|
a.cpu.x++
|
||||||
a.maybeSetFlagZero(a.cpu.x)
|
a.maybeSetFlagZero(a.cpu.x)
|
||||||
a.maybeSetFlagOverflow(a.cpu.x)
|
a.maybeSetFlagOverflow(a.cpu.x)
|
||||||
|
@ -64,7 +64,7 @@ func execINX(a *Appleone, o op) error {
|
||||||
|
|
||||||
// Y + 1 -> Y N Z C I D V
|
// Y + 1 -> Y N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execINY(a *Appleone, o op) error {
|
func execINY(a *Appleone, o operation) error {
|
||||||
a.cpu.y++
|
a.cpu.y++
|
||||||
a.maybeSetFlagZero(a.cpu.y)
|
a.maybeSetFlagZero(a.cpu.y)
|
||||||
a.maybeSetFlagOverflow(a.cpu.y)
|
a.maybeSetFlagOverflow(a.cpu.y)
|
||||||
|
@ -73,7 +73,7 @@ func execINY(a *Appleone, o op) error {
|
||||||
|
|
||||||
// A -> X N Z C I D V
|
// A -> X N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execTAX(a *Appleone, o op) error {
|
func execTAX(a *Appleone, o operation) error {
|
||||||
a.cpu.x = a.cpu.a
|
a.cpu.x = a.cpu.a
|
||||||
a.maybeSetFlagZero(a.cpu.x)
|
a.maybeSetFlagZero(a.cpu.x)
|
||||||
a.maybeSetFlagOverflow(a.cpu.x)
|
a.maybeSetFlagOverflow(a.cpu.x)
|
||||||
|
@ -82,7 +82,7 @@ func execTAX(a *Appleone, o op) error {
|
||||||
|
|
||||||
// A -> Y N Z C I D V
|
// A -> Y N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execTAY(a *Appleone, o op) error {
|
func execTAY(a *Appleone, o operation) error {
|
||||||
a.cpu.y = a.cpu.a
|
a.cpu.y = a.cpu.a
|
||||||
a.maybeSetFlagZero(a.cpu.y)
|
a.maybeSetFlagZero(a.cpu.y)
|
||||||
a.maybeSetFlagOverflow(a.cpu.y)
|
a.maybeSetFlagOverflow(a.cpu.y)
|
||||||
|
@ -91,7 +91,7 @@ func execTAY(a *Appleone, o op) error {
|
||||||
|
|
||||||
// X - 1 -> X N Z C I D V
|
// X - 1 -> X N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execDEX(a *Appleone, o op) error {
|
func execDEX(a *Appleone, o operation) error {
|
||||||
a.cpu.x--
|
a.cpu.x--
|
||||||
a.maybeSetFlagZero(a.cpu.x)
|
a.maybeSetFlagZero(a.cpu.x)
|
||||||
a.maybeSetFlagOverflow(a.cpu.x)
|
a.maybeSetFlagOverflow(a.cpu.x)
|
||||||
|
@ -100,7 +100,7 @@ func execDEX(a *Appleone, o op) error {
|
||||||
|
|
||||||
// Y - 1 -> Y N Z C I D V
|
// Y - 1 -> Y N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execDEY(a *Appleone, o op) error {
|
func execDEY(a *Appleone, o operation) error {
|
||||||
a.cpu.y--
|
a.cpu.y--
|
||||||
a.maybeSetFlagZero(a.cpu.y)
|
a.maybeSetFlagZero(a.cpu.y)
|
||||||
a.maybeSetFlagOverflow(a.cpu.y)
|
a.maybeSetFlagOverflow(a.cpu.y)
|
||||||
|
@ -109,7 +109,7 @@ func execDEY(a *Appleone, o op) error {
|
||||||
|
|
||||||
// M -> A N Z C I D V
|
// M -> A N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execLDA(a *Appleone, o op) error {
|
func execLDA(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -122,7 +122,7 @@ func execLDA(a *Appleone, o op) error {
|
||||||
|
|
||||||
// M -> X N Z C I D V
|
// M -> X N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execLDX(a *Appleone, o op) error {
|
func execLDX(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -135,7 +135,7 @@ func execLDX(a *Appleone, o op) error {
|
||||||
|
|
||||||
// M -> Y N Z C I D V
|
// M -> Y N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execLDY(a *Appleone, o op) error {
|
func execLDY(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -148,7 +148,7 @@ func execLDY(a *Appleone, o op) error {
|
||||||
|
|
||||||
// A + M + C -> A, C N Z C I D V
|
// A + M + C -> A, C N Z C I D V
|
||||||
// + + + - - +
|
// + + + - - +
|
||||||
func execADC(a *Appleone, o op) error {
|
func execADC(a *Appleone, o operation) error {
|
||||||
b, err := a.getOperand(o)
|
b, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -177,7 +177,7 @@ func execADC(a *Appleone, o op) error {
|
||||||
|
|
||||||
// A - M - C -> A N Z C I D V
|
// A - M - C -> A N Z C I D V
|
||||||
// + + + - - +
|
// + + + - - +
|
||||||
func execSBC(a *Appleone, o op) error {
|
func execSBC(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -211,7 +211,7 @@ func execSBC(a *Appleone, o op) error {
|
||||||
|
|
||||||
// X -> M N Z C I D V
|
// X -> M N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execSTX(a *Appleone, o op) error {
|
func execSTX(a *Appleone, o operation) error {
|
||||||
addr, err := a.getAddr(o)
|
addr, err := a.getAddr(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -222,7 +222,7 @@ func execSTX(a *Appleone, o op) error {
|
||||||
|
|
||||||
// Y -> M N Z C I D V
|
// Y -> M N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execSTY(a *Appleone, o op) error {
|
func execSTY(a *Appleone, o operation) error {
|
||||||
addr, err := a.getAddr(o)
|
addr, err := a.getAddr(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -233,7 +233,7 @@ func execSTY(a *Appleone, o op) error {
|
||||||
|
|
||||||
// A -> M N Z C I D V
|
// A -> M N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execSTA(a *Appleone, o op) error {
|
func execSTA(a *Appleone, o operation) error {
|
||||||
addr, err := a.getAddr(o)
|
addr, err := a.getAddr(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -244,7 +244,7 @@ func execSTA(a *Appleone, o op) error {
|
||||||
|
|
||||||
// branch on Z = 1 N Z C I D V
|
// branch on Z = 1 N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execBEQ(a *Appleone, o op) error {
|
func execBEQ(a *Appleone, o operation) error {
|
||||||
if a.getFlag(flagZero) == flagZero {
|
if a.getFlag(flagZero) == flagZero {
|
||||||
a.branch(o)
|
a.branch(o)
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ func execBEQ(a *Appleone, o op) error {
|
||||||
|
|
||||||
// branch on Z = 0 N Z C I D V
|
// branch on Z = 0 N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execBNE(a *Appleone, o op) error {
|
func execBNE(a *Appleone, o operation) error {
|
||||||
if a.getFlag(flagZero) != flagZero {
|
if a.getFlag(flagZero) != flagZero {
|
||||||
a.branch(o)
|
a.branch(o)
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ func execBNE(a *Appleone, o op) error {
|
||||||
|
|
||||||
// branch on V = 0 N Z C I D V
|
// branch on V = 0 N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execBVC(a *Appleone, o op) error {
|
func execBVC(a *Appleone, o operation) error {
|
||||||
if a.getFlag(flagOverflow) == 0 {
|
if a.getFlag(flagOverflow) == 0 {
|
||||||
a.branch(o)
|
a.branch(o)
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ func execBVC(a *Appleone, o op) error {
|
||||||
|
|
||||||
// branch on V = 1 N Z C I D V
|
// branch on V = 1 N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execBVS(a *Appleone, o op) error {
|
func execBVS(a *Appleone, o operation) error {
|
||||||
if a.getFlag(flagOverflow) != 0 {
|
if a.getFlag(flagOverflow) != 0 {
|
||||||
a.branch(o)
|
a.branch(o)
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ func execBVS(a *Appleone, o op) error {
|
||||||
|
|
||||||
// bits 7 and 6 of operand are transfered to bit 7 and 6 of SR (N,V);
|
// bits 7 and 6 of operand are transfered to bit 7 and 6 of SR (N,V);
|
||||||
// the zeroflag is set to the result of operand AND accumulator.
|
// the zeroflag is set to the result of operand AND accumulator.
|
||||||
func execBIT(a *Appleone, o op) error {
|
func execBIT(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -298,7 +298,7 @@ func execBIT(a *Appleone, o op) error {
|
||||||
|
|
||||||
// branch on C = 0 N Z C I D V
|
// branch on C = 0 N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execBCC(a *Appleone, o op) error {
|
func execBCC(a *Appleone, o operation) error {
|
||||||
if a.getFlag(flagCarry) == 0 {
|
if a.getFlag(flagCarry) == 0 {
|
||||||
a.branch(o)
|
a.branch(o)
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ func execBCC(a *Appleone, o op) error {
|
||||||
|
|
||||||
// branch on N = 1 N Z C I D V
|
// branch on N = 1 N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execBMI(a *Appleone, o op) error {
|
func execBMI(a *Appleone, o operation) error {
|
||||||
if a.getFlag(flagNegative) == flagNegative {
|
if a.getFlag(flagNegative) == flagNegative {
|
||||||
a.branch(o)
|
a.branch(o)
|
||||||
}
|
}
|
||||||
|
@ -316,7 +316,7 @@ func execBMI(a *Appleone, o op) error {
|
||||||
|
|
||||||
// branch on N = 0 N Z C I D V
|
// branch on N = 0 N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execBPL(a *Appleone, o op) error {
|
func execBPL(a *Appleone, o operation) error {
|
||||||
if a.getFlag(flagNegative) == 0 {
|
if a.getFlag(flagNegative) == 0 {
|
||||||
a.branch(o)
|
a.branch(o)
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ func execBPL(a *Appleone, o op) error {
|
||||||
|
|
||||||
// branch on C = 1 N Z C I D V
|
// branch on C = 1 N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execBCS(a *Appleone, o op) error {
|
func execBCS(a *Appleone, o operation) error {
|
||||||
if a.getFlag(flagCarry) != 0 {
|
if a.getFlag(flagCarry) != 0 {
|
||||||
a.branch(o)
|
a.branch(o)
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ func execBCS(a *Appleone, o op) error {
|
||||||
|
|
||||||
// X - M N Z C I D V
|
// X - M N Z C I D V
|
||||||
// + + + - - -
|
// + + + - - -
|
||||||
func execCPX(a *Appleone, o op) error {
|
func execCPX(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -345,7 +345,7 @@ func execCPX(a *Appleone, o op) error {
|
||||||
|
|
||||||
// A EOR M -> A N Z C I D V
|
// A EOR M -> A N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execEOR(a *Appleone, o op) error {
|
func execEOR(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -358,7 +358,7 @@ func execEOR(a *Appleone, o op) error {
|
||||||
|
|
||||||
// A - M N Z C I D V
|
// A - M N Z C I D V
|
||||||
// + + + - - -
|
// + + + - - -
|
||||||
func execCMP(a *Appleone, o op) error {
|
func execCMP(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -369,7 +369,7 @@ func execCMP(a *Appleone, o op) error {
|
||||||
|
|
||||||
// Y - M N Z C I D V
|
// Y - M N Z C I D V
|
||||||
// + + + - - -
|
// + + + - - -
|
||||||
func execCPY(a *Appleone, o op) error {
|
func execCPY(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -380,62 +380,62 @@ func execCPY(a *Appleone, o op) error {
|
||||||
|
|
||||||
// 0 -> C N Z C I D V
|
// 0 -> C N Z C I D V
|
||||||
// - - 0 - - -
|
// - - 0 - - -
|
||||||
func execCLC(a *Appleone, o op) error {
|
func execCLC(a *Appleone, o operation) error {
|
||||||
a.clearFlag(flagCarry)
|
a.clearFlag(flagCarry)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 -> D N Z C I D V
|
// 0 -> D N Z C I D V
|
||||||
// - - - - 0 -
|
// - - - - 0 -
|
||||||
func execCLD(a *Appleone, o op) error {
|
func execCLD(a *Appleone, o operation) error {
|
||||||
a.clearFlag(flagDecimalMode)
|
a.clearFlag(flagDecimalMode)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 -> I N Z C I D V
|
// 0 -> I N Z C I D V
|
||||||
// - - - 0 - -
|
// - - - 0 - -
|
||||||
func execCLI(a *Appleone, o op) error {
|
func execCLI(a *Appleone, o operation) error {
|
||||||
a.clearFlag(flagDisableInterrupts)
|
a.clearFlag(flagDisableInterrupts)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 -> V N Z C I D V
|
// 0 -> V N Z C I D V
|
||||||
// - - - - - 0
|
// - - - - - 0
|
||||||
func execCLV(a *Appleone, o op) error {
|
func execCLV(a *Appleone, o operation) error {
|
||||||
a.clearFlag(flagOverflow)
|
a.clearFlag(flagOverflow)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 -> C N Z C I D V
|
// 1 -> C N Z C I D V
|
||||||
// - - 1 - - -
|
// - - 1 - - -
|
||||||
func execSEC(a *Appleone, o op) error {
|
func execSEC(a *Appleone, o operation) error {
|
||||||
a.setFlag(flagCarry)
|
a.setFlag(flagCarry)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 -> D N Z C I D V
|
// 1 -> D N Z C I D V
|
||||||
// - - - - 1 -
|
// - - - - 1 -
|
||||||
func execSED(a *Appleone, o op) error {
|
func execSED(a *Appleone, o operation) error {
|
||||||
a.setFlag(flagDecimalMode)
|
a.setFlag(flagDecimalMode)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 -> I N Z C I D V
|
// 1 -> I N Z C I D V
|
||||||
// - - - 1 - -
|
// - - - 1 - -
|
||||||
func execSEI(a *Appleone, o op) error {
|
func execSEI(a *Appleone, o operation) error {
|
||||||
a.setFlag(flagDisableInterrupts)
|
a.setFlag(flagDisableInterrupts)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- N Z C I D V
|
// --- N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execNOP(a *Appleone, o op) error {
|
func execNOP(a *Appleone, o operation) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// (PC+1) -> PCL N Z C I D V
|
// (PC+1) -> PCL N Z C I D V
|
||||||
// (PC+2) -> PCH - - - - - -
|
// (PC+2) -> PCH - - - - - -
|
||||||
func execJMP(a *Appleone, o op) error {
|
func execJMP(a *Appleone, o operation) error {
|
||||||
if o.addrMode == indirect {
|
if o.addrMode == indirect {
|
||||||
addr, err := a.getAddr(o)
|
addr, err := a.getAddr(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -454,14 +454,14 @@ func execJMP(a *Appleone, o op) error {
|
||||||
|
|
||||||
// push A N Z C I D V
|
// push A N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execPHA(a *Appleone, o op) error {
|
func execPHA(a *Appleone, o operation) error {
|
||||||
a.pushWordToStack(a.cpu.a)
|
a.pushWordToStack(a.cpu.a)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// X -> A N Z C I D V
|
// X -> A N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execTXA(a *Appleone, o op) error {
|
func execTXA(a *Appleone, o operation) error {
|
||||||
a.cpu.a = a.cpu.x
|
a.cpu.a = a.cpu.x
|
||||||
a.maybeSetFlagOverflow(a.cpu.a)
|
a.maybeSetFlagOverflow(a.cpu.a)
|
||||||
a.maybeSetFlagZero(a.cpu.a)
|
a.maybeSetFlagZero(a.cpu.a)
|
||||||
|
@ -470,7 +470,7 @@ func execTXA(a *Appleone, o op) error {
|
||||||
|
|
||||||
// Y -> A N Z C I D V
|
// Y -> A N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execTYA(a *Appleone, o op) error {
|
func execTYA(a *Appleone, o operation) error {
|
||||||
a.cpu.a = a.cpu.y
|
a.cpu.a = a.cpu.y
|
||||||
a.maybeSetFlagOverflow(a.cpu.a)
|
a.maybeSetFlagOverflow(a.cpu.a)
|
||||||
a.maybeSetFlagZero(a.cpu.a)
|
a.maybeSetFlagZero(a.cpu.a)
|
||||||
|
@ -479,7 +479,7 @@ func execTYA(a *Appleone, o op) error {
|
||||||
|
|
||||||
// SP -> X N Z C I D V
|
// SP -> X N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execTSX(a *Appleone, o op) error {
|
func execTSX(a *Appleone, o operation) error {
|
||||||
a.cpu.x = a.cpu.sp
|
a.cpu.x = a.cpu.sp
|
||||||
a.maybeSetFlagOverflow(a.cpu.x)
|
a.maybeSetFlagOverflow(a.cpu.x)
|
||||||
a.maybeSetFlagZero(a.cpu.x)
|
a.maybeSetFlagZero(a.cpu.x)
|
||||||
|
@ -488,7 +488,7 @@ func execTSX(a *Appleone, o op) error {
|
||||||
|
|
||||||
// pull A N Z C I D V
|
// pull A N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execPLA(a *Appleone, o op) error {
|
func execPLA(a *Appleone, o operation) error {
|
||||||
a.cpu.a = a.popStackWord()
|
a.cpu.a = a.popStackWord()
|
||||||
a.maybeSetFlagOverflow(a.cpu.a)
|
a.maybeSetFlagOverflow(a.cpu.a)
|
||||||
a.maybeSetFlagZero(a.cpu.a)
|
a.maybeSetFlagZero(a.cpu.a)
|
||||||
|
@ -496,7 +496,7 @@ func execPLA(a *Appleone, o op) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pull SR from stack N Z C I D V
|
// pull SR from stack N Z C I D V
|
||||||
func execPLP(a *Appleone, o op) error {
|
func execPLP(a *Appleone, o operation) error {
|
||||||
a.cpu.ps = a.popStackWord() | 0B_00110000
|
a.cpu.ps = a.popStackWord() | 0B_00110000
|
||||||
a.maybeSetFlagOverflow(a.cpu.a)
|
a.maybeSetFlagOverflow(a.cpu.a)
|
||||||
a.maybeSetFlagZero(a.cpu.a)
|
a.maybeSetFlagZero(a.cpu.a)
|
||||||
|
@ -505,7 +505,7 @@ func execPLP(a *Appleone, o op) error {
|
||||||
|
|
||||||
// push SR N Z C I D V
|
// push SR N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execPHP(a *Appleone, o op) error {
|
func execPHP(a *Appleone, o operation) error {
|
||||||
a.pushWordToStack(a.cpu.ps)
|
a.pushWordToStack(a.cpu.ps)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -513,7 +513,7 @@ func execPHP(a *Appleone, o op) error {
|
||||||
// push (PC+2), N Z C I D V
|
// push (PC+2), N Z C I D V
|
||||||
// (PC+1) -> PCL - - - - - -
|
// (PC+1) -> PCL - - - - - -
|
||||||
// (PC+2) -> PCH
|
// (PC+2) -> PCH
|
||||||
func execJSR(a *Appleone, o op) error {
|
func execJSR(a *Appleone, o operation) error {
|
||||||
a.pushDWordToStack(a.cpu.pc - 1)
|
a.pushDWordToStack(a.cpu.pc - 1)
|
||||||
addr, err := a.getAddr(o)
|
addr, err := a.getAddr(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -525,14 +525,14 @@ func execJSR(a *Appleone, o op) error {
|
||||||
|
|
||||||
// pull PC, PC+1 -> PC N Z C I D V
|
// pull PC, PC+1 -> PC N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execRTS(a *Appleone, o op) error {
|
func execRTS(a *Appleone, o operation) error {
|
||||||
a.cpu.pc = a.popStackDWord() + 1
|
a.cpu.pc = a.popStackDWord() + 1
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 -> [76543210] -> C N Z C I D V
|
// 0 -> [76543210] -> C N Z C I D V
|
||||||
// 0 + + - - -
|
// 0 + + - - -
|
||||||
func execLSR(a *Appleone, o op) error {
|
func execLSR(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -555,18 +555,16 @@ func execLSR(a *Appleone, o op) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, err := a.getAddr(o)
|
if err := a.setMem(o, operand); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
a.mem[addr] = operand
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// C <- [76543210] <- C N Z C I D V
|
// C <- [76543210] <- C N Z C I D V
|
||||||
// + + + - - -
|
// + + + - - -
|
||||||
func execROL(a *Appleone, o op) error {
|
func execROL(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -597,18 +595,16 @@ func execROL(a *Appleone, o op) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, err := a.getAddr(o)
|
if err := a.setMem(o, operand); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
a.mem[addr] = operand
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// X -> SP N Z C I D V
|
// X -> SP N Z C I D V
|
||||||
// - - - - - -
|
// - - - - - -
|
||||||
func execTXS(a *Appleone, o op) error {
|
func execTXS(a *Appleone, o operation) error {
|
||||||
a.cpu.sp = a.cpu.x
|
a.cpu.sp = a.cpu.x
|
||||||
// TODO: needed?
|
// TODO: needed?
|
||||||
// a.maybeSetFlagZero(a.cpu.sp)
|
// a.maybeSetFlagZero(a.cpu.sp)
|
||||||
|
@ -618,7 +614,7 @@ func execTXS(a *Appleone, o op) error {
|
||||||
|
|
||||||
// C -> [76543210] -> C N Z C I D V
|
// C -> [76543210] -> C N Z C I D V
|
||||||
// + + + - - -
|
// + + + - - -
|
||||||
func execROR(a *Appleone, o op) error {
|
func execROR(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -649,18 +645,16 @@ func execROR(a *Appleone, o op) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, err := a.getAddr(o)
|
if err := a.setMem(o, operand); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
a.mem[addr] = operand
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// C <- [76543210] <- 0 N Z C I D V
|
// C <- [76543210] <- 0 N Z C I D V
|
||||||
// + + + - - -
|
// + + + - - -
|
||||||
func execASL(a *Appleone, o op) error {
|
func execASL(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -682,18 +676,16 @@ func execASL(a *Appleone, o op) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, err := a.getAddr(o)
|
if err := a.setMem(o, operand); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
a.mem[addr] = operand
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// A AND M -> A N Z C I D V
|
// A AND M -> A N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execAND(a *Appleone, o op) error {
|
func execAND(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -706,7 +698,7 @@ func execAND(a *Appleone, o op) error {
|
||||||
|
|
||||||
// A OR M -> A N Z C I D V
|
// A OR M -> A N Z C I D V
|
||||||
// + + - - - -
|
// + + - - - -
|
||||||
func execORA(a *Appleone, o op) error {
|
func execORA(a *Appleone, o operation) error {
|
||||||
operand, err := a.getOperand(o)
|
operand, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -4,18 +4,18 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// op represents an operation. It includes the name of the op, it's 8 bit hexidecimal
|
// operation includes the name of the operation, it's 8 bit hexidecimal opcode, how
|
||||||
// opcode, how many bytes it occupies (it's size), as well as it's addressing mode.
|
// many bytes it occupies (it's size), as well as it's addressing mode.
|
||||||
type op struct {
|
type operation struct {
|
||||||
name string
|
name string
|
||||||
opcode byte
|
opcode byte
|
||||||
size byte
|
size byte
|
||||||
addrMode addrMode
|
addrMode addrMode
|
||||||
exec func(a *Appleone, o op) error
|
exec func(a *Appleone, op operation) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOp(name string, opcode, size byte, addrMode addrMode, exec func(a *Appleone, o op) error) op {
|
func newOp(name string, opcode, size byte, addrMode addrMode, exec func(a *Appleone, op operation) error) operation {
|
||||||
return op{
|
return operation{
|
||||||
name: name,
|
name: name,
|
||||||
opcode: opcode,
|
opcode: opcode,
|
||||||
size: size,
|
size: size,
|
||||||
|
@ -24,18 +24,18 @@ func newOp(name string, opcode, size byte, addrMode addrMode, exec func(a *Apple
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// opByCode takes an opcode (a single byte/word) and returns the associated operation
|
// operationByCode takes an opcode (a single byte/word) and returns the associated operation
|
||||||
func opByCode(b byte) (op, error) {
|
func operationByCode(b byte) (operation, error) {
|
||||||
o, ok := opcodes[b]
|
o, ok := opcodes[b]
|
||||||
if !ok {
|
if !ok {
|
||||||
return op{}, errors.New("unknown opcode")
|
return operation{}, errors.New("unknown opcode")
|
||||||
}
|
}
|
||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// opcodes represent all of the Apple 1 opcodes available. Each 8 bit opcode is mapped to a corresponding
|
// opcodes represent all of the Apple 1 opcodes available. Each 8 bit opcode is mapped to a corresponding
|
||||||
// "op" which is just a struct holding metadata about the operation.
|
// "op" which is just a struct holding metadata about the operation.
|
||||||
var opcodes = map[byte]op{
|
var opcodes = map[byte]operation{
|
||||||
// BRK Force Break
|
// BRK Force Break
|
||||||
// addressing assembler opc bytes cyles
|
// addressing assembler opc bytes cyles
|
||||||
// --------------------------------------------
|
// --------------------------------------------
|
||||||
|
|
|
@ -26,19 +26,19 @@ func (a *Appleone) load(addr uint16, data []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Appleone) step() {
|
func (a *Appleone) step() {
|
||||||
op, err := opByCode(a.mem[a.cpu.pc])
|
operation, err := operationByCode(a.mem[a.cpu.pc])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("TODO")
|
fmt.Println("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
a.cpu.pc += uint16(op.size)
|
a.cpu.pc += uint16(operation.size)
|
||||||
|
|
||||||
if err := op.exec(a, op); err != nil {
|
if err := operation.exec(a, operation); err != nil {
|
||||||
fmt.Println("TODO")
|
fmt.Println("TODO")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Appleone) getAddr(o op) (uint16, error) {
|
func (a *Appleone) getAddr(o operation) (uint16, error) {
|
||||||
switch o.addrMode {
|
switch o.addrMode {
|
||||||
// TODO: will these ever apply here?
|
// TODO: will these ever apply here?
|
||||||
// case accumulator:
|
// case accumulator:
|
||||||
|
@ -75,7 +75,7 @@ func (a *Appleone) getAddr(o op) (uint16, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Appleone) getOperand(o op) (byte, error) {
|
func (a *Appleone) getOperand(o operation) (byte, error) {
|
||||||
if o.addrMode == accumulator {
|
if o.addrMode == accumulator {
|
||||||
return a.cpu.a, nil
|
return a.cpu.a, nil
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ func (a *Appleone) maybeSetFlagOverflow(word byte) {
|
||||||
|
|
||||||
// Branch offsets are signed 8-bit values, -128 ... +127, negative offsets in two's
|
// Branch offsets are signed 8-bit values, -128 ... +127, negative offsets in two's
|
||||||
// complement. Page transitions may occur and add an extra cycle to the exucution
|
// complement. Page transitions may occur and add an extra cycle to the exucution
|
||||||
func (a *Appleone) branch(o op) error {
|
func (a *Appleone) branch(o operation) error {
|
||||||
offset, err := a.getOperand(o)
|
offset, err := a.getOperand(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -187,3 +187,12 @@ func (a *Appleone) compare(b1, b2 byte) {
|
||||||
b := byte(uint16(b1) - uint16(b2))
|
b := byte(uint16(b1) - uint16(b2))
|
||||||
a.maybeSetFlagOverflow(b)
|
a.maybeSetFlagOverflow(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Appleone) setMem(o operation, operand byte) error {
|
||||||
|
addr, err := a.getAddr(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
a.mem[addr] = operand
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user