From 01bb2379ce1a02f7e9ede46e8c7b1407cc88c003 Mon Sep 17 00:00:00 2001 From: Bradford Lamson-Scribner Date: Sun, 31 May 2020 21:41:47 -0600 Subject: [PATCH] internal/vm/{exec_funcs,opcodes,vm}: update design around opcode addr and operand fetching Refactor: `(o op) getAddr` -> `(a *Appleone) getAddr` `(o op) getOperand` `(a *Appleone) getOperand` This makes way more sense to me and has been bothering me for a while. --- internal/vm/exec_funcs.go | 56 +++++++++++++++++++-------------------- internal/vm/opcodes.go | 48 --------------------------------- internal/vm/vm.go | 51 ++++++++++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 77 deletions(-) diff --git a/internal/vm/exec_funcs.go b/internal/vm/exec_funcs.go index 57b9e35..d97d129 100644 --- a/internal/vm/exec_funcs.go +++ b/internal/vm/exec_funcs.go @@ -33,7 +33,7 @@ func execRTI(a *Appleone, o op) error { // M - 1 -> M N Z C I D V // + + - - - - func execDEC(a *Appleone, o op) error { - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -48,7 +48,7 @@ func execDEC(a *Appleone, o op) error { // M + 1 -> M N Z C I D V // + + - - - - func execINC(a *Appleone, o op) error { - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -117,7 +117,7 @@ func execDEY(a *Appleone, o op) error { // M -> A N Z C I D V // + + - - - - func execLDA(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -130,7 +130,7 @@ func execLDA(a *Appleone, o op) error { // M -> X N Z C I D V // + + - - - - func execLDX(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -143,7 +143,7 @@ func execLDX(a *Appleone, o op) error { // M -> Y N Z C I D V // + + - - - - func execLDY(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -156,7 +156,7 @@ func execLDY(a *Appleone, o op) error { // A + M + C -> A, C N Z C I D V // + + + - - + func execADC(a *Appleone, o op) error { - b, err := o.getOperand(a) + b, err := a.getOperand(o) if err != nil { return err } @@ -185,7 +185,7 @@ func execADC(a *Appleone, o op) error { // A - M - C -> A N Z C I D V // + + + - - + func execSBC(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -219,7 +219,7 @@ func execSBC(a *Appleone, o op) error { // X -> M N Z C I D V // - - - - - - func execSTX(a *Appleone, o op) error { - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -230,7 +230,7 @@ func execSTX(a *Appleone, o op) error { // Y -> M N Z C I D V // - - - - - - func execSTY(a *Appleone, o op) error { - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -241,7 +241,7 @@ func execSTY(a *Appleone, o op) error { // A -> M N Z C I D V // - - - - - - func execSTA(a *Appleone, o op) error { - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -288,7 +288,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); // the zeroflag is set to the result of operand AND accumulator. func execBIT(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -342,7 +342,7 @@ func execBCS(a *Appleone, o op) error { // X - M N Z C I D V // + + + - - - func execCPX(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -353,7 +353,7 @@ func execCPX(a *Appleone, o op) error { // A EOR M -> A N Z C I D V // + + - - - - func execEOR(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -366,7 +366,7 @@ func execEOR(a *Appleone, o op) error { // A - M N Z C I D V // + + + - - - func execCMP(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -377,7 +377,7 @@ func execCMP(a *Appleone, o op) error { // Y - M N Z C I D V // + + + - - - func execCPY(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -444,14 +444,14 @@ func execNOP(a *Appleone, o op) error { // (PC+2) -> PCH - - - - - - func execJMP(a *Appleone, o op) error { if o.addrMode == indirect { - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } a.cpu.pc = a.littleEndianToUint16(a.mem[addr+1], a.mem[addr]) return nil } - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -522,7 +522,7 @@ func execPHP(a *Appleone, o op) error { // (PC+2) -> PCH func execJSR(a *Appleone, o op) error { a.pushDWordToStack(a.cpu.pc - 1) - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -540,7 +540,7 @@ func execRTS(a *Appleone, o op) error { // 0 -> [76543210] -> C N Z C I D V // 0 + + - - - func execLSR(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -562,7 +562,7 @@ func execLSR(a *Appleone, o op) error { return nil } - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -574,7 +574,7 @@ func execLSR(a *Appleone, o op) error { // C <- [76543210] <- C N Z C I D V // + + + - - - func execROL(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -604,7 +604,7 @@ func execROL(a *Appleone, o op) error { return nil } - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -626,7 +626,7 @@ func execTXS(a *Appleone, o op) error { // C -> [76543210] -> C N Z C I D V // + + + - - - func execROR(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -656,7 +656,7 @@ func execROR(a *Appleone, o op) error { return nil } - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -668,7 +668,7 @@ func execROR(a *Appleone, o op) error { // C <- [76543210] <- 0 N Z C I D V // + + + - - - func execASL(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -689,7 +689,7 @@ func execASL(a *Appleone, o op) error { return nil } - addr, err := o.getAddr(a) + addr, err := a.getAddr(o) if err != nil { return err } @@ -701,7 +701,7 @@ func execASL(a *Appleone, o op) error { // A AND M -> A N Z C I D V // + + - - - - func execAND(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } @@ -714,7 +714,7 @@ func execAND(a *Appleone, o op) error { // A OR M -> A N Z C I D V // + + - - - - func execORA(a *Appleone, o op) error { - operand, err := o.getOperand(a) + operand, err := a.getOperand(o) if err != nil { return err } diff --git a/internal/vm/opcodes.go b/internal/vm/opcodes.go index 9178632..50cd5ac 100644 --- a/internal/vm/opcodes.go +++ b/internal/vm/opcodes.go @@ -33,54 +33,6 @@ func opByCode(b byte) (op, error) { return o, nil } -func (o op) getAddr(a *Appleone) (uint16, error) { - switch o.addrMode { - // TODO: will these ever apply here? - // case accumulator: - // - // case implied: - // - case absolute: - return a.nextDWord(), nil - case absoluteXIndexed: - return a.nextDWord() + uint16(a.cpu.x), nil - case absoluteYIndexed: - return a.nextDWord() + uint16(a.cpu.y), nil - case immediate: - return a.cpu.pc - 1, nil - case indirect: - return uint16(a.nextWord()), nil - case indirectXIndexed: - addr := (uint16(a.nextWord()) + uint16(a.cpu.x)) & 0xFF - return a.littleEndianToUint16(a.mem[addr+1], a.mem[addr]), nil - case indirectYIndexed: - addr := uint16(a.nextWord()) - val := a.littleEndianToUint16(a.mem[addr+1], a.mem[addr]) - return val + uint16(a.cpu.y), nil - case relative: - return a.cpu.pc - 1, nil - case zeroPage: - return uint16(a.nextWord()) & 0xFF, nil - case zeroPageXIndexed: - return (uint16(a.nextWord()) + uint16(a.cpu.x)) & 0xFF, nil - case zeroPageYIndexed: - return (uint16(a.nextWord()) + uint16(a.cpu.y)) & 0xFF, nil - default: - return 0, errors.New("unkown addressing mode") - } -} - -func (o op) getOperand(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{ diff --git a/internal/vm/vm.go b/internal/vm/vm.go index ec19a46..f53d603 100644 --- a/internal/vm/vm.go +++ b/internal/vm/vm.go @@ -1,6 +1,7 @@ package vm import ( + "errors" "fmt" ) @@ -36,6 +37,54 @@ func (a *Appleone) step() { } } +func (a *Appleone) getAddr(o op) (uint16, error) { + switch o.addrMode { + // TODO: will these ever apply here? + // case accumulator: + // + // case implied: + // + case absolute: + return a.nextDWord(), nil + case absoluteXIndexed: + return a.nextDWord() + uint16(a.cpu.x), nil + case absoluteYIndexed: + return a.nextDWord() + uint16(a.cpu.y), nil + case immediate: + return a.cpu.pc - 1, nil + case indirect: + return uint16(a.nextWord()), nil + case indirectXIndexed: + addr := (uint16(a.nextWord()) + uint16(a.cpu.x)) & 0xFF + return a.littleEndianToUint16(a.mem[addr+1], a.mem[addr]), nil + case indirectYIndexed: + addr := uint16(a.nextWord()) + val := a.littleEndianToUint16(a.mem[addr+1], a.mem[addr]) + return val + uint16(a.cpu.y), nil + case relative: + return a.cpu.pc - 1, nil + case zeroPage: + return uint16(a.nextWord()) & 0xFF, nil + case zeroPageXIndexed: + return (uint16(a.nextWord()) + uint16(a.cpu.x)) & 0xFF, nil + case zeroPageYIndexed: + return (uint16(a.nextWord()) + uint16(a.cpu.y)) & 0xFF, nil + default: + return 0, errors.New("unkown addressing mode") + } +} + +func (a *Appleone) getOperand(o op) (uint8, error) { + if o.addrMode == accumulator { + return a.cpu.a, nil + } + b, err := a.getAddr(o) + if err != nil { + return 0, err + } + return a.mem[b], nil +} + func (a *Appleone) littleEndianToUint16(big, little byte) uint16 { return uint16(a.mem[big])<<8 | uint16(a.mem[little]) } @@ -140,7 +189,7 @@ func (a *Appleone) getZero() byte { } func (a *Appleone) branch(o op) error { - offset, err := o.getOperand(a) + offset, err := a.getOperand(o) if err != nil { return err }