Double passing of strings
Moderators: David Barker, Jerry Messina
-
- Posts: 113
- Joined: Mon Jan 11, 2010 10:39 pm
- Location: Chesterfield
Double passing of strings
Working on some display driver routines I'm finding some odd behaviour with strings.
I have a function which returns the width of a character and a second function with calls this multiple times for a string and returns the width of the string. (In pixels)
I'm trying to write a sub to centralise a string on the display. However, I can't get it to centralise properly and when I do some debugging I am finding that for longer strings the width returned is garbage.
However, if I copy the same code to my main program all works as expected. The issue seems to be that I'm passing a string to the CentralStr routine which is passing it on to the WidthOfStr routine and somehow in this double-passing things are getting mangled. It works OK for short strings (< about 6 characters) but anything longer, and especially over 10 characters returns an incorrect width and therefore the string doesn't centralise properly.
Is this a known issue with Swordfish or can anyone suggest anything I may be doing wrongly?
I have a function which returns the width of a character and a second function with calls this multiple times for a string and returns the width of the string. (In pixels)
I'm trying to write a sub to centralise a string on the display. However, I can't get it to centralise properly and when I do some debugging I am finding that for longer strings the width returned is garbage.
However, if I copy the same code to my main program all works as expected. The issue seems to be that I'm passing a string to the CentralStr routine which is passing it on to the WidthOfStr routine and somehow in this double-passing things are getting mangled. It works OK for short strings (< about 6 characters) but anything longer, and especially over 10 characters returns an incorrect width and therefore the string doesn't centralise properly.
Is this a known issue with Swordfish or can anyone suggest anything I may be doing wrongly?
-
- Posts: 113
- Joined: Mon Jan 11, 2010 10:39 pm
- Location: Chesterfield
The code is below. I've adapted the font format slightly.
For debugging I've altered the CentralStr routine to:
If, for example, I pass 10 spaces (character width 3 pixels) I get the correct value of 40 returned. (3 pixels + 1 pixel padding x 10). However, if I pass 15 spaces I get a width of 47. Similar problems occur with other text strings, some start hitting problems with fewer characters than others, it doesn't seem consistent.
Code: Select all
// Find the width of a character. Right hand padding defaults to 1 if not specified.
// Remember if using this to supply a fixed width to WriteChar or WriteStr that you need to specify zero padding either here or in the write command.
Public Function WidthOfChar(ByRefConst FontMap() As Byte, CNo As Byte, CPad As Byte = 1) As Byte
Dim w, l As Word
If CNo < FontMap(2) Then CNo = FontMap(2) EndIf // Set limits on the character number.
If CNo > FontMap(3) Then CNo = FontMap(3) EndIf // Limit to the number of characters defined.
CNo = CNo - FontMap(2) // Remove ASCII offset. We will end up with a character reference between 0 and the number of chrs defined.
w = CNo * 2
w = w + FontOffset
l.byte0 = FontMap(w)
l.byte1 = FontMap(w+1)
result = FontMap(l) + CPad
End Function
// Find the width of a full string of characters
Public Function WidthOfStr(ByRefConst FontMap() As Byte, CStr As String) As Byte
Dim sw, sl As Byte
sw = 0
sl = 0
While CStr(sl) <> null
sw = sw + WidthOfChar(FontMap, CStr(sl))
Inc(sl)
Wend
result = sw
End Function
Public Sub CentralStr(ByRefConst Fontmap() As Byte, CStr As String, YPage As Byte)
Dim w As Byte
w = D_COLUMNS - WidthOfStr(FontMap, CStr)
w = w / 2
w = w + D_OFFSET
WriteStr(Fontmap, CStr, w, YPage)
End Sub
Code: Select all
Public Sub CentralStr(ByRefConst Fontmap() As Byte, CStr As String, YPage As Byte)
Dim w As Byte
w = WidthOfStr(FontMap,CStr)
WriteStr(FontMap, DecToStr(w),0,YPage)
End Sub
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
-
- Posts: 113
- Joined: Mon Jan 11, 2010 10:39 pm
- Location: Chesterfield
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
-
- Posts: 113
- Joined: Mon Jan 11, 2010 10:39 pm
- Location: Chesterfield
Not sure how much code you will need to recreate this. If you are able to do without the output routine and read the returned width elsewhere then this might be enough:
Code: Select all
Public Const MediumFont() As Byte = (
15, 15, 32, 90,
$7A, $00, // Space
$8B, $00, // !
$90, $00, // "
$9B, $00, // #
$B4, $00, // $
$C5, $00, // %
$E2, $00, // &
$F7, $00, // '
$FC, $00, // (
$07, $01, // )
$12, $01, // *
$1F, $01, // +
$30, $01, // ,
$35, $01, // -
$42, $01, // .
$47, $01, // /
$52, $01, // 0
$63, $01, // 1
$70, $01, // 2
$81, $01, // 3
$92, $01, // 4
$A3, $01, // 5
$B4, $01, // 6
$C5, $01, // 7
$D6, $01, // 8
$E7, $01, // 9
$F8, $01, // :
$01, $02, // ;
$06, $02, // <
$17, $02, // =
$28, $02, // >
$39, $02, // ?
$4A, $02, // Solid arrow (was @
$59, $02, // A
$70, $02, // B
$83, $02, // C
$98, $02, // D
$AD, $02, // E
$C0, $02, // F
$D3, $02, // G
$EA, $02, // H
$FF, $02, // I
$04, $03, // J
$13, $03, // K
$28, $03, // L
$39, $03, // M
$54, $03, // N
$69, $03, // O
$80, $03, // P
$93, $03, // Q
$AA, $03, // R
$C1, $03, // S
$D4, $03, // T
$E9, $03, // U
$FE, $03, // V
$15, $04, // W
$34, $04, // X
$4B, $04, // Y
$64, $04, // Z
$08, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, ' Code for char
$02, $FF, $67, $FF, $67, ' Code for char !
$05, $1F, $00, $1F, $00, $00, $00, $1F, $00, $1F, $00, ' Code for char "
$0C, $00, $06, $30, $76, $B0, $7F, $F8, $1F, $FF, $06, $37, $06, $30, $76, $B0, $7F, $F8, $1F, $FF, $06, $37, $06, $30, $00, ' Code for char #
$08, $3C, $18, $7E, $38, $E7, $70, $C3, $60, $FF, $7F, $83, $61, $8E, $3F, $0C, $1F, ' Code for char $
$0E, $3C, $00, $42, $00, $42, $40, $42, $70, $3C, $3C, $00, $0F, $80, $03, $E0, $00, $78, $00, $1E, $1E, $07, $21, $01, $21, $00, $21, $00, $1E, ' Code for char %
$0A, $00, $1E, $00, $3F, $9C, $71, $FF, $60, $E3, $60, $E3, $61, $3F, $37, $1E, $1F, $00, $3B, $00, $20, ' Code for char &
$02, $1F, $00, $1F, $00, ' Code for char '
$05, $E0, $03, $F8, $0F, $1E, $3C, $07, $70, $01, $40, ' Code for char (
$05, $01, $40, $07, $70, $1E, $3C, $F8, $0F, $E0, $07, ' Code for char )
$06, $06, $00, $34, $00, $1F, $00, $1F, $00, $34, $00, $06, $00, ' Code for char *
$08, $80, $01, $80, $01, $80, $01, $F0, $0F, $F0, $0F, $80, $01, $80, $01, $80, $01, ' Code for char +
$02, $00, $58, $00, $38, ' Code for char ,
$06, $80, $01, $80, $01, $80, $01, $80, $01, $80, $01, $80, $01, ' Code for char -
$02, $00, $30, $00, $30, ' Code for char .
$05, $00, $38, $80, $3F, $F8, $07, $7F, $00, $07, $00, ' Code for char /
$08, $F8, $0F, $FE, $3F, $07, $70, $03, $60, $03, $60, $07, $70, $FE, $3F, $F8, $0F, ' Code for char 0
$06, $00, $00, $30, $00, $18, $00, $0C, $00, $FF, $7F, $FF, $7F, ' Code for char 1
$08, $0C, $60, $0E, $78, $07, $6C, $03, $66, $03, $63, $C7, $61, $FE, $60, $3C, $60, ' Code for char 2
$08, $0C, $18, $0E, $38, $07, $70, $C3, $60, $C3, $60, $E7, $71, $BE, $3F, $1C, $1F, ' Code for char 3
$08, $00, $07, $C0, $07, $F0, $06, $3C, $06, $0F, $06, $FF, $7F, $FF, $7F, $00, $06, ' Code for char 4
$08, $F0, $18, $FF, $38, $6F, $70, $63, $60, $63, $60, $E3, $70, $C3, $3F, $80, $0F, ' Code for char 5
$08, $F8, $0F, $FE, $3F, $C6, $70, $63, $60, $63, $60, $E7, $70, $CE, $3F, $8C, $1F, ' Code for char 6
$08, $03, $00, $03, $00, $03, $78, $83, $7F, $E3, $07, $7B, $00, $0F, $00, $03, $00, ' Code for char 7
$08, $3C, $1F, $FE, $3F, $E7, $71, $C3, $60, $C3, $60, $E7, $71, $FE, $3F, $3C, $1F, ' Code for char 8
$08, $FC, $18, $FE, $39, $87, $73, $03, $63, $03, $63, $87, $31, $FE, $3F, $F8, $07, ' Code for char 9
$04, $00, $00, $0C, $18, $0C, $18, $00, $00, ' Code for char :
$02, $0C, $2C, $0C, $1C, ' Code for char ;
$08, $C0, $01, $C0, $01, $60, $03, $60, $03, $30, $06, $18, $0C, $18, $0C, $0C, $18, ' Code for char <
$08, $30, $06, $30, $06, $30, $06, $30, $06, $30, $06, $30, $06, $30, $06, $30, $06, ' Code for char =
$08, $0C, $18, $18, $0C, $18, $0C, $30, $06, $60, $03, $60, $03, $C0, $01, $C0, $01, ' Code for char >
$08, $0C, $00, $0E, $00, $07, $00, $03, $6E, $83, $6F, $C7, $01, $FE, $00, $3C, $00, ' Code for char ?
$07, $FE, $3F, $FC, $1F, $F8, $0F, $F0, $07, $E0, $03, $C0, $01, $80, $00, ' Code for char @
$0B, $00, $60, $00, $7E, $E0, $1F, $FC, $07, $3F, $06, $03, $06, $3F, $06, $FC, $07, $E0, $1F, $00, $7E, $00, $60, ' Code for char A
$09, $FF, $7F, $FF, $7F, $C3, $60, $C3, $60, $C3, $60, $C3, $60, $E7, $71, $BE, $3F, $1C, $1F, ' Code for char B
$0A, $F0, $07, $FC, $1F, $0E, $38, $07, $70, $03, $60, $03, $60, $03, $70, $0E, $38, $1E, $1E, $18, $06, ' Code for char C
$0A, $FF, $7F, $FF, $7F, $03, $60, $03, $60, $03, $60, $03, $60, $07, $70, $0E, $38, $FC, $1F, $F0, $07, ' Code for char D
$09, $FF, $7F, $FF, $7F, $C3, $60, $C3, $60, $C3, $60, $C3, $60, $C3, $60, $C3, $60, $C3, $60, ' Code for char E
$09, $FF, $7F, $FF, $7F, $C3, $00, $C3, $00, $C3, $00, $C3, $00, $C3, $00, $C3, $00, $03, $00, ' Code for char F
$0B, $F0, $07, $FC, $1F, $0E, $38, $06, $30, $03, $60, $03, $60, $83, $61, $83, $61, $86, $31, $9E, $3F, $98, $1F, ' Code for char G
$0A, $FF, $7F, $FF, $7F, $C0, $00, $C0, $00, $C0, $00, $C0, $00, $C0, $00, $C0, $00, $FF, $7F, $FF, $7F, ' Code for char H
$02, $FF, $7F, $FF, $7F, ' Code for char I
$07, $00, $1C, $00, $3C, $00, $70, $00, $60, $00, $60, $FF, $3F, $FF, $1F, ' Code for char J
$0A, $FF, $7F, $FF, $7F, $80, $01, $E0, $00, $F0, $01, $98, $07, $0C, $0E, $07, $38, $03, $70, $00, $40, ' Code for char K
$08, $FF, $7F, $FF, $7F, $00, $60, $00, $60, $00, $60, $00, $60, $00, $60, $00, $60, ' Code for char L
$0D, $FF, $7F, $FF, $7F, $3F, $00, $FC, $01, $C0, $1F, $00, $7E, $00, $60, $00, $7E, $C0, $1F, $F8, $03, $3F, $00, $FF, $7F, $FF, $7F, ' Code for char M
$0A, $FF, $7F, $FF, $7F, $1E, $00, $78, $00, $E0, $01, $C0, $03, $00, $0F, $00, $3C, $FF, $7F, $FF, $7F, ' Code for char N
$0B, $F0, $07, $FC, $1F, $0E, $38, $07, $70, $03, $60, $03, $60, $03, $60, $07, $70, $0E, $38, $FC, $1F, $F0, $07, ' Code for char O
$09, $FF, $7F, $FF, $7F, $83, $01, $83, $01, $83, $01, $83, $01, $C7, $01, $FE, $00, $7C, $00, ' Code for char P
$0B, $F0, $07, $FC, $1F, $0E, $38, $07, $70, $03, $60, $03, $60, $03, $68, $07, $30, $0E, $38, $FC, $6F, $F0, $43, ' Code for char Q
$0B, $FF, $7F, $FF, $7F, $C3, $00, $C3, $00, $C3, $00, $C3, $01, $43, $03, $67, $0E, $7E, $3C, $3C, $70, $00, $40, ' Code for char R
$09, $3C, $18, $7E, $38, $67, $70, $C3, $60, $C3, $60, $83, $61, $87, $73, $0E, $3F, $0C, $1E, ' Code for char S
$0A, $03, $00, $03, $00, $03, $00, $03, $00, $FF, $7F, $FF, $7F, $03, $00, $03, $00, $03, $00, $03, $00, ' Code for char T
$0A, $FF, $0F, $FF, $3F, $00, $70, $00, $60, $00, $60, $00, $60, $00, $60, $00, $30, $FF, $3F, $FF, $0F, ' Code for char U
$0B, $03, $00, $3F, $00, $FC, $01, $C0, $1F, $00, $7E, $00, $60, $00, $7E, $C0, $1F, $FC, $01, $3F, $00, $03, $00, ' Code for char V
$0F, $07, $00, $FF, $00, $F8, $1F, $00, $7F, $00, $60, $F8, $7F, $FF, $0F, $03, $00, $FF, $0F, $F8, $7F, $00, $60, $00, $7F, $F8, $1F, $FF, $00, $0F, $00, ' Code for char W
$0B, $01, $40, $07, $70, $0E, $38, $3C, $1E, $F0, $07, $C0, $01, $F0, $07, $3C, $1E, $0E, $38, $03, $70, $01, $40, ' Code for char X
$0C, $01, $00, $07, $00, $0E, $00, $3C, $00, $F0, $00, $C0, $7F, $C0, $7F, $F0, $00, $38, $00, $0E, $00, $07, $00, $01, $00, ' Code for char Y
$0A, $03, $70, $03, $78, $03, $6E, $03, $67, $83, $63, $E3, $60, $73, $60, $1B, $60, $0F, $60, $07, $60 ' Code for char Z
)
Code: Select all
#option DISPLAY_COLUMNS = 128
Const D_COLUMNS = DISPLAY_COLUMNS
Const FontOffset = 4 // (Size of the header)
// Find the width of a character. Right hand padding defaults to 1 if not specified.
// Remember if using this to supply a fixed width to WriteChar or WriteStr that you need to specify zero padding either here or in the write command.
Public Function WidthOfChar(ByRefConst FontMap() As Byte, CNo As Byte, CPad As Byte = 1) As Byte
Dim w, l As Word
If CNo < FontMap(2) Then CNo = FontMap(2) EndIf // Set limits on the character number.
IfCNo > FontMap(3) Then CNo = FontMap(3) EndIf // Limit to the number of characters defined.
CNo = CNo - FontMap(2) // Remove ASCII offset. We will end up with a character reference between 0 and the number of chrs defined.
w = CNo * 2
w = w + FontOffset
l.byte0 = FontMap(w)
l.byte1 = FontMap(w+1)
result = FontMap(l) + CPad
End Function
// Find the width of a full string of characters
Public Function WidthOfStr(ByRefConst FontMap() As Byte, CStr As String) As Byte
Dim sw, sl As Byte
sw = 0
sl = 0
While CStr(sl) <> null
sw = sw + WidthOfChar(FontMap, CStr(sl))
Inc(sl)
Wend
result = sw
End Function
Public Sub CentralStr(ByRefConst Fontmap() As Byte, CStr As String, YPage As Byte)
Dim w As Byte
w = D_COLUMNS - WidthOfStr(FontMap, CStr)
w = w / 2
// Add code to output width w here
//WriteStr(Fontmap, CStr, w, YPage)
End Sub
Code: Select all
// Samples of how this routine is called
CentralStr(MediumFont,"01234567890",0)
CentralStr(MediumFont,"ABCDEFGHIJK",0)
CentralStr(MediumFont," ",0)
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
Just to be sure, this code will reproduce the error? Can you put in the code (a) expected result and (b) actual result against each test condition, so that I have some terms of reference. For example,
and so on
> If you are able to do without the output routine
> and read the returned width elsewhere
No, I need a way in your code that displays the output.
Code: Select all
' expected = xx, actual = yy
CentralStr(MediumFont,"01234567890",0)
> If you are able to do without the output routine
> and read the returned width elsewhere
No, I need a way in your code that displays the output.
-
- Posts: 113
- Joined: Mon Jan 11, 2010 10:39 pm
- Location: Chesterfield
I'll have to have a think and see what I can come up with. I have no easily replicable output means, I'm using an OLED on custom hardware for text display so pasting the output routines I use would be of little use to you here. I also don't have an RS232 input so I can't use a terminal instead....
A shame Swordfish doesn't directly support in-circuit debugging.
A shame Swordfish doesn't directly support in-circuit debugging.
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
While you can't do it directly from the SF IDE, it's pretty easy to use MPLAB and either the MPLAB simulator (if you're only interested in algorithm debugging) or one of the ICD programmers like the Pickit2 or Pickit3 to do actual in-circuit source level debugging.A shame Swordfish doesn't directly support in-circuit debugging.
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
It seems that the length allocation for the CStr parameter in WidthOfStr() isn't consistent.
I used four different length strings for the test (all spaces). I tried a few different test cases, and depending on the order in which I declared the calls I got different allocation lengths for CStr. Depending on the order of the test calls, other variables can/are getting stomped on.
BTW - for the given MediumFont, a SPACE character should end up 8 pixels wide + 1 = 9 pixels/char
In case I changed anything while I was looking at it, this is the basic code I used
I used four different length strings for the test (all spaces). I tried a few different test cases, and depending on the order in which I declared the calls I got different allocation lengths for CStr. Depending on the order of the test calls, other variables can/are getting stomped on.
BTW - for the given MediumFont, a SPACE character should end up 8 pixels wide + 1 = 9 pixels/char
Code: Select all
Test #1
----------
CentralStr(MediumFont," ", 0) // w = 10*9=90
CentralStr(MediumFont," ", 0) // w = 20*9=180
CentralStr(MediumFont," ", 0) // w = 15*9=135
CentralStr(MediumFont," ", 0) // w = 90
.func PUB 00003 $005B6 00086 $002B 0021 00162 00170 WidthOfStr
.var CEF $002B 00 0000 0000 U08 FontMap
.var VAL $002F 00 0011 0000 U08 CStr <<<<<<<<<<<<
.var PRI $003A 00 0000 0000 U08 sw
.var PRI $003B 00 0000 0000 U08 sl
.ret PRI $003C 00 0000 0000 U08 WidthOfStr
.end
.proc PUB 00004 $0060C 00048 $0040 0031 00175 00180 CentralStr
.var CEF $0040 00 0000 0000 U08 Fontmap
.var VAL $0044 00 0021 0000 U08 CStr
.var PRI $005A 00 0000 0000 U08 w
.end
Test #2
----------
CentralStr(MediumFont," ", 0) // w = 20*9=180
CentralStr(MediumFont," ", 0) // w = 10*9=90
CentralStr(MediumFont," ", 0) // w = 15*9=135
CentralStr(MediumFont," ", 0) // w = 90
.func PUB 00003 $005B6 00086 $002B 0031 00162 00170 WidthOfStr
.var CEF $002B 00 0000 0000 U08 FontMap
.var VAL $002F 00 0021 0000 U08 CStr <<<<<<<<<<<<
.var PRI $0044 00 0000 0000 U08 sw
.var PRI $0045 00 0000 0000 U08 sl
.ret PRI $0046 00 0000 0000 U08 WidthOfStr
.end
.proc PUB 00004 $0060C 00048 $004A 0031 00175 00180 CentralStr
.var CEF $004A 00 0000 0000 U08 Fontmap
.var VAL $004E 00 0021 0000 U08 CStr
.var PRI $0064 00 0000 0000 U08 w
.end
Test #3
-----------
CentralStr(MediumFont," ", 0) // w = 15*9=135
CentralStr(MediumFont," ", 0) // w = 20*9=180
CentralStr(MediumFont," ", 0) // w = 10*9=90
CentralStr(MediumFont," ", 0) // w = 90
.func PUB 00003 $005B6 00086 $002B 0026 00162 00170 WidthOfStr
.var CEF $002B 00 0000 0000 U08 FontMap
.var VAL $002F 00 0016 0000 U08 CStr <<<<<<<<<<<<<
.var PRI $003F 00 0000 0000 U08 sw
.var PRI $0040 00 0000 0000 U08 sl
.ret PRI $0041 00 0000 0000 U08 WidthOfStr
.end
.proc PUB 00004 $0060C 00048 $0045 0031 00175 00180 CentralStr
.var CEF $0045 00 0000 0000 U08 Fontmap
.var VAL $0049 00 0021 0000 U08 CStr
.var PRI $005F 00 0000 0000 U08 w
.end
In case I changed anything while I was looking at it, this is the basic code I used
Code: Select all
#option _showvar = true
public const MediumFont() as byte = (
15, 15, 32, 90, // header 0-3
$7A, $00, // Space '4-5
$8B, $00, // !
$90, $00, // "
$9B, $00, // #
$B4, $00, // $
$C5, $00, // %
$E2, $00, // &
$F7, $00, // '
$FC, $00, // (
$07, $01, // )
$12, $01, // *
$1F, $01, // +
$30, $01, // ,
$35, $01, // -
$42, $01, // .
$47, $01, // /
$52, $01, // 0
$63, $01, // 1
$70, $01, // 2
$81, $01, // 3
$92, $01, // 4
$A3, $01, // 5
$B4, $01, // 6
$C5, $01, // 7
$D6, $01, // 8
$E7, $01, // 9
$F8, $01, // :
$01, $02, // ;
$06, $02, // <
$17, $02, // =
$28, $02, // >
$39, $02, // ?
$4A, $02, // Solid arrow (was @
$59, $02, // A
$70, $02, // B
$83, $02, // C
$98, $02, // D
$AD, $02, // E
$C0, $02, // F
$D3, $02, // G
$EA, $02, // H
$FF, $02, // I
$04, $03, // J
$13, $03, // K
$28, $03, // L
$39, $03, // M
$54, $03, // N
$69, $03, // O
$80, $03, // P
$93, $03, // Q
$AA, $03, // R
$C1, $03, // S
$D4, $03, // T
$E9, $03, // U
$FE, $03, // V
$15, $04, // W
$34, $04, // X
$4B, $04, // Y
$64, $04, // Z
// offset 122
$08, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, ' Code for char
$02, $FF, $67, $FF, $67, ' Code for char !
$05, $1F, $00, $1F, $00, $00, $00, $1F, $00, $1F, $00, ' Code for char "
$0C, $00, $06, $30, $76, $B0, $7F, $F8, $1F, $FF, $06, $37, $06, $30, $76, $B0, $7F, $F8, $1F, $FF, $06, $37, $06, $30, $00, ' Code for char #
$08, $3C, $18, $7E, $38, $E7, $70, $C3, $60, $FF, $7F, $83, $61, $8E, $3F, $0C, $1F, ' Code for char $
$0E, $3C, $00, $42, $00, $42, $40, $42, $70, $3C, $3C, $00, $0F, $80, $03, $E0, $00, $78, $00, $1E, $1E, $07, $21, $01, $21, $00, $21, $00, $1E, ' Code for char %
$0A, $00, $1E, $00, $3F, $9C, $71, $FF, $60, $E3, $60, $E3, $61, $3F, $37, $1E, $1F, $00, $3B, $00, $20, ' Code for char &
$02, $1F, $00, $1F, $00, ' Code for char '
$05, $E0, $03, $F8, $0F, $1E, $3C, $07, $70, $01, $40, ' Code for char (
$05, $01, $40, $07, $70, $1E, $3C, $F8, $0F, $E0, $07, ' Code for char )
$06, $06, $00, $34, $00, $1F, $00, $1F, $00, $34, $00, $06, $00, ' Code for char *
$08, $80, $01, $80, $01, $80, $01, $F0, $0F, $F0, $0F, $80, $01, $80, $01, $80, $01, ' Code for char +
$02, $00, $58, $00, $38, ' Code for char ,
$06, $80, $01, $80, $01, $80, $01, $80, $01, $80, $01, $80, $01, ' Code for char -
$02, $00, $30, $00, $30, ' Code for char .
$05, $00, $38, $80, $3F, $F8, $07, $7F, $00, $07, $00, ' Code for char /
$08, $F8, $0F, $FE, $3F, $07, $70, $03, $60, $03, $60, $07, $70, $FE, $3F, $F8, $0F, ' Code for char 0
$06, $00, $00, $30, $00, $18, $00, $0C, $00, $FF, $7F, $FF, $7F, ' Code for char 1
$08, $0C, $60, $0E, $78, $07, $6C, $03, $66, $03, $63, $C7, $61, $FE, $60, $3C, $60, ' Code for char 2
$08, $0C, $18, $0E, $38, $07, $70, $C3, $60, $C3, $60, $E7, $71, $BE, $3F, $1C, $1F, ' Code for char 3
$08, $00, $07, $C0, $07, $F0, $06, $3C, $06, $0F, $06, $FF, $7F, $FF, $7F, $00, $06, ' Code for char 4
$08, $F0, $18, $FF, $38, $6F, $70, $63, $60, $63, $60, $E3, $70, $C3, $3F, $80, $0F, ' Code for char 5
$08, $F8, $0F, $FE, $3F, $C6, $70, $63, $60, $63, $60, $E7, $70, $CE, $3F, $8C, $1F, ' Code for char 6
$08, $03, $00, $03, $00, $03, $78, $83, $7F, $E3, $07, $7B, $00, $0F, $00, $03, $00, ' Code for char 7
$08, $3C, $1F, $FE, $3F, $E7, $71, $C3, $60, $C3, $60, $E7, $71, $FE, $3F, $3C, $1F, ' Code for char 8
$08, $FC, $18, $FE, $39, $87, $73, $03, $63, $03, $63, $87, $31, $FE, $3F, $F8, $07, ' Code for char 9
$04, $00, $00, $0C, $18, $0C, $18, $00, $00, ' Code for char :
$02, $0C, $2C, $0C, $1C, ' Code for char ;
$08, $C0, $01, $C0, $01, $60, $03, $60, $03, $30, $06, $18, $0C, $18, $0C, $0C, $18, ' Code for char <
$08, $30, $06, $30, $06, $30, $06, $30, $06, $30, $06, $30, $06, $30, $06, $30, $06, ' Code for char =
$08, $0C, $18, $18, $0C, $18, $0C, $30, $06, $60, $03, $60, $03, $C0, $01, $C0, $01, ' Code for char >
$08, $0C, $00, $0E, $00, $07, $00, $03, $6E, $83, $6F, $C7, $01, $FE, $00, $3C, $00, ' Code for char ?
$07, $FE, $3F, $FC, $1F, $F8, $0F, $F0, $07, $E0, $03, $C0, $01, $80, $00, ' Code for char @
$0B, $00, $60, $00, $7E, $E0, $1F, $FC, $07, $3F, $06, $03, $06, $3F, $06, $FC, $07, $E0, $1F, $00, $7E, $00, $60, ' Code for char A
$09, $FF, $7F, $FF, $7F, $C3, $60, $C3, $60, $C3, $60, $C3, $60, $E7, $71, $BE, $3F, $1C, $1F, ' Code for char B
$0A, $F0, $07, $FC, $1F, $0E, $38, $07, $70, $03, $60, $03, $60, $03, $70, $0E, $38, $1E, $1E, $18, $06, ' Code for char C
$0A, $FF, $7F, $FF, $7F, $03, $60, $03, $60, $03, $60, $03, $60, $07, $70, $0E, $38, $FC, $1F, $F0, $07, ' Code for char D
$09, $FF, $7F, $FF, $7F, $C3, $60, $C3, $60, $C3, $60, $C3, $60, $C3, $60, $C3, $60, $C3, $60, ' Code for char E
$09, $FF, $7F, $FF, $7F, $C3, $00, $C3, $00, $C3, $00, $C3, $00, $C3, $00, $C3, $00, $03, $00, ' Code for char F
$0B, $F0, $07, $FC, $1F, $0E, $38, $06, $30, $03, $60, $03, $60, $83, $61, $83, $61, $86, $31, $9E, $3F, $98, $1F, ' Code for char G
$0A, $FF, $7F, $FF, $7F, $C0, $00, $C0, $00, $C0, $00, $C0, $00, $C0, $00, $C0, $00, $FF, $7F, $FF, $7F, ' Code for char H
$02, $FF, $7F, $FF, $7F, ' Code for char I
$07, $00, $1C, $00, $3C, $00, $70, $00, $60, $00, $60, $FF, $3F, $FF, $1F, ' Code for char J
$0A, $FF, $7F, $FF, $7F, $80, $01, $E0, $00, $F0, $01, $98, $07, $0C, $0E, $07, $38, $03, $70, $00, $40, ' Code for char K
$08, $FF, $7F, $FF, $7F, $00, $60, $00, $60, $00, $60, $00, $60, $00, $60, $00, $60, ' Code for char L
$0D, $FF, $7F, $FF, $7F, $3F, $00, $FC, $01, $C0, $1F, $00, $7E, $00, $60, $00, $7E, $C0, $1F, $F8, $03, $3F, $00, $FF, $7F, $FF, $7F, ' Code for char M
$0A, $FF, $7F, $FF, $7F, $1E, $00, $78, $00, $E0, $01, $C0, $03, $00, $0F, $00, $3C, $FF, $7F, $FF, $7F, ' Code for char N
$0B, $F0, $07, $FC, $1F, $0E, $38, $07, $70, $03, $60, $03, $60, $03, $60, $07, $70, $0E, $38, $FC, $1F, $F0, $07, ' Code for char O
$09, $FF, $7F, $FF, $7F, $83, $01, $83, $01, $83, $01, $83, $01, $C7, $01, $FE, $00, $7C, $00, ' Code for char P
$0B, $F0, $07, $FC, $1F, $0E, $38, $07, $70, $03, $60, $03, $60, $03, $68, $07, $30, $0E, $38, $FC, $6F, $F0, $43, ' Code for char Q
$0B, $FF, $7F, $FF, $7F, $C3, $00, $C3, $00, $C3, $00, $C3, $01, $43, $03, $67, $0E, $7E, $3C, $3C, $70, $00, $40, ' Code for char R
$09, $3C, $18, $7E, $38, $67, $70, $C3, $60, $C3, $60, $83, $61, $87, $73, $0E, $3F, $0C, $1E, ' Code for char S
$0A, $03, $00, $03, $00, $03, $00, $03, $00, $FF, $7F, $FF, $7F, $03, $00, $03, $00, $03, $00, $03, $00, ' Code for char T
$0A, $FF, $0F, $FF, $3F, $00, $70, $00, $60, $00, $60, $00, $60, $00, $60, $00, $30, $FF, $3F, $FF, $0F, ' Code for char U
$0B, $03, $00, $3F, $00, $FC, $01, $C0, $1F, $00, $7E, $00, $60, $00, $7E, $C0, $1F, $FC, $01, $3F, $00, $03, $00, ' Code for char V
$0F, $07, $00, $FF, $00, $F8, $1F, $00, $7F, $00, $60, $F8, $7F, $FF, $0F, $03, $00, $FF, $0F, $F8, $7F, $00, $60, $00, $7F, $F8, $1F, $FF, $00, $0F, $00, ' Code for char W
$0B, $01, $40, $07, $70, $0E, $38, $3C, $1E, $F0, $07, $C0, $01, $F0, $07, $3C, $1E, $0E, $38, $03, $70, $01, $40, ' Code for char X
$0C, $01, $00, $07, $00, $0E, $00, $3C, $00, $F0, $00, $C0, $7F, $C0, $7F, $F0, $00, $38, $00, $0E, $00, $07, $00, $01, $00, ' Code for char Y
$0A, $03, $70, $03, $78, $03, $6E, $03, $67, $83, $63, $E3, $60, $73, $60, $1B, $60, $0F, $60, $07, $60 ' Code for char Z
)
#option DISPLAY_COLUMNS = 128
const D_COLUMNS = DISPLAY_COLUMNS
const FontOffset = 4 // (Size of the header)
// Find the width of a character. Right hand padding defaults to 1 if not specified.
// Remember if using this to supply a fixed width to WriteChar or WriteStr that you need to specify zero padding either here or in the write command.
public function WidthOfChar(byrefconst FontMap() as byte, CNo as byte, CPad as byte = 1) as byte
dim w, l as word
if CNo < FontMap(2) then CNo = FontMap(2) endif // Set limits on the character number.
if CNo > FontMap(3) then CNo = FontMap(3) endif // Limit to the number of characters defined.
CNo = CNo - FontMap(2) // Remove ASCII offset. We will end up with a character reference between 0 and the number of chrs defined.
w = CNo * 2
w = w + FontOffset
l.byte0 = FontMap(w)
l.byte1 = FontMap(w+1)
result = FontMap(l) + CPad
end function
// Find the width of a full string of characters
public function WidthOfStr(byrefconst FontMap() as byte, CStr as string) as byte
dim sw, sl as byte
sw = 0
sl = 0
while CStr(sl) <> null
sw = sw + WidthOfChar(FontMap, CStr(sl))
inc(sl)
wend
result = sw
end function
public sub CentralStr(byrefconst Fontmap() as byte, CStr as string, YPage as byte)
dim w as byte
w = WidthOfStr(FontMap, CStr)
// set a brkpoint here and examine w before doing other math on it
w = D_COLUMNS - w
w = w / 2
// Add code to output width w here
//WriteStr(Fontmap, CStr, w, YPage)
end sub
// Samples of how this routine is called
CentralStr(MediumFont," ", 0) // w = 15*9=135
CentralStr(MediumFont," ", 0) // w = 20*9=180
CentralStr(MediumFont," ", 0) // w = 10*9=90
CentralStr(MediumFont," ", 0) // w = 90
CentralStr(MediumFont,"01234567890",0)
CentralStr(MediumFont,"ABCDEFGHIJK",0)
CentralStr(MediumFont," ",0)
-
- Posts: 113
- Joined: Mon Jan 11, 2010 10:39 pm
- Location: Chesterfield
Thanks, Jerry.
I will have to look in to using MPLAB but I was a bit put off using that as last time I tried I ended up bricking my PICKit3 and had a right hassle fixing it.
If I'm understanding your results correctly, it appears the compiler is looking at the first call of a routine to determine the amount of string space it needs to allow.
Without looking at my code in great detail I think this doesn't apply when you call a routine directly - I use WidthOfStr elsewhere for formatting purposes and it all seems to work as expected.
Presumably the problem comes where a string is being 'passed on' - I guess it is harder under those circumstances to determine the maximum size.
I guess a work-around is to copy the WidthOfStr code in to the CentralStr routine so you don't need to pass the string on. This would also seem to be more RAM efficient - I ended up replacing the CentralStr command by copying and pasting the code each time I used it (only 6 places at the moment) and ended up saving about 35 bytes of RAM.
I will have to look in to using MPLAB but I was a bit put off using that as last time I tried I ended up bricking my PICKit3 and had a right hassle fixing it.
If I'm understanding your results correctly, it appears the compiler is looking at the first call of a routine to determine the amount of string space it needs to allow.
Without looking at my code in great detail I think this doesn't apply when you call a routine directly - I use WidthOfStr elsewhere for formatting purposes and it all seems to work as expected.
Presumably the problem comes where a string is being 'passed on' - I guess it is harder under those circumstances to determine the maximum size.
I guess a work-around is to copy the WidthOfStr code in to the CentralStr routine so you don't need to pass the string on. This would also seem to be more RAM efficient - I ended up replacing the CentralStr command by copying and pasting the code each time I used it (only 6 places at the moment) and ended up saving about 35 bytes of RAM.
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
That looks to be what's happening.Without looking at my code in great detail I think this doesn't apply when you call a routine directly - I use WidthOfStr elsewhere for formatting purposes and it all seems to work as expected.
Presumably the problem comes where a string is being 'passed on' - I guess it is harder under those circumstances to determine the maximum size.
I added a few direct calls to WidthOfStr() before calling CentralStr() and it was able to determine the proper max length required.
Code: Select all
WidthOfStr(MediumFont," ") // len = 15
WidthOfStr(MediumFont," ") // len = 20
WidthOfStr(MediumFont," ") // len = 30
You can see this if you look in the resulting .IDF file...
Code: Select all
.func PUB 00002 $005D6 00086 $002B 0041 00153 00161 WidthOfStr
.var CEF $002B 00 0000 0000 U08 FontMap
.var VAL $002F 00 0031 0000 U08 CStr <<<<< reserve 31 bytes
.var PRI $004E 00 0000 0000 U08 sw
.var PRI $004F 00 0000 0000 U08 sl
.ret PRI $0050 00 0000 0000 U08 WidthOfStr
.end
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
Oh, and forgot to mention...
Whenever you change processor family types like switching from an 18F to a 18FJ, MPLAB will want to download new firmware to the Pickit3.
It also usually does this if you update MPLAB versions, too.
I haven't had any issues of late, but I always follow these steps whenever I switch uC types:
- First off, make sure you've got the most recent version of MPLAB (early versions were more problematic).
- Close MPLAB (if it's open)
- Remove the Pickit3 connection to the target board
- Open MPLAB and change the processor type in MPLAB using "Configure | Select Device..."
(this will give you the "downloading new bootloader, RS, AP, etc")
- After it's all done, save the workspace so the next time it reopens MPLAB with the new setup
- Reconnect the Pickit3 to the new target
I don't know if all of these steps are actually required, but ever since I started being completely paraniod
and doing that whenever I change families things have been pretty stable (knock on wood).
I've had that happen to me a few times, too.I will have to look in to using MPLAB but I was a bit put off using that as last time I tried I ended up bricking my PICKit3 and had a right hassle fixing it.
Whenever you change processor family types like switching from an 18F to a 18FJ, MPLAB will want to download new firmware to the Pickit3.
It also usually does this if you update MPLAB versions, too.
I haven't had any issues of late, but I always follow these steps whenever I switch uC types:
- First off, make sure you've got the most recent version of MPLAB (early versions were more problematic).
- Close MPLAB (if it's open)
- Remove the Pickit3 connection to the target board
- Open MPLAB and change the processor type in MPLAB using "Configure | Select Device..."
(this will give you the "downloading new bootloader, RS, AP, etc")
- After it's all done, save the workspace so the next time it reopens MPLAB with the new setup
- Reconnect the Pickit3 to the new target
I don't know if all of these steps are actually required, but ever since I started being completely paraniod
and doing that whenever I change families things have been pretty stable (knock on wood).
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact: