Add support for MS2107

This commit is contained in:
Bertold Van den Bergh 2023-10-02 09:07:41 +02:00
parent dd3c764148
commit fba02f5f19
8 changed files with 182 additions and 72 deletions

View file

@ -3,7 +3,7 @@ package main
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil" "os"
"strings" "strings"
"time" "time"
@ -23,6 +23,7 @@ type dumpCodeParams struct {
addrLoad int addrLoad int
addrHook int addrHook int
valueHook byte valueHook byte
delay time.Duration
} }
func (d *DumpROM) Run(c *Context) error { func (d *DumpROM) Run(c *Context) error {
@ -36,6 +37,14 @@ func (d *DumpROM) Run(c *Context) error {
p.addrLoad = 0xC4A0 p.addrLoad = 0xC4A0
p.addrHook = 9 p.addrHook = 9
p.valueHook = 0x96 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") { } else if strings.Contains(devType, "MS2109") {
p.addrMailbox = 0xCBF0 p.addrMailbox = 0xCBF0
p.addrTemp = 0xD300 p.addrTemp = 0xD300
@ -52,7 +61,7 @@ func (d *DumpROM) Run(c *Context) error {
return err return err
} }
return ioutil.WriteFile(d.Filename, code, 0644) return os.WriteFile(d.Filename, code, 0644)
} }
//go:embed asm/dumprom.bin //go:embed asm/dumprom.bin
@ -104,7 +113,7 @@ func (d *DumpROM) work(ms *mshal.HAL, p dumpCodeParams) ([]byte, error) {
return nil, err return nil, err
} }
/* Enable USB hook */ /* Enable USB/Periodic hook */
if err := mshal.WriteByte(config, p.addrHook, p.valueHook); err != nil { if err := mshal.WriteByte(config, p.addrHook, p.valueHook); err != nil {
return nil, err return nil, err
} }
@ -133,6 +142,8 @@ func (d *DumpROM) work(ms *mshal.HAL, p dumpCodeParams) ([]byte, error) {
return nil, err return nil, err
} }
time.Sleep(p.delay)
ack, err := mshal.ReadByte(xdata, p.addrMailbox) ack, err := mshal.ReadByte(xdata, p.addrMailbox)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -9,3 +9,4 @@ rm hook_2106.asm
as31 -Fbin gpio.asm as31 -Fbin gpio.asm
as31 -Fbin code.asm as31 -Fbin code.asm
as31 -Fbin i2cRead2109.asm as31 -Fbin i2cRead2109.asm
as31 -Fbin i2cRead2107.asm

View file

@ -0,0 +1,2 @@
MOV 0x23.5, C
LJMP 0x5934

View file

@ -0,0 +1 @@
Y4

View file

@ -62,9 +62,13 @@ func New(dev gohid.HIDDevice, config HALConfig) (*HAL, error) {
case 0xa7: case 0xa7:
h.deviceType = 2109 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 */ case 0x00: /* TODO: Find a better ID register, as this will likely match many devices */
h.deviceType = 2130 h.deviceType = 2130
config.PatchTryInstall = false config.PatchTryInstall = false
default: default:
return nil, ErrorUnknownDevice return nil, ErrorUnknownDevice
} }
@ -140,6 +144,8 @@ func (h *HAL) GetDeviceType() string {
return "MS2106" return "MS2106"
} else if h.deviceType == 2130 { } else if h.deviceType == 2130 {
return "MS2130" return "MS2130"
} else if h.deviceType == 2107 {
return "MS2107"
} }
return "MS2109" return "MS2109"

View file

@ -2,7 +2,9 @@ package mshal
func (h *HAL) patchI2CStart() error { func (h *HAL) patchI2CStart() error {
addr := 0x3639 addr := 0x3639
if h.deviceType == 2109 { if h.deviceType == 2107 {
addr = 0x68bd
} else if h.deviceType == 2109 {
addr = 0x6a8c addr = 0x6a8c
} }
@ -12,7 +14,9 @@ func (h *HAL) patchI2CStart() error {
func (h *HAL) patchI2CStop() error { func (h *HAL) patchI2CStop() error {
addr := 0x3730 addr := 0x3730
if h.deviceType == 2109 { if h.deviceType == 2107 {
addr = 0x6b5b
} else if h.deviceType == 2109 {
addr = 0x6aba addr = 0x6aba
} }
_, err := h.PatchExecFunc(true, addr, PatchExecFuncRequest{}) _, err := h.PatchExecFunc(true, addr, PatchExecFuncRequest{})
@ -21,7 +25,7 @@ func (h *HAL) patchI2CStop() error {
func (h *HAL) patchI2CRead(ack bool) (uint8, error) { func (h *HAL) patchI2CRead(ack bool) (uint8, error) {
addr := 0x26cb addr := 0x26cb
if h.deviceType == 2109 { if h.deviceType == 2109 || h.deviceType == 2107 {
addr = h.patchCallAddrs[3] addr = h.patchCallAddrs[3]
} }
r7 := byte(1) r7 := byte(1)
@ -34,11 +38,13 @@ func (h *HAL) patchI2CRead(ack bool) (uint8, error) {
func (h *HAL) patchI2CWrite(value uint8) (bool, error) { func (h *HAL) patchI2CWrite(value uint8) (bool, error) {
addr := 0x2126 addr := 0x2126
if h.deviceType == 2109 { if h.deviceType == 2107 {
addr = 0x5323
} else if h.deviceType == 2109 {
addr = 0x4648 addr = 0x4648
} }
resp, err := h.PatchExecFunc(true, addr, PatchExecFuncRequest{R7_A: value}) resp, err := h.PatchExecFunc(true, addr, PatchExecFuncRequest{R7_A: value})
if h.deviceType == 2109 { if h.deviceType != 2106 {
return resp.C, err return resp.C, err
} }
return resp.R7 > 0, err return resp.R7 > 0, err

View file

@ -7,6 +7,7 @@ import (
"encoding/hex" "encoding/hex"
"errors" "errors"
"hash/crc32" "hash/crc32"
"time"
) )
func (h *HAL) patchAlloc(len int) int { func (h *HAL) patchAlloc(len int) int {
@ -71,9 +72,9 @@ func patchTrampolineEncode(orig []byte, origAddr int, R0Value byte, hookAddr int
return result 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 var trampoline []byte
if replaceCode { if len(oldCode) == 0 {
replaceLen := 0 replaceLen := 0
var in [14]byte 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) trampoline = patchTrampolineEncode(in[:replaceLen], addr+replaceLen, R0value, hookAddr)
} else { } else {
trampoline = patchTrampolineEncode(nil, 0, R0value, hookAddr) trampoline = patchTrampolineEncode(oldCode, 0, R0value, hookAddr)
} }
trampolineAddr := h.patchAlloc(len(trampoline)) trampolineAddr := h.patchAlloc(len(trampoline))
@ -138,8 +139,11 @@ var codeGpio []byte
//go:embed asm/code.bin //go:embed asm/code.bin
var codeMOVC []byte var codeMOVC []byte
//go:embed asm/i2cRead2107.bin
var codei2cRead2107 []byte
//go:embed asm/i2cRead2109.bin //go:embed asm/i2cRead2109.bin
var codei2cRead []byte var codei2cRead2109 []byte
var installBlobs2106 = []CodeBlob{ var installBlobs2106 = []CodeBlob{
{ {
@ -151,6 +155,18 @@ var installBlobs2106 = []CodeBlob{
Data: codeMOVC, Data: codeMOVC,
}} }}
var installBlobs2107 = []CodeBlob{
{
Data: codeCallgate2109,
Relocate: relocateCallgate,
}, {
Data: codeGpio,
}, {
Data: codeMOVC,
}, {
Data: codei2cRead2107,
}}
var installBlobs2109 = []CodeBlob{ var installBlobs2109 = []CodeBlob{
{ {
Data: codeCallgate2109, Data: codeCallgate2109,
@ -160,7 +176,7 @@ var installBlobs2109 = []CodeBlob{
}, { }, {
Data: codeMOVC, Data: codeMOVC,
}, { }, {
Data: codei2cRead, Data: codei2cRead2109,
}, },
} }
@ -172,19 +188,28 @@ func (h *HAL) EEPROMReloadUser() error {
ram := h.MemoryRegionGet(MemoryRegionRAM) ram := h.MemoryRegionGet(MemoryRegionRAM)
userConfig := h.MemoryRegionGet(MemoryRegionUserConfig) 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 { if err != nil {
return err return err
} } else if err := h.patchHookSet(userConfig, doInIRQ, false); err != nil {
return err
/* Write RET and enable callback */ } else if err := h.patchHookSet(userConfig, !doInIRQ, false); err != nil {
if err := h.patchHookConfigure(userConfig, true, false); err != nil {
return err return err
}
loadEEPROM := []byte{0x02, 0x12, 0x82}
if h.deviceType == 2109 {
loadEEPROM = []byte{0x02, 0x5f, 0x19}
} }
/* Reload EEPROM from IRQ context */ /* Reload EEPROM from IRQ context */
@ -192,7 +217,7 @@ func (h *HAL) EEPROMReloadUser() error {
return err return err
} }
return h.patchHookConfigure(userConfig, true, true) return h.patchHookSet(userConfig, doInIRQ, true)
} }
func (h *HAL) EEPROMIgnoreUser() error { func (h *HAL) EEPROMIgnoreUser() error {
@ -205,6 +230,7 @@ func (h *HAL) EEPROMIgnoreUser() error {
ff := bytes.Repeat([]byte{0xFF}, userConfig.GetLength()) ff := bytes.Repeat([]byte{0xFF}, userConfig.GetLength())
ff[4] = 0 ff[4] = 0
ff[5] = 0 ff[5] = 0
ff[8] = 0
_, err := userConfig.Access(true, 0, ff) _, err := userConfig.Access(true, 0, ff)
return err return err
@ -222,14 +248,19 @@ func (h *HAL) EEPROMIsLoaded() (bool, int, error) {
if h.deviceType == 2106 { if h.deviceType == 2106 {
return hdr[0] == 0x5a && hdr[1] == 0xa5, eepromLen, nil 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
}
return hdr[0] == 0x96 && hdr[1] == 0x69, eepromLen, nil
} }
if hdr[0] == 0xa5 && hdr[1] == 0x5a { return false, 0, ErrorUnknownDevice
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
} }
func (h *HAL) patchHookGet(loc MemoryRegion, inIRQ bool) (int, bool, error) { func (h *HAL) patchHookGet(loc MemoryRegion, inIRQ bool) (int, bool, error) {
@ -241,20 +272,25 @@ func (h *HAL) patchHookGet(loc MemoryRegion, inIRQ bool) (int, bool, error) {
value, err := ReadByte(loc, 0x5) value, err := ReadByte(loc, 0x5)
return 0xc420, value == 0x5a, err return 0xc420, value == 0x5a, err
} }
} else if h.deviceType == 2107 {
value, err := ReadByte(loc, 0x8)
if inIRQ {
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
}
} }
value, err := ReadByte(loc, 0x4) return 0, false, ErrorUnknownDevice
if err != nil {
return 0, false, err
}
if inIRQ {
return 0xcc20, value&4 > 0, nil
}
return 0xcc00, value&1 > 0, nil
} }
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 { if h.config.LogFunc != nil {
h.config.LogFunc(2, "Configuring userhook: inIRQ=%v, enable=%v", inIRQ, enable) h.config.LogFunc(2, "Configuring userhook: inIRQ=%v, enable=%v", inIRQ, enable)
} }
@ -272,26 +308,47 @@ func (h *HAL) patchHookConfigure(loc MemoryRegion, inIRQ bool, enable bool) erro
} }
return WriteByte(loc, 0x5, value) return WriteByte(loc, 0x5, value)
} }
} } else if h.deviceType == 2107 {
value, err := ReadByte(loc, 0x8)
value, err := ReadByte(loc, 0x4) if err != nil {
if err != nil { return err
return err
}
if inIRQ {
value &= ^byte(4)
if enable {
value |= 4
} }
} else {
value &= ^byte(1) if inIRQ {
if enable { value &= ^byte(2)
value |= 1 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
}
if inIRQ {
value &= ^byte(4)
if enable {
value |= 4
}
} else {
value &= ^byte(1)
if enable {
value |= 1
}
}
return WriteByte(loc, 0x4, value)
} }
return WriteByte(loc, 0x4, value) return ErrorUnknownDevice
} }
func (h *HAL) patchInitAlloc(userConfig MemoryRegion) (bool, error) { func (h *HAL) patchInitAlloc(userConfig MemoryRegion) (bool, error) {
@ -313,6 +370,8 @@ func (h *HAL) patchInstall() (bool, error) {
var installBlobs []CodeBlob var installBlobs []CodeBlob
if h.deviceType == 2109 { if h.deviceType == 2109 {
installBlobs = installBlobs2109 installBlobs = installBlobs2109
} else if h.deviceType == 2107 {
installBlobs = installBlobs2107
} else if h.deviceType == 2106 { } else if h.deviceType == 2106 {
installBlobs = installBlobs2106 installBlobs = installBlobs2106
} else { } else {
@ -416,27 +475,41 @@ func (h *HAL) patchInstall() (bool, error) {
return true, err return true, err
} }
if userCodePresent && (!enableIrq || !enableNorm) { var oldCodeIRQ []byte
return true, ErrorPatchFailed 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 */ /* 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 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
} else if err := h.patchHookSet(userConfig, false, enableNorm); err != nil {
return true, err return true, err
}
/* Enable callbacks */
if !userCodePresent {
if err := h.patchHookConfigure(userConfig, true, true); err != nil {
return true, err
}
if err := h.patchHookConfigure(userConfig, false, true); err != nil {
return true, err
}
} }
/* Write patch sumblock */ /* Write patch sumblock */

View file

@ -79,7 +79,7 @@ func (h *HAL) MemoryRegionList() []MemoryRegionNameType {
MemoryRegionUserConfig, MemoryRegionUserConfig,
} }
if h.deviceType == 2106 || h.deviceType == 2109 { if h.deviceType == 2106 || h.deviceType == 2109 || h.deviceType == 2107 {
list = append(list, MemoryRegionUserRAM) 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 { if h.deviceType == 2109 {
switch t { switch t {
case MemoryRegionUserRAM: case MemoryRegionUserRAM: