i6502/cpu/instruction.go

58 lines
1.3 KiB
Go

package cpu
import (
"fmt"
"github.com/ariejan/i6502/bus"
)
// Instruction is a self-contained, variable length instruction,
// it includes the the operation type and a possible 8 or 16 bit operand.
type Instruction struct {
OpType
// 2 byte instructions have a single byte operand
Op8 uint8
// 3 byte instruction have a double byte operand
Op16 uint16
}
func (i *Instruction) String() string {
var output string
switch i.Bytes {
case 1:
output = fmt.Sprintf("0x%02X - %s\n", i.Opcode, instructionNames[i.id])
case 2:
output = fmt.Sprintf("0x%02X - %s %02X\n", i.Opcode, instructionNames[i.id], i.Op8)
case 3:
output = fmt.Sprintf("0x%02X - %s %04X\n", i.Opcode, instructionNames[i.id], i.Op16)
}
return output
}
func ReadInstruction(pc uint16, bus *bus.Bus) Instruction {
// Read the opcode
opcode := bus.Read(pc)
// Do we know this opcode in our optypes table?
optype, ok := optypes[opcode]
if !ok {
panic(fmt.Sprintf("Unknown opcode $%02X at $%04X", opcode, pc))
}
instruction := Instruction{OpType: optype}
switch instruction.Bytes {
case 1: // No operand.
case 2:
instruction.Op8 = bus.Read(pc + 1)
case 3:
instruction.Op16 = bus.Read16(pc + 1)
default:
panic(fmt.Sprintf("Unknown instruction length (%d) for $%02X at $04X", instruction.Bytes, opcode, pc))
}
return instruction
}