Jump to content
IGNORED

Erik's ET-PEB


speccery

Recommended Posts

I'm impressed TurboForth, as a comprehensive software suite for the TI-99/4A. I have tested it in the past, but without disk support. Now with ET-PEB development I've used it as a development tool to test the ET-PEB disk support. The DIR and FTYPE words have been very useful.

 

FTYPE, a word to display contents of files, revealed several issues with my disk support code. For one, it uses OP_STATUS DSR command to see if end of file has been reached. This wasn't fully supported, so added that. With that out of the way came the next problem. First, it seems to me that FTYPE can only display files with variable record fields. Fair enough, so I found one for testing. I then uncovered something surprising (to me): it does not update the record number when fetching records from the file. For reads it seems to always use record number zero. With my disk support code it would always return first record (first line), and get stuck there in a loop as it would never reach end of file and just print first line over and over.

 

That looked weird to me, as I was assuming the record number is used when reading content. With that in mind I tested the FTYPE word under classic99. Naturally it worked. Then I looked at classic 99 source code. And there it is, diskclass.cpp Read() method comment says it all:

        // handles fixed files (the record number is not used in variable files)
        if (0 == (pFile->Status & FLAG_VARIABLE)) {
                // if a file is not variable, use the record number
                pFile->nCurrentRecord = pFile->RecordNumber;
        }

I did not see this in Thierry's tech pages or the "Console Peripheral expansion system technical data document" either, but perhaps I did not read enough of it. So I guess I need to modify my code to just ignore the record number with variable record length files. That actually simplifies things a lot...

 

The other thing I have worked on is creation of disk listing, for example using Basic Catalog program as a test tool. That works now.

 

In order to classify files properly for directory listing, the disk system needs to open each one of them, read the header, and return proper file type for them. I am using FIAD type files, i.e. TI files are ordinary files on the SD card, having the TIFILES or V9T9 128-byte headers. Now each disk can have 127 files to my understanding, so the disk support code needs to go through all of them. The easiest way to manage that activity is to scan all files on a disk (in practice a directory on an SD card) when a disk is opened, and then store of that in memory, so that subsequent read operations for directory entries can directly access the relevant data. Here I ran into a memory issue, as described in the previous message: the filename, type, size etc. occupy in my case 40 bytes per file. 127 times that means 5k bytes of RAM. Nothing on normal computer, but my microcontroller has 12K of RAM, of which 2K is used for USB buffers, and another 2KB is a separate block I'm not using yet. Thus the actual RAM available is 8K overall, and most of it is already used. There is also the theoretical case that multiple directories could be open at the same time, bringing the total to 15K, since I support 3 disks simultaneously. So that cannot be stored on chip, and is now being stored on the SRAM chip also serving as 256K of SAMS memory. Good thing to have that direct memory access in place, allowing the microcontroller to access the external RAM concurrently to the TI-99/4A.

 

Working on these details takes quite a bit of time...

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

Not sure if this of any value Speccery, but I have a simple shell program.  It's pretty solid these days.

It is built primarily for DV80 files but it might have some value to you and if you need it customized in some way just ask.

 

It can be used as a simple de-bugger as well because it also has DUMP and VDUMP utilities pre-compiled.

And of course you can peek and poke integers with @ and ! , bytes with C@ and C!. 

VDP integers with V@ and V!, VDP bytes with VC@ and VC!.

 

There is not a pre-made command to jump into code but if you need one I can add one.

 

The full compiler is inside so it could be extended with source code.

I have a binary loader if you need that.  It could load E/A5 programs code in low RAM or in the hi ram form E000 to FE00  (Forth stacks are above that)

 

However it is not a cartridge and needs E/A to load so it may not work for your needs as well as Turbo Forth does. 

 

I am not sure I have enough life span to learn Verilog and such but it looks like an amazing pass-time what you are doing.

 

FOXSHELLSCREEN.png

VDUMP.png

FOXSHELL.ZIP

  • Like 4
Link to comment
Share on other sites

11 hours ago, TheBF said:

Not sure if this of any value Speccery, but I have a simple shell program.  It's pretty solid these days.

It is built primarily for DV80 files but it might have some value to you and if you need it customized in some way just ask.

 

FOXSHELL.ZIP 10.38 kB · 2 downloads

 

Thank you @TheBF, will definitely take a look! More test software is very welcome, especially if I can trouble you with questions I might have...

I might just copy paste from TIPI DSR code the EA loader it embeds, that should enable me to load your code. Or just using E/A cartridge.

  • Like 3
Link to comment
Share on other sites

@TheBF Thanks again for providing Foxshell! 

I've now done a bit of testing. I noticed that the copy command misses the last line. I've used the DSK1.AEMSSYS file as the test file (included in Classic-99). Please see the screenshots below, they partly overlap.

 

Doing MORE DSK1.AEMSSYS shows 8 lines, while TurboForth FTYPE on the same file shows 9 lines (although the last line seems to be trash).

Anyway, doing COPY DSK1.AEMSSYS DSK2.A drops one line, and COPY DSK2.A DSK1.B drops one more line, so doing MORE DSK1.B shows 6 lines. Also, a very small comment, the copy command shows the number of bytes copied in decimal, while the "more" command shows the number of bytes displayed in hex.

Still, Foxshell is very useful for testing. For example the APND command is useful to test appending, which I haven't implemented yet. It now just acts as the copy command, as it doesn't seek to the end of the file.

 

My todo list is getting shorter, the remaining things are:

- a couple of DSR commands (FILES, and something to MOUNT a directory)

- support seeking for writes for fixed length records

- support append

 

1078003671_Screenshot2021-02-06at21_23_51.thumb.png.6ea535a0b4b7509026100b9b72cb97fa.png

 

972539701_Screenshot2021-02-06at21_24_57.thumb.png.4379cab481a2c45f0c8373505c755d6e.png

  • Like 5
Link to comment
Share on other sites

1 hour ago, speccery said:

@TheBF Thanks again for providing Foxshell! 

I've now done a bit of testing. I noticed that the copy command misses the last line. I've used the DSK1.AEMSSYS file as the test file (included in Classic-99). Please see the screenshots below, they partly overlap.

 

Doing MORE DSK1.AEMSSYS shows 8 lines, while TurboForth FTYPE on the same file shows 9 lines (although the last line seems to be trash).

Anyway, doing COPY DSK1.AEMSSYS DSK2.A drops one line, and COPY DSK2.A DSK1.B drops one more line, so doing MORE DSK1.B shows 6 lines. Also, a very small comment, the copy command shows the number of bytes copied in decimal, while the "more" command shows the number of bytes displayed in hex.

When troubleshooting things like this, please make sure you confirm them with the TI Disk Controller ROM or real hardware. Remember when you are using FIAD or even disk images with the Classic99 DSR, that you are running a Classic99-specific DSR. While I strive to make them behave like the original hardware for cases like this, I am still wary about people relying /solely/ on it. You can't even guarantee that between Corcomp and TI controllers, and they have a lot more in common. ;)

 

  • Like 4
Link to comment
Share on other sites

9 hours ago, Tursi said:

When troubleshooting things like this, please make sure you confirm them with the TI Disk Controller ROM or real hardware. Remember when you are using FIAD or even disk images with the Classic99 DSR, that you are running a Classic99-specific DSR. While I strive to make them behave like the original hardware for cases like this, I am still wary about people relying /solely/ on it. You can't even guarantee that between Corcomp and TI controllers, and they have a lot more in common. ;)

 

A very good comment! Sadly, I don’t have the a real PEB or disk drives... I only have what I have built. And the TIPI in my FPGA setup, but currently no connection from the real console to the TIPI. That I can build though. 
I suppose one hardcore option would to build floppy drive hardware emulation in a microcontroller or FPGA. When you mention using TI Disk controller ROM - is there a way to run it with classic99?

  • Like 1
Link to comment
Share on other sites

3 hours ago, speccery said:

A very good comment! Sadly, I don’t have the a real PEB or disk drives... I only have what I have built. And the TIPI in my FPGA setup, but currently no connection from the real console to the TIPI. That I can build though. 
I suppose one hardcore option would to build floppy drive hardware emulation in a microcontroller or FPGA. When you mention using TI Disk controller ROM - is there a way to run it with classic99?

Yeah...

 

image.thumb.png.fae8a1d92e88d36331c4efc8eb743234.png

 

It's limited in all the ways that the real controller is limited - DSK1-DSK3 only, it takes over the handling of CALL FILES (so always reset the TI after changing to or from it, or it'll probably crash), and it only supports 180k disk images. I support it only for the purposes of testing, people using it for their sole interaction with Classic99 will earn "don't do that" from me when they have problems. ;)

 

But, it lets you test what the TI controller will do with your code - you can even step into the disk controller DSR to see what it's doing (the final sector read/write is simulated, rather than the actual controller chip being emulated, but that gets you pretty far).

 

 

 

  • Like 2
Link to comment
Share on other sites

20 hours ago, speccery said:

 

Anyway, doing COPY DSK1.AEMSSYS DSK2.A drops one line, and COPY DSK2.A DSK1.B drops one more line, so doing MORE DSK1.B shows 6 lines.

 

Also, a very small comment, the copy command shows the number of bytes copied in decimal, while the "more" command shows the number of bytes displayed in hex.

Still, Foxshell is very useful for testing. For example the APND command is useful to test appending, which I haven't implemented yet. It now just acts as the copy command, as it doesn't seek to the end of the file.

 

My todo list is getting shorter, the remaining things are:

- a couple of DSR commands (FILES, and something to MOUNT a directory)

- support seeking for writes for fixed length records

- support append

So in V1.1 I have corrected :

1. MORE now reads the entire file

2. COPY copies all the lines. :) 

3. All file numbers are displayed in DECIMAL

4. APND seems work correctly as I understand  it. It opens the destination file in APPEND mode and the number of lines are correct now. I am reading the EOF flag now.

 

Todo:

  • I will have to see if my DSR supports FILES.  ( It should but I have never tested it)
  • I don't know what a mount command is. (Where do I find that info?)
  • Tell me what you mean by support APPEND

     

Tell me more about what you need for fixed length records.

 

FOXSHELL1.1.ZIP

  • Like 1
Link to comment
Share on other sites

1 hour ago, TheBF said:

Todo:

  • I will have to see if my DSR supports FILES.  ( It should but I have never tested it)
  • I don't know what a mount command is. (Where do I find that info?)
  • Tell me what you mean by support APPEND
    0.41 kB · 4 downloads

Thank you @TheBF, I will give this a go!

Sorry, my message was not clear. The mount command is a specific feature of ET-PEB. It is used to mount a directory on the SD card as a disk for the TI-99/4A. My note about append was for me, I need to implement that on the ET-PEB side. I still miss that feature. 

 

I noticed something else, with the previous version of Foxshell, regarding DEL command: (note that the problem may well be due to the way ET-PEB works, although classic99 seems to have the same behaviour.)

  • If I try to delete a file, Foxshell attempts to open that file first, as a fixed record length file. Since the file I was trying to delete was a variable length file, the open fails. The delete command is never issued.
  • Thus DEL command does not seem to work.

Is the COPY command supposed to be able to work with other files than DV80 files? I tried to copy the Foxshell executable, but that did not work - it was trying to open the file as variable record file, and that failed as the file is a fixed record one.

Link to comment
Share on other sites

1 minute ago, speccery said:

Thank you @TheBF, I will give this a go!

Sorry, my message was not clear. The mount command is a specific feature of ET-PEB. It is used to mount a directory on the SD card as a disk for the TI-99/4A. My note about append was for me, I need to implement that on the ET-PEB side. I still miss that feature. 

 

I noticed something else, with the previous version of Foxshell, regarding DEL command: (note that the problem may well be due to the way ET-PEB works, although classic99 seems to have the same behaviour.)

  • If I try to delete a file, Foxshell attempts to open that file first, as a fixed record length file. Since the file I was trying to delete was a variable length file, the open fails. The delete command is never issued.
  • Thus DEL command does not seem to work.

Is the COPY command supposed to be able to work with other files than DV80 files? I tried to copy the Foxshell executable, but that did not work - it was trying to open the file as variable record file, and that failed as the file is a fixed record one.

Ok I get it now.

 

So the del command has only been tried on my TI with floppy drives.  It does not work on Classic99 with FIAD the disk option.

I believe Tursi has said he does not support the delete command. I suspect if I used the TI controller option it would work in Classic 99.  (?)

 

Currently copy is locked to DV80 files.  It was for my own selfish purposes.  I think I can make things more versatile with a little work.  I will work on that for version 1.2.

 

 

  • Like 2
Link to comment
Share on other sites

1 minute ago, TheBF said:

Ok I get it now.

 

So the del command has only been tried on my TI with floppy drives.  It does not work on Classic99 with FIAD the disk option.

I believe Tursi has said he does not support the delete command. I suspect if I used the TI controller option it would work in Classic 99.  (?)

 

Currently copy is locked to DV80 files.  It was for my own selfish purposes.  I think I can make things more versatile with a little work.  I will work on that for version 1.2.

The copy command limited to DV80 format files is fine with me, just an observation about the limitation.

I was able to test the delete command with DM2K, and it worked fine. As I was looking at the code I realised I missed that PAB opcode, but it's now done.

My testing is indeed very limited, to this FIAD system I am building, so do take my findings with a grain of salt :)

 

The new version works as expected, COPY and MORE work now with the entire file - thank you!

  • Like 2
Link to comment
Share on other sites

The system controls are pretty versatile. I have an entire command set to define the file modes like BASIC essentially.

For example there is already a command called DV80.

 

In Forth it is defined as:

DECIMAL 
: DV80  ( -- ) UPDATE DISPLAY SEQUENTIAL 80 VARI ;

:)  Pretty easy.

 

I hard coded the DV80 in the COPY command. That will be removed. 

It can remain the default on startup, but I can give you a DF128 command and a PROG command to change the current file mode. 

I think COPY will then copy whatever file type is set as the current type.

 

I also will create a document for the file mode commands so you could make your own.

 

  • Like 1
Link to comment
Share on other sites

2 hours ago, TheBF said:

So the del command has only been tried on my TI with floppy drives.  It does not work on Classic99 with FIAD the disk option.

I believe Tursi has said he does not support the delete command. I suspect if I used the TI controller option it would work in Classic 99.  (?)

The Classic99 DSK driver will support delete too. I did not see any reason for an emulator to be deleting Windows files, though, and I still don't. Manipulate Windows files with Windows. ;)

 

  • Like 4
Link to comment
Share on other sites

On 2/7/2021 at 9:17 PM, TheBF said:

The system controls are pretty versatile. I have an entire command set to define the file modes like BASIC essentially.

For example there is already a command called DV80.

 

In Forth it is defined as:


DECIMAL 
: DV80  ( -- ) UPDATE DISPLAY SEQUENTIAL 80 VARI ;

:)  Pretty easy.

 

I hard coded the DV80 in the COPY command. That will be removed. 

It can remain the default on startup, but I can give you a DF128 command and a PROG command to change the current file mode. 

I think COPY will then copy whatever file type is set as the current type.

 

I also will create a document for the file mode commands so you could make your own.

 

Good stuff :)

A quick question: does your Forth implementation include the word SEE or something similar to show how words are defined? Would be handy for me to see how those words work. What you've done is very useful for testing.

This may a stupid question, but do you support loading Forth code from the disk with the LOAD keyword or something similar? I'm not in front of the TI right now so cannot check easily... 

Link to comment
Share on other sites

3 hours ago, speccery said:

Good stuff :)

A quick question: does your Forth implementation include the word SEE or something similar to show how words are defined? Would be handy for me to see how those words work. What you've done is very useful for testing.

This may a stupid question, but do you support loading Forth code from the disk with the LOAD keyword or something similar? I'm not in front of the TI right now so cannot check easily... 

I am just reviewing and building a version of the system V2.66 so I will publish that shortly and you will have all the source code since the whole thing is a tiny 8K kernel and you compile what you want as needed.

 

Here are some answers in advance:

1. Yes I have a decompiler SEE. 

2. The ANS/ISO Forth command line command to compile source code is INCLUDE. 

     So INCLUDE DSK1.SEE loads the decompiler. 

    (If you wanted to compile code inside a colon definition you do this:  S" DSK1.SEE" INCLUDED  )

 

3. I notice that for reasons probably due to the way I am saving the binary image, the FoxShell does not always work correctly as a compiler for extra code. I just tried the decompiler and it didn't work correctly but compiles perfectly on the Forth kernel.

So humbling. :) 

 

Anyway standby and I will get you a zip file of the entire system. I will include the entire source code for the FoxShell also.

 

Here is FoxShell 1.2  which has  DV80 and DF128  descriptors and copy and MORE seem to work correctly when you use the file descriptors first. ( DV80 COPY DSK1.MYFILE  DSK3.MYFILE ) 

The descriptors only need to be used once.

 

 A few more commands available that you may already know from Forth.

 

COLD   restarts the Foxshell program

WORDS   shows all the words in the dictionary. Space bar halts the screen. Space bar again starts it up again.  Fctn 4 breaks the command.

 

Here is the Foxshell 1.2  source while you wait for the system.   

 

( As you probably know, Forth has been used for boot new iron for many years. It is so handy for hardware people to find out it their designs work as they planned... or not.  :)  

  I am very pleased that something I have been working on is useful to someone else besides me.)  

 

 

Edit in V1.2  the file size counter is a 32 bit integer.  It was overflowing on big files before. 4 billion bytes should be big enough. :) 

 

Spoiler

\ FOXSHELL.FTH   CAMEL99 shell for disk file management
\ Oct 2020:  built with SAVESYS to create stand alone program
\ Feb 8 2021, Built V1.2 with CAMEL99 V2.66 and libraries

NEEDS DUMP       FROM DSK1.TOOLS
NEEDS OPEN-FILE  FROM DSK1.ANSFILES
NEEDS VALUE      FROM DSK1.VALUES
NEEDS CASE       FROM DSK1.CASE
NEEDS BUFFER:    FROM DSK1.BUFFER
NEEDS MALLOC     FROM DSK1.MALLOC
NEEDS COMPARE    FROM DSK1.COMPARE
NEEDS U.R        FROM DSK1.UDOTR   \ right justified printing

CR .( Compiling FOXSHELL )

VARIABLE WARNINGS   WARNINGS ON
CREATE #BYTES  0 , 0 ,     \  32bit variable for big files

: #BYTES+! ( n -- ) #BYTES 2@ ROT M+ #BYTES 2! ; \ add n, keep 32bit sum

\ busy spinner to show activity
VARIABLE SPIN#
CREATE SCHARS   CHAR | C, CHAR / C, CHAR - C, CHAR \ C,
: GETXY    ( -- col row) VROW 2@ ;
: SPINCHAR ( -- char ) SPIN# @ 1+ 3 AND DUP SPIN# ! SCHARS + C@  ;
: SPINNER  ( -- )      SPINCHAR GETXY >VPOS VC! ;

\ simplified file language
\ Usage example:  S" DSK2.MYFILE" R/W OPEN AS: #1
HEX .( .)
0 VALUE #1   0 VALUE #2   0 VALUE #3

: AS:  ( n -- <value> )  POSTPONE TO ;  IMMEDIATE

: OPEN  ( addr len -- hndl ) OPEN-FILE ?FILERR ;
: CLOSE ( hndl -- )         CLOSE-FILE ?FILERR ;
: READH ( hndl -- )         READ-LINE ?FILERR 2DROP ;

DECIMAL
\ CR if near end of screen
: ?CR     ( n -- ) LINES @ 3 MOD 0= IF CR THEN ;
.( .)
HEX
\ string helpers
 : ?PATH    ( addr len -- )
            2DUP [CHAR] . SCAN NIP
            0= IF CR TYPE TRUE ABORT" Path expected" THEN ;

 : ?FAM     FAM @ 0= ABORT" Set file mode:DV80 DF128" ;
 : ARG$     ( -- addr len ) BL PARSE-WORD ?PATH ;
 : $.       ( $addr -- ) COUNT TYPE ;
 : $.LEFT   ( $ width -- ) OVER C@ - >R $.  R> SPACES ;
 : NEXT$    ( addr len -- addr' len') + COUNT ;
\  : +PLACE  ( addr n $ -- ) 2DUP 2>R  COUNT +  SWAP CMOVE 2R> C+! ;

DECIMAL
80 VALUE BUFFSIZE

: DF128  ( -- )
     128 TO BUFFSIZE
     DISPLAY RELATIVE   BUFFSIZE FIXED ;

: DV80  ( -- )
     80 TO BUFFSIZE
     DISPLAY SEQUENTIAL BUFFSIZE VARI ;

.( .)
HEX
: CLOSE-ALL ( --)  4 1 DO  I ]FID @ IF  I CLOSE-FILE DROP THEN   LOOP ;

\ ?break closes all open files.
: ?BREAK ( ? -- ) IF  CLOSE-ALL   TRUE ABORT" *BREAK*"   THEN ;

\ Modify key to allow it to break and close files
: FKEY    ( -- char)
           VPOS VC@ >R
           BEGIN                  \ start the loop
              CURS @              \ fetch 2 char cursor (space & _ )
              TMR@ 1FFF <         \ compare hardware timer to 1FFF
              IF DROP R@ THEN VPUT   \ swap cursor for screen char, write
              ?TERMINAL ?BREAK    \ test for Break key
              KEY?                \ check the keyboard
              ?DUP                \ DUP IF <> 0
            UNTIL                 \ loop until a key pressed
            R>  VPUT ;            \ put the space char on screen

\ screen control
: SPACE?   ( -- ?) KEY? BL = ;
: SPACEBAR ( -- ) SPACE? IF    FKEY DROP    THEN ;

.( .)
: OPEN-CATFILE ( adr len -- hndl) RELATIVE 100 FIXED R/O BIN OPEN ;

\ 3 DIGIT BCD to int convertor. Limited to 999
HEX
: F>INT   ( addr len -- addr len n)
          OVER C@  ( -- mantissa)
          CASE
            0 OF  0                    ENDOF
           40 OF  OVER 1+ C@           ENDOF
           41 OF  OVER 1+ C@ 64 * >R
                  OVER 2+ C@  R> +     ENDOF
           ( default)  -1  \ bad # indicator
           ENDCASE ;

DECIMAL
: DIR.TYPE  ( addr -- )
          F>INT
          CASE
             1 OF ." Txt/Fix"  ENDOF
             2 OF ." Txt/Var"  ENDOF
             3 OF ." Bin/Fix"  ENDOF
             4 OF ." Bin/Var"  ENDOF
             5 OF ." Program"  ENDOF
             ." ????"
          ENDCASE ;
.( .)
: HEAD.REC ( addr -- )
          DECIMAL
          DUP  7 $.LEFT SPACE COUNT ( addr len)
          NEXT$
          ."  Size " NEXT$ F>INT 5 U.R   ."  Used " NEXT$ F>INT 5 U.R
          2DROP ;

: DIR.REC ( addr -- )
          DUP  11 $.LEFT SPACE COUNT ( addr len)
          NEXT$ DIR.TYPE
          NEXT$ F>INT 7 U.R
          NEXT$ F>INT 7 U.R
          2DROP ;

: FILE.REPORT
          BASE @ >R
          DECIMAL
          CR LINES @ . ." lines, " #BYTES 2@ DU. ." bytes"
          R> BASE ! ;

\ ========================================
\ *
\ * User commands: CAT DIR MORE DEL COPY
\ *

: CAT  ( <DSK?.> )   \  needs the '.' ONLY shows file name
          BASE @ >R DECIMAL
          ARG$ OPEN-CATFILE >R  \ store file handle

          PAD 80 R@ READH
          CR PAD HEAD.REC
          CR 13 SPACES  ." -type-  -sect- -b/rec-"

          LINES OFF
          BEGIN
             PAD DUP 80 R@ READH
           ( PAD)  C@   \ do while length > 0
          WHILE
             CR PAD DIR.REC
             1 LINES +!
             SPACEBAR
             ?TERMINAL ?BREAK
          REPEAT
          R> CLOSE
          CR LINES @ . ." files" CR
          R> BASE ! ;
.( .)
HEX
: DIR  ( <DSK?.> )
          ARG$
          OPEN-CATFILE >R  \ push handle
          PAD 50 R@ READH
          CR PAD HEAD.REC
          CR

          LINES OFF
          BEGIN
            PAD DUP 80 R@ READH
          ( PAD) C@   \ do while length <> 0
          WHILE
             PAD 0D $.LEFT ?CR
             1 LINES +!
             SPACEBAR
            ?TERMINAL ?BREAK
          REPEAT
          R> CLOSE
          DECIMAL
          CR LINES @ . ." files" CR
          HEX ;

.( .)
: MORE  ( <filename>)
          ?FAM
          LINES OFF
          0 0 #BYTES 2!
          ARG$ R/O OPEN >R
          BEGIN
             PAD DUP BUFFSIZE R@ READ-LINE ?FILERR ( adr len flag)  DROP
             DUP #BYTES+!
             CR TYPE
             LINES 1+!
             SPACEBAR
             ?TERMINAL ?BREAK
          R@ EOF
          UNTIL
          R> CLOSE
          CR FILE.REPORT
;

HEX
: TOUPPER ( char -- upperchar ) 5F AND ;

: SURE?  ( -- ?)
         WARNINGS @
         IF
           CR ." Are you sure? (Y/N)"   ( )
           KEY TOUPPER [CHAR] Y =
         THEN ;

: .CANCEL  CR ." Cancelled" CR ;

: DEL   ( <filename>)
         ?FAM
         ARG$ 2DUP R/W OPEN-FILE ?FILERR
         CR ." Delete " TYPE
         SURE?
         IF  7 FILEOP ?FILERR
              CLOSE-FILE 2DROP
              CR ." Done"
         ELSE
            DROP  .CANCEL
         THEN ;
DECIMAL
: MOVE-FILE ( buff-size -- buff-size)
        ?FAM
        0 0 #BYTES 2!
        DUP MALLOC >R
        LINES OFF
        SPACE
        BEGIN
\ 256 is used to accomodate the largest possible record size
          R@  BUFFSIZE #1 READ-LINE ?FILERR ( -- #bytes eof?) DROP
          DUP #BYTES+!
          R@ SWAP #2 WRITE-LINE ?FILERR
          LINES 1+!
          SPINNER
          #1 EOF
        UNTIL
        R> DROP                 \ DROP buffer address from rstack
        MFREE
;
.( .)
DECIMAL
: COPY  ( <file1> <file2> )
        ?FAM
        ARG$ ARG$
        SURE?
        IF
          W/O OPEN AS: #2
          R/O OPEN AS: #1
          BUFFSIZE MOVE-FILE
          #2 CLOSE
          #1 CLOSE
          CR ." Copy complete. "
          FILE.REPORT
        ELSE
           2DROP 2DROP  .CANCEL
        THEN
;
\ TI-99 file access mode: write/append
: W/O+  ( -- fam ) APPEND FAM @  ;

HEX
: APND  ( <file1> <file2> )
        ?FAM
        ARG$  ARG$
        W/O+ OPEN AS: #2  \ open destination in Append mode
        R/O  OPEN AS: #1
        BUFFSIZE MOVE-FILE
        #2 CLOSE
        #1 CLOSE
        CR ." Append complete"
        FILE.REPORT
;

: CLS   PAGE ;

: HELP  CR
        CR ." Commands"
        CR ." --------------------"
        CR ." HELP Show this list"
        CR ." DIR  <DSK?.> show file names"
        CR ." CAT  <DSK?.> show files and types"
        CR ." MORE <path>  show contents of DV80 file"
        CR ." DEL  <path>  delete file at path"
        CR ." COPY <path1> <space> <path2> "
        CR ."      Copy file at path1 to path2"
        CR ." APND <path1> <space> <path2"
        CR ."      Append file1 to file2"
        CR ." WAITFOR <path> Paste to Classic99"
        CR ." CLS  Clear screen"
        CR ." BYE  Return to Home screen"
        CR ." WARNINGS OFF   Disables 'Are you sure?'"
        CR ." ------------------"
        CR ." SPACE bar will stop scrolling"
        CR ." FNCT 4 halts operations"
;


\ re-write accept to use new KEY. ( could patch it but this is clearer)
: FACCEPT     ( c-addr +n -- +n')
             OVER + OVER
             BEGIN
               FKEY DUP 0D <>
             WHILE
                DUP EMIT
                DUP 8 =
                IF   DROP 1-  3 PICK  UMAX  \ changed to use: 3 PICK   B.F.
                ELSE OVER C!  1+ OVER UMIN
                THEN
             REPEAT
             DROP NIP SWAP - ;
.( .)
: RCV  ( caddr len --  )
      DV80 W/O OPEN AS: #1
      BEGIN
        PAD DUP 50 FACCEPT ( addr len) #1 WRITE-LINE ?FILERR
      AGAIN ;

\ USED WITH Classic99. Pastes text into DV80 FILE
: WAITFOR  ( <PATH> )
        ARG$
        CR ." Waiting for file " 2DUP TYPE
        CR ." Press FCTN 4 to halt & SAVE"
        CR RCV ;

: COLD           \ replace COLD so we always reboot correctly
       WARM
       201E CURS !
       DV80
       PAGE ." Fox Shell V1.2,  Brian Fox 2021"
       DECIMAL
       HELP
       WARNINGS ON
       ABORT ;

LOCK
CR .( Save as EA5 binary files)

INCLUDE DSK1.SAVESYS
 ' COLD  SAVESYS DSK2.FOXSHELL

 

 

 

 

 

FOXSHELL1.2.ZIP

  • Like 1
Link to comment
Share on other sites

20 hours ago, TheBF said:

I posted the latest version of Camel Forth with some release notes.

See last post.

 

 

Thank you very much! I will take a look and appreciate the help and insights. Haven’t had the time yet to look at the latest version you posted.

 

I have some history with Forth: first on my ZX Spectrum I had Abersoft Forth, I was probably around 15 then. Lots of tape loading back then...

 

I have implemented Forth for a MC68HC11F1 microcontroller board I built 20 years ago (had to check that, I thought it was 10 years ago, but actually around 2002). This was a port of MC6800 FIG Forth if I remember correctly. And indeed I used Forth to test the system :)


Also back in the day when I had an Amiga 500 I wrote a Forth for it. This one was not a port of anything, just my own version.
For these two Forth systems I did not have disk support, so some catching up to do for me.

More recently I have tested the J1 Forth FPGA processor on a couple of FPGA systems. It is a fascinating system, similar to Novix NC4016 as I recall. I intend to add the J1 to my Icy99 system as a coprocessor.

Edited by speccery
Corrected timeline...
  • Like 2
Link to comment
Share on other sites

So you are an old hand at this. Super.  That makes our communication a easier.

Ah 68HC11.  That's a nice little machine. I built a system to count baby chicks on a custom 68HC11 that had an 8K Forth kernel in ROM.  It was made by Randy Dumse from Texas. He just passed away in Dec. Sad to hear.

I added Forth multi-tasking to that little thing. It was counting and controlling the robotics with a user terminal and an RS488 remote control port.  The final version was counting over 80,000 baby birds per hour. :) 

 

What the heck: here is a video

(1) KUHL by TL Chick counter & boxer - YouTube

 

These little birds just came out of the egg!  Nobody wants to know where their food comes from.  :)

-----------

The only thing I can mention on the Forth front is that some of the new things that have happen since Forth 94 standardized are a bit different that what you might be used to.

IMHO opinion it changes the feel of the language a bit but it's not revolutionary.

 

In light of my missing glossary use this web site for the standard words.

6 Glossary (forth-standard.org)

 

Camel99 has the CORE words and a lot of the Extended Core words.  The rest of the system is highly TI-99 focused and the best way to understand it is read the source code and comments.

If that fails ask here. :)

 

I tried to make the file system layer translate between ANS/ISO Forth and TI-99's file system as best I could. It's quite different that the character based file systems the standard assumes but it seems to work ok.

 

FYI I realized that I my recent system post is way too big for DSK1 to hold everything on a floppy disk so I am pruning DSK1 to the files that will most likely be useful.

 

By the way, Turbo Forth is hella faster in the screen I/O and number printing than my system. Mark layed down some awesome code for that. 

On general benchmark stuff Camel99 comes in close to Turbo Forth except where there is a lot stack primitives used. Marked cleverly packed most of the small Forth primitives in 16bit RAM.  Wins hands down in that department.

 

 

  • Like 3
Link to comment
Share on other sites

3 hours ago, speccery said:

More recently I have tested the J1 Forth FPGA processor on a couple of FPGA systems. It is a fascinating system, similar to Novix NC4016 as I recall. I intend to add the J1 to my Icy99 system as a coprocessor.

This machine is pretty cool.  I have wondered if it would benefit from a set of stack windows like workspaces in 9900. What a cool idea using it as a coprocessor.

It is quite challenging to multi-task on these Novix style machines because the stack is so shallow.

I have a Papillio Pro board here and I found a J1 build for it on Github. It loads but I don't get any prompt back from the board. Have not looked any further.

 

  • Like 1
Link to comment
Share on other sites

20 hours ago, TheBF said:

So you are an old hand at this. Super.  That makes our communication a easier.

Ah 68HC11.  That's a nice little machine. I built a system to count baby chicks on a custom 68HC11 that had an 8K Forth kernel in ROM.  It was made by Randy Dumse from Texas. He just passed away in Dec. Sad to hear.

I added Forth multi-tasking to that little thing. It was counting and controlling the robotics with a user terminal and an RS488 remote control port.  The final version was counting over 80,000 baby birds per hour. :) 

 

What the heck: here is a video

(1) KUHL by TL Chick counter & boxer - YouTube

 

These little birds just came out of the egg!  Nobody wants to know where their food comes from.  :)

 

Well that video nearly left me speechless... I don't want to see the giant bot doing that for human beings... But the counter is cool. You've clearly put Forth to actual hard work! I've only been tinkering with it.

20 hours ago, TheBF said:

The only thing I can mention on the Forth front is that some of the new things that have happen since Forth 94 standardized are a bit different that what you might be used to.

IMHO opinion it changes the feel of the language a bit but it's not revolutionary.

 

In light of my missing glossary use this web site for the standard words.

6 Glossary (forth-standard.org)

 

Camel99 has the CORE words and a lot of the Extended Core words.  The rest of the system is highly TI-99 focused and the best way to understand it is read the source code and comments.

If that fails ask here. :)

 

I tried to make the file system layer translate between ANS/ISO Forth and TI-99's file system as best I could. It's quite different that the character based file systems the standard assumes but it seems to work ok.

 

FYI I realized that I my recent system post is way too big for DSK1 to hold everything on a floppy disk so I am pruning DSK1 to the files that will most likely be useful.

 

By the way, Turbo Forth is hella faster in the screen I/O and number printing than my system. Mark layed down some awesome code for that. 

On general benchmark stuff Camel99 comes in close to Turbo Forth except where there is a lot stack primitives used. Marked cleverly packed most of the small Forth primitives in 16bit RAM.  Wins hands down in that department.

I really need to test the stuff you provided. I got side tracked today: I'm also thinking about the next version of the ET-PEB. I don't know if you're familiar with it, but my current version is basically SRAM + CPLD + MCU. The bloody CPLD ended up being too small for what I wanted to do. I did manage to cram SAMS memory paging in it as well as a DMA channel so that the MCU can access the SRAM directly. So for the next version the CPLD probably needs to go, and I'll put a proper FPGA instead. But the interesting FPGA chips are larger chips in terms of pincount. I needed to test that out, and today I assembled this from parts I ordered many months ago:

IMG_4090.thumb.jpg.053c45b2e374febd7d69406973fcbf19.jpgIMG_4089.thumb.jpg.18ac82a9fa25886faaaefde3731280fb.jpg 

 

I am getting better at SMD soldering, so I got the whole thing hand soldered in something like 2 hours. After moving last year I don't exactly know where my Atari 800XL is, but I actually built this Ultimate Cart just to see if the assembly job is doable. It is - in single quantities. This one is using Altera/Intel Max 10 FPGA, in 144 pin TQFP package. I don't know if this fully works (need to find that Atari) but I did get the FPGA programmed and at least the FPGA works and LED flashes. It is remarkable that it's a two layer board. I went with a 4 layer design for the ET-PEB. In this case it is helpful that the FPGA here has many more pins than actually needed, making PCB routing easier.

 

Anyway, I suppose my next version will be something similar: 144 pin FPGA, a set of buffers for 5V - 3.3V translation, and some support chips. Even a small FPGA can host the J1 core :) 

 

I look forward to trying out Camel99. TurboForth is very nice too. thanks for the pointers.

 

  • Like 2
Link to comment
Share on other sites

19 hours ago, TheBF said:

This machine is pretty cool.  I have wondered if it would benefit from a set of stack windows like workspaces in 9900. What a cool idea using it as a coprocessor.

It is quite challenging to multi-task on these Novix style machines because the stack is so shallow.

I have a Papillio Pro board here and I found a J1 build for it on Github. It loads but I don't get any prompt back from the board. Have not looked any further.

 

I have a Papilio Duo board, but not the Pro. If you provide a pointer to that project, I could try it out and port it to the Duo if possible.

 

I haven't tested J1 on Xilinx chips, but for sure it will work on those too. I have played with the J1 only on small Lattice FPGAs. The stack implementation there is remarkable: in the J1 on those chips James Bowman (the designer) is using long shift registers (which shift in 16-bit quantities) for data and return stacks. There are no stack pointers at all. The small Lattice FPGAs don't have true dual port memories (their RAM blocks have one write and one read port, so they are dual port but no simultaneous writes or reads), so the stacks are implemented in the logic array. This implies that the stacks have to be small. I suppose for multitasking one could just dump the small stacks in their entirety to normal RAM.

 

The Icy99 is running on more capable bigger chips, so there multitasking could be done on a per processor basis. In addition, the FPGA I'm currently using for development (ECP5 85F) could easily include at least four (if not eight or even more) J1 subsystems. Would be a fun exercise to see how many could fit in there...

  • Like 1
Link to comment
Share on other sites

5 minutes ago, speccery said:

I have a Papilio Duo board, but not the Pro. If you provide a pointer to that project, I could try it out and port it to the Duo if possible.

 

I haven't tested J1 on Xilinx chips, but for sure it will work on those too. I have played with the J1 only on small Lattice FPGAs. The stack implementation there is remarkable: in the J1 on those chips James Bowman (the designer) is using long shift registers (which shift in 16-bit quantities) for data and return stacks. There are no stack pointers at all. The small Lattice FPGAs don't have true dual port memories (their RAM blocks have one write and one read port, so they are dual port but no simultaneous writes or reads), so the stacks are implemented in the logic array. This implies that the stacks have to be small. I suppose for multitasking one could just dump the small stacks in their entirety to normal RAM.

 

The Icy99 is running on more capable bigger chips, so there multitasking could be done on a per processor basis. In addition, the FPGA I'm currently using for development (ECP5 85F) could easily include at least four (if not eight or even more) J1 subsystems. Would be a fun exercise to see how many could fit in there...

I am definitely getting envious. :)  I want to give Verilog and J1 mods a try. Gotta get my docs done for this project first.

So are you using the Icestorm open source synthesizer?

 

Here is the link to the J1 on Papillio

j1eforth/fpga at master · samawati/j1eforth (github.com)

Link to comment
Share on other sites

I didn't have time to work on the ET-PEB this weekend, will try to continue to work on it during the evenings. I got a bit sidetracked with a Forth exercise, thanks to this fun discussion with @TheBF :) 

I took a trip down the memory line, to see how the Forth I created for the Amiga was. I bought some years ago an A1200, must be five years ago by now. Haven't used it much, but I do have my Forth on it.  The Forth is not really finished, according to comments in the source code I have started and stopped the project in December 1989. It's been a while... I think I have the same assembler I used to write that also on this machine so I could continue working on it (I was able to copy material from an old floppy I had from my Amiga 500).

So I did run a benchmark I found here, the Fibonacci 2. On my Forth from 30+ years ago the Fibonacci 2 benchmark took approximately 1.6s (my Amiga 1200 has turbo card in it with a 40MHz MC68EC030 CPU - I have a 50MHz 68030 that I want to install, but haven't dared to pull the old CPU from its socket...).  The 40MHz CPU runs so hot that I can feel it's location even through the desk :) On the Amiga the CPU slot is under the machine.

I tried the same on Camel99 i.e. Foxshell, it was about 1min 55s. Not a surprise there, the 68030 appeared 11 years after the TMS9900. I wanted to compare both of these to the J1, but that needs to wait for another day.

With all of this fooling around with Forth I am also thinking it would be nice to test how fast it would run on the MCU on the ET-PEB. I think it would beat the Amiga hands down. And I assume the J1 @ 50MHz would beat the ET-PEB's MCU.

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

Very nice.  I suspect J1 will be pretty fast on the simple benchmarks. 

Calling sub-routines in 1 clock cycle and returning in ZERO clocks gives some advantages in Forth code. :) 

 

OVER + SWAP  is common phrase used to set up DO LOOPs to run through a range of addresses.

Stephen Pelc at MPE Forth codified it as a word called BOUNDS many years ago which I like and so I added it to Camel99 Forth.

 

( addr len -- )  ->  BOUNDS -> ( -- addr-end  addr-start ) 

 

 

 

So in Camel99 Forth you can do this and get the result in the screen capture.

DECIMAL
: FIB2
  0 1 ROT 0 DO
    BOUNDS
  LOOP DROP ;
: FIB2-BENCH 1000 0 DO
    I FIB2 DROP
  LOOP ;

So that's about a 2X speed up  :) 

 

I am working on a machine Forth compiler. Thanks for the reminder of these benchmarks. I will use them in my testing.

 

 

FIBONACCI USING BOUNDS.png

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