191 lines
6.2 KiB
Python
191 lines
6.2 KiB
Python
#!/usr/bin/env python
|
|
|
|
import sys
|
|
import time
|
|
import math
|
|
import array
|
|
import random
|
|
|
|
import gameduino
|
|
import gameduino.remote
|
|
import gameduino.sim
|
|
|
|
from duplicator import Duplicator
|
|
|
|
random.seed(10)
|
|
|
|
def read_y(y):
|
|
gd.wr16(gameduino.SCREENSHOT_Y, 0x8000 | y)
|
|
gd.waitvblank()
|
|
gd.waitvblank()
|
|
line = "".join([gd.rdstr(gameduino.SCREENSHOT + i, 200) for i in range(0, 800, 200)])
|
|
gd.wr16(gameduino.SCREENSHOT_Y, 0)
|
|
return array.array('H', line).tolist()
|
|
|
|
def sling(n):
|
|
n1s = random.randrange(n + 1)
|
|
return sum([(1 << i) for i in random.sample(range(n), n1s)])
|
|
|
|
def r(n):
|
|
return random.randrange(n)
|
|
|
|
def randbytes(n):
|
|
return array.array('B', [r(256) for i in range(n)])
|
|
|
|
def matches(r):
|
|
return r[0] == r[1]
|
|
|
|
class TestRegime(object):
|
|
def __init__(self, dd):
|
|
self.dd = dd
|
|
assert matches(dd.rd(gameduino.IDENT))
|
|
self.dd.microcode(open("../synth/sketches/j1firmware/thrasher.binle").read())
|
|
self.setup()
|
|
|
|
def scramble(self):
|
|
""" Scramble all registers and memories """
|
|
for rg in self.reg8s:
|
|
self.dd.wr(rg, r(2**8))
|
|
for rg in self.reg16s:
|
|
self.dd.wr16(rg, r(2**16))
|
|
for a,s in self.memories:
|
|
self.dd.wrstr(a, randbytes(s))
|
|
|
|
def setup(self):
|
|
self.scramble()
|
|
|
|
def cycle(self):
|
|
for c in xrange(1000000):
|
|
print "Cycle", c
|
|
for (area,size) in random.sample(self.memories, r(len(self.memories))):
|
|
dat = randbytes(1 + sling(6))
|
|
if len(dat) == size:
|
|
a = area
|
|
else:
|
|
a = area + random.randrange(0, size - len(dat))
|
|
self.dd.wrstr(a, dat)
|
|
if r(2) == 0 and self.reg16s:
|
|
self.dd.wr16(random.choice(self.reg16s), random.getrandbits(16))
|
|
if r(2) == 0 and self.reg8s:
|
|
self.dd.wr(random.choice(self.reg8s), random.getrandbits(8))
|
|
|
|
for (y, (e,a)) in [(y, self.dd.linecrc(y)) for y in self.checklines()]:
|
|
if e != a:
|
|
print "mismatch at line", y, (e,a)
|
|
e = gameduino.sim.screen([y])[y]
|
|
a = read_y(y)
|
|
print "expected", e
|
|
print "actual", a
|
|
print set([(ee != aa) for (ee,aa) in zip(e,a)])
|
|
print 'y', self.dd.linecrc(y)
|
|
sys.exit(1)
|
|
a,s = random.choice(self.memories)
|
|
if r(5) == 0:
|
|
assert matches(self.dd.rd(a + r(s)))
|
|
if r(5) == 0:
|
|
assert matches(self.dd.memcrc(a, s))
|
|
|
|
if not matches(self.dd.collcrc()):
|
|
def s9(vv):
|
|
vv &= 0x1ff
|
|
if vv > 400:
|
|
vv -= 512;
|
|
return vv
|
|
|
|
if 0:
|
|
page = self.dd.spr_page()[0]
|
|
for i in range(256):
|
|
sprval = gdsim.rd32(page + 4 * i)
|
|
sx = s9(sprval)
|
|
sy = s9(sprval >> 16)
|
|
simg = (sprval >> 25) & 63
|
|
spal = (sprval >> 12) & 15
|
|
srot = (sprval >> 9) & 7
|
|
sjk = (sprval >> 31)
|
|
print "%3d: x=%3d y=%3d img=%2d pal=%d rot=%d jk=%d" % (i, sx, sy, simg, spal, srot, sjk)
|
|
(e,a) = self.dd.coll()
|
|
print 'collcrc', self.dd.collcrc()
|
|
import binascii
|
|
print 'e crc', 0xffffffff & binascii.crc32(array.array('B', e).tostring())
|
|
print 'a crc', 0xffffffff & binascii.crc32(array.array('B', a).tostring())
|
|
for i in range(256):
|
|
print "%3d: e=%3d a=%3d" % (i, e[i], a[i])
|
|
sys.exit(1)
|
|
# gdsim.im().save("p%04d.png" % c)
|
|
|
|
class FullchipRegime(TestRegime):
|
|
reg16s = [gameduino.SCROLL_X, gameduino.SCROLL_Y, gameduino.BG_COLOR, gameduino.SAMPLE_L, gameduino.SAMPLE_R]
|
|
reg8s = [gameduino.IDENT,
|
|
gameduino.REV,
|
|
gameduino.SPR_PAGE,
|
|
gameduino.JK_MODE,
|
|
gameduino.SPR_DISABLE,
|
|
gameduino.IOMODE]
|
|
memories = [
|
|
(gameduino.RAM_PIC, 10 * 1024),
|
|
(gameduino.RAM_SPR, 2048),
|
|
(gameduino.RAM_SPRPAL, 2048),
|
|
(gameduino.RAM_SPRIMG, 16384),
|
|
(gameduino.PALETTE16A, 64),
|
|
(gameduino.PALETTE4A, 64),
|
|
(gameduino.VOICES, 256),
|
|
# (gameduino.IDENT, 64), # register file
|
|
]
|
|
def checklines(self):
|
|
return [0, 299] + random.sample(range(1, 299), 2)
|
|
|
|
class SpriteRegime(TestRegime):
|
|
reg16s = []
|
|
reg8s = [gameduino.JK_MODE,
|
|
gameduino.SPR_PAGE]
|
|
memories = [
|
|
(gameduino.RAM_SPR, 2048),
|
|
(gameduino.RAM_SPRPAL, 2048),
|
|
# (gameduino.RAM_SPRIMG, 16384),
|
|
(gameduino.PALETTE16A, 64),
|
|
(gameduino.PALETTE4A, 64),
|
|
(gameduino.VOICES, 256),
|
|
]
|
|
|
|
def setup(self):
|
|
self.scramble()
|
|
patt = (
|
|
"0101010101010101"
|
|
"1222222222222220"
|
|
"0222222222222221"
|
|
"1222222222222220"
|
|
"0222222222222221"
|
|
"1222222222222220"
|
|
"0222222222222221"
|
|
"1222222222222220"
|
|
"0222222222222221"
|
|
"1222222222222220"
|
|
"0222222222222221"
|
|
"1222222222222220"
|
|
"0222222222222221"
|
|
"1222222222222220"
|
|
"0222222222222221"
|
|
"1010101010101010" )
|
|
def expand(c):
|
|
c = int(c)
|
|
return c + 4 * c + 16 * c + 64 * c
|
|
|
|
image = array.array('B', [expand(c) for c in patt])
|
|
for i in range(64):
|
|
self.dd.wrstr(gameduino.RAM_SPRIMG + 256 * i, image);
|
|
self.dd.microcode(open("../synth/sketches/j1firmware/thrasher.binle").read())
|
|
|
|
def checklines(self):
|
|
return []
|
|
|
|
def main():
|
|
gdsim = gameduino.sim.Gameduino()
|
|
gd = gameduino.remote.Gameduino(sys.argv[1], 115200)
|
|
dd = Duplicator((gdsim, gd))
|
|
# rr = SpriteRegime(dd)
|
|
rr = FullchipRegime(dd)
|
|
rr.cycle()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|