arm

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2025 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
const (
	BUS_SEQ   = (1 << 0) // sequential access (BUS_SEQ が 1 であることに依存している箇所がある)
	BUS_CODE  = (1 << 1) // code access
	BUS_BURST = (1 << 2) // burst access (GBAのパイプラインで必要)

)
View Source
const (
	CYCLE_I = (1 << 0) // Internal cycle
	CYCLE_C = (1 << 1) // Code cycle
	CYCLE_D = (1 << 2) // Data cycle
)
View Source
const (
	PRIV_USER = 0b1_0000

	// 以下のモードは特権モードといって、cpsrの制御ビット(bit0-7)が変更できる
	PRIV_FIQ        = 0b1_0001
	PRIV_IRQ        = 0b1_0010
	PRIV_SUPERVISOR = 0b1_0011
	PRIV_ABORT      = 0b1_0111
	PRIV_UNDEFINED  = 0b1_1011
	PRIV_SYSTEM     = 0b1_1111 // 基本的にユーザーモードと同じだが、cpsrの制御ビット(bit0-7)が変更できる
)
View Source
const (
	BIT_TF = (1 << 5)  // Thumb mode
	BIT_FF = (1 << 6)  // Fast interrupt disable (FIQ disable)
	BIT_IF = (1 << 7)  // IRQ disable
	BIT_QF = (1 << 27) // Saturation (Sticky Overflow の Sticky から Q らしい?)
	BIT_VF = (1 << 28) // Overflow
	BIT_CF = (1 << 29) // Carry
	BIT_ZF = (1 << 30) // Zero
	BIT_NF = (1 << 31) // Negative
)
View Source
const (
	BANK_FIQ     = 0
	BANK_IRQ     = 1
	BANK_SVC     = 2
	BANK_ABT     = 3
	BANK_UND     = 4
	BANK_NONE    = 5 // usr/sys
	BANK_INVALID = -1
)

Variables

This section is empty.

Functions

func MajorVersion

func MajorVersion(model Model) int

Types

type Bank

type Bank [7]uint32 // 0-4: R8-R12(usr, fiq のみ), 5,6: R13,R14

type Bus

type Bus interface {
	CodeRead32(addr uint32, flag uint32) uint32
	CodeRead16(addr uint32, flag uint32) uint32
	Read(width int, addr uint32, flag uint32) uint32
	Write(width int, addr, data, flag uint32)
}

type CPU

type CPU struct {
	Model Model
	*Registers

	IRQ    bool // IME && (IE & IF)
	NonSeq bool // non-sequential store命令とかで、 コードフェッチを nS+1N -> (n-1)S+2N にするためとかで使う, なおNDS9では、コードフェッチが SもNも同じサイクル(正確には強制的にランダムアクセスになる) なので特に意味はない

	Coprocs         [16]Coprocessor
	ExceptionVector uint32

	BlockTransfer bool // LDM/STMの時に、データフェッチをシーケンシャルにさせるためのフラグ

	Debugger Debugger
	// contains filtered or unexported fields
}

func New

func New(model Model, bus Bus, tick func(category uint32, cycles int64)) *CPU

func (*CPU) Coproc

func (c *CPU) Coproc(id int, cp Coprocessor) *CPU

func (*CPU) CreateSnapshot

func (c *CPU) CreateSnapshot() Snapshot

func (*CPU) DataRead16

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

func (*CPU) DataRead16S

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

ldrsh

func (*CPU) DataRead32

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

func (*CPU) DataRead8

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

func (*CPU) DataWrite16

func (c *CPU) DataWrite16(addr uint32, data16 uint32)

func (*CPU) DataWrite32

func (c *CPU) DataWrite32(addr uint32, data32 uint32)

func (*CPU) DataWrite8

func (c *CPU) DataWrite8(addr uint32, data8 uint32)

func (*CPU) IsThumb

func (c *CPU) IsThumb() bool

func (*CPU) MDR

func (c *CPU) MDR() uint32

func (*CPU) PC

func (c *CPU) PC() uint32

PC returns the current program counter value (not including pipeline effect) In THUMB state, the bit0 is 0b1.

func (*CPU) Reset

func (c *CPU) Reset()

func (*CPU) RestoreSnapshot

func (c *CPU) RestoreSnapshot(snap *Snapshot) error

func (*CPU) SetR

func (c *CPU) SetR(regNum uint32, val uint32)

func (*CPU) Step

func (c *CPU) Step()

func (*CPU) UpdateSnapshot

func (c *CPU) UpdateSnapshot(snap *Snapshot) error

type Coprocessor

type Coprocessor interface {
	MRC(op1, cn, cm, op2 uint32) uint32 // Read
	MCR(op1, cn, cm, op2, val uint32)   // Write
}

type Debugger

type Debugger interface {
	PrintLog(message string)
	InstructionHook(id int, pc uint64)
}

type Inst

type Inst struct {
	Opcode uint32
	Addr   uint32
	Thumb  bool // 例外処理のときは、cpsr.tをARMにした後で、元々がTHUMBだったかどうかを知る必要がある
}

type Model

type Model uint8
const (
	ARM7TDMI Model = iota
	ARM946E_S
)

値に意味を持たせて ARMの命令セットの互換性を判断できるようにしてもいいかも?(他のARMコアの命令セットを知らんからまだそれでいいのかわからん)

type Pipeline

type Pipeline struct {
	Execute Inst // ゲームによっては、(エミュ対策で)直後の命令を書き換えることがあるがパイプラインにすでに入っている命令は書き換えられない(ので.opcodeも持つ必要がある)
	Decode  Inst
	Fetch   Inst
	Reload  bool // on jump
}

type Registers

type Registers struct {
	// 現在のモードでのレジスタ (ハードウェア的にはないが、どのモードでも .R[n] で自分のレジスタにアクセスできるようにした方が便利なので用意した)
	// R: *[16]uint32 で &Bank[CPSR&0x1F] がハードウェア的に素直な実装だが、全部のモードで共有するレジスタ(R0..R7)とかがあるため、モード切り替え時に結局コピーが必要になるので、このように実装した方が楽だった
	R    [16]uint32
	Bank [6]Bank // 0-5: FIQ, IRQ, SVC, ABT, UND, USR/SYS

	CPSR uint32 // NZCVQ--- | -------- | -------- | IFTMMMMM
	// 例外が起きた時のCPSRを退避して(復帰できるようにして)おくためのもの で、 .Bank と違い モードごとのPSR を持っておくためのものではない
	// .Bank は 各モードのために用意されたもの、 SPSR は 例外から復帰するために用意されたもの と考えるとわかりやすい(...多分)
	// また msr, mrs 命令で SPSR を手動で読み書きすることもできる
	SPSR [5]uint32
}

func (*Registers) Priviledged

func (r *Registers) Priviledged() bool

func (*Registers) Reset

func (r *Registers) Reset()

func (*Registers) ReturnFromException

func (r *Registers) ReturnFromException()

func (*Registers) String

func (r *Registers) String() string

func (*Registers) SwitchMode

func (r *Registers) SwitchMode(mode uint8)

type Snapshot

type Snapshot struct {
	Header             uint64     // バージョン番号とかなんか持たせたいとき用に確保
	GPR                [16]uint32 // R0-R15
	PSR                [6]uint32  // CPSR, SPSR
	RegBanks           [6]Bank    // R8-R14 (fiq, irq, svc, abt, und, usr)
	Pipeline           Pipeline
	Carry, IRQ, NonSeq bool
	ExceptionVector    uint32
	BlockTransfer      bool
	Reserved           [1024]uint8
}

Jump to

Keyboard shortcuts

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