Area starting at page boundary

Help
2007-03-08
2013-03-12
  • I want the function USB_Jump_Table() to start at a page boundary. Therefore, I defined the following assembler code:

          .area JTAB (PAG, CODE)
    _USB_Jump_Table::
          ljmp  _ISR_Sudav            ;(00) Setup Data Available
          .db  0
          ljmp  _ISR_Sof              ;(04) Start of Frame
          .db  0
          ljmp  _ISR_Sutok            ;(08) Setup Data Loading
          .db  0

    I hoped that in this way the linker would automatically place the code at a page boundary, but I only get

    ?ASlink-Warning-Paged Area     JTAB Boundary Error

    Is there a simple way of doing this?

     
    • elcat
      elcat
      2007-04-19

      I assume that you are trying to port the EZ-USB framework to be used with SDCC. I did the same job these days :-)
      I ran into the same problem. The "paged" attribute seems to be ignored in conjunction with the "code" attribute. I wrote:

      .area JTAB (XDATA,PAG)

      to solve the problem. This of course puts the jump table into the xdata segment, but that does not make a difference... at least with the EZ-USB project, because code and xdata share the same address space.

      Happy hacking,

      Markus Klama.

       
    • elcat
      elcat
      2007-04-19

      Sorry, I did not pay attention to the fact that the SDCC runtime startup will clear the xdata area. So for now I would suggest that you put the jump table into the same segment where you have put the interrupt vector jumps (that would have to be a non relocateable segment) and put a ".org 0x0100" just in front of the jump table code. This actually works for me. Look at the resulting map file to see what's happening!

      Markus Klama.

       
    • Maarten Brock
      Maarten Brock
      2007-04-20

      PAG only makes sure the whole segment fits inside a 256 bytes page and doesn't cross a border.

      Why does it need to be at a page boundary?

      Using a JTAB (ABS, CODE) area with a .org will do fine too. Don't try to offset with the ".org 0x0100" from another segment. It ends up at 0x100 absolute.

       
    • elcat
      elcat
      2007-04-20

      Maarten,

      the 8051 based Cypress chips (CY7C64 family) have a special feature called "autovectoring". These chips supply 46 (!!!) USB related interrupt events, routed to the controller via interrupts 8 and 10. Within both interrupt service routines, the programmer would have to check more than 20 hardware sources to figure out the reason for the interrupt.
      By turning on the autovectoring feature, the hardware assumes that the vectoring addresses for those two interrupts contain ljmp instructions. When the interrupt occurs and the controller fetches this instruction, it replaces the 3rd byte of the instruction with an interrupt source number, multiplied by 4. So the ljmp can point to another, big jump table, which contains 46 ljmps.
      Of course this feature will work only if the the big 46 entries jump table starts at a 256 byte boundary. The autovectoring feature is a simple replacement of the 3rd byte of the first three bytes fetched from the irq vector location.
      The KEIL C compiler, however is capeable of handling code segments with attributes like "is relocateable", but must start at a 256 byte boundary.
      By now, my solution is to use a JUMPTAB (CODE, ABS) area and nail it down to 0x0100 using an .org directive.

      Best regards,
      Markus.