Are all of these versions of PropFORTH by Sal, (dating back to the original posted at the Ultimate List) open source?
I believe it is under the MIT license. I don't know if your list goes back to the original, my records only go back to 2.5. The starting comment in propforth.spin is the same in all version AFAIK except for the year:
Copyright (c) 2010 Sal Sanci
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
What is trouble?
I don't have 4X20 LCD.
Maybe it is caused by code below;
{
x -- horizontal pos : 1 to 16
y -- line number : 1 or 2
( x y -- )
}
: pos_move _rs_out_l 1- 40 u* swap 1- 80 + + LCD_com ;
This code send command to calculate CGRAM address.
You should check your LCD's datasheet.
If you use serial LCD, I think you must load serial code(assembler) to another cog.
If it is successful, communication between prop and serial-LCD is very easy.
I will try it later.
What is trouble?
I don't have 4X20 LCD.
Maybe it is caused by code below;
{
x -- horizontal pos : 1 to 16
y -- line number : 1 or 2
( x y -- )
}
: pos_move _rs_out_l 1- 40 u* swap 1- 80 + + LCD_com ;
This code send command to calculate CGRAM address.
You should check your LCD's datasheet.
If you use serial LCD, I think you must load serial code(assembler) to another cog.
If it is successful, communication between prop and serial-LCD is very easy.
I will try it later.
I got the basic code going on a 2x16 display. (see first picture red display), Clear and x/y positioning works. My only observation (bug or feature???)is that if you LCD_str a string over 16 bytes it truncates rather than wraps ... see second picture with red display
Put a 4x20 display in and ran basic demo,, it works and uses only 2x16 of display(see 3rd picture blue display) Clear works, ,but x/y positioning beyond 2x16 is AFU. It doesn't know what to do with Lines 3 and 4 or characters columns beyond position16.
Demo code, character dump is very 2x16 oriented
If I remember correctly, line 3's CGRAM is the extension of line 1, and line 4 is the extension of line 2
...talk with a serial LCD, one pin ... serial input to the display controller at 19,200 baud
Sal's example in the propforth4.0 readme sets up a serial channel to talk to the spineret on the spineret's 30 & 31. This might be what you are after. It is the code on the master does the "term" word on the masters pins connected to the spineret 30& 31. I belive the word that sets up the structure is CHA or CHB. Sorry I can't be more specific I havent' gotten to play with it yet. Pi-Rho (Pi'd, derrick) was looking at this extra serial stuff, I don't know if he's still experimenting on it
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Line1 0 1 2 3 4 5 6 7 8 9 A B C D E F
Line2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4F 4F
There are many type in Character-LCD, although conteroler might be same.
Ram-address might be dufferent. Sorry I don't know well.
I don't have 4X20-LCD.
Please check its ram-address on 4X20-LCD's datasheet.
And you can change code.
HD44780 has $80 bytes of CGRAM ... every display (2x8, 2x16, 2x20, 2x24, 2x40, 4x16, 4x20) uses the same addressing, just smaller dispalsy ignore code that writes to spaces not there.
2.5.2 Addressing Display RAM
----------------------------
In the list below, "line 1" is the topmost line, and "line n" is the bottommost line. On each line, the leftmost character has the lowest address, and addresses increase to the right. Also, DD RAM addresses are shown without the 80h mode bit set.
16x1 module is arranged as two 8-character lines side by side.
"Line 1" (left) addresses are 00h to 07h
"Line 2" (right) addresses are 40h to 47h
As you write characters to the module, the cursor will
automatically increment until you get to the 9th
character--you have to move the cursor to address 40h
before writing the 9th character on the 1x16 module.
16x2 module is two lines by 16 chars
Line 1 addresses are 00h to 0Fh
Line 2 addresses are 40h to 4Fh
20x1 module
Line 1 addresses are 00h to 13h
20x2 module
Line 1 addresses are 00h to 13h
Line 2 addresses are 40h to 53h
20x4 module
Line 1 addresses are 00h to 13h
Line 2 addresses are 40h to 53h
Line 3 addresses are 14h to 27h
Line 4 addresses are 54h to 67h
24x2 module
Line 1 addresses are 00h to 17h
Line 2 addresses are 40h to 57h
40x2 module
Line 1 addresses are 00h to 27h
Line 2 addresses are 40h to 67h
The full 128 bytes of display RAM exist no matter how many characters appear on the display. These extra bytes can be typed on when display window scrolling is enabled, or they can be used to store other information--external data RAM for the CPU, if you like.
** Notice that 40x2 and 20x4 are identical addressing, just physically different
{
x -- horizontal pos : 0x1 to 0x14
y -- line number : 0x1 or 0x4
( x y -- )
}
: pos_move _rs_out_l 2 u/mod swap 0= if 1 = if 40 else 54 then
else 0= if 0 else 14 then
then
1- + 80 or
LCD_com
;
This also works on 2X16-LCD.
Maybe 4X20-LCD too.
Part[display character] for LCD_demo are display only 16-characters & 2-lines.
By the way your LCD(2X16,4X20) can display charcter-code[0xa0 - 0xdf]?
My 2X16-LCD display japanese char-code(katakana).
NICE Work ... I checked it thoroughly and it looks good. I tried these combinations
1 1 pos_move c" string1" LCD_str \ works as expected
4 2 pos_move c" string2" LCD_str \ works as expected
6 3 pos_move c" string3" LCD_str \ works as expected
1 4 pos_move c" string4" LCD_str \ works as expected
12 1 pos_move c" string5" LCD_str \ works as expected
\ Interesting note #1
18 1 pos_move c" string" LCD_str \ this command sequence places the string
4 3 pos_move c" string" LCD_str \ in the same place as this command sequence
\ Interesting note #2
4 1 pos_move c" green" LCD_str \ works as expected
c" machine" LCD_str \ prints where "green" left off
\ Interesting note #3
10 1 pos_move c" abcdefgh" LCD_str \ prints "abcde" in upper right and
\ prints "fgh" at beginning of line 3
We ought to have a word "4 2 LCDclreol" that goes to position 4/2 and blanks the remainder of the line. Then we need a way to get numbers from variables, into ASCII for LCD display
I attached a pic of the 4x20 display using Kaz' new xy routine and a Copy of the updated code with Kaz' new routine and a 4x20 demo routine I created by copying and editing Kaz' original. **Warning** my Propeller pin assignment are different from the original, but I added comments to guide pin selection.
I sucked up and cracked my copy of Starting Forth, reviewed stack manipulation, and tried doing clear-to-end-off-line myself ... here it is ... it works, but I am sure at least a couple of you can whittle a few bytes off what I have here ...
fl
20 constant _blank
14 constant linlen \ number of characters per line $10, $14, $18, $28
{
LCD_clreol - (n1 n2 --)
- clears LCD from column n1 to end of line n2
- uses constant for linelength and WORDs pos_move and char
}
: LCD_clreol over rot rot pos_move linlen swap - 1+ 0 do _blank char loop ;
It took me a while to get around to testing long 2 line displays ... they mostly have 2x7 (no backlight) or 2x8 (backlight) connectors that don't get along with solder-less breadboards ... I had too rig an adapter board.
Anyway, I did it and checked a 24 by 2 lines and a 40 by 2 lines and they worked fine with Kaz's corrected main code and as well with my clear-to-end-of-line code. Enclosed is a picture of the 40x2.
I updated to LCD_1.0.
I used 16X4-LCD.
Default is 16X2-LCD.
When you use 16X2-LCD, comment out "10 4 LCD_setup" inside WORD"demo".
Kaz, nice work. I love the bar graph ... I ran it through my stash of various displays and they all ran demo well, however, I think you need to change a small part of one line in WORD demo.
\ near the top of demo, this line, is the innermost display loop
1 i 1+ LCD_pos 10 0 do dup LCD_char 100 delms 1+ loop loop
\ should be changed to this
1 i 1+ LCD_pos char W@ 0 do dup LCD_char 100 delms 1+ loop loop
Question ... Dec, Bin, and Hex
\ display hex number (n1 n2 -- ) n1:hex-value n2:digits(1 to 8)
: Hex
\ display binary number (n1 n2 -- ) n1:hex-value n2:digits(1 to 10)
: Bin
\ display decimal number (n -- ) n:hex-value
: Dec
Is there some reason Dec doesn't allow specifying the number of digits?
Kaz, nice work. I love the bar graph ... I ran it through my stash of various displays and they all ran demo well, however, I think you need to change a small part of one line in WORD demo.
\ near the top of demo, this line, is the innermost display loop
1 i 1+ LCD_pos 10 0 do dup LCD_char 100 delms 1+ loop loop
\ should be changed to this
1 i 1+ LCD_pos char W@ 0 do dup LCD_char 100 delms 1+ loop loop
I know. But I set 16-charcters because character's line are 16fonts on character-code-table.
Conversion for Hex to Decimal need all hex-digit.
I merely translate Hex/Bin/Dec from spin object to PropForth.
Please check LCD-object inside Display object list
I think LCD_com need to be wrote by assembler because display speed for bar-graoph is slow.
I know. But I set 16-charcters because character's line are 16fonts on character-code-table.
Conversion for Hex to Decimal need all hex-digit.
I merely translate Hex/Bin/Dec from spin object to PropForth.
Please check LCD-object inside Display object list
I think LCD_com need to be wrote by assembler because display speed for bar-graoph is slow.
OK, found spin object ... bar-graph is slow because you have the delays in there that give it dramatic effect. I used the bar graph characters in a routine I wrote sans delays and LCD_com performed just fine.
There is a flaw in your WORD Dec, if the value is zero it prints nothing. The spin code line for suppressing lead zeroes is
elseif result or i == 1
out("0")
you only implemented the test for "result" and not for "i == 1" and 'lead zero' as the rightmost digit was also suppressed.
I also coded in digit control and for the moment we are stuck with lead zeroes. This code is a little ragged but it works and so far seems stable.
fl
{
Dec ( n1 n2 -- )
n1 - number to be displayed
n2 - number of digits
** caution ** if you give it 123456 and specify 4 digits
it will print 3456
}
: Dec
0 result W!
3b9aca00 tmp L!
dup a swap - 0 do tmp L@ a u/ tmp L! loop \ shrink loop to n2
swap
dup 80000000 and if invert 1+ 2d LCD_char then \ check neg, "-"
swap
0 do
dup tmp L@ >= if
tmp L@ u/mod 30 + LCD_char
else
30 LCD_char
then
tmp L@ a u/ tmp L!
loop
drop
;
I added code to make the minus sign in negative numbers part of the display with computation so the width of any decimal dispaly will be controlled
fl
{
Dec ( n1 n2 -- )
n1 - number to be displayed
n2 - number of digit positions
** caution **
- if you give it 123456 and specify 4 digits
it will print 3456
- the minus sign in neg numbers counts as one of the
digit positions
}
: Dec
0 result W!
3b9aca00 tmp L!
swap dup 80000000 and if \ check neg, "-"
invert 1+ 2d LCD_char swap 1-
else
swap
then
dup a swap - 0 do tmp L@ a u/ tmp L! loop \ shrink loop to n2
0 do
dup tmp L@ >= if
tmp L@ u/mod 30 +
else
30
then
LCD_char
tmp L@ a u/ tmp L!
loop
drop
;
I measured time for LCD_cmd.(WORD: time)
It took 2DB00 ticks(2.34msec).
I changed wait-time to 2msec on LCD_cmd.
When writing to LCD, wait-time is 40usec on datasheet.
If making shorter delay WORD, this time become short.
But I think it is not need.
I haven't specifically used either, but I would expect:
branch does> if the value of the flag on the top of the stack (n1) is non zero, branch to the address on the stack (n2)
0branch does> if the value of the flag on the top of the stack (n1) is zero, branch to the address on the stack (n2)
I measured time for LCD_cmd.(WORD: time)
It took 2DB00 ticks(2.34msec).
I changed wait-time to 2msec on LCD_cmd.
When writing to LCD, wait-time is 40usec on datasheet.
If making shorter delay WORD, this time become short.
But I think it is not need.
Kaz, in the 0925.txt file you had a change in LCD_init WORD from "5 delms" to "2 delms", but I didn't see any changes in LCD_com WORD
I understand branch & 0branch to get hint from your reply.
branch is unconditional branch instruction.
When there is WORD"branch"s value(0x001B) on dictionary, it jump to offset value on next adderess.
0branch is conditional branch instruction according to t/f on stack.
When there is WORD"0branch"s value(0x00D8) on dictionary, it jump to offset value on next adderess in case of false on stack-data.
@nglord
It has not been.needed so far. (also architecture considerations) What did you have in mind, maybe we could suggest something or start implementing.
Can you
@prof_braino
I have a desire to transfer one of my first forth programs (an analog computer simulator) to propforth. It makes use of the Create...DOES> pair to create defining words with attached
execution code, in my case an integrator defining word.
I am using the original version of the propeller platform with a 128 kb eeprom as my "forth computer". I have added a shield populated with a 2nd "slave" propeller, video output, keyboard
and sd card programmed with a modified version of OBC's propterminal plus a full screen editor. With this setup I can communicate with the forth system without a pc.
I will provide more details at a later date.
@prof_braino
transfer .. forth programs .. to propforth... use of the Create...DOES> .. defining words
... communicate with the forth system without a pc....nickL
This sounds really cool. I'm working on non-pc configurations also, right now I'm working on moving Jupiter ACE propforth to the C3.
I'll ask Sal for suggestions how to get you what you need.
Comments
Copyright (c) 2010 Sal Sanci
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
I made LCD-demo.
@caskaz ... nice work ... I will try it out
@Braino et al. How do I talk with a serial LCD, one pin ... serial input to the display controller at 19,200 baud
What is trouble?
I don't have 4X20 LCD.
Maybe it is caused by code below; This code send command to calculate CGRAM address.
You should check your LCD's datasheet.
If you use serial LCD, I think you must load serial code(assembler) to another cog.
If it is successful, communication between prop and serial-LCD is very easy.
I will try it later.
I got the basic code going on a 2x16 display. (see first picture red display), Clear and x/y positioning works. My only observation (bug or feature???)is that if you LCD_str a string over 16 bytes it truncates rather than wraps ... see second picture with red display
Put a 4x20 display in and ran basic demo,, it works and uses only 2x16 of display(see 3rd picture blue display) Clear works, ,but x/y positioning beyond 2x16 is AFU. It doesn't know what to do with Lines 3 and 4 or characters columns beyond position16.
Demo code, character dump is very 2x16 oriented
If I remember correctly, line 3's CGRAM is the extension of line 1, and line 4 is the extension of line 2
My 2x16-LCD's ram-address is below. There are many type in Character-LCD, although conteroler might be same.
Ram-address might be dufferent. Sorry I don't know well.
I don't have 4X20-LCD.
Please check its ram-address on 4X20-LCD's datasheet.
And you can change code.
Sal's example in the propforth4.0 readme sets up a serial channel to talk to the spineret on the spineret's 30 & 31. This might be what you are after. It is the code on the master does the "term" word on the masters pins connected to the spineret 30& 31. I belive the word that sets up the structure is CHA or CHB. Sorry I can't be more specific I havent' gotten to play with it yet. Pi-Rho (Pi'd, derrick) was looking at this extra serial stuff, I don't know if he's still experimenting on it
HD44780 has $80 bytes of CGRAM ... every display (2x8, 2x16, 2x20, 2x24, 2x40, 4x16, 4x20) uses the same addressing, just smaller dispalsy ignore code that writes to spaces not there.
I re-write code of pos_move This also works on 2X16-LCD.
Maybe 4X20-LCD too.
Part[display character] for LCD_demo are display only 16-characters & 2-lines.
By the way your LCD(2X16,4X20) can display charcter-code[0xa0 - 0xdf]?
My 2X16-LCD display japanese char-code(katakana).
NICE Work ... I checked it thoroughly and it looks good. I tried these combinations
We ought to have a word "4 2 LCDclreol" that goes to position 4/2 and blanks the remainder of the line. Then we need a way to get numbers from variables, into ASCII for LCD display
I attached a pic of the 4x20 display using Kaz' new xy routine and a Copy of the updated code with Kaz' new routine and a 4x20 demo routine I created by copying and editing Kaz' original. **Warning** my Propeller pin assignment are different from the original, but I added comments to guide pin selection.
Anyway, I did it and checked a 24 by 2 lines and a 40 by 2 lines and they worked fine with Kaz's corrected main code and as well with my clear-to-end-of-line code. Enclosed is a picture of the 40x2.
I updated to LCD_1.0.
I used 16X4-LCD.
Default is 16X2-LCD.
When you use 16X2-LCD, comment out "10 4 LCD_setup" inside WORD"demo".
Kaz, nice work. I love the bar graph ... I ran it through my stash of various displays and they all ran demo well, however, I think you need to change a small part of one line in WORD demo.
Question ... Dec, Bin, and Hex
Is there some reason Dec doesn't allow specifying the number of digits?
Thanks to test code.
I know. But I set 16-charcters because character's line are 16fonts on character-code-table.
Conversion for Hex to Decimal need all hex-digit.
I merely translate Hex/Bin/Dec from spin object to PropForth.
Please check LCD-object inside Display object list
I think LCD_com need to be wrote by assembler because display speed for bar-graoph is slow.
OK, found spin object ... bar-graph is slow because you have the delays in there that give it dramatic effect. I used the bar graph characters in a routine I wrote sans delays and LCD_com performed just fine.
There is a flaw in your WORD Dec, if the value is zero it prints nothing. The spin code line for suppressing lead zeroes is
you only implemented the test for "result" and not for "i == 1" and 'lead zero' as the rightmost digit was also suppressed.
I also coded in digit control and for the moment we are stuck with lead zeroes. This code is a little ragged but it works and so far seems stable.
Anyone know how to use branch and 0branch?
I measured time for LCD_cmd.(WORD: time)
It took 2DB00 ticks(2.34msec).
I changed wait-time to 2msec on LCD_cmd.
When writing to LCD, wait-time is 40usec on datasheet.
If making shorter delay WORD, this time become short.
But I think it is not need.
I haven't specifically used either, but I would expect:
branch does> if the value of the flag on the top of the stack (n1) is non zero, branch to the address on the stack (n2)
0branch does> if the value of the flag on the top of the stack (n1) is zero, branch to the address on the stack (n2)
Kaz, in the 0925.txt file you had a change in LCD_init WORD from "5 delms" to "2 delms", but I didn't see any changes in LCD_com WORD
I understand branch & 0branch to get hint from your reply.
branch is unconditional branch instruction.
When there is WORD"branch"s value(0x001B) on dictionary, it jump to offset value on next adderess.
0branch is conditional branch instruction according to t/f on stack.
When there is WORD"0branch"s value(0x00D8) on dictionary, it jump to offset value on next adderess in case of false on stack-data.
Refere to 'Structure of the compiler' for http://en.wikipedia.org/wiki/Forth_(programming_language)#Dictionary_entry.
As an old forth programmer (dating back to fig-forth), I finally tried propForth. Is the does> construct available?
nickL
does> is not available.
@nglord
It has not been.needed so far. (also architecture considerations) What did you have in mind, maybe we could suggest something or start implementing.
Can you
I have a desire to transfer one of my first forth programs (an analog computer simulator) to propforth. It makes use of the Create...DOES> pair to create defining words with attached
execution code, in my case an integrator defining word.
I am using the original version of the propeller platform with a 128 kb eeprom as my "forth computer". I have added a shield populated with a 2nd "slave" propeller, video output, keyboard
and sd card programmed with a modified version of OBC's propterminal plus a full screen editor. With this setup I can communicate with the forth system without a pc.
I will provide more details at a later date.
nickL
This sounds really cool. I'm working on non-pc configurations also, right now I'm working on moving Jupiter ACE propforth to the C3.
I'll ask Sal for suggestions how to get you what you need.