Program Doesn't Work When Clock Speed Changed
A forum member here, __red__, is having a class for a few people on Propeller. We got the chips, built some boards, and built some name badges with a 7 x 8 grid of charliplexed LEDs.
So, I decided to write Snake for our badges. This is literally my first Spin program ever. And it works just fine. But, for various reasons, now I'm trying to turn up the clock speed. I *know* I have the right Crystal speed and everything, because I've loaded another program on my badge that uses these exact settings and *that* program works just fine.
However, I can't for the life of me figure out what's going on with my Snake game. When I add in the higher clockspeed settings in the CON block and flash it to RAM, the program just doesn't work. One single LED flashes once, and then it crashes and goes back to the program in the EEPROM.
Here's the code, with the clock settings I'm trying to use commented out. You can also see some other attempts at using different waitcnt() values in an attempt to fix it. Obviously, none of them have worked.
I've also tried removing the waits altogether, and instead of having the game run at a speed far to fast for a human to respond to (which is what I would expect)... it still just crashes.
Anyone have any suggestions? I read the Prop Manual, but there's nothing obvious about why it would cause the program to crash.
So, I decided to write Snake for our badges. This is literally my first Spin program ever. And it works just fine. But, for various reasons, now I'm trying to turn up the clock speed. I *know* I have the right Crystal speed and everything, because I've loaded another program on my badge that uses these exact settings and *that* program works just fine.
However, I can't for the life of me figure out what's going on with my Snake game. When I add in the higher clockspeed settings in the CON block and flash it to RAM, the program just doesn't work. One single LED flashes once, and then it crashes and goes back to the program in the EEPROM.
Here's the code, with the clock settings I'm trying to use commented out. You can also see some other attempts at using different waitcnt() values in an attempt to fix it. Obviously, none of them have worked.
I've also tried removing the waits altogether, and instead of having the game run at a speed far to fast for a human to respond to (which is what I would expect)... it still just crashes.
Anyone have any suggestions? I read the Prop Manual, but there's nothing obvious about why it would cause the program to crash.
CON
'_clkmode=xtal1+pll8x 'Run at 16x5 = 80mhz!
'_xinfreq=5_000_000 'We are using a 5Mhz Crystal
GameSpeedMultiplier = 4
StartingPixels = 4
XBounds = 7
YBounds = 6
S2Pin = 17
S3Pin = 18
S4Pin = 19
OBJ
rr: "RealRandom.spin"
VAR
byte SnakePixelsX[56]
byte SnakePixelsY[56]
byte CurrentLength
long DrawStack[20]
long MoveStack[20]
long InputStack[20]
long GraphicsCogID
byte CurrentDirection ' 0 is up, 1 is right, 2 is down, 3 is left.
long RandomSeed
byte FruitX
byte FruitY
byte FruitExists
byte GameOver
byte TurnQueued
PUB Main | i
initializeSnake
cognew(Graphics, @DrawStack)
cognew(Input, @InputStack)
GenerateFruit
repeat while GameOver == 0
Move
waitcnt(clkfreq * 2 + cnt)
'waitcnt(500000 + cnt)
COGSTOP(GraphicsCogID)
repeat
DrawX
pub Input
repeat
if ina[S2Pin] == 0 AND TurnQueued == 0
TurnQueued := 1
TurnCounterClockwise
waitcnt(clkfreq/5 + cnt)
'waitcnt(500000 + cnt)
WatchForButtonRelease(S2PIN)
elseif ina[S4Pin] == 0 AND TurnQueued == 0
TurnQueued := 1
TurnClockwise
waitcnt(clkfreq/5 + cnt)
'waitcnt(500000 + cnt)
WatchForButtonRelease(S4PIN)
pri WatchForButtonRelease (PIN) | i
repeat while i < 2
if ina[PIN] == 1
i++
pri TurnCounterClockwise
if CurrentDirection == 0
CurrentDirection := 3
else
CurrentDirection -= 1
pri TurnClockwise
if CurrentDirection == 3
CurrentDirection := 0
else
CurrentDirection += 1
pri Move | collision,i
waitcnt(clkfreq/GameSpeedMultiplier + cnt)
'waitcnt(500000 + cnt)
collision := DetectFruitCollision
if collision == 1
eatFruit
repeat i from CurrentLength -1 to 1
SnakePixelsX[i] := SnakePixelsX[i - 1]
SnakePixelsY[i] := SnakePixelsY[i - 1]
if CurrentDirection == 0
SnakePixelsY[0] += 1
elseif CurrentDirection == 1
SnakePixelsX[0] -= 1
elseif CurrentDirection == 2
SnakePixelsY[0] -= 1
else
SnakePixelsX[0] += 1
DetectOutOfBounds
DetectSelfCollision
TurnQueued := 0
pri DetectSelfCollision | i,n
repeat i from 0 to CurrentLength - 1
repeat n from 0 to CurrentLength - 1
ifnot i == n
if SnakePixelsX[i] == SnakePixelsX[n] AND SnakePixelsY[i] == SnakePixelsY[n]
FruitX := SnakePixelsX[i]
FruitY := SnakePixelsY[i]
FruitExists := 1
GameOver := 1
pri DetectOutOfBounds | i
repeat i from 0 to CurrentLength - 1
if SnakePixelsX[i] > XBounds OR SnakePixelsY[i] > YBounds
GameOver := 1
FruitX := SnakePixelsX[i+1]
FruitY := SnakePixelsY[i+1]
elseif SnakePixelsX[i] < 0 OR SnakePixelsY[i] < 0
GameOver := 1
FruitX := SnakePixelsX[i+1]
FruitY := SnakePixelsY[i+1]
pri eatFruit
FruitExists := 0
SnakePixelsX[currentLength] := SnakePixelsX[CurrentLength - 1]
SnakePixelsY[currentLength] := SnakePixelsY[CurrentLength - 1]
GenerateFruit
CurrentLength++
pri clearScreen
dira[20..27] := 0
pri Graphics | i,Counter
GraphicsCogID := COGID
repeat
if GameOver == 0
repeat i from 0 to CurrentLength - 1
lightPixel(SnakePixelsX[i], SnakePixelsY[i])
elseif GameOver == 1
repeat i from 1 to CurrentLength - 1
if SnakePixelsX[i] <> FruitX OR SnakePixelsY[i] <> FruitY
lightPixel(SnakePixelsX[i], SnakePixelsY[i])
if FruitExists == 1 AND Counter > 50
lightPixel(FruitX, FruitY)
Counter := 0
Counter++
pri GenerateFruit | collision
collision := 1
repeat while collision == 1
fruitX := Roll(0, 7)
fruitY := Roll(0, 6)
collision := DetectFruitCollision
FruitExists := 1
pri DetectFruitCollision | collision, i
repeat i from 0 to CurrentLength - 1
if FruitX == SnakePixelsX[i] AND FruitY == SnakePixelsY[i]
collision := 1
return collision
pri Roll(minValue, maxValue) : returnValue
returnValue := ||(RandomSeed?//256)
repeat while returnValue < minValue OR returnValue > maxValue
returnValue := ||(RandomSeed?//256)
return returnValue
pri lightPixel(X, Y)
dira[20..27] := 0
dira[X + 20] := 1
outa[X + 20] := 0
if X > Y
dira[Y + 20] := 1
outa[Y + 20] := 1
else
dira[Y + 21] := 1
outa[Y + 21] := 1
pri DrawX | i
repeat i from 0 to 7
lightPixel(i, i)
lightPixel(i, XBounds - (i + 1))
Pri initializeSnake
CurrentDirection := 1
CurrentLength := 4
SnakePixelsX[0] := 4
SnakePixelsY[0] := 3
SnakePixelsX[1] := 5
SnakePixelsY[1] := 3
SnakePixelsX[2] := 6
SnakePixelsY[2] := 3
SnakePixelsX[3] := 7
SnakePixelsY[3] := 3
rr.Start
RandomSeed := rr.Random
rr.Stop
dira[S2Pin] := 0
dira[S3Pin] := 0
dira[S4Pin] := 0

Comments
Mickster
P.S. Oh wait. You have "xinfreq" but your prog requires the following, I believe:
_clkmode = xtal1 + pll16x
_clkfreq = 80_000_000
Or maybe not....I see there's both in other sample progs.