Help me understand this Pasm VGA driver code
Agent420
Posts: 439
Again with the vga driver ;-)
I'm having a bit of trouble understanding some coding aspects of this [url=http://rayslogic.com/propeller/Users/VGA_Tile_Driver_Demo_-_Archive__[Date_2006.11.12__Time_03.56].zip]vga driver code[/url]·(similar to the vga tile drivers included with the Prop Tool demos)...·· Specifically, the reasoning to programmatically relocate code, have RES blocks in the middle and using multiple ORG statements.
The code basically has 2 sections with some RES space between them.· Normally, the advice in the Prop manual is not to do this, and have the RES directives at the bottom.· The program begins by moving the 2nd section of program code to the addresses where the RES blocks were (d0s0 is a simple constant used to increment the destination and source adresses):
This is similar to the Vga HiRes Text Demo in the Prop Tool...· Here the pasm code moves itself around to accommodate ram usage at the top of memory...· what is the benefit of doing this?· It seems like a lot of work for nothing when you could simply set your buffers near the bottom of cog ram to begin with?
Any insight?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Post Edited (Agent420) : 9/1/2009 1:40:08 PM GMT
I'm having a bit of trouble understanding some coding aspects of this [url=http://rayslogic.com/propeller/Users/VGA_Tile_Driver_Demo_-_Archive__[Date_2006.11.12__Time_03.56].zip]vga driver code[/url]·(similar to the vga tile drivers included with the Prop Tool demos)...·· Specifically, the reasoning to programmatically relocate code, have RES blocks in the middle and using multiple ORG statements.
The code basically has 2 sections with some RES space between them.· Normally, the advice in the Prop manual is not to do this, and have the RES directives at the bottom.· The program begins by moving the 2nd section of program code to the addresses where the RES blocks were (d0s0 is a simple constant used to increment the destination and source adresses):
org
' Move field loop into position entry mov field,field_code add entry,d0s0_ djnz regs,#entry ... d0s0_ long 1 << 9 + 1 'd and s field increments regs long $1F0 - field 'number of registers in field loop space
This is similar to the Vga HiRes Text Demo in the Prop Tool...· Here the pasm code moves itself around to accommodate ram usage at the top of memory...· what is the benefit of doing this?· It seems like a lot of work for nothing when you could simply set your buffers near the bottom of cog ram to begin with?
' COG RAM usage: $000 = d0 - used to inc destination fields for indirection ' $001-$080 = scanbuff - longs which hold 4 scan lines ' $081-$182 = scancode - stacked WAITVID/SHR for fast display ' $183-$1EF = maincode - main program loop which drives display org 'set origin to $000 for start of program d0 long 1 << 9 'd0 always resides here at $000, executes as NOP ' Initialization code and data - after execution, space gets reused as scanbuff 'Move main program into maincode area :move mov $1EF,main_begin+main_size-1 sub :move,d0s0 '(do reverse move to avoid overwrite) djnz main_ctr,#:move
Any insight?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Post Edited (Agent420) : 9/1/2009 1:40:08 PM GMT
Comments
I think you save a register if you move the code as opposed to just inserting a JMP instruction. All of the code that does the move gets overwritten by data after execution begins.
Not a very complete answer I'm afraid.
As for consistent addressing, isn't it just as easy to assign constant or variable symbols to those addresses and use them instead?
While we're discussing this, what is the reasoning for the 2nd ORG declaration?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
In terms of where things go ... Just remember that there are two program counters in the assembler. One determines where the data will go in hub memory and one defines where the data will be expected to reside in cog memory. ORG and RES change the 2nd counter without affecting the 1st counter. Since a block of 512 longs is copied to the cog from the hub, things (like "field") may initially end up somewhere different from where they're written to run ... very confusing. I'd rather write code with an offset (field+x) to reflect where it's expected to be during execution. It looks messier, but it's explicit about what's intended.
As for 0 based addresses, because all cog memory fits within the available 9 bit field, what benefit would that provide?· I can understand trying to locate main memory in some fashion towards that end, but does it really matter in cog memory space?
^ edit - n/m figured out the 0 based thing.
Also, the manual states that ORG directives without a specified address default to 0...· wouldn't that make the "field" label reference 0 rather than "field code", where it is moved to?· I can understand perhaps needing to reset "field" to "field code" because of the address count displacement caused by the RES directives above it, but I don't see how 0 makes that work.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Post Edited (Agent420) : 9/1/2009 3:11:07 PM GMT