How do you write your time sensitive pasm code?
I'm working on hacking one of the video drivers to include support for 3· 64x32 monochrome sprites.· This is my first real foray into pasm programming.· I've done a lot of 8 bit asm with 6502's and avr's, but some aspects of pasm are different enough to make me scratch my head.
For those of you who have programmed time sensitive code, what working style do you use to keep track of your cycles?· Do you keep a running track within comment code on the right?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For those of you who have programmed time sensitive code, what working style do you use to keep track of your cycles?· Do you keep a running track within comment code on the right?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Comments
Either that (comments on right) or I print out time sensitive portions and annotate them by hand in pencil. Whatever works for you really.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lt's not particularly silly, is it?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Composite NTSC sprite driver: Forum
NTSC & PAL driver templates: ObEx Forum
OnePinTVText driver: ObEx Forum
It would be neat if there was some kind of plugin that automatically inserted the correct cycle times inside the Propeller Tool, or a similar option for the compiler that provides an automatic listing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Visit some of my articles at Propeller Wiki:
MATH on the propeller propeller.wikispaces.com/MATH
pPropQL: propeller.wikispaces.com/pPropQL
pPropQL020: propeller.wikispaces.com/pPropQL020
OMU for the pPropQL/020 propeller.wikispaces.com/OMU
Then in the comments I put the clock cycles for each line and then somewhere in the comments I include the total for the routine.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
One thing I find handy is to express things in terms of a primary time unit. In the templates Eric provided for us, that's PLLA / Pixel. This is extremely handy.
What I like to do with Excel is express everything parametrically, so that changes roll down through the spreadsheet, and if you want to, the driver can respond in real time.
Do new calcs during the VBLANK, and draw the next frame with the new timings.
Excel is also handy for proofing out assembly math. I've just started doing this and have had some good results. You run two columns, one with the timings just expressed in ordinary math. Then do the other one using the operations the propeller can do. When they match over a number of values, then code.
(I have spent way too much time NOT doing that. Live 'n learn.)
The other thing I find handy is to break your timings down to coarse totals. For NTSC as an example, there are lots of timings that really don't change. Sync, cburst, etc... What can and does change is what that active scanline looks like.
Do a sum of your base timing for that. The porches, plus the active pixel area. Then, when you decide to change resolutions, you can build your VSCL, calculate number of waitvids, add the PLLAs up, then take the difference between the sum for the scanline, and use that for the porches. This saves a ton of hassle.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Propeller Wiki: Share the coolness!
Chat in real time with other Propellerheads on IRC #propeller @ freenode.net
Safety Tip: Life is as good as YOU think it is!
All of the methods mentioned above are good, you can even use the "{ }" to insert a comment inline with your code.
{4 clocks} mov temp, parWith hub operations it is easy to lose your determinism, but it can be re-gained by using waitcnt command.
See this link: http://forums.parallax.com/showthread.php?p=689451
In the end it is best to measure your timing or at least measure sections of code during the debugging process.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
I was coincidentally trying to comprehend the cog synching mechanism, as I may have to add an additional cog to those already in the code source I am hacking away at (which is in here btw).· I see this is how his vga driver accomplishes the task...
' Synchronize all cogs' video circuits so that waitvid's will be pixel-locked movi frqa,#(pr / 5) << 2 'set pixel rate (VCO runs at 2x) mov vscl,#1 'set video shifter to reload on every pixel waitcnt cnt,d8_d4 'wait for sync count, add ~3ms - cogs locked! movi ctra,#%00001_110 'enable PLLs now - NCOs locked! waitcnt cnt,#0 'wait ~3ms for PLLs to stabilize - PLLs locked! mov vscl,#100 'subsequent WAITVIDs will now be pixel-locked!But what I am having trouble understanding is why the Spin code that launches these cogs allows the first 2 to start before launching the 3rd...· I would think they would all want to be in synch?
'Launch cogs, abort if error repeat i from 0 to 2 if i == 2 'cursor cog? ifnot cursor_ptr 'cursor enabled? quit 'if not, quit loop waitcnt($2000 + cnt) 'cursor cog, allow prior cog to launch vcfg_ ^= $10000000 'set two-color mode array_ptr_~ 'flag cursor function ifnot cog[noparse][[/noparse]i] := cognew(@entry, @dira_ + i << 15) + 1 stop return {false}▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
' Do three lines minus horizontal back porch pixels to buy a big block of time mov vscl,vscl_three_lines_mhb waitvid ccolor,#0 ' start of my timing window (4765 free) ' Get cursor data rdlong cx,regs ' unknown 7-22? but creates a base add regs,#4 ' + 4 rdlong cy,regs ' +12 (7+5 for hub access) add regs,#4 ' + 4 rdlong ccolor,regs ' +12 (7+5 for hub access) add regs,#4 ' + 4 and ccolor,#$FC ' + 4 rdlong cshape_l,regs ' + 8 (7+1 for hub access) add regs,#32 ' + 4 shl ccolor,#8 ' + 4 rdlong cshape_r,regs ' + 8 (7+1 for hub access) add regs,#32 ' + 4 rdlong coff,regs ' +12 (7+5 for hub access) sub regs,#76 ' + 4▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Composite NTSC sprite driver: Forum
NTSC & PAL driver templates: ObEx Forum
OnePinTVText driver: ObEx Forum