cpu

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2025 License: MIT Imports: 2 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// SR_C is carry
	SRC = 1 << 0
	// SR_V is overflow
	SRV = 1 << 1
	// SR_Z is zero
	SRZ = 1 << 2
	// SR_N is negative
	SRN = 1 << 3
	// SR_X is extend
	SRX = 1 << 4
	// SR_I0 is interrupt level 0
	SRI0 = 1 << 8
	// SR_I1 is interrupt level 1
	SRI1 = 1 << 9
	// SR_I2 is interrupt level 2
	SRI2 = 1 << 10
	// SR_S is supervisor state
	SRS = 1 << 13
	// SR_T is trace mode
	SRT = 1 << 15
	// SRI combines interrupt levels
	SRI = SRI0 | SRI1 | SRI2
)

Status register flags.

View Source
const (
	// Logical and Bit Manipulation Instructions
	OPAND                 = 0xC000 // AND
	OPOR                  = 0x8000 // OR
	OPEOR                 = 0xB100 // EOR
	OPANDI                = 0x0200 // ANDI
	OPORI                 = 0x0000 // ORI
	OPEORI                = 0x0A00 // EORI
	OPANDItoCCR           = 0x023C // ANDI to CCR
	OPORItoCCR            = 0x003C // ORI to CCR
	OPEORItoCCR           = 0x0A3C // EORI to CCR
	OPANDItoSR            = 0x027C // ANDI to SR (privileged)
	OPORItoSR             = 0x007C // ORI to SR (privileged)
	OPEORItoSR            = 0x0A7C // EORI to SR (privileged)
	OPNOT                 = 0x4600 // NOT
	OPCLR                 = 0x4200 // CLR
	OPTST                 = 0x4A00 // TST
	OPNEG                 = 0x4400 // NEG
	OPNEGX                = 0x4000 // NEGX
	OPNBCD                = 0x4800 // NBCD
	OPEXT                 = 0x4800 // EXT
	OPSWAP                = 0x4840 // SWAP
	OPBCHG                = 0x0840 // BCHG
	OPBCLR                = 0x0880 // BCLR
	OPBSET                = 0x08C0 // BSET
	OPBTST                = 0x0800 // BTST
	OPBitManipulationBase = 0x0100 // Base for dynamic BTST, BSET, etc.

	// Arithmetic Instructions
	OPADD  = 0xD000 // ADD
	OPADDQ = 0x5000 // ADDQ
	OPADDA = 0xD000 // ADDA (Base, size bits added separately)
	OPADDI = 0x0600 // ADDI
	OPADDX = 0xD100 // ADDX
	OPSUB  = 0x9000 // SUB
	OPSUBQ = 0x5100 // SUBQ
	OPSUBA = 0x9000 // SUBA (Base, size bits added separately)
	OPSUBI = 0x0400 // SUBI
	OPSUBX = 0x9100 // SUBX
	OPMULS = 0xC1C0 // MULS
	OPMULU = 0xC0C0 // MULU
	OPDIVS = 0x81C0 // DIVS
	OPDIVU = 0x80C0 // DIVU

	// Comparison Instructions
	OPCMP  = 0xB000 // CMP
	OPCMPI = 0x0C00 // CMPI
	OPCMPA = 0xB000 // CMPA (Base, size bits added separately)
	OPCHK  = 0x4180 // CHK

	// Shift and Rotate Instructions
	OPShiftRotateBase = 0xE000 // Base for all shifts and rotates
	OPASR             = 0xE000 // ASR
	OPASL             = 0x100  // ASL
	OPLSR             = 0xE008 // LSR
	OPLSL             = 0xE108 // LSL
	OPROR             = 0xE018 // ROR
	OPROL             = 0xE118 // ROL
	OPROXR            = 0xE020 // ROXR
	OPROXL            = 0xE120 // ROXL

	// Move Instructions
	OPMOVE        = 0x0000 // MOVE (placeholder, size bits are added)
	OPMOVEA       = 0x0040 // MOVEA (placeholder, size bits are added)
	OPMOVEQ       = 0x7000 // MOVEQ
	OPMOVEM       = 0x4880 // MOVEM (base)
	OPMOVEP       = 0x0008 // MOVEP (base)
	OPMOVEFromSR  = 0x40C0 // MOVE from SR
	OPMOVEToSR    = 0x46C0 // MOVE to SR (privileged)
	OPMOVEToCCR   = 0x44C0 // MOVE to CCR
	OPMOVEFromUSP = 0x4E68 // MOVE from USP
	OPMOVEToUSP   = 0x4E60 // MOVE to USP

	// Address Calculation and Stack Instructions
	OPPEA  = 0x4840 // PEA
	OPLEA  = 0x41C0 // LEA (Base, register is OR'd)
	OPLINK = 0x4E50 // LINK
	OPUNLK = 0x4E58 // UNLK

	// Control Instructions
	OPTRAP    = 0x4E40 // TRAP
	OPTRAPV   = 0x4E76 // TRAPV
	OPRTE     = 0x4E73 // RTE
	OPSTOP    = 0x4E72 // STOP
	OPRESET   = 0x4E70 // RESET
	OPNOP     = 0x4E71 // NOP
	OPILLEGAL = 0x4AFC // ILLEGAL
	OPRTS     = 0x4E75 // RTS
	OPRTR     = 0x4E77 // RTR
	OPTAS     = 0x4AC0 // TAS
	OPEXG     = 0xC100 // EXG (base)

	// Conditional Instructions
	OPScc  = 0x50C0 // Scc (base, condition code OR'd)
	OPDBcc = 0x50C8 // DBcc (base, condition code OR'd)

	// Branch Instructions (base values, condition codes are OR'd)
	OPBRA = 0x6000 // Branch Always
	OPBSR = 0x6100 // Branch to Subroutine
	OPBHI = 0x6200 // Branch if Higher
	OPBLS = 0x6300 // Branch if Lower or Same
	OPBCC = 0x6400 // Branch if Carry Clear (Higher or Same)
	OPBCS = 0x6500 // Branch if Carry Set (Lower)
	OPBNE = 0x6600 // Branch if Not Equal
	OPBEQ = 0x6700 // Branch if Equal
	OPBVC = 0x6800 // Branch if Overflow Clear
	OPBVS = 0x6900 // Branch if Overflow Set
	OPBPL = 0x6A00 // Branch if Plus (Positive)
	OPBMI = 0x6B00 // Branch if Minus (Negative)
	OPBGE = 0x6C00 // Branch if Greater or Equal
	OPBLT = 0x6D00 // Branch if Less Than
	OPBGT = 0x6E00 // Branch if Greater Than
	OPBLE = 0x6F00 // Branch if Less or Equal

	// Jump and Subroutine Instructions
	OPJMP = 0x4EC0 // JMP
	OPJSR = 0x4E80 // JSR
)

Opcodes for various instructions.

View Source
const (
	// 000 — Data Register Direct: Dn
	ModeData uint16 = 0

	// 001 — Address Register Direct: An
	ModeAddr uint16 = 1

	// 010 — Address Register Indirect: (An)
	ModeAddrInd uint16 = 2

	// 011 — Address Register Indirect with Postincrement: (An)+
	ModeAddrPostInc uint16 = 3

	// 100 — Address Register Indirect with Predecrement: -(An)
	ModeAddrPreDec uint16 = 4

	// 101 — Address Register Indirect with Displacement: (d16,An)
	ModeAddrDisp uint16 = 5

	// 110 — Address Register Indirect with Index: (d8,An,Xn)
	ModeAddrIndex uint16 = 6

	// 111 — Miscellaneous / “other” addressing modes
	ModeOther uint16 = 7
)

Addressing mode constants (3-bit mode field + 3-bit register field)

View Source
const (
	// 000 — Absolute short address: (xxx).W
	RegAbsShort uint16 = 0

	// 001 — Absolute long address: (xxx).L
	RegAbsLong uint16 = 1

	// 010 — Program counter with displacement: (d16,PC)
	RegPCDisp uint16 = 2

	// 011 — Program counter with index: (d8,PC,Xn)
	RegPCIndex uint16 = 3

	// 100 — Immediate: #<data>
	RegImmediate uint16 = 4
)

Submodes for ModeOther (register field = 3 bits)

View Source
const (
	ModeAbsShort   uint16 = 0 // (xxx).W
	ModeAbsLong    uint16 = 1 // (xxx).L
	ModePCRelative uint16 = 2 // (d16,PC)
	ModeImmediate  uint16 = 4 // #<data>
)

Derived addressing modes (for clarity in assembler code)

View Source
const (
	// Data registers
	D0 = 0
	D1 = 1
	D2 = 2
	D3 = 3
	D4 = 4
	D5 = 5
	D6 = 6
	D7 = 7

	// Address registers
	A0 = 0
	A1 = 1
	A2 = 2
	A3 = 3
	A4 = 4
	A5 = 5
	A6 = 6
	A7 = 7 // stack pointer
)

Register numbers

Variables

View Source
var BranchOpcodes = map[string]uint16{
	"bra": OPBRA,
	"bsr": OPBSR,
	"bhi": OPBHI,
	"bls": OPBLS,
	"bcc": OPBCC,
	"bcs": OPBCS,
	"bne": OPBNE,
	"beq": OPBEQ,
	"bvc": OPBVC,
	"bvs": OPBVS,
	"bpl": OPBPL,
	"bmi": OPBMI,
	"bge": OPBGE,
	"blt": OPBLT,
	"bgt": OPBGT,
	"ble": OPBLE,
}

BranchOpcodes maps branch mnemonics to their base opcodes.

View Source
var ConditionCodes = map[string]uint16{
	"t":  0x0,
	"f":  0x1,
	"hi": 0x2,
	"ls": 0x3,
	"cc": 0x4,
	"cs": 0x5,
	"ne": 0x6,
	"eq": 0x7,
	"vc": 0x8,
	"vs": 0x9,
	"pl": 0xA,
	"mi": 0xB,
	"ge": 0xC,
	"lt": 0xD,
	"gt": 0xE,
	"le": 0xF,
}

ConditionCodes maps condition mnemonics to their 4-bit codes.

Functions

func BytesToWords

func BytesToWords(b []byte) []uint16

BytesToWords interprets bytes as big-endian 16-bit words. If an odd number of bytes is passed, the final byte is padded with 0.

func IsLittleEndianHost

func IsLittleEndianHost() bool

IsLittleEndianHost checks if the host system is little-endian.

func WordsToBytes

func WordsToBytes(words []uint16) []byte

WordsToBytes converts a slice of 16-bit words to a big-endian byte slice.

Types

type CPU

type CPU struct {
	// D is for data registers.
	D [8]uint32
	// A is for address registers. A7 is the current stack pointer.
	A [8]uint32
	// PC is the program counter.
	PC uint32
	// USP is the user stack pointer.
	USP uint32
	// SSP is the supervisor stack pointer.
	SSP uint32
	// SR is the status register.
	SR uint16
	// ISP is the interrupt stack pointer.
	ISP uint32

	// Memory
	Mem []byte
	// Cache for instructions.
	ICache map[uint32]uint32

	// Cycles count.
	Cycles int32
	// Running or not.
	Running bool
}

CPU memory and registers.

func New

func New(memsize, cachesize int) *CPU

New creates a new CPU instance with given memory size.

func (*CPU) Decode added in v0.4.0

func (c *CPU) Decode(opcode uint16) (*DecodedInstruction, error)

Decode takes a 16-bit opcode and returns a structured DecodedInstruction. This is the heart of the CPU, determining what each instruction means.

func (*CPU) Execute

func (c *CPU) Execute() error

Execute fetches, decodes, and executes a single instruction.

func (*CPU) GetOperand added in v0.4.0

func (c *CPU) GetOperand(mode, reg uint16, size Size) (uint32, error)

GetOperand fetches a value using the specified addressing mode. This is the core of resolving the "source" part of an instruction.

func (*CPU) PutOperand added in v0.4.0

func (c *CPU) PutOperand(mode, reg uint16, size Size, value uint32) error

PutOperand writes a value using the specified addressing mode. This is the core of resolving the "destination" part of an instruction.

func (*CPU) ReadU16 added in v0.4.0

func (c *CPU) ReadU16(addr uint32) uint16

ReadU16 reads a big-endian 16-bit word from memory at the given address.

func (*CPU) ReadU32 added in v0.4.0

func (c *CPU) ReadU32(addr uint32) uint32

ReadU32 reads a big-endian 32-bit long word from memory at the given address.

func (*CPU) WriteU16 added in v0.4.0

func (c *CPU) WriteU16(addr uint32, val uint16)

WriteU16 writes a 16-bit word to memory at the given address in big-endian format.

func (*CPU) WriteU32 added in v0.4.0

func (c *CPU) WriteU32(addr uint32, val uint32)

WriteU32 writes a 32-bit long word to memory at the given address in big-endian format.

type DecodedInstruction added in v0.4.0

type DecodedInstruction struct {
	// Handler is the function that executes this instruction.
	Handler func(*CPU, *DecodedInstruction) error
	// Size of the operation (Byte, Word, Long).
	Size Size
	// SrcMode is the source addressing mode.
	SrcMode uint16
	// SrcReg is the source register number.
	SrcReg uint16
	// DstMode is the destination addressing mode.
	DstMode uint16
	// DstReg is the destination register number.
	DstReg uint16
}

DecodedInstruction holds the parsed details of an M68k instruction.

type Size

type Size int

Size defines the data size for an instruction's operation.

const (
	// SizeInvalid is the zero value, indicating no size suffix was provided.
	SizeInvalid Size = iota
	// SizeByte represents 8-bit data size.
	SizeByte
	// SizeWord represents 16-bit data size.
	SizeWord
	// SizeLong represents 32-bit data size.
	SizeLong
	// SizeShort is used for branch instructions (displacement).
	SizeShort
)

func (Size) Bytes added in v0.4.0

func (s Size) Bytes() int

Bytes returns the size in bytes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL