Jump to content
IGNORED

Camel99 Forth Information goes here


TheBF

Recommended Posts

Trying to make Forth system that complies with the ANS/ISO Standard is not easy for a mediocre programmer like me.

 

While doing some work on creating a library file for "double" (32 bit) integers I had to check the definition of "M*/"

It means "mixed multiply and divide". It can be using for scaling large numbers.

 

Online I found this:

 

M*/

( d1 n1 +n2 -- d2 )

Multiply d1 by n1 producing the triple-cell intermediate result t. Divide t by +n2 giving the double-cell quotient d2.

An ambiguous condition exists if +n2 is zero or negative, or the quotient lies outside of the range of a double-precision signed integer.

LOL! I could tell that might take me some time so... I opened GNU Forth and ran the decompiler "SEE" on "M*/" and am I GLAD I did!

Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
SEE M*/
: m*/
  >r s>d >r abs -rot s>d r> xor r> swap >r >r dabs rot tuck um* 2swap um* swap
  >r 0 d+ r> -rot i um/mod -rot r> um/mod -rot r>
  IF     IF     1 0 d+
         THEN
         dnegate
  ELSE   drop
  THEN ; ok

That is the longest definition of a Forth math operator I have ever seen! . :-o

They would have found me dead at the keyboard trying to solve that one.

 

The good news is I only had to replace the 'i' in the code with R@, convert to upper case and it worked.

 

"Standards are great! Everybody should have one"

Chuck Moore

 

P.S. 804 bytes is the compile size of the library

post-50750-0-41474900-1542252092_thumb.jpg

Edited by TheBF
  • Like 2
Link to comment
Share on other sites

Yep.. I like to see this worked through, I too though I am older, really just getting into programming (c#, JS, and so forth) like to see how you work though the problems to get this to work. After I get some more stuff done around the house and yard and get my hardware functioning again, can set aside time to do it, want to get into learning forth, so this is of benefit to me.

  • Like 1
Link to comment
Share on other sites

I reference compiling times with CAMEL99 Forth in another post.

 

http://atariage.com/forums/topic/224905-xb-game-developers-package/?p=4158546

 

Here is a video showing the process using some tools that measure elapsed time and printing the no. of lines compiled.

 

(The Forth elapsed timer adds a few hundred milli-seconds to the real time, but it's pretty close)

COMPILETIME.mp4

Edited by TheBF
  • Like 1
Link to comment
Share on other sites

Loading and Saving Font Files

 

One of the cool things that I see TI-99 programs written by experienced people is the use of custom fonts.

I downloaded the gif file library of fonts by Sometimes99er and it is amazing.

 

I brought some of those into Magellan to look at them and then exported some of them out as BASIC DATA.

This was not a perfect format for my Forth graphics wordset, so I wrote a Forth word that would work a little better with that data requiring a little text search and replace.

 

I called it … wait for it …

 

CALLCHAR. :) What would you call it?

 

It uses some stuff I made that CHOPS a string quickly and then I use the ANS Forth word >NUMBER to convert each 8 character HEX string into a 32 bit integer.

A font source code file using CALLCHAR looks like this:

CR .( FONT277 for 32 column mode only)
NEEDS CALLCHAR FROM DSK2.CALLCHAR
\ character data
DECIMAL
 33 S" 0010101010001000" CALLCHAR
 34 S" 0024240000000000" CALLCHAR
 35 S" 00247E24247E2400" CALLCHAR
 36 S" 00083E283E0A3E08" CALLCHAR
 37 S" 0062640810264600" CALLCHAR
( ETC...)

CALLCHAR lets me INTERPRET a file of character definitions for the entire character set in about 10 seconds. (ASCII 33..127)

Remember that is reading a text file and interpreting it line by line in "normal" TI-99 speed. It uses no program memory permanently to do the job. Data goes directly into VDP RAM.

However 10 seconds is a long time.

 

Armed with my new DSRLINK courtesy the great people on Atariage, I thought I would try using the LOAD and SAVE functions of the file system.

This is an example of where Forth shows it's colours. Because I had done all the work to define a little language to work with the PABs and call the DSRLINK here is all it took to make routines to LOAD and save directly to VDP memory from files.

 

Edit: fixed late night mistakes

\ loadfile savefile utilties
HEX
0B CONSTANT W/O100  \ output, internal, relative, fixed 100
0D CONSTANT R/O100  \ input,  internal, relative, fixed 100

: SETPAB   ( VDPaddr count file$ len mode -- ) (common factor for both routines)
            [PAB FLG] VC!       \ set file access mode byte
            [PAB FNAME] VPLACE  \ set file name
          0 [PAB RECLEN] VC!    \ set rec. length to 0
            [PAB REC#]  V!      \ set #bytes to save (int)
            [PAB FBUFF] V! ;    \ set start address in VDP Ram (int)

: SAVE-FILE ( VDPaddr count file$ len mode -- ior) (*ior: I/O response)
           PSHPAB SETPAB  6 FILEOP ?FILERR  POPPAB ;

: LOAD-FILE ( VDPaddr count file$ len mode -- ior)
           PSHPAB SETPAB  5 FILEOP ?FILERR  POPPAB ;

Using these commands I will create SAVE-FONT LOAD-FONT commands like this:

: SAVE-FONT ( file$ len --)  800 400  2SWAP W/O100 SAVE-FILE ;
: LOAD-FONT ( file$ len --)  800 400  2SWAP R/O100 LOAD-FILE ; \ edited the last typo

Where 800 is the pattern descriptor table and 400 is the 1K bytes, from character 0 to character 128 ASCII.

 

In testing the process loading a font is virtually instant, so I can include a font file in the Forth START file that loads when Forth boots up.

 

Now I have to decide which font to load... That might be harder for me to decide than writing the code! :grin:

 

Note:

The process will be to create source code files with help from Magellan, compile the files to VDP memory, then SAVE-FONT to a TI-99 binary file.

Edited by TheBF
  • Like 3
Link to comment
Share on other sites

Yep.. I like to see this worked through, I too though I am older, really just getting into programming (c#, JS, and so forth) like to see how you work though the problems to get this to work. After I get some more stuff done around the house and yard and get my hardware functioning again, can set aside time to do it, want to get into learning forth, so this is of benefit to me.

 

Hey Ricky Dean I re-read your post here and realized that if you download my instruction manual it might give you some insights in how I created this system.

If gives you some comparisons of the differences between programming Basic and programming in Forth.

 

https://github.com/bfox9900/CAMEL99-V2/tree/master/DOCS

 

But the best way to learn is to play with it while you read.

 

Let me know if you have any questions.

 

Brian

Link to comment
Share on other sites

You should be able to use my fbForth font files (FBFONT, CHARA1FBF, CHAR@1FBF). They are 1 KiB (128 chars) or 2 KiB (256 chars), with char 0 as the first byte. If you find typical TI font files you can load them into the fbForth 2.0 font editor ( FONTED ), shift the frame offset for proper view and save them out in fbForth (Camel99) format. Of course, you can edit individual characters, as well.

 

...lee

Link to comment
Share on other sites

You should be able to use my fbForth font files (FBFONT, CHARA1FBF, CHAR@1FBF). They are 1 KiB (128 chars) or 2 KiB (256 chars), with char 0 as the first byte. If you find typical TI font files you can load them into the fbForth 2.0 font editor ( FONTED ), shift the frame offset for proper view and save them out in fbForth (Camel99) format. Of course, you can edit individual characters, as well.

 

...lee

 

Cool! I didn't know you had that feature. I have been editing up Asm data files exported from Magellan to get a some candidate fonts for general use.

It's a new world for me with the TI.

Link to comment
Share on other sites

Here is how the source code compiles and saves a Font file.

 

It's pretty convenient. This is FONT0230, but I tweaked the 'f',@ and '*" characters.

 

 

\ FONT0230  pattern source code for CAMEL99 Forth
NEEDS CALLCHAR   FROM DSK1.CALLCHAR
NEEDS SAVE-FONT  FROM DSK1.LOADSAVE

DECIMAL
32  S" 0000000000000000" CALLCHAR
33  S" 0010101010001000" CALLCHAR
34  S" 0028282800000000" CALLCHAR
35  S" 00287C28287C2800" CALLCHAR
36  S" 0038543018543800" CALLCHAR
37  S" 00444C1830644400" CALLCHAR
38  S" 0020502054483400" CALLCHAR
39  S" 0008102000000000" CALLCHAR
40  S" 0008101010100800" CALLCHAR
41  S" 0020101010102000" CALLCHAR
42  S" 000028107C102800" CALLCHAR
43  S" 0010107C10100000" CALLCHAR
44  S" 0000000000301020" CALLCHAR
45  S" 0000007C00000000" CALLCHAR
46  S" 0000000000303000" CALLCHAR
47  S" 0004081020400000" CALLCHAR
48  S" 0038444444443800" CALLCHAR
49  S" 0010301010103800" CALLCHAR
50  S" 0038440810207C00" CALLCHAR
51  S" 0038441804443800" CALLCHAR
52  S" 00081828487C0800" CALLCHAR
53  S" 0078407804443800" CALLCHAR
54  S" 0038407844443800" CALLCHAR
55  S" 007C040810202000" CALLCHAR
56  S" 0038443844443800" CALLCHAR
57  S" 003844443C047800" CALLCHAR
58  S" 0000303000303000" CALLCHAR
59  S" 0000303000301020" CALLCHAR
60  S" 0000102040201000" CALLCHAR
61  S" 0000007C007C0000" CALLCHAR
62  S" 0000100804081000" CALLCHAR
63  S" 0038440810001000" CALLCHAR
64  S" 00384C545C403C00" CALLCHAR
65  S" 003844447C444400" CALLCHAR
66  S" 0078447844447800" CALLCHAR
67  S" 0038444040443800" CALLCHAR
68  S" 0078444444447800" CALLCHAR
69  S" 007C407840407C00" CALLCHAR
70  S" 007C407840404000" CALLCHAR
71  S" 003844404C443800" CALLCHAR
72  S" 0044447C44444400" CALLCHAR
73  S" 0038101010103800" CALLCHAR
74  S" 0004040404443800" CALLCHAR
75  S" 0044485070484400" CALLCHAR
76  S" 0040404040407C00" CALLCHAR
77  S" 00446C5444444400" CALLCHAR
78  S" 00446454544C4400" CALLCHAR
79  S" 007C444444447C00" CALLCHAR
80  S" 0078444478404000" CALLCHAR
81  S" 00384444544C3C00" CALLCHAR
82  S" 0078444478484400" CALLCHAR
83  S" 0038443008443800" CALLCHAR
84  S" 007C101010101000" CALLCHAR
85  S" 0044444444443800" CALLCHAR
86  S" 0044444444281000" CALLCHAR
87  S" 0044444454542800" CALLCHAR
88  S" 0044281010284400" CALLCHAR
89  S" 0044442810101000" CALLCHAR
90  S" 007C081020407C00" CALLCHAR
91  S" 0038202020203800" CALLCHAR
92  S" 0000402010080400" CALLCHAR
93  S" 0038080808083800" CALLCHAR
94  S" 0010284400000000" CALLCHAR
95  S" 0000000000007C00" CALLCHAR
96  S" 0020100800000000" CALLCHAR
97  S" 0000003848483C00" CALLCHAR
98  S" 0020203824243800" CALLCHAR
99  S" 0000001C20201C00" CALLCHAR
100 S" 0004041C24241C00" CALLCHAR
101 S" 000000182C301C00" CALLCHAR
102 S" 000C103C10101000" CALLCHAR
103 S" 0000001C241C0438" CALLCHAR
104 S" 0020203824242400" CALLCHAR
105 S" 0010003010103800" CALLCHAR
106 S" 0008000808084830" CALLCHAR
107 S" 0020202438282400" CALLCHAR
108 S" 0030101010103800" CALLCHAR
109 S" 0000007854545400" CALLCHAR
110 S" 0000003824242400" CALLCHAR
111 S" 0000001824241800" CALLCHAR
112 S" 0000003824382020" CALLCHAR
113 S" 0000001C241C0404" CALLCHAR
114 S" 0000002834202000" CALLCHAR
115 S" 0000001C300C3800" CALLCHAR
116 S" 0010103810100C00" CALLCHAR
117 S" 0000002424241C00" CALLCHAR
118 S" 0000004428281000" CALLCHAR
119 S" 0000004454542800" CALLCHAR
120 S" 0000002418182400" CALLCHAR
121 S" 00000024241C0438" CALLCHAR
122 S" 0000003C08103C00" CALLCHAR
123 S" 000C10102010100C" CALLCHAR
124 S" 0010101000101010" CALLCHAR
125 S" 0060101008101060" CALLCHAR
126 S" 0000205408000000" CALLCHAR

S" DSK3.FONT0230" SAVE-FONT

 

 

  • Like 1
Link to comment
Share on other sites

Here is how the source code compiles and saves a Font file.

 

It's pretty convenient. This is FONT0230, but I tweaked the 'f',@ and '*" characters.

 

 

\ FONT0230  pattern source code for CAMEL99 Forth
NEEDS CALLCHAR   FROM DSK1.CALLCHAR
NEEDS SAVE-FONT  FROM DSK1.LOADSAVE

DECIMAL
32  S" 0000000000000000" CALLCHAR
33  S" 0010101010001000" CALLCHAR
34  S" 0028282800000000" CALLCHAR
35  S" 00287C28287C2800" CALLCHAR
36  S" 0038543018543800" CALLCHAR
37  S" 00444C1830644400" CALLCHAR
38  S" 0020502054483400" CALLCHAR
39  S" 0008102000000000" CALLCHAR
40  S" 0008101010100800" CALLCHAR
41  S" 0020101010102000" CALLCHAR
42  S" 000028107C102800" CALLCHAR
43  S" 0010107C10100000" CALLCHAR
44  S" 0000000000301020" CALLCHAR
45  S" 0000007C00000000" CALLCHAR
46  S" 0000000000303000" CALLCHAR
47  S" 0004081020400000" CALLCHAR
48  S" 0038444444443800" CALLCHAR
49  S" 0010301010103800" CALLCHAR
50  S" 0038440810207C00" CALLCHAR
51  S" 0038441804443800" CALLCHAR
52  S" 00081828487C0800" CALLCHAR
53  S" 0078407804443800" CALLCHAR
54  S" 0038407844443800" CALLCHAR
55  S" 007C040810202000" CALLCHAR
56  S" 0038443844443800" CALLCHAR
57  S" 003844443C047800" CALLCHAR
58  S" 0000303000303000" CALLCHAR
59  S" 0000303000301020" CALLCHAR
60  S" 0000102040201000" CALLCHAR
61  S" 0000007C007C0000" CALLCHAR
62  S" 0000100804081000" CALLCHAR
63  S" 0038440810001000" CALLCHAR
64  S" 00384C545C403C00" CALLCHAR
65  S" 003844447C444400" CALLCHAR
66  S" 0078447844447800" CALLCHAR
67  S" 0038444040443800" CALLCHAR
68  S" 0078444444447800" CALLCHAR
69  S" 007C407840407C00" CALLCHAR
70  S" 007C407840404000" CALLCHAR
71  S" 003844404C443800" CALLCHAR
72  S" 0044447C44444400" CALLCHAR
73  S" 0038101010103800" CALLCHAR
74  S" 0004040404443800" CALLCHAR
75  S" 0044485070484400" CALLCHAR
76  S" 0040404040407C00" CALLCHAR
77  S" 00446C5444444400" CALLCHAR
78  S" 00446454544C4400" CALLCHAR
79  S" 007C444444447C00" CALLCHAR
80  S" 0078444478404000" CALLCHAR
81  S" 00384444544C3C00" CALLCHAR
82  S" 0078444478484400" CALLCHAR
83  S" 0038443008443800" CALLCHAR
84  S" 007C101010101000" CALLCHAR
85  S" 0044444444443800" CALLCHAR
86  S" 0044444444281000" CALLCHAR
87  S" 0044444454542800" CALLCHAR
88  S" 0044281010284400" CALLCHAR
89  S" 0044442810101000" CALLCHAR
90  S" 007C081020407C00" CALLCHAR
91  S" 0038202020203800" CALLCHAR
92  S" 0000402010080400" CALLCHAR
93  S" 0038080808083800" CALLCHAR
94  S" 0010284400000000" CALLCHAR
95  S" 0000000000007C00" CALLCHAR
96  S" 0020100800000000" CALLCHAR
97  S" 0000003848483C00" CALLCHAR
98  S" 0020203824243800" CALLCHAR
99  S" 0000001C20201C00" CALLCHAR
100 S" 0004041C24241C00" CALLCHAR
101 S" 000000182C301C00" CALLCHAR
102 S" 000C103C10101000" CALLCHAR
103 S" 0000001C241C0438" CALLCHAR
104 S" 0020203824242400" CALLCHAR
105 S" 0010003010103800" CALLCHAR
106 S" 0008000808084830" CALLCHAR
107 S" 0020202438282400" CALLCHAR
108 S" 0030101010103800" CALLCHAR
109 S" 0000007854545400" CALLCHAR
110 S" 0000003824242400" CALLCHAR
111 S" 0000001824241800" CALLCHAR
112 S" 0000003824382020" CALLCHAR
113 S" 0000001C241C0404" CALLCHAR
114 S" 0000002834202000" CALLCHAR
115 S" 0000001C300C3800" CALLCHAR
116 S" 0010103810100C00" CALLCHAR
117 S" 0000002424241C00" CALLCHAR
118 S" 0000004428281000" CALLCHAR
119 S" 0000004454542800" CALLCHAR
120 S" 0000002418182400" CALLCHAR
121 S" 00000024241C0438" CALLCHAR
122 S" 0000003C08103C00" CALLCHAR
123 S" 000C10102010100C" CALLCHAR
124 S" 0010101000101010" CALLCHAR
125 S" 0060101008101060" CALLCHAR
126 S" 0000205408000000" CALLCHAR

S" DSK3.FONT0230" SAVE-FONT

 

 

 

Here are the character codes using fbForth 2.0’s CHAR :

 

 

\ FONT0230  pattern source code for CAMEL99 Forth
\ ..converted to fbForth 2.0

HEX
0000 0000 0000 0000 20 CHAR
0010 1010 1000 1000 21 CHAR
0028 2828 0000 0000 22 CHAR
0028 7C28 287C 2800 23 CHAR
0038 5430 1854 3800 24 CHAR
0044 4C18 3064 4400 25 CHAR
0020 5020 5448 3400 26 CHAR
0008 1020 0000 0000 27 CHAR
0008 1010 1010 0800 28 CHAR
0020 1010 1010 2000 29 CHAR
0000 2810 7C10 2800 2A CHAR
0010 107C 1010 0000 2B CHAR
0000 0000 0030 1020 2C CHAR
0000 007C 0000 0000 2D CHAR
0000 0000 0030 3000 2E CHAR
0004 0810 2040 0000 2F CHAR
0038 4444 4444 3800 30 CHAR
0010 3010 1010 3800 31 CHAR
0038 4408 1020 7C00 32 CHAR
0038 4418 0444 3800 33 CHAR
0008 1828 487C 0800 34 CHAR
0078 4078 0444 3800 35 CHAR
0038 4078 4444 3800 36 CHAR
007C 0408 1020 2000 37 CHAR
0038 4438 4444 3800 38 CHAR
0038 4444 3C04 7800 39 CHAR
0000 3030 0030 3000 3A CHAR
0000 3030 0030 1020 3B CHAR
0000 1020 4020 1000 3C CHAR
0000 007C 007C 0000 3D CHAR
0000 1008 0408 1000 3E CHAR
0038 4408 1000 1000 3F CHAR
0038 4C54 5C40 3C00 40 CHAR
0038 4444 7C44 4400 41 CHAR
0078 4478 4444 7800 42 CHAR
0038 4440 4044 3800 43 CHAR
0078 4444 4444 7800 44 CHAR
007C 4078 4040 7C00 45 CHAR
007C 4078 4040 4000 46 CHAR
0038 4440 4C44 3800 47 CHAR
0044 447C 4444 4400 48 CHAR
0038 1010 1010 3800 49 CHAR
0004 0404 0444 3800 4A CHAR
0044 4850 7048 4400 4B CHAR
0040 4040 4040 7C00 4C CHAR
0044 6C54 4444 4400 4D CHAR
0044 6454 544C 4400 4E CHAR
007C 4444 4444 7C00 4F CHAR
0078 4444 7840 4000 50 CHAR
0038 4444 544C 3C00 51 CHAR
0078 4444 7848 4400 52 CHAR
0038 4430 0844 3800 53 CHAR
007C 1010 1010 1000 54 CHAR
0044 4444 4444 3800 55 CHAR
0044 4444 4428 1000 56 CHAR
0044 4444 5454 2800 57 CHAR
0044 2810 1028 4400 58 CHAR
0044 4428 1010 1000 59 CHAR
007C 0810 2040 7C00 5A CHAR
0038 2020 2020 3800 5B CHAR
0000 4020 1008 0400 5C CHAR
0038 0808 0808 3800 5D CHAR
0010 2844 0000 0000 5E CHAR
0000 0000 0000 7C00 5F CHAR
0020 1008 0000 0000 60 CHAR
0000 0038 4848 3C00 61 CHAR
0020 2038 2424 3800 62 CHAR
0000 001C 2020 1C00 63 CHAR
0004 041C 2424 1C00 64 CHAR
0000 0018 2C30 1C00 65 CHAR
000C 103C 1010 1000 66 CHAR
0000 001C 241C 0438 67 CHAR
0020 2038 2424 2400 68 CHAR
0010 0030 1010 3800 69 CHAR
0008 0008 0808 4830 6A CHAR
0020 2024 3828 2400 6B CHAR
0030 1010 1010 3800 6C CHAR
0000 0078 5454 5400 6D CHAR
0000 0038 2424 2400 6E CHAR
0000 0018 2424 1800 6F CHAR
0000 0038 2438 2020 70 CHAR
0000 001C 241C 0404 71 CHAR
0000 0028 3420 2000 72 CHAR
0000 001C 300C 3800 73 CHAR
0010 1038 1010 0C00 74 CHAR
0000 0024 2424 1C00 75 CHAR
0000 0044 2828 1000 76 CHAR
0000 0044 5454 2800 77 CHAR
0000 0024 1818 2400 78 CHAR
0000 0024 241C 0438 79 CHAR
0000 003C 0810 3C00 7A CHAR
000C 1010 2010 100C 7B CHAR
0010 1010 0010 1010 7C CHAR
0060 1010 0810 1060 7D CHAR
0000 2054 0800 0000 7E CHAR
DECIMAL 

 

 

 

After running the above code, I invoked the Font Editor with FONTED , but, alas, the Font Editor initializes by unconditionally changing to Graphics mode, which reloads the current, default font, overwriting the just changed character codes. I should change the initializing code to not invoke Graphics mode if it is already there. That way codes could be changed with the above Forth code and output to a font file from the Font Editor.

 

On second thought, it would be easy enough to write a word like yours that saves a font. The Font Editor is, after all, for editing existing fonts. |:) There is already a way to change the current font by loading a font file, viz., “ USEFFL DSKn.<fontfile> ” followed by FNT . And, if you only want to edit a font, it can be loaded into the Font Editor without changing the current, default font. But, I digress...

 

...lee

  • Like 1
Link to comment
Share on other sites

 

Here are the character codes using fbForth 2.0’s CHAR :

 

 

\ FONT0230  pattern source code for CAMEL99 Forth
\ ..converted to fbForth 2.0

HEX
0000 0000 0000 0000 20 CHAR
0010 1010 1000 1000 21 CHAR
0028 2828 0000 0000 22 CHAR
0028 7C28 287C 2800 23 CHAR
0038 5430 1854 3800 24 CHAR
0044 4C18 3064 4400 25 CHAR
0020 5020 5448 3400 26 CHAR
0008 1020 0000 0000 27 CHAR
0008 1010 1010 0800 28 CHAR
0020 1010 1010 2000 29 CHAR
0000 2810 7C10 2800 2A CHAR
0010 107C 1010 0000 2B CHAR
0000 0000 0030 1020 2C CHAR
0000 007C 0000 0000 2D CHAR
0000 0000 0030 3000 2E CHAR
0004 0810 2040 0000 2F CHAR
0038 4444 4444 3800 30 CHAR
0010 3010 1010 3800 31 CHAR
0038 4408 1020 7C00 32 CHAR
0038 4418 0444 3800 33 CHAR
0008 1828 487C 0800 34 CHAR
0078 4078 0444 3800 35 CHAR
0038 4078 4444 3800 36 CHAR
007C 0408 1020 2000 37 CHAR
0038 4438 4444 3800 38 CHAR
0038 4444 3C04 7800 39 CHAR
0000 3030 0030 3000 3A CHAR
0000 3030 0030 1020 3B CHAR
0000 1020 4020 1000 3C CHAR
0000 007C 007C 0000 3D CHAR
0000 1008 0408 1000 3E CHAR
0038 4408 1000 1000 3F CHAR
0038 4C54 5C40 3C00 40 CHAR
0038 4444 7C44 4400 41 CHAR
0078 4478 4444 7800 42 CHAR
0038 4440 4044 3800 43 CHAR
0078 4444 4444 7800 44 CHAR
007C 4078 4040 7C00 45 CHAR
007C 4078 4040 4000 46 CHAR
0038 4440 4C44 3800 47 CHAR
0044 447C 4444 4400 48 CHAR
0038 1010 1010 3800 49 CHAR
0004 0404 0444 3800 4A CHAR
0044 4850 7048 4400 4B CHAR
0040 4040 4040 7C00 4C CHAR
0044 6C54 4444 4400 4D CHAR
0044 6454 544C 4400 4E CHAR
007C 4444 4444 7C00 4F CHAR
0078 4444 7840 4000 50 CHAR
0038 4444 544C 3C00 51 CHAR
0078 4444 7848 4400 52 CHAR
0038 4430 0844 3800 53 CHAR
007C 1010 1010 1000 54 CHAR
0044 4444 4444 3800 55 CHAR
0044 4444 4428 1000 56 CHAR
0044 4444 5454 2800 57 CHAR
0044 2810 1028 4400 58 CHAR
0044 4428 1010 1000 59 CHAR
007C 0810 2040 7C00 5A CHAR
0038 2020 2020 3800 5B CHAR
0000 4020 1008 0400 5C CHAR
0038 0808 0808 3800 5D CHAR
0010 2844 0000 0000 5E CHAR
0000 0000 0000 7C00 5F CHAR
0020 1008 0000 0000 60 CHAR
0000 0038 4848 3C00 61 CHAR
0020 2038 2424 3800 62 CHAR
0000 001C 2020 1C00 63 CHAR
0004 041C 2424 1C00 64 CHAR
0000 0018 2C30 1C00 65 CHAR
000C 103C 1010 1000 66 CHAR
0000 001C 241C 0438 67 CHAR
0020 2038 2424 2400 68 CHAR
0010 0030 1010 3800 69 CHAR
0008 0008 0808 4830 6A CHAR
0020 2024 3828 2400 6B CHAR
0030 1010 1010 3800 6C CHAR
0000 0078 5454 5400 6D CHAR
0000 0038 2424 2400 6E CHAR
0000 0018 2424 1800 6F CHAR
0000 0038 2438 2020 70 CHAR
0000 001C 241C 0404 71 CHAR
0000 0028 3420 2000 72 CHAR
0000 001C 300C 3800 73 CHAR
0010 1038 1010 0C00 74 CHAR
0000 0024 2424 1C00 75 CHAR
0000 0044 2828 1000 76 CHAR
0000 0044 5454 2800 77 CHAR
0000 0024 1818 2400 78 CHAR
0000 0024 241C 0438 79 CHAR
0000 003C 0810 3C00 7A CHAR
000C 1010 2010 100C 7B CHAR
0010 1010 0010 1010 7C CHAR
0060 1010 0810 1060 7D CHAR
0000 2054 0800 0000 7E CHAR
DECIMAL 

 

 

 

After running the above code, I invoked the Font Editor with FONTED , but, alas, the Font Editor initializes by unconditionally changing to Graphics mode, which reloads the current, default font, overwriting the just changed character codes. I should change the initializing code to not invoke Graphics mode if it is already there. That way codes could be changed with the above Forth code and output to a font file from the Font Editor.

 

On second thought, it would be easy enough to write a word like yours that saves a font. The Font Editor is, after all, for editing existing fonts. | :) There is already a way to change the current font by loading a font file, viz., “ USEFFL DSKn.<fontfile> ” followed by FNT . And, if you only want to edit a font, it can be loaded into the Font Editor without changing the current, default font. But, I digress...

 

...lee

 

 

Ah well... If nothing else it keeps us thinking about system enhancements. I am happy something I did struck a little chord. :-)

 

I am always amazed at how difficult it is to keep all the assumptions we make in some kind of sensible balance. (regarding selecting graphics mode which reloaded the font)

 

I have tried to for years to keep the Forth philosophy in mind and make words do something simple so I can re-combine them in different ways later, but it's still a challenge. It really flies in the face of current software trends but I think Chucks thinking has merit.

 

I attribute the conflict between the two camps to the fact that you can't "concatenate" (spelling checked) code together in conventional languages, like we can in Forth, so it's simpler to wrap things up in a big function and select code with input parameters.

 

But now I digress...

  • Like 3
Link to comment
Share on other sites

Direct Threading vs Indirect Threading in Two Numbers

 

I managed to get most of my Direct threaded Forth code to run. I had made a lot of changes over the past year to the primary code base so it took a bit of work.

The only outstanding bug is CREATE DOES> which I don't think I had working before either.

 

The point of this post is to show the biggest difference between the two threading mechanisms.

CAMEL99 Forth has the 9901 internal timer running continuously without interrupts so your can grab a time stamp anytime you want with TMR@.

 

The good thing about this is that the timer can measure things with a 21.3 micro-second resolution.

The downside is that you can only measure things that happen in less than 325mS.

 

I used the timer to measure the speed of the "inner" interpreter in both Forth systems simply by compiling a word that calls the timer twice.

By subtracting the two values we get the speed it took for Forth to get from one Forth word to the next one.

The screen captures tell the story nicely.: ITC= 3 ticks or about 64 uS vs DTC= 2 ticks or about 43uS.

 

The direct threading mechanism is only 2 instructions vs 3 for indirect threading.

 

The good news about direct threading is that every CODE word created with Forth Assembler uses 2 LESS bytes.

The bad news about direct threading is that every Forth word uses 4 MORE bytes in the definition.

 

The net speed-up of empty loops is about 25% however with real applications it seems closer to 10%.

 

In a memory constrained system like TI-99 ITC is probably a better choice for most applications.

 

 

post-50750-0-34195100-1543505972.jpg

post-50750-0-13899700-1543505980.jpg

  • Like 1
Link to comment
Share on other sites

I found a little benchmark program called BENCHIE. I replaced the VALUE in the original with a variable to make it simpler to use across multiple Forth systems.

Here is code. It iterates 65536 times from what I can understand. or not :-)

5 CONSTANT FIVE
VARIABLE VAR  
HEX
100 CONSTANT MASK
: BENCHIE      
         MASK 0
         DO
            1
            BEGIN
              DUP SWAP DUP ROT DROP 1 AND
              IF FIVE +
              ELSE 1-
              THEN VAR !
              VAR @ DUP MASK AND
            UNTIL
            DROP
         LOOP ;

Here are some results:

 

FB Forth :47.2

Turbo Forth :26.9

Camel99 ITC : 28.3

Camel99 DTC :25.3

 

You can see the benefit of all those stack primitives living in scratch-pad RAM in Turbo Forth.

I believe FB Forth is slower because of the legacy threading mechanism used in Forth Interest Group (FIG) Forth.

 

Here is the published result for the only CPU from a similar era as 9900.

> 8051 ANS Forth (12 MHz 80C535): 126 bytes 15,8 sec

 

This makes the 9900 look pretty good, running 1/2 speed with 1/4 the clock speed!

Edited by TheBF
Link to comment
Share on other sites

I believe FB Forth is slower because of the legacy threading mechanism used in Forth Interest Group (FIG) Forth.

 

I would bet fbForth 2.0's slower performance will be improved by disabling its ISR. It is not necessary unless speech or sound is to be processed. The ISR can be disabled with

HEX 0 83C4!

I probably should have disabled the ISR as the startup default. Oh, well.

 

...lee

Link to comment
Share on other sites

 

I would bet fbForth 2.0's slower performance will be improved by disabling its ISR. It is not necessary unless speech or sound is to be processed. The ISR can be disabled with

HEX 0 83C4!

I probably should have disabled the ISR as the startup default. Oh, well.

 

...lee

 

I will try it, but I keep interrupts running all the time as well.

 

I forget the details but I remember reading a long time ago about the way FIG-FORTH does the entry routines for colon, variable, constant and user have extra overhead.

 

For example here are my definitions for the various data "creators". The runtime address is compiled inline.

I believe that is different in FIG implementations.

: CONSTANT  ( n --)  HEADER  COMPILE DOCON     , ;  
: USER      ( n --)  HEADER  COMPILE DOUSER    , ; 
: CREATE    ( -- )   HEADER  COMPILE DOVAR       ; 
: VARIABLE  ( -- )   CREATE                  0 , ; 
Edited by TheBF
Link to comment
Share on other sites

Nov 30, 2018 V2.1.F Camel99 Forth Update
  • COMPILER CHANGE: To handle ITC and DTC versions the cross-compiler "word creators"
    are kept in separate files and are included in the Forth system source code as required.
    Documentation is forth coming. See: compiler/ITCTYPES.HSF and compiler/DTCTYPES.HSF
  • Source file CAMEL99F.HSF now has a compiler switch: SMALLER
  • Uses more Forth words to save space when set to TRUE
  • Uses more CODE words if SMALLER is set to FALSE. SMALLER saves ~46 bytes, but runs a little slower.
  • Addition of CALLCHAR and LOADSAVE libraries allows compiling FONT
    information into binary font files that load into VDP ram in 1 second.
  • Font file source code examples are in FONTS folder. Compiled binary versions are in DSK3.
  • Addition of a direct threaded code (DTC) version (DSK1.CAM99DTC) that runs about 10% faster.
    *Note* CREATE DOES> is not functional in the DTC version at this time.
Edited by TheBF
  • Like 1
Link to comment
Share on other sites

Here are some results:

 

FB Forth :47.2

Turbo Forth :26.9

Camel99 ITC : 28.3

Camel99 DTC :25.3

 

You can see the benefit of all those stack primitives living in scratch-pad RAM in Turbo Forth.

I believe FB Forth is slower because of the legacy threading mechanism used in Forth Interest Group (FIG) Forth.

 

Here is the published result for the only CPU from a similar era as 9900.

> 8051 ANS Forth (12 MHz 80C535): 126 bytes 15,8 sec

 

This makes the 9900 look pretty good, running 1/2 speed with 1/4 the clock speed!

Yay! Go TurboForth. :-D You're correct of course. This particular routine is performing a fair amount of stackrobatics in the loop, which TF will benefit from. If this were a demo of something like... Oh I dunno, calculating PI using fixed point (for example) then all bets are off!

 

While I'm here, I'd like to apologise for my lack of input to Atariage. I'm still lurking here almost every day, however my life has entered a particulalry busy stage at the moment. I'm (happily) married with two young children still at home, and I work away during the week, so weekends are all about the wife and children. They're only little once and I want to enjoy it. I'm also undertaking a Masters degree with the University of Liverpool (Software Engineering) and it's very demanding as you can imagine. I don't have a lot of head-space for hobby things right now, more's the pity. However, please rest assured I'm still lurking, especially the Forth threads, which is my main area of interest now on the TI, and on CLF.

 

Cheers :thumbsup:

 

Mark

  • Like 2
Link to comment
Share on other sites

"I'm also undertaking a Masters degree with the University of Liverpool (Software Engineering) and it's very demanding as you can imagine. "

 

 

 

Hey Mark,

 

Does your thesis have anything to do with Forth or stack machines?

 

(Had to ask)

 

B

Edited by TheBF
Link to comment
Share on other sites

I saw an blank spot on Rosetta code for the Magic8ball program in Forth so I took up the challenge using a variation of a fast case statement/vector table invented by the late James T. Kalihan the author of HsForth.

It works a little like ONGOTO in BASIC but instead of line numbers it use the ** "execution token" of a Forth word and "EXECUTEs" it.

 

** (a memory address in CAMEL99 Forth)

 

I love the simplicity of it.

 

Here is the CAMEL99 Forth version.

\ magic eight ball Rosetta Code

INCLUDE DSK1.RANDOM

\ for GFORTH
\ INCLUDE RANDOM.FS

DECIMAL
: CASE:  ( -- -7)   CREATE   ;
: ;CASE   ( n -- )  DOES>  SWAP CELLS +  @ EXECUTE ;

: VECTORS  0  DO  , LOOP ;

:NONAME   ." It is certain" ;
:NONAME   ." It is decidedly so" ;
:NONAME   ." Without a doubt" ;
:NONAME   ." Yes, definitely" ;
:NONAME   ." You may rely on it" ;
:NONAME   ." As I see it, yes." ;
:NONAME   ." Most likely" ;
:NONAME   ." Outlook good" ;
:NONAME   ." Signs point to yes." ;
:NONAME   ." Yes." ;
:NONAME   ." Reply hazy, try again" ;
:NONAME   ." Ask again later" ;
:NONAME   ." Better not tell you now" ;
:NONAME   ." Cannot predict now" ;
:NONAME   ." Concentrate and ask again" ;
:NONAME   ." Don't bet on it" ;
:NONAME   ." My reply is no"  ;
:NONAME   ." My sources say no" ;
:NONAME   ." Outlook not so good" ;
:NONAME   ." Very doubtful" ;

CASE: MAGIC8BALL  20 VECTORS  ;CASE

: GO   
       CR ." Please enter your question or a blank line to quit."
       BEGIN CR ." ? :" PAD 80 ACCEPT 0>
       WHILE CR 19 RND MAGIC8BALL CR
       REPEAT ;

post-50750-0-43774900-1543694839.jpg

Edited by TheBF
Link to comment
Share on other sites

A Better Elapsed Timer

 

I was looking at an old copy of **"STARTING FORTH" the seminal training text book to study to get acquainted with Forth. It demonstrated a time formatting number that used BASE 60 to compute the correct digits for minutes and hours.

Huh! I had not remembered that from 1985 when I bought the book :)

 

If you compare the code here: http://atariage.com/forums/topic/273872-camel99-forth-information-goes-here/?p=3935777

You can see the simplification with this version.

The input parameter is an integer in hundredths of a second.

After formatting hundredths and tenths as DECIMAL digits, we switch to SEXTAL math and the # routine computes the correct digits for minutes.

Amazing!

HEX
83D6 CONSTANT TICKER   \ screen timeout counter increments by 2 /16mS
DECIMAL
: SEXTAL   60 BASE ! ;
: ':'     [CHAR] : HOLD ;
: '.'     [CHAR] . HOLD ;

: .TIME   ( n -- )
          BASE @ >R    ( save the current number base on return stack)
          0 <#  DECIMAL # # '.'  # # ':' SEXTAL # #   #> TYPE
          R> BASE ! ;  (  restore the old number base from return stack)

: .ELAPSED ( -- )  CR ." Elapsed time =" TICKER @ 5 6 */ .TIME ;

: ELAPSE   ( -- <text> ) 1 PARSE  TICKER OFF  EVALUATE .ELAPSED ;

The secret lies in the Forth number formatting words which are so deceptively simple it's hard to believe they create arbitrary number formatting in about 120 bytes of code!

Rather than use patterning matching like most languages use (###.##) Chuck Moore does it with simple code routines.

 

The one thing that puts people off is that the number is formatted from the smallest values to the largest which is right to left.

BUT the code runs from left to right so you have to think of the number backwards to understand the code format. Hey, "Forth though is this!" :-D

 

For the very curious the spoiler has the formatting words with comments about these functions.

If you study them, they could be implemented in assembly language without much problem.

 

VARIABLE HP  \ "hold pointer" points to where the next character goes in the buffer

\ decr. HP, Store char at the address contained in HP
: HOLD   ( char -- ) -1 HP +! HP @ C! ;

: >DIGIT ( n -- c) DUP 9 > 7 AND + 30 + ;   \ convert n to ascii digit c

\ initialize Hold Pointer to end of the number buffer
: <#     ( --)    PAD HP ! ;

\ convert 1 digit in ud1, place in HOLD buffer
: #      ( ud1 -- ud2)  BASE @ UD/MOD ROT  >DIGIT  HOLD  ;  

\ convert all digits in ud1. ud2 will be 0 on completion
: #S     ( ud1 -- ud2)  BEGIN   # 2DUP OR    0= UNTIL ;     

\ return a stack string (address, length)  of the converted number
: #>     ( ud1 -- caddr u) 2DROP HP @ PAD OVER - ;         

\ if 'n'<0  add '-' char  string created in #PAD
: SIGN   ( n -- ) 0< IF [CHAR] -  HOLD THEN ;

\ **Use the above words to create some number printer words**
\ print 'd' as an un-signed 32 bit integer
: DU.     ( d -- )   <#  #S  #>  TYPE SPACE ; 

\ print an unsigned integer. The '0' converts u to a double (32bit)
: U.     ( u -- ) 0  DU. ;  

\ "dot" prints n as signed integer
: .      ( n -- ) DUP ABS 0  <# #S ROT SIGN #> TYPE SPACE ; 

 

*** Edit fixed the book title Starting Forth, Leo Brodie

Edited by TheBF
  • Like 2
Link to comment
Share on other sites

Forced to drink my own Koolaid

 

I have a dream of running CAMEL Forth from my PC over the RS232 port. I did this many years ago with TI Forth with a 2nd hand dumb terminal that I found at an electronics surplus store. At that time I didn't understand how to vector the I/O primitives so I wrote a lot more code than necessary but it was fun.

 

CAMEL99 Forth steals the top part of scratch pad for user variables. (task specific variables)

This means, from what I can read, that the RS232 DSR will not work. An in fact the RS232 DSR is not ideal for a multi-tasking Forth system. I need primitives that will give up the system while they are waiting for I/O to complete.

 

No problem. I will just write my own 9902 chip driver thought I.

 

Doing that has forced me to develop on real hardware for the first time in a while.

What a shock! Oh how I miss the built-in editor of TI-Forth. :(

 

In my initial thoughts on making a more modern Forth for TI-99 I believed that the "edit, load Forth, compile file, run code, loop" would be so much better than the Assembler process that it would be ok. I forgot how slow the floppy disk really is.

 

(Note: I discovered that CAMEL99 Forth can compile a file from floppy disk in about the same time that EDIT1 takes to save that file to floppy disk. :-D It still sucks )

 

All that to say that I need to make an integrated editor for CAMEL99 Forth. I am considering a few options:

  1. Re-build EDIT40 as a binary "overlay" that I start from within Forth
  2. Write a binary overly program in cross-compiled Forth
  3. Write the editor in ANS Forth and have it compile into the system and stay resident.

I am leaning towards just writing it in ANS Forth. I wrote a block editor 35 years ago for MVP Forth that I ported and added to

but I can see with new eyes that it is not great code so I think I start from scratch.

 

I have never written an editor for files and I can see there are some other considerations in a memory constrained system that I need to address. Forth BLOCKS are real virtual memory so it is much simpler. However files offer advantages that I like.

 

So drinking my own Koolaid means I need to write an editor to be anywhere near as useful as the IDE provided by FBForth and TurboForth.

 

Such a humbling hobby is this...

  • Like 1
Link to comment
Share on other sites

Though it is a massive 2.3 KiB (in ROM space :P ), you are certainly welcome to port the editor source code of fbForth 2.0 in fbForth105_Editor4080.a99.

 

...lee

 

2.3Kb would not be unreasonable.

I am struggling with how to organize the different memory spaces for best use considering I want a resident editor and enough space to hold a reasonable file size.

Keeping the raw file data in VDP Ram is temping but I will have to do some tests with inserting variable lines lengths into VDP ram. That could be very slow.

The alternative is maintaining all the VDP text as linked lists which makes me weak in the knees.

 

I probably should just use low mem for the data and limit the file size to 6K bytes, keeping room there for an undo/copy/delete stack.

 

I have made a fast text file reader that moves the PAB file buffer through VDP ram depending on the length of the text line.

Probably the most innovative part of that is that I fill the VDP Ram with end-of-line delimiters, and then write over them.

This makes the data automatically delimited!

HEX
  0D CONSTANT ^M         \ carriage return
  1A CONSTANT ^Z         \ end of Text file marker
1138 CONSTANT REC#1      \ Free VDP ram after pattern table
2500 CONSTANT MEM-SIZE   \ 9,472 bytes is largest file

     VARIABLE ELINES     \ count editor lines

: READ-REC    ( -- ) 2 FILEOP ?FILERR ;
: NEXT-BUFFER ( -- )     \ advance buffer by rec. len+1
              [PAB FBUFF]        \ current VDP buffer pointer
              [PAB CHARS] VC@    \ fetch last line length
              OVER V@ + 1+       \ calc. new buffer. 1+ makes room for ^M delimiter
              SWAP V! ;          \ change the VDP buffer pointer 

: READ-FILE  ( $addr len -- ior)
             ELINES OFF
             REC#1 MEM-SIZE ^M VFILL     \ fill space CR char
             R/O OPEN-FILE ?FILERR  >R   \ file handle to rstack
             REC#1 [PAB FBUFF] V!        \ set VDP buffer address
             BEGIN
                R@ EOF 0=
             WHILE
                READ-REC
                ELINES 1+!
                NEXT-BUFFER
             REPEAT
             R> CLOSE-FILE ;
  • Like 1
Link to comment
Share on other sites

Taming the TMS9902, FORTH Style

 

Many years ago I read an article in Forth Dimensions magazine called something like "Menu Driving the 8250 UART".

This really got under my skin because menus are not the way you do things with Forth.

In Forth you make WORDS to control the computer. Words are infinitely more useful than a menu driven program to setup a piece of hardware.

So I wrote a "counter-article" called "8250 UART Revisited.

 

In the article I detailed how to calculate the baud rate divisor for a given BAUD rate and showed words to configure the UART like this:

 

COM1: 9600 BAUD 8 BITS EVEN PARITY 1 STOP-BITS

 

I think I have that working for 9902 now. I shortened the name STOP-BITS to STOPS to save a few precious TI-99 bytes.

I further simplified the BAUD word by eliminating 110 BAUD and 300 BAUD. I won't be using them, :) however the programmer could manually set the BPS variable if that was needed.

 

The spoiler has the source for the entire RS232 driver. These will ultimately be used to create a TTY terminal task that will control the system from the comfort of my PC.

HEX
      1300 CONSTANT RS232    \ card address
RS232 40 + CONSTANT PORT1    \ 40= 9902#1,
RS232 80 + CONSTANT PORT2    \ 80= 9902#2

\ configuration variables
      VARIABLE BPS         \ bits per sec
      VARIABLE PROTOCOL    \ 8 BITS ODD PARITY
      VARIABLE PORT

DECIMAL
: 499200. ( -- d) 40488 7 ;   \ double precision literal

: BAUD   ( n -- )
         DUP 600 < ABORT" BAUD rate!"       \ 600..19200 only
         499200. ROT UM/MOD NIP  BPS ! ;

: PROTOCOL! ( n -- ) PROTOCOL @ OR PROTOCOL ! ;

: STOPS  ( n -- ) \ bits 7 & 6
          3 - ABS
          2 OVER U< ABORT" stop bits!"
          6 LSHIFT  PROTOCOL! ;

: BITS  ( n -- ) \ bits 1 & 0
        5 -  4 OVER U< ABORT" data bits!"
        PROTOCOL!  ;

2 BASE !
00010000 CONSTANT NO
00100000 CONSTANT EVEN
00110000 CONSTANT ODD

HEX
: PARITY  ( n -- ) \ bit 5 & 4
          DUP NO ODD 1+ WITHIN 0= ABORT" Bad parity!"
          PROTOCOL! ;

 

 

\ CAMEL99 FORTH TMS9902 RS232/1 direct CRU communication 07DEC18 BJF

NEEDS DUMP  FROM DSK1.TOOLS
NEEDS CRU!  FROM DSK1.CRU2

HEX
      1300 CONSTANT RS232    \ card address
RS232 40 + CONSTANT PORT1    \ 40= 9902#1,
RS232 80 + CONSTANT PORT2    \ 80= 9902#2

\ 9902 control bits
DECIMAL
      13 CONSTANT LDIR     \ load interval register
      16 CONSTANT RTSON    \ request to send
      18 CONSTANT RIENB    \ rcv interrupt enable
      21 CONSTANT RXRL     \ receive register loaded bit
      22 CONSTANT TXRE     \ transmit register empty bit
      27 CONSTANT -DSR     \ NOT data set ready
\      28 CONSTANT -CTS     \ NOT clear to send
      31 CONSTANT RESET    \ reset the UART

\ configuration variables
      VARIABLE BPS         \ bits per sec
      VARIABLE PROTOCOL    \ 8 BITS ODD PARITY
      VARIABLE PORT

DECIMAL
: 499200. ( -- d) 40488 7 ;   \ double precision literal

: BAUD   ( n -- )
         DUP 600 < ABORT" BAUD rate!"       \ 600..19200 only
         499200. ROT UM/MOD NIP  BPS ! ;

: PROTOCOL! ( n -- ) PROTOCOL @ OR PROTOCOL ! ;

: STOPS  ( n -- ) \ bits 7 & 6
          3 - ABS
          2 OVER U< ABORT" stop bits!"
          6 LSHIFT  PROTOCOL! ;

: BITS  ( n -- ) \ bits 1 & 0
        5 -  4 OVER U< ABORT" data bits!"
        PROTOCOL!  ;

2 BASE !
00010000 CONSTANT NO
00100000 CONSTANT EVEN
00110000 CONSTANT ODD

HEX
: PARITY  ( n -- ) \ bit 5 & 4
          DUP NO ODD 1+ WITHIN 0= ABORT" Bad parity!"
          PROTOCOL! ;

: CARD    ( cru -- )
          CRU@ OVER <>  \ is this a new card?
          IF   0SBZ     \ yes, turn off current card
          THEN CRU! ;   \ then select new card

: RS232-ON  ( -- ) RS232 CARD  0SBO  7 SBO ;
: RS232-OFF ( -- ) RS232 CARD  0SBZ  7 SBZ ;

: OPEN-TTY ( -- )   \ Use: PORT1 OPEN-TTY
          BPS @  0= ABORT" Baud err"
          PORT @ 0= ABORT" Port err"
          PROTOCOL @ 0= ABORT" Protocol err"

          RS232-ON
          PORT @ CRU!               \ chip is base address
          RESET SBO  10 MS          \ reset 9902 chip & wait
          PROTOCOL @ 8 PORT @ LDCR  \ 8 bits, Odd, 1 stop
          LDIR SBZ                  \ interval timer off
          BPS @  0C PORT @ LDCR     \ set RX/TX baud (12 bits)
          RS232-OFF ;

: ?TTYBRK  ( -- ) ?TERMINAL ABORT" TTY stopped" ;

: TTYEMIT   ( c -- ) \ with RTS handshake
\     7F AND
     RS232-ON
     PORT @ CRU!
     BEGIN
       BEGIN
         RTSON SBO
        -DSR TB INVERT
       WHILE
         PAUSE
         ?TTYBRK
       REPEAT
       TXRE TB
     UNTIL
     8 PORT @ LDCR  \ send byte
     RTSON SBZ      \ clear tx buffer
     1 OUT +!       \ count character
     RS232-OFF ;

: TTYKEY ( -- n)
          RS232-ON
          PORT @ CRU!
          BEGIN
            PAUSE
            RXRL TB
          UNTIL
          8 PORT @ STCR
          RIENB SBZ
          RS232-OFF ;

HEX
: TTYCR    ( -- ) 0D TTYEMIT 0A TTYEMIT   OUT OFF ;
: TTY-TYPE ( adr len -- ) BOUNDS DO I C@ TTYEMIT LOOP ;

: TTY1:  ( -- ) PORT1 PORT !   PROTOCOL OFF   BPS OFF ;

CR .( Opening TTY1)
DECIMAL
 TTY1: 9600 BAUD  8 BITS  ODD PARITY  1 STOPS  
 OPEN-TTY

CR .( Done!)

CR .( TESTERS...)
DECIMAL
: TCHARS TTYCR 127 32 DO I TTYEMIT LOOP TTYCR ;

: TESTRUN  BEGIN TCHARS ?TERMINAL UNTIL ;


 

 

 

  • Like 2
Link to comment
Share on other sites

Phwoar! This is really cool. I never got a chance to look at serial. Do you mind if I use this this code (with attribution, of course) for TurboForth?

 

Would you mind posting some example outputs from BAUD (i.e the value that gets written into BPS) for some example baud rates? I need to check UM/MOD implementation in TF :-)

 

Also, can you post your code for MS if you don't mind? :-)

 

It'll give me something to look at over Christmas (along with Lee's recent work of CF7 and variants) now that uni has stopped until January.

 

Thanks

 

Mark

Edited by Willsy
  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...