Among the features I find most attractive in Swordfish is its flexibility in byte addressing of longword (32-bit) data. For example, I frequently rely on constructs such as defining variables “Private Dim CSst As LongWord” and then setting aliases like “Dim TbstL As CSst.Byte0 “, “Dim TbstH As CSst.Byte1”, and “Dim TbsvU As CSst.Byte2”. I find this extremely useful in porting code from PBP to Swordfish, as in writing a program memory checksum calculator.
However, I was frustrated when I discovered the compiler does not support similar addressing for constants. What I would like to do is define a constant “Private Const CSst As LongWord = $000018 //start of pgm memory” and then use similar aliases for the individual bytes that make up the longword constant. I realize that putting in runtime support for such variable aliasing must have been an arduous task. However, byte addressing of longword constants would require no runtime support whatsoever. All the code generator would need to do is pick off one particular byte of an already known constant. Would it be feasible to support such operations in a future edition of the compiler?
On another subject
Moderators: David Barker, Jerry Messina
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
> Would it be feasible to support such operations in a
> future edition of the compiler?
Bytes, Words, LongWords etc are actually represented internally in the compiler as special case structures - which supports the dot notation used. This makes it possible to support declarations such as...
or you can use directly in your code...
Unfortunately, constants are not represented this way. The effort needed to implement would, in my opinion, not be worth the time. However, you can do what you want like this...
> future edition of the compiler?
Bytes, Words, LongWords etc are actually represented internally in the compiler as special case structures - which supports the dot notation used. This makes it possible to support declarations such as...
Code: Select all
dim MyLong as longword
dim MyByteA as MyLong.Word1.Byte1
dim MyBytesB as MyLong.Words(1).Bytes(1)
Code: Select all
MyLong.Words(1).Bytes(1) = 10
MyLong.Word1.Byte1 = 10
Unfortunately, constants are not represented this way. The effort needed to implement would, in my opinion, not be worth the time. However, you can do what you want like this...
Code: Select all
include "usart.bas"
include "convert.bas"
const
CSst as longword = $12345678,
CSstL as byte = CSst,
CSstH as byte = CSst >> 8,
CSstHH as byte = CSst >> 16,
CSstHHH as byte = CSst >> 24
SetBaudrate(br19200)
Write("$", HexToStr(CSstL), 13, 10)
Write("$", HexToStr(CSstH), 13, 10)
Write("$", HexToStr(CSstHH), 13, 10)
Write("$", HexToStr(CSstHHH), 13, 10)
Dave,
Is there a method to write a particular value anywhere in Program Mem? For instance, can I get the compiler to write the value for RETURN at $3FFE?
Or maybe this was what you were trying to explain above.
Is there a method to write a particular value anywhere in Program Mem? For instance, can I get the compiler to write the value for RETURN at $3FFE?
Code: Select all
Const RTRN as Word = 0x0012 Org 0x3FFE
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
> Is there a method to write a particular value anywhere
> in Program Mem
At the moment, you cannot ORG in Swordfish. Atomic constants types are actually embedded in program memory when they are needed. For example,
will translate to...
Array constants are stored differently in ROM (using DB). You can obviously index a constant array like any other type of array in swordfish, or you can get the ROM address to manipulate directly (for example, @MyConstArray)
If you want to use jump tables, you can use something like this...
Note that for PIC18, ROM access is BYTES but word aligned, hence the * 2 multiply. If you index word aligned (0,2,4,8 etc) you wont need the multiply.
The ASM generated in the above example is pretty efficient, as the param and return is in WREG.
> in Program Mem
At the moment, you cannot ORG in Swordfish. Atomic constants types are actually embedded in program memory when they are needed. For example,
Code: Select all
const RTRN as word = $0012
dim Value as word
Value = RTRN
Code: Select all
CLRF M0_U16H,0
MOVLW 18
MOVWF M0_U16,0
If you want to use jump tables, you can use something like this...
Code: Select all
noinline function Jump(pOffset as WREG) as WREG
pOffset = pOffset * 2
PCL = PCL + pOffset
asm
retlw 0x02 ; offset = 0
retlw 0x04 ; offset = 1
retlw 0x08 ; offset = 2
retlw 0x0A ; offset = 3
end asm
end function
dim Value as byte
Value = Jump(3)
The ASM generated in the above example is pretty efficient, as the param and return is in WREG.
Thanks Dave. Those types of explanations are so helpful.
This is a silly optimization idea and why I asked the question, for which I don't know if there is really a practical solution. If, for instance, you could insert the RETURN Instruction ($0012) at the end of Program ROM, you could probably make CALL's to any of the empty memory addreses before this point and then let the Program Counter NOP it's way to this inserted Return instruction. It could be a very optimized method of creating simple and short delays with unused Program Memory by a CALL to an address as many memory positions as requred for the short delay.
This is a silly optimization idea and why I asked the question, for which I don't know if there is really a practical solution. If, for instance, you could insert the RETURN Instruction ($0012) at the end of Program ROM, you could probably make CALL's to any of the empty memory addreses before this point and then let the Program Counter NOP it's way to this inserted Return instruction. It could be a very optimized method of creating simple and short delays with unused Program Memory by a CALL to an address as many memory positions as requred for the short delay.