Skip to content

Instantly share code, notes, and snippets.

@gabonator
Created February 8, 2023 17:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gabonator/aeed694b0115b43e436ec47bf13b796d to your computer and use it in GitHub Desktop.
Save gabonator/aeed694b0115b43e436ec47bf13b796d to your computer and use it in GitHub Desktop.
Novation mini mk3 hack - simple editor
#include <stdint.h>
#define LED_BUFFER ((uint32_t*)0x20000304)
#define REFRESH_BUFFER ((uint32_t*)0x20006754)
uint8_t buttonMap[8][8];
uint8_t image[8][8];
uint32_t getPixel(int x, int y)
{
uint8_t f = (y+1)*10 + x+1;
return LED_BUFFER[f];
}
uint8_t setPixel(int x, int y, uint32_t c)
{
uint8_t f = (y+1)*10 + x+1;
LED_BUFFER[f] = c;
REFRESH_BUFFER[f] &= 0xf8;
}
uint8_t getButton(int x, int y)
{
uint8_t* buttons = (uint8_t*)0x20001dd0;
static const uint8_t ofs[] = {
64, 65, 66, 67, 96, 97, 98, 99,
60, 61, 62, 63, 92, 93, 94, 95,
56, 57, 58, 59, 88, 89, 90, 91,
52, 53, 54, 55, 84, 85, 86, 87,
48, 49, 50, 51, 80, 81, 82, 83,
44, 45, 46, 47, 76, 77, 78, 79,
40, 41, 42, 43, 72, 73, 74, 75,
36, 37, 38, 39, 68, 69, 70, 71,
};
return !!buttons[ofs[y*8+x]];
}
void inject()
{
((void (*) (void)) 0x0801c0ed)();
for (int y=0; y<8; y++)
for (int x=0; x<8; x++)
{
uint8_t pressed = getButton(x, y);
if (buttonMap[x][y] != pressed)
{
buttonMap[x][y] = pressed;
if (pressed)
{
image[x][y] = !image[x][y];
setPixel(x, y, image[x][y] ? 0 : 255);
}
}
}
}
MEMORY
{
rom (rx) : ORIGIN = 0x0801C4B0, LENGTH = 4K
ram (rwx) : ORIGIN = 0x2000d000, LENGTH = 1K
}
SECTIONS
{
.text : {
*(.text.inject);
*(.text*)
*(.rodata*)
} >rom
.data : {
*(.data*)
} >ram
.bss : {
*(.bss*)
} >ram
}
var fs = require("fs");
var buf1 = fs.readFileSync("LPMiniMK3-407.bin");
var buf2 = fs.readFileSync("code.bin");
var pad = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0])
if (buf1.length + pad.length != 0x104b0)
throw "error"
// TIM1_UP_TIM10_IRQHandle 0800c0a4 ed c0 01 08 addr LAB_0801c0ec+1
var firmwareBase = 0x0800c000;
var vectorPtr = 0x0800c0a4 - firmwareBase;
var vectorOrg = 0x0801c0ed;
var vectorNew = firmwareBase + buf1.length + pad.length | 1;
if (buf1[0x100a0] != "a".charCodeAt(0))
throw "error 3";
if (buf1[vectorPtr+0] != ((vectorOrg>>0)&0xff) ||
buf1[vectorPtr+1] != ((vectorOrg>>8)&0xff) ||
buf1[vectorPtr+2] != ((vectorOrg>>16)&0xff) ||
buf1[vectorPtr+3] != ((vectorOrg>>24)&0xff))
throw "error 2";
var callFlashLed = 0x0800fb20;
buf1[vectorPtr+0] = (vectorNew>>0)&0xff;
buf1[vectorPtr+1] = (vectorNew>>8)&0xff;
buf1[vectorPtr+2] = (vectorNew>>16)&0xff;
buf1[vectorPtr+3] = (vectorNew>>24)&0xff;
//buf1[0x100a0] = "x".charCodeAt(0); // webusb url: api.focusrite-novation.com
// flash_led - 0800f9e0 - 0800fe14 - MainLoop
//var callFlashLed = 0x0800fe16 - firmwareBase;
buf1[callFlashLed+0] = 0x00;
buf1[callFlashLed+1] = 0xbf;
buf1[callFlashLed+2] = 0x00;
buf1[callFlashLed+3] = 0xbf;
/*
buf1[callFlashLed+0] = (vectorNew>>0)&0xff;
buf1[callFlashLed+1] = (vectorNew>>8)&0xff;
buf1[callFlashLed+2] = (vectorNew>>16)&0xff;
buf1[callFlashLed+3] = (vectorNew>>24)&0xff;
*/
fs.writeFileSync("final.bin", Buffer.concat([buf1, pad, buf2]))
set -e
arm-none-eabi-gcc -fno-common -Wno-psabi -Os -g -mcpu=cortex-m4 -mlittle-endian \
-mfpu=fpv4-sp-d16 -mthumb -nostartfiles -ffunction-sections -T code.lds code.c -o code.elf
arm-none-eabi-objdump -S -marm -d ./code.elf > code.s
arm-none-eabi-objcopy -j .text -O binary ./code.elf code.bin
node combine.js
./bintosyx /minimk3 444 ./final.bin final.syx
#flash with (up up down down left right left right): https://fw.mat1jaczyyy.com/firmware
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment