View previous topic :: View next topic |
Author |
Message |
mrak
Joined: 14 Dec 2005 Posts: 24
|
Posted: Fri Oct 17, 2014 7:44 am Post subject: How to READ from the data table with offset? |
|
|
The READ command is convenient for sequential reading of data from the data table but the RESTORE command always sets the data pointer at the beginning of the table.
Could you, please, advise how to skip over a block of data in the table and start sequential reading from the offset point (i.e. Nth element of the table)?
Thanks,
makarak
(BASCOM-AVR version : 2.0.7.7 ) |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Oct 17, 2014 8:59 am Post subject: |
|
|
Processor registers R8/R9 hold the pointer used by Read(), it's possible to add an offset there.
Care has to be taken with processors of > 64k flash, where RAMPZ needs to be taken care of. |
|
Back to top |
|
|
O-Family
Joined: 23 May 2010 Posts: 320 Location: Japan
|
Posted: Sat Oct 18, 2014 1:43 am Post subject: |
|
|
Hi
"Lookup" if the numeric data.
"Lookupstr" if the string data.
In changing to this instruction, do you have any problems? |
|
Back to top |
|
|
mrak
Joined: 14 Dec 2005 Posts: 24
|
Posted: Mon Nov 03, 2014 8:43 pm Post subject: |
|
|
O-Family wrote: | Hi
"Lookup" if the numeric data.
"Lookupstr" if the string data.
In changing to this instruction, do you have any problems? |
O-Family,
I'm aware of the both commands.
I need to jump over to the offset point and next do the sequential read. Therefore the lookup commands are not very convenient enough here as require explicite calculation of the current pointer position. Referring to a pair of the R8/R9 registers approach suggested by Mark works fine and fully meet my expectation. |
|
Back to top |
|
|
mrak
Joined: 14 Dec 2005 Posts: 24
|
Posted: Mon Nov 03, 2014 8:46 pm Post subject: |
|
|
O-Family wrote: | Hi
"Lookup" if the numeric data.
"Lookupstr" if the string data.
In changing to this instruction, do you have any problems? |
O-Family,
I'm aware of the both commands.
I need to jump over to the offset point and next do the sequential read. Therefore the lookup commands are not very convenient enough here as require explicite calculation of the current pointer position. Referring to a pair of the R8/R9 registers approach suggested by Mark works fine and fully meet my expectation. |
|
Back to top |
|
|
O-Family
Joined: 23 May 2010 Posts: 320 Location: Japan
|
Posted: Tue Nov 04, 2014 1:06 pm Post subject: |
|
|
If you can write using an assembler, operation of a data table can also choose various kinds of methods.
I proposed the method of operating a table on BASIC grammar.
If the same is the type of number that is prepared for data statement, "Lookup" instruction by varying the index, and operation equivalent to a sequential lead is possible. |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Tue Nov 04, 2014 3:26 pm Post subject: |
|
|
See my answear in SUB topic and test this in simulator to understand that offset can be calculated even on strings table
Example show "Poland" in first Line and "Bartek" in the second because strings are readed to its end.
Code: | $sim
$regfile = "m8def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 64
Dim Address As Word
Dim N As Byte
Dim Items(5) As Byte
Dim Offset As Word
Offset = 2 'TRY OTHER VALUES
Declare Sub Show_array(byval Address As Word , Byval Linia As Byte , Byval Offset As Word)
Cls
Address = Loadlabel(label_1 )
Call Show_array(address , 1 , 6)
Call Show_array(address , 2 , 13)
Macro Restore_address
Loadadr Address , X 'restore address
!LD R8,X+
!LD R9,X
End Macro
'** pro forma
Do
nop
Loop
End
'** End **
Sub Show_array(byval Address As Word , Byval Linia As Byte, Byval Offset As Word)
Local Addr_to As Word
Local Text As String * 20
Locate Linia , 1
Address = Address + Offset
Restore_address 'macro is used
Read Text
Lcd Text
End Sub
Label_1:
Data "Hello Poland" , "Bartek" |
|
|
Back to top |
|
|
O-Family
Joined: 23 May 2010 Posts: 320 Location: Japan
|
Posted: Tue Nov 04, 2014 4:21 pm Post subject: |
|
|
It is a method peculiar to BASCOM to operate the registers R8 and R9 directly.
I would like to think more simply.
Code: | $sim
$regfile = "m8def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 64
$baud = 9600
Dim Offset As Word , Temp1 As Byte , Temp2 As Byte
Offset = 16 'ASCII "0" Font character.
Offset = Offset * 8 '8 bytes step.
Offset = Offset + 4 'Font information is skipped.
For Temp1 = 1 To 8 'Get 8 bytes.
Temp2 = Lookup(offset , Font8x8)
Print Temp2
Offset = Offset + 1
Next Temp1
End
$include "font8x8.font" '"lcdgraph" Font data. |
|
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5914 Location: Holland
|
Posted: Tue Nov 04, 2014 10:07 pm Post subject: |
|
|
maybe good to know that in 2078 the label parameter can be a numeric value too. This allows to pass to a sub/function. _________________ Mark |
|
Back to top |
|
|
O-Family
Joined: 23 May 2010 Posts: 320 Location: Japan
|
Posted: Wed Nov 05, 2014 1:31 am Post subject: |
|
|
Hi Mark
Yes, in 2078(2077 SLA), the address of the label was passed by the variable.
The following is possible.
It is very good!
Code: | $sim
$regfile = "m8def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 64
$baud = 9600
Dim Offset As Word , Temp1 As Byte , Temp2 As Byte , ___fonttable As Word
Setfont Font8x8 '*** Standard font of BASCOM ***
'
Offset = 16 'ASCII "0" Font character.
Offset = Offset * 8 '8 bytes step.
Offset = Offset + 4 'Font information is skipped.
For Temp1 = 1 To 8 'Get 8 bytes.
Temp2 = Lookup(offset , ___fonttable)
Print Temp2
Offset = Offset + 1
Next Temp1
Setfont Font8x8_user '*** Font made by the user ***
'
Offset = 16 'ASCII "0" Font character.
Offset = Offset * 8 '8 bytes step.
Offset = Offset + 4 'Font information is skipped.
For Temp1 = 1 To 8 'Get 8 bytes.
Temp2 = Lookup(offset , ___fonttable)
Print Temp2
Offset = Offset + 1
Next Temp1
End
$include "font8x8.font" '"lcdgraph" Font data.
$include "font8x8_User.font" 'User Font data. |
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Wed Nov 05, 2014 12:48 pm Post subject: |
|
|
albertsm wrote: | maybe good to know that in 2078 the label parameter can be a numeric value too. This allows to pass to a sub/function. |
How is RAMPZ taken care of in this variable, if flash > 64k?
May I suggest an additional parameter for the Lookup()-function, which sets the pointer for sequential Read's immediately on the byte following the lookup?
This way the first value can be retrieved by an absolute read and the following by sequential reads. |
|
Back to top |
|
|
O-Family
Joined: 23 May 2010 Posts: 320 Location: Japan
|
Posted: Wed Nov 05, 2014 2:03 pm Post subject: |
|
|
MWS wrote: | How is RAMPZ taken care of in this variable, if flash > 64k? |
I think that it is managed by the LONG variable.
See an assembler output!
Code: | [ATmega8]
0034 : 2466 CLR R6
0035 : EBE2 LDI ZL,LOW(S01B2)
0036 : E0F1 LDI ZH,HIGH(S01B2)
0037 : E6A4 LDI XL,LOW(S0064)
0038 : E0B0 LDI XH,HIGH(S0064)
0039 : 93ED ST X+,ZL
003A : 93FC ST X,ZH
[ATmega1284P]
006C : 2466 CLR R6
006D : E5E6 LDI ZL,LOW(S0256)
006E : E0F2 LDI ZH,HIGH(S0256)
006F : 940E 07A8 CALL L07A8
0071 : E0A5 LDI XL,LOW(S0105)
0072 : E0B1 LDI XH,HIGH(S0105)
0073 : 93ED ST X+,ZL
0074 : 93FD ST X+,ZH
0075 : B78B IN R24,$3B [RAMPZ]
0076 : 938C ST X,R24
07A2 : 930F PUSH R16
07A3 : E001 LDI R16,$01
07A4 : BF0B L07A4: OUT $3B,R16
07A5 : 910F POP R16
07A6 : 9488 CLC
07A7 : 9508 RET
07A8 : 930F L07A8: PUSH R16
07A9 : 2700 CLR R16
07AA : CFF9 RJMP L07A4 |
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Wed Nov 05, 2014 6:01 pm Post subject: |
|
|
O-Family wrote: | I think that it is managed by the LONG variable.
See an assembler output!
[code]
[ATmega1284P]
006C : 2466 CLR R6
006D : E5E6 LDI ZL,LOW(S0256)
006E : E0F2 LDI ZH,HIGH(S0256)
006F : 940E 07A8 CALL L07A8
0071 : E0A5 LDI XL,LOW(S0105)
0072 : E0B1 LDI XH,HIGH(S0105)
0073 : 93ED ST X+,ZL
0074 : 93FD ST X+,ZH
0075 : B78B IN R24,$3B [RAMPZ]
0076 : 938C ST X,R24
07A2 : 930F PUSH R16
07A3 : E001 LDI R16,$01
07A4 : BF0B L07A4: OUT $3B,R16
07A5 : 910F POP R16
07A6 : 9488 CLC
07A7 : 9508 RET
07A8 : 930F L07A8: PUSH R16
07A9 : 2700 CLR R16
07AA : CFF9 RJMP L07A4 |
If you think that, you think wrong.
Look for the line, where the codepage is set, then you see it is hard-coded to page 0.
The compiler knows addresses of all labels, so it knows the codepage of the label-start.
But if the label-start is just below a 64k boundary, and the target address is on the next page, knowing only the label-start is not enough.
The true page and address within page has to be calculated from the pointer-variable, and it has to be done dynamically. The variable must thus contain all information to the target, means the absolute position within flash.
Bascom can use a subroutine then, to calculate the page and position within page.
The shown code does not do this, it reads only the word position within a page and assumes a fixed page. |
|
Back to top |
|
|
O-Family
Joined: 23 May 2010 Posts: 320 Location: Japan
|
Posted: Thu Nov 06, 2014 1:01 am Post subject: |
|
|
This assembler code is the thing which compiled and disassembled the above-mentioned Font extraction program.
The shown portion is the code which extracted the portion which stores the address of a label in a variable.
When the Flash of a chip are 64K or more, it is saying that it is automatically stored in a LONG variable.
Therefore, a user also has to prepare a LONG variable.
Moreover, by the "Lookup" processing routine, if 64K is exceeded, it is programmed to change RAMPZ. |
|
Back to top |
|
|
|