Iteratively assigning cog variables from Main RAM
in Propeller 1
How's it going everyone?
I've finished my VGA driver which is able to output a 640x480 VGA signal @ 60 Hz, compatible with both 8x8 and 16x16 tiles. In order to support this flexibility (as well as the ability to define custom screen tile dimensions and memory tile map dimensions) I calculate a fair number of attributes in the hub which are then passed to the VGA driver cog. Right now, I'm setting these internal registers in the following way (the full code can be viewed here):
As you can see, this is hideous and it seems to me that it MUST be excessively explicit.
Is there a way to iteratively (i.e. using a loop) set internal cog registers? Thank you!
I've finished my VGA driver which is able to output a 640x480 VGA signal @ 60 Hz, compatible with both 8x8 and 16x16 tiles. In order to support this flexibility (as well as the ability to define custom screen tile dimensions and memory tile map dimensions) I calculate a fair number of attributes in the hub which are then passed to the VGA driver cog. Right now, I'm setting these internal registers in the following way (the full code can be viewed here):
' Initialize frame attributes
mov csl, #0 ' Initialize upscale tracking register
mov attptr, par ' Set attribute pointer
add attptr, #4 ' Iterate through attributes and set external to internal equivalents
rdlong vTilesH,attptr
mov numTL, vTilesH
add attptr, #4
rdlong vTilesV,attptr
mov numTF, vTilesV
add attptr, #4
rdlong tSizeH,attptr
add attptr, #4
rdlong tSizeV,attptr
add attptr, #4
rdlong tMapSizeH,attptr
add attptr, #4
rdlong tMapSizeV,attptr
add attptr, #4
rdlong tMemSizeH,attptr
add attptr, #4
rdlong tSize,attptr
add attptr, #4
rdlong tOffset,attptr
add attptr, #4
rdlong vLineSize,attptr
add attptr, #4
rdlong tMapLineSize,attptr
add attptr, #4
rdlong tlslRatio,attptr
mov slr, tlslRatio
sub slr, #1
add attptr, #4
rdlong lPerTile,attptr
mov numLT, lPerTile
add attptr, #4
rdlong cPerFrame,attptr
add attptr, #4
rdlong cPerPixel,attptr
add attptr, #4
rdlong vSclVal,attptr
As you can see, this is hideous and it seems to me that it MUST be excessively explicit.
Is there a way to iteratively (i.e. using a loop) set internal cog registers? Thank you!

Comments
In my rgbw pixel driver I have six variables than need to be passed to the PASM driver. The address of connection is passed in par.
And here's the top of my PASM code that copies moves these six values into the cog.
pixdriver mov t1, par ' hub address of parameters -> t1 movd :read, #connect ' location of cog parameters -> :read(dest) mov t2, #6 ' get 6 parameters :read rdlong 0-0, t1 ' copy parameter from hub to cog add t1, #4 ' next hub element add :read, INC_DEST ' next cog element djnz t2, #:read ' done?I didn't create this strategy (Chip probably did) -- though I do take advantage of it.
In your case, you might do something else. The loop moves the values from hub to cog, the next section takes care of the extra mov instructions. It's probably obvious, but your hub and cog variables must be laid out in the same order.
mov t1, par add t1, #4 movd :read, #vTilesH mov t2, #16 :read rdlong 0-0, t1 add t1, #4 add :read, INC_DEST djnz t2, #:read mov numTL, vTilesH mov numTF, vTilesV mov slr, tlslRatio sub slr, #1 mov numLT, lPerTile' ' Tasks - performed in sections during invisible back porch lines ' tasks mov t1,par 'load parameters movd :par,#_enable '(skip _status) mov t2,#paramcount - 1 :load add t1,#4 :par rdlong 0,t1 add :par,d0 djnz t2,#:load '+164' Initialize frame attributes attptr mov csl, #0 ' Initialize upscale tracking register vTilesH mov attptr, par ' Set attribute pointer numTL add attptr, #4 ' Iterate through attributes and set external to internal equivalents vTilesV rdlong vTilesH,attptr numTF mov numTL, vTilesH tSizeH add attptr, #4 tSizeV rdlong vTilesV,attptr tMapSizeH mov numTF, vTilesV tMapSizeV add attptr, #4 etc rdlong tSizeH,attptr add attptr, #4 rdlong tSizeV,attptr add attptr, #4 rdlong tMapSizeH,attptr add attptr, #4Especially hideous and obfuscatingYeah although it's a particularly handy way to maximize the resources available in the COG.
Actually I find that form of instruction space reuse after initialization not so bad. It gets a lot trickier when you have code being dynamically modified during its execution and registers being reused in different parts of the code for different purposes when they can be. Then deciphering the code and tracking problems down can become rather difficult, you need a lot of coffee for that. I've resorted to basically using all of those techniques in tight spots where you have to fit everything in the COG and get it to run in realtime - it's saved me quite a few times when writing video drivers etc where you also have to store a fair bit of data in the COG as well.
I remember way back in undergrad Computer Science classes they would teach you that space can be traded for time in software. Once you try to wring everything out of a propeller chip in PASM that connection is clearly demonstrated.
@JonnyMac you didn't mention you had a full walkthrough of this strategy: http://radio-hobby.org/uploads/journal/NV/2013/NV_09_2013.pdf
That article is outstanding, and your code worked perfectly in my application.
FWIW... I have made a lot of changes/improvements over the years to my pixel driver. The latest is in ObEx.