Getting around the "Not a Long Address" problem when using DAT sections for byte code
Peter Jakacki
Posts: 10,193
I've got this problem when I use BST and the Spin tool is the same in that it insists upon references to addresses being aligned to long boundaries which makes sense when you are writing PASM code but not much if DAT sections are supposed to be more general-purpose.
In my byte code I have to calculate relative branches by hand at present because as soon as I perform a simple HERE - THERE calculation the compiler throws a fit if neither address is aligned on long boundaries.
Looking at the listing below you see how I have made it work by throwing in a long before PRTBYTE to make sure that it was aligned. Of course I could pad it manually as well but a long suffices to demonstrate that this keeps the compiler happy. The same also applies to the label DM1 at the end of the listing in that it needs to be aligned for the calculation DM1-PRTBYTE just previous to DM1, for this purpose I threw in a couple of NOPs. Without these the compiler throws up an error "Not a Long Address".
So does anyone have any ideas or perhaps there is another compiler out there that is a little more flexile? Of course I'd really love to be able to code macros just like we do in assembly but no such luck.
BTW, this little problem only affects the code that is "Spin" compiled as I then use the byte code VM to compile further definitions itself. But I want to make this a simple thing anyone can do in one or two simple steps.
EDIT: The calculation needs to be on it's address in hub RAM rather than assuming it's loaded into a cog. So the DM1-PRTHEX result is incorrect and can't be used like this.
In my byte code I have to calculate relative branches by hand at present because as soon as I perform a simple HERE - THERE calculation the compiler throws a fit if neither address is aligned on long boundaries.
Looking at the listing below you see how I have made it work by throwing in a long before PRTBYTE to make sure that it was aligned. Of course I could pad it manually as well but a long suffices to demonstrate that this keeps the compiler happy. The same also applies to the label DM1 at the end of the listing in that it needs to be aligned for the calculation DM1-PRTBYTE just previous to DM1, for this purpose I threw in a couple of NOPs. Without these the compiler throws up an error "Not a Long Address".
So does anyone have any ideas or perhaps there is another compiler out there that is a little more flexile? Of course I'd really love to be able to code macros just like we do in assembly but no such luck.
BTW, this little problem only affects the code that is "Spin" compiled as I then use the byte code VM to compile further definitions itself. But I want to make this a simple thing anyone can do in one or two simple steps.
EDIT: The calculation needs to be on it's address in hub RAM rather than assuming it's loaded into a cog. So the DM1-PRTHEX result is incorrect and can't be used like this.
0530(001B) 06 | _BOUNDS byte OVER/2,PLUS/2,SWAP/2,EXIT/2 0531(001B) 0C | 0532(001B) 08 | 0533(001B) 00 | 0534(001C) | PRTHEX ' ( n -- ) print n (0..$0F) as a hex character 0534(001C) 2D | byte CLIT/2,$30,PLUS/2 0535(001C) 30 | 0536(001C) 0C | 0537(001C) 05 | byte DUP/2,CLIT/2,$39,GT/2,_IF/2,3 0538(001D) 2D | 0539(001D) 39 | 053A(001D) 20 | 053B(001D) 3E | 053C(001E) 03 | 053D(001E) 2D | byte CLIT/2,12,PLUS/2 'Adjust for A..F 053E(001E) 0C | 053F(001E) 0C | 0540(001F) 49 | PRTCH byte EMIT/2,EXIT/2 0541(001F) 00 | 0544(0020) 00 00 00 00 | LONG 0 0548(0021) | PRTBYTE 0548(0021) 05 | byte DUP/2,CLIT/2,4,_SHR/2 0549(0021) 2D | 054A(0021) 04 | 054B(0021) 1A | 054C(0022) 3B | byte RCALL/2,20 '-->PRTHEX 'Due to limitations of Spin tool & BST this needs to be calculated by hand 054D(0022) 14 | 054E(0022) 3B | byte RCALL/2,22 054F(0022) 16 | 0550(0023) 00 | byte EXIT/2 0551(0023) | PRTWORD 0551(0023) 05 | byte DUP/2,CLIT/2,8,_SHR/2 0552(0023) 2D | 0553(0023) 08 | 0554(0024) 1A | 0555(0024) 3B | byte RCALL/2,15,RCALL/2,17 ' PRTBYTE 0556(0024) 0F | 0557(0024) 3B | 0558(0025) 11 | 0559(0025) 00 | byte EXIT/2 055A(0025) | PRTSTR 055A(0025) 46 | byte RPOP/2 055B(0025) 05 | PSTLP byte DUP/2,CFETCH/2,DUP/2,_IF/2,3 055C(0026) 23 | 055D(0026) 05 | 055E(0026) 3E | 055F(0026) 03 | 0560(0027) 49 | byte EMIT/2,_AGAIN/2,8 0561(0027) 41 | 0562(0027) 08 | 0563(0027) 03 | byte DROP/2,INC/2,PUSHR/2,EXIT/2 0564(0028) 0E | 0565(0028) 45 | 0566(0028) 00 | 0567(0028) | DEMO 0567(0028) 2E | DUMP byte WLIT/2,00,$10 0568(0029) 00 | 0569(0029) 10 | 056A(0029) 12 | byte LIT0/2,DO/2 056B(0029) 42 | 056C(002A) 2D | byte CLIT/2,$0D,EMIT/2,CLIT/2,$0A,EMIT/2 056D(002A) 0D | 056E(002A) 49 | 056F(002A) 2D | 0570(002B) 0A | 0571(002B) 49 | 0572(002B) 48 | byte I/2,RCALL/2,36 ' PRTWORD 0573(002B) 3B | 0574(002C) 24 | 0575(002C) 3B | byte RCALL/2,29,": ",0 0576(002C) 1D | 0577(002C) 3A | 0578(002D) 20 | 0579(002D) 00 | 057A(002D) 02 | byte _NOP,_NOP 057B(002D) 02 | 057C(002E) 2D | byte CLIT/2,$10,BOUNDS/2,DO/2 057D(002E) 10 | 057E(002E) 0C | 057F(002E) 42 | 0580(002F) 48 | byte I/2,CFETCH/2,RCALL/2,DM1-PRTBYTE 0581(002F) 23 | 0582(002F) 3B | 0583(002F) 0F | 0584(0030) | DM1 |
Comments
With a @ before the label you use the hubadress which is in bytes. So try this: then the compiler will also not complain about not long aligned.
Andy