import { parseJSON } from '../codegen.js'; import { ASM, liDX, strlen, str2inst, inst2gecko } from '../asm.js'; export const lskey = 'config/PatternSelector'; import * as GMSJ01 from './code/GMSJ01.js'; import * as GMSJ0A from './code/GMSJ0A.js'; // import * as GMSE01 from './code/GMSE01.js'; // import * as GMSP01 from './code/GMSP01.js'; const codes = { GMSJ01, GMSJ0A }; export const defaultConfig = { x: 16, y: 320, fontSize: 20, fgRGB: 0xffffff, fgA: 0xff, fgRGB2: null, fgA2: null, label: 'Pattern ', }; /** @returns {typeof defaultConfig} */ export function getConfig() { const config = (typeof localStorage !== 'undefined' && parseJSON(localStorage.getItem(lskey))) || {}; return { ...defaultConfig, ...config }; } const addrDrawText = 0x817f0238; const addrCodeBase = 0x817f9000; const addrPV1Data1 = 0x817f9167; const addrFmt0 = 0x817f919d; /** @param {keyof typeof codes} version */ export default function codegen(version) { const { x, y, fontSize, fgRGB, fgA, fgRGB2, fgA2, label } = getConfig(); const colorTop = (fgRGB << 8) | fgA; const colorBot = fgRGB2 == null || fgA2 == null ? colorTop : (fgRGB2 << 8) | fgA; const text = label + '>%X>%X>%X'; const fmtCS0 = strlen(label); const fmtCSD = 3; const { code04, addrDraw2D, codes: cs0 } = codes[version]; const cs = cs0.map((e) => e.replace(/\s+/g, '')); const params = [ liDX(3, x), liDX(4, y), liDX(5, fontSize), liDX(6, colorTop), colorTop === colorBot ? ASM.mr(7, 6) : liDX(7, colorBot), ].flatMap((e) => e); const extraOffset = (params.length - 5) << 2; // default: 5 inst let pc; // 07 let code07 = '801F0000'; /* li32 rEntry, .data.patterns.PV1-1 */ code07 += liDX(8, addrPV1Data1 + extraOffset) .map(inst2gecko) .join(''); code07 += cs[0]; /* li r8 */ code07 += liDX(8, addrFmt0 + extraOffset) .map(inst2gecko) .join(''); code07 += cs[1]; /* stb r0/12/12, fmtCS0+fmtCSD*i(r8) */ code07 += [ ASM.stb(0, 8, fmtCS0), 0x540cc63e, ASM.stb(12, 8, fmtCS0 + fmtCSD), 0x540c863e, ASM.stb(12, 8, fmtCS0 + fmtCSD * 2), ] .flatMap((e) => e) .map(inst2gecko) .join(''); /* (code) */ code07 += cs[2]; /* r3~r7 */ code07 += params.map(inst2gecko).join(''); code07 += '4CC63182'; // crclr 6 /* bl drawText */ pc = addrCodeBase + (code07.length >> 1); code07 += ASM.b(addrDrawText - pc, true) .map(inst2gecko) .join(''); /* addi */ code07 += '38210010'; /* b 4+$b$.draw2d */ pc = addrCodeBase + (code07.length >> 1); code07 += ASM.b(4 + addrDraw2D - pc, false) .map(inst2gecko) .join(''); /* (code) */ code07 += cs[3]; /* fmt */ // prepend 1 dummy char as 'FF' in code code07 += str2inst('.' + text) .map(inst2gecko) .join('') .slice(2); const head07 = [0x06000000 | (addrCodeBase & 0x1ffffff), code07.length >> 1] .map(inst2gecko) .join(''); // align code 07 (8 digit = 4 byte) if (code07.length & 8) code07 += '00000000'; return (code04 + head07 + code07).replace(/\s+/g, ''); }