Jump to content
IGNORED

TF, camel, FB Forth fun


GDMike

Recommended Posts

1 hour ago, GDMike said:

Btw, Something that I didn't know. In the dump routine, screen 36, Is a word that identifies a users screen mode, by reading a value returns 32 column or 80 column. 

 

If you are talking about _step , that is used to hold the number of bytes per line to dump to the screen. It is 20 for 80-column-text mode or 8 for 40-column-text mode (not for 32-column graphics mode). DUMP and VDUMP presume you are using one of the text modes.

 

...lee

  • Like 1
Link to comment
Share on other sites

20 hours ago, GDMike said:

Not that one..I'll have to look again at it, but the word returned a 32 or an 80. I can't remember what the word is, but I'll look in a bit again here.

 

20 hours ago, GDMike said:

It was XMAX that returned the value

 

XMAX is updated whenever the graphics mode is changed. TurboForth has three graphics modes, 0 (40 columns, TEXT); 1 (32 columns, GRAPHICS); 2 (80 columns, TEXT80). Though DUMP and VDUMP work in GRAPHICS mode, each line’s display wrapping to a second line is not very neat—they were intended for the two text modes. If you must display the result in GRAPHICS mode, you can redefine _step on block 36 to

 

: _step  XMAX 7 - 2* 7 / 2/ 2*  ;

 

This will insure that all three modes display the dump without any line wraps. Bytes per line will be

 

Mode     Bytes/line
-------- ----------
TEXT80      20
TEXT         8
GRAPHICS     6

 

...lee

  • Like 2
  • Thanks 2
Link to comment
Share on other sites

8 hours ago, Lee Stewart said:

 

 

XMAX is updated whenever the graphics mode is changed. TurboForth has three graphics modes, 0 (40 columns, TEXT); 1 (32 columns, GRAPHICS); 2 (80 columns, TEXT80). Though DUMP and VDUMP work in GRAPHICS mode, each line’s display wrapping to a second line is not neat—they were intended for the two text modes. If you must display the result in GRAPHICS mode, you can redefine _step on block 36 to

 

: _step  XMAX 7 - 2* 7 / 2/ 2*  ;

 

This will insure that all three modes display the dump without any line wraps. Bytes per line will be

 

Mode     Bytes/line
-------- ----------
TEXT80      20
TEXT         8
GRAPHICS     6

 

...lee

Awesome..thx

Link to comment
Share on other sites

Looking at my code, I'm vexed that _step is evaluated four times in the word _dmp :x.

 

 
--BLOCK-00036---------
\ DUMP & VDUMP - MRW 8th October 2011
0 VALUE _vect
: _step ( -- n ) XMAX 7 - 2* 7 / 2/ 2*  ;
: _dmp CR  TRUE ZEROS !
  _step /MOD SWAP IF 1+ THEN 0 DO DUP $. ASCII = EMIT SPACE
  _step 0 DO DUP I + _vect EXECUTE DUP $. HERE I + ! 2 +LOOP
  HERE _step TYPE CR  _step + LOOP   FALSE ZEROS ! DROP ;
: _vread    DUP V@ SWAP 1+ V@ SWAP 8 << OR ;
: DUMP  ( addr count -- ) ['] @ TO _vect  _dmp ;
: VDUMP ( addr count -- ) ['] _vread TO _vect  _dmp ;
.( DUMP and VDUMP loaded)
.( Syntax: <address> <count> DUMP or VDUMP )
.( to dump CPU or VDP memory )

 

I think this is much better:

 

 
--BLOCK-00036---------
\ DUMP & VDUMP - MRW 8th October 2011
0 VALUE _vect  0 VALUE _step
: _getStep ( -- ) XMAX 7 - 2* 7 / 2/ 2* to _step ;
: _dmp CR  TRUE ZEROS !
  _step /MOD SWAP IF 1+ THEN 0 DO DUP $. ASCII = EMIT SPACE
  _step 0 DO DUP I + _vect EXECUTE DUP $. HERE I + ! 2 +LOOP
  HERE _step TYPE CR  _step + LOOP   FALSE ZEROS ! DROP ;
: _vread ( addr -- n ) DUP V@ SWAP 1+ V@ SWAP 8 << OR ;
: DUMP  ( addr count -- ) _getStep ['] @      TO _vect  _dmp ;
: VDUMP ( addr count -- ) _getStep ['] _vread TO _vect  _dmp ;
.( DUMP and VDUMP loaded)
.( Syntax: <address> <count> DUMP or VDUMP )
.( to dump CPU or VDP memory )
 
 
 

 

  • Like 4
Link to comment
Share on other sites

Very interesting to see another version. Your code is a lot smaller and uses a different method than mine. 

You build a string at HERE and type it which I am liking and didn't think of.

I read the data to the stack and figure out what to do with it on the fly.

 

\ extracted from dsk1.tools

DEFER MEM@
DEFER MEMC@

HEX
: ?BREAK  ( -- ) ?TERMINAL ABORT" *BREAK*" ;
: SPACEBAR ( -- ) KEY? BL = IF  KEY DROP  THEN ;

.( ..)
: .####   ( n --) 0 <#  # # # #  #> TYPE ;

: .ASCII  ( adr n --)
          BOUNDS
          DO
            I MEMC@ DUP
            80 [ BL 1- ] LITERAL WITHIN ( ascii 127..31)
            IF DROP [CHAR] .
            THEN EMIT
          LOOP ;

DECIMAL
: ?80 ( -- 16 | 8)  C/L @ 80 = IF 16 ELSE 8 THEN ;
.( ..)
HEX
: (DUMP)   ( offset n -- )
         BASE @ >R
         HEX
         BOUNDS   ( -- endadr startadr)
         DO PAUSE
         CR  I  .####  [CHAR] : EMIT 
             I  ?80  BOUNDS DO  SPACE I MEM@ .####  2 +LOOP SPACE
             I  ?80  .ASCII
             SPACEBAR
             ?BREAK
          ?80 +LOOP
          CR
          R> BASE ! ;

: DUMP    ['] @  IS MEM@    ['] C@  IS MEMC@  (DUMP) ;
: VDUMP   ['] V@ IS MEM@    ['] VC@ IS MEMC@  (DUMP) ;

 

 

 

  • Like 3
Link to comment
Share on other sites

Made wonder what happens If I duplicate your functionality (no BREAK, no space bar stop, no 80 column adjustment) it comes down to 242 bytes just for DUMP.

Of course, I need DEFER to be installed and that's 174 bytes extra if I want the vectored stuff. Might be smaller just using variables and EXECUTE. :)

 

 

INCLUDE DSK1.DEFER

DEFER MEM@
DEFER MEMC@

HERE
HEX
.( ..)
: .####   ( n --) 0 <#  # # # #  #> TYPE ;

: .ASCII  ( adr n --)
          BOUNDS
          DO
            I MEMC@ DUP
            80 [ BL 1- ] LITERAL WITHIN ( ascii 127..31)
            IF DROP [CHAR] .
            THEN EMIT
          LOOP ;

.( ..)
HEX
: (DUMP)   ( offset n -- )
         BASE @ >R
         HEX
         BOUNDS   ( -- endadr startadr)
         DO PAUSE
         CR  I  .####  [CHAR] : EMIT 
             I  8  BOUNDS DO  SPACE I MEM@ .####  2 +LOOP SPACE
             I  8  .ASCII
          8 +LOOP
          CR
          R> BASE ! ;

: DUMP    ['] @  IS MEM@    ['] C@  IS MEMC@  (DUMP) ;
: VDUMP   ['] V@ IS MEM@    ['] VC@ IS MEMC@  (DUMP) ;          
          
HERE SWAP - DECIMAL . 

 

 

  • Like 1
Link to comment
Share on other sites

  • 5 weeks later...
1 hour ago, GDMike said:

quick question, if using SAMs in TF is there a way to redefine a charset without using SAMs memory, because when I'm using SAMs  and I created a charset, I used a couple banks quickly using DCHAR.

 

It takes only half a bank (2KiB) to store a complete character set of 256 characters---code coming in a bit.

 

...lee

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

2 hours ago, Lee Stewart said:

It takes only half a bank (2KiB) to store a complete character set of 256 characters---code coming in a bit.

 

...lee

 

Indeed, trying to set up a complete character set with TurboForth code using DCHAR and DATA in interpret mode will take up more than one SAMS bank. But, you can write two blocks of binary code (1KiB each) for a complete character set and load those with minimal code. One way to do this is to actually redefine the character set followed by writing the new PDT (Pattern Definition Table) to 2 blocks of your choosing in 2 passes:

 

\ First...Redefine characters [You figure it out]
\ Following is TurboForth code to copy the new PDT to blocks 21 and 22.
\ [Change block numbers to your preferences]
HEX
TEMPBUF VARIABLE 0400 ALLOT   \ reserve dictionary space for transfer
0800 CONSTANT PDT             \ VRAM address of PDT
DECIMAL
\ Copy first half of PDT to block 21
PDT TEMPBUF 1024 VMBR         \ get first half of PDT to TEMPBUF
21 BLOCK       \ get block 21 from disk to a block buffer S:vaddr
TEMPBUF 1024 VMBW \ write first half of PDT to block 21's block buffer
UPDATE         \ mark block 21 as edited
FLUSH          \ write block 21 to disk
\ Copy second half of PDT to block 22
PDT 1024 +     \ address of second half of PDT
TEMPBUF 1024 VMBR    \ get second half of PDT to TEMPBUF
22 BLOCK       \ get block 22 to a block buffer S:vaddr
TEMPBUF 1024 VMBW \ write second half of PDT to block 22's block buffer
UPDATE         \ mark block 22 as edited
FLUSH          \ write block 22 to disk
FORGET TEMPBUF    \ return unneeded space to dictionary

 

Then, you can load the new character definitions into the PDT with

 

\ Following is TurboForth code to copy new character definitions
\ from blocks 21 and 22 to the PDT.
\ [Change block numbers to your preferences]
HEX
TEMPBUF VARIABLE 0400 ALLOT   \ reserve dictionary space for transfer
0800 CONSTANT PDT             \ VRAM address of PDT
DECIMAL
\ Copy block 21 to first half of PDT
21 BLOCK       \ get block 21 from disk to a block buffer S:vaddr
TEMPBUF 1024 VMBR    \ get block 21 contents to TEMPBUF
PDT TEMPBUF 1024 VMBW   \ write TEMPBUF to first half of PDT
\ Copy block 22 to second half of PDT
22 BLOCK       \ get block 22 from disk to a block buffer S:vaddr
TEMPBUF 1024 VMBR    \ get block 22 contents to TEMPBUF
PDT 1024 +     \ address of second half of PDT
TEMPBUF 1024 VMBW   \ write TEMPBUF to second half of PDT
FORGET TEMPBUF    \ return unneeded space to dictionary

 

...lee

Edited by Lee Stewart
CODE IMPROVEMENT
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

52 minutes ago, Lee Stewart said:

Indeed, trying to set up a complete character set with TurboForth code using DCHAR and DATA in interpret mode will take up more than one SAMS bank. But, you can write two blocks of binary code (1KiB each) for a complete character set and load those with minimal code. One way to do this is to actually redefine the character set followed by writing the new PDT (Pattern Definition Table) to 2 blocks of your choosing in 2 passes:

 

The same code in fbForth 2.0 is simpler because the block buffers are in CPU RAM and PDT is a system constant:
 

\ First...Redefine characters [You figure it out]
\ Following is fbForth code to copy the new PDT to blocks 21 and 22.
\ [Change block numbers to your preferences]
\ Copy first half of PDT to block 21
PDT 21 BLOCK 1024 VMBR  \ write first half of PDT to block 21's buffer
UPDATE         \ mark block 21 as edited
FLUSH          \ write block 21 to disk
\ Copy second half of PDT to block 22
PDT 1024 +     \ from address of second half of PDT
22 BLOCK 1024 VMBR   \ write to block 22's buffer
UPDATE         \ mark block 22 as edited
FLUSH          \ write block 22 to disk

\ Following is fbForth code to copy new character definitions
\ from blocks 21 and 22 to the PDT.
\ [Change block numbers to your preferences]
\ Copy block 21 to first half of PDT
21 BLOCK       \ get block 21 from disk to a block buffer S:vaddr
PDT 1024 VMBW  \ write block 21 to first half of PDT
\ Copy block 22 to second half of PDT
22 BLOCK       \ get block 22 from disk to a block buffer S:vaddr
PDT 1024 +     \ address of second half of PDT
1024 VMBW      \ write block 22 to second half of PDT

 

...lee

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

Thank you Lee I knew that there had to be something I was doing to cause a massive amount of ram use.

BUT in assy, there was not this issue.

I can see NOW that DCHAR is probably not my best bet here.

I'm so very glad you corrected me here. I couldn't figure out what the heck was going on. 

Here was my issue originally.

I had created 2 words, "UCASE"  and "LCASE" 

For a different set other than the default in TF.

And I didn't know how to restore the original default charset in TF, so I created a word, "DEFSET". All those definitions are data statements and pushed with DCHAR.

I'm also thinking there may be another way to "RESET" TF back to the default charset as well.

Thx lee,. Happy turkey day. I'm actually back under the weather again today... but that's the way things go. Have a great day 

Edited by GDMike
Typo
  • Like 1
Link to comment
Share on other sites

Hope you get well soon.

 

Lee's code shows how nice it is to have BLOCK.

Way simpler than using TI files when you save/get data.

 

Your challenge when you get better, will be to wrap it up into a pair of words like SAVE-FONT and LOAD-FONT.

(No pressure) :)

 

 

 

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

3 hours ago, Lee Stewart said:

Indeed, trying to set up a complete character set with TurboForth code using DCHAR and DATA in interpret mode will take up more than one SAMS bank. But, you can write two blocks of binary code (1KiB each) for a complete character set and load those with minimal code. One way to do this is to actually redefine the character set followed by writing the new PDT (Pattern Definition Table) to 2 blocks of your choosing in 2 passes:

 

Even simpler—

 

\ First...Redefine characters [You figure it out]
\ Following is TurboForth code to copy the new PDT to a file
S" DSK1.LUNSFONT01" 2048 $0800 SAVE#5

\ Following is TurboForth code to copy new character definitions
S" DSK1.LUNSFONT01" $0800 LOAD#5

 

...lee

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

1 hour ago, Lee Stewart said:

 

Even simpler—

 

\ First...Redefine characters [You figure it out]
\ Following is TurboForth code to copy the new PDT to a file
S" DSK1.LUNSFONT01" 2048 $0800 SAVE#5

\ Following is TurboForth code to copy new character definitions
S" DSK1.LUNSFONT01" $0800 LOAD#5

 

...lee

I stand corrected.  I guess if someone has implemented the file solution for you TI99 is pretty nice. :)

 

In my dialect it would be:

INCLUDE DSK1.LOADSAVE
HEX 800 CONSTANT PDT 

DECIMAL 
S" DSK1.LUNSFONT01" PDT 2048 SAVE-FONT 

S" DSK1.LUNSFONT01" PDT 2048 LOAD-FONT

This saves the files in internal, relative, fixed format. 

  • Like 2
Link to comment
Share on other sites

Forth code in SAMS for TurboForth 

Since this thread is all about fun I am sharing some of mine. 

 

This version of Mark's code removes the array of addresses in the Forth dictionary that keep track of the SAMS dictionary pointer.

It is replaced with the last memory cell in each SAMS bank.

 

To start to use a bank of SAMS the dictionary pointer must be initialized to >3000.

Previously you used BANKS.

 

n BANKS 

 

With this version you use 

n NEWBANK

... the first time you want to use it. That initializes the memory and does a SETBANK.

Any SAMS can be used for code after you use NEWBANK.

 

After that can use SETBANK just as before. 

 

It seems to work in Turbo Forth. 

 

Other changes: 

  • There are some extra constants defined that came from the Camel99 version. They could be removed if they offend you.
  • _BFREE has been changed to .BFREE which is more conventional naming for something the prints
  •  IF statements have been removed by defining ?BANK which abort with a message if the bank# is outside 0 and 255.  Change the range as you see fit. 
  • The constant CSEG (code seg) has been defined so you can move the SAMS window if you want too. 
     

Next up I want to see if I can move the stuff at the end of the definition into SAMS memory to save dictionary space.

I loaded a program with 22 words into SAMS with this system and it used 1238 bytes of dictionary space!

We will find out if that's why my other versions died on DEFER. 

 

EDIT: Added a protection in NEWBANK to argument <0 

 

Spoiler
\ bankcode-2.fth  for turbo forth

\ ***************************************************************
\ * this version keeps sams dictionary pointer in the sams page *
\ ***************************************************************

here
hex
4000 constant $4000
1000 constant 4k

\ sams card management
hex
             $3000 constant cseg  \ cpu ram window for sams code
$4000 cseg 0b >> + constant creg      \ pre-compute cseg sams register
 cseg 0c <<        constant passthru  \ default page for cseg

decimal
create _bnkstk   20 cells allot  \ bank stack

\ when turbo forth is in its "default" configuration the second
\ half of the 8k memory expansion (>3000) is set to sams page
\ >f9. the following line of code initialises the first page of
\ the bank stack to page f9. this ensures that when executing
\ nested bank/pages, when it all unwinds, the default page is
\ swapped into memory.

hex
passthru  _bnkstk ! \ force first entry on bank stack to passthru bank

_bnkstk value _bsp             \ pointer into bank stack
-1 value _bank                 \ current bank
 0 value _nhere                 \ "normal" here

00ff value _maxbank \ *changed

: ?bnkstk ( -- )
 _bsp _bnkstk [ _bnkstk 20 cells + ] literal within 0=
 IF  _bnkstk to _bsp  true ABORT" >>Bank stack<<"  then ;

: bnkpop  ( -- n ) -2 +to _bsp ?bnkstk  _bsp @ ;
: bnkpush ( n -- )  2 +to _bsp ?bnkstk  _bsp ! ;

: >bank   ( n -- ) DUP bnkpush CSEG >map ;
: bank>   ( -- n )     bnkpop  CSEG >map ;

cseg 0ffe + constant samsdp \ *changed

: b: ( bank -- )
  \ begin compiling a banked definition in bank bank
  _bank -1 <> if
  :
  compile lit _bank ,
  compile >bank
  compile branch  samsdp @ dup ,

  here to _nhere           \ save "normal here"
  h !                     \ set h to _bank's "here"
  _bank  CSEG >map        \ map in the appropriate bank

  else : then ;

: .bfree ( -- )  $4000  samsdp @ -  .  ." bytes free." cr ;

: ;b ( -- ) \ end banked compilation
   compile branch  _nhere ,
   here samsdp ! \ update here for bank
    _nhere h !    \ restore dp to "normal" memory
    compile bank>
    [compile] ;
    .bfree
; IMMEDIATE  ( had to add immediate for CAMEL99 )

: ?bank ( n --n) dup 0 _maxbank 1+ 0= within abort" illegal bank number" ;

: setbank ( bank -- ) \ sets bank number that will receive colon definitions
    ?bank   to _bank
   _bank -1 <>
    if   cr ." bank " _bank . ." is active."  .bfree
    else cr ." compiling to 32k memory." cr
    then
;

: newbank ( bank# --) \ init a SAMS bank
      DUP 0< IF DROP EXIT THEN
      ?bank
      dup CSEG >map
      cseg 4k ff fill   \ fill is for debugging
      cseg samsdp !     \ set the local cseg dp variable to start of cseg
      setbank ;

 : : ( -- ) \ banked / non-banked compilation
  _bank -1 = if : else b: then ;

 : ; ( -- ) _bank -1 =
      if   [compile] ;
      else [compile] ;b   \ ;b is immediate in camel99 forth
      then ; immediate

here swap - decimal  . .( bytes)

 

 

 

Edited by TheBF
Updated code , fixed comment
  • Like 4
Link to comment
Share on other sites

5 hours ago, TheBF said:

Did you ever wish you had a computer to help you organize your stack parameters better.

Wish no more!

 

Forth Wizard (sovietov.com)

BOOKMARKED the heck out it!!!! I've been playing with it for 15 minutes - writing code in TF to check it - it's bullet proof!!! Thanks!

Edited by Willsy
  • Like 1
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...