Jump to content

Photo

Camel99 Forth Information goes here

Camel99 Forth Concatentive Programming ANS Forth

114 replies to this topic

#101 TheBF OFFLINE  

TheBF

    Dragonstomper

  • Topic Starter
  • 606 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
  • 606 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
  • 606 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
  • 606 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
  • 606 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
  • 606 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
  • 606 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
  • 606 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
  • 606 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 ONLINE  

Asmusr

    River Patroller

  • 2,751 posts
  • Location:Denmark

Posted Yesterday, 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
  • 606 posts
  • Location:The Great White North

Posted Yesterday, 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,253 posts
  • Location:Germany

Posted Yesterday, 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



#114 Asmusr ONLINE  

Asmusr

    River Patroller

  • 2,751 posts
  • Location:Denmark

Posted Yesterday, 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 OFFLINE  

Tursi

    Quadrunner

  • 5,072 posts
  • HarmlessLion
  • Location:BUR

Posted Yesterday, 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. ;)





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