Jump to content
Sign in to follow this  
GDMike

Turboforth and TSR ability

Recommended Posts

I'm looking to see if it's possible to create a TSR program for the sAMS card especially. To start off with, let's say a clock- it's only a TSR but that is fine. So how would I go about writing a piece of code that would allow a hot key to access it activate it but not allow me to lose Turboforth functionality? If that makes any sense.

Share this post


Link to post
Share on other sites

Have not used TSR in a sentence for quite some time. :-)

 

So having a TSR in SAMS memory that is available to start from Turbo Forth and then return to Turbo Forth is not too hard.

You could move the dictionary pointer to a SAMS block and compile some Forth program into that memory.

(I call the variable DP but check TurboForth docs for Willy's name.) EDIT: It's called 'H'

 

Then restore the dictionary pointer back to where it was before. You now have a TSR compiled in the SAMS space.

 

To make it run you would need to know it's "code field address". (CFA) Best to make note of that just after you compile the TSR into SAMS.

The word that you make to start the TSR code needs to be sure and turn on the correct SAMS PAGE with >MAP in TurboForth.

Then it would pass the CFA to the word EXECUTE and it should run.

 

I am making this up since I have not tried but this "theory" should get you started.

I would try putting a program into a block of free Expansion ram first to test the concept.

 

The program could be:

: MYTSR   CR ." THE TSR WORKED"  
          CR ." Press a key to exit" KEY DROP ;

' MYTSR CONSTANT TSRENTRY  (need to remember where to find the entry later)

If you want your TSR to be computing the time in the background that's a different matter.

That will need someway to regularly read a timer somewhere. You could put a timer on the ISR like this but remember this is CAMEL99 ANS style Forth. Then your "clock program would read the X variable as the source of time and print it the way you want to format it.

 

You will need to dust of the Turboforth Docs to get some of the words correct for TF for the ISR handler. I think TurboForth will let you write the ISR handler in Forth as well.

 

Ask questions and experiment. Crashing the machine is your right as a low level coder. :-)

VARIABLE X
CODE COUNTER ( -- ) \ example ISR
     X @@ INC,
     RT,
     ENDCODE

: ?CODE ( cfa -- ) DUP @ 2- - ABORT" Not code word" ;

\ API LAYER
: ISR'  ( -- code-address)
        BL WORD  FIND  0= ABORT" ISR not found"
        DUP ?CODE >BODY ;

: INSTALL   83C4 ! ;   \ Usage: ISR' COUNTER  INSTALL
Edited by TheBF

Share this post


Link to post
Share on other sites

You can write a set of words that initialize the SAMS card and load the needed code into one or more of its pages given that TF allows for inline assembly code. These words would be saved on the main BLOCKS disk and can be made to load automatically when TF starts. The SAMS pages reference certain memory blocks in the standard 32K memory expansion area divided into high (24k) and low (8k) memory sections and you should be able to access the "TSR" code directly from TF subsequently.

At least that's how I would envision this. However, there are high-level Forth gurus on this board who I'm sure will be chiming in shortly. And of course the ultimate word would rest with Willsy, the author of TF :)

  • Like 1

Share this post


Link to post
Share on other sites

I'm looking to see if it's possible to create a TSR program for the sAMS card especially. To start off with, let's say a clock- it's only a TSR but that is fine. So how would I go about writing a piece of code that would allow a hot key to access it activate it but not allow me to lose Turboforth functionality? If that makes any sense.

 

LOL. Now that I think about it ALL of Forth is a bunch of TSR programs.

 

If you do this:

: HI   CR ." HELLO WORLD!" ;

The program HI is in memory and can be started anytime by typing HI.

 

So if typing a short name and hitting enter is enough you have it.

If you want a hot key, you may have to patch into the KEY routine to do that or write your own KEY handler and patch your new KEY into the dictionary where the OLD KEY is. You can do that quite simply in TurboForth.

Share this post


Link to post
Share on other sites

I'm looking to see if it's possible to create a TSR program for the sAMS card especially. To start off with, let's say a clock- it's only a TSR but that is fine. So how would I go about writing a piece of code that would allow a hot key to access it activate it but not allow me to lose Turboforth functionality? If that makes any sense.

 

So this code works as expected.

 

Paste it into TF and try it. If you wanted to disable the TSR just re-enter the line ' BADTSR TSRENTRY !

This sets the TSR to an error message program.

 

Again ask any questions you need answered.

\ Create & RUN a "TSR" in a different RAM space with Turbo Forth

VARIABLE TSRENTRY
: BADTSR  TRUE ABORT" NO TSR ASSIGNED" ;

' BADTSR TSRENTRY !

\ fetch the address and run it
: RUNTSR    TSRENTRY @ EXECUTE ;

HERE      \ remember the dictionary position on the stack

HEX 3000 H !  \ move the FORTH dictionary to low RAM >3000

\ compile our TSR code. It will start at >3000 (could be a SAMS block)
: MYTSR
    CR ." TSR RUNS!"
    CR ." Press a key to exit:" KEY DROP  ;

' MYTSR  TSRENTRY !   \ GET the execution token & save it in a VARIABLE

H !     \ restore the dictionary back to "HERE" we left on the stack
DECIMAL

\ type RUNTSR to run the TSR :-)

Share this post


Link to post
Share on other sites

I've got to take time out to "compile" and decompress what all was mentioned. I love the statement, "LOL. Now that I think about it ALL of Forth is a bunch of TSR programs".

Because after i asked my question here, I thought the same thing!! and the fact that forth is word driven not "hot key" driven.

Oh, and getting the timer is easy, there's the system clock that's updated every 1/60th for screen blank out. But that wasn't what I was searching for. But I think you nailed most if it, I forgot all about moving the dictionary!! Thanks for this I'm sure I can put it to use.

  • Like 1

Share this post


Link to post
Share on other sites

@Willsy will likely have a more elegant and useful answer for you, but in order to intercept a hot key in TurboForth, you would need to write a user ISR that looks for said key and install its entry point address in >A008 (the memory location [normally 0] monitored by TurboForth’s ISR for just such a hook. Without some preparation that will make your head hurt to accommodate it, you will not be able to run high-level Forth code in your ISR/TSR. It will, instead, need to be written in Assembler because the user ISR hook must be the address of an executable TMS9900 instruction and the routine must return with “B *R11”. This is made much simpler with TurboForth’s structured Assembler (see @Willsy’s website, turboforth.net, for details), though you do need to be able to navigate TMS9900 Assembler Code (ALC) to write the routine.

 

You should also write your TSR as an ISR to be installed by your hot-key routine.

 

Given that you know how to write some ALC, you might proceed as follows:

\ Values used to install MYISR and MYTSR as ISRs:
0 VALUE MYTSR_ADR
0 VALUE MYISR_ADR

\ User TSR (which is also an ISR) to be triggered with hot key.
\ This TSR will never be executed as a normal Forth word.  It is
\ intended to be entered at the code pointed to by its CFA.
ASM: MYTSR  ( -- )
   R1 CLR,           \ first executable ALC pointed to by CFA
      \ do more relevant ALC stuff
   R11 ** B,           \ return to TurboForth ISR
;ASM

\ User ISR to watch for hot key, which should be a key not normally
\ used, say CTRL+9 (>1F).  As with MYTSR above, MYISR is never intended
\ to be executed by the Forth interpreter.
ASM: MYISR  ( -- )
   R1 CLR,                 \ zero R1
   $8375 @@ R1 MOVB,       \ move last char typed to hi byte of R1
   R1 $1F00 CI,            \ check for hot key
   EQ IF,                  \ hot key?
      $A008 @@ MYTSR_ADR LI,  \ yes..move contents of MYTSR's CFA to usrisr
   ENDIF,
   R11 ** B,                 \ return to TurboForth ISR
;ASM

\ Update ISR/TSR hooks to real addresses
' MYTSR @ TO MYTSR_ADR     \ store MYTSR entry address
' MYISR @ TO MYISR_ADR     \ store MYISR entry address

\ To install MYISR, type the following Forth code:
MYISR_ADR $A008 !       \ store contents of MYISR's CFA in usrisr

You obviously must keep a TSR like the one above as short as possible to avoid missing interrupts because it is, after all, an ISR.

 

If you want to use SAMS memory for the TSR, you will need to do a bit more work to manage the SAMS bank switching. There is a very nice SAMS library on @Willsy’s website to do this for you with Forth words. To use it, however, we would need to figure out how to enter Forth from ALC and return to ALC from Forth without polluting the return stack. I have done it in fbForth 2.0, but I would have to think on it a bit to manage it in TurboForth.

 

...lee

  • Like 1

Share this post


Link to post
Share on other sites

Even I don't know how to call a Forth word (in TF) from an assembler word. I've looked at it a couple of times and it makes my hed hurt!

 

If you guys ever fathom, could you let me now :-D

Share this post


Link to post
Share on other sites

@Willsy will likely have a more elegant and useful answer for you, but in order to intercept a hot key in TurboForth, you would need to write a user ISR that looks for said key and install its entry point address in >A008 (the memory location [normally 0] monitored by TurboForth’s ISR for just such a hook. Without some preparation that will make your head hurt to accommodate it, you will not be able to run high-level Forth code in your ISR/TSR. It will, instead, need to be written in Assembler because the user ISR hook must be the address of an executable TMS9900 instruction and the routine must return with “B *R11”. This is made much simpler with TurboForth’s structured Assembler (see @Willsy’s website, turboforth.net, for details), though you do need to be able to navigate TMS9900 Assembler Code (ALC) to write the routine.

 

You should also write your TSR as an ISR to be installed by your hot-key routine.

 

Given that you know how to write some ALC, you might proceed as follows:

\ Values used to install MYISR and MYTSR as ISRs:
0 VALUE MYTSR_ADR
0 VALUE MYISR_ADR

\ User TSR (which is also an ISR) to be triggered with hot key.
\ This TSR will never be executed as a normal Forth word.  It is
\ intended to be entered at the code pointed to by its CFA.
ASM: MYTSR  ( -- )
   R1 CLR,           \ first executable ALC pointed to by CFA
      \ do more relevant ALC stuff
   R11 ** B,           \ return to TurboForth ISR
;ASM

\ User ISR to watch for hot key, which should be a key not normally
\ used, say CTRL+9 (>1F).  As with MYTSR above, MYISR is never intended
\ to be executed by the Forth interpreter.
ASM: MYISR  ( -- )
   R1 CLR,                 \ zero R1
   $8375 @@ R1 MOVB,       \ move last char typed to hi byte of R1
   R1 $1F00 CI,            \ check for hot key
   EQ IF,                  \ hot key?
      $A008 @@ MYTSR_ADR LI,  \ yes..move contents of MYTSR's CFA to usrisr
   ENDIF,
   R11 ** B,                 \ return to TurboForth ISR
;ASM

\ Update ISR/TSR hooks to real addresses
' MYTSR @ TO MYTSR_ADR     \ store MYTSR entry address
' MYISR @ TO MYISR_ADR     \ store MYISR entry address

\ To install MYISR, type the following Forth code:
MYISR_ADR $A008 !       \ store contents of MYISR's CFA in usrisr

You obviously must keep a TSR like the one above as short as possible to avoid missing interrupts because it is, after all, an ISR.

 

If you want to use SAMS memory for the TSR, you will need to do a bit more work to manage the SAMS bank switching. There is a very nice SAMS library on @Willsy’s website to do this for you with Forth words. To use it, however, we would need to figure out how to enter Forth from ALC and return to ALC from Forth without polluting the return stack. I have done it in fbForth 2.0, but I would have to think on it a bit to manage it in TurboForth.

 

...lee

 

I just got off of someone's website that was talking about XOP's on the TI-99/4A. In this case, it was indeed for the TI-99/4A and not the Geneve 9640.

 

I don't know Forth at all, but if there was someway to call an XOP to branch to some of your own code, couldn't you then have your own workspace and SAMS memory mapping code? The 4A has a number of limitations since the vectors are in ROM and not RAM, but I thought the website I was reading suggested there were some opportunities for their use on the TI-99/4A.

 

Second option, it's been many years ago, but there was a Load/Reset button users used to do screen printing. The hook as I recall was at >FFFC and >FFFE. That would allow you to bounce out of your program and I believe a simple RTWP would allow you to return as well. Maybe something like this could be even easier to implement........

 

Beery

Share this post


Link to post
Share on other sites

Yes but you need to access vdp regularly to allow the interrupts to fire. Interrupts in TF were an after thought.

 

Most video related commands, and things like JOYST do that for you.

 

For example if you ran this program, interrupts wouldn't work:

 

: test begin again ;

 

But this would work:

 

: test begin 0 [email protected] drop again ;

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.

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...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...