Jump to content
TheBF

Camel99 Forth Information goes here

Recommended Posts

So this is interesting.

JS99er reports that my binary files are "too short"

I will have take a look at what that is all about.

I put the size of the binary image in the file header not the total size of the file.

TI-99 seems to load them ok.

 

Things that make you say hmm...  

Share this post


Link to post
Share on other sites

When I manually edited the binary file and changed the length from >2040 to >2042, JS99er says the same thing and Classic99 won't load it.

Change it back and all is well again with Classic99.

 

Share this post


Link to post
Share on other sites

I was curious what you guys were talking about, so I took a look using version 2. The files look correct* to me, and they work fine in JS99er for me as well. Perhaps the disk image you're sending to JS99er is corrupted?

 

* - File THEMATRIX is oversized, reporting a full 8k of data available although six bytes are lost to the header. This is a common bug that nearly all EA#5 files have, and results in 6 bytes of garbage being copied, which is then overwritten with correct data when the next file is loaded.

 

But I didn't see any errors?

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
20 hours ago, TheBF said:

JS99er reports that my binary files are "too short"

Where does it say that?

The first version doesn't work for me but the second does.

BTW there's no need to use a disk image, you can just click 'Load disk' and select the zip file.

  • Like 3

Share this post


Link to post
Share on other sites
1 hour ago, Asmusr said:

Where does it say that?

The first version doesn't work for me but the second does.

BTW there's no need to use a disk image, you can just click 'Load disk' and select the zip file.

I think I might have found an earlier version of JS99er. It defaulted to TI BASIC and Editor/Assembler in the menu.

That's the one that gave me the "too short" message.

 

I have not learned how to add cartridges to JS99er to use it for my purposes. 

I will look for some docs. 

Share this post


Link to post
Share on other sites
21 minutes ago, TheBF said:

I think I might have found an earlier version of JS99er. It defaulted to TI BASIC and Editor/Assembler in the menu.

That's the one that gave me the "too short" message.

 

I have not learned how to add cartridges to JS99er to use it for my purposes. 

I will look for some docs. 

So now that I know how to use the emulator a bit I have found that programs I create with Camel99 Forth like theMatrix demo load fine on JS99ER.

The Camel99 program that is cross-compile with my DOS compiler are called "too short".

So I will be spending some time learning what I have wrong in my cross-compiler. :) 

Interesting that TI-99 and Classic99 load the files. 

I suspect there is something wrong with the cross-compiler as it was my first journey back into TI-99 space.

 

Share this post


Link to post
Share on other sites
4 hours ago, Asmusr said:

BTW there's no need to use a disk image, you can just click 'Load disk' and select the zip file.

Ah, that's a nice time saver!

Share this post


Link to post
Share on other sites
2 hours ago, TheBF said:

Interesting that TI-99 and Classic99 load the files. 

Classic99 is fairly generous when it's loading, check the debug log after loading to see if it threw any warnings. The real TI of course doesn't care and just does whatever it's told, whether valid or not. You could also post a file that complains and we can check the headers for you.

 

  • Like 1

Share this post


Link to post
Share on other sites
7 hours ago, Tursi said:

Classic99 is fairly generous when it's loading, check the debug log after loading to see if it threw any warnings. The real TI of course doesn't care and just does whatever it's told, whether valid or not. You could also post a file that complains and we can check the headers for you.

 

Thank you.  So far it is every file generated by my DOS cross-compiler, but none that I save from Camel99 Forth.

To be fair the code is entirely different. The DOS version is clunky from when I was just getting back to this stuff. 

 

Here is one the JS99er complains about.

Ignore the error on startup. It's just looking for the START file that is like autoexec.

 

 

CAMEL268.zip

  • Like 2

Share this post


Link to post
Share on other sites

The total file on disk is 8264 bytes.

 

I think there are size problems in the header.

 

image.thumb.png.51b8ba542b655c9531381a6bc87fc777.png

 

So the first 128 bytes are the V9T9 header. Of interest, bytes 14-15 show that the file length is 32 sectors, or 8192 bytes. 

 

But the first 6 bytes after that are the EA5 header. So starting at 80 in that image:

 

00 00 - means there are no more files after this one

20 46 - means this file is >2046 bytes long, or 8262 bytes

A0 00 - means this file loads at >A000

 

However, the file is NOT 8262 bytes long, and some loaders would not load it even if it were (since 8192 bytes, or 8k, is normally the maximum expected size). The actual TI part of this file is only 8136 bytes long, so loadable data is just 8130 bytes (cause the 6 byte header doesn't count).

 

Classic99 has this report:

DSR opcode >5 (LOAD) on PAB >100E, filename DSK0.CAMEL268
Loading to VDP >1380 DSK0.CAMEL268 on drive type FIAD
Detected d:\classic99\dsk1\CAMEL268 as a V9T9 file
loading 0x1FC8 bytes

That shows a smaller number still for the load size... 0x1FC8, which is the size on disk minus the 128 byte header (8136 bytes).

 

As an aside, the PAB (from Editor/Assembler) allows for up to >2100 bytes (8448).

So I am not sure what part JS99er is looking at, but you have a file on disk with 8136 bytes of TI data that represents itself as containing 8192 bytes of TI data and tries to load 8262 bytes of TI data. Somewhere in there. :)

 

 

Edited by Tursi
  • Like 3

Share this post


Link to post
Share on other sites

Super helpful analysis. Thanks @Tursi. 

I will compare these ratios to the one that JS99er likes and see what it takes to the fix the cross-compiler.

 

Share this post


Link to post
Share on other sites

Just make it accurate.

 

Pad it out to a full sector size, so your 8136 bytes of data should become 8192 bytes. At that point, your V9T9 header is already correct, so you can leave it alone. Change the load size in the EA5 header to 1FC8 (the actual size of the data you want to load), and all should be well.

 

Likely the padding alone will make JS99er happy, since the rest happens inside the TI side. ;)

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
On 11/28/2021 at 2:05 AM, Tursi said:

The total file on disk is 8264 bytes.

 

I think there are size problems in the header.

 

image.thumb.png.51b8ba542b655c9531381a6bc87fc777.png

 

So the first 128 bytes are the V9T9 header. Of interest, bytes 14-15 show that the file length is 32 sectors, or 8192 bytes. 

 

But the first 6 bytes after that are the EA5 header. So starting at 80 in that image:

 

00 00 - means there are no more files after this one

20 46 - means this file is >2046 bytes long, or 8262 bytes

A0 00 - means this file loads at >A000

 

However, the file is NOT 8262 bytes long, and some loaders would not load it even if it were (since 8192 bytes, or 8k, is normally the maximum expected size). The actual TI part of this file is only 8136 bytes long, so loadable data is just 8130 bytes (cause the 6 byte header doesn't count).

 

Classic99 has this report:

DSR opcode >5 (LOAD) on PAB >100E, filename DSK0.CAMEL268
Loading to VDP >1380 DSK0.CAMEL268 on drive type FIAD
Detected d:\classic99\dsk1\CAMEL268 as a V9T9 file
loading 0x1FC8 bytes

That shows a smaller number still for the load size... 0x1FC8, which is the size on disk minus the 128 byte header (8136 bytes).

 

As an aside, the PAB (from Editor/Assembler) allows for up to >2100 bytes (8448).

So I am not sure what part JS99er is looking at, but you have a file on disk with 8136 bytes of TI data that represents itself as containing 8192 bytes of TI data and tries to load 8262 bytes of TI data. Somewhere in there. :)

 

 

So the final resolution to this for JS99er was to use the correct Ti-99 code image size not the "total image-size" in the Program header. So 2046 became 1FC0.

Then when the cross-compiler writes out the file I had to pad out the binary image to match the >2000 which is the number in the DOS file header.

Now JS99ER loads programs created by my cross-compiler.

Makes perfect sense.  

Now I need to make a TIFILES. directive and stop creating V9T9 files. 

 

 

 

Edited by TheBF
typo
  • Like 1

Share this post


Link to post
Share on other sites

"The rumor's of my death have been greatly exaggerated"    Mark Twain

 

I have not been posting because I have been distracted by a few things.  In particular I am trying to create a  VI style editor called VI99. 

It will run without using SAMS or disk base virtual memory. 

The design spec is something like:

  1. Runs on console with expansion RAM and disk. 
  2. Ability to edit the largest files in my system. (~300 lines, >8K )  
  3. Leverages the Forth interpreter to replicate the command programmability of VI.
  4. Data is held in memory as single linked list using byte counted strings to save space.

image.png.973b2950576845ccbcf2cc170f458de5.png

 

 

Camel99 kernel Update

I have to do a release with changes but I have made to Camel99 but in the mean-time I have posted the kernel program here which has a few warts fixed.

 

1. A couple of words that I "improved" in ALC would not have worked correctly in a multi-tasking environment. (I forgot to use workspace relative addressing) DOH!

2. There was a bug in TYPE that would not work correctly if the length was 0. It would fail to DROP the address. Oops.

3. And as discussed programs from my cross-compiler didn't work on JS99er.  This one does. 

 

image.thumb.png.c1f7f0d47e3dde157a9739eeaa551ebe.png

CAMEL268.zip

  • Like 5

Share this post


Link to post
Share on other sites
1 hour ago, TheBF said:

"The rumor's of my death have been greatly exaggerated"    Mark Twain

 

I have not been posting because I have been distracted by a few things.  In particular I am trying to create a  VI style editor called VI99. 

It will run without using SAMS or disk base virtual memory. 

The design spec is something like:

  1. Runs on console with expansion RAM and disk. 
  2. Ability to edit the largest files in my system. (~300 lines, >8K )  
  3. Leverages the Forth interpreter to replicate the command programmability of VI.
  4. Data is held in memory as single linked list using byte counted strings to save space.

image.png.973b2950576845ccbcf2cc170f458de5.png

 

 

Camel99 kernel Update

I have to do a release with changes but I have made to Camel99 but in the mean-time I have posted the kernel program here which has a few warts fixed.

 

1. A couple of words that I "improved" in ALC would not have worked correctly in a multi-tasking environment. (I forgot to use workspace relative addressing) DOH!

2. There was a bug in TYPE that would not work correctly if the length was 0. It would fail to DROP the address. Oops.

3. And as discussed programs from my cross-compiler didn't work on JS99er.  This one does. 

 

image.thumb.png.c1f7f0d47e3dde157a9739eeaa551ebe.png

CAMEL268.zip 5.83 kB · 5 downloads

 

That is most interesting. Very much like the idea of using the forth interpreter for programmability and the linked list.

If I may make a suggestion; you could detect if the final grom is present and turn on its advanced mode (RAM). 

That way you could put the editor text there and go way beyond 300 lines. And there are a lot of people with final groms out there.

 

Even though with Stevie the original idea was to get a VI-editor style, it kinda took its own spin and I’m not following up on that anymore. I have so much more stuff I’d like to implement, that VI-editor compability went down the priority list a lot.

Anyway, very much looking forward to see how this further develops.

 

 

  • Like 2

Share this post


Link to post
Share on other sites

Thanks.

I will have to learn more about Final grom.  It's magic to me at the moment. :)

 

Share this post


Link to post
Share on other sites

In the course of working on VI99 I need a way to push things into a temp buffer. I decided to use VDP RAM since there is a lot of it available.

This little memory management scheme combines the Forth dictionary static allocation method with a 32 bit stack to hold the VDP address and size of each allocated block.

It seems to work pretty well and I think could be moved to other Forth systems with a little bit tweaking. 

 

One of the application problems was how to insert an arbitrary sized string into the middle of an array of byte counted strings.

Current solution: Copy everything below the string to a temp buffer, do your editing and then append the temp buffer onto the end of the newly inserted text.  :) 

 

We shall see how it all works but here is the API that gives me the ability to try it.

\ VS stack holds allocated VBLOCK data
DECIMAL
CREATE VS0   10 4* CELLS ALLOT  \ room for 10 allocated VDP blocks
CREATE VSP   VS0 ,              \ VDP stack pointer, initialzed to VS0

: VSDEPTH ( -- n) VS0 VSP @ -  2/ ;
: >VS     ( addr len --) 4 VSP +!   VSP @ 2! ;
: ?VMEM   ( -- ) DUP VS0 = ABORT" VStack empty" ;
: VBLOCK  ( -- Vaddr size) VSP @ ?VMEM [email protected]  ;  \ return last allocation.

HEX
: NEW-VDP ( -- )  1000 VP ! ;
: VHERE   ( vdp-mem) VP @ ;  \ next free address in VDP RAM
: VALLOT  ( n --)  VP +! ;
: V,      ( n --)  VHERE V!  2 VALLOT ;  \ compile integer to VDP ram
: VC,     ( n --)  VHERE VC! 1 VALLOT ;  \ compile byte to VDP ram

\ reserve block of size n returning addres Vaddr
: RESERVE ( n -- Vaddr) VHERE SWAP 2DUP >VS  VALLOT ;

\ de-allocate the last VBLOCK
: VFREE   ( -- ) VBLOCK -4 VSP +!  NEGATE VALLOT DROP ;

 

 

 

 

  • Like 2

Share this post


Link to post
Share on other sites
5 hours ago, TheBF said:

One of the application problems was how to insert an arbitrary sized string into the middle of an array of byte counted strings.

Current solution: Copy everything below the string to a temp buffer, do your editing and then append the temp buffer onto the end of the newly inserted text.  :)

 

Perhaps you could use a uni- or bi-directional linked list to avoid having to do any text patching until writing out the edited text. It would, of course, add 16 bits for each address link.

 

...lee

  • Like 1

Share this post


Link to post
Share on other sites

I considered the bi directional linked list but it seemed complicated so I tried the counted string concept.

The counted strings, placed end to end, act like a single linked list that I can scan through with just COUNT +.

I put those together in a CODE word called NEXTLN so it zips along pretty fast.  

I have SEEK2LINE and SEEK2END  words that let me move around in the "general buffer" as VI docs call it.

 

The whole thing is way more fragile than our normal block editors. I really get why Chuck just uses blocks.

Text files are the norm and save space on disk, but manipulating them seems way harder.

 

I have a tiny editor that I made that takes blocks and just uses the 40col VDP RAM screen as the editing buffer.

When you are done editing, it just does a VMBW of the entire screen back into the block buffer. :) 

It is fast and compact. 

However your source is best kept to 40 column width which I don't want. 

 

I am also wondering if my entire approach is wrong.  When I looked at the VI source code it looks like they use a structure for each line in the file which which would add a lot of overhead to the data in RAM.

However I guess it would still be less than wasting and entire 80byte record for each line as I did before. 

 

Feeling my way along...

  • Like 3

Share this post


Link to post
Share on other sites

Old Demons Raise their head  (and I cut them off) :) 

 

In the course of working on the VI99 editor an old bug came alive. My repeating key code call RKEY has been a thorn in my side for a while.

I thought I had fixed it a while back but today I had the Classic99 Heat Map running. (I love that thing @Tursi)  While testing the editor I saw a green laser beam shoot across the heat map. That is the telltale sign that VDP was accessed wrong.  I looked at the log and sure enough an "illegal instruction" was detected but Forth kept running.

I set the "Break on illegal opcode" and fooled around until it happened again.  Bang!  The break stopped and I recognized the code as what happens when Camel Forth "leaves" a DO/LOOP early.  I have never had a problem with this code anywhere else but RKEY does exercise it all the time so that's one more on the bug pile.

 

I re-worked the RKEY code to work without a DO/LOOP and it seems totally solid now.   

The new code uses the multiple WHILE construct that is allowed in ANS Forth.  I know it looks pretty strange but if you can remember WHILE is really just "IF" renamed, then it makes a bit more sense.  I am just happy to have this @#$!$!% piece of code working reliably now.  I will have to rebuild ED99 with it. 

 

Something interesting to me is that the code example on TI-99 tech pages used about 242 bytes in Assembler.

www.unige.ch/medecine/nouspikel/ti99/keyboard.htm#auto-repeat

 

This new version is 194 bytes in Forth.  Some of the saving is from not needing a separate workspace but it is interesting to see that Forth can save space versus ALC sometimes. 

 

Here is the new code.

For the great multitude of Camel99 users out there, please replace the file DSK1.RKEY with this RKEY file.

I zipped up a TI-99 version for DSK1. and a PC text file for the folder LIB.ITC.

 

Spoiler
\ Repeating key based on Nouspikel TI-99 tech pages,   V2 BFox
\ Improved Dec 11, 2021

HERE
DECIMAL
VARIABLE OUTKEY     \ key buffer
VARIABLE OLDKEY     \ previous key buffer
VARIABLE RPT

HEX
: RKEY?   ( -- char)
    RPT @
    IF    3             \ short delay value
    ELSE 45             \ long delay value
    THEN >R             \ delay counter on rstack
    BEGIN
       R> 1- DUP>R      \ dect. counter
    WHILE ( counter>0)
       83C8 ON          \ clear key buffer
       KEY?             \ call kscan
       OLDKEY @ OVER =  \ compare to oldkey
    WHILE ( key is same)
       DROP             \ don't need this key
       RPT ON
    REPEAT ( endwhile #2)
      DUP OUTKEY !  OLDKEY !
      RPT OFF
    THEN ( endwhile #1)
    R> DROP             \ remove the counter
    OUTKEY @
;

: RKEY ( -- char)
   VPOS [email protected] >R
   BEGIN
     PAUSE
     [email protected] 1FFF >
     IF CURS @ ELSE [email protected]  THEN VPUT
     RKEY?
     ?DUP
   UNTIL
   R> VPUT
;

HERE SWAP - DECIMAL .  ( 194 bytes)

 

 

RKEY.ZIP

  • Like 4

Share this post


Link to post
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...