PDA

View Full Version : transfer a string from ROM to an array



Marcick
- 14th April 2015, 12:38
Hi all,
I'm using this code to load an array with a certain text string


inbuff VAR BYTE(100)
arraywrite inbuff,["Sample test string"]

I have many different string in variuos parts of the program and this code consumes a lot of space, so I would like to optimize it using macros .

It's easy to store the string in code space and then with a macro retrieve the address and read it:



ROM_String1: PokeCode "Sample test string",0


; macro to retrieve the address

@getaddr macro Text, Addr
@ movlw low Text
@ movwf Addr
@ movlw High Text
@ movwf Addr + 1
@ endm


; code
@ getaddr _ROM_String1, _w0
repeat
peekcode w0, x
if x then
debug x
w0=w0+2
endif
until x=0 ' print till end of string '0'

Sb00:
.....



Now I have some difficulties to continue: instead of print the string, I need to store it in RAM, the same things that does ArrayWrite.
So the macro should be modified to accept as parameters, the source ROM string and the destination address in RAM
Something like


@ LoadStr _ROM_CfgString, _inbuff

So calling the macro I can specify any string stored in ROM and any RAM destination where to put it.
Could anybody help me to complete the macro ?
Thanks
Marco

HenrikOlsson
- 14th April 2015, 12:46
Hi,
How about:
inBuff VAR BYTE[100]
i VAR BYTE

i = 24 ' Start putting the string at inBuff[24] for example
repeat
peekcode w0, x
if x then
inBuff[i] = x
debug x
w0=w0+2
endif
i=i+1
until x=0

/Henrik.

Marcick
- 14th April 2015, 12:55
Hi Enrik, thanks,
inbuff should be a parameter passed to the macro and not a fixed address.

I have something like this:


inBuff VAR BYTE[100]
Outbuff VAR BYTE[100]
Testbuff VAR BYTE[200]
etc etc


I want that Inbuff, Outbuff, TestBuff is a parameter of the macro, so the string can be written anywhere

HenrikOlsson
- 14th April 2015, 13:24
I'm not very good at assembly language but can't you just pass it the variable name, like _inBuff, which would be the "start adress" of the array?

/Henrik.

Marcick
- 15th April 2015, 09:17
There must be some awful mistakes, I can't get this code working


#CONFIG
CONFIG OSC = IRCIO67 ;Internal oscillator block, port function on RA6 and RA7
CONFIG WDT = ON ;WDT enabled
CONFIG WDTPS = 64 ;1:64
CONFIG PWRT = ON ;PWRT enabled
CONFIG BOREN = BOHW ;Brown-out Reset enabled in hardware only (SBOREN is disabled)
CONFIG BORV = 3 ;VBOR set to 2.1V
CONFIG MCLRE = OFF ;RE3 input pin enabled; MCLR disabled
CONFIG LPT1OSC = OFF ;Timer1 configured for higher power operation
CONFIG PBADEN = OFF ;PORTB<4:0> pins are configured as digital I/O on Reset
CONFIG XINST = OFF ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
CONFIG LVP = OFF ;Single-Supply ICSP disabled
CONFIG STVREN = ON
CONFIG CP0 = ON
CONFIG CP1 = ON
CONFIG CP2 = ON
CONFIG CP3 = ON
#ENDCONFIG

Define USE_LFSR 1
DEFINE OSC 8
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 4
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0

OSCCON =%01110000
Led VAR PORTB.3
inbuff VAR BYTE[100]
x VAR BYTE
y VAR BYTE
LS0 VAR Word
LS1 VAR Word

goto Start

ASM
LoadString macro Text, Dest
movlw low Text
movwf _LS0
movlw High Text
movwf _LS0 + 1
movlw low Dest
movwf _LS1
movlw High Dest
movwf _LS1 + 1
L?CALL _Lstr
endm
ENDASM

Lstr:
y=0
repeat
peekcode LS0, x
LS1(y)=x
y=y+1
LS0=LS0+2
until x=0
return


Start:
@ LoadString _ROM_CfgString, inbuff
debug str inbuff\100,13,10
pause 500
high led
pause 500
low led
goto start

end

ROM_CfgString: PokeCode "This a test string",0

richard
- 15th April 2015, 10:01
try a forum search "embedded string"

Marcick
- 15th April 2015, 10:49
What I can't find how to do, is to pass to the macro the address of an array.

richard
- 15th April 2015, 11:15
as henrik said
inBuff VAR BYTE[100]


in asm the array address is
_inBuff

or give a new name

ASM
mybuff =_inBuff
ENDASM
note label in col 0

make sure you don't overrun your buffer

Marcick
- 15th April 2015, 13:22
Hi, I undestand, but I can't put togheter something of working. If you want to have a look to this code, you'll see in my comments where are my doubts.
Anyway the code doesn't compile and give errors ...



inbuff VAR BYTE[100]
x VAR BYTE
y VAR BYTE
LS0 VAR WORD
LS1 VAR WORD

Lp1:
@ LoadInbuff _ROM_CfgString, _Inbuff ; I would like to transfer the ROM string in RAM Inbuff
debug str inbuff\100,13,10
goto lp1

ASM
LoadInbuff macro Text, Dest
CHK?RP _LS0
movlw low Text ; here I load in LS0 the ROM address of the source string
movwf _LS0
movlw High Text
movwf _LS0 + 1
CHK?RP _LS1 ; here I suppose to load in LS1 the address of the destination buffer
movlw low Dest ; but I feel something is wrong
movwf _LS1
movlw High Dest
movwf _LS1 + 1
L?CALL _Lstr
endm
ENDASM

Lstr:
y=0
do
peekcode LS0, x
; --->>> what to do here to write the value x to the destination buffer ??
if x=0 then exit
y=y+1
LS0=LS0+2
loop
return



ROM_CfgString: PokeCode "This a test string",0

richard
- 15th April 2015, 13:46
add this to your code
ARRAYWRITE inbuff,3,,["123"]

and then look at the lst file generated

see how arraywrite works

01487 LIST
000004 C00C FFE9 01488 ARRAYWRITE movff R5, FSR0L ; Put the array pointer into FSR0
000008 C00D FFEA 01489 movff R5 + 1, FSR0H
00000C 6EEE 01490 movwf POSTINC0 ; Put the char into the array and bump up the address
00000E CFE9 F00C 01491 movff FSR0L, R5 ; Save new pointer
000012 CFEA F00D 01492 movff FSR0H, R5 + 1


the array address goes in like this



C:\PBP3\EXAMPLES\MARCICK.PBP 00074 ARRAYWRITE inbuff,3,,["123"]
00192 ARRAYWRITENAME?B _inbuff
M MOVE?CW _inbuff, R5
M ifdef USE_LINKER
M CHK?RP R5
M movlw low (_inbuff)
M movwf R5
M movlw high (_inbuff)
M movwf (R5) + 1


you need to emulate this using your own vars don't use r5 of course


interrupts will need to be disabled too


ps the forum totally destroys white space you need to look at your xxx.lst file to make it out properly

Marcick
- 15th April 2015, 14:14
Richard,
Thanks for your time but .. if you have some more ... could you please take my sample above and correct it so it works ?
It's two days I'm turning crazy.
Anyway thank you
Marco

richard
- 16th April 2015, 01:46
'pic18f45k20
'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2015 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 4/14/2015 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2015 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 4/14/2015 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
#CONFIG
CONFIG FOSC = INTIO67
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRT = OFF
CONFIG BOREN = SBORDIS
CONFIG BORV = 18
CONFIG WDTEN = ON
CONFIG WDTPS = 512
CONFIG CCP2MX = PORTC
CONFIG PBADEN = OFF
CONFIG LPT1OSC = OFF
CONFIG HFOFST = ON
CONFIG MCLRE = ON
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG XINST = OFF
CONFIG DEBUG = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
CONFIG WRT0 = OFF
CONFIG WRT1 = OFF
CONFIG WRT2 = OFF
CONFIG WRT3 = OFF
CONFIG WRTC = OFF
CONFIG WRTB = OFF
CONFIG WRTD = OFF
CONFIG EBTR0 = OFF
CONFIG EBTR1 = OFF
CONFIG EBTR2 = OFF
CONFIG EBTR3 = OFF
CONFIG EBTRB = OFF
#ENDCONFIG


define OSC 64
osccon=$70 '64 mhz
OSCTUNE.6=1



pause 2000

Serout2 PORTb.7,84,["ready",13,10]

Addr var word
Char var byte
cnt var byte
inbuff var byte[30]
buff var byte[30]
Clear





goto StartLoop ' Required

String1:
@ da "This is a string",0

AnotherString:
@ da "Here is another string",0

'------------GetAddress Macro - Location insensitive -------------------------
ASM
GetAddress macro Label, Wout ; Returns the Address of a Label as a Word
CHK?RP Wout
movlw low Label
movwf Wout
movlw High Label
movwf Wout + 1
endm
ENDASM


StartLoop: ' This loop repeats continuously just as a test.
@ GetAddress _String1, _Addr ' Get address of String
cnt=0
gosub StringOut ' Send the String
Serout2 PORTb.7,84, [13,10] ' New Line
Serout2 PORTb.7,84, ["inbuff ",str inbuff\cnt ,13,10] ' New Line


@ GetAddress _AnotherString, _Addr ' Get address of String
cnt=0
gosub StringOut ' Send the String
Serout2 PORTb.7,84,[13,10] ' New Line
Serout2 PORTb.7,84, ["inbuff ",str inbuff\cnt ,13,10] ' New Line
pause 500
goto StartLoop ' Repeat


StringOut: ' Send the string out via Hserout
Readcode Addr, Char ' Get a character
if Char = 0 then StringDone ' Look for Null char, Stop if found
buff[cnt]=char
cnt=cnt+1
Serout2 PORTb.7,84, [Char] ' Send char
Addr = Addr + 1 ' Point to next character
goto StringOut ' Continue with rest of the string
StringDone:
ARRAYWRITE inbuff,cnt,,[str buff]
return


end

I do it this way , and use the bounds checking features of arraywrite

Marcick
- 16th April 2015, 07:59
Well, any help is appreciated, so thank you anyway, but this is not what I'm asking.
My intent is not to use Arraywrite because consumes a lot of space.
With this sample code that now works I transfer a ROM string to an array, but I want also the destination array to be a parameter passed to the macro.
So with a single macro I could transfer to inbuff or testbuff or any buffer Is declared.



Define USE_LFSR 1
DEFINE OSC 8
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 4
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0

OSCCON =%01110000

inbuff VAR BYTE[100]
x VAR BYTE
y VAR BYTE
LS0 VAR WORD
LS1 VAR WORD
goto Lp1

ASM
LoadInbuff macro Text
CHK?RP _LS0
movlw low Text ; here I load in LS0 the ROM address of the source string
movwf _LS0
movlw High Text
movwf _LS0 + 1
L?CALL _Lstr
endm
ENDASM

Lstr:
y=0
do
peekcode LS0, x
inbuff(y)=x
if x=0 then exit
y=y+1
LS0=LS0+2
loop
return


Lp1:
@ LoadInbuff _ROM_CfgString
debug str inbuff\100,13,10
goto lp1


ROM_CfgString: PokeCode "This a test string",0

richard
- 16th April 2015, 10:42
I understand but pbp does not allow pointers like in C . the only way I can see for this to be done is to have either a user cmd or asm code that actually mimics arraywrite's array loading method anyway .I'm sure something like that could be made accept a pointer to the array to be loaded .
I'm just having trouble seeing any point to this. my prog with arraywite 1041 bytes , with arraywrite commented out 951 bytes ,surely 90 bytes is pretty good I'm sure my asm attempts would be much worse than that
I have to ask why do this at all . I can't see a good reason to read a string from flash into ram ,surely its best shuffled off to its destination directly . if it needs to be altered before its used was it really a good move putting it in flash memory in the first place.
have a look at this thread post#50 where I update portions of an array with EXT modifiers and arraywrite . the fixed unchanging parts could be in flash
http://www.picbasic.co.uk/forum/showthread.php?t=19420
perhaps if you provide a little more detail .....

Marcick
- 17th April 2015, 08:07
Hi Richard,
yes, strings need to be altered before use.
Well, I had about 3K free on 64k (PIC18F4680) and needed to add more code, so I was looking for some tricks to save space and make a diet to the actual code.
I have noted that if I substitute an arraywrite entry (for a string of about 100 char) with the method above, I save around 600 bytes of code. I have about 10 difefrent strings, so the total saved space is several KB.
To be honest I can't understand why there is so much difference between the two methods ....
Also I have noted this: in a blank project like the sample above, the difference between the two methods is about 150 bytes. Inside my 63KB project, the difference is more than 600 bytes.
So it probably depends where the instruction and the buffer are located (bank switching, etc). For thei sreason I wonder also if the method above with the macro is correct or can bring to unexpected behavours in some situations .....
For example: why did you say before "interrupts need to be disabled" ? Context is fully saved and restored in the interrupt routines. Also I use "PBP Instant Interrupt" of that great Darrel that should be bullet-proof.
Marco

richard
- 17th April 2015, 08:39
why did you say before "interrupts need to be disabled

I was thinking that if were to read the flash using TABLPU reg and index through the ram array using fsr0 then I'm not convinced that method is interrupt proof
but your not doing that anyway


I expect you realise that pokecode uses twice the memory to store a string compared to da

Marcick
- 17th April 2015, 09:31
well, I was not understanding why I had to increment the pointer by two when reading data ...
I have subsituted now pokecode with da and peekcode with readcode and saved another kb .. thanks !
Marco

richard
- 17th April 2015, 11:44
this might do what you want
note with the da method char values must be<128 ie 7 bit ascii
just noticed I left an arraywrite in there it can/should be removed and the bit setting the 0 at end of the string was fixed too


'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2015 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 4/14/2015 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2015 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 4/14/2015 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
#CONFIG
CONFIG FOSC = INTIO67
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRT = OFF
CONFIG BOREN = SBORDIS
CONFIG BORV = 18
CONFIG WDTEN = ON
CONFIG WDTPS = 512
CONFIG CCP2MX = PORTC
CONFIG PBADEN = OFF
CONFIG LPT1OSC = OFF
CONFIG HFOFST = ON
CONFIG MCLRE = ON
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG XINST = OFF
CONFIG DEBUG = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
CONFIG WRT0 = OFF
CONFIG WRT1 = OFF
CONFIG WRT2 = OFF
CONFIG WRT3 = OFF
CONFIG WRTC = OFF
CONFIG WRTB = OFF
CONFIG WRTD = OFF
CONFIG EBTR0 = OFF
CONFIG EBTR1 = OFF
CONFIG EBTR2 = OFF
CONFIG EBTR3 = OFF
CONFIG EBTRB = OFF
#ENDCONFIG


define OSC 64
osccon=$70 '64 mhz
OSCTUNE.6=1



pause 2000

Serout2 PORTb.7,84,["ready",13,10]

Addr var word
Char var byte
cnt var word
inbuff var byte[30]
buff var byte[30]
Clear





goto StartLoop ' Required

String1:
@ da "This is a string",0

AnotherString:
@ da "Here is another string",0

'------------GetAddress Macro - Location insensitive -------------------------
ASM
GetAddress macro Label, Wout ; Returns the Address of a Label as a Word
CHK?RP Wout
movlw low Label
movwf Wout
movlw High Label
movwf Wout + 1
endm
ENDASM

ASM
Loadb macro buffer
CHK?RP _cnt
movlw low buffer
movwf FSR2L
movlw High buffer
movwf FSR2H

endm
ENDASM





ARRAYWRITE buff,["123"]

StartLoop: ' This loop repeats continuously just as a test.
@ GetAddress _String1, _Addr ' Get address of String
@ Loadb _inbuff
CNT=0

gosub StringOut ' Send the String

Serout2 PORTb.7,84, ["inbuff "," c ",hex CNT," ",str inbuff\CNT ,13,10] ' New Line



@ GetAddress _AnotherString, _Addr ' Get address of String
@ Loadb _inbuff
CNT=0

gosub StringOut ' Send the String

Serout2 PORTb.7,84, ["inbuff "," c ",hex CNT," ",str inbuff\CNT ,13,10] ' New Line
pause 500
goto StartLoop ' Repeat


StringOut: ' Send the string out via Hserout
Readcode Addr, Char ' Get a character
if Char = 0 then StringDone ' Look for Null char, Stop if found
bfill:
asm
CHK?RP _Char
movf _Char ,w

movwf POSTINC2

endasm



cnt=cnt+1
Addr = Addr + 1 ' Point to next character
goto StringOut ' Continue with rest of the string


StringDone:
asm

movlw 0

movwf INDF2
endasm
return






end

Marcick
- 17th April 2015, 14:46
Wow, thanks !
Need a break now. I'll let you know tomorrow or monday, as I test everything.
Marco

richard
- 17th April 2015, 15:40
a cleaned up version

richard
- 18th April 2015, 03:33
an even better way

Marcick
- 18th April 2015, 07:58
Hi again,
thanks for the cleaned and full working sample.
I'm much scared about "its not interrupt proof , other pbp functons may and do use FSR2 and TBLPTR" ....
I'll try to ask Melabs if it's safe or not.
Marco

richard
- 18th April 2015, 10:43
marco
I will give you three options
1. intcon.7=0 ' I'm assuming it was set
@ Flash2Ram _buff,_String1' Get a String from flash memory
intcon.7=1
2 . examine your .lst file and determine if any of your isr routines use FSR2 or TBLPTR
if none of them do then don't worry (this is the most likely case)
3. there are two other indirect addressing pointers FSR0 and FSR1 maybe one of them would be free

as groucho would say if you don't like these I have others

this is the best I can offer without seeing your code

HenrikOlsson
- 18th April 2015, 11:35
Hi,
Looking at the DT-INTS_18 file Darrel is declaring variables for saving the FSR's:

fsave0H var WORD BANK0 SYSTEM ' locations for FSR registers
fsave1H var WORD BANK0 SYSTEM
fsave2H var WORD BANK0 SYSTEM
fsave0L var WORD BANK0 SYSTEM ' low priority FSR locations
fsave1L var WORD BANK0 SYSTEM
fsave2L var WORD BANK0 SYSTEM

There's also a section towards the end that says

; ---[See if we need to save TBLPTR]------------------------------------------
Which sets a flag SAVE_TBLPTR = 1 when any PBP command that uses TBLPTR is used and in the ReEnterPBP-18 file he's declaring variables for TBLPTR like:

TBLPTRU_H VAR HP_Vars[31]
TBLPTRU_SaveH VAR TBLPTRU_H.lowbyte
TBLPTR_H VAR HP_Vars[32]
TBLPTRH_SaveH VAR TBLPTR_H.highbyte
TBLPTRL_SaveH VAR TBLPTR_H.lowbyte

And then, further down in that file:

@ if Save_TBLPTR == 1
TBLPTRU_SaveH = TBLPTRU
TBLPTRH_SaveH = TBLPTRH
TBLPTRL_SaveH = TBLPTRL
@ endif

So, to me, it looks like DT-INTS is handling all that stuff and you would/should only need to worry about it of you're using the FSR's or TBLPTR in any other ASM routines which would mean that DT-INTS does't detect them being used and therefor doesn't save them.

Of course I may have it all wrong in which case I hope someone who can understand the ASM in DT-Ints better then me can explain what's going on.

/Henrik.

richard
- 18th April 2015, 12:06
thanks for that henrik I never thought to look at how dt ints works . dt's code leaves nothing to chance ,I'm left humbled again

Marcick
- 18th April 2015, 13:47
Guys,
about Darrel code I could put my hand on fire.
about my code I can bet there are bugs ...
but with your help now I have everything clear and know where problems can be or not. I have DTint and other ISR where I'll take care about FSR and TBLPTR.
so, many thanks again for your support !
bye
Marco

Marcick
- 20th April 2015, 13:23
Hi Richard,
maybe I'm doing some confusion and about to say something of funny, but I have a doubt:
How do you ensure in this code that you are in the correct bank reading the address of "buffer" ?


ASM
Flash2Ram macro buffer, msg ; Fills the buffer from flash msg
movlw UPPER msg
movwf TBLPTRU
movlw HIGH msg
movwf TBLPTRH
movlw LOW msg
movwf TBLPTRL
movlw low buffer
movwf FSR2L
movlw High buffer
movwf FSR2H
L?CALL _bfill
endm
ENDASM

richard
- 20th April 2015, 14:17
buffer does not actually exist its just a label in the macro , when assembled
@ Flash2Ram _buff , _String1 , produces




000168 0E00 M movlw UPPER _String1
0016A 6EF8 M movwf TBLPTRU
00016C 0E01 M movlw HIGH _String1
00016A 6EF8 M movwf TBLPTRU
00016C 0E01 M movlw HIGH _String1
00016E 6EF7 M movwf TBLPTRH
000170 0E3E M movlw LOW _String1
000172 6EF6 M movwf TBLPTRL
000174 0E1A M movlw low _buff
000176 6ED9 M movwf FSR2L
000178 0E00 M movlw High _buff
00017A 6EDA M movwf FSR2H
M L?CALL _bfill

the label "buffer" is replaced with the symbol of the intended target
at no stage do we actually write directly to the "buffer" we simply load its address (from the symbol table) into the fsr regs
the bfill subroutine then fills the "buffer" indirectly via the fsr regs
macro's are not subroutines they are just another shortcut way to save typing, every time the macro is encountered the real code as above is inserted into your program

Marcick
- 21st April 2015, 05:54
Yes, but while _String1 is a fixed address that point to a univoque ROM location, isn't _buff a RAM location that points to different register according to the current bank ?
Marco

richard
- 21st April 2015, 07:13
evidently I'm not explaining it well
we never write directly to _buff we do it 'indirectly' via the 16 bit full address in fsr2 its called INDIRECT ADDRESSING read the chapter in the data sheet ,(this is how pic18's have arrays that can be bigger than a ram bank)
bank select is not applicable to indirect addressing

richard
- 21st April 2015, 07:27
observe symbol table


inbuff var byte[30]
buff var byte[30] $500



SYMBOL TABLE
LABEL VALUE

_STVREN_OFF_4L 000000FE
_STVREN_ON_4L 000000FF
_StartLoop 00000168
_String1 0000013E
_String2 00000150
_TRISH 00000F94
_TRISL 00000F93
_WDTEN_OFF_2H 000000FE
_WDTEN_ON_2H 000000FF
_WDTPS_1024_2H 000000F5
_WDTPS_128_2H 000000EF
_WDTPS_16384_2H 000000FD
_WDTPS_16_2H 000000E9
_WDTPS_1_2H 000000E1
_WDTPS_2048_2H 000000F7
_WDTPS_256_2H 000000F1
_WDTPS_2_2H 000000E3
_WDTPS_32768_2H 000000FF
_WDTPS_32_2H 000000EB
_WDTPS_4096_2H 000000F9
_WDTPS_4_2H 000000E5
_WDTPS_512_2H 000000F3
_WDTPS_64_2H 000000ED
_WDTPS_8192_2H 000000FB
_WDTPS_8_2H 000000E7
_WRT0_OFF_6L 000000FF
_WRT0_ON_6L 000000FE
_WRT1_OFF_6L 000000FF
_WRT1_ON_6L 000000FD
_WRT2_OFF_6L 000000FF
_WRT2_ON_6L 000000FB
_WRT3_OFF_6L 000000FF
_WRT3_ON_6L 000000F7
_WRTB_OFF_6H 000000FF
_WRTB_ON_6H 000000BF
_WRTC_OFF_6H 000000FF
_WRTC_ON_6H 000000DF
_WRTD_OFF_6H 000000FF
_WRTD_ON_6H 0000007F
_XINST_OFF_4L 000000BF
_XINST_ON_4L 000000FF
__18F45K20 00000001
_bfill 0000022C
_buff 00000500
_inbuff 0000001A
main 000000EA
pauseloop 000000A6
pauseusloop 000000C2
ser2delay 0000007C
serout2bit 0000004E
serout2done 0000004A
serout2loop 00000022
serout2norm 00000068

richard
- 21st April 2015, 07:32
buff var byte[30] $4f0 ; buff is now straddles banks 4 and 5

_buff 000004F0 symbol table

code still works perfectly as expected

Marcick
- 21st April 2015, 08:24
Richard,
the source of my doubts is that I have some unexpected behaviours and I'm trying to understand where is the problem.
Watching the program memory, I found some "00" chars here and there in the middle of the string
Lets' say the string "Hello",0 when I look the program memory is 48 65 6C 00 6C 6F 00
I'm discovering now that the directive "da" is only for PIC12/16 and not for PIC18

http://ww1.microchip.com/downloads/en/DeviceDoc/33014J.pdf

I think I should use "db" or "data", I'm trying to understand

"db" seems to work fine

richard
- 21st April 2015, 08:48
how are you looking at the pgm memory , I think something is not right

for me the da and data directives produce exactly the same result , I left the da directive in, thinking I might try the code on a pic16f1825 for a learning experience , for 7 bit ascii data either will do (pic 18's can store 2x8 bit ,pic 16's 2x7bit )

the relevant listings

0
0013E 6854 7369 6920 00199 data "This is a string",0
2073 2061 7473
6972 676E 0000



00013E 6854 7369 6920 00199 da "This is a string",0
2073 2061 7473
6972 676E 0000

HenrikOlsson
- 21st April 2015, 08:57
I think it might have something to do with the number of bytes (odd or even) in the string.
In both of Richards examples there's an even number of bytes (16 and 22) but your Hello string there's an odd number of bytes (5). I seem to remember an issue with this being discussed in one of the 'Strings in codespace' threads some years ago.

/Henrik.

richard
- 21st April 2015, 09:05
odd length strings , wastes space but not a problem


00013E 6854 7369 6920 00199 data "This is a string1",0
2073 2061 7473
6972 676E 0031
0000

00013E 6854 7369 6920 00199 da "This is a string1",0
2073 2061 7473
6972 676E 0031
0000

richard
- 21st April 2015, 09:09
00013E 6548 6C6C 006F 00199 da "Hello",0
0000

richard
- 21st April 2015, 09:15
there's another little cheat if all the strings are odd length the 0 terminator is redundant

Marcick
- 21st April 2015, 09:17
Found the problem.

I have a string like this:

say "hello"

I use this format do declare it, the same format I was using with arraywrite


@ da "say",34,"hello",34,0

The result in program memory is that before each char 34 is added a char 00
If I use "db" instead the result is correct.
The pdf I linked before says that "da" is not for PIC18

richard
- 21st April 2015, 09:22
where ?
da – Data ASCII.
Generates a packed 14-bit number representing two 7-bit ASCII characters.

richard
- 21st April 2015, 09:28
this works
@ da "say \"Hello\"\0"

Marcick
- 21st April 2015, 09:37
where ?
da – Data ASCII.
Generates a packed 14-bit number representing two 7-bit ASCII characters.

4.14 da – STORE STRINGS IN PROGRAM MEMORY (PIC12/16 MCUs)

Funny, but if you try it you'll see the unwanted 00 added

db is ok

richard
- 21st April 2015, 10:47
db is definitely an easier way to pack a mixed string data statement like "say",34,"hello",34,0 . funny I could never see the point of db until now

Marcick
- 21st April 2015, 11:11
PICs always have hidden surprises ....

Ok, understood also indirect addressing now, thanks for your patience :-)

Ruben Pena
- 23rd April 2015, 20:58
Hi:
I use this routine to send eeprom stored msg's to display LCD.
It can be modified to send then to a string...
I hope this helps...
'************************************************* ***************
'USED VARS:

SDAT VAR PORTD.1 'I2C EEPROM DATA 'ADJUST TO USED PINS AND
SCLK VAR PORTD.0 'I2C EEPROM CLOCK 'MAKE THEM INPUTS IN USED TRIS REG.
CHAR VAR BYTE
SLAVE VAR BYTE
EEADDR VAR WORD
SLAVE = $A0 'EEPROM SLAVE ADDRESS
'***** SUB TO DISPLAY MSGS STORED IN EEPROM ****************
MSG_DISP:
GOSUB CLRDISP 'CLEAR SCREEN
MSG:
LEENXT: I2CREAD SDAT,SCLK,SLAVE,EEADDR,[CHAR] 'SIN CLEAR
IF CHAR => $80 THEN
LCDOUT $FE,CHAR
GOTO INCADD
ENDIF
IF CHAR <> 0 THEN
LCDOUT CHAR
INCADD: EEADDR = EEADDR + 1
GOTO LEENXT
ENDIF
RETURN
'************************************************* *************
'TO CALL THE ROUTINE:
'SET EEPROM ADDRES:
'YOUR STRING CAN HAVE ANY LENGTH AND MUST BE TERMINATED WITH A NULL CHAR
'"00"
'*********************************************
EEADDR = $0350 'WHEREVER YOUR STRING STARTS
GOSUB MSG_DISP
'*********************************************
' YOU MUST USE AN EEPROM WITH WORD ADDRESS (25LC32A,OR BIGGER)
'PROGRAMM YOUR EEPROM WITH MSGS ENDED WITH 00 (NULL) AND TAKE NOTE OF
'THE START ADDRESSES.
'AND THATS ALL...
Greetings...
Ruben de la Pena V.