little-scale — Nanoloop Tuned to 18-TET, Hacked ROM (2009)

author little-scale (Sebastian Tomczak); credited to Abrasive
date 2009-03-21
article blog post; the one post in the cluster that spells the whole spreadsheet method out in prose, plus a before/after hex-editor screenshot
created 2026-08-31 · updated 2026-08-31

The earliest post of the cluster, a day before the LSDj tables, and the one that explains the arithmetic in words. Same technique, different tracker: nanoloop 1.3d retuned to 18 equal divisions of the octave.

Key claims#

  • What 18-TET is, in his framing: "18-TET = 18 divisions of the octave instead of 12 (which is standard for western tuning)… By editing the frequency table, we can change the space between notes — so we can edit the tuning. Instead of there being 12 pitches per octave, there are now 18 in the above example (ie. each step of pitch in Nanoloop is now only 2/3s of a semitone instead of a full semitone). It doesn't have to be 18, but thats just what I wanted to experiment with."
  • "You could easily change the tuning to just intonation, 1/4 tone steps, ragas or middle eastern scales, or many other flavours of microtonality."
  • The address: "As far as I can tell, the lookup table starts at 0x730a and is 144 bytes long." The screenshot's status bar confirms it — "144 bytes selected at offset 29,450 out of 32,768 bytes" (29,450 = $730A), on a ROM named nl13d edit.gb. Nanoloop 1.3d is therefore a 32 KB ROM, and its pitch table is 72 entries, against LSDj's 108.
  • Both windows in the picture are the same file, before and after: "On left, the original ROM with its frequency lookup table intact, and on the right the edited ROM with the 18-TET lookup table." Read from the image, the stock values are 2C 00 9C 00 06 01 6B 01 C9 01 … — byte for byte the same series as lsdj's table (s-little-scale-lsdj-tuning-tables), because both are plain 12-TET from C2 on the same hardware. The edited values are 44, 120, 193, 263, 330, 395, 457, 518, 575 …; decoded here through f = 131072 ÷ (2048 − v) their successive ratios average 1.0393, and 2^(1/18) = 1.03926 — the 18-TET claim checks out, from the same starting C2.
  • The whole spreadsheet method, verbatim — the only place in the cluster where it is written down:
    • "One column had the MIDI notes from 0 to 127."
    • frequency: Frequency = 440 * 2 ^ ((Note - 49) / 12)
    • register value: Data = (- 131072 / Frequency) + 2048
    • check column: Frequency = 131072 / (2048 - Data)
    • four nibble columns: dec2hex of: (Data / 4096) % 16, (Data / 256) % 16, (Data / 16) % 16, (Data % 16), "then copied and pasted into the ROM at the correct point".
  • How to get any tuning out of it: "By changing the MIDI notes to fractions of whole numbers, different tuning can be obtained. Remember that each percentage point of a MIDI number is equal to a cent in musical interval terms." (0.01 of a semitone = 1 cent — so 18-TET is a step of 12/18 = 0.667 per row.)
  • "In the spreadsheet, Nanoloop only uses the data in rows 27 - 90 it seems" — 64 rows.
  • Spreadsheet published at milkcrate.com.au/_other/downloads/spreadsheets/nanoloop_tuning.xls (not fetched).
  • "Special, special thanks to Abrasive for his help and his idea with this — all of the credit goes to him of course" (abrasive).
  • The screenshot has a KiGB window over it — the emulator whose SGB-table quirk he warns about the next day.
  • From the comments: nitro2k01 (answered by name by little-scale) had done the same to LSDj with a different goal — "I hacked the frequency table for LSDj, but that time for a justly intonated 12 tone scale. I look how it gives each scale it's own character. After doing that I've started to like F better than C when I need a major scale, even when working with the ET-12 scale."

Practical takeaways#

  • The register formula is the same on any Game Boy tracker; only the table's address and length change. $730A, 144 bytes for Nanoloop 1.3d; $6D3A and $6E12, 216 bytes each for LSDj 3.8.9.
  • Build the spreadsheet once with a fractional note-number column and every tuning becomes one edit: 12/18 per row for 18-TET, 12/24 for quarter-tones, 12/n for any equal division.
  • Two-thirds of a semitone is a usable amount of "wrong": at 18-TET the octave and (roughly) the fifth survive, everything between them moves.

Notable quotes#

"each step of pitch in Nanoloop is now only 2/3s of a semitone instead of a full semitone."

"Remember that each percentage point of a MIDI number is equal to a cent in musical interval terms."

Relevance to the wiki#

The method page for rom-retuning comes mostly from here, and it is the wiki's first technical material on nanoloop at all.

To verify#

  • His frequency formula uses (Note - 49), which is the piano key convention (key 49 = A440), not the MIDI convention (note 69 = A440), although the column is labelled "MIDI notes from 0 to 127". The two disagree by 20 semitones; which one his sheet actually indexed is not recoverable from the post. The shape of the tuning is unaffected — only which row lands on which key.
  • 144 bytes is 72 entries, but he says Nanoloop uses only rows 27–90 of the sheet, which is 64. The two numbers are not reconciled in the post.
  • The selection in the screenshot begins one byte before the 2C 00 series; whether $730A is the table proper or one byte of padding ahead of it is not resolvable from the image.
  • The two linked demo videos were not fetched.

Pages touched#

alternative-tunings · rom-retuning · nanoloop · abrasive · nitro2k01 · game-boy-apu · little-scale · semitone-math

source file wiki/summaries/s-little-scale-nanoloop-18-tet.md · graph