Jump to content
TheBF

Camel99 Forth Information goes here

Recommended Posts

I have something that seems useful now although some code that I have in my libraries breaks when loaded in SAMS.

Need to understand why.

This version runs faster because MAPPER is now smart and does not map in a SAMS page if it is already in memory.

I will do a benchmark comparison between CPU RAM and SAMS memory.

 

Here is the code 

Spoiler
\ Code in SAMS memory based on concept in TurboForth by Mark Wills
\ Ported to Camel99 Forth  Oct 7, 2021

\ Changes from original:
\ Remove bank stack.  Used return stack for bank# storage
\ Removed BANKS word. Changed to preset DP array
\ CMAP is a fast sub-routine for mapping SAMS pages F0..FF
\      CMAP Remembers the last bank that was paged in variable LASTBNK
\ Changed to compile a far "colon" definition to reduce dictionary overhead

\ Oct 7, 2021:  Compares input to CMAP to LAstbnk and
\               does nothing if page is still in memory

\ FAR word data structure:
\   CELL: link
\   BYTE: immediate field
\   BYTE: name length
\   BYTES: <....>
\   CELL:  code field
\   CELL:  DATA field #1 , bank#
\   CELL:  DATA field #2 , SAMS code field address


INCLUDE DSK1.MARKER
INCLUDE DSK1.VALUES
\ INCLUDE DSK1.TOOLS
 INCLUDE DSK1.ASM9900

HERE
F0 VALUE _1STBANK
FF VALUE _MAXBANK

\ SAMS memory management for code
HEX              3000 CONSTANT CSEG      \ code seg in CPU RAM
4000 CSEG 0B RSHIFT + CONSTANT CREG      \ compute CSEG SAMS register
CSEG 0C RSHIFT        CONSTANT PASSTHRU  \ default page for CSEG

DECIMAL
CREATE []DP  \ DP for 0 .. 15 pages of SAMS
  CSEG , CSEG , CSEG , CSEG  ,
  CSEG , CSEG , CSEG , CSEG  ,
  CSEG , CSEG , CSEG , CSEG  ,
  CSEG , CSEG , CSEG , CSEG  ,

HEX
CODE ]DP ( bank# -- addr )
     TOS _1STBANK NEGATE  AI,  \ remove first bank offset to index []DP
     TOS TOS ADD,
     TOS []DP AI,
     NEXT,
ENDCODE

 VARIABLE  SAVHERE   \ temp holder for RAM Dictionary pointer
 VARIABLE  BANK#     \ active SAMS bank# for compiling
 VARIABLE  LASTBNK   \ last bank# passed to MAPPER

CODE BANK#@   ( -- bank#)  \ Used 8 times so this saves space and is fast
      TOS PUSH,
      BANK# @@ TOS MOV,
      NEXT,
ENDCODE

HEX
CREATE MAPPER ( R1: 0 .. 16 )  \ smart MAPPER
      R1 LASTBNK @@ CMP,  \ already mapped?
      NE IF,
         R1 LASTBNK @@ MOV,  \ update the last bank used
         R1 SWPB,          \ swap bytes
         R12 1E00 LI,      \ DO CMAP
         0 SBO,            \ turn on the card
         R1 CREG @@ MOV,   \ restore bank# from return stack
         0 SBZ,            \ turn off card
      ENDIF,
      RT,

CODE CMAP  ( bank# --) \ Forth word to map SAMS pages
      TOS R1 MOV,
      MAPPER @@ BL,
      TOS POP,
      NEXT,
      ENDCODE

CODE GOTO  ( addr -- ) *IP IP MOV,  NEXT, ENDCODE

CREATE FARCOL   \ run time executor for SAMS colon words.
     IP RPUSH,
     W IP MOV,
     RP DECT,
     LASTBNK @@ *RP MOV,  \ Rpush the active bank
     *IP+ R1 MOV,         \ fetch bank# from DATA FIELD -> R1, inc IP
     MAPPER @@ BL,        \ & switch to SAMS page for this word
     *IP IP MOV,          \ get SAMS DP & set new IP
     NEXT,

: FAR: ( -- ) \ special colon for words in FAR memory
     !CSP
     HEADER                \ compile Forth header with name
     FARCOL ,              \ compile the new executor as CFA
     BANK#@  ,            \ compile bank# as the DATA field
     BANK#@ ]DP @ ,     \ compile this word's SAMS address ( ie: FAR XT)

     HERE SAVHERE !        \ save "normal here"
     BANK#@ ]DP @ DP !  \ set dp to CSEG. Compiling goes here now
     BANK#@ CMAP          \ map SAMS for compiling
     HIDE
     ]                    \ turn on the compiler
;

HEX
CODE FAREXIT
     R1 RPOP,
     MAPPER @@ BL,
     IP RPOP,
     NEXT,
ENDCODE

: FARSEMIS ( -- )
      POSTPONE FAREXIT
      POSTPONE [
      REVEAL ?CSP ; IMMEDIATE

: ;FAR ( -- ) \ end banked compilation
      POSTPONE GOTO  SAVHERE @ ,
      HERE  BANK#@ ]DP !      \ update here for bank
      SAVHERE @ DP !             \ restore dp to "normal" memory
      POSTPONE FARSEMIS
; IMMEDIATE

DECIMAL
: SETBANK ( bank# -- ) \  0..15 are valid args
      DUP 256 240 WITHIN ABORT" Bad bank number"
      BANK# !
;

HEX
: _BFREE ( -- n) 4000  BANK#@ ]DP @ - ;
: .BFREE ( -- ) DECIMAL
    CR ." Bank# " BANK#@  . ." , "  _BFREE  .  ." bytes free." CR ;

HERE SWAP -
DECIMAL CR . .( bytes)  \ free 11,566

PASSTHRU CMAP  \ init the Forth memory bank# as LASTBNK
\ REMOVE-TOOLS
HEX
F0 SETBANK

 

 

Here is a test suite using a SAMS wordlist to hold a the SAMS version of  :  and  ;   plus all the SAMS words. 

 

Spoiler
\ redirecting : and ;
INCLUDE DSK1.WORDLISTS
ONLY FORTH DEFINITIONS
\ rename normal : ;  so we don't over-ride them and can still use them
: H:   :   ;
: ;H   POSTPONE ;  ;  IMMEDIATE

VOCABULARY SAMS
ALSO SAMS DEFINITIONS
\ Put : and ; in SAMS VOCABULARY as aliased FAR:  ;FAR
H: :    FAR:  ;H
H: ;   POSTPONE ;FAR  ;H  IMMEDIATE

\ SAMS must first in the search order to find the special
\ version of : and ;

FORTH DEFINITIONS
INCLUDE DSK1.DEFER  \ Defer seems to break SAMS compiling ??

SAMS DEFINITIONS
HEX F0 SETBANK
INCLUDE DSK1.TOOLS

SAMS DEFINITIONS
HEX F1 SETBANK
INCLUDE DSK1.ANSFILES
INCLUDE DSK1.CATALOG
INCLUDE DSK1.MORE

SAMS DEFINITIONS
HEX F2 SETBANK
INCLUDE DSK1.GRAFIX
INCLUDE DSK1.DIRSPRIT
INCLUDE DSK1.COOLSPRITE

ONLY SAMS ALSO FORTH DEFINITIONS

 

 

  • Like 1

Share this post


Link to post
Share on other sites

So I did a benchmark program in two versions.

 

One that lives in completely in CPU RAM.

 

The 2nd has the outer loop in SAMS F9 but the inner loop is in SAMS F8. 

This forces a cross SAMS page call. :) 

 

Here is the code.

Spoiler
\ sams benchmark vs CPU RAM
INCLUDE DSK1.WORDLISTS

ONLY FORTH DEFINITIONS
INCLUDE DSK1.VALUES
INCLUDE DSK1.ELAPSE

\ rename normal : ;  so we don't over-ride them and can still use them
: H:   :   ;
: ;H   POSTPONE ;  ;  IMMEDIATE

\ redirecting : and ;
VOCABULARY SAMS
ALSO SAMS DEFINITIONS
H: :    FAR:  ;H
H: ;   POSTPONE ;FAR  ;H  IMMEDIATE

FORTH DEFINITIONS
HEX
  5 CONSTANT FIVE
100 CONSTANT MASK
  0 VALUE BVAR

: INNERBENCH
    BEGIN
      DUP SWAP DUP ROT DROP 1 AND
      IF FIVE +
      ELSE 1-
      THEN TO BVAR
      BVAR DUP MASK AND
    UNTIL ;

: BENCHIE  MASK 0 DO  1 INNERBENCH  DROP  LOOP ;

\ __________________________________________
SAMS DEFINITIONS
F8 SETBANK      \ Force a call to another SAMS bank
: INNERBENCH
    BEGIN
      DUP SWAP DUP ROT DROP 1 AND
      IF FIVE +
      ELSE 1-
      THEN TO BVAR
      BVAR DUP MASK AND
    UNTIL ;

F9 SETBANK
: BENCHIE  MASK 0 DO  1 INNERBENCH  DROP  LOOP ;

FORTH ELAPSE BENCHIE
SAMS  ELAPSE BENCHIE

 

 

The screen shots tell the tale. Pages were toggling...

image.thumb.png.af606d1d9388eec8dc39c54d8d8a26c9.png 

 

Speed is VERY good.

Classic99 QI399.046 2021-10-07 9_07_51 PM.png

  • Like 3

Share this post


Link to post
Share on other sites

I was doing some folder housekeeping and found something I tried to do a long time ago.

I guess I have learned something over the last few years because it was clear to me that it was all wrong. :) 

 

The objective was to make a character pattern compiler the lets you "draw" your character patterns in text in your source code like these examples.

CREATE BIG-O
\  01234567
 |  ****   |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 |  ****   |

CREATE SQUARE
\  01234567
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|

 

The better idea was to convert a string of asterisks and spaces into a string of ones and zeros.

A string of ones and zeros can be "evaluated" by Forth as a binary number.

That number can then be compiled into memory as one byte of a pattern definition.

 

It's not nearly as fancy as a program that let's you draw on the screen but its a heck of lot easier than HEX bytes in a string.  :)

 

Here is the code with the examples above.

Code Edit: Removed HOLDER buffer and used PAD instead. Saves bytes  

 

Spoiler
\ Character shape compiler using text    Oct 12, 2021     B Fox

DECIMAL

VARIABLE PH

: BINARY   2 BASE ! ;

: DIGIT!  ( byte -- )
        PAD PH @ + C! \ store byte in PAD buffer
        PH 1+!        \ increment the PAD pointer
        1 PAD C+!  ;  \ increment the count byte

: STAR># ( char -- )     \ convert '*' to one or space to zero
        [CHAR] * =
        IF   [CHAR] 1 DIGIT!    \ store characters in PAD
        ELSE [CHAR] 0 DIGIT!
        THEN  ;

: >STAR#S  ( addr len -- addr len) \ convert string of * and spaces to 1s and zeros
        PAD OFF   1 PH !        \ init PAD and point position
        BOUNDS DO  I [email protected] STAR>#  LOOP
        PAD COUNT  ;            \ return PAD as a stack string

: |   ( -- )
       [CHAR] | PARSE-WORD  >STAR#S  \ parse string, convert to binary # string
       BINARY EVALUATE  C, ;         \ evaluate the string & compile the byte

HEX   ( these are in DSK1.GRAFIX )
: ]PDT     ( char# -- 'pdt[n] )  8* 800 + ;
: CHARDEF  ( addr char# --)  ]PDT 8 VWRITE ;


CREATE BIG-O
\  01234567
 |  ****   |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 |  ****   |

CREATE SQUARE
\  01234567
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|

DECIMAL
BIG-O  0 CHARDEF
SQUARE  1 CHARDEF
CR 0 EMIT  SPACE  1 EMIT

\ You can remove the shape compiler from the system when you are done with it.
\ but the character patterns DATA stays in VDP RAM.
\ FORGET PH

 

 

  • Like 2
  • Thanks 1

Share this post


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

I was doing some folder housekeeping and found something I tried to do a long time ago.

I guess I have learned something over the last few years because it was clear to me that it was all wrong. :) 

 

The objective was to make a character pattern compiler the lets you "draw" your character patterns in text in your source code like these examples.

CREATE BIG-O
\  01234567
 |  ****   |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 |  ****   |

CREATE SQUARE
\  01234567
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|

 

The better idea was to convert a string of asterisks and spaces into a string of ones and zeros.

A string of ones and zeros can be "evaluated" by Forth as a binary number.

That number can then be compiled into memory as one byte of a pattern definition.

 

It's not nearly as fancy as a program that let's you draw on the screen but its a heck of lot easier than HEX bytes in a string.  :)

 

Here is the code with the examples above.

  Reveal hidden contents

\ Character shape compiler using text    Oct 12, 2021     B Fox

VARIABLE PH
DECIMAL
CREATE HOLDER  10 ALLOT      HOLDER 10 0 FILL

: BINARY   2 BASE ! ;

: DIGIT!  ( byte -- )
        HOLDER PH @ + C! \ store byte in holder string
        PH 1+!           \ increment the holder pointer
        1 HOLDER C+!  ;  \ increment the count byte

: STAR># ( char -- )     \ convert '*' to one or space to zero
        [CHAR] * =
        IF   [CHAR] 1 DIGIT!    \ store characters in HOLDER
        ELSE [CHAR] 0 DIGIT!
        THEN  ;

: >STAR#S  ( addr len -- addr len) \ convert string of * and spaces to 1s and zeros
        HOLDER OFF   1 PH !        \ init HOLDER and point position
        BOUNDS DO  I [email protected] STAR>#  LOOP
        HOLDER COUNT  ;            \ return HOLDER as a stack string

: |   ( -- )
       [CHAR] | PARSE-WORD  >STAR#S  \ parse string, convert to binary # string
       BINARY EVALUATE  C, ;         \ evaluate the string & compile the byte

HEX   ( these are in DSK1.GRAFIX )
: ]PDT     ( char# -- 'pdt[n] )  8* 800 + ;
: CHARDEF  ( addr char# --)  ]PDT 8 VWRITE ;


CREATE BIG-O
\  01234567
 |  ****   |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 |  ****   |

CREATE SQUARE
\  01234567
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|

DECIMAL
BIG-O  0 CHARDEF
SQUARE  1 CHARDEF
CR 0 EMIT  SPACE  1 EMIT

\ You can even remove the shape compiler from the system when you are done with it.
\ but the character patterns DATA stays in VDP RAM.
FORGET PH

 

 

Neat. Cool

Share this post


Link to post
Share on other sites

I updated the code above to remove the HOLDER buffer and just used PAD.

 

Then I realized if you wanted to, the compiler could just put the bytes directly into VDP RAM in the pattern table.

You just replace C, with VC,   

 

Then you just need a word to set the VDP memory pointer to the correct location in the pattern table for the character you want to change.

This code does that.  So no CPU RAM is used to hold the patterns.

The downside of course is that the patterns have to be re-compiled each time you want them.

But I see this as simple way to design patterns on real iron.

Spoiler
\ Character shape compiler Direct to VDP   Oct 12, 2021     B Fox

: TASK ; 

INCLUDE DSK1.VDPMEM

DECIMAL

VARIABLE PH

: BINARY   2 BASE ! ;

: DIGIT!  ( byte -- )
        PAD PH @ + C! \ store byte in PAD buffer
        PH 1+!        \ increment the PAD pointer
        1 PAD C+!  ;  \ increment the count byte

: STAR># ( char -- )     \ convert '*' to one or space to zero
        [CHAR] * =
        IF   [CHAR] 1 DIGIT!    \ store characters in PAD
        ELSE [CHAR] 0 DIGIT!
        THEN  ;

: >STAR#S  ( addr len -- addr len) \ convert string of * and spaces to 1s and zeros
        PAD OFF   1 PH !        \ init PAD and point position
        BOUNDS DO  I [email protected] STAR>#  LOOP
        PAD COUNT  ;            \ return PAD as a stack string

: |   ( -- )
       [CHAR] | PARSE-WORD  >STAR#S  \ parse string, convert to binary # string
       BINARY EVALUATE  VC, ;         \ evaluate the string & compile the byte

HEX 800 CONSTANT PDT
: SHAPE ( ascii -- ) 8* PDT +  VP ! ;  \ set VDP memory to the char's pattern table

DECIMAL
0 SHAPE
\  01234567
 |  ****   |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 | *    *  |
 |  ****   |

1 SHAPE
\  01234567
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|
 | ********|

CHAR A SHAPE
 \ 01234567
 |         |
 |    *    |
 |   * *   |
 |  *   *  |
 |  *****  |
 |  *   *  |
 |  *   *  |
 |         |

DECIMAL

CR  0 EMIT
CR  1 EMIT
CR 65 EMIT
\ Remove shape compiler from the system when you are done with it.
\ FORGET TASK

 

 

  • Like 2

Share this post


Link to post
Share on other sites

Obsessed with SAMS

 

I have managed to take out 4 more bytes per definition. Two in SAMS memory and two in the forth Dictionary entry. 

I removed the GOTO SAVEHERE line and replaced it with FARSEMIS.

This is a run-time exit from a SAMS definition so it can go in SAMS memory at the end of a definition.

The caller's IP address is pulled from the return stack so that's that.

 

Changing the dictionary pointer is a compile time complication so that is handled by ;FAR when we compile a new SAMS word.

 

My ultimate goal here is to get the entire FAR: definition living in SAMS memory and then modify FIND to search through SAMS banks first in declining order before searching Forth.  This will make FAR: definitions look similar to ANS Forth wordlists but we can have a lot more of these SAMS lists than wordlists. I only have room for 9 in the kernel.

 

Spoiler
\ Code in SAMS memory based on concept in TurboForth by Mark Wills
\ Ported to Camel99 Forth  Oct 13, 2021

\ Changes from original:
\ Remove bank stack.  Used return stack for bank# storage
\ Removed BANKS word. Changed to preset DP array
\ CMAP is a fast sub-routine for mapping SAMS pages F0..FF
\      CMAP Remembers the last bank that was paged in variable LASTBNK
\ Changed to compile a far "colon" definition to reduce dictionary overhead

\ Oct 7, 2021:  Compares input to CMAP to LAstbnk and
\               does nothing if page is still in memory
\ Oct 13, 2021  Remove GOTO in FAR exit. Not needed.
\               Compile FARSEMIS on the SAMS side, not in RAM Dictionary
\               Saves 2 bytes in dictionary and in 2 bytes SAMS definition

\ FAR word data structure:
\   CELL: link
\   BYTE: immediate field
\   BYTE: name length
\   BYTES: <....>
\   CELL:  code field
\   CELL:  DATA field #1 , bank#
\   CELL:  DATA field #2 , SAMS code field address
\ 10 bytes + name length

INCLUDE DSK1.MARKER
INCLUDE DSK1.ASM9900

HERE
F0 CONSTANT _1STBANK
FF CONSTANT _MAXBANK

\ SAMS memory management for code
HEX              3000 CONSTANT CSEG      \ code seg in CPU RAM
4000 CSEG 0B RSHIFT + CONSTANT CREG      \ compute CSEG SAMS register
CSEG 0C RSHIFT        CONSTANT PASSTHRU  \ default page for CSEG

DECIMAL
CREATE []DP  \ DP for 0 .. 15 pages of SAMS
  CSEG , CSEG , CSEG , CSEG  ,
  CSEG , CSEG , CSEG , CSEG  ,
  CSEG , CSEG , CSEG , CSEG  ,
  CSEG , CSEG , CSEG , CSEG  ,

HEX
CODE ]DP ( bank# -- addr )
     TOS _1STBANK NEGATE  AI,  \ remove first bank offset to index []DP
     TOS TOS ADD,
     TOS []DP AI,
     NEXT,
ENDCODE

 VARIABLE  SAVHERE   \ temp holder for RAM Dictionary pointer
 VARIABLE  BANK#     \ active SAMS bank# for compiling
 VARIABLE  LASTBNK   \ last bank# passed to MAPPER

CODE BANK#@   ( -- bank#)  \ Used 8 times so this saves space and is fast
      TOS PUSH,
      BANK# @@ TOS MOV,
      NEXT,
ENDCODE

HEX
CREATE MAPPER ( R1: 0 .. 16 )  \ smart MAPPER
      R1 LASTBNK @@ CMP,  \ already mapped?
      NE IF,
         R1 LASTBNK @@ MOV,  \ update the last bank used
         R1 SWPB,          \ swap bytes
         R12 1E00 LI,      \ DO CMAP
         0 SBO,            \ turn on the card
         R1 CREG @@ MOV,   \ restore bank# from return stack
         0 SBZ,            \ turn off card
      ENDIF,
      RT,

CODE CMAP  ( bank# --) \ Forth word to map SAMS pages
      TOS R1 MOV,
      MAPPER @@ BL,
      TOS POP,
      NEXT,
      ENDCODE


CREATE FARCOL   \ run time executor for SAMS colon words.
     IP RPUSH,
     W IP MOV,
     RP DECT,
     LASTBNK @@ *RP MOV,  \ Rpush the active bank
     *IP+ R1 MOV,         \ fetch bank# from DATA FIELD -> R1, inc IP
     MAPPER @@ BL,        \ & switch to SAMS page for this word
     *IP IP MOV,          \ get SAMS DP & set new IP
     NEXT,

: FAR: ( -- ) \ special colon for words in FAR memory
     !CSP
     HEADER               \ compile Forth header with name
     FARCOL ,             \ compile the new executor as CFA
     BANK#@ ,             \ compile bank# as the DATA field
     BANK#@ ]DP @ ,       \ compile this word's SAMS address ( ie: FAR XT)

     HERE SAVHERE !       \ save "normal here"
     BANK#@ ]DP @ DP !    \ set dp to CSEG. Compiling goes here now
     BANK#@ CMAP          \ map SAMS for compiling
     HIDE
     ]                    \ turn on the compiler
;

HEX
CODE FAREXIT
     R1 RPOP,            \ get bank# save by FARCOL
     MAPPER @@ BL,       \ map it in
     IP RPOP,            \ Regular FORTH EXIT
     NEXT,
ENDCODE

: FARSEMIS ( -- )
      POSTPONE FAREXIT
      POSTPONE [        \ turn compiler off
      REVEAL ?CSP ; IMMEDIATE

: ;FAR ( -- ) \ end banked compilation
      POSTPONE FARSEMIS           \ compile ending in SAMS part of definition
      HERE  BANK#@ ]DP !          \ update here for this bank
      SAVHERE @ DP !              \ restore dp to CPU RAM
; IMMEDIATE

DECIMAL
: SETBANK ( bank# -- ) \  0..15 are valid args
      DUP 256 240 WITHIN ABORT" Bad bank number"
      BANK# !
;

HEX
: _BFREE    ( -- n) 4000  BANK#@ ]DP @ - ;
: .BFREE ( -- ) DECIMAL
    CR ." Bank# " BANK#@  . ." , "  _BFREE  .  ." bytes free." CR ;

HERE SWAP -
DECIMAL CR . .( bytes)  \ free 11,566

PASSTHRU CMAP  \ init the Forth memory bank# as LASTBNK
\ REMOVE-TOOLS
HEX
F0 SETBANK

 

 

I have also moved my INCLUDE line buffer into high RAM. I was using PAD but when INCLUDEing into a SAMS block PAD is in the SAMS memory and so it prevents using the last 127 bytes of the SAMS bank.

 

The other thing that is interesting is how compact headless Forth code is. 

All these files compiled into 4K with 380 bytes to spare. Of course there was another 1800 bytes of header code over in CPU RAM.

(I need to make a way to leverage this idea to create headless programs that can be saved as EA5 images.) 

DECIMAL 240 SETBANK
HEX
INCLUDE DSK1.ELAPSE
INCLUDE DSK1.UDOTR
INCLUDE DSK1.ANSFILES
INCLUDE DSK1.CATALOG
INCLUDE DSK1.DIR
INCLUDE DSK1.MORE
INCLUDE DSK1.BUFFER
INCLUDE DSK1.COMPARE
INCLUDE DSK1.CASE
INCLUDE DSK1.VALUES
INCLUDE DSK1.TRAILING
INCLUDE DSK1.SYNONYM
INCLUDE DSK1.3RD4TH
INCLUDE DSK1.MALLOC
INCLUDE DSK1.VDPMEM
INCLUDE DSK1.FASTCASE
INCLUDE DSK1.ASMLABELS
INCLUDE DSK1.GRAFIX
INCLUDE DSK1.DIRSPRIT
INCLUDE DSK1.COOLSPRITE

 

 

  • Like 4

Share this post


Link to post
Share on other sites

Sometimes maintenance is worthwhile.

 

I had hacked together a version of -TRAILING like this. (-TRAILING removes trailing spaces from a string)

CODE -TRAILING ( addr len -- addr len') 
     *SP  W  MOV,   \ DUP addr in W
      TOS W  ADD,   \ add len
      R1 2000 LI,   \ R1 holds the space character
      W DEC,        \ w=address of last char
      BEGIN,
        *W R1 CMPB, \ compare to ascii >20
      EQ WHILE,
         W   DEC,   \ move back 1 char
         TOS DEC,   \ dec len in TOS
      REPEAT,
      TOS 0 CI,
      1 JGT,
      TOS CLR,
  NEXT,
  ENDCODE
 

Looking at it I didn't like having two DEC instructions inside the loop and I really didn't like the negative length test at the end.

 

This is about 13% faster. It seems to test solidly.

HEX
CODE -TRAILING ( addr len -- addr len')
     *SP TOS  ADD,     \ add len
         TOS  DEC,
      R1 2000 LI,      \ R1 holds the space character
      BEGIN,
        *TOS R1 CMPB,  \ compare to ascii >20
      EQ WHILE,
            TOS DEC,   \ move back 1 char
      REPEAT,
    *SP TOS SUB,
        TOS INC,
   NEXT,
ENDCODE

 

  • Like 4

Share this post


Link to post
Share on other sites

"It takes nine months to have a baby no matter how many women you put on the job."  (Fred Brookes, The Mythical Man Month)

 

Well actually my newest granddaughter arrived in 8 months plus one week, about 2 weeks ago and she is really cute.

 

Unlike little baby Ivory, my documentation for the linker took longer than it should but here it is.

 

I included @FarmerPotato 's disk with some additions of my own to aid in the getting used to this beasty.

I have been testing on an unreleased version of Camel99 (2.68F)  but it should work on the latest released version.

 

Maybe it is of some use to someone out there.  :) 

Erik I believe your original question was because you have some bit map graphics code that you want to run under Forth.

If you want to post it here I can take a run at making it work (if it assembles with the standard TI Assembler) 

 

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