Initial attempt at adding some functions to MS213x firmware

This commit is contained in:
Bertold Van den Bergh 2023-11-03 23:38:13 +01:00
parent 9866c7b404
commit 162cc22d62
15 changed files with 391 additions and 0 deletions

5
ms213x_patch/asm/asm.sh Executable file
View file

@ -0,0 +1,5 @@
as31 -Fbin init.asm
as31 -Fbin hook.asm
as31 -Fbin finishf660.asm
as31 -Fbin finishsig.asm
as31 -Fbin readinfo.asm

View file

@ -0,0 +1,36 @@
INC DPTR
MOVX @DPTR, A
MOV DPTR, #0x7b10
MOVX A, @DPTR
MOV R7, A
INC DPTR
MOVX A, @DPTR
MOV R6, A
INC DPTR
MOVX A, @DPTR
MOV R5, A
INC DPTR
MOVX A, @DPTR
MOV R4, A
MOV DPTR, #0xf660
MOV A, R7
MOVX @DPTR, A
INC DPTR
MOV A, R6
MOVX @DPTR, A
INC DPTR
MOV A, R5
MOVX @DPTR, A
INC DPTR
MOV A, R4
MOVX @DPTR, A
RET

View file

@ -0,0 +1 @@
Јрђ{аяЈаюЈаэЈаьђц`прЈорЈнрЈмр"

View file

@ -0,0 +1,7 @@
ORL A, R7
MOV DPTR, #0x7b14
MOVX @DPTR, A
MOV R7, A
RET

View file

@ -0,0 +1 @@
O<EFBFBD>{đ˙"

82
ms213x_patch/asm/hook.asm Normal file
View file

@ -0,0 +1,82 @@
hookRun:
MOV DPTR, #0x12b3
MOVX A, @DPTR
XRL A, R0
JNZ hookRet
LCALL hookWork
MOV DPTR, #0x12b3+1
MOVX @DPTR, A
INC DPTR
MOV A, R2
MOVX @DPTR, A
INC DPTR
MOV A, R3
MOVX @DPTR, A
INC DPTR
MOV A, R4
MOVX @DPTR, A
INC DPTR
MOV A, R5
MOVX @DPTR, A
INC DPTR
MOV A, R6
MOVX @DPTR, A
INC DPTR
MOV A, R7
MOVX @DPTR, A
MOV DPTR, #0x12b3
MOV A, #0xFF
RLC A
MOVX @DPTR, A
SETB EA
hookRet:
RET
hookWork:
CLR EA
MOV DPTR, #0x12b3+1
MOVX A, @DPTR
MOV 1, A
INC DPTR
MOVX A, @DPTR
MOV 0, A
PUSH 0
PUSH 1
INC DPTR
MOVX A, @DPTR
MOV R3, A
INC DPTR
MOVX A, @DPTR
MOV R4, A
INC DPTR
MOVX A, @DPTR
MOV R5, A
INC DPTR
MOVX A, @DPTR
MOV R6, A
INC DPTR
MOVX A, @DPTR
MOV R7, A
RRC A
MOV A, R7
MOV DPH, R3
MOV DPL, R4
RET ;Call address in HID+1

BIN
ms213x_patch/asm/hook.bin Normal file

Binary file not shown.

18
ms213x_patch/asm/init.asm Normal file
View file

@ -0,0 +1,18 @@
; Tell host about the existence of this patch
MOV DPTR, #0x7B00
MOV A, #'B'
MOVX @DPTR, A
INC DPTR
MOV A, #'V'
MOVX @DPTR, A
INC DPTR
MOV A, #'D'
MOVX @DPTR, A
INC DPTR
MOV A, #'B'
MOVX @DPTR, A
INC DPTR
CLR A
MOVX @DPTR, A
RET

BIN
ms213x_patch/asm/init.bin Normal file

Binary file not shown.

View file

@ -0,0 +1,26 @@
; Resolution info
MOV DPTR, #0x7b10
MOVX A, @DPTR
MOV R2, A
INC DPTR
MOVX A, @DPTR
MOV R3, A
INC DPTR
MOVX A, @DPTR
MOV R4, A
INC DPTR
MOVX A, @DPTR
MOV R5, A
; Signal info
INC DPTR
MOVX A, @DPTR
; Frame counter
MOV R6, 0x29
MOV R7, 0x28
RET

View file

@ -0,0 +1 @@
<EFBFBD>{את£א<C2A3>£א<C2A3>£א£א®)¯("

48
ms213x_patch/main.go Normal file
View file

@ -0,0 +1,48 @@
package main
import (
"encoding/binary"
"flag"
"log"
"os"
"github.com/BertoldVdb/ms-tools/mshal/ms213x"
)
func main() {
input := flag.String("input", "", "Input filename")
output := flag.String("output", "/tmp/modified.bin", "Output filename")
flag.Parse()
in, err := os.ReadFile(*input)
if err != nil {
log.Fatalln("Failed to open file:", err)
}
if err := ms213x.CheckImage(in); err != nil {
log.Fatalln("Failed to parse image:", in)
}
clen := binary.BigEndian.Uint16(in[2:])
code := in[0x30:]
code = code[:clen]
code, err = patch(code)
if err != nil {
log.Fatalln("Failed to patch code:", err)
}
out := make([]byte, 0x30, 0x30+len(code)+4)
copy(out, in)
binary.BigEndian.PutUint16(out[2:], uint16(len(code)))
out = append(out, code...)
out = binary.BigEndian.AppendUint32(out, 0)
ms213x.FixImage(out)
os.WriteFile("/tmp/modcode.bin", code, 0644)
if err := os.WriteFile(*output, out, 0644); err != nil {
log.Fatalln("Failed to write output:", err)
}
}

BIN
ms213x_patch/ms213x_patch Executable file

Binary file not shown.

122
ms213x_patch/patch.go Normal file
View file

@ -0,0 +1,122 @@
package main
import (
"crypto/sha256"
"encoding/binary"
"encoding/hex"
"fmt"
"log"
_ "embed"
)
type patcher struct {
image []byte
hookOffset uint16
}
//go:embed asm/init.bin
var patchInit []byte
//go:embed asm/hook.bin
var patchHook []byte
//go:embed asm/finishf660.bin
var patchFinishf660 []byte
//go:embed asm/finishsig.bin
var patchFinishSig []byte
//go:embed asm/readinfo.bin
var patchReadInfo []byte
func (p *patcher) addCode(code []byte) uint16 {
offs := len(p.image)
p.image = append(p.image, code...)
return uint16(offs)
}
func (p *patcher) detourCall(offset uint16, dest uint16) {
a := p.image[offset]
if a != 0x02 && a != 0x12 {
panic("Not LJMP or LCALL")
}
var code [6]byte
code[0] = 0x12 /* LCALL */
binary.BigEndian.PutUint16(code[1:], dest)
code[3] = 0x02 /* LJMP */
copy(code[4:], p.image[offset+1:]) /* Copy original address */
binary.BigEndian.PutUint16(p.image[offset+1:], p.addCode(code[:]))
}
func (p *patcher) createHook(cmd uint8) uint16 {
return p.addCode([]byte{
0x78, cmd,
0x02, byte(p.hookOffset >> 8), byte(p.hookOffset),
})
}
func (p *patcher) replaceJump(offset, dest uint16) {
p.image[offset] = 0x02
binary.BigEndian.PutUint16(p.image[offset+1:], dest)
}
func patch(in []byte) ([]byte, error) {
/* Check if it is a file we know how to handle */
hash := sha256.Sum256(in)
hashStr := hex.EncodeToString(hash[:])
if hashStr != "cc67f79a043da85dc8e6688a22111ade626e519e1ab549f110b3a06308190047" {
return nil, fmt.Errorf("code hash %s is not supported", hashStr)
}
p := patcher{
image: in,
}
/* Add init code */
p.detourCall(0x4d48, p.addCode(patchInit))
/* Add hook code and update its internal jump */
p.hookOffset = p.addCode(patchHook)
binary.BigEndian.PutUint16(p.image[p.hookOffset+8:], binary.BigEndian.Uint16(p.image[p.hookOffset+8:])+p.hookOffset)
/* Add hook entry to main loop */
p.detourCall(0x4d70, p.createHook(0xEF)) /* Not in IRQ, but handled the same as the other USB commands */
/* Add 0xEE, remove result codes 0xFF and 0xFE which are legitimate commands (function unclear, can still call them
* via hook if needed) */
table, dflt := p.jumptableParse(0x1d9c)
var newTable []jumptableEntry
needInsert := true
for _, b := range table {
if b.Key > 0xEE && needInsert {
needInsert = false
newTable = append(newTable, jumptableEntry{
Key: 0xEE,
Address: p.createHook(0xEE),
})
}
if b.Key >= 0xFE {
break
}
newTable = append(newTable, b)
}
p.jumptableWrite(0x1d9c, newTable, dflt)
/* Write 0xF660 also to safe place (0x7b10) */
binary.BigEndian.PutUint16(p.image[0xbbb3:], 0x7b10)
binary.BigEndian.PutUint16(p.image[0xbbbf:], 0x7b12)
p.replaceJump(0xbbc3, p.addCode(patchFinishf660))
/* Write signal info to safe place (0x7b14) */
p.replaceJump(0xe9c6, p.addCode(patchFinishSig))
/* Finally, add read results function */
log.Printf("ReadInfo Offset: %02x", p.addCode(patchReadInfo))
return p.image, nil
}

View file

@ -0,0 +1,44 @@
package main
import "encoding/binary"
type jumptableEntry struct {
Key uint8
Address uint16
}
func (p *patcher) jumptableParse(offset uint16) ([]jumptableEntry, uint16) {
var results []jumptableEntry
lastKey := -1
for {
addr := binary.BigEndian.Uint16(p.image[offset:])
offset += 2
if addr > 0 {
key := int(p.image[offset])
offset++
if key < lastKey {
panic("Parse error")
}
lastKey = key
results = append(results, jumptableEntry{
Key: uint8(key),
Address: addr,
})
} else {
return results, binary.BigEndian.Uint16(p.image[offset:])
}
}
}
func (p *patcher) jumptableWrite(offset uint16, entries []jumptableEntry, dflt uint16) {
for _, m := range entries {
binary.BigEndian.PutUint16(p.image[offset:], m.Address)
p.image[offset+2] = m.Key
offset += 3
}
binary.BigEndian.PutUint16(p.image[offset:], 0)
binary.BigEndian.PutUint16(p.image[offset+2:], dflt)
}