Jump to content

Photo

Camel99 Forth Information goes here

Camel99 Forth Concatentive Programming ANS Forth

180 replies to this topic

#101 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Sun Jun 3, 2018 6:21 AM

You are moving right along!  I see that I need to explore how I might similarly compose sound lists/tables in fbForth 2.0.  I am still in slow motion with physical therapy and rest taking up far more time than I would like.

 

...lee

 

Following your physio regime will pay off longer term.  Stick with it.



#102 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Sun Jun 3, 2018 8:00 PM

CAMEL99 Manual V0.98 is on GITHUB

 

https://github.com/b...ers Rev .98.pdf

 

 

It's getting close to a real release document.  

Just in case anybody was waiting.  :)

Attached Files



#103 D-Type OFFLINE  

D-Type

    Space Invader

  • 17 posts
  • Location:Zürich

Posted Wed Jun 6, 2018 4:02 PM

 

In fbForth 2.0, typing 0 1 2 3 4 5 6 7 8 9 happens in 0.67 s, while typing 4 5 6 7 8 9 8 7 6 5 takes 0.88 s.  The reason for the difference is that 0 1 2 3 are defined as constants and are found in the dictionary, so are faster than number conversion.  I am a little surprised that Camel99 Forth is so much slower because the dictionary search for words not found in fbForth 2.0  is 505 words!

 

INTERPRET uses -FIND :

: -FIND     ( --- false | pfa len true )  ( IS:string )
    BL WORD                       \ get next word in input stream to HERE
    HERE CONTEXT @ @ (FIND)       \ search CONTEXT vocabulary for the word
    DUP 0=                        \ did we find it?
    IF                            \ no
        DROP HERE LATEST (FIND)   \ search CURRENT vocabulary
    THEN  ;

 

So I finally, got round to speed testing FIND on the Vectrex Camel Forth:

 

There are roughly 250 words in my Vectrex dictionary.

 

This was with a phone stopwatch, so +/- 0.2 seconds, plus the result was pushed out to a 921600 baud terminal..

 

Entering 50 numbers onto the stack from 0 to 9 = 4.84 seconds or 0.96 for 10 numbers.

 

Including/excluding 0 1 2 3 4 makes no difference, so I presume they're not defined as constants. (I had a quick look and couldn't find them.)

 

However, FIND is not in code, it's defined as:

 

: FIND        \ c-addr -- c-addr 0/1/-1   not found/immed/normal
    LATEST @ BEGIN              \ -- a nfa
        2DUP C@ BF AND SWAP C@  \ -- a nfa n1 n2
        = IF 2DUP CHAR+ SWAP DUP CHAR+ SWAP C@ S= ELSE 1 THEN
        DUP IF DROP NFA>LFA @ DUP THEN
    0= UNTIL                    \ -- a nfa  OR  a 0
    DUP IF                      \ if found, check immed status
        NIP DUP NFA>CFA         \ -- nfa xt
        SWAP IMMED?  0= 1 OR  THEN ;

 

6809 FTW!



#104 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Wed Jun 6, 2018 6:45 PM

For certain. 6809 is a good one.  As I recall the 6809 was one of Brad's favourite processors back in those 8 bit days. 

 

From moving Forth "Sometimes there's no tradeoff at all: in a 6809 DTC Forth, an in-line NEXT is shorter than a Jump instruction! "

 

However the 9900 has a nicer instruction set, 16  general purpose registers and a very fast context switch.

 

It's just kind of slow...



#105 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Fri Jun 8, 2018 2:37 PM

V2.0.16 Camel99 Forth

 

In a fit of "cleverness" I implemented synonym of >BODY which adds 2 to the number on the stack in CAMEL99.

Well... that was not such a good idea. My cross-compiling SYNONYM sucked!

 

Next time I tried to multi-task I found R14 being changed without permission!

 

So that has been corrected in V2.0.16 which has been put up on Github.

 

Now I can try to implement a multi-voice music player using my music scripting language.

 

B



#106 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Mon Jun 11, 2018 7:45 PM

So I can play three voices with the multi-tasker, but of course they loose sync after about 6 notes. They are close and the voices almost end together, but it's not good enough for music,.

So back to drawing board.

 

My evil scheme now is to continue to use the Forth compiler to sequence the note sequences which will start each note from the same task, 3 at once if need be but...

The timers for the duration of each voice will be a single background task that simple checks if it is time to mute the voice or not.

I am hoping that keeps things playing together.

 

We shall see...

 

For interests sake here is what the scripts look like. Each voice was a Forth definition and each definition was assigned to its own task.

The bar lines are there for the human. They are "noops" to mark the measures of music.

 

Spoiler


#107 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Mon Jun 11, 2018 7:55 PM

On cool thing that I created was a form of the  "repeat" double bar lines that are used in music.

 

By re-defining the names of  DO  and LOOP  to "||:"        and  ":||"  it allows the music scripts to mark parts of the music as repeating as is used in music notation.

I allowed the opening repeat symbol to take a parameter so you can specify how many times to repeat the musical phrase:

\ Repeat barlines

: ||:   ( n -- )  POSTPONE 0  POSTPONE DO  ; IMMEDIATE

: :||   ( -- )    POSTPONE LOOP ; IMMEDIATE

\ Usage: 

\ : TEST    2 ||:  1/4  E4  E4  D4   D4   | C#4  C#4  1/2 B3  :||  ;

Edited by TheBF, Mon Jun 11, 2018 7:56 PM.


#108 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Tue Jun 12, 2018 2:02 PM

Putting it all Together

 

​I have been working on testing this system by creating demos using the library code. This little demo uses some advanced features that may be interesting to those studying Forth.

​The demo's job is to create a sorted list of the words in the Forth dictionary. It can sort ascending or descending with a command.

 

​The MALLOC and MFREE words are NOT standard Forth. They simply let me use the 8K RAM in low memory as a HEAP.  It is very handy.

Here are the features it brings into the mix:

  1. Dynamically allocating memory in the HEAP ( ultra simple MALLOC )
  2. Vectored execution of the comparison operator
  3. Comb-Sort routine which runs about 10X faster than Bubble sort
  4. Measuring elapsed time using screen timeout timer value
  5. Text macros to improve speed of time critical routines
  6. Sorts an array of pointers. The actual strings do not move
  7. ​The spoiler shows the code and the video shows it in operation

 

Spoiler

Attached Files


Edited by TheBF, Tue Jun 12, 2018 2:02 PM.


#109 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Thu Jun 21, 2018 10:18 PM

CAMEL99 Version 2.0.18 On GitHub

 

Updates:

 

Faster CORE

  • V2.0.18 saves 40 bytes in the Kernel.
  • ASM primitives re-written using structured assembler (mostly)
  • Speed ups in CMOVE, CMOVE>, SKIP, SCAN, (FIND) ,FILL,  VFILL, S=  code routines

Files System improvements

  • BUG fixes to ANSFILES.F 
  • New Catalog utility and bug fixes to DIR and MORE

Demos

  • Alpha Intelligence DEMOs (ALPHA1.F,  FLY.F)
  • GROM base TI LOGO demo

Sprite Improvements

  • New MOTION.F provides simple NON auto motion
  • New Sprite DEMO using MOTION.F
  • Speed ups to Sprite control using machine language access to SDT
  • 50% speed up to sprite to sprite coincidence using machine language primitives

New Manual

  • Last but not least v0.99 of the instruction manual
  • New chapter on E/A Editor use with screen captured illustrations
  • more teaching programs in the manual
  • New chapter on ANS file words and use of LINPUT
  • New chapter on Developer tool usage
  • Expanded Forth Assembler Explanation with examples for integrating with Forth top of stack system
  • Updates PAD RAM usage table showing Registers and USER variable names
  • New chapter on SOUND.F with example code
  • Expanded Multi-tasker chapter


#110 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Sat Jun 23, 2018 6:35 PM

Still working on clarifying my use of PAD RAM and documenting things which has led to some circular activity where documenting caused understanding which caused code changes which etc... :-)

 

However as we are all keen on the 9900 architecture here I thought I would share a bit of innovation that the old girl allowed me to do in the CAMEL99 Forth implementation.

I can't think of another CPU where this would be possible.

I think I explained it well enough for those less familiar with Forth but ask questions if I failed.

 

CPU RAM PAD DETAIL

CAMEL99 makes special use of the small 256 byte RAM chip (PAD) that resides on the 16 bit buss.  In this Forth system there are three separate uses of the “PAD” RAM:

1.       Workspace: CPU registers 0 to 15

2.       User Variables: A table of variables that are duplicated every time you create a new task.

3.       CODE routines: This 16 bit memory is two times faster than expansion ram so putting some of the internal parts of Forth here make the system run about 20% faster.

User Area Description

User Variables were created in Forth to support multitasking. They create what is typically called a USER AREA, a block of memory that is unique to each Forth task running on the machine. In a typical Forth system the USER AREA may contain all the system variables needed by the Forth interpreter and the compiler, the I/O system and the DATA and RETURN stacks as well. Most Forth implementations must either allocate a register or create a memory location to be the USER Pointer (UP) that points to the USER AREA in memory, of the currently running task.  The 9900 lets us do things differently…

No UP Register Required with the 9900

CAMEL99 Forth takes the 9900 “Workspace” concept one step further. Using to the TMS9900 Architecture, CAMEL99 has the CPU registers in the Workspace, as per normal,  but then it also adds the USER VARIABLES immediately following the registers.

The 9900 internal Workspace register (WP) already points to a form of “user area” for the CPU registers.  CAMEL99 simply expands the workspace to be 110 bytes rather than 32 bytes.  The first 32 bytes are registers and the rest are USER VARIABLES. We are using the internal CPU Workspace pointer as a replacement for the normal “User Pointer” (UP) register in a conventional Forth implementation.

This means there is one less thing to change when we switch from task to task. In fact we context switch in CAMEL99 with one instruction: RTWP 

In practical programmer terms this means that the USER VARIABLE list starts at >20 rather than 0. No big deal. 

At runtime to access a USER VARIABLE we run three instructions:

(For the un-initiated Forth variables return a address and you must fetch the value from the address explicitly.

Ya I know it seems backwards.  It's Forth.  But what do you do in Assembler with a DATA  address... ;) )

\ The ‘W’ register points to the DATA field of the running Forth word 
\ (in this case a user variable)

CODE: DOUSER ( -- addr)
              TOS PUSH,     \ make some space in the TOS register
              TOS STWP,     \ store workspace register WP in TOS
             *W TOS ADD,    \ add the offset stored in the USER variable                                           
              NEXT,
              END-CODE 
 

One Minor Caveat

The only problem we had to navigate was there are 3 CELLS right in the middle of our variables in PAD RAM that are used by the Device Service Routines.  Not a problem! 

We simply NEVER declare USER VARIABLES >54, >56 and >58.  

Problem solved.

 



#111 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 2,871 posts
  • Location:Denmark

Posted Sun Jun 24, 2018 12:25 AM

I was browsing the manual (very impressive) and noticed that you're mapping SAMS into cartridge space at >6000, but I'm pretty sure that's not possible. You can only map SAMS into the same regions as the 32K RAM is using.



#112 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Sun Jun 24, 2018 3:10 AM

I was browsing the manual (very impressive) and noticed that you're mapping SAMS into cartridge space at >6000, but I'm pretty sure that's not possible. You can only map SAMS into the same regions as the 32K RAM is using.

 

Thanks for that knowledge.  I only tried it in Classic99 and seemed to work . :-) (very little testing at this stage)

 

I will work on that.  I could use a spot in low RAM or High RAM but it seemed so logical to put in the cartridge space since I have nothing there. :-)

 

B



#113 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,354 posts
  • Location:Germany

Posted Sun Jun 24, 2018 4:25 AM

I was browsing the manual (very impressive) and noticed that you're mapping SAMS into cartridge space at >6000, but I'm pretty sure that's not possible. You can only map SAMS into the same regions as the 32K RAM is using.

 

But it's only because the SAMS is designed that way. It is not a general problem with the address space, i.e. you can respond to 6000-7FFF from the box (otherwise, the HSGPL would not work). This address space is just decoded for the ROMG line to the cartridge port, but not inhibited.

Attached Files


  • RXB likes this

#114 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 2,871 posts
  • Location:Denmark

Posted Sun Jun 24, 2018 4:42 AM

 

But it's only because the SAMS is designed that way. It is not a general problem with the address space, i.e. you can respond to 6000-7FFF from the box (otherwise, the HSGPL would not work). This address space is just decoded for the ROMG line to the cartridge port, but not inhibited.

 

It's a shame the designers of SAMS didn't think of that. It would make the SAMS much more useful to be able to page into an unused area, and it would make it easier to convert ROM paged software to SAMS. 

 

I'm moving off topic here, but does this mean it would be possible to make a paged ROM cart for the sideport that also included 32K RAM?



#115 Tursi ONLINE  

Tursi

    Quadrunner

  • 5,241 posts
  • HarmlessLion
  • Location:BUR

Posted Sun Jun 24, 2018 12:56 PM

It's a shame the designers of SAMS didn't think of that. It would make the SAMS much more useful to be able to page into an unused area, and it would make it easier to convert ROM paged software to SAMS.


Well, the problem is, how do you know when there's a cartridge at that address space, so you don't conflict? Without modifications to the console you can't tell, and you can't disable the ROM plugged into the cart port.

Classic99 shouldn't be allowing the map into cartridge space, but I didn't write the SAMS support. I'll check that. ;)
  • RXB likes this

#116 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Thu Jul 5, 2018 9:23 PM

And now for something completely different...

 

I enjoy rummaging around in Rosetta code to see how different things are solved in different languages and of course I occasionally make a code contribution.

I saw the Task "Date Format" and when I looked at the Forth version I thought I would do it a little differently.

 

As I understand it Forth is not a language; it's a set of tools to help you make the language you need to solve your computing problem. That's why it takes longer to learn it IMHO. It's a different way to think about programming.

 

So the Rosetta task is:

 

 Display the current date in the formats of:
     2007-11-23     and
     Sunday, November 23, 2007 

 

After letting Forth do its magic here is the solution:

\ Rosetta Date Format 1
: Y-M-D.     ( d m y -- )  ####. '-' ##. '-' ##. ;

\ Rosetta Date Format 2
: LONG.DATE ( d m y -- )
    3DUP CDAY DOW ]DAY$. ',' -ROT ]MONTH$. SPACE ##.  ','  ####.  ;

Testing it at the TI-99 console  it works like this:

 

 5 7 2018 Y-M-D. 2018-07-05 ok
  ok
5 7 2018 LONG.DATE Thursday, July 05, 2018 ok

 

The spoiler has all the language extension code for CAMEL99 Forth which also seems to run perfectly on GForth.

Spoiler

Edited by TheBF, Thu Jul 5, 2018 9:34 PM.


#117 RXB OFFLINE  

RXB

    River Patroller

  • 3,303 posts
  • Location:Vancouver, Washington, USA

Posted Fri Jul 6, 2018 11:05 AM

Deleted


Edited by RXB, Sun Jul 15, 2018 1:11 PM.


#118 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Fri Jul 6, 2018 7:58 PM

Just so you guys know RXB new routine 

CALL SAMS("LOAD","DSK#.FILENAME")

will load SAMS 1Meg takes 5 minutes.

(Classic99 or RAMDISK speeds, SCSI slightly slower at just under 6 minutes.)

 

Once done you have 31 (32K banks) memory loaded and can switch with

CALL SAMS("32K",BANK#,ADDRESS)

 

EVEN IF FORTH IS IN ONE OF THOSE BANKS.

 

CARTS are great but they do not SAVE WHAT WAS DONE!!!!!

 

Run your 32K memory exit to another 32K memory program or another....

 

But save it all to disk with 

CALL SAMS("SAVE","DSK#.FILENAME",#of banks to save) ! you can save from 1 (32K) to 31 (32K) banks.

 

Tell me this is not a new idea in the TI99/4A world?????

 

 

That's a cool hack Rich. I have only made some testing routines to load up 32K blocks of SAMS with nonsense data. I have not done anything serious.  I made a way to access any 2-byte cell in SAMS with a 32bit store operator and a 32bit fetch operator. But that's as far as I went.

 

So do you use a variable to hold a "page" for the active 32K section?  (A kind of segment approach)


  • RXB likes this

#119 RXB OFFLINE  

RXB

    River Patroller

  • 3,303 posts
  • Location:Vancouver, Washington, USA

Posted Fri Jul 6, 2018 8:34 PM

 

 

That's a cool hack Rich. I have only made some testing routines to load up 32K blocks of SAMS with nonsense data. I have not done anything serious.  I made a way to access any 2-byte cell in SAMS with a 32bit store operator and a 32bit fetch operator. But that's as far as I went.

 

So do you use a variable to hold a "page" for the active 32K section?  (A kind of segment approach)

LOL GPL!!!!

 

See GPL stores in Scratch Pad RAM and needs no RAM to work, only the GPL Workspace Registers.

So everything is run from GPL in Scratch Pad RAM and VDP.

 

Nothing to load as GPL is built into the TI OS!!!

 

When you use CALL SAMS("SAVE", "DSK4.TEST",31) it uses a PAB at VDP >0A00 and VDP Buffer at >0A80 

 

When you use CALL SAMS("LOAD","DSK4.TEST",CPU Address) it does the same thing but runs the Address.

 

And when you want to change programs (32K) you use CALL SAMS("32K",CPU Address) and it switches 32K in SAMS then runs that CPU address.

 

If you are asking for a contiguous segment of 32K programs you could make a RXB XB program to do that and could look at a flag set in VDP at unused VDP memory like >3FE0


Edited by RXB, Fri Jul 6, 2018 8:38 PM.


#120 RXB OFFLINE  

RXB

    River Patroller

  • 3,303 posts
  • Location:Vancouver, Washington, USA

Posted Sun Jul 8, 2018 12:00 PM

 

 

That's a cool hack Rich. I have only made some testing routines to load up 32K blocks of SAMS with nonsense data. I have not done anything serious.  I made a way to access any 2-byte cell in SAMS with a 32bit store operator and a 32bit fetch operator. But that's as far as I went.

 

So do you use a variable to hold a "page" for the active 32K section?  (A kind of segment approach)

Oh I forgot in my last post to explain you can use ADDRESS or LINK names.

 

So CALL SAMS("32K',BANK#,"LINKNAME") will work the same as CALL SAMS("32K",BANK#,ADDRESS)



#121 FarmerPotato OFFLINE  

FarmerPotato

    Chopper Commander

  • 108 posts
  • Location:Austin, TX

Posted Mon Jul 9, 2018 12:48 PM

Well, the problem is, how do you know when there's a cartridge at that address space, so you don't conflict? Without modifications to the console you can't tell, and you can't disable the ROM plugged into the cart port.

Classic99 shouldn't be allowing the map into cartridge space, but I didn't write the SAMS support. I'll check that. ;)

 

When the CPU reads from the cartridge port, what do the data lines look like on the side port? I think the cartridge port data lines and side port data lines are the same wire. This could be read by a sideport peripheral connected directly to the data bus -- but not by a Pbox card where there are LS245 buffers in the flex cable and the card itself.

 

I'm imagining the CPU reading from >6000 and expecting to find >AA. A really smart sideport peripheral would detect the first read cycle on that address, monitor the data bus to see if the cartridge ROM supplies >AA, and stand down. Or discover what happens when it contends for the data bus :)

 

This doesn't solve contention in the case that you want the sideport ROM to be there at startup. By the time the smart peripheral waits to see if the cartridge responds, it will be too late for it to supply a byte. So it would fail to be included in the cartridge menu scan. 

 

It would apply in the case where SAMS is told to map into the cartridge space after startup. I don't really see a sensible use case here, unless this imaginary sidecar device provides a menu loader in addition to a cartridge library, and you don't ever exoect to plug in a cartridge like E/A or XB.

 

Just an idea.  

 

Supposing a more sophisticated future SAMS implementation,


Edited by FarmerPotato, Tue Jul 10, 2018 8:51 AM.


#122 marc.hull OFFLINE  

marc.hull

    Stargunner

  • 1,297 posts
  • Location:Oklahoma CIty.

Posted Mon Jul 9, 2018 4:39 PM

When the system is powered on the card is in pass mode which as I understand it means that the SAMS card looks only like a normal 32k card.

If SAMS were to be invoked then it would be pretty simple to first check the cart space for occupancy and abort if a cart ROM is present. DSR space could also be utilized provided the program didn't double dip in that pool.

#123 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 703 posts
  • Location:The Great White North

Posted Tue Jul 10, 2018 7:06 AM

What about me simply stating that CAMEL99 is designed to operate with the standard E/A cartridge?

 

All other configurations are not supported.

 

 

B



#124 RXB OFFLINE  

RXB

    River Patroller

  • 3,303 posts
  • Location:Vancouver, Washington, USA

Posted Tue Jul 10, 2018 6:50 PM

When the system is powered on the card is in pass mode which as I understand it means that the SAMS card looks only like a normal 32k card.

If SAMS were to be invoked then it would be pretty simple to first check the cart space for occupancy and abort if a cart ROM is present. DSR space could also be utilized provided the program didn't double dip in that pool.

 

Here is the issue, SAMS PASS MODE works like a normal 32K as default.

 

If you are going to use CART SPACE or ANY SPACE you have to check before you activate SAMS MAP MODE!

So asking the SAMS to do this is pretty silly as there is NO DSR on the SAMS, just REGISTERS and nothing else.

 

It is the responsibility of the SOFTWARE USING SAMS to figure this out not the TI OS.

RXB does this by default as should everyone else that makes software for the SAMS.


Edited by RXB, Tue Jul 10, 2018 6:50 PM.


#125 marc.hull OFFLINE  

marc.hull

    Stargunner

  • 1,297 posts
  • Location:Oklahoma CIty.

Posted Sat Jul 14, 2018 8:10 PM

 
Here is the issue, SAMS PASS MODE works like a normal 32K as default.
 
If you are going to use CART SPACE or ANY SPACE you have to check before you activate SAMS MAP MODE!
So asking the SAMS to do this is pretty silly as there is NO DSR on the SAMS, just REGISTERS and nothing else.
 
It is the responsibility of the SOFTWARE USING SAMS to figure this out not the TI OS.
RXB does this by default as should everyone else that makes software for the SAMS.

Yea that's pretty much EXACTLY WHAT I POSTED.

Rich, you need to read and digest posts before you go and fire off some left field response that either reiterates what someone just posted or goes off on some RXB tangent that has nothing to do with what is being discussed.

And while I'm throwing myself under the bus again.... Your RXB posts belong in the RXB thread or any other thread where SOMEONE ELSE brings up RXB. It's really worn thin.

Edited by marc.hull, Sat Jul 14, 2018 8:11 PM.






Also tagged with one or more of these keywords: Camel99, Forth, Concatentive Programming, ANS Forth

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users