You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hal/hal/module.go

79 lines
1.9 KiB

package hal
import "fmt"
const maxInstructions = 1000
type Program map[int64]*ProgrammedInstruction
type Module struct {
accumulator float64
programStorage Program
register []float64
IO []float64
isStopped bool
debugEnabled bool
}
func (h *Module) programCounter() int64 {
return int64(h.register[0])
}
func (h *Module) setProgramCounter(counter int64) error {
h.register[0] = float64(counter)
if _, ok := h.programStorage[counter]; !ok {
return fmt.Errorf("index %d does not exist in program storage", counter)
}
return nil
}
func (h *Module) increaseProgramCounter() {
h.register[0]++
}
func (h *Module) debug(format string, args ...interface{}) {
if !h.debugEnabled {
return
}
fmt.Printf("[DEBUG] "+format+"\n", args...)
}
func (h *Module) Step() error {
instruction := h.programStorage[h.programCounter()]
h.increaseProgramCounter()
if instruction == nil {
h.debug("Skip undefined instruction %d", h.programCounter())
return nil
}
h.debug("Instruction: %s", instruction.Instruction.Name)
h.debug("Accumulator before: %f", h.accumulator)
if err := instruction.Execute(h); err != nil {
return err
}
h.debug("Accumulator after: %f", h.accumulator)
return nil
}
func (h *Module) Run() error {
for !h.isStopped && h.programCounter() <= maxInstructions {
if err := h.Step(); err != nil {
return err
}
}
if h.programCounter() > maxInstructions {
return fmt.Errorf("module exceeded max instructions without being stopped")
}
return nil
}
func NewHALModule(program Program, registerSize uint64, ioSize uint64, debug bool) (*Module, error) {
if registerSize <= 10 {
return nil, fmt.Errorf("register size must be greater then 10 [ registerSize = %d ]", registerSize)
}
return &Module{
programStorage: program,
register: make([]float64, registerSize),
IO: make([]float64, ioSize),
debugEnabled: debug,
}, nil
}