-
Posts
4,465 -
Joined
-
Last visited
Content Type
Profiles
Forums
Blogs
Gallery
Events
Store
Posts posted by TheBF
-
-
VT100 driver Change
While working on porting an editor to TTY control I did a re-read of the control code specs and discovered that the terminal assumes cursor home is coordinates (1,1).
Standard Forth AT-XY (and GOTOXY in TI-Forth, FbForth and TurboForth) assumes home is (0,0).
I have modified a couple of words in my code to compensate. This has made my porting of the editor code way easier.
The word AT-XY is modified below:
CR .( VT100 terminal control, [0,0] Home coordinates May 2020 ) DECIMAL \ type 'n' as a two digit number in base 10, with no space : <##> ( n -- ) BASE @ >R \ save radix 0 <# DECIMAL # # #> TYPE \ convert to 2 digits & print R> BASE ! ; \ restore radix \ markup language for terminal control codes : <ESC> ( -- ) 27 EMIT ; : <ESC>[ ( -- ) <ESC> 91 EMIT ; : <UP> ( n -- ) <ESC>[ <##> ." A" ; : <DOWN> ( n -- ) <ESC>[ <##> ." B" ; : <RIGHT> ( n -- ) <ESC>[ <##> ." C" ; : <BACK> ( n -- ) <ESC>[ <##> ." D" ; : <HOME> ( -- ) <ESC>[ ." H" 0 0 VROW 2! ; \ define Forth words using markup words : PAGE ( n -- ) <ESC>[ ." 2J" <HOME> ; : AT-XY ( col row --) 2DUP VROW 2! \ store col,row <ESC>[ 1+ <##> ." ;" 1+ <##> ." f" ;
And the word <SCROLLROWS> below has been correct to reflect 0,0 screen home. <SCROLLROWS> is pretty cool. It lets you set a section of the screen that scrolls between rstart row and rend row.
CR .( VT100+.FTH extended terminal control) NEEDS <##> FROM DSK1.VT100 DECIMAL \ reset the terminal, clear screen & buffer : <RESETVT100> ( -- ) <ESC> [CHAR] c EMIT ; \ More VT100 terminal controls : <SCROLLALL> ( -- ) <ESC>[ ." r" ; \ Enable scrolling for entire display. \ Enable scrolling from row {start} to row {end}. [0,0] IS HOME !! : <SCROLLROWS> ( rstart rend-- ) SWAP <ESC>[ 1+ <##> ." ;" 1+ <##> ." r" ; : <SCROLLDOWN> ( -- ) <ESC> [CHAR] D EMIT ; \ Scroll display down one line. : <SCROLLUP> ( -- ) <ESC> [CHAR] M EMIT ; \ Scroll display up one line. \ Erasing Text : <ERASERIGHT> <ESC>[ ." K" ; \ Erase from cursor to end of line : <ERASELEFT> <ESC>[ ." 1K" ; \ Erase from Cursor to start of line : <ERASELINE> <ESC>[ ." 2K" ; \ Erases the entire current line : <ERASEDOWN> <ESC>[ ." J" ; \ Erases screen from current line down : <ERASEUP> <ESC>[ ." 1J" ; \ Erases screen from current line up
- 1
-
14 hours ago, Tursi said:
Yeah, don't launch programs with interrupts enabled - a lot of software will break.
To be sure I was abiding by this I checked. Camel99 enters it's first code to create the virtual machine.
(set workspace, init 3 registers, write some code into scratchpad and init 1 memory location)
Interrupts are off by default from E/A 5 as mentioned.
I don't enable interrupts until I start Forth and load a value into the 9901 timer. When that code exits it enables interrupts.
So more by ignorance than design, back when I made this thing I did follow this advice.
-
35 minutes ago, Tursi said:
Yeah, don't launch programs with interrupts enabled - a lot of software will break.
Noted. Thanks!
-
Thank you for the clarification.
I always appreciate your details.
- 1
-
9 hours ago, jedimatt42 said:
It is likely something I'm not initializing in my EA5 loader built into the TIPI DSR ROM...
It works fine from loading from TIPI, but using the EA5 loader in the actual Editor/Assembler GROM.
The only interrupt'y stuff I mess with in that process is LIMI 0.. My loader is probably leaving LIMI 0. unmasking what you need would probably protect your program from my bad-behavior... I was, under the impression that EA left interrupts off before launching into the loaded image, but I must have measured that wrong... I will likely update the DSR on TIPI to fix this, cause my intention is for CALL TIPI to be as close to EA option 5 loading as is reasonable.
I think Lee has clarified "normal" from the sacred text, so please don't change your code on my account.
I am the wild card. I have re-built and reverted back to using the 9901 timer which is how it was since Version 2 of this project began. That gave some problems in Classic99 at one point but it has long since been fixed.
My motivation for these step-wise changes has been exploring removing bytes from the kernel to have more space for user programs. I think I am at the end of that exercise.
If it ain't broke etc...
- 1
-
6 hours ago, Lee Stewart said:
On page 164 of the E/A Manual it says
The instruction, “LIMI 0”, disables all interrupts and is the normal state of the computer.
And, in fact, any program started by the E/A loader will have interrupts disabled unless the loaded program enables them.
If interrupts are enabled, the console interrupt routine increments the screen timer (>83D6, interrupt workspace R11) by 2 each interrupt. The screen timer is reset by the console’s KSCAN at every keystroke if the loaded program uses KSCAN for keyboard input. I cannot imagine how TIPI would be affecting the screen timer.
...lee
That manual is a real gold mine.
In the release that JediMatt tested I was not reading the screen timer but rather the random number seed at >8379, which continues spinning on one byte with the E/A cartridge.
Could it be that TI BASIC changes that location or stops incrementing it when it starts? I will have to check that here.
Nevertheless it was a test version to see if that would work better than the 9901 timer. I should think that the timer is a better strategy for general use.
-
13 hours ago, jedimatt42 said:
@TheBF You asked about testing on some of the other hardware that is out there...
On my 4A, no cartridge, just 32k + Tipi Sideport, and usb keyboard adapter...
I tested loading the CAML259B program image..
TIPI set to 'auto map' dsk1 on program image load.
from TI BASIC: CALL TIPI("TIPI.CAMELF99.CAML259B")
I see:
CAMEL99 Forth 2.59B Loading: DSK1.START Loading: DSK1.SYSTEM compiling ANS Forth extensions....... Ready _
No cursor blink... no keyboard input... I turned off my USB keyboard adapter, just in case and tried again... same issue.
I just copied all the files in the archive under DISK1.ITC onto the TIPI, they seem to be TIFILES files already.
It seems to read around 3 records from DSK1.START, and then many from DSK1.SYSTEM, and then more from DSK1.START
To confirm: This version is using the interrupt driven counter at >8379 to time how fast to blink the cursor.
It looks like TIPI disables this counter. (?)
If I send you the version that uses the 9901 timer could I trouble you to try that one?
-
11 hours ago, jedimatt42 said:
Ah, follow up...
Loading from an Editor/Assembler cart, works fine... blinky blinky...
." Hello World" Hello World ok
Thank you!
So that points perhaps to the way that I am doing blinky part and how it interacts with other hardware.
I explored two methods. One uses the 9901 timer the other uses the interrupt driven counter in scratch pad RAM.
I have to double back and check which method is used in that version, but I believe it is the 9901 timer which I have running continuously.
If the other hardware is blocking the timer somehow that would stop the blinky thing.
Thanks again for the testing.
-
On 11/16/2019 at 3:58 PM, jwild said:
I figured it out. It turns out that the files i was working with were not TIFILES format. I was using the SMB shares and Windows Explorer to move files around - simple enough.
What I should have done was taken a look at the files on the web interface. That’s how i discovered that FBLOCKS wasn’t TIFILES format.
All I had to do was check the box to the left of the file, and then go to the drop down menu and convert it.
Then I copied to DSK1 using force cmd and it worked (slowly since it was a big file). It also reported only being 320 blocks in size
FbForth fires up now!
I am always happy to hear about someone digging into Forth. No reason for just a few of us to back talkwards around here.
If you have any spare band-width could I ask you try to start Camel99 Forth on a TIPI drive.
**Not to replace FBForth** (which has far better documentation for the novice)
I just don't have TIPI and want to know if it works.
You can get a current version here.
You really only need DSK1. or even less just the files CAMEL99 START and SYSTEM just to see if it boots and loads the startup stuff.
No rush or pressure. I am just curious for a simple test by someone on this fancy new hardware.
Thanks in advance.
B
- 1
-
In the process of fighting with making an editor for the VT100 terminal I looked into what features I had.
I have a simple file that compiles on startup with the TTY version of Camel99 Forth that gives cursor positioning, clearing the screen as well some basic cursor movements.
I took the approach of creating a tag type language for this lexicon so the VT100 words stand out from other Forth words. Kind of HTMLish.
CR .( VT100 terminal control) DECIMAL \ type 'n' as a two digit number in base 10, with no space : <##> ( n -- ) BASE @ >R \ save radix 0 <# DECIMAL # # #> TYPE \ convert to 2 digits & print R> BASE ! ; \ restore radix \ markup language for terminal control codes : <ESC> ( -- ) 27 EMIT ; : <ESC>[ ( -- ) <ESC> 91 EMIT ; : <UP> ( n -- ) <ESC>[ <##> ." A" ; : <DOWN> ( n -- ) <ESC>[ <##> ." B" ; : <RIGHT> ( n -- ) <ESC>[ <##> ." C" ; : <BACK> ( n -- ) <ESC>[ <##> ." D" ; : <HOME> ( -- ) <ESC>[ ." H" 1 1 VROW 2! ; \ define Forth words using markup words : PAGE ( n -- ) <ESC>[ ." 2J" <HOME> ; : AT-XY ( col row --) ( uses base 0 coordinates) 2DUP VROW 2! \ store col,row <ESC>[ <##> ." ;" <##> ." f" ;
Here are some scrolling controls. I have created separate files to save space in a program that doesn't need everything.
CR .( VT100+.FTH extended terminal control) NEEDS <##> FROM DSK1.VT100 DECIMAL : <RESETVT100> ( -- ) <ESC> [CHAR] c EMIT ; \ reset the terminal : <SCROLLALL> ( -- ) <ESC>[ ." r" ; \ Enable scrolling for entire display. \ Enable scrolling from row {start} to row {end}. : <SCROLLROWS> ( rstart rend-- ) SWAP <ESC>[ <##> ." ;" <##> ." r" ; : <SCROLLDOWN> ( -- ) <ESC> [CHAR] D EMIT ; \ Scroll display down one line. : <SCROLLUP> ( -- ) <ESC> [CHAR] M EMIT ; \ Scroll display up one line. \ Erasing Text : <ERASERIGHT> <ESC>[ ." K" ; \ Erase from cursor to end of line : <ERASELEFTS> <ESC>[ ." 1K" ; \ Erase from Cursor to start of line : <ERASELINE> <ESC>[ ." 2K" ; \ Erases the entire current line : <ERASEDOWN> <ESC>[ ." J" ; \ Erases screen from current line down : <ERASEUP> <ESC>[ ." 1J" ; \ Erases screen from current line up
And here is some color control
CR .( VT100COLR.FTH Display Attribute control lexicon) \ BJF May 2020 NEEDS <##> FROM DSK1.VT100 DECIMAL \ colors 0 CONSTANT BLK 1 CONSTANT RED 2 CONSTANT GRN 3 CONSTANT YEL 4 CONSTANT BLU 5 CONSTANT MAG 6 CONSTANT CYN 7 CONSTANT WHT : <ATTRIB> ( n -- ) <ESC>[ <##> ." m" ; \ Usage: BLK <FG> CYN <BG> : <FG> ( color -- ) 30 + <ATTRIB> ; \ convert to foreground value : <BG> ( color -- ) 40 + <ATTRIB> ; \ convert to background value \ attributes : <DEFAULT> 0 <ATTRIB> ; : <BRIGHT> 1 <ATTRIB> ; : <DIM> 2 <ATTRIB> ; : <UNDERSCORE> 4 <ATTRIB> ; : <BLINK> 5 <ATTRIB> ; : <REVERSE> 7 <ATTRIB> ; : <HIDDEN> 8 <ATTRIB> ;
Here is some test code and a little video
: A$ S" This sentence will be displayed with different attributes." ; \ TEST CODE : TESTBG CR 8 0 DO I <BG> A$ TYPE CR LOOP <DEFAULT> CR ; : TESTFG CR 8 0 DO I <FG> A$ TYPE CR LOOP <DEFAULT> CR ; : TESTATTRIB CR 8 0 DO I <ATTRIB> A$ TYPE CR LOOP <DEFAULT> CR ;
- 3
-
Duplicated
-
I was reading about and tried this program to generate Morse code on the TI-99.
I thought some would find it interesting to see how you could do it in Forth.
I wrote this up for Rosetta Code a few years ago for a PC so here it is ported to Camel99 Forth.
In this method each letter of the Alphabet becomes a Forth program that knows how to send it's own Morse code sound.
The Transmit routine reads each character in a string and interprets them. A rather different approach.
\ MORSE CODE GENERATOR for Rosetta Code Brian Fox, Feb 2016 \ Ported to Camel99 Forth May 2020 NEEDS VALUE FROM DSK1.VALUES NEEDS SOUND FROM DSK1.SOUND NEEDS FORGET FROM DSK1.FORGET DECIMAL 750 VALUE FREQ \ 750 Hz will be the tone freq. 200 VALUE ADIT \ duration of one "dit" \ Compute all durations based on ADIT : DIT_DUR ADIT MS ; : DAH_DUR ADIT 3 * MS ; : WORDGAP ADIT 5 * MS ; : OFF_DUR ADIT 2/ MS ; : LETTERGAP DAH_DUR ; \ space between letters is commonly a DAH. : TONE ( -- ) FREQ HZ 0 DB ; : MORSE-EMIT ( char -- ) DUP BL = \ check for space character IF DROP WORDGAP \ ignore char and delay ELSE PAD C! \ write char to buffer PAD 1 EVALUATE \ evaluate 1 character string LETTERGAP THEN ; : TRANSMIT ( ADDR LEN -- ) CR \ newline, BOUNDS \ convert loop indices to address ranges DO I C@ DUP EMIT \ dup and send char to console MORSE-EMIT \ send the morse code LOOP ; \ dit and dah define all the reset : . ( -- ) TONE DIT_DUR MUTE OFF_DUR ; : - ( -- ) TONE DAH_DUR MUTE OFF_DUR ; \ define morse letters as Forth words. They transmit when executed : A . - ; : B - . . . ; : C - . - . ; : D - . . ; : E . ; : F . . - . ; : G - - . ; : H . . . . ; : I . . ; : J . - - - ; : K . - . ; : L . - . . ; : M - - ; : N - . ; : O - - - ; : P . - - . ; : Q - - . - ; : R . - . ; : S . . . ; : T - ; : U . . - ; : V . . . - ; : W . - - ; : X - . . - ; : Y - . - - ; : Z - - . . ; : 0 - - - - - ; : 1 . - - - - ; : 2 . . - - - ; : 3 . . . - - ; : 4 . . . . - ; : 5 . . . . . ; : 6 - . . . . ; : 7 - - . . . ; : 8 - - - . . ; : 9 - - - - . ; : ' - . . - . ; : \ . - - - . ; : ! . - . - . ; : ? . . - - . . ; : , - - . . - - ; : / . . . - . - ; ( SK means end of transmission in int'l Morse code) : . . - . - . - ; ( ~ 10 words per minute ) S" CQ CQ CQ DE VE3CFW / " TRANSMIT
Note:
I am getting different timing on Classic99 versus real iron. Hmm... ?This was my mistake. They both run at the same speed but... the real iron timing using the 9901 is more precise than Classic99 under windows. (to be expected)
On the real hardware the letters are crisp and accurate every time even at morse code speeds of 20 WPM.
Camel99 Forth's timer word MS, shines on real hardware.
- 1
-
Sometimes the world presents us with strange coincidences
A while back I added a string comparator to the CASE statement in Forth just to see what it would take.
I am working on porting my SAMS editor to a VT100 terminal and guess what I need? A way to parse escape strings and run code.
On the VT100 terminal when you press Page-up, Page-down or the cursor keys for example, the terminal emits a string of key-strokes.
For example PAGE-UP emits: <ESC>[6~"
Where <esc> is HEX 1B.
So if you detect the escape character you then have to collect the next three characters as a string. That string needs to be compared to a table of strings to know what to do.
Now the Forthy way to do this might be to make Forth words called [6~, [5~ etc. This way the Forth language would just run the routine like any Forth word. It could even compile that routine into other routines. The only trouble with that is we encounter an unknown sequence of characters Forth will Abort to interpreter. There are some solutions to that problem but I will leave that for later.
Here is what I came up with that seems to work but I suspect it will not be fast. It revolves around code I developed to allow me to upload text files to disk with out using XMODEM.
TIMEKEY is routine that waits for a key until a specific time elapses. I need this because the length of the escape sequences is variable. You never know how many characters you are waiting for exactly.
STRAIGHT is the end user word to read data into a buffer & lenght set of input parameters and it returns the number of characters received.
READSEQ puts them all together and put the string in PAD as a counted string which can be fed to the CASE statement. The case statement is for testing and just prints the name of the code it will run in the final application.
I did not count on this much trouble to build an editor for a VT100/ANSI terminal.
: STRAIGHT ( addr len -- n) 0 -ROT \ char counter under address OVER >R \ save the 1st buffer location 1 /STRING BOUNDS ( -- end start) R> ( -- end start addr) KEY SWAP C! \ wait for 1st key & store DO 100 TIMEKEY DUP I C! 0= IF 1+ LEAVE THEN 1+ LOOP ; CREATE SEQ$ 8 ALLOT \ returns a counted string : READSEQ ( -- Caddr) SEQ$ DUP 4 STRAIGHT PAD PLACE PAD ; : $OF ( -- ) POSTPONE OVER POSTPONE =$ POSTPONE IF POSTPONE DROP ; IMMEDIATE : ESCAPE-HANDLER ( caddr -- ) CASE " [5~" $OF ." PGUP " ENDOF " [6~" $OF ." PGDN " ENDOF " [A" $OF ." -LINE " ENDOF " [B" $OF ." +LINE " ENDOF " [D" $OF ." LEFT " ENDOF " [C" $OF ." RIGHT " ENDOF " [Z" $OF ." -TAB " ENDOF ENDCASE ;
The screen shot shows this little test code running the code about. It exits with ^C . ( CHAR 03)
HEX 1B CONSTANT [ESC] : TESTER BEGIN KEY DUP [ESC] = IF READSEQ ESCAPE-HANDLER ELSE DUP EMIT THEN 3 = UNTIL ;
-
Just curious...
Has anyone tried CAMEL99Forth /TTY version?
I am also curious how it works with TIPI or some other disk drives on TI-99 systems.
-
3 hours ago, retroclouds said:
Thinking about it I’m going to keep the DIS/VAR 80 as an “import/export” functionality (for compatibility reasons with other software on the TI-99/4a). But also allow native saving/loading as program.
I was thinking the same thing. You could read/write the files in 4K chunks the way Rich is doing it. (i believe)
- 2
-
27 minutes ago, RXB said:
Try using the RXB IN THE DARK game I am told it loads pretty fast off of disk for 584K.
Is it loading text files or program files?
The 99 goes like blazes on program loading.
- 1
-
I don't have any fancy drives on my TI-99 but even when I test loading files into SAMS memory on Classic99 it is pretty slow.
From what I can see on your video you are loading about 1.4K bytes per second.
On my SAMS editor on Classic99 I loaded a 13.6K file (the editor source) in about 7.5 seconds. That included erasing the 64K segment which took just over 1 second.
So just a touch faster but of course Classic99 may well be serving up the files much faster than TIPI.
-
21 hours ago, TheBF said:
Give me a day. I should be able to make a script to combine a pile of source code files into one big file.
Well... I had never tested my file util shell using APPEND mode and of course there was a bug. ?
But you have been well looked after and I can now APPEND files to my hearts content.
Thanks for forcing me to test better.
I love the editor BTW.
- 3
-
16 hours ago, Lee Stewart said:
I might need to translate that to fbForth. I suspect it will cost me more memory real estate, however—what with vocabularies and all.
...lee
In case you haven't tried this yet, I was mistaken. Very sorry.
The only time I used these two words was in a bigger program. It worked fine.
The concept is valid but I think it needs to separate the '[' ']' words to operate on their own. More testing needed to use it independently.
Here is the original usage.
\ inline.fth a simple speedup for ITC FORTH July 2017 B Fox \ Premis: \ An indirect threaded code (ITC) system can spend up to 50% of its time \ running the Forth thread interperpreter, typically called NEXT. \ The ITC NEXT routine is three instructions on the TMS9900. \ The Forth Kernel contains many words called primitives, that are coded \ in Assembler. \ Many of these primitives are only 1 or 2 instructions. \ INLINE[ ... ] copies the code from a primitive and compiles it in a new \ definition but removes the call to NEXT at the end of each primitive. \ This can double the speed of chains of CODE words. \ **not portable Forth code** Uses TMS9900/CAMEL99 CARNAL Knowledge \ INCLUDE DSK1.CODE HEX \ TEST for CODE word \ CFA of a code word contains the address of the next cell : ?CODE ( cfa -- ) DUP @ 2- - ABORT" Not code word" ; \ scan MACHINE code looking for the NEXT, routine. \ abort if NEXT is not found after 256 bytes. This is an arbitrary size \ but most Forth code words are much smaller than 256 bytes. : TONEXT ( adr -- adr2 ) 0 \ flag that falls thru if we don't succeed SWAP ( ADR) 80 \ max length of code word is $80 CELLS BOUNDS DO I @ 045A = \ test each CELL for CAMEL99 NEXT (B *R10) IF DROP I LEAVE THEN 2 +LOOP DUP 0= ABORT" can't find NEXT" ; \ : RANGE ( cfa -- addr cnt ) \ >BODY DUP TONEXT OVER - ; \ calc. start and length of code \ put inline ASM in colon definitions : ASM[ HERE CELL+ , \ compile a pointer to the next cell HERE CELL+ , \ which is the CFA of the inline code [ ; IMMEDIATE \ switch to interpreter mode : ]ASM 0209 , HERE 2 CELLS + , \ macro: LI R9,HERE+4 \ moves Forth IP reg.) NEXT, ] ; IMMEDIATE \ switch ON compiler \ create code words using primitives : CODE[ BEGIN BL PARSE-WORD PAD PLACE PAD CHAR+ C@ [CHAR] ] <> WHILE PAD FIND 0= ABORT" not found" DUP ?CODE >BODY DUP TONEXT OVER - \ calc. start and len. of code HERE OVER ALLOT SWAP CMOVE \ transcribe the code to HERE REPEAT ; IMMEDIATE \ embed a literal number as machine code *HUGE* 8 bytes!! \ equivalent: TOS PUSH, LI TOS ( n ) , ; : :ARG ( n -- ) 0646 , C584 , 0204 , ( n) , ; IMMEDIATE \ compile primitives inline inside a colon definition : INLINE[ POSTPONE ASM[ POSTPONE CODE[ POSTPONE ]ASM ; IMMEDIATE \ =================================== \ EXAMPLES \ CODE 1+! ASM[ *TOS INC, TOS POP, ]ASM NEXT, \ CREATE Q 20 ALLOT \ CODE ]Q CODE[ 2* ] Q :ARG CODE[ + ] NEXT, END-CODE : *+ INLINE[ * + ] ; : DUPC@ INLINE[ DUP C@ ] ; \ : DUP>R INLINE[ DUP >R ] ; : ^2 INLINE[ DUP * ] ;
-
It's a neat little hack. I think you just need the macro to use your IP register instead of R9 to make it work. ??
-
Typically the ASM code you need is not very big so 10 bytes may or may not be important. Speed/size. It's the classic trade-off.
BTW on 6809 is might be smaller because of 8 bit op-codes in some cases. However the ASM[ will be pretty much the same for any ITC Forth. (I think)
-
Give me a day. I should be able to make a script to combine a pile of source code files into one big file.
- 1
-
CAMEL99 Forth /TTY
For anyone interested here is a re-built version of CAMEL99 Forth /TTY. This is the first time I have put this out to the public. I am not 100% certain it is a perfect mirror of what is on my floppy disk here but it should start ok. If you get into trouble type COLD to reboot the system if it is still responding.
It runs over RS232/1 on a regular TI-994a with RS232 card and floppy drives. I would be interested to hear what happens with some of the alternative disk systems out there. It "should" work with whatever DSR is installed for the device. (he said quietly, his lip trembling slightly...)
Disk utilities are CAT, DIR and MORE (to see a text file)
Editors are only working for VDP and console keyboard at this time. More work for me.
Disclaimer: Not all of the demo programs on DSK3. work as expected because they were made for VDP terminal. Caveat Emptor
- 4
-
Working on re-building the TTY version of Camel99 Forth I did some testing to see the effect of increasing the baud rate.
I simply used WORDS and ELAPSE to see how long it took to show the dictionary of 379 words on Terraterm.
Here are the results
Baud Seconds 9600 2.60 19200 2.11 38400 2.10
Looks like there is very little point in going past 19,200 bps on this implementation of Forth. I might be able to go faster with a version of TYPE in Assembler.
Might give that a try...
Edit: However the current version is vectored and multi-tasking friendly so maybe not...
Camel99 Forth Information goes here
in TI-99/4A Development
Posted
Who needs string comparison case statements?
In the course of porting an editor to TTY over RS232 I bumped into the challenge of escape key sequences. One way to do it is to read the sequences into strings and then compare the strings to other strings to determine which control sequences was sent from the terminal. However...
It occurred to me that a faster way to do it would be to hash the characters sequence into a unique number and then use a regular integer case statement to do the correct action.
The sequences are short so the overhead to hash the string is small.
Here is what I came up with to test the concept. Since the sequences are variable I use TKEY to wait for each character. TKEY will read a key or return zero if the key does not arrive in time.
Then for the 2nd, 3rd and 4th character I multiply the ascii value by a different value. Actually I just do 3 different shifts. I tried just summing the ascii values but I could not differentiate the keys F9..F12 from the F1 to F4 keys without doing the multiply operations.
The longest string is 4 chars but I got cleaner read by adding a 5th TKEY. When a key is held down this reader would get out of sync and generate a single ascii character which would go into the text of the editor if I left it there. The extra TKEY cleaned that up.
The first KEYHANDLER reads normal control keys with single value output. If it detects the ESC key it calls the ESCHANDLER to deal with the control sequence.
The short video demonstrates this test code.
\ Esc sequence decoder using hashing NEEDS CASE FROM DSK1.CASE MARKER REMOVE HEX 1B CONSTANT [ESC] : TKEY ( wait-time -- 0 | c ) \ waits for a key -or- until counter hits zero BEGIN 1- DUP WHILE CKEY? ?DUP IF NIP EXIT THEN REPEAT ; DECIMAL : HASHKEY ( -- n) 75 TKEY 75 TKEY 2* 75 TKEY 4* 75 TKEY 8* 75 TKEY \ dummy read + + + + ; \ 5 timed reads & sum HEX : ESCHANDLER ( -- ) HASHKEY CASE \ TESTED 02B5 OF ." HOME " ENDOF \ PC Home 02B7 OF ." INSERT " ENDOF \ PC Insert 02BB OF ." END " ENDOF \ PC End 02BD OF ." PGUP " ENDOF \ PC Page up 02BF OF ." PGDN " ENDOF \ PC Page down 00DD OF ." UPARROW " ENDOF \ PC up arrow 00DF OF ." DNARROW " ENDOF \ PC down arrow 00E1 OF ." RIGHT " ENDOF \ PC right arrow 00E3 OF ." LEFT " ENDOF \ PC left arrow 010F OF ." -TAB " ENDOF \ PC shift TAB \ PC function keys 0571 OF ." FCTN1 " ENDOF 0575 OF ." FCTN2 " ENDOF 0579 OF ." FCTN3 " ENDOF 057D OF ." FCTN4 " ENDOF 0581 OF ." FCTN5 " ENDOF 0589 OF ." FCTN6 " ENDOF 058D OF ." FCTN7 " ENDOF 0591 OF ." FCTN8 " ENDOF 056F OF ." FCTN9 " ENDOF 0573 OF ." FCTN10 " ENDOF 057B OF ." FCTN11 " ENDOF 057F OF ." FCTN12 " ENDOF ENDCASE ; : KEYHANDLER ( char -- ) \ VT100 TERMINAL key codes CASE [ESC] OF ESCHANDLER ENDOF \ if we get ESC key [CHAR] A OF ." A " ENDOF [CHAR] B OF ." B " ENDOF [CHAR] C OF ." C " ENDOF 9 OF ." TAB " ENDOF 3 OF CR QUIT ENDOF \ ^C 7 EMIT \ key not found, ring the bell ENDCASE ; HEX : TEST KEY HASHKEY . ; : TESTHASH BEGIN KEY KEYHANDLER AGAIN ;