ms-tools/mshal/hal_patch_call.go
2023-11-03 23:50:56 +01:00

116 lines
2 KiB
Go

package mshal
import (
"encoding/hex"
"errors"
"time"
)
func (h *HAL) patchExchangeReport(out [9]byte) ([9]byte, error) {
var in [9]byte
if h.config.LogFunc != nil {
h.config.LogFunc(3, "PatchOut: %s", hex.EncodeToString(out[:]))
}
if _, err := h.dev.SendFeatureReport(out[:]); err != nil {
return in, err
}
timeout := time.Now().Add(3 * time.Second)
for time.Now().Before(timeout) {
_, err := h.dev.GetFeatureReport(in[:])
if err != nil {
return in, err
}
if in[1]&0xFE == 0xFE {
if h.config.LogFunc != nil {
h.config.LogFunc(3, "PatchIn: %s", hex.EncodeToString(in[:]))
}
return in, nil
}
}
return in, ErrorTimeout
}
type PatchExecFuncResponse struct {
A byte
R2 byte
R3 byte
R4 byte
R5 byte
R6 byte
R7 byte
C bool
}
type PatchExecFuncRequest struct {
DPTR uint16
R3 byte
R4 byte
R5 byte
R6 byte
R7_A byte
}
func (h *HAL) PatchExecFunc(inIRQ bool, addr int, req PatchExecFuncRequest) (PatchExecFuncResponse, error) {
var response PatchExecFuncResponse
if !h.patchInstalled && !h.patchCanCall {
return response, ErrorMissingFunction
}
if req.DPTR != 0 && (req.R4 != 0 || req.R3 != 0) {
return response, errors.New("can't set both DPTR and R3/R4")
}
var out [9]byte
out[1] = 0xef
if inIRQ {
out[1] = 0xee
}
out[2] = byte(addr >> 8)
out[3] = byte(addr)
if req.DPTR != 0 {
out[4] = byte(req.DPTR >> 8)
out[5] = byte(req.DPTR)
} else {
out[4] = req.R3
out[5] = req.R4
}
out[6] = req.R5
out[7] = req.R6
out[8] = req.R7_A
in, err := h.patchExchangeReport(out)
if err != nil {
return response, err
}
response.A = in[2]
response.R2 = in[3]
response.R3 = in[4]
response.R4 = in[5]
response.R5 = in[6]
response.R6 = in[7]
response.R7 = in[8]
response.C = in[1]&1 > 0
return response, nil
}
func (h *HAL) PatchCodeBlobGetAddress(index int) int {
if index < 0 {
return 0
}
index += h.patchCallAddrsExternalStart
if index >= len(h.patchCallAddrs) {
return 0
}
return h.patchCallAddrs[index]
}