6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon Apr 29, 2024 2:43 pm

All times are UTC




Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Mon Jan 30, 2017 6:53 am 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
One of the cool features that Gforth offers is the ability to "vectorize" EMIT, TYPE and KEY. Slightly simplified, EMIT is actually a "default" routine (EMIT), which at start up is linked to EMIT as DEFER EMIT followed by (EMIT) IS EMIT. This allows the user to redirect the output.

However, since none of this is in ANSI, there are some questions. If I redirect EMIT, should TYPE automatically be redirected as well? What about error messages and other output?

Currently, I'm favoring the idea of making EMIT and TYPE separate so the user has the flexibility to keep them separate, especially because it isn't to hard to redirect both. Harder is if I want to make error output vectorizable, because on the one hand it is nice to have a central "console", on the other hand it doesn't seem to make much sense to move everything to (say) another terminal and not show the user there the output.

Does anybody have experience with these questions? Any recommendations?

EDIT: Forgot to add the link to Gforth's take on this: https://www.complang.tuwien.ac.at/forth ... ction.html Note that it calls this "Redirection" and offers two levels: One via a file (and Liara Forth doesn't have files), and one via DEFER. Both EMIT and TYPE need to be redirected separately.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 30, 2017 8:57 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
What I did 25 years ago (and have been using although I might do it differently in the future) is to have emit and type (the internals used by EMIT and TYPE) do OUTDEV @ (to look up what the current output device is), then have a CASE structure. The options for variable OUTDEV to hold are CONDEV# (console (ie, LCD) device number constant), LPTDEV# (the parallel-port line printer device number constant), or 232DEV# (the main RS-232 device number constant); and anything else defaults to getting the address of the appropriate driver from variable AUXemit which you can change at any time for special things you might use. The word pointed to by AUXemit could also further break it down, like if you had several things on the same I²C port. Any of these could do their own error reporting; for example that the printer was out of paper or not online.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 30, 2017 4:02 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1927
Location: Sacramento, CA, USA
Having a separate error channel for diagnostics would make sense, but EMIT and TYPE should probably follow each other rather closely, due to the fact that the Forths I've disassembled so far all call EMIT from within TYPE. I haven't delved too deeply into KEY and friends yet.

Mike B.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 30, 2017 7:13 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
Depending on how the vectoring is done, would determine what you would need to do.

For example, the way DEFER works in F83 (and I have no reason to suspect that it's unique in this regard) is something like this:
Code:
    DEFER TEST
    : T1 ." T1" ;
    : T2 ." T2" ;
    : T TEST ;
    ' T1 IS TEST
    T <prints> T1 ok
    ' T2 IS TEST
    T <prints> T2 ok

So, if TYPE is implemented using EMIT, and EMIT is vectored (or DEFERed), then TYPE does not need to change, only EMIT.

So you could do something like:
Code:
    ' ERROR-EMIT IS EMIT
    TYPE …. goes to error channel
    ' ORIG-EMIT IS EMIT
    TYPE … original emit


Top
 Profile  
Reply with quote  
PostPosted: Wed Feb 01, 2017 11:55 am 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
GARTHWILSON wrote:
The options for variable OUTDEV to hold are CONDEV# (console (ie, LCD) device number constant), LPTDEV# (the parallel-port line printer device number constant), or 232DEV# (the main RS-232 device number constant); and anything else defaults to getting the address of the appropriate driver from variable AUXemit which you can change at any time for special things you might use.
Very interesting, thanks -- ANSI has SOURCE-ID to tell you where stuff is coming from, maybe something OUTDEV could be realized as DESTINATION-ID and decided were stuff goes to. Will go off and stare are my code for a while ...


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 17, 2018 10:13 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 855
EMIT, TYPE, and EXPECT are defered on my system for the C64 . I have three words for redirecting output:
CONSOLE directs output from EMIT and TYPE to the video screen.
PRINTER directs output from EMIT and TYPE to the printer.
LOGGER directs output from EMIT and TYPE to the video screen and the printer. EXPECT is vectored so that in addition to doing its usual job it also sends a copy of what is expected to the printer.
This is really handy to make a log of an interactive session at the computer.
BTW since I am using VICE, I don't have a printer set up. The simulator sends all printed text to a print.dump file.


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 28, 2020 1:12 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 855

Fleet Forth's TYPE is no longer a deferred word. It is now a high level word that uses EMIT .
Code:
: TYPE  ( ADR CNT -- )
   0
   ?DO
      COUNT EMIT
   LOOP
   DROP PAUSE ;

Note: PAUSE is the task switcher.


Top
 Profile  
Reply with quote  
PostPosted: Sun Nov 29, 2020 12:19 am 
Offline

Joined: Mon Jun 24, 2019 1:13 pm
Posts: 34
My very first embedded Forth was on the R6511AQ chip where I bought and cloned the RSC-Forth ROMs and modified the machine code by hand. I think I could still read R6502 machine code to this day :)
RSC-Forth was based on Fig Forth but used vectors for (EMIT) and (KEY) and also (KEY?) IIRC. I used this extensively in my POS terminal designs where output would be redirected to displays and printers and even video. When I eventually created my own fresh source years later it was for the 65C816 (and then for the 65C02 for a volume product). Because I was used to using vectors and they were so useful, I used the same technique in my Forth. One thing I did was standardize the character coding so that for example a "clear screen" character would work the same across all output devices. I later enhanced this Forth to work with the M37702 which was a super-set of the 65C816, and used this MCU in many products for many years.

Nowadays I mainly work with the Parallax Propeller chip, especially the new P2 and this technique has been carried through from all my embedded products. I find though that some of the complicated command channel stuff I did by sending data to the (KEY) vector (one of which was to actually read input) etc is no longer necessary. I just have (EMIT) and (KEY) but KEY always returns a null if there is no input, and if it a raw binary device that could send a 00 then I simply OR it with $100. So KEY is non-blocking and instant, it is never trying to wait for input.

With (EMIT) it is always a blocking emit because I find that no matter how much buffering I might have, it is easy to fill that buffer so most of my output stuff is no buffered and way more efficient, especially if I use high baud rate for serial etc.

So the main takeaway is that there is no KEY? word, just KEY, and if it returns a zero then there is no input. However, KEY and especially EMIT are normally two good places for PAUSE because most I/O is inherently slow.

So, one day I will like to revisit the 65C02/65C816 and write a brand new Forth that embodies many of the techniques and things I have learned over the years.

BTW, there is no PAUSE in my multi-core Tachyon Forth on the Parallax P1 and P2 simply because each task can have its own CPU.


Top
 Profile  
Reply with quote  
PostPosted: Sun Nov 29, 2020 9:55 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 855

Since Fleet Forth is for the Commodore 64, I'm limited to a single CPU core.
Fleet Forth's word (?KEY) is the vector for the deferred word ?KEY . It is not the same as the Ansi Forth word KEY? . ?KEY returns a zero if there is no character ready, otherwise it returns a character (sounds like your KEY ) because the C64 routine GETIN ( $FFE4 ) works that way.
KEY is defined as:
Code:
: KEY  ( -- B )
   BEGIN
      PAUSE ?KEY ?DUP
   UNTIL ;

I have found having both a nonblocking ?KEY and a blocking KEY to be useful.
Code:
: DONE?  ( -- F )
   ?KEY DUP 0EXIT
   3 = ?DUP ?EXIT
   KEY 3 = ;

Fleet Forth's EXPECT is a deferred word vectored to (EXPECT) . (EXPECT) does not use ?KEY or KEY , it is a code word that uses the C64's screen editor because it is so handy.
EXPECT is the Forth-83 word similar to Ansi Forth's ACCEPT. ACCEPT returns the count on the stack of actual characters received, EXPECT returns that count in a variable named SPAN .


Top
 Profile  
Reply with quote  
PostPosted: Sun Nov 29, 2020 10:48 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
?TERMINAL is the word for just seeing if there is a key available, then KEY is to pick it up. I have mine set up slightly differently since the workbench computer's only full "keyboard" is the RS-232 port that brings the source code (including commands that might not be for compilation) in from the host computer (which has a professional programmers' text editor, big monitor, and hard discs), and I have words for the 5-key onboard keypad for which I put a "p" (for "pad") in front, like pKEY and p?TERMINAL. I also have WHICHKEY which outputs a cell with a bit clear for whatever key is being pressed, or FFFF if no key is being pressed, and I have ASKY/N which waits until either the YES/Continue/Enter key or the NO/Cancel/Exit key is pressed, and puts a true flag on the stack for YES or a false flag for NO. pKEY uses the time-before-repeat and the time-between-repetitions variables for repetition which is particularly useful for the up-arrow and down-arrow keys. It watches the RTC so the delays are not dependent on other things happening at the same time; IOW, it's not a delay loop which would keep the computer from doing other things while waiting, but instead pKEY ends every time so you can process the key before coming back for it to give you the next repetition at the right time.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 03, 2020 12:32 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 855

This sounds like the Ansi Forth word KEY? .
Fleet Forth does not have the word ?TERMINAL . Blazin' Forth does have the word ?TERMINAL , but it only checks if the STOP key was pressed and that's it.
I could support the behaviour of KEY? or ?TERMINAL , but I choose not to. Since the Forth-83 Standard doesn't specify the words ?TERMINAL , ?KEY or KEY? this allows me to have a Forth kernel that, in this instance, works with what Commodore 64 Kernal makes available without excess code and without further deviation from the Forth-83 Standard.
I've already deviated from the standard concerning which variables should be user variables.
If I need to, I will deviate from the standard further, but I really would like to keep that sort of thing to a minimum.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: