Shop OBEX P1 Docs P2 Docs Learn Events
Help me understand this Pasm VGA driver code — Parallax Forums

Help me understand this Pasm VGA driver code

Agent420Agent420 Posts: 439
edited 2009-09-01 15:12 in Propeller 1
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):

                        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

  • Ken PetersonKen Peterson Posts: 806
    edited 2009-09-01 12:44
    That's a good question. Seems you could just put the buffers after the code. Perhaps it's to keep the addresses consistent with code changes?

    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.
  • Agent420Agent420 Posts: 439
    edited 2009-09-01 13:35
    I thought about the saving of space and consistent addressing as well... I mean there has to be some reason to go through all of this.· I note that the code is launched in multiple cogs, and some cogs performa a different operation than the other; in this example, 2 cogs are dedicated to video displau and 1 is dedicated to the cursor.· I thought perhaps each of these might try to use the memory space of the unneeded instructions as buffer space, but even then, it all fit into the cog in the first place right?
    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?
    field_code                                              'field loop code begins at this offset
    ' Undefined cursor data
    cx                      res     1
    cy                      res     1
    ccolor                  res     1
    cshape_l                res     1
    cshape_r                res     1
    coff                    res     1
    cseg_l                  res     1
    cseg_r                  res     1
    cshr                    res     1
    cshl                    res     1
    cpix_l                  res     32
    cpix_r                  res     32
    
    ' &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    ' &#9474;  Field Loop - two cogs  &#9474;
    ' &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                            [b][color=red]org[/color][/b]
    ' Allocate buffers
    palettes                res     64                      'palettes of colors
    colors                  res     xtiles                  'colors for tile row
    pixels0                 res     xtiles                  'pixels for tile row line +0
    pixels1                 res     xtiles                  'pixels for tile row line +1
    pixels2                 res     xtiles                  'pixels for tile row line +2
    pixels3                 res     xtiles                  'pixels for tile row line +3
    ' Each cog alternately builds and displays four scan lines
                              
    field                   mov     cnt,#ytiles * 4 / 2 
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-01 14:15
    The 2nd ORG effectively overlays the buffers on top of the initialization / relocated code. I would agree that this way of arranging things is confusing and hard to understand. As I understand it, the main reason for doing things this way is to be able to use zero-based addresses for the color palettes and save an addition in the inner loop of the code.

    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.
  • Agent420Agent420 Posts: 439
    edited 2009-09-01 15:04
    <light slowly appearing at end of tunnel>

    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
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-01 15:12
    The Propeller uses instruction modification to do indexing. If you have an array that's referenced often in a tight inner loop, you really really want to place that array starting at location zero so you don't have to have an addition in your inner loop to add the base address of the array.
Sign In or Register to comment.