Last active
December 23, 2021 21:13
-
-
Save shirriff/b06676f3a909dec01a373cf7d1903611 to your computer and use it in GitHub Desktop.
UM66T sound chip analysis program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This code prints out the melody in the UM66T sound chip's ROM. | |
# The ROM holds Jingle Bells, Santa Claus is Coming to Town, and We Wish You a Merry Christmas. | |
# See this Twitter thread for details: https://twitter.com/kenshirriff/status/1472297415201869831 | |
from collections import defaultdict | |
notes = ['X', 'X', 'G4', 'A5', 'B5', 'C5', 'D5', 'E5', 'F5', 'G5', 'A6', 'B6', 'C6', 'X', 'X', 'X'] | |
# Hard-coded ROM contents. | |
bits = {"24,1":0,"15,0":1,"15,1":0,"15,3":1,"15,4":0,"14,4":1,"13,4":0,"12,4":1,"11,4":0,"10,4":1,"9,4":1,"8,4":0,"7,4":0,"6,4":1,"5,4":1,"4,4":0,"0,4":0,"1,4":1,"2,4":1,"3,4":0,"0,1":1,"0,0":1,"3,0":1,"4,0":1,"7,0":1,"8,0":1,"11,0":1,"12,0":1,"17,0":1,"19,0":1,"20,0":1,"23,0":1,"25,0":1,"26,0":1,"29,0":1,"31,0":1,"30,1":1,"28,1":1,"26,1":1,"25,1":1,"22,1":1,"21,1":1,"18,1":1,"17,1":1,"30,5":1,"31,6":1,"30,8":1,"30,9":1,"30,10":1,"31,11":1,"31,13":1,"31,14":1,"30,15":1,"31,16":1,"30,18":1,"30,19":1,"31,20":1,"31,21":1,"30,23":1,"31,24":1,"31,25":1,"31,26":1,"31,28":1,"30,29":1,"30,28":0,"29,26":1,"29,25":1,"29,24":1,"29,23":1,"29,21":1,"29,20":1,"29,19":1,"29,18":1,"29,16":1,"28,15":1,"29,14":1,"28,13":1,"29,11":1,"28,10":1,"28,8":0,"29,8":1,"28,9":1,"29,6":1,"28,5":1,"28,4":1,"28,3":1,"27,3":1,"27,4":1,"27,5":1,"26,6":1,"26,8":1,"26,9":1,"27,10":1,"27,11":1,"26,13":1,"27,14":1,"27,15":1,"27,16":1,"27,18":1,"26,19":1,"27,20":1,"26,21":1,"27,23":1,"27,24":0,"26,24":1,"26,25":1,"27,26":1,"26,28":1,"27,29":1,"25,29":1,"25,28":1,"25,26":1,"24,24":1,"25,25":1,"24,23":1,"24,21":1,"24,20":1,"24,19":1,"25,18":1,"24,16":1,"24,15":1,"24,14":1,"25,13":1,"24,11":1,"24,10":1,"25,9":1,"24,8":1,"25,6":1,"24,5":1,"24,4":1,"24,3":1,"23,3":1,"22,4":1,"22,5":1,"23,6":1,"23,8":1,"23,9":1,"22,10":1,"22,11":1,"22,13":1,"23,14":1,"22,15":1,"22,16":1,"23,18":1,"23,19":1,"22,20":1,"23,21":1,"23,23":1,"22,24":1,"23,25":1,"23,26":1,"22,28":1,"23,29":1,"21,29":1,"21,28":1,"20,26":1,"20,25":1,"20,24":1,"20,23":1,"20,21":1,"20,20":1,"20,19":1,"20,18":1,"20,16":1,"20,15":1,"21,14":1,"20,13":1,"21,11":1,"21,10":1,"21,9":1,"21,8":1,"20,6":1,"21,5":1,"20,4":1,"20,3":1,"19,3":1,"19,4":1,"18,5":1,"19,6":1,"18,7":0,"18,8":1,"18,9":1,"19,10":1,"19,11":1,"19,13":1,"18,14":1,"18,15":1,"18,16":1,"18,18":1,"18,19":1,"19,20":1,"18,21":1,"19,23":1,"19,24":1,"19,25":1,"19,26":1,"19,28":1,"18,29":1,"17,29":1,"16,28":1,"17,26":1,"16,25":1,"16,24":1,"16,23":1,"16,21":1,"16,20":1,"17,19":1,"16,18":1,"17,16":1,"17,15":1,"16,14":1,"17,13":1,"16,11":1,"16,10":1,"17,9":1,"17,8":1,"16,6":1,"16,5":1,"16,4":1,"16,2":0,"16,3":1,"14,1":1,"14,5":1,"15,6":1,"14,8":1,"15,9":1,"14,10":1,"15,11":1,"14,13":1,"15,14":1,"14,15":1,"15,16":1,"14,18":1,"14,19":1,"15,20":1,"15,21":1,"15,23":1,"15,24":1,"15,25":1,"15,26":1,"15,28":1,"14,29":1,"13,29":1,"12,28":1,"12,26":1,"14,25":0,"13,25":1,"12,24":1,"12,23":1,"12,21":1,"12,20":1,"13,19":1,"12,19":0,"12,18":1,"13,16":1,"13,15":1,"13,14":1,"13,13":1,"13,11":1,"13,10":1,"13,9":1,"13,8":1,"13,6":1,"13,5":1,"12,3":1,"12,1":1,"11,1":1,"11,3":1,"10,5":1,"10,6":1,"10,8":1,"11,9":1,"10,10":1,"11,11":1,"10,13":1,"11,14":1,"10,15":1,"10,16":1,"11,18":1,"11,19":1,"11,20":1,"10,21":1,"11,23":1,"10,24":1,"11,25":1,"11,26":1,"10,28":1,"11,29":1,"9,29":1,"8,28":1,"8,26":1,"8,25":1,"8,24":1,"9,23":1,"8,21":1,"8,20":1,"8,19":1,"9,18":1,"9,19":0,"8,16":1,"9,15":1,"8,14":1,"9,13":1,"9,11":1,"9,10":1,"8,9":1,"8,8":1,"9,6":1,"9,5":1,"8,3":1,"8,1":1,"6,1":1,"7,3":1,"6,5":1,"7,6":1,"6,8":1,"7,9":1,"6,10":1,"7,11":1,"7,13":1,"7,14":1,"6,15":1,"7,16":1,"7,18":1,"6,19":1,"7,20":1,"7,21":1,"7,23":1,"7,24":1,"6,25":1,"7,26":1,"7,28":1,"7,29":1,"4,29":1,"4,28":1,"4,26":1,"5,25":0,"4,24":1,"4,23":1,"4,21":1,"4,20":1,"4,19":1,"5,18":1,"5,16":1,"5,15":1,"5,14":1,"4,13":1,"4,11":1,"5,10":1,"4,9":1,"5,8":1,"5,6":0,"5,5":1,"4,3":1,"5,1":1,"2,1":1,"3,3":1,"2,5":1,"3,6":1,"3,8":0,"3,9":1,"2,10":1,"3,11":1,"3,12":0,"2,13":1,"3,14":1,"2,15":1,"2,16":1,"3,18":1,"2,19":1,"3,20":1,"3,21":1,"3,23":1,"2,24":1,"3,25":1,"3,26":1,"3,28":1,"3,29":1,"1,29":1,"0,28":1,"1,26":1,"0,25":1,"0,24":1,"0,23":1,"0,21":1,"0,20":1,"1,19":1,"1,18":1,"1,16":1,"1,15":1,"0,14":1,"1,13":0,"1,11":1,"0,10":1,"0,9":1,"1,8":1,"1,6":1,"0,5":1,"0,3":1,"29,29":1,"29,28":1,"1,0":0,"31,3":1,"31,4":1,"0,13":1,"2,8":1,"4,6":1,"4,25":1} | |
def get(x, y): | |
return int(bits.get('%d,%d' % (x, y), 0)) | |
def dump1(): | |
row = 0 | |
for y in range(0, 30): | |
# The ROM row numbering includes the spacer rows, so skip over those. | |
if y in [2, 7, 12, 17, 22, 27]: continue | |
print(y, end=" ") | |
for x in range(0, 32, 2): | |
x0 = get(x, y) | |
x1 = get(x + 1, y) | |
if x0 != x1: | |
print(x0, end="") | |
else: | |
print('***') | |
print() | |
row += 1 | |
def dump2(): | |
yidx = [[0 + 5 * k, 1 + 5 * k, 4 + 5 * k, 3 + 5 * k] for k in range(0, 6)] | |
for n in range(0, 64): | |
xc = n % 16 | |
yc = n >> 4 | |
def get2(x, y): | |
if x % 2: | |
return get(2 * x, y) | |
else: | |
return get(2 * x + 1, y) | |
bitsn = [get2(xc, yidx[i][yc]) for i in range(0, 4)] | |
bitsdur = [get2(xc, yidx[i][yc]) for i in range(4, 6)] | |
bitsn_s = ''.join(map(str, bitsn)) | |
bitsdur_s = ''.join(map(str, bitsdur)) | |
n = bitsn[0] * 8 + bitsn[1] * 4 + bitsn[2] * 2 + bitsn[3] | |
print(n, notes[n], bitsn_s, bitsdur_s) | |
dump2() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment