Documentation
¶
Index ¶
- Constants
- Variables
- func BytesToWords(b []byte) []uint16
- func IsLittleEndianHost() bool
- func WordsToBytes(words []uint16) []byte
- type CPU
- func (c *CPU) Decode(opcode uint16) (*DecodedInstruction, error)
- func (c *CPU) Execute() error
- func (c *CPU) GetOperand(mode, reg uint16, size Size) (uint32, error)
- func (c *CPU) PutOperand(mode, reg uint16, size Size, value uint32) error
- func (c *CPU) ReadU16(addr uint32) uint16
- func (c *CPU) ReadU32(addr uint32) uint32
- func (c *CPU) WriteU16(addr uint32, val uint16)
- func (c *CPU) WriteU32(addr uint32, val uint32)
- type DecodedInstruction
- type Size
Constants ¶
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.
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.
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)
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)
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)
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 ¶
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.
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 ¶
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 ¶
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 (*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) GetOperand ¶ added in v0.4.0
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
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
ReadU16 reads a big-endian 16-bit word from memory at the given address.
func (*CPU) ReadU32 ¶ added in v0.4.0
ReadU32 reads a big-endian 32-bit long word from memory at the given address.
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 )