Jump to content

TheBF

+AtariAge Subscriber
  • Posts

    4,465
  • Joined

  • Last visited

Posts posted by TheBF

  1. 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 ;

     

     

    • Like 1
  2. 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

     

    • Like 1
  3. 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. :) 

  4. 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... :)

     

     

    • Thanks 1
  5. 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.

     

  6. 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?

     

     

  7. 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.

     

  8. 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

     

     

    • Thanks 1
  9. 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 ;
    
    

     

    • Like 3
  10. 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.

    • Like 1
  11. 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 ;
    

     

    COM1 - TI-99 TTY VT 2020-05-04 11_42_02 PM.png

  12. 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)

    • Thanks 2
  13. 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. 

     

  14. 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.

     

     

    • Like 3
  15. 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 *  ] ;
    
    
    

     

     

  16. 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)

  17. 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

     

     

     

    CAMEL99TTY.260.zip

    • Like 4
  18. 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...

     

×
×
  • Create New...