From 9eedbe5e5fadeff798fe70dfce8541dcaca37f41 Mon Sep 17 00:00:00 2001 From: Thiemo Tiziani Date: Mon, 26 Oct 2026 22:02:45 +0100 Subject: [PATCH] site 1.9.4: advanced_waveforms 1.4.0 (overview matches the big waveform, also over LINK; RGB overview in the track's colours), new comparison and boot screenshots Co-Authored-By: Claude Opus 5.5 --- assets/boot-mods.png | Bin 12899 -> 12904 bytes assets/card-boot.png | Bin 11596 -> 11590 bytes assets/mods-full.png | Bin 39769 -> 42550 bytes assets/versions.js | 23 ++++++++++++++++++++--- builder.html | 12 ++++++------ builder/py/bundle.json | 2 +- builder/ui.js | 2 +- datenschutz.html | 6 +++--- docs.html | 14 +++++++------- impressum.html | 6 +++--- index.html | 12 ++++++------ issues.html | 6 +++--- tools/changelog.json | 17 +++++++++++++++++ upcoming.html | 6 +++--- 14 files changed, 70 insertions(+), 36 deletions(-) diff --git a/assets/boot-mods.png b/assets/boot-mods.png index 1df5d6a32331cdadd5378ed27470abb5e53b93d8..5c0a8519f20c3a4de3fffd6f9fb588ba676adf11 100644 GIT binary patch delta 10929 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 RatsU%44$rjF6*2Ung9=S`PTpd delta 10925 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 O3=E#GelF{r5}E*zS}dsm diff --git a/assets/card-boot.png b/assets/card-boot.png index 8ae0aa15f0231b5046b690389c9a34324db9b810..2424e13effc6fb84caf1bbe8a9afd892a97914e2 100644 GIT binary patch delta 10378 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 N!PC{xWt~$(69D3&QXl{T delta 10379 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 CDq9@@ diff --git a/assets/mods-full.png b/assets/mods-full.png index 48467aef919fbef8604057d5df07911ab70a7625..74f1bb4dff720b4b531fed3168ec310dd26174c1 100644 GIT binary patch literal 42550 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%0AhSo6fq2`O}&s_bpe@ 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 Mods Builder - - - - - - + + + + + + diff --git a/builder/py/bundle.json b/builder/py/bundle.json index 43a5ee4..84ddff8 100644 --- a/builder/py/bundle.json +++ b/builder/py/bundle.json @@ -1 +1 @@ -{"mods/patch_cdj900nxs.py":"#!/usr/bin/env python3\n# SPDX-License-Identifier: GPL-2.0-or-later\n\"\"\"Apply arnoldasr's CDJ-900NXS 1.31 mods to the unpacked MAIN image.\n\n usage: patch_cdj900nxs.py [,...]\n patch_cdj900nxs.py --list\n\nThe mods come from https://github.com/arnoldasr/cdj900nxs, read as data from a\ncheckout of it (CDJ900NXS_MODS_SRC, default mods/cdj900nxs/upstream, which is\nnot committed: that repository carries no licence). Nothing of its Python is\nimported; what its build_firmware.py does is redone here:\n\n extended_bpm the BPM with hundredths: the stock tenths moved into a new\n small digit above, the lower one showing hundredths.\n phasemeter the two-line phase meter (orange master, blue this deck, a\n marker each) in place of the four boxes, chosen in UTILITY >\n PHASE METER (SLIP FLASHING relabelled; mods/phase-meter-\n utility.cdjmod.json).\n advanced_waveforms (was rgb_waveform; based on arnoldasr's, updated and\n maintained by us) the big waveform in rekordbox's RGB colours\n (1.0.1: also when its colour detail is a little short,\n cdj900nxs/wavefix.py), and the overview's colour table as a red-to-white\n gradient (mods/waveform-colour.cdjmod.json); with our\n UTILITY > WAVEFORM: BLUE / RGB / 3BAND (cdj900nxs/wavemodes.py,\n left out with public=True).\n\n The three are arnoldasr's code mod (patches/mods.json): hooks\n in the application redirected to SH-4 code appended after it\n (0x08FC1000), plus an asset blob at 0x08FC2D00 generated from\n the stock image (the resource table extended by four phase-meter\n images, then the RGB waveform palette and LUT). Upstream tested\n it as one build, and as one without the RGB waveform\n (patches/bpm-phase-meter.json); one of those two is built and\n checked against its hash first, then the hooks of a feature not\n chosen get their original bytes back. Their shared startup hook\n (0x08C071FC) installs the BPM digits and the phase markers: the\n call of the one not chosen is taken out there.\n beatjump ours, not arnoldasr's (cdj900nxs/beatjump.py): TRACK SEARCH\n jumps 1/2/4/8 beats along the grid, chosen in UTILITY > BEAT JUMP,\n made at once in the DSP's decoded audio (cdj900nxs/dspjump.py, a\n patch of the audio DSP's code),\n which replaces SCREEN SAVER. hotcuekeys' engine makes the jumps,\n so it needs hotcuekeys and cuecolours. Needs no upstream checkout.\n cuecolours ours (cdj900nxs/cuecolours.py): memory cues drawn in their\n rekordbox colour on the overview and the detail waveform, the\n rekordbox hot cues shown as lettered boxes.\n Needs no upstream checkout.\n hotcuekeys ours (cdj900nxs/hotcuekeys.py): UTILITY > HOT CUE KEYS (a new,\n 18th item); with it ON, QUANTIZE briefly pressed switches a hot\n cue key mode shown in a HOT KEYS box, held it is QUANTIZE. In\n the mode the top three BEAT DIVIDE keys play hot cues A-C (held: a\n gate), set one (empty key held while paused) or delete one\n (DELETE held). The hot cues come from cuecolours.\n ledsaver ours (cdj900nxs/ledsaver.py): UTILITY > LED ANIMATION (one more\n item, after the others); with it ON, while the screen saver dims\n the display the button LEDs and the jog's rings play a loop.\n keynotation ours (cdj900nxs/keynotation.py): UTILITY > KEY NOTATION (one\n more item): every track's key in Camelot, Open Key or classic\n notation, whatever rekordbox exported.\n usbautoload ours (cdj900nxs/usbautoload.py): UTILITY > USB AUTO LOAD (one\n more item): a stick's MY SETTINGS are loaded when the player finds\n them, without waiting for MENU.\n quicksearch ours (cdj900nxs/quicksearch.py): BROWSE held opens SEARCH,\n BROWSE twice the list the playing track came from.\n (phasemeter, in unreleased builds, also gets ours from cdj900nxs/phasereverse.py:\n UTILITY > PHASE METER OFF / ON / REVERSE, and the beat countdown\n moved clear of the line meter; `phasereverse` is an old name for it.)\n wide_waveform ours (cdj900nxs/widewave.py): the big waveform runs on to the\n right edge (624 columns, the extra ones ahead of the position); the\n ZOOM/GRID wheel gives way to a small grey ZOOM / GRID box.\n credit ours (cdj900nxs/credit.py): the boot screen says \"Pionaarr Mods\n 1.0\" where it said \"Ver 1.31\".\n\nEvery patch is applied only where the image holds the expected original\nbytes, and arnoldasr's code is first built as one of the builds he tested\nand checked against its hash.\n\nOur lzss_decode.py runs 54 bytes past the end of the packed stream, so\nmain_unpacked.bin is the 1.31 application plus a tail the firmware never\nreads; the application is cut back to its own length first.\n\"\"\"\nimport hashlib\nimport json\nimport os\nimport struct\nimport sys\n\nHERE = os.path.dirname(os.path.abspath(__file__))\nsys.path.insert(0, os.path.join(HERE, 'cdj900nxs'))\nimport beatjump # noqa: E402\nimport credit # noqa: E402\nimport dspjump # noqa: E402\nimport cuecolours # noqa: E402\nimport hotcuekeys # noqa: E402\nimport keynotation # noqa: E402\nimport ledsaver # noqa: E402\nimport usbautoload # noqa: E402\nimport quicksearch # noqa: E402\nimport phasereverse # noqa: E402\nimport wavemodes # noqa: E402\nimport wavefix # noqa: E402\nimport cuenames # noqa: E402\nimport endwarn # noqa: E402\nimport played # noqa: E402\nimport widewave # noqa: E402\n\nBASE = 0x08000000\nAPP_SIZE = 16519056\nAPP_SHA256 = '1ac3e30cde292865413950fe159663b3958e85939ed0a5d0122f796809a5f8ef'\n\nMODS = {\n 'extended_bpm': 'BPM with hundredths: tenths as a small digit above (arnoldasr)',\n 'phasemeter': 'two-line phase meter, UTILITY > PHASE METER (SLIP FLASHING) chooses it (arnoldasr); '\n 'OFF / ON / REVERSE and the beat countdown moved clear of it (ours: cdj900nxs/phasereverse.py)',\n 'advanced_waveforms': 'big waveform in RGB colours, overview as a red-to-white gradient (arnoldasr); '\n 'UTILITY > WAVEFORM: BLUE / RGB / 3BAND (ours: cdj900nxs/wavemodes.py)',\n 'beatjump': 'TRACK SEARCH jumps 1/2/4/8 beats, UTILITY > BEAT JUMP (ours: cdj900nxs/beatjump.py)',\n 'cuecolours': 'memory cues in their rekordbox colours, hot cues shown (ours: cdj900nxs/cuecolours.py)',\n 'hotcuekeys': 'hot cues A-C on the BEAT DIVIDE keys: play, gate, set, delete; UTILITY > HOT CUE KEYS, '\n 'QUANTIZE short = hot key mode (ours: cdj900nxs/hotcuekeys.py)',\n 'ledsaver': 'the button and jog LEDs play an animation while the screen saver dims the display; '\n 'UTILITY > LED ANIMATION (ours: cdj900nxs/ledsaver.py)',\n 'keynotation': 'every key in one notation (Camelot / Open Key / classic), UTILITY > KEY NOTATION '\n '(ours: cdj900nxs/keynotation.py)',\n 'usbautoload': 'MY SETTINGS on a USB stick loaded at once, UTILITY > USB AUTO LOAD '\n '(ours: cdj900nxs/usbautoload.py)',\n 'quicksearch': 'BROWSE held: SEARCH; BROWSE twice: the playing track in its list '\n '(ours: cdj900nxs/quicksearch.py)',\n 'cuenames': 'the rekordbox comment of the next cue (\"Drop\") in the title bar, in its colour '\n '(ours: cdj900nxs/cuenames.py, needs cuecolours)',\n 'endwarn': 'the playing-address bar blinks red in the last 30 seconds (ours: cdj900nxs/endwarn.py)',\n 'played': 'BROWSE ticks the tracks loaded on this player since it was switched on (ours: cdj900nxs/played.py)',\n 'wide_waveform': 'the big waveform to the right edge, the ZOOM/GRID wheel replaced by a small ZOOM / GRID box '\n '(ours: cdj900nxs/widewave.py)',\n 'credit': 'boot screen says \"Pionaarr Mods 1.0\" instead of \"Ver 1.31\" (ours: cdj900nxs/credit.py)',\n}\n# every mod's version (Semantic Versioning); ours from their modules, arnoldasr's\n# split-up mods as packaged here\nVERSIONS = {\n 'extended_bpm': '1.0.0', 'phasemeter': '1.0.1', 'advanced_waveforms': wavemodes.VERSION, # with its WAVEFORM modes (wavefix: wavefix.VERSION)\n 'beatjump': beatjump.VERSION, 'cuecolours': cuecolours.VERSION, 'hotcuekeys': hotcuekeys.VERSION,\n 'ledsaver': ledsaver.VERSION, 'keynotation': keynotation.VERSION, 'usbautoload': usbautoload.VERSION,\n 'quicksearch': quicksearch.VERSION,\n 'cuenames': cuenames.VERSION, 'endwarn': endwarn.VERSION, 'played': played.VERSION,\n 'wide_waveform': widewave.VERSION, 'credit': credit.VERSION,\n}\nMANIFESTS = {\n 'phasemeter': 'mods/phase-meter-utility.cdjmod.json',\n 'advanced_waveforms': 'mods/waveform-colour.cdjmod.json',\n}\n# arnoldasr's code mod split up: each feature's hooks in the application\nUPSTREAM = ('extended_bpm', 'phasemeter', 'advanced_waveforms')\nHOOKS = {\n 'extended_bpm': (0x08BD3E50, 0x08BD3ED8, 0x08BD3A48, 0x08BCBA60, 0x08BCBCFC),\n 'phasemeter': (0x08B2E2EE, 0x08C6A6CC, 0x08C6CCD0),\n 'advanced_waveforms': (0x089A061C, 0x08BC6830, 0x08BC6A7C, 0x08BCFD72, 0x08BCFF50),\n}\nSHARED_HOOKS = (0x08C071FC, 0x08B27BC8) # startup binding, arena reset: BPM and phase\nBPM_INSTALL_CALL = 0x08FC2444 # startup_bind's jsr of the BPM digits' installer\nPHASE_MARKERS_CALL = 0x08FC2450 # ... and of the phase markers' (startup_markers)\n\n\ndef source_dir():\n return os.environ.get('CDJ900NXS_MODS_SRC') or os.path.join(HERE, 'cdj900nxs', 'upstream')\n\n\ndef read_json(rel):\n path = os.path.join(source_dir(), rel)\n if not os.path.isfile(path):\n raise SystemExit('patch_cdj900nxs: %s missing -- check out '\n 'https://github.com/arnoldasr/cdj900nxs into %s'\n % (path, source_dir()))\n with open(path, encoding='utf-8') as f:\n return json.load(f)\n\n\ndef sha(data):\n return hashlib.sha256(data).hexdigest()\n\n\n# The asset blob, as tools/phase_assets.py builds it (same constants).\nTABLE, DESCRIPTOR, ORIGINAL_COUNT, TEMPLATE = 0x08100000, 0x2C, 0x2A1, 0x1C8\nDATA_BASE = 0x08FC2D00\nWIDTH, HEIGHT, MARKER_WIDTH, BAR = 200, 24, 8, 5\nKEY = 0xF81F\nORANGE_LINE, ORANGE_MARK = (120, 65, 20), (255, 140, 0)\nBLUE_LINE, BLUE_MARK = (40, 90, 120), (60, 170, 255)\nWAVE_COLOURS = [\n 448, 457, 47, 458, 449, 111, 495, 466, 175, 467, 487, 239, 303, 479, 367, 459, 456, 431,\n 468, 465, 475, 476, 474, 39, 477, 31, 471, 46, 469, 45, 23, 460, 109, 484, 110, 485, 103,\n 478, 483, 493, 494, 486, 95, 15, 450, 167, 492, 173, 174, 231, 115, 470, 238, 44, 237, 159,\n 295, 87, 108, 302, 51, 301, 491, 482, 359, 223, 366, 365, 236, 300, 179, 423, 461, 287, 430,\n 429, 172, 364, 473, 428, 351, 114, 151, 463, 299, 363, 415, 215, 427, 178, 490, 50, 279, 235,\n 79, 462, 451, 343, 511, 298, 362, 400, 52, 116, 426, 234, 407, 7, 143, 180, 207, 113, 233,\n 243, 481, 57, 271, 452, 417, 177]\nWHITENESS_COLOURS = [(150, 20, 20), (220, 40, 30), (255, 110, 20), (255, 190, 30), (170, 230, 60),\n (40, 210, 170), (60, 160, 255), (225, 240, 255)]\n\n\ndef rgb565(rgb):\n r, g, b = rgb\n return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)\n\n\ndef line_image(colour):\n px = [KEY] * (WIDTH * HEIGHT)\n for x in range(2, WIDTH - 2):\n px[12 * WIDTH + x] = rgb565(colour)\n for i in range(5):\n x = 2 + i * (WIDTH - 5) // 4\n for y in range(7, 18):\n px[y * WIDTH + x] = rgb565(colour)\n return px\n\n\ndef marker_image(colour):\n return [rgb565(colour) if 3 <= y <= 21 and x < BAR else KEY\n for y in range(HEIGHT) for x in range(MARKER_WIDTH)]\n\n\ndef rgb9(code):\n return tuple(((code >> shift) & 7) * 255 // 7 for shift in (6, 3, 0))\n\n\ndef wave_palette():\n colours = WHITENESS_COLOURS + [rgb9(c) for c in WAVE_COLOURS]\n return struct.pack('<128H', *[rgb565(c) for c in colours])\n\n\ndef wave_lut():\n def nearest(code):\n r, g, b = (code >> 6) & 7, (code >> 3) & 7, code & 7\n return min(range(len(WAVE_COLOURS)), key=lambda i: (\n (((WAVE_COLOURS[i] >> 6) & 7) - r) ** 2 + (((WAVE_COLOURS[i] >> 3) & 7) - g) ** 2\n + ((WAVE_COLOURS[i] & 7) - b) ** 2, i))\n return bytes(8 + nearest(code) for code in range(512))\n\n\ndef assets(app):\n images = [(WIDTH, line_image(ORANGE_LINE)), (WIDTH, line_image(BLUE_LINE)),\n (MARKER_WIDTH, marker_image(ORANGE_MARK)), (MARKER_WIDTH, marker_image(BLUE_MARK))]\n original = app[TABLE - BASE:TABLE - BASE + ORIGINAL_COUNT * DESCRIPTOR]\n template = original[TEMPLATE * DESCRIPTOR:(TEMPLATE + 1) * DESCRIPTOR]\n count = ORIGINAL_COUNT + len(images)\n table_bytes = count * DESCRIPTOR\n pixels_base = DATA_BASE + ((table_bytes + 31) & ~31)\n table, pixels = bytearray(original), bytearray()\n for i, (width, data) in enumerate(images):\n entry = bytearray(template)\n struct.pack_into(' mov #0,r0 (not installed)\n if 'phasemeter' not in names:\n call(PHASE_MARKERS_CALL, 0x410B, 0x0009) # jsr @r1 -> nop\n return bytes(out)\n\n\ndef apply_manifest(app, stock, name):\n doc = read_json(MANIFESTS[name])\n if doc['target']['application_sha256'] != APP_SHA256:\n raise SystemExit('patch_cdj900nxs: %s targets another application' % name)\n out = bytearray(app)\n for p in doc['patches']:\n off = int(p['offset'], 16) if isinstance(p['offset'], str) else p['offset']\n before, after = bytes.fromhex(p['expect']), bytes.fromhex(p['replace'])\n if len(before) != len(after) or off + len(before) > APP_SIZE:\n raise SystemExit('patch_cdj900nxs: %s: bad patch at 0x%x' % (name, off))\n if stock[off:off + len(before)] != before or app[off:off + len(before)] != before:\n raise SystemExit('patch_cdj900nxs: %s: bytes at 0x%x are not the expected original'\n % (name, off))\n out[off:off + len(before)] = after\n return bytes(out)\n\n\n# old names still taken\nALIASES = {'rgb_waveform': 'advanced_waveforms', 'waveform3band': 'advanced_waveforms',\n 'phasereverse': 'phasemeter'}\n\n\ndef check_names(names):\n \"\"\"The names with old ones taken, every mod known and what each needs.\"\"\"\n names = list(dict.fromkeys(ALIASES.get(n, n) for n in names))\n unknown = [n for n in names if n not in MODS]\n if unknown:\n raise SystemExit('patch_cdj900nxs: unknown mod(s) %s; known: %s'\n % (', '.join(unknown), ', '.join(MODS)))\n if 'cuenames' in names and 'cuecolours' not in names:\n raise SystemExit('patch_cdj900nxs: cuenames needs cuecolours (its cue reader brings the comments)')\n if 'beatjump' in names and not {'cuecolours', 'hotcuekeys'} <= set(names):\n raise SystemExit('patch_cdj900nxs: beatjump needs cuecolours and hotcuekeys '\n '(the jumps are made by hotcuekeys)')\n return names\n\n\ndef patch_upstream(stock, names):\n \"\"\"Stage 1: arnoldasr's mods (his code and assets, his manifests, and\n advanced_waveforms' fix that sits on his code). The website's builder\n has this stage as data (tools/make_builder_data.py).\"\"\"\n upstream = [n for n in UPSTREAM if n in names]\n app = apply_code(stock, upstream) if upstream else stock\n for name in ('phasemeter', 'advanced_waveforms'):\n if name in names:\n app = apply_manifest(app, stock, name)\n if 'advanced_waveforms' in names:\n app = wavefix.patch(app, stock) # 1.0.1: a slightly short PWV5 is taken too\n return app\n\n\ndef patch_ours(app, stock, names):\n \"\"\"Stage 2: our mods, on the application stage 1 made (the website's\n builder runs this function itself, in the browser).\"\"\"\n if 'beatjump' in names:\n app = beatjump.patch(app, stock)\n app = dspjump.patch(app, stock) # the jumps in the DSP's decoded audio\n if 'cuecolours' in names:\n app = cuecolours.patch(app, stock)\n if 'hotcuekeys' in names:\n app = hotcuekeys.patch(app, stock)\n if 'ledsaver' in names:\n app = ledsaver.patch(app, stock)\n if 'keynotation' in names:\n app = keynotation.patch(app, stock)\n if 'cuenames' in names:\n app = cuenames.patch(app, stock) # after keynotation: chains its text draw\n if 'played' in names:\n app = played.patch(app, stock) # after keynotation and cuenames: chains their text draw\n if 'endwarn' in names:\n app = endwarn.patch(app, stock)\n if 'usbautoload' in names:\n app = usbautoload.patch(app, stock)\n if 'quicksearch' in names:\n app = quicksearch.patch(app, stock)\n if 'phasemeter' in names:\n app = phasereverse.patch(app, stock) # PHASE METER: OFF / ON / REVERSE\n app = phasereverse.shift_bars(app, stock) # the beat countdown clear of the line meter\n if 'advanced_waveforms' in names:\n app = wavemodes.patch(app, stock) # UTILITY > WAVEFORM: BLUE / RGB / 3BAND\n if 'wide_waveform' in names:\n app = widewave.patch(app, stock) # after advanced_waveforms (its centre-row literal) and hotcuekeys (the draw method)\n if 'credit' in names:\n app = credit.patch(app, stock)\n return app\n\n\ndef patch(data, names, public=False):\n \"\"\"The patched application for the mods named, in a fixed order: stage 1\n (arnoldasr's) and stage 2 (ours). Everything is released now; `public`\n is still taken and changes nothing.\"\"\"\n names = check_names(names)\n stock = data[:APP_SIZE]\n if sha(stock) != APP_SHA256:\n raise SystemExit('patch_cdj900nxs: not the CDJ-900NXS 1.31 application')\n return patch_ours(patch_upstream(stock, names), stock, names)\n\n\ndef main():\n args = sys.argv[1:]\n if args == ['--list']:\n for name, what in MODS.items():\n print('%-13s %-6s %s' % (name, VERSIONS[name], what))\n return\n if len(args) != 3:\n raise SystemExit(__doc__)\n names = [n for n in args[2].replace(' ', ',').split(',') if n]\n with open(args[0], 'rb') as f:\n out = patch(f.read(), names)\n with open(args[1], 'wb') as f:\n f.write(out)\n print('patch_cdj900nxs: %s (%s), %d bytes, sha256 %s'\n % (args[1], ','.join(names), len(out), sha(out)))\n\n\nif __name__ == '__main__':\n main()\n","mods/cdj900nxs/beatjump.py":"# SPDX-License-Identifier: GPL-2.0-or-later\n\"\"\"BEAT JUMP for the CDJ-900NXS 1.31: TRACK SEARCH jumps N beats along the\ntrack's beat grid, N set in UTILITY > BEAT JUMP (OFF/1/2/4/8, default 4).\n\nOur own mod, not arnoldasr's; mods/patch_cdj900nxs.py applies it as `beatjump`.\nEverything here was found by tracing the firmware in the emulator:\n\n * The UI's poller calls the panel decoder 0x08B63278 (through its literal\n at 0x08B622A8), which turns report byte 0x12 bits 0x04 / 0x08 of the\n frame at 0x0B2E8280 into the key bits TRACK - (0x0B2E82C6 bit 0x01) and\n TRACK + (0x0B2E82C5 bit 0x80); later readers (0x08B630D0) turn those\n into the track search. The literal now points at bj_poll, which runs the\n decoder and then, with BEAT JUMP on and a beat grid loaded, takes both\n key bits out again: the track search never starts, so neither the UI nor\n the player changes track, and a press is a jump instead. (Clearing the\n report byte before the decoder instead lost a race with the panel task\n refilling the frame.)\n * The jump is made by hotcuekeys' engine (hk_engine's he_bj, which is\n why beatjump needs hotcuekeys and cuecolours): bj_poll writes the\n target in 1/150 s with bit 31 set to hotcuekeys.BJ_REQ, the tick of\n the press to BJ_TICK and the jump's length in ms to BJ_DELTA, unless a\n jump is still waiting. The engine has the DSP move its playing head by\n that many 1/75 s slots inside the audio it has already decoded\n (dspjump.py, a patch of the audio DSP): at once, gapless, the CUE point\n stays, playing, paused or at cue standby (standing, the UI is left\n paused, so PLAY plays on from there). Only where the DSP has not that\n much audio decoded does it refuse: playing, the engine then loads the\n target into the beat jumps' own DSP cue slot (hotcuekeys.BJ_SLOT) the\n old way, moved on by the time such a load takes so the deck comes back\n in phase; standing, the press is dropped (the old way there, a memory\n CALL, left the UI waiting for good after the third or fourth).\n [Since: no fallback at all; the slot load left the deck standing. A\n press the DSP cannot jump now (it keeps dspjump.MARGIN decoded ahead, so\n the time needed grows with the setting) or made while a jump still\n waits is ignored: nothing is put off, the next press counts again.]\n * The setting is kept in the player's settings journal (hotcuekeys'\n hk_save2/hk_load2 through HK_API, id SAVE_ID): the first poll takes the\n last saved value (else DEFAULT, 4 beats) into the setting's word, a\n change is written back. The firmware itself kept SCREEN SAVER's ON/OFF\n only, so BEAT JUMP came back as 1 after a restart.\n * The grid is read as arnoldasr's phase meter reads it, from the player\n context 0x099445DC: track *(ctx+0x20), X = *(track+0xC4), grid\n *(X+0x104), timestamp adjustment *(X+0x10C); 0x08A27D4C(grid, adj,\n pos_ms) gives 1 + the index of the beat at or before pos_ms, 0x08A0EFB6\n (record, adj) a beat's time in ms. The position in ms is ctx+0x2CC.\n * A jump keeps the position's offset within its beat: target = pos +\n t[i +/- N] - t[i]. Before the first beat (a track just loaded stands at\n its CUE, often a hair before beat 1) i is beat 0. A press whose target\n would leave the grid does nothing. With the setting OFF, or no grid, TRACK SEARCH is untouched.\n\nUTILITY > SCREEN SAVER (item 14, a word at 0x0A4DD270 + 0x1760, values\nOFF/ON, factory default ON = 1) becomes BEAT JUMP: its label in all 19\nlanguages, five values OFF/1/2/4/8 (the existing \"OFF\" and MIDI CHANNEL's digit\nstrings), so the old ON is now \"1\". The screen saver itself no longer reads\nthe setting: its getter literal (0x08BB7E60) points at a firmware tail that\nreturns 1, so it stays on as it was by default.\n\"\"\"\nimport os\nimport struct\nimport sys\n\nsys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))\nimport hotcuekeys # noqa: E402\n\nVERSION = '1.0.1' # Semantic Versioning: MAJOR.MINOR.PATCH\n\nBASE = 0x08000000\nBJ_BASE = 0x08FCF400 # after arnoldasr's code mod (ends 0x08FCF260)\n\nPLAYER_CTX = 0x099445DC\nDECODER_LIT = 0x08B622A8 # the UI poller's literal of the panel decoder\nDECODER = 0x08B63278\nKEYS_TRACK = 0x0B2E82C5 # decoded keys: TRACK + is bit 0x80 here, TRACK - 0x01 of the next byte\nSEND = 0x08B3B666 # the UI's player-message builder\nGET_SETTING = 0x08AFD9E0 # SCREEN SAVER getter: *(0x0A4DD270 + 0x1760)\nGRID_LOOKUP = 0x08A27D4C\nGRID_TIME = 0x08A0EFB6\nFPSCR_MASK = 0xFFE7FFFF # what the firmware does to fpscr after every call\n\nSAVER_ITEM = 0x08C6CBB4 # UTILITY item 14 (copied to RAM at start-up)\nSAVER_CONSUMER_LIT = 0x08BB7E60 # the screen saver's literal of the getter\nRETURN_ONE = 0x08BDA1B0 # 'rts; mov #1,r0' at the end of a firmware function\nVALUE_STRINGS = [0xA80D013C, 0xA80D0144, 0xA80D0148, 0xA80D0150, 0xA80D0160] # OFF 1 2 4 8\nLABEL_OLD = 'SCREEN SAVER\\0'.encode('utf-16-le')\nLABEL_NEW = 'BEAT JUMP'.encode('utf-16-le').ljust(len(LABEL_OLD), b'\\0')\nLABEL_COPIES = 19\n\nVALUE_LIST = BJ_BASE + 0x400 # the five value-string pointers, after the code\nPREV_BITS = BJ_BASE + 0x3FC # last frame's TRACK bits, for press edges\nLAST_SET = BJ_BASE + 0x3F8 # word: the setting last seen (-1 at start: taken from the journal then)\nSETTING = 0x0A4DD270 + 0x1760 # the setting's word (the SCREEN SAVER's)\nSAVE_ID = 0x83E2 # ours in the settings journal (hotcuekeys' is 0x83E1)\nDEFAULT = 3 # 4 beats\nBJ_DELTA = 0x08FCF818 # word: the last jump's length in ms (signed), for hotcuekeys' DSP jump\nBJ_POSV = hotcuekeys.BJ_POSV # word: the position (ms) to reckon from, if not 0\nBJ_PEND = hotcuekeys.BJ_PEND # word: presses counted while hotcuekeys' CALL had no grid\n\n\nclass Asm:\n \"\"\"Just enough SH-4 to write bj_poll: two passes over a list of\n instructions, labels, and a literal pool of .long/.word constants.\"\"\"\n\n def __init__(self, base):\n self.base, self.items, self.labels = base, [], {}\n\n def label(self, name):\n self.items.append(('label', name))\n\n def op(self, fn):\n self.items.append(('op', fn))\n\n def long(self, name, value):\n self.items.append(('align4', None))\n self.label(name)\n self.items.append(('long', value))\n\n def word(self, name, value):\n self.label(name)\n self.items.append(('word', value))\n\n def assemble(self):\n for final in (False, True):\n pc, out = self.base, bytearray()\n for kind, arg in self.items:\n if kind == 'label':\n self.labels[arg] = pc\n continue\n if kind == 'align4':\n while pc % 4:\n out += struct.pack('> 36 = q / 20\n a.long('L_req', hotcuekeys.BJ_REQ)\n a.long('L_tick', hotcuekeys.TICK)\n a.long('L_bit31', 0x80000000)\n a.long('L_delta', BJ_DELTA)\n a.long('L_posv', BJ_POSV)\n a.long('L_pend', BJ_PEND)\n a.long('L_third', 0xAAAAAAAB) # q * this >> 33 = q / 3\n a.long('L_last', LAST_SET)\n a.long('L_setting', SETTING)\n a.long('L_bjid', SAVE_ID)\n a.long('L_bjid16', SAVE_ID << 16)\n a.long('L_api', hotcuekeys.HK_API)\n code = a.assemble()\n return code, None\n\n\ndef patch(app, stock):\n \"\"\"The application with BEAT JUMP added; `stock` is the unmodified 1.31\n application, which every replaced byte is checked against.\"\"\"\n code, _ = routine()\n assert len(code) <= LAST_SET - BJ_BASE\n out = bytearray(app)\n end = VALUE_LIST + 4 * len(VALUE_STRINGS) - BASE\n if len(out) < end:\n out += bytes(end - len(out))\n if any(out[BJ_BASE - BASE:end]):\n raise SystemExit('patch_cdj900nxs: beatjump: its area 0x%08x.. is not free' % BJ_BASE)\n\n def put(addr, before, after):\n off = addr - BASE\n if stock[off:off + len(before)] != before or out[off:off + len(before)] != before:\n raise SystemExit('patch_cdj900nxs: beatjump: bytes at 0x%08x are not the expected original'\n % addr)\n out[off:off + len(after)] = after\n\n out[BJ_BASE - BASE:BJ_BASE - BASE + len(code)] = code\n out[LAST_SET - BASE:LAST_SET - BASE + 4] = b'\\xff\\xff\\xff\\xff'\n out[VALUE_LIST - BASE:end] = b''.join(struct.pack('= 0:\n put(BASE + at, LABEL_OLD, LABEL_NEW)\n found += 1\n at = stock.find(LABEL_OLD, at + 2)\n if found != LABEL_COPIES:\n raise SystemExit('patch_cdj900nxs: beatjump: %d SCREEN SAVER labels, expected %d'\n % (found, LABEL_COPIES))\n return bytes(out)\n","mods/cdj900nxs/c6asm.py":"#!/usr/bin/env python3\n\"\"\"casm.py: a minimal TI C674x assembler for our DSP patches (32-bit, serial\ninstructions only: every p bit 0, no compact forms). Every encoding below is\nchecked against words of the CDJ-900NXS DSP image (selftest()).\n\nRegisters: 'a0'..'a31', 'b0'..'b31'. Predicates: '[b0]', '[!a1]' prefix\n(A1, A2, B0, B1, B2 only). Delay slots are the caller's business: loads need\n4 slots before their result is used, branches 5.\n\n asm = Asm(base)\n asm.label('x'); asm.op('mvk', 0x1234, 'a3'); asm.op('b', 'x') ...\n words = asm.assemble()\n\"\"\"\nimport struct\n\nCREG = {'b0': 1, 'b1': 2, 'b2': 3, 'a1': 4, 'a2': 5, 'a0': 6}\n\n\ndef reg(r):\n side = 1 if r[0] == 'b' else 0\n return side, int(r[1:])\n\n\ndef pred(p):\n if not p:\n return 0\n neg = p.startswith('!')\n return CREG[p.lstrip('!')] << 29 | (1 << 28 if neg else 0)\n\n\n# .L unit 3-operand ops (op field bits 11-5): (si,xsi) form and (s5,xsi) form\nL_OPS = {\n 'add': (0x03, 0x02), 'sub': (0x07, 0x06), 'cmpeq': (0x53, 0x52),\n 'cmpgt': (0x47, 0x46), 'cmplt': (0x57, 0x56), 'cmpgtu': (0x4F, 0x4E),\n 'cmpltu': (0x5F, 0x5E), 'or': (0x7F, 0x7E), 'and': (0x7B, 0x7A),\n}\n# .D load/store op field (bits 6-4)\nD_OPS = {'ldhu': 0, 'ldbu': 1, 'ldb': 2, 'stb': 3, 'ldh': 4, 'sth': 5, 'ldw': 6, 'stw': 7}\nD_SCALE = {'ldhu': 2, 'ldbu': 1, 'ldb': 1, 'stb': 1, 'ldh': 2, 'sth': 2, 'ldw': 4, 'stw': 4}\n\n\ndef enc_l(op, src1, src2, dst, p=''):\n \"\"\"op src1,src2,dst on .L (unit side = dst side; src2 may cross).\"\"\"\n ds, dn = reg(dst)\n s2s, s2n = reg(src2)\n x = 1 if s2s != ds else 0\n if isinstance(src1, int):\n assert -16 <= src1 < 16\n code = L_OPS[op][1]\n s1 = src1 & 31\n else:\n s1s, s1 = reg(src1)\n assert s1s == ds, 'src1 must be on the unit side'\n code = L_OPS[op][0]\n return pred(p) | dn << 23 | s2n << 18 | s1 << 13 | x << 12 | code << 5 | 0b110 << 2 | ds << 1\n\n\ndef enc_mvk(hi, val, dst, p=''):\n ds, dn = reg(dst)\n cst = (val >> 16 if hi else val) & 0xFFFF\n return pred(p) | dn << 23 | cst << 7 | (0b11010 if hi else 0b01010) << 2 | ds << 1\n\n\ndef enc_d(op, data, base, off, p=''):\n \"\"\"ld/st *+base(off) (byte offset, scaled by the access size).\"\"\"\n ss, sn = reg(data)\n bs, bn = reg(base)\n sc = D_SCALE[op]\n assert off % sc == 0 and 0 <= off // sc < 32, (op, off)\n return pred(p) | sn << 23 | bn << 18 | (off // sc) << 13 | 0b0001 << 9 | bs << 7 | D_OPS[op] << 4 | 0b01 << 2 | ss << 1\n\n\ndef enc_b_imm(at, target, side=0, p=''):\n disp = (target - (at & ~31)) // 4\n assert -(1 << 20) <= disp < (1 << 20)\n return pred(p) | (disp & 0x1FFFFF) << 7 | 0b00100 << 2 | side << 1\n\n\ndef enc_b_reg(r, p=''):\n rs, rn = reg(r)\n return pred(p) | rn << 18 | (1 if rs == 0 else 0) << 12 | 0x362 # .S2 (X for an A register)\n\n\ndef enc_nop(n):\n assert 1 <= n <= 9\n return (n - 1) << 13\n\n\nDINT, RINT = 0x10004000, 0x10006000\n\n\ndef enc_shl(src, cst, dst, p=''):\n \"\"\"shl .S src,ucst5,dst\"\"\"\n ds, dn = reg(dst)\n ss, sn = reg(src)\n assert ss == ds and 0 <= cst < 32\n return pred(p) | dn << 23 | sn << 18 | cst << 13 | 0x32 << 6 | 0b1000 << 2 | ds << 1\n\n\ndef enc_dp(op, data, off, p=''):\n \"\"\"ld/st *+b14(ucst15) (byte offset, scaled), .D2\"\"\"\n ds, dn = reg(data)\n sc = D_SCALE[op]\n assert off % sc == 0 and 0 <= off // sc < 32768\n return pred(p) | dn << 23 | (off // sc) << 8 | 0 << 7 | D_OPS[op] << 4 | 0b11 << 2 | ds << 1\n\n\ndef enc_extu(src, csta, cstb, dst, p=''):\n \"\"\"extu .S src,csta,cstb,dst (field form, bits 7-6 = 00).\"\"\"\n ds, dn = reg(dst)\n ss, sn = reg(src)\n assert ss == ds\n return pred(p) | dn << 23 | sn << 18 | csta << 13 | cstb << 8 | 0b00 << 6 | 0b0010 << 2 | ds << 1\n\n\ndef enc_addaw(src2, src1, dst, p=''):\n \"\"\"addaw .D dst = src2 + src1*4 (src1 register or ucst5).\"\"\"\n ds, dn = reg(dst)\n s2s, s2n = reg(src2)\n assert s2s == ds\n if isinstance(src1, int):\n return pred(p) | dn << 23 | s2n << 18 | (src1 & 31) << 13 | 0x3A << 7 | 0b10000 << 2 | ds << 1\n s1s, s1n = reg(src1)\n return pred(p) | dn << 23 | s2n << 18 | s1n << 13 | 0x38 << 7 | 0b10000 << 2 | ds << 1\n\n\nclass Asm:\n def __init__(self, base):\n self.base, self.items, self.labels = base, [], {}\n\n def label(self, name):\n self.items.append(('label', name))\n\n def org(self, addr):\n \"\"\"continue at addr (a new block; the caller branches there)\"\"\"\n self.items.append(('org', addr))\n\n def op(self, mn, *a, p=''):\n self.items.append(('op', (mn, a, p)))\n\n def word(self, w):\n self.items.append(('word', w))\n\n def _enc(self, at, mn, a, p):\n if mn == 'mvk':\n return enc_mvk(0, a[0], a[1], p)\n if mn == 'mvkh':\n return enc_mvk(1, a[0], a[1], p)\n if mn == 'mvkl32': # helper: emitted as two words by assemble()\n raise AssertionError\n if mn in L_OPS:\n return enc_l(mn, a[0], a[1], a[2], p)\n if mn in D_OPS:\n return enc_d(mn, a[0], a[1], a[2], p)\n if mn == 'b':\n t = a[0]\n if isinstance(t, str) and t[0] in 'ab' and t[1:].isdigit():\n return enc_b_reg(t, p)\n t = self.labels[t] if isinstance(t, str) else t\n return enc_b_imm(at, t, a[1] if len(a) > 1 else 0, p)\n if mn == 'nop':\n return enc_nop(a[0] if a else 1)\n if mn == 'dint':\n return DINT\n if mn == 'rint':\n return RINT\n if mn == 'extu':\n return enc_extu(a[0], a[1], a[2], a[3], p)\n if mn == 'addaw':\n return enc_addaw(a[0], a[1], a[2], p)\n if mn == 'shl':\n return enc_shl(a[0], a[1], a[2], p)\n if mn == 'lddp': # ldbu/ldw/... *+b14(off)\n return enc_dp(a[0], a[1], a[2], p)\n if mn == 'mv':\n return enc_l('add', 0, a[0], a[1], p)\n raise KeyError(mn)\n\n def assemble(self):\n \"\"\"-> [(addr, word)]\"\"\"\n out = []\n for final in (False, True):\n pc, out = self.base, []\n for kind, arg in self.items:\n if kind == 'label':\n self.labels[arg] = pc\n continue\n if kind == 'org':\n pc = arg\n continue\n if kind == 'word':\n out.append((pc, arg))\n pc += 4\n continue\n mn, a, p = arg\n if mn == 'const': # mvk + mvkh of a 32-bit value\n v = self.labels.get(a[0], a[0]) if isinstance(a[0], str) else a[0]\n out.append((pc, enc_mvk(0, v if final or not isinstance(a[0], str) else 0, a[1], p)))\n out.append((pc + 4, enc_mvk(1, v if final or not isinstance(a[0], str) else 0, a[1], p)))\n pc += 8\n continue\n try:\n w = self._enc(pc, mn, a, p)\n except KeyError:\n if final:\n raise\n w = 0\n out.append((pc, w))\n pc += 4\n return out\n\n\ndef selftest():\n ref = [\n (enc_d('ldw', 'a4', 'a3', 0), 0x020c0264),\n (enc_d('stw', 'a3', 'a5', 0), 0x01940274),\n (enc_d('sth', 'a4', 'a3', 2), 0x020c2254),\n (enc_d('ldh', 'a4', 'a3', 6), 0x020c6244),\n (enc_d('ldhu', 'a4', 'a3', 0), 0x020c0204),\n (enc_l('cmpeq', 1, 'a4', 'a0'), 0x00102a58),\n (enc_l('or', 0, 'a4', 'a0'), 0x00100fd8),\n (enc_l('add', 'b10', 'b4', 'b6'), 0x0311407b & ~1),\n (enc_l('cmplt', 0, 'b4', 'b0'), 0x00100adb & ~1),\n (enc_l('cmpgt', 'a3', 'a10', 'a0'), 0x002868f8),\n (enc_l('sub', 'a3', 'a4', 'a10'), 0x051060f8),\n (enc_l('add', 'a4', 'a3', 'a3'), 0x018c8078),\n (enc_mvk(0, -7576, 'b4'), 0x0271342a),\n (enc_mvk(1, 0x1182e268, 'b4'), 0x0208c16a),\n (enc_b_reg('b4'), 0x00100362),\n (enc_addaw('a4', 'a6', 'a3'), 0x0190dc41 & ~1),\n (enc_nop(5), 0x00008000),\n (enc_shl('a14', 3, 'a8'), 0x04386ca1 & ~1),\n (enc_dp('ldbu', 'b6', 969), 0x0303c91e),\n ]\n bad = [(hex(a), hex(b)) for a, b in ref if a != b]\n assert not bad, bad\n return True\n\n\nif __name__ == '__main__':\n print('selftest', selftest())\n","mods/cdj900nxs/credit.py":"# SPDX-License-Identifier: GPL-2.0-or-later\n\"\"\"The mods' credit on the CDJ-900NXS 1.31 boot screen: \"Pionaarr Mods\"\nand the release (RELEASE, e.g. \"Pionaarr Mods 1.8.1\") where the splash\nshows \"Ver 1.31\". Our own; mods/patch_cdj900nxs.py\napplies it as `credit` (the patcher ticks it at the start).\n\nThe splash's text is made by 0x08BDCC14: a 50-byte buffer gets strcpy\n(0x08C28460) of the string the .data word at RAM 0x1110766C points to\n(image 0x08C6D22C, \"Ver \" at 0xA80D12BC), then strcat (the same function)\nof the version the getter 0x08BE9A8C returns (\"1.31\" at 0xA8000740), and is\nshown. The .data word now points at our text, and the function's own\nliteral of the getter (0x08BDCD8C, read only at 0x08BDCC34) at a stub that\nreturns an empty string, so nothing is added to it. The text's box (.data\n0x08C841E0: 139,363 - 619,385, right-aligned) is 8 lines taller, so the\ndescenders of p and y show. The getter itself and\neverything else that shows the version (the LINK screen's \"Ver %s\",\nUTILITY, the updater, the boot loader) are untouched.\"\"\"\nimport struct\n\nVERSION = '1.1.0' # Semantic Versioning: MAJOR.MINOR.PATCH\nRELEASE = '1.9.3' # the Pionaarr Mods release, ALWAYS the latest: the website's generator\n # (tools/make_builder_data.py) writes its version here\n\nBASE = 0x08000000\nDATA_WORD = 0x08C6D22C # .data: the splash's \"Ver \" pointer (RAM 0x1110766C)\nDATA_VER = 0xA80D12BC # \"Ver \"\nGETTER_LIT = 0x08BDCD8C # the splash function's literal of the version getter\nGETTER = 0x08BE9A8C\nTEXT = 'Pionaarr Mods ' + RELEASE\nCREDIT = 0x08FCF900 # between beatjump's 0x08FCF400..0x08FCF814 and cuecolours' 0x08FCFA00\nCREDIT_LEN = 0x40\nSTUB = CREDIT + 0x20 # mov.l @(4,pc),r0; rts; nop; nop; .long the text's final NUL\nBOX = 0x08C841E0 # .data: the splash text's box, x1 y1 x2 y2 (16 bits each)\nBOX_STOCK = (139, 363, 619, 385)\nBOX_NEW = (139, 363, 619, 393) # \"Ver 1.31\" has no descender; p and y need 8 more lines\n\n\ndef area():\n \"\"\"The credit area's bytes: the text, then the stub returning \"\".\"\"\"\n text = TEXT.encode('ascii') + b'\\0' # the splash takes bytes as Latin-1: no UTF-8\n # the splash's buffer is 50 bytes, its UTF-16 copy 100\n assert len(text) <= STUB - CREDIT and len(text) <= 50\n empty = CREDIT + len(text) - 1\n stub = struct.pack('<4HI', 0xD001, 0x000B, 0x0009, 0x0009, empty | 0xA0000000)\n return text.ljust(STUB - CREDIT, b'\\0') + stub\n\n\ndef patch(app, stock):\n \"\"\"The application with the credit; `stock` is the unmodified 1.31\n application, which every replaced byte is checked against.\"\"\"\n out = bytearray(app)\n end = CREDIT + CREDIT_LEN - BASE\n if len(out) < end:\n out += bytes(end - len(out))\n if any(out[CREDIT - BASE:end]):\n raise SystemExit('patch_cdj900nxs: credit: its area 0x%08x.. is not free' % CREDIT)\n\n def put(addr, before, after):\n off = addr - BASE\n if stock[off:off + 4] != struct.pack(' the 44-byte resource records\nTRI_ID = 0xC5 # the red memory-cue triangle, 16 x 5, RGB565\nTRI_PIXELS = 0x0815A1B0 # its pixels in the image\nTRI_RED = 0xF800\nMEMLIST = 0x0B7BE8D4 # the UI's memory list, 10 x 0x24\nOV_RECS = 0x0B800D9C # the overview's marker records, 12 bytes\nMK_RECS = 0x0B801258 # the marker records they come from, 16 bytes\nMK_RECORDS = 101\nMKCOPY_LIT = 0x08BC6BF8 # the waveform preparer's literal for memcpy, which fills MK_RECS\nMEMCPY = 0x08C279C4\nHOT_DEFAULT = 0x07E0 # a hot cue without a colour: green, as rekordbox's default\n\n# rekordbox's eight memory-cue colours (ids 1-8), as the player itself draws\n# them: the track-colour dots of the browser, resources 0x14, 0x16, 0x13,\n# 0x18, 0x12, 0x0F, 0x11 and 0x15 (RGB565 there).\nMEMORY_RGB565 = [\n 0xFA55, # 1 pink\n 0xF800, # 2 red\n 0xFC20, # 3 orange\n 0xFFE0, # 4 yellow\n 0x07E0, # 5 green\n 0x079F, # 6 aqua\n 0x22FF, # 7 blue\n 0x881F, # 8 purple\n]\n\n# hot cue letters A-H, 5 x 7, for the overview's bigger marker (bit 7 = left)\nLETTERS5 = [\n ['01110', '10001', '10001', '11111', '10001', '10001', '10001'],\n ['11110', '10001', '10001', '11110', '10001', '10001', '11110'],\n ['01110', '10001', '10000', '10000', '10000', '10001', '01110'],\n ['11110', '10001', '10001', '10001', '10001', '10001', '11110'],\n ['11111', '10000', '10000', '11110', '10000', '10000', '11111'],\n ['11111', '10000', '10000', '11110', '10000', '10000', '10000'],\n ['01110', '10001', '10000', '10111', '10001', '10001', '01111'],\n ['10001', '10001', '10001', '11111', '10001', '10001', '10001'],\n]\n\n# hot cue letters A-H, 3 x 5, rows top down: drawn black into a 9 x 5 marker\nLETTERS = ['010101111101101', '110101110101110', '011100100100011', '110101101101110',\n '111100110100111', '111100110100100', '011100101101011', '101101111101101']\n\n# data after the code (zero in the image)\nDATA = 0x08FD0000 # after the code (checked in patch())\nHOT_TABLE = DATA # 8 x 8: +0 time 1/150 s (-1 none), +4 RGB565, +6 hot cue number;\n # entry 0's +7 counts the loads (cue_get)\nSLOTS = 18 # triangles: memory list index 0-9, hot cues 10-17\nTRI_BUF = DATA + 0x40 # SLOTS x 160 bytes\nHOTBOX_W, HOTBOX_H = 16, 9 # the overview's hot cue marker: 11 x 9, then transparent; the\nHOTBOX_SIZE = 288 # blitter wants lines of a multiple of 16 bytes, as all the firmware's\nHOTBOX = (TRI_BUF + SLOTS * 160 + 31) & ~31 # 8 x HOTBOX_SIZE\nFAKE_RECS = HOTBOX + 8 * HOTBOX_SIZE # one 44-byte record, the detail waveform's\nDATA_END = FAKE_RECS + 44\nassert DATA_END <= CC_END\n\n\ndef rgb565(r, g, b):\n return (r & 0xF8) << 8 | (g & 0xFC) << 3 | b >> 3\n\n\nSOURCE = r'''\n; ---- cue_get: dbcl_GetUsbSdCueInfo(r4 connection, r5 track, r6 reply) plus colours\ncue_get:\n mov.l r8,@-r15\n mov.l r9,@-r15\n mov.l r10,@-r15\n mov.l r11,@-r15\n mov.l r12,@-r15\n mov.l r13,@-r15\n mov.l r14,@-r15\n sts.l pr,@-r15\n add #-20,r15 ; +0 wait's slot, +4/+8 message, +12 block, +16 size\n mov r4,r8\n mov r5,r9\n mov r6,r10\n mov.l K_cueinfo,r1\n jsr @r1\n nop\n mov r0,r12 ; the stock result, returned as it is\n mov.l K_hot,r1 ; no hot cues known\n mov #8,r2\n mov #-1,r3\ncg_clear:\n mov.l r3,@r1\n dt r2\n bf/s cg_clear\n add #8,r1\n mov.l K_hot,r1 ; one more load: entry 0's spare byte counts\n mov.b @(7,r1),r0 ; them (hotcuekeys reloads its slots on it)\n add #1,r0\n mov.b r0,@(7,r1)\n cmp/pl r12\n bf cg_early\n mov.l @r8,r11 ; the connection's socket side\n tst r11,r11\n bt cg_early\n mov.l K_check,r1\n jsr @r1\n mov r11,r4\n tst r0,r0\n bt cg_early\n mov.l K_alloc,r1\n jsr @r1\n mov #72,r4\n tst r0,r0\n bt cg_early\n mov.l r0,@(4,r15)\n mov.l r0,@(8,r15)\n mov #0,r1\n mov.l r1,@r15\n mov.l r1,@(12,r15)\n mov.l r1,@(16,r15)\n mov r8,r4\n mov r0,r5\n mov.l K_type,r6\n mov.l K_init,r1\n jsr @r1\n mov #8,r7 ; as dbcl_GetUsbSdCueInfo\n mov.l @(4,r15),r2\n mov.l r9,@(24,r2) ; the track\n mov #0,r1\n mov.l r1,@(28,r2)\n mov r11,r4\n mov.l @(8,r15),r5\n mov.l K_send,r1\n jsr @r1\n nop\n tst r0,r0\n bf cg_early\n mov r15,r1\n add #12,r1\n mov.l r1,@-r15 ; &block\n mov.l @(12,r15),r4 ; the message\n mov.l K_reply,r5\n mov r15,r6\n add #4,r6\n mov r15,r7\n mov.l K_wait,r1\n jsr @r1\n add #20,r7 ; &size\n add #4,r15\n mov.l @(12,r15),r13 ; the reply's entries\n tst r13,r13\n bt cg_early\n cmp/pz r0\n bf cg_free\n mov.l @(16,r15),r14\n add r13,r14 ; their end\n bra cg_entry\n nop\ncg_early:\n bra cg_out\n nop\ncg_entry:\n mov r13,r1\n add #16,r1\n cmp/hi r14,r1\n bt cg_free ; not even a header left\n mov.l @r13,r11 ; length\n mov #64,r1\n cmp/hs r1,r11\n bf cg_free\n mov r13,r1\n add r11,r1\n cmp/hi r14,r1\n bt cg_free ; runs past the end\n mov.l @(12,r13),r1 ; ms -> 1/150 s: ms * 3 / 20\n mov r1,r2\n add r1,r2\n add r1,r2\n mov.l K_div20,r1\n dmulu.l r1,r2\n sts mach,r9\n shlr2 r9\n shlr2 r9 ; r9 = time\n mov.b @(4,r13),r0\n extu.b r0,r6 ; r6 = hot cue number, 0 = memory cue\n tst r6,r6\n bf cg_hot\n mov #58,r0\n mov.b @(r0,r13),r0 ; colour id\n extu.b r0,r0\n tst r0,r0\n bt cg_next\n mov #8,r1\n cmp/hi r1,r0\n bt cg_next\n add r0,r0\n mov.l K_pal,r1\n add r1,r0\n mov.w @r0,r7\n bra cg_match\n extu.w r7,r7\ncg_hot:\n mov.l K_green,r7 ; no colour: rekordbox's default\n mov #82,r1 ; colour code, R, G, B, 2 bytes: 0x52 at least\n cmp/hs r1,r11\n bf cg_hstore\n mov #72,r0 ; the comment: its length in bytes at +0x48, text from +0x4A,\n mov.w @(r0,r13),r2 ; then 4 bytes, then colour code, R, G, B\n extu.w r2,r2 ; (the server's own entries: not checked against the length)\n add r13,r2\n add #78,r2\n mov.b @r2,r0 ; colour code; 0 = none\n tst r0,r0\n bt cg_hstore\n mov.b @(1,r2),r0 ; R\n extu.b r0,r7\n mov #-8,r0\n and r0,r7\n shll8 r7\n mov.b @(2,r2),r0 ; G\n extu.b r0,r0\n shlr2 r0\n shll2 r0\n shll r0\n shll2 r0\n or r0,r7\n mov.b @(3,r2),r0 ; B\n extu.b r0,r0\n shlr2 r0\n shlr r0\n or r0,r7\ncg_hstore:\n mov #9,r1 ; hot cues 1-8 into our table\n cmp/hs r1,r6\n bt cg_match\n mov r6,r1\n add #-1,r1\n shll2 r1\n shll r1\n mov.l K_hot,r2\n add r1,r2\n mov.l r9,@r2\n mov r7,r0\n mov.w r0,@(4,r2)\n mov r6,r0\n mov.b r0,@(6,r2)\ncg_match:\n ; mark the stock reply's entry with the same hot cue number and time\n mov.l @(24,r10),r1 ; entries\n tst r1,r1\n bt cg_next\n mov.l @(16,r10),r2\n mov.l @(20,r10),r3\n add r3,r2 ; memory + hot cue entries\n mov #16,r3\n cmp/hi r3,r2\n bf cg_m_ok\n mov r3,r2\ncg_m_ok:\n tst r2,r2\n bt cg_next\ncg_m:\n mov.b @(2,r1),r0\n extu.b r0,r0\n cmp/eq r6,r0\n bf cg_m_next\n mov.l @(12,r1),r0\n sub r9,r0 ; time difference, within one unit\n add #1,r0\n mov #2,r3\n cmp/hi r3,r0\n bt cg_m_next\n mov r7,r0\n mov.w r0,@(16,r1)\n mov r1,r3\n add #18,r3\n mov #1,r0\n mov.b r0,@r3\ncg_m_next:\n dt r2\n bf/s cg_m\n add #36,r1\ncg_next:\n bra cg_entry\n add r11,r13\ncg_free:\n mov.l @(12,r15),r4\n tst r4,r4\n bt cg_out\n mov.l K_free,r1\n jsr @r1\n nop\ncg_out:\n mov r12,r0\n add #20,r15\n lds.l @r15+,pr\n mov.l @r15+,r14\n mov.l @r15+,r13\n mov.l @r15+,r12\n mov.l @r15+,r11\n mov.l @r15+,r10\n mov.l @r15+,r9\n rts\n mov.l @r15+,r8\n\n .align 4\nK_alloc: .long 0x089A791E\nK_check: .long 0x089736F2\nK_cueinfo: .long CUEINFO\nK_div20: .long 0xCCCCCCCD\nK_free: .long 0x08A5EBC2\nK_green: .long HOT_DEFAULT\nK_hot: .long HOT_TABLE\nK_init: .long 0x08973C50\nK_pal: .long PALETTE\nK_reply: .long 0x00004E02\nK_send: .long 0x089738F0\nK_type: .long 0x00002B04\nK_wait: .long 0x08974198\n\n; ---- colour_for: r4 time (1/150 s), r5 tolerance -> r0 RGB565 or -1, r1 slot\ncolour_for:\n mov.l L_memlist,r1\n mov #0,r2 ; slot\ncf_loop:\n mov.l @r1,r0\n cmp/eq #-1,r0\n bt cf_hot\n mov #18,r0\n mov.b @(r0,r1),r0\n cmp/eq #1,r0\n bf cf_skip\n mov.l @(12,r1),r0\n sub r4,r0\n add r5,r0\n mov r5,r3\n add r5,r3\n cmp/hi r3,r0\n bt cf_skip\n mov.w @(16,r1),r0\n extu.w r0,r0\n rts\n mov r2,r1\ncf_skip:\n add #1,r2\n mov #10,r0\n cmp/hs r0,r2\n bf/s cf_loop\n add #36,r1\ncf_hot:\n mov.l L_hot,r1 ; then the hot cues: slots 10-17\n mov #10,r2\ncf_hloop:\n mov.l @r1,r0\n cmp/eq #-1,r0\n bt cf_hskip\n sub r4,r0\n add r5,r0\n mov r5,r3\n add r5,r3\n cmp/hi r3,r0\n bt cf_hskip\n mov.w @(4,r1),r0\n extu.w r0,r0\n rts\n mov r2,r1\ncf_hskip:\n add #1,r2\n mov #18,r0\n cmp/hs r0,r2\n bf/s cf_hloop\n add #8,r1\n rts\n mov #-1,r0\n\n; ---- make_tri: r4 slot, r5 RGB565 -> r0 its triangle (uncached address)\nmake_tri:\n mov r4,r0\n shll2 r0\n add r4,r0\n shll2 r0\n shll2 r0\n shll r0 ; slot * 160\n mov.l L_tribuf,r1\n add r0,r1 ; destination, through P2\n mov r1,r6\n mov #10,r0\n cmp/hs r0,r4\n bt mt_box\n mov.l L_tripix,r2\n mov.l L_red,r3\n mov #80,r7\nmt_loop:\n mov.w @r2+,r0\n extu.w r0,r0\n cmp/eq r3,r0\n bf mt_keep\n mov r5,r0\nmt_keep:\n mov.w r0,@r1\n dt r7\n bf/s mt_loop\n add #2,r1\n rts\n mov r6,r0\nmt_box:\n mov r4,r0 ; the letter, left-aligned in a word\n add #-10,r0\n shll2 r0\n mov.l L_font,r2\n mov.l @(r0,r2),r3\n mov.l L_key,r2 ; transparent\n mov #5,r7\nmb_row:\n mov #0,r4\nmb_col:\n mov #9,r0\n cmp/hs r0,r4\n bt mb_t ; past the marker\n mov #3,r0\n cmp/hs r0,r4\n bf mb_c\n mov #6,r0\n cmp/hs r0,r4\n bt mb_c\n shll r3 ; the letter's next pixel into T\n bf mb_c\n bra mb_st\n mov #0,r0 ; black\nmb_c:\n bra mb_st\n mov r5,r0\nmb_t:\n mov r2,r0\nmb_st:\n mov.w r0,@r1\n add #2,r1\n add #1,r4\n mov #16,r0\n cmp/hs r0,r4\n bf mb_col\n dt r7\n bf mb_row\n rts\n mov r6,r0\n\n; ---- mk_copy: memcpy(r4, r5, r6) for the waveform preparer; filling the\n; marker records, it adds the hot cues to them as memory-cue markers.\nmk_copy:\n mov.l r8,@-r15\n sts.l pr,@-r15\n mov r4,r8\n mov.l L_memcpy,r1\n jsr @r1\n nop\n mov.l L_mkrecs,r1\n cmp/eq r1,r8\n bf mk_out\n mov.l r0,@-r15 ; memcpy's result\n mov r8,r1\n mov #101,r2\n mov #-1,r3\n extu.b r3,r3 ; 0xff ends the list\nmk_find:\n mov.l @r1,r0\n cmp/eq r3,r0\n bt mk_add\n dt r2\n bf/s mk_find\n add #16,r1\n bra mk_done\n nop\nmk_add:\n mov.l L_hot,r3\n mov #8,r7\nmk_h:\n mov.l @r3,r0 ; time\n cmp/eq #-1,r0\n bt mk_hn\n tst r2,r2\n bt mk_done ; the list is full\n mov.l r0,@(8,r1)\n mov #0,r0\n mov.l r0,@r1 ; a memory cue\n mov.l r0,@(4,r1)\n mov #-1,r0\n mov.l r0,@(12,r1)\n add #16,r1\n add #-1,r2\nmk_hn:\n dt r7\n bf/s mk_h\n add #8,r3\nmk_done:\n mov.l @r15+,r0\nmk_out:\n lds.l @r15+,pr\n rts\n mov.l @r15+,r8\n\n; ---- det_res: the resource resolver, for the detail waveform (r9 = its column).\n; Every 0xC5 it is asked for becomes a 16 x 8 marker of ours, as the renderer\n; (patched) copies 11 x 8: a memory cue's triangle in rows 3-7 (coloured, or\n; the stock red one), a hot cue's box with its letter in rows 0-7.\ndet_res:\n mov.l L_resolve,r1\n mov.l L_triid,r0\n cmp/eq r0,r4\n bt dr_mine\n jmp @r1\n nop\ndr_mine:\n mov.l r8,@-r15\n mov.l r9,@-r15\n mov.l r10,@-r15\n mov.l r11,@-r15\n sts.l pr,@-r15\n mov r9,r8\n jsr @r1\n nop\n mov r0,r10 ; the record\n tst r10,r10\n bt dr_out\n mov r8,r4\n bsr colour_for\n mov #16,r5 ; zoomed out, a column stands for up to 16\n mov r1,r9 ; slot\n cmp/eq #-1,r0\n bt dr_plain\n mov r0,r5\n mov r9,r4\n mov #10,r2\n cmp/hs r2,r4\n bt dr_hot\n bsr make_tri\n nop\n mov #3,r11 ; triangle: rows 3-7\n bra dr_copy\n mov #5,r6\ndr_hot:\n bsr make_hotbox\n nop\n mov #0,r11 ; box: rows 0-7\n bra dr_copy\n mov #8,r6\ndr_plain:\n mov #18,r9 ; no colour: the stock triangle\n mov.l L_tripix,r0\n mov #3,r11\n mov #5,r6\ndr_copy:\n mov r0,r3 ; source, 16 pixels a line\n mov.l L_detbuf,r2\n mov r9,r0\n shll8 r0\n add r0,r2\n mov r2,r8 ; this slot's 16 x 8\n mov.l L_key,r0\n mov #64,r7\n shll r7\n mov r2,r1\ndr_fill:\n mov.w r0,@r1\n dt r7\n bf/s dr_fill\n add #2,r1\n mov r11,r0\n shll2 r0\n shll2 r0\n shll r0\n add r0,r2\ndr_row:\n mov #16,r7\ndr_px:\n mov.w @r3+,r0\n mov.w r0,@r2\n dt r7\n bf/s dr_px\n add #2,r2\n dt r6\n bf dr_row\n mov.l L_fake,r2 ; the record, with our size and pixels\n mov r10,r3\n mov #11,r4\ndr_rec:\n mov.l @r3+,r1\n mov.l r1,@r2\n dt r4\n bf/s dr_rec\n add #4,r2\n add #-44,r2\n mov.l L_detsize,r1\n mov.l r1,@(4,r2)\n mov.l r8,@(12,r2)\n mov r2,r10\ndr_out:\n mov r10,r0\n lds.l @r15+,pr\n mov.l @r15+,r11\n mov.l @r15+,r10\n mov.l @r15+,r9\n rts\n mov.l @r15+,r8\n\n; ---- ov_draw: draw_bitmap(r4, r5 x, r6 y, r7 resource) for the overview (r13 = its record)\nov_draw:\n mov.l L_draw,r1\n mov.l L_triid,r0\n cmp/eq r0,r7\n bt od_mine\n jmp @r1\n nop\nod_mine:\n mov.l r13,@-r15\n mov.l r8,@-r15\n mov.l r9,@-r15\n mov.l r10,@-r15\n mov.l r11,@-r15\n mov.l r12,@-r15\n mov.l r14,@-r15\n sts.l pr,@-r15\n mov r4,r8\n mov r5,r9\n mov r6,r10\n mov r7,r11\n mov.l L_ovrecs,r1 ; which record: 12 bytes each, 16 in the other list\n mov r13,r2\n sub r1,r2\n mov #0,r3\n mov #101,r4\nod_idx:\n cmp/pl r2\n bf od_found\n add #-12,r2\n dt r4\n bf/s od_idx\n add #16,r3\n bra od_plain\n nop\nod_found:\n tst r2,r2\n bf od_plain ; not on a record\n mov.l L_mkrecs,r1\n add r3,r1\n mov.l @(8,r1),r4\n bsr colour_for\n mov #0,r5\n cmp/eq #-1,r0\n bt od_plain\n mov r1,r4\n mov #10,r2\n cmp/hs r2,r4\n bt od_hot\n bsr make_tri\n mov r0,r5\n mov.l L_trisize,r13 ; 16 x 5, the triangle's own size\n bra od_pix\n nop\nod_hot:\n bsr make_hotbox ; a hot cue: the bigger box\n mov r0,r5\n mov.l L_boxsize,r13\nod_pix:\n mov.l L_restab,r1 ; the triangle's record\n mov.l @r1,r12\n mov.l L_trirec,r1\n add r1,r12\n mov.l @(32,r12),r14 ; its pixel offset and size, put back below\n mov.l @(4,r12),r1\n mov.l r13,@(4,r12)\n mov r1,r13\n mov.l L_p0mask,r1 ; the blitter gets the plain address\n and r1,r0\n mov.l L_imgbase,r1\n sub r1,r0\n mov.l r0,@(32,r12)\n mov r8,r4\n mov r9,r5\n mov r10,r6\n mov.l L_draw,r1\n jsr @r1\n mov r11,r7\n mov.l r13,@(4,r12)\n bra od_out\n mov.l r14,@(32,r12)\nod_plain:\n mov r8,r4\n mov r9,r5\n mov r10,r6\n mov.l L_draw,r1\n jsr @r1\n mov r11,r7\nod_out:\n lds.l @r15+,pr\n mov.l @r15+,r14\n mov.l @r15+,r12\n mov.l @r15+,r11\n mov.l @r15+,r10\n mov.l @r15+,r9\n mov.l @r15+,r8\n rts\n mov.l @r15+,r13\n\n .align 4\nL_cueinfo: .long CUEINFO\nL_check: .long 0x089736F2\nL_alloc: .long 0x089A791E\nL_init: .long 0x08973C50\nL_send: .long 0x089738F0\nL_wait: .long 0x08974198\nL_free: .long 0x08A5EBC2\nL_type: .long 0x00002B04\nL_reply: .long 0x00004E02\nL_div20: .long 0xCCCCCCCD\nL_hot: .long HOT_TABLE\nL_memlist: .long MEMLIST\nL_tribuf: .long TRI_BUF_P2\nL_tripix: .long TRI_PIXELS\nL_red: .long TRI_RED\nL_resolve: .long RESOLVE\nL_draw: .long DRAW\nL_triid: .long TRI_ID\nL_fake: .long FAKE_RECS\nL_detbuf: .long DET_BUF\nL_detsize: .long 0x00080010\nL_ovrecs: .long OV_RECS\nL_mkrecs: .long MK_RECS\nL_restab: .long RES_TABLE_PTR\nL_trirec: .long TRI_REC_OFF\nL_imgbase: .long 0x08100000\nL_p0mask: .long 0x1FFFFFFF\nL_pal: .long PALETTE\nL_green: .long HOT_DEFAULT\nL_font: .long FONT\nL_key: .long 0xF81F\nL_memcpy: .long MEMCPY\nL_trisize: .long 0x00050010\nL_boxsize: .long BOXSIZE\n\n; ---- make_hotbox: r4 slot (10-17), r5 RGB565 -> r0 the overview's hot cue\n; marker, 11 x 9 in its colour with the letter in black (uncached address)\nmake_hotbox:\n mov.l r8,@-r15\n mov.l r9,@-r15\n mov r4,r6\n add #-10,r6 ; 0 = A\n mov r6,r1 ; HOTBOX_SIZE (288) * index\n shll8 r1\n mov r6,r2\n shll2 r2\n shll2 r2\n shll r2\n add r2,r1\n mov.l M_hotbox,r2\n add r2,r1\n mov r1,r9 ; returned\n mov r6,r2 ; its letter: 7 bytes from FONT5 + 7 * index\n shll2 r2\n shll r2\n sub r6,r2\n mov.l M_font5,r3\n add r2,r3\n mov.l M_key,r2\n mov #0,r6 ; row\nhb_row:\n mov #0,r4 ; the letter's bits in this row\n mov r6,r0\n cmp/eq #0,r0\n bt hb_cols\n cmp/eq #8,r0\n bt hb_cols\n add #-1,r0\n mov.b @(r0,r3),r4\n extu.b r4,r4\nhb_cols:\n mov #0,r8 ; column\nhb_col:\n mov #11,r0\n cmp/hs r0,r8\n bt hb_t\n mov #3,r0\n cmp/hs r0,r8\n bf hb_c\n mov #8,r0\n cmp/hs r0,r8\n bt hb_c\n mov r4,r0\n tst #128,r0\n bt/s hb_c\n shll r4\n bra hb_st\n mov #0,r0 ; black\nhb_c:\n bra hb_st\n mov r5,r0\nhb_t:\n mov r2,r0\nhb_st:\n mov.w r0,@r1\n add #2,r1\n add #1,r8\n mov #16,r0\n cmp/hs r0,r8\n bf hb_col\n add #1,r6\n mov #9,r0\n cmp/hs r0,r6\n bf hb_row\n mov r9,r0\n mov.l @r15+,r9\n rts\n mov.l @r15+,r8\n\n .align 4\nM_hotbox: .long HOTBOX_P2\nM_font5: .long FONT5\nM_key: .long 0xF81F\nFONT:\n'''\n\n\ndef routine():\n \"\"\"The code at CC_BASE, the memory-cue palette after it, and the labels.\"\"\"\n syms = {\n 'CUEINFO': CUEINFO, 'RESOLVE': RESOLVE, 'DRAW': DRAW, 'HOT_TABLE': HOT_TABLE,\n 'MEMLIST': MEMLIST, 'TRI_BUF_P2': TRI_BUF | 0xA0000000, 'TRI_PIXELS': TRI_PIXELS,\n 'TRI_RED': TRI_RED, 'TRI_ID': TRI_ID, 'FAKE_RECS': FAKE_RECS, 'OV_RECS': OV_RECS,\n 'MK_RECS': MK_RECS, 'RES_TABLE_PTR': RES_TABLE_PTR, 'TRI_REC_OFF': TRI_ID * 44,\n 'HOT_DEFAULT': HOT_DEFAULT, 'MEMCPY': MEMCPY, 'HOTBOX_P2': HOTBOX | 0xA0000000,\n 'BOXSIZE': HOTBOX_W | HOTBOX_H << 16, 'DET_BUF': DET_BUF,\n }\n font = b''.join(struct.pack(' r0 the named cue to show (CN_TABLE entry) or 0; r1-r7 used\ncn_pick:\n mov.l P_hot,r6\n mov.b @(7,r6),r0 ; the table is this load's?\n mov.l P_load,r1\n mov.b @r1,r1\n cmp/eq r1,r0\n bf pk_none\n mov.l P_count,r1\n mov.l @r1,r3\n tst r3,r3\n bt pk_none\n mov.l P_pos,r1\n mov.l @r1,r4\n mov.l P_behind,r1\n sub r1,r4 ; from a second behind\n mov.l P_table,r2\n mov #0,r0 ; best so far\npk_loop:\n mov.l @r2,r1 ; ms\n cmp/ge r4,r1\n bf pk_next ; behind\n mov.l @(8,r2),r5 ; a hot cue still where it was?\n tst r5,r5\n bt pk_ok\n mov #9,r7\n cmp/hs r7,r5\n bt pk_next\n add #-1,r5\n shll2 r5\n shll r5\n add r6,r5\n mov.l @r5,r5 ; HOT_TABLE's time, 1/150 s\n mov.l @(4,r2),r7\n sub r7,r5\n add #1,r5\n mov #2,r7\n cmp/hi r7,r5\n bt pk_next\npk_ok:\n tst r0,r0\n bt pk_take\n mov.l @r0,r7\n cmp/ge r7,r1\n bt pk_next ; not nearer\npk_take:\n mov r2,r0\npk_next:\n dt r3\n bf/s pk_loop\n add #64,r2\n rts\n nop\npk_none:\n rts\n mov #0,r0\n\n; ---- cn_draw: the text widget's draw method (r4 renderer, r5 widget)\ncn_draw:\n mov.l r8,@-r15\n mov.l r9,@-r15\n mov.l r10,@-r15\n mov.l r11,@-r15\n sts.l pr,@-r15\n mov r4,r8\n mov r5,r9\n mov.l @(4,r5),r1 ; the title?\n mov.l D_title,r2\n cmp/eq r2,r1\n bf dr_plain\n mov.l D_depth,r1 ; BROWSE closed?\n mov.b @r1,r1\n tst r1,r1\n bf dr_plain\n mov.l @(40,r9),r1 ; the title white? (dimmed behind a popup, as MENU's: no name)\n mov #-1,r2\n cmp/eq r2,r1\n bf dr_plain\n bsr cn_pick\n nop\n tst r0,r0\n bt dr_plain\n mov r0,r10 ; the cue\n mov.l D_label,r2 ; the label: \"A \" for a hot cue, then the name\n mov.l @(8,r10),r1\n tst r1,r1\n bt dr_name\n add #64,r1 ; 'A' - 1 + number\n mov r1,r0\n mov.w r0,@r2\n mov #32,r0\n mov.w r0,@(2,r2)\n add #4,r2\ndr_name:\n mov r10,r1\n add #16,r1\ndr_ncopy:\n mov.w @r1+,r0\n mov.w r0,@r2\n tst r0,r0\n bf/s dr_ncopy\n add #2,r2\n mov.l @(28,r9),r11 ; the title, narrowed\n mov r11,r1\n mov.l D_hmask,r2\n and r2,r1\n mov.l D_tw,r2\n or r2,r1\n mov.l r1,@(28,r9)\n mov r8,r4\n mov r9,r5\n mov.l D_next,r1\n jsr @r1\n nop\n mov.l r11,@(28,r9)\n mov.l D_clone,r2 ; the copy: our place, text, colour\n mov r9,r1\n mov #24,r3\ndr_clone:\n mov.l @r1+,r0\n mov.l r0,@r2\n dt r3\n bf/s dr_clone\n add #4,r2\n mov.l D_clone,r5\n mov.l @(24,r9),r1 ; y stays, x ours\n mov.l D_hmask,r2\n and r2,r1\n mov.l D_lx,r2\n or r2,r1\n mov.l r1,@(24,r5)\n mov r11,r1\n mov.l D_hmask,r2\n and r2,r1\n mov.l D_lw,r2\n or r2,r1\n mov.l r1,@(28,r5)\n mov.l @(12,r10),r1\n mov.l r1,@(40,r5)\n mov.l D_label,r1\n mov.l r1,@(52,r5)\n mov r8,r4\n mov.l D_next,r1\n jsr @r1\n nop\n bra dr_out\n nop\ndr_plain:\n mov r8,r4\n mov r9,r5\n mov.l D_next,r1\n jsr @r1\n nop\ndr_out:\n lds.l @r15+,pr\n mov.l @r15+,r11\n mov.l @r15+,r10\n mov.l @r15+,r9\n rts\n mov.l @r15+,r8\n\n .align 4\nP_behind: .long BEHIND_MS\nP_count: .long CN_COUNT\nP_hot: .long HOT_TABLE\nP_load: .long CN_LOAD\nP_pos: .long POS_MS\nP_table: .long CN_TABLE\nD_clone: .long CN_CLONE\nD_depth: .long BROWSE_DEPTH\nD_hmask: .long 0xFFFF0000\nD_label: .long CN_LABEL\nD_lw: .long LABEL_W\nD_lx: .long LABEL_X\nD_next: .long NEXT_DRAW\nD_title: .long TITLE_ID\nD_tw: .long TITLE_W\nMEMORY_TAB:\n'''\n\n\ndef routine(next_draw):\n src = SOURCE + ''.join(' .long 0x%08X\\n' % c for c in MEMORY_ABGR)\n return sh4asm.assemble(src, CN_CODE, {\n 'CN_COUNT': CN_COUNT, 'CN_LOAD': CN_LOAD, 'CN_TABLE': CN_TABLE, 'CN_LABEL': CN_LABEL,\n 'CN_CLONE': CN_CLONE, 'CN_MAX': CN_MAX, 'CN_NAME': CN_NAME, 'FREE': FREE,\n 'HOT_TABLE': HOT_TABLE, 'POS_MS': POS_MS, 'BROWSE_DEPTH': BROWSE_DEPTH,\n 'TITLE_ID': TITLE_ID, 'TITLE_W': TITLE_W, 'LABEL_X': LABEL_X, 'LABEL_W': LABEL_W,\n 'BEHIND_MS': BEHIND_MS, 'NO_COLOUR': NO_COLOUR, 'NEXT_DRAW': next_draw})\n\n\ndef patch(app, stock):\n \"\"\"The application with CUE NAMES added (after cuecolours and, if chosen,\n keynotation); `stock` is the unmodified 1.31 application.\"\"\"\n out = bytearray(app)\n word = lambda a: struct.unpack_from(' 0xC00487A4)\nTRAMP_TARGET = 0xC00487A4\nMB = 0x1183E000\nDP = 0x11806900\nHEADS = 0x1182E0E0\nLINKS = 0xC1F38B90\nPLAY_HEAD_DP = 969 # byte: the playing head's index\nMARGIN = 750 # slots (10 s) a forward jump leaves decoded ahead (2 s: EMERGENCY LOOP\n # after rapid 8-beat jumps, emulator too; 5 s was fine there)\nBLOCKS = ((0xC0000040, 0xC0000080), (0xC00000A0, 0xC0000100), (0xC0000120, 0xC00001E0))\nFREE_PACKETS = (struct.pack('<8I', *([0x0c6e0c6e] * 7 + [0xefe00000])), # compact nops only\n struct.pack('<8I', *([0x0c6e0c6e] * 6 + [0, 0xe7e00000])))\n\n\ndef code():\n \"\"\"[(addr, word)] of dj_poll.\"\"\"\n a = c6asm.Asm(BLOCKS[0][0])\n o = a.op\n # block 1: the mailbox; e = heads + 30 * h\n o('const', MB, 'a3')\n o('ldw', 'a4', 'a3', 0)\n o('nop', 4)\n o('cmpeq', 1, 'a4', 'a1')\n o('b', 'tail', p='!a1')\n o('nop', 5)\n o('ldw', 'b4', 'a3', 4) # n\n o('lddp', 'ldbu', 'b5', PLAY_HEAD_DP) # h\n o('nop', 4)\n o('shl', 'b5', 5, 'b6')\n o('shl', 'b5', 1, 'b7')\n o('sub', 'b6', 'b7', 'b6') # 30 h\n o('b', 'blk2')\n o('nop', 5)\n # block 2: the head's fields, the direction\n a.org(BLOCKS[1][0])\n a.label('blk2')\n o('const', HEADS, 'b8')\n o('add', 'b8', 'b6', 'b6') # e\n o('ldhu', 'a5', 'b6', 2) # cur\n o('ldh', 'a6', 'b6', 6) # behind\n o('ldh', 'a7', 'b6', 8) # ahead\n o('nop', 4)\n o('stw', 'a5', 'a3', 16)\n o('stw', 'a6', 'a3', 24)\n o('stw', 'a7', 'a3', 28)\n o('mvk', 2, 'a9') # refused unless done\n o('const', LINKS, 'a4')\n o('cmplt', 0, 'b4', 'b0') # n > 0\n o('b', 'fwd', p='b0')\n o('nop', 5)\n o('cmpgt', 0, 'b4', 'b1') # n < 0\n o('b', 'ok', p='!b1') # n = 0\n o('nop', 5)\n o('sub', 0, 'b4', 'b2') # m = -n\n o('mv', 'b2', 'a8')\n o('sub', 'a6', 'a8', 'a8') # behind - m\n o('b', 'blk3')\n o('nop', 5)\n # block 3: the walk\n a.org(BLOCKS[2][0])\n a.label('blk3')\n o('cmplt', 0, 'a8', 'a1') # at least one slot left behind\n o('b', 'done', p='!a1')\n o('nop', 5)\n a.label('loopb')\n o('addaw', 'a4', 'a5', 'a2')\n o('ldhu', 'a5', 'a2', 0) # prev\n o('nop', 4)\n o('add', -1, 'b2', 'b2')\n o('b', 'loopb', p='b2')\n o('nop', 5)\n o('sub', 0, 'b4', 'b7')\n o('mv', 'b7', 'a8') # m\n o('sub', 'a6', 'a8', 'a6') # behind - m\n o('add', 'a8', 'a7', 'a7') # ahead + m\n o('b', 'store')\n o('nop', 5)\n a.label('fwd')\n o('mv', 'b4', 'a8')\n o('sub', 'a7', 'a8', 'a8') # ahead - n\n o('mvk', MARGIN, 'b7')\n o('cmplt', 'b7', 'a8', 'b1') # more than MARGIN left ahead\n o('b', 'done', p='!b1')\n o('nop', 5)\n o('mv', 'b4', 'b2')\n a.label('loopf')\n o('addaw', 'a4', 'a5', 'a2')\n o('ldhu', 'a5', 'a2', 2) # next\n o('nop', 4)\n o('add', -1, 'b2', 'b2')\n o('b', 'loopf', p='b2')\n o('nop', 5)\n o('mv', 'b4', 'a8')\n o('add', 'a8', 'a6', 'a6') # behind + n\n o('sub', 'a7', 'a8', 'a7') # ahead - n\n a.label('store')\n o('sth', 'a5', 'b6', 2)\n o('sth', 'a6', 'b6', 6)\n o('sth', 'a7', 'b6', 8)\n o('sth', 'a5', 'b6', 14) # the point the decoder fills from (set on a\n o('sth', 'a6', 'b6', 16) # pause): moved along, so standing it decodes\n o('sth', 'a7', 'b6', 18) # on from the new place\n o('stw', 'a5', 'a3', 20)\n a.label('ok')\n o('mvk', 1, 'a9')\n a.label('done')\n o('stw', 'a9', 'a3', 8)\n o('ldw', 'a8', 'a3', 12)\n o('nop', 4)\n o('add', 1, 'a8', 'a8')\n o('stw', 'a8', 'a3', 12)\n o('mvk', 0, 'a8')\n o('stw', 'a8', 'a3', 0)\n a.label('tail')\n o('b', TRAMP_TARGET)\n o('nop', 5)\n words = a.assemble()\n for at, _ in words:\n assert any(lo <= at < hi for lo, hi in BLOCKS), 'dspjump: 0x%08x is past its blocks' % at\n return words\n\n\ndef packets(words):\n \"\"\"{packet addr: 8 words}: our words, the rest of each packet nop.\"\"\"\n out = {}\n for at, w in words:\n fp = at & ~31\n out.setdefault(fp, [0] * 8)[(at - fp) // 4] = w\n return out\n\n\ndef set_cst16(word, value):\n return (word & ~(0xFFFF << 7)) | (value & 0xFFFF) << 7\n\n\ndef patch(app, stock):\n out = bytearray(app)\n for fp, ws in packets(code()).items():\n off = B_IMG - BASE + (fp - 0xC0000000)\n if stock[off:off + 32] not in FREE_PACKETS or out[off:off + 32] != stock[off:off + 32]:\n raise SystemExit('patch_cdj900nxs: dspjump: the vector packet 0x%08x is not the expected one' % fp)\n out[off:off + 32] = struct.pack('<8I', *ws)\n entry = BLOCKS[0][0]\n for at, want, value in ((TRAMP_MVK, 0x0543d22a, entry), (TRAMP_MVKH, 0x0560026a, entry >> 16)):\n off = A_IMG - BASE + (at - A_AT)\n w = struct.unpack_from(' red, grey -> dark red\n\nSOURCE = r'''\n; ---- ew_draw: draw_bitmap(r4, r5 x, r6 y, r7 resource) for the playing-address bar\new_draw:\n mov.l E_draw,r0\n mov.l E_res,r1\n cmp/eq r1,r7\n bt ew_bar\n jmp @r0\n nop\new_bar:\n mov.l E_len,r1 ; length in ms: 1/150 s * 20 / 3\n mov.l @r1,r1\n tst r1,r1\n bt ew_plain\n mov r1,r2\n shll2 r2\n shll2 r2\n shll2 r1\n add r2,r1 ; * 20\n mov.l E_div3,r2\n dmulu.l r2,r1\n sts mach,r1\n shlr r1 ; / 3\n mov.l E_pos,r2\n mov.l @r2,r2\n sub r2,r1 ; left\n cmp/pl r1\n bf ew_plain\n mov.l E_warn,r2\n cmp/hs r2,r1\n bt ew_plain\n mov.l r8,@-r15 ; red: the record pointed at RED_BAR for this call\n mov.l r9,@-r15\n sts.l pr,@-r15\n mov.l E_tab,r8\n mov.l @r8,r8\n mov.l E_recoff,r1\n add r1,r8\n mov.l @(32,r8),r9\n mov.l E_redoff,r1\n mov.l r1,@(32,r8)\n jsr @r0\n nop\n mov.l r9,@(32,r8)\n lds.l @r15+,pr\n mov.l @r15+,r9\n rts\n mov.l @r15+,r8\new_plain:\n jmp @r0\n nop\n\n .align 4\nE_div3: .long 0xAAAAAAAB\nE_draw: .long DRAW\nE_len: .long TRACK_LEN\nE_pos: .long POS_MS\nE_recoff: .long REC_OFF\nE_redoff: .long RED_OFF\nE_res: .long RES_BAR\nE_tab: .long RES_TABLE_PTR\nE_warn: .long WARN_MS\n'''\n\n\ndef routine():\n return sh4asm.assemble(SOURCE, EW_CODE, {\n 'DRAW': DRAW, 'TRACK_LEN': TRACK_LEN, 'POS_MS': POS_MS, 'REC_OFF': RES_BAR * 44,\n 'RED_OFF': RED_BAR - RES_BASE, 'RES_BAR': RES_BAR, 'RES_TABLE_PTR': RES_TABLE_PTR,\n 'WARN_MS': WARN_MS})\n\n\ndef patch(app, stock):\n \"\"\"The application with END WARNING added; `stock` is the unmodified 1.31\n application, which every replaced byte is checked against.\"\"\"\n out = bytearray(app)\n word = lambda buf, a: struct.unpack_from('