mirror of
https://github.com/BertoldVdb/ms-tools.git
synced 2025-12-10 07:44:46 +01:00
Add support for MS2107
This commit is contained in:
parent
dd3c764148
commit
fba02f5f19
8 changed files with 182 additions and 72 deletions
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -23,6 +23,7 @@ type dumpCodeParams struct {
|
|||
addrLoad int
|
||||
addrHook int
|
||||
valueHook byte
|
||||
delay time.Duration
|
||||
}
|
||||
|
||||
func (d *DumpROM) Run(c *Context) error {
|
||||
|
|
@ -36,6 +37,14 @@ func (d *DumpROM) Run(c *Context) error {
|
|||
p.addrLoad = 0xC4A0
|
||||
p.addrHook = 9
|
||||
p.valueHook = 0x96
|
||||
} else if strings.Contains(devType, "MS2107") {
|
||||
p.addrMailbox = 0xD000
|
||||
p.addrTemp = 0xD100
|
||||
p.addrTempLen = 256
|
||||
p.addrLoad = 0xC800
|
||||
p.addrHook = 8
|
||||
p.valueHook = 1
|
||||
p.delay = 25 * time.Millisecond
|
||||
} else if strings.Contains(devType, "MS2109") {
|
||||
p.addrMailbox = 0xCBF0
|
||||
p.addrTemp = 0xD300
|
||||
|
|
@ -52,7 +61,7 @@ func (d *DumpROM) Run(c *Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(d.Filename, code, 0644)
|
||||
return os.WriteFile(d.Filename, code, 0644)
|
||||
}
|
||||
|
||||
//go:embed asm/dumprom.bin
|
||||
|
|
@ -104,7 +113,7 @@ func (d *DumpROM) work(ms *mshal.HAL, p dumpCodeParams) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
/* Enable USB hook */
|
||||
/* Enable USB/Periodic hook */
|
||||
if err := mshal.WriteByte(config, p.addrHook, p.valueHook); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -133,6 +142,8 @@ func (d *DumpROM) work(ms *mshal.HAL, p dumpCodeParams) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
time.Sleep(p.delay)
|
||||
|
||||
ack, err := mshal.ReadByte(xdata, p.addrMailbox)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@ rm hook_2106.asm
|
|||
as31 -Fbin gpio.asm
|
||||
as31 -Fbin code.asm
|
||||
as31 -Fbin i2cRead2109.asm
|
||||
as31 -Fbin i2cRead2107.asm
|
||||
|
|
|
|||
2
mshal/asm/i2cRead2107.asm
Normal file
2
mshal/asm/i2cRead2107.asm
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
MOV 0x23.5, C
|
||||
LJMP 0x5934
|
||||
1
mshal/asm/i2cRead2107.bin
Normal file
1
mshal/asm/i2cRead2107.bin
Normal file
|
|
@ -0,0 +1 @@
|
|||
’Y4
|
||||
|
|
@ -62,9 +62,13 @@ func New(dev gohid.HIDDevice, config HALConfig) (*HAL, error) {
|
|||
case 0xa7:
|
||||
h.deviceType = 2109
|
||||
|
||||
case 0xff: /* TODO: Find a better ID register, as this will likely match many devices */
|
||||
h.deviceType = 2107
|
||||
|
||||
case 0x00: /* TODO: Find a better ID register, as this will likely match many devices */
|
||||
h.deviceType = 2130
|
||||
config.PatchTryInstall = false
|
||||
|
||||
default:
|
||||
return nil, ErrorUnknownDevice
|
||||
}
|
||||
|
|
@ -140,6 +144,8 @@ func (h *HAL) GetDeviceType() string {
|
|||
return "MS2106"
|
||||
} else if h.deviceType == 2130 {
|
||||
return "MS2130"
|
||||
} else if h.deviceType == 2107 {
|
||||
return "MS2107"
|
||||
}
|
||||
|
||||
return "MS2109"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ package mshal
|
|||
|
||||
func (h *HAL) patchI2CStart() error {
|
||||
addr := 0x3639
|
||||
if h.deviceType == 2109 {
|
||||
if h.deviceType == 2107 {
|
||||
addr = 0x68bd
|
||||
} else if h.deviceType == 2109 {
|
||||
addr = 0x6a8c
|
||||
}
|
||||
|
||||
|
|
@ -12,7 +14,9 @@ func (h *HAL) patchI2CStart() error {
|
|||
|
||||
func (h *HAL) patchI2CStop() error {
|
||||
addr := 0x3730
|
||||
if h.deviceType == 2109 {
|
||||
if h.deviceType == 2107 {
|
||||
addr = 0x6b5b
|
||||
} else if h.deviceType == 2109 {
|
||||
addr = 0x6aba
|
||||
}
|
||||
_, err := h.PatchExecFunc(true, addr, PatchExecFuncRequest{})
|
||||
|
|
@ -21,7 +25,7 @@ func (h *HAL) patchI2CStop() error {
|
|||
|
||||
func (h *HAL) patchI2CRead(ack bool) (uint8, error) {
|
||||
addr := 0x26cb
|
||||
if h.deviceType == 2109 {
|
||||
if h.deviceType == 2109 || h.deviceType == 2107 {
|
||||
addr = h.patchCallAddrs[3]
|
||||
}
|
||||
r7 := byte(1)
|
||||
|
|
@ -34,11 +38,13 @@ func (h *HAL) patchI2CRead(ack bool) (uint8, error) {
|
|||
|
||||
func (h *HAL) patchI2CWrite(value uint8) (bool, error) {
|
||||
addr := 0x2126
|
||||
if h.deviceType == 2109 {
|
||||
if h.deviceType == 2107 {
|
||||
addr = 0x5323
|
||||
} else if h.deviceType == 2109 {
|
||||
addr = 0x4648
|
||||
}
|
||||
resp, err := h.PatchExecFunc(true, addr, PatchExecFuncRequest{R7_A: value})
|
||||
if h.deviceType == 2109 {
|
||||
if h.deviceType != 2106 {
|
||||
return resp.C, err
|
||||
}
|
||||
return resp.R7 > 0, err
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"encoding/hex"
|
||||
"errors"
|
||||
"hash/crc32"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (h *HAL) patchAlloc(len int) int {
|
||||
|
|
@ -71,9 +72,9 @@ func patchTrampolineEncode(orig []byte, origAddr int, R0Value byte, hookAddr int
|
|||
return result
|
||||
}
|
||||
|
||||
func (h *HAL) patchTrampolineInstall(ram MemoryRegion, replaceCode bool, addr int, R0value byte, hookAddr int) error {
|
||||
func (h *HAL) patchTrampolineInstall(ram MemoryRegion, oldCode []byte, addr int, R0value byte, hookAddr int) error {
|
||||
var trampoline []byte
|
||||
if replaceCode {
|
||||
if len(oldCode) == 0 {
|
||||
replaceLen := 0
|
||||
var in [14]byte
|
||||
|
||||
|
|
@ -93,7 +94,7 @@ func (h *HAL) patchTrampolineInstall(ram MemoryRegion, replaceCode bool, addr in
|
|||
|
||||
trampoline = patchTrampolineEncode(in[:replaceLen], addr+replaceLen, R0value, hookAddr)
|
||||
} else {
|
||||
trampoline = patchTrampolineEncode(nil, 0, R0value, hookAddr)
|
||||
trampoline = patchTrampolineEncode(oldCode, 0, R0value, hookAddr)
|
||||
}
|
||||
|
||||
trampolineAddr := h.patchAlloc(len(trampoline))
|
||||
|
|
@ -138,8 +139,11 @@ var codeGpio []byte
|
|||
//go:embed asm/code.bin
|
||||
var codeMOVC []byte
|
||||
|
||||
//go:embed asm/i2cRead2107.bin
|
||||
var codei2cRead2107 []byte
|
||||
|
||||
//go:embed asm/i2cRead2109.bin
|
||||
var codei2cRead []byte
|
||||
var codei2cRead2109 []byte
|
||||
|
||||
var installBlobs2106 = []CodeBlob{
|
||||
{
|
||||
|
|
@ -151,6 +155,18 @@ var installBlobs2106 = []CodeBlob{
|
|||
Data: codeMOVC,
|
||||
}}
|
||||
|
||||
var installBlobs2107 = []CodeBlob{
|
||||
{
|
||||
Data: codeCallgate2109,
|
||||
Relocate: relocateCallgate,
|
||||
}, {
|
||||
Data: codeGpio,
|
||||
}, {
|
||||
Data: codeMOVC,
|
||||
}, {
|
||||
Data: codei2cRead2107,
|
||||
}}
|
||||
|
||||
var installBlobs2109 = []CodeBlob{
|
||||
{
|
||||
Data: codeCallgate2109,
|
||||
|
|
@ -160,7 +176,7 @@ var installBlobs2109 = []CodeBlob{
|
|||
}, {
|
||||
Data: codeMOVC,
|
||||
}, {
|
||||
Data: codei2cRead,
|
||||
Data: codei2cRead2109,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -172,19 +188,28 @@ func (h *HAL) EEPROMReloadUser() error {
|
|||
ram := h.MemoryRegionGet(MemoryRegionRAM)
|
||||
userConfig := h.MemoryRegionGet(MemoryRegionUserConfig)
|
||||
|
||||
addr, _, err := h.patchHookGet(userConfig, true)
|
||||
doInIRQ := true
|
||||
var loadEEPROM []byte
|
||||
if h.deviceType == 2106 {
|
||||
loadEEPROM = []byte{0x02, 0x12, 0x82}
|
||||
} else if h.deviceType == 2107 {
|
||||
doInIRQ = false
|
||||
loadEEPROM = []byte{0x02, 0x66, 0x56}
|
||||
defer time.Sleep(125 * time.Millisecond)
|
||||
} else if h.deviceType == 2109 {
|
||||
loadEEPROM = []byte{0x02, 0x5f, 0x19}
|
||||
} else {
|
||||
return ErrorUnknownDevice
|
||||
}
|
||||
|
||||
/* Write RET and disable callback */
|
||||
addr, _, err := h.patchHookGet(userConfig, doInIRQ)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* Write RET and enable callback */
|
||||
if err := h.patchHookConfigure(userConfig, true, false); err != nil {
|
||||
} else if err := h.patchHookSet(userConfig, doInIRQ, false); err != nil {
|
||||
return err
|
||||
} else if err := h.patchHookSet(userConfig, !doInIRQ, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
loadEEPROM := []byte{0x02, 0x12, 0x82}
|
||||
if h.deviceType == 2109 {
|
||||
loadEEPROM = []byte{0x02, 0x5f, 0x19}
|
||||
}
|
||||
|
||||
/* Reload EEPROM from IRQ context */
|
||||
|
|
@ -192,7 +217,7 @@ func (h *HAL) EEPROMReloadUser() error {
|
|||
return err
|
||||
}
|
||||
|
||||
return h.patchHookConfigure(userConfig, true, true)
|
||||
return h.patchHookSet(userConfig, doInIRQ, true)
|
||||
}
|
||||
|
||||
func (h *HAL) EEPROMIgnoreUser() error {
|
||||
|
|
@ -205,6 +230,7 @@ func (h *HAL) EEPROMIgnoreUser() error {
|
|||
ff := bytes.Repeat([]byte{0xFF}, userConfig.GetLength())
|
||||
ff[4] = 0
|
||||
ff[5] = 0
|
||||
ff[8] = 0
|
||||
|
||||
_, err := userConfig.Access(true, 0, ff)
|
||||
return err
|
||||
|
|
@ -222,16 +248,21 @@ func (h *HAL) EEPROMIsLoaded() (bool, int, error) {
|
|||
|
||||
if h.deviceType == 2106 {
|
||||
return hdr[0] == 0x5a && hdr[1] == 0xa5, eepromLen, nil
|
||||
} else if h.deviceType == 2107 {
|
||||
if hdr[0] == 0x08 && hdr[1] == 0x16 {
|
||||
return true, eepromLen, nil
|
||||
}
|
||||
|
||||
return hdr[0] == 0x32 && hdr[1] == 0x64, eepromLen, nil
|
||||
} else if h.deviceType == 2109 {
|
||||
if hdr[0] == 0xa5 && hdr[1] == 0x5a {
|
||||
return true, eepromLen, nil
|
||||
}
|
||||
|
||||
/* 2109 can also use 16bit eeproms and they have a different header */
|
||||
return hdr[0] == 0x96 && hdr[1] == 0x69, eepromLen, nil
|
||||
}
|
||||
|
||||
return false, 0, ErrorUnknownDevice
|
||||
}
|
||||
|
||||
func (h *HAL) patchHookGet(loc MemoryRegion, inIRQ bool) (int, bool, error) {
|
||||
if h.deviceType == 2106 {
|
||||
if inIRQ {
|
||||
|
|
@ -241,20 +272,25 @@ func (h *HAL) patchHookGet(loc MemoryRegion, inIRQ bool) (int, bool, error) {
|
|||
value, err := ReadByte(loc, 0x5)
|
||||
return 0xc420, value == 0x5a, err
|
||||
}
|
||||
}
|
||||
|
||||
value, err := ReadByte(loc, 0x4)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
|
||||
} else if h.deviceType == 2107 {
|
||||
value, err := ReadByte(loc, 0x8)
|
||||
if inIRQ {
|
||||
return 0xcc20, value&4 > 0, nil
|
||||
return 0xc810, value&2 > 0, err
|
||||
} else {
|
||||
return 0xc800, value&1 > 0, err
|
||||
}
|
||||
} else if h.deviceType == 2109 {
|
||||
value, err := ReadByte(loc, 0x4)
|
||||
if inIRQ {
|
||||
return 0xcc20, value&4 > 0, err
|
||||
} else {
|
||||
return 0xcc00, value&1 > 0, err
|
||||
}
|
||||
}
|
||||
|
||||
return 0xcc00, value&1 > 0, nil
|
||||
return 0, false, ErrorUnknownDevice
|
||||
}
|
||||
func (h *HAL) patchHookConfigure(loc MemoryRegion, inIRQ bool, enable bool) error {
|
||||
func (h *HAL) patchHookSet(loc MemoryRegion, inIRQ bool, enable bool) error {
|
||||
if h.config.LogFunc != nil {
|
||||
h.config.LogFunc(2, "Configuring userhook: inIRQ=%v, enable=%v", inIRQ, enable)
|
||||
}
|
||||
|
|
@ -272,8 +308,26 @@ func (h *HAL) patchHookConfigure(loc MemoryRegion, inIRQ bool, enable bool) erro
|
|||
}
|
||||
return WriteByte(loc, 0x5, value)
|
||||
}
|
||||
} else if h.deviceType == 2107 {
|
||||
value, err := ReadByte(loc, 0x8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if inIRQ {
|
||||
value &= ^byte(2)
|
||||
if enable {
|
||||
value |= 2
|
||||
}
|
||||
} else {
|
||||
value &= ^byte(1)
|
||||
if enable {
|
||||
value |= 1
|
||||
}
|
||||
}
|
||||
|
||||
return WriteByte(loc, 0x8, value)
|
||||
} else if h.deviceType == 2109 {
|
||||
value, err := ReadByte(loc, 0x4)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -294,6 +348,9 @@ func (h *HAL) patchHookConfigure(loc MemoryRegion, inIRQ bool, enable bool) erro
|
|||
return WriteByte(loc, 0x4, value)
|
||||
}
|
||||
|
||||
return ErrorUnknownDevice
|
||||
}
|
||||
|
||||
func (h *HAL) patchInitAlloc(userConfig MemoryRegion) (bool, error) {
|
||||
userCodePresent, userCodeLen, err := h.EEPROMIsLoaded()
|
||||
if err != nil {
|
||||
|
|
@ -313,6 +370,8 @@ func (h *HAL) patchInstall() (bool, error) {
|
|||
var installBlobs []CodeBlob
|
||||
if h.deviceType == 2109 {
|
||||
installBlobs = installBlobs2109
|
||||
} else if h.deviceType == 2107 {
|
||||
installBlobs = installBlobs2107
|
||||
} else if h.deviceType == 2106 {
|
||||
installBlobs = installBlobs2106
|
||||
} else {
|
||||
|
|
@ -416,28 +475,42 @@ func (h *HAL) patchInstall() (bool, error) {
|
|||
return true, err
|
||||
}
|
||||
|
||||
if userCodePresent && (!enableIrq || !enableNorm) {
|
||||
var oldCodeIRQ []byte
|
||||
if userCodePresent {
|
||||
if !enableIrq || !enableNorm {
|
||||
return true, ErrorPatchFailed
|
||||
}
|
||||
} else {
|
||||
enableIrq = true
|
||||
enableNorm = true
|
||||
if h.deviceType == 2107 {
|
||||
/* If the USB IRQ patch is enabled it must call the original handler (or do everything itself) */
|
||||
oldCodeIRQ = []byte{0x02, 0x54, 0xae}
|
||||
}
|
||||
}
|
||||
|
||||
if h.deviceType == 2107 {
|
||||
/* Disable callbacks during writing, just putting RET is not enough */
|
||||
if err := h.patchHookSet(userConfig, true, false); err != nil {
|
||||
return true, err
|
||||
} else if err := h.patchHookSet(userConfig, false, false); err != nil {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
|
||||
/* Install trampolines to callgate */
|
||||
if err := h.patchTrampolineInstall(ram, userCodePresent, addrIrq, 0xee, h.patchCallAddrs[0]); err != nil {
|
||||
if err := h.patchTrampolineInstall(ram, oldCodeIRQ, addrIrq, 0xee, h.patchCallAddrs[0]); err != nil {
|
||||
return true, err
|
||||
} else if err := h.patchTrampolineInstall(ram, nil, addrNorm, 0xef, h.patchCallAddrs[0]); err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
if err := h.patchTrampolineInstall(ram, userCodePresent, addrNorm, 0xef, h.patchCallAddrs[0]); err != nil {
|
||||
/* Re-enable callbacks */
|
||||
if err := h.patchHookSet(userConfig, true, enableIrq); err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
/* Enable callbacks */
|
||||
if !userCodePresent {
|
||||
if err := h.patchHookConfigure(userConfig, true, true); err != nil {
|
||||
} else if err := h.patchHookSet(userConfig, false, enableNorm); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if err := h.patchHookConfigure(userConfig, false, true); err != nil {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
|
||||
/* Write patch sumblock */
|
||||
for i := range installBlobs {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ func (h *HAL) MemoryRegionList() []MemoryRegionNameType {
|
|||
MemoryRegionUserConfig,
|
||||
}
|
||||
|
||||
if h.deviceType == 2106 || h.deviceType == 2109 {
|
||||
if h.deviceType == 2106 || h.deviceType == 2109 || h.deviceType == 2107 {
|
||||
list = append(list, MemoryRegionUserRAM)
|
||||
}
|
||||
|
||||
|
|
@ -145,6 +145,16 @@ func (h *HAL) MemoryRegionGet(name MemoryRegionNameType) MemoryRegion {
|
|||
}
|
||||
}
|
||||
|
||||
if h.deviceType == 2107 {
|
||||
switch t {
|
||||
case MemoryRegionUserRAM:
|
||||
return regionWrapPartial(MemoryRegionUserRAM, h.MemoryRegionGet(MemoryRegionRAM), 0xC000, 0x1400)
|
||||
|
||||
case MemoryRegionUserConfig:
|
||||
return regionWrapPartial(MemoryRegionUserConfig, h.MemoryRegionGet(MemoryRegionUserRAM), 0x7D0, 0x30)
|
||||
}
|
||||
}
|
||||
|
||||
if h.deviceType == 2109 {
|
||||
switch t {
|
||||
case MemoryRegionUserRAM:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue