mirror of
https://github.com/bradford-hamilton/apple-1.git
synced 2024-06-12 00:29:26 +00:00
internal/vm/{exec_funcs,opcodes,vm}: add support for executing LDX, LDY, and ADC
This commit is contained in:
parent
3730835466
commit
ca699a78af
|
@ -63,20 +63,18 @@ 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 op) error {
|
||||||
b := a.cpu.x + 1
|
a.cpu.x++
|
||||||
a.cpu.x = b
|
a.setZeroIfNeeded(a.cpu.x)
|
||||||
a.setZeroIfNeeded(b)
|
a.setNegativeIfOverflow(a.cpu.x)
|
||||||
a.setNegativeIfOverflow(b)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 op) error {
|
||||||
b := a.cpu.y + 1
|
a.cpu.y++
|
||||||
a.cpu.y = b
|
a.setZeroIfNeeded(a.cpu.y)
|
||||||
a.setZeroIfNeeded(b)
|
a.setNegativeIfOverflow(a.cpu.y)
|
||||||
a.setNegativeIfOverflow(b)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,20 +99,18 @@ 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 op) error {
|
||||||
b := a.cpu.x - 1
|
a.cpu.x--
|
||||||
a.cpu.x = b
|
a.setZeroIfNeeded(a.cpu.x)
|
||||||
a.setZeroIfNeeded(b)
|
a.setNegativeIfOverflow(a.cpu.x)
|
||||||
a.setNegativeIfOverflow(b)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 op) error {
|
||||||
b := a.cpu.y - 1
|
a.cpu.y--
|
||||||
a.cpu.y = b
|
a.setZeroIfNeeded(a.cpu.y)
|
||||||
a.setZeroIfNeeded(b)
|
a.setNegativeIfOverflow(a.cpu.y)
|
||||||
a.setNegativeIfOverflow(b)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,5 +122,62 @@ func execLDA(a *Appleone, o op) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
a.cpu.a = b
|
a.cpu.a = b
|
||||||
|
a.setZeroIfNeeded(a.cpu.a)
|
||||||
|
a.setNegativeIfOverflow(a.cpu.a)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// M -> X N Z C I D V
|
||||||
|
// + + - - - -
|
||||||
|
func execLDX(a *Appleone, o op) error {
|
||||||
|
b, err := o.getData(a)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
a.cpu.x = b
|
||||||
|
a.setZeroIfNeeded(a.cpu.x)
|
||||||
|
a.setNegativeIfOverflow(a.cpu.x)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// M -> Y N Z C I D V
|
||||||
|
// + + - - - -
|
||||||
|
func execLDY(a *Appleone, o op) error {
|
||||||
|
b, err := o.getData(a)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
a.cpu.y = b
|
||||||
|
a.setZeroIfNeeded(a.cpu.y)
|
||||||
|
a.setNegativeIfOverflow(a.cpu.y)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// A + M + C -> A, C N Z C I D V
|
||||||
|
// + + + - - +
|
||||||
|
func execADC(a *Appleone, o op) error {
|
||||||
|
b, err := o.getData(a)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
operand := uint16(b)
|
||||||
|
regA := uint16(a.cpu.a)
|
||||||
|
sum := regA + operand + uint16(a.getCarry())
|
||||||
|
a.cpu.a = uint8(sum)
|
||||||
|
|
||||||
|
a.clearCarry()
|
||||||
|
if sum > 255 {
|
||||||
|
a.setCarry()
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://www.righto.com/2012/12/the-6502-overflow-flag-explained.html
|
||||||
|
a.clearOverflow()
|
||||||
|
if (operand^sum)&(regA^sum)&0x80 != 0 {
|
||||||
|
a.setOverflow()
|
||||||
|
}
|
||||||
|
|
||||||
|
a.setZeroIfNeeded(a.cpu.a)
|
||||||
|
a.setNegativeIfOverflow(a.cpu.a)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,11 +184,11 @@ var opcodes = map[uint8]op{
|
||||||
// zeropage,Y LDX oper,Y B6 2 4
|
// zeropage,Y LDX oper,Y B6 2 4
|
||||||
// absolute LDX oper AE 3 4
|
// absolute LDX oper AE 3 4
|
||||||
// absolute,Y LDX oper,Y BE 3 4*
|
// absolute,Y LDX oper,Y BE 3 4*
|
||||||
0xA2: newOp("LDX", 0xA2, 2, immediate, todo),
|
0xA2: newOp("LDX", 0xA2, 2, immediate, execLDX),
|
||||||
0xA6: newOp("LDX", 0xA6, 2, zeroPage, todo),
|
0xA6: newOp("LDX", 0xA6, 2, zeroPage, execLDX),
|
||||||
0xB6: newOp("LDX", 0xB6, 2, zeroPageYIndexed, todo),
|
0xB6: newOp("LDX", 0xB6, 2, zeroPageYIndexed, execLDX),
|
||||||
0xAE: newOp("LDX", 0xAE, 3, absolute, todo),
|
0xAE: newOp("LDX", 0xAE, 3, absolute, execLDX),
|
||||||
0xBE: newOp("LDX", 0xBE, 3, absoluteYIndexed, todo),
|
0xBE: newOp("LDX", 0xBE, 3, absoluteYIndexed, execLDX),
|
||||||
|
|
||||||
// LDY Load Index Y with Memory
|
// LDY Load Index Y with Memory
|
||||||
// addressing assembler opc bytes cyles
|
// addressing assembler opc bytes cyles
|
||||||
|
@ -198,11 +198,11 @@ var opcodes = map[uint8]op{
|
||||||
// zeropage,X LDY oper,X B4 2 4
|
// zeropage,X LDY oper,X B4 2 4
|
||||||
// absolute LDY oper AC 3 4
|
// absolute LDY oper AC 3 4
|
||||||
// absolute,X LDY oper,X BC 3 4*
|
// absolute,X LDY oper,X BC 3 4*
|
||||||
0xA0: newOp("LDY", 0xA0, 2, immediate, todo),
|
0xA0: newOp("LDY", 0xA0, 2, immediate, execLDY),
|
||||||
0xA4: newOp("LDY", 0xA4, 2, zeroPage, todo),
|
0xA4: newOp("LDY", 0xA4, 2, zeroPage, execLDY),
|
||||||
0xB4: newOp("LDY", 0xB4, 2, zeroPageXIndexed, todo),
|
0xB4: newOp("LDY", 0xB4, 2, zeroPageXIndexed, execLDY),
|
||||||
0xAC: newOp("LDY", 0xAC, 3, absolute, todo),
|
0xAC: newOp("LDY", 0xAC, 3, absolute, execLDY),
|
||||||
0xBC: newOp("LDY", 0xBC, 3, absoluteXIndexed, todo),
|
0xBC: newOp("LDY", 0xBC, 3, absoluteXIndexed, execLDY),
|
||||||
|
|
||||||
// ADC Add Memory to Accumulator with Carry
|
// ADC Add Memory to Accumulator with Carry
|
||||||
// addressing assembler opc bytes cyles
|
// addressing assembler opc bytes cyles
|
||||||
|
@ -215,14 +215,14 @@ var opcodes = map[uint8]op{
|
||||||
// absolute,Y ADC oper,Y 79 3 4*
|
// absolute,Y ADC oper,Y 79 3 4*
|
||||||
// (indirect,X) ADC (oper,X) 61 2 6
|
// (indirect,X) ADC (oper,X) 61 2 6
|
||||||
// (indirect),Y ADC (oper),Y 71 2 5*
|
// (indirect),Y ADC (oper),Y 71 2 5*
|
||||||
0x69: newOp("ADC", 0x69, 2, immediate, todo),
|
0x69: newOp("ADC", 0x69, 2, immediate, execADC),
|
||||||
0x65: newOp("ADC", 0x65, 2, zeroPage, todo),
|
0x65: newOp("ADC", 0x65, 2, zeroPage, execADC),
|
||||||
0x75: newOp("ADC", 0x75, 2, zeroPageXIndexed, todo),
|
0x75: newOp("ADC", 0x75, 2, zeroPageXIndexed, execADC),
|
||||||
0x6D: newOp("ADC", 0x6D, 3, absolute, todo),
|
0x6D: newOp("ADC", 0x6D, 3, absolute, execADC),
|
||||||
0x7D: newOp("ADC", 0x7D, 3, absoluteXIndexed, todo),
|
0x7D: newOp("ADC", 0x7D, 3, absoluteXIndexed, execADC),
|
||||||
0x79: newOp("ADC", 0x79, 3, absoluteYIndexed, todo),
|
0x79: newOp("ADC", 0x79, 3, absoluteYIndexed, execADC),
|
||||||
0x61: newOp("ADC", 0x61, 2, indirectXIndexed, todo),
|
0x61: newOp("ADC", 0x61, 2, indirectXIndexed, execADC),
|
||||||
0x71: newOp("ADC", 0x71, 2, indirectYIndexed, todo),
|
0x71: newOp("ADC", 0x71, 2, indirectYIndexed, execADC),
|
||||||
|
|
||||||
// SBC Subtract Memory from Accumulator with Borrow
|
// SBC Subtract Memory from Accumulator with Borrow
|
||||||
// addressing assembler opc bytes cyles
|
// addressing assembler opc bytes cyles
|
||||||
|
|
|
@ -106,3 +106,23 @@ func (a *Appleone) setNegative() {
|
||||||
func (a *Appleone) clearNegative() {
|
func (a *Appleone) clearNegative() {
|
||||||
a.cpu.sp &^= flagZero
|
a.cpu.sp &^= flagZero
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Appleone) getCarry() uint8 {
|
||||||
|
return a.cpu.sp & flagCarry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Appleone) setCarry() {
|
||||||
|
a.cpu.sp |= flagCarry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Appleone) clearCarry() {
|
||||||
|
a.cpu.sp &^= flagCarry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Appleone) setOverflow() {
|
||||||
|
a.cpu.sp |= flagOverflow
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Appleone) clearOverflow() {
|
||||||
|
a.cpu.sp &^= flagOverflow
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user