From da70e2cfe389c0873d4a52b68899cc68c2dcbb58 Mon Sep 17 00:00:00 2001 From: Bradford Lamson-Scribner Date: Sun, 31 May 2020 09:38:10 -0600 Subject: [PATCH] internal/vm/{exec_funcs,opcodes}: add support for executing DEY, DEX, TAY, TAX opcodes --- internal/vm/exec_funcs.go | 49 +++++++++++++++++++++++++++++++++++++++ internal/vm/opcodes.go | 35 ++++++++++++++++++---------- 2 files changed, 72 insertions(+), 12 deletions(-) diff --git a/internal/vm/exec_funcs.go b/internal/vm/exec_funcs.go index 858f8bb..f736bef 100644 --- a/internal/vm/exec_funcs.go +++ b/internal/vm/exec_funcs.go @@ -79,3 +79,52 @@ func execINY(a *Appleone, o op) error { a.setNegativeIfOverflow(b) return nil } + +// A -> X N Z C I D V +// + + - - - - +func execTAX(a *Appleone, o op) error { + a.cpu.x = a.cpu.a + a.setZeroIfNeeded(a.cpu.x) + a.setNegativeIfOverflow(a.cpu.x) + return nil +} + +// A -> Y N Z C I D V +// + + - - - - +func execTAY(a *Appleone, o op) error { + a.cpu.y = a.cpu.a + a.setZeroIfNeeded(a.cpu.y) + a.setNegativeIfOverflow(a.cpu.y) + return nil +} + +// X - 1 -> X N Z C I D V +// + + - - - - +func execDEX(a *Appleone, o op) error { + b := a.cpu.x - 1 + a.cpu.x = b + a.setZeroIfNeeded(b) + a.setNegativeIfOverflow(b) + return nil +} + +// Y - 1 -> Y N Z C I D V +// + + - - - - +func execDEY(a *Appleone, o op) error { + b := a.cpu.y - 1 + a.cpu.y = b + a.setZeroIfNeeded(b) + a.setNegativeIfOverflow(b) + return nil +} + +// M -> A N Z C I D V +// + + - - - - +func execLDA(a *Appleone, o op) error { + b, err := o.getData(a) + if err != nil { + return err + } + a.cpu.a = b + return nil +} diff --git a/internal/vm/opcodes.go b/internal/vm/opcodes.go index 2896aa0..2b842c5 100644 --- a/internal/vm/opcodes.go +++ b/internal/vm/opcodes.go @@ -70,6 +70,17 @@ func (o op) getAddr(a *Appleone) (uint16, error) { } } +func (o op) getData(a *Appleone) (uint8, error) { + if o.addrMode == accumulator { + return a.cpu.a, nil + } + b, err := o.getAddr(a) + if err != nil { + return 0, err + } + return a.mem[b], nil +} + // 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. var opcodes = map[uint8]op{ @@ -125,25 +136,25 @@ var opcodes = map[uint8]op{ // addressing assembler opc bytes cyles // -------------------------------------------- // implied TAX AA 1 2 - 0xAA: newOp("TAX", 0xAA, 1, implied, todo), + 0xAA: newOp("TAX", 0xAA, 1, implied, execTAX), // TAY Transfer Accumulator to Index Y // addressing assembler opc bytes cyles // -------------------------------------------- // implied TAY A8 1 2 - 0xA8: newOp("TAY", 0xA8, 1, implied, todo), + 0xA8: newOp("TAY", 0xA8, 1, implied, execTAY), // DEX Decrement Index X by One // addressing assembler opc bytes cyles // -------------------------------------------- // implied DEC CA 1 2 - 0xCA: newOp("DEX", 0xCA, 1, implied, todo), + 0xCA: newOp("DEX", 0xCA, 1, implied, execDEX), // DEY Decrement Index Y by One // addressing assembler opc bytes cyles // -------------------------------------------- // implied DEC 88 1 2 - 0x88: newOp("DEY", 0x88, 1, implied, todo), + 0x88: newOp("DEY", 0x88, 1, implied, execDEY), // LDA Load Accumulator with Memory // addressing assembler opc bytes cyles @@ -156,14 +167,14 @@ var opcodes = map[uint8]op{ // absolute,Y LDA oper,Y B9 3 4* // (indirect,X) LDA (oper,X) A1 2 6 // (indirect),Y LDA (oper),Y B1 2 5* - 0xA9: newOp("LDA", 0xA9, 2, immediate, todo), - 0xA5: newOp("LDA", 0xA5, 2, zeroPage, todo), - 0xB5: newOp("LDA", 0xB5, 2, zeroPageXIndexed, todo), - 0xAD: newOp("LDA", 0xAD, 3, absolute, todo), - 0xBD: newOp("LDA", 0xBD, 3, absoluteXIndexed, todo), - 0xB9: newOp("LDA", 0xB9, 3, absoluteYIndexed, todo), - 0xA1: newOp("LDA", 0xA1, 2, indirectXIndexed, todo), - 0xB1: newOp("LDA", 0xB1, 2, indirectYIndexed, todo), + 0xA9: newOp("LDA", 0xA9, 2, immediate, execLDA), + 0xA5: newOp("LDA", 0xA5, 2, zeroPage, execLDA), + 0xB5: newOp("LDA", 0xB5, 2, zeroPageXIndexed, execLDA), + 0xAD: newOp("LDA", 0xAD, 3, absolute, execLDA), + 0xBD: newOp("LDA", 0xBD, 3, absoluteXIndexed, execLDA), + 0xB9: newOp("LDA", 0xB9, 3, absoluteYIndexed, execLDA), + 0xA1: newOp("LDA", 0xA1, 2, indirectXIndexed, execLDA), + 0xB1: newOp("LDA", 0xB1, 2, indirectYIndexed, execLDA), // LDX Load Index X with Memory // addressing assembler opc bytes cyles