BBC BASIC for Windows
General >> General Board >> BB4W FORTH Thoughts...
http://bb4w.conforums.com/index.cgi?board=general&action=display&num=1252189423

BB4W FORTH Thoughts...
Post by afarlie on Sep 5th, 2009, 10:23pm

i) Technical enquiry:

Jones Forth has no ROLL word.

I.E <n> ROLL would take the n'th item below the current top of stack and move it to the top of the stack.

I was looking into how to do some graphics commands,
and found that to do one of the VDU commands related
to setting up BBC style viewports, I wanted to be able to find an item more than 3 down on the FORTH stack.

IIRC some FORTH's Implemented ROLL and PICK words for
dealing with 'arbitarily' deep stack items.

I'll have another read of what some of the basic FORTH words
are supposed to do, to see if this is possible.

ii)
Forth source code for some basic graphics operations follow
on which comments are welcomed..

/ I am doing <x> <y> <word> because it makes for code
that maybe easier to understand :)

/ The ultimate goal might be to implement some kind of
/display list building capability, although I'm not entirly
/sure how that might be done...

:ORIGIN / call as <x> <y> ORIGIN
29 EMIT
SWAP
DUP 256 MOD EMIT 256 \ EMIT
DUP 256 MOD EMIT 256 \ EMIT

:PLOT / call as <x> <y> PLOT
25 EMIT
69 EMIT
SWAP
DUP 256 MOD EMIT 256 \ EMIT
DUP 256 MOD EMIT 256 \ EMIT
;

:DRAW / call as <x><y> DRAW
25 EMIT
5 EMIT
SWAP
DUP 256 MOD EMIT 256 \ EMIT
DUP 256 MOD EMIT 256 \ EMIT
;

:MOVE / call as <X> <Y> MOVE
25 EMIT
4 EMIT
SWAP
DUP 256 MOD EMIT 256 \ EMIT
DUP 256 MOD EMIT 256 \ EMIT
;

;FILL / (<x> <y> FILL)
25 EMIT
133 EMIT
SWAP
DUP 256 MOD EMIT 256 \ EMIT
DUP 256 MOD EMIT 256 \ EMIT
;


;FILL_BY / (<x> <y> FILL_BY)
25 EMIT
129 EMIT
SWAP
DUP 256 MOD EMIT 256 \ EMIT
DUP 256 MOD EMIT 256 \ EMIT
;

:GCOL <color> GCOL
18 EMIT
0 EMIT
EMIT
;

iii) Internal sounds - There are almost certainly emulations of sound chips on the net. There is NOT yet as far as I know an
emulation of the Hybrid 5000 though...

On a BBC Micro - I think setting up a sound was OSWORD 7?
(which BB4W AFIAK doesn't directly expose to the user).

The other thing that would be needed for a 'music' FORTH is
some kind of timer routine, for which I probably need to go and look at some of the existing BB4W examples such as TIMERLIB which would callback to a specfic word. Hmm...


iv) A SYS call... I'm not sure if an explicity SYS word is needed.

As surely you just put a function address on the FORTH stack
and do something like EXECUTE (which will jump to the appropriate address?)

If so and it's 'stdcall' (most API calls are) the params would need to be on the FORTH stack below the relevant address to call,
something that could be done easily in a FORTH system.

The problem of calling API functions then becomes a case of
how to do "LoadLibrary" and "GetProcedureAddress" in a FORTH
safe way...

My train of thought here is that you would get an address for a procedure and a 'compile' a word which puts an appropriate address on the Forth stacks and EXECUTES it.

I was thinking of something like the following...

"EXTERNAL.DLL" LOADLIB TO ExternalLib

which would create a WORD ExternalLib which would put
an appropriate pointer on the stack.

ExternalLib "ApiFunc" EXTERNAL Api_Func

Which would create a word called Api_Func which called
the function Api_Func in the external Library.

The word EXTERNAL could add any generic sanity checking needed.


v) 'Environment' Variables :
Assuming it's possible to have EXTERNAL words..
Things like HWND and the device context could be obtained directly. That said, to me it makes far more sense to use the BB4W environment.

I assume that by knowing appropriate addresses the VDU variables could be accessed within the FORTH system..
(This would be useful so that current positions could be preserved
inside a CIRCLE word for example.)

Thanks for reading this far, I hope I am asking the right questions
as well...
























Re: BB4W FORTH Thoughts...
Post by John F on Sep 6th, 2009, 07:52am

-PICK exists in JonesForth. eg try '1 2 3 4 5 6 7 4 PICK .' and it does what you describe the missing 'ROLL' word doing.

I was fazed by missing the 'DO ... LOOP' structure and don't even know how I'd open a view port!!

You are clearly getting stuck well in here & I'll follow with interest.
I have the old Acornsoft Forth (Grandis-Harrison) manual from 1983- I may scan the 'Graphics' chapter if you or Richard are interested in what it implemented. It sounds as if you are already beyond this....
Re: BB4W FORTH Thoughts...
Post by John F on Sep 6th, 2009, 07:59am

Sorry. Just realised it copies rather than moves. Ooops!!
Re: BB4W FORTH Thoughts...
Post by admin on Sep 6th, 2009, 09:35am

Quote:
Jones Forth has no ROLL word

Can this be implemented in Forth? If so you obviously have your solution, but if not it will require an assembler primitive to be added. I would be happy to do that.

The next version I release will have the necessary primitive for DOES> to be implemented.

Quote:
Forth source code for some basic graphics operations follow on which comments are welcomed..

They're very much the kind of thing I had in mind, although the repeated use of DUP 256 MOD EMIT 256 / EMIT doesn't seem very 'Forth-like' to me: wouldn't it be better to define a word (e.g. EMIT16) to do it (and indeed another word to output two 16-bit values)?

Quote:
A SYS call... I'm not sure if an explicity SYS word is needed.

It may be that you don't need a specific SYS word, but I'm not sure how you'd get the 'return value' from an API function onto the stack without one.

My thinking about API access was similar to yours, but I'd envisaged just a single word, e.g. SYSADDR, which would be used as follows:

Code:
S" GetTickCount" S" kernel32" SYSADDR 


In practical terms you'd put the address in a 'constant':

Code:
S" GetTickCount" S" kernel32" SYSADDR CONSTANT GetTickCount 


Richard.
Re: BB4W FORTH Thoughts...
Post by admin on Sep 6th, 2009, 10:13am

Quote:
I was fazed by missing the 'DO ... LOOP' structure

Again, the obvious question is "can this be implemented in Forth"? AIUI JonesForth actually implements rather more words as assembler primitives than some other Forths (probably done for speed).

If DO ... LOOP cannot be implemented in Forth then I'd ideally like to see another assembler implementation; I'm not sure that my primitive knowledge of Forth is good enough to write the code from scratch.

Richard.
Re: BB4W FORTH Thoughts...
Post by Malcolm on Sep 6th, 2009, 5:31pm

Be aware of this from a Forth blog:

Quote:
ROT reversed?

Am I crazy, or is ROT/-ROT swapped compared to the standard (as in Starting Forth)?
By kotlinski at Thu, 2009-01-15 10:38 | login or register to post comments
No

No you're not crazy. I did get them backwards.
By Richard W.M. Jones at Fri, 2009-08-14 15:02


regards, Malcolm.
Re: BB4W FORTH Thoughts...
Post by afarlie on Sep 6th, 2009, 5:44pm

on Sep 6th, 2009, 09:35am, Richard Russell wrote:
Can this be implemented in Forth? If so you obviously have your solution, but if not it will require an assembler primitive to be added. I would be happy to do that.


ROLL does the following IIRC... -

7 6 5 4 3 2 1 6 ROLL

Would leave the stack as :
6 5 4 3 2 1 7

I'm not sure how to do this in pure FORTH.


Quote:
The next version I release will have the necessary primitive for DOES> to be implemented.


And BUILDS?


Quote:
They're very much the kind of thing I had in mind, although the repeated use of DUP 256 MOD EMIT 256 / EMIT doesn't seem very 'Forth-like' to me: wouldn't it be better to define a word (e.g. EMIT16) to do it (and indeed another word to output two 16-bit values)?


I will post the revised version later...


Quote:
It may be that you don't need a specific SYS word, but I'm not sure how you'd get the 'return value' from an API function onto the stack without one.

My thinking about API access was similar to yours, but I'd envisaged just a single word, e.g. SYSADDR, which would be used as follows:

Code:
S" GetTickCount" S" kernel32" SYSADDR 


In practical terms you'd put the address in a 'constant':

Code:
S" GetTickCount" S" kernel32" SYSADDR CONSTANT GetTickCount 




So typing GetTickCount would execute the relevant item putting the returns on the FORTH stack ? Hmm :)






Re: BB4W FORTH Thoughts...
Post by admin on Sep 6th, 2009, 8:29pm

Quote:
Be aware of this from a Forth blog:

I was already aware of that (and the compatibility problems with HERE, ALLOT, CREATE). Unfortunately ROT and -ROT can't straightforwardly be corrected, because they're used extensively in jonesforth.f.

In principle it would be possible to change the primitives, and then edit every occurrence in jonesforth.f, but then it would be incompatible with every other implementation of JonesForth. This would cause problems updating to a later version, if one was ever released by Richard Jones.

Not being a Forth enthusiast, I don't really understand why the mistakes went uncorrected up to version 45, and still haven't been. I can only assume that the language isn't as standardised as some, and that users cope with this kind of thing.

It would appear that JonesForth was written by somebody who knew (at the start) virtually nothing about Forth. As a result the implementation is faulty in several respects, and wastefully inefficient in others. Unfortunately it's the only 'free' IA-32 implementation of Forth that I know of.

Richard.
Re: BB4W FORTH Thoughts...
Post by admin on Sep 6th, 2009, 8:31pm

Quote:
So typing GetTickCount would execute the relevant item putting the returns on the FORTH stack ?

No, you'd have to do:

Code:
GetTickCount SYSCALL 

(with my proposal of adding SYSADDR and SYSCALL words).

Richard.
Re: BB4W FORTH Thoughts...
Post by afarlie on Sep 6th, 2009, 9:37pm

on Sep 6th, 2009, 8:29pm, Richard Russell wrote:
I was already aware of that (and the compatibility problems with HERE, ALLOT, CREATE). Unfortunately ROT and -ROT can't straightforwardly be corrected, because they're used extensively in jonesforth.f.

....

It would appear that JonesForth was written by somebody who knew (at the start) virtually nothing about Forth. As a result the implementation is faulty in several respects, and wastefully inefficient in others. Unfortunately it's the only 'free' IA-32 implementation of Forth that I know of.

Richard.


on Sep 6th, 2009, 8:29pm, Richard Russell wrote:
Unfortunately it's the only 'free' IA-32 implementation of Forth that I know of.


In terms of other 'free'-ish FORTH's around there are :

gForth http://www.jwdt.com/~paysan/gforth.html - GNU Forth implementation ( which being GNU is assumed to be GPL)

There is also Win32Forth (http://win32forth.sourceforge.net/)
which also has a Yahoo group - here (http://tech.groups.yahoo.com/group/win32forth/)

It may be possible to patch Win32Forth to use oswrch or to use
Win32Forth as reference for someone willing to fix JonesForth's shortcomings.

There are also seemingly a number of freeware and proprietary systems targeting both i386 and ARM (There are some fairly developed FORTH's for RISC OS if anyones interested.)

Obviously these may not implement their output via oswrch,
or use the intended SYSADDR and SYSCALL words that were being
considered for addition to the JonesForth port.

if anyone is still bothered at this point,
the 'standard' for ANS FORTH appears to have been archived here... "http://www.taygeta.com/forth/dpans.htm".












Re: BB4W FORTH Thoughts...
Post by admin on Sep 6th, 2009, 10:01pm

Quote:
gForth... There is also Win32Forth

I'm pretty sure they're both written in C (or C++), so not really relevant to the current discussion.

Quote:
There are also seemingly a number of freeware and proprietary systems targeting both i386 and ARM

In the context of Forth, i386 may mean 16-bit (i.e. MS-DOS), so again not really relevant to BB4W; and of course ARM code is totally incompatible.

Let's not lose sight of the fact that we are here primarily discussing BBC BASIC, not Forth! This is not the place to talk about Forth in general, or other ways in which to get Forth working under Windows.

I still see some benefits of a BBC BASIC-hosted Forth, principally the VDU drivers which give easy access to a graphical output capability. At the moment that means JonesForth, for good or ill.

If the consensus of opinion is that the shortcomings of JonesForth make it unacceptable, I suggest we draw this to a close. Those interested more in Forth than in BBC BASIC are requested to take their discussions elsewhere.

Richard.

Re: BB4W FORTH Thoughts...
Post by admin on Sep 7th, 2009, 12:27pm

Rich Jones, the author of JonesForth, has contacted me to ask if he can link to the BBC BASIC version on his site! I've responded, for the moment, to the effect that it isn't appropriate to promote it until issues such as the ROT/-ROT reversal are addressed.

I've also asked questions on comp.lang.forth, where one correspondent has described JonesForth as "pretty hopeless".

So I still don't know what is the best course of action. It would seem a shame to abandon the considerable work I have done so far, but if JonesForth is incapable of becoming a 'useful' Forth implementation then I don't want to waste my time expending extra effort.

Richard.
Re: BB4W FORTH Thoughts...
Post by admin on Sep 8th, 2009, 3:51pm

Quote:
My thinking about API access was similar to yours, but I'd envisaged just a single word, e.g. SYSADDR, which would be used as follows:
S" GetTickCount" S" kernel32" SYSADDR

That appears to be impossible (in Jonesforth at least) because there's only one buffer for strings, so "GetTickCount" immediately gets overwritten with "kernel32".

I can split the LoadLibrary and GetProcAddress into separate words, as somebody suggested, but I need a word for FreeLibrary as well:

Code:
Z" kernel32.dll" LoadLibrary DUP
Z" GetTickCount" GetProcAddress
CONSTANT GetTickCount
GetTickCount SYSCALL .
6491875
GetTickCount SYSCALL .
6499843
FreeLibrary 


It works, as you can see (this is a snapshot of the actual output), but it's messy. Can anybody think of a nicer way?

Richard.

Re: BB4W FORTH Thoughts...
Post by knudvaneeden on Sep 13th, 2009, 11:35pm

on Sep 6th, 2009, 8:29pm, Richard Russell wrote:
Unfortunately it's the only 'free' IA-32 implementation of Forth that I know of.
Richard.


FreeForth?
http://christophe.lavarenne.free.fr/ff/

with friendly greetings,
Knud van Eeden
Re: BB4W FORTH Thoughts...
Post by admin on Sep 14th, 2009, 2:15pm

I have uploaded the latest version (0.22) of BB4Wforth:

http://groups.yahoo.com/group/bb4w/files/Miscellaneous/forth.zip

Changes in this version include:

1. The following standard Forth words, which work incorrectly in Jonesforth (v45), have been corrected: ROT, -ROT, ALLOT, DEPTH, HERE, MOD, / and U. (etc.)

2. The following standard Forth words, which aren't present at all in Jonesforth (v45) have been added: ROLL, DO, ?DO, LOOP, +LOOP, I, J, LEAVE, UNLOOP, <BUILDS, DOES>

3. The following custom Forth words (specific to this version) have been added: ERR, OSCLI, SYSCALL, HWND, VERSION$, LoadLibrary, FreeLibrary, GetProcAddress, EMIT16, XY, MODE, CLS, CLG, COLOUR, GCOL, ORIGIN, PLOT, MOVE, DRAW, FILL, MOVEBY, DRAWBY, EXEC

4. Operation of the following Forth words has been slightly modified: DEPTH, .S

Also supplied is the program fern.f which is a Forth version of the FERN.BBC graphics demo supplied with BB4W (translating it into Forth with virtually zero knowledge of the language was interesting!):

Code:
\ 'Fake' fractal fern
\ Original QBASIC program published in PC Magazine
\ BB4Wforth version by Richard Russell, 14-Sep-2009

VARIABLE RND 
: RANDOM ( n -- u ) RND @ 134775813 * 1 + DUP RND ! SWAP U/MOD DROP 1 + ;
: FERN
8 MODE
2 0 GCOL
0 0 ( X Y )
80000 1 DO ( Loop 80000 times )
  100 RANDOM 
  DUP 10 <= IF DROP
    SWAP DROP 0 SWAP 16 * 100 / 
  ELSE
    DUP 86 <= IF DROP
      2DUP 2DUP ( X Y X Y X Y )
      4 * 100 / SWAP 85 * 100 / + ( X Y X Y x )
      -ROT ( X Y x X Y )
      85 * 100 / SWAP 4 * 100 / - 160 + ( X Y x y )
      2SWAP 2DROP
    ELSE
      DUP 93 <= IF DROP
        2DUP 2DUP ( X Y X Y X Y )
        -26 * 100 / SWAP 20 * 100 / + ( X Y X Y x )
        -ROT ( X Y x X Y )
        22 * 100 / SWAP 23 * 100 / + 160 + ( X Y x y )
        2SWAP 2DROP
      ELSE DROP
          2DUP 2DUP ( X Y X Y X Y )
          28 * 100 / SWAP 15 * 100 / - ( X Y X Y x )
          -ROT ( X Y x X Y )
          24 * 100 / SWAP 26 * 100 / + 44 + ( X Y x y )
          2SWAP 2DROP
      THEN
    THEN
  THEN
  2DUP SWAP 600 + SWAP 2DUP MOVE DRAW
LOOP
2DROP
." OK"
;

FERN 

You can run the program from BB4Wforth using the command:

Code:
S" fern.f" EXEC 

As this thread has gone very quiet, I would value any feedback, bug reports etc. to indicate that somebody out there is appreciative of my efforts!

Richard.
Re: BB4W FORTH Thoughts...
Post by knudvaneeden on Sep 14th, 2009, 3:04pm

on Sep 14th, 2009, 2:15pm, Richard Russell wrote:
I have uploaded the latest version (0.22) of BB4Wforth:

[As this thread has gone very quiet, I would value any feedback, bug reports etc. to indicate that somebody out there is appreciative of my efforts!

Richard.


Richard, yes, this is very much appreciated.

I tested yesterday some programs from the Forth book from Leo Brody, using BB4WForth, and that went fine.
Now even with graphics.

Note:
See also http://www.techworld.com.au/article/250530/-z_programming_languages_forth
which might be an interesting read.

with friendly greetings,
Knud van Eeden





Re: BB4W FORTH Thoughts...
Post by afarlie on Sep 14th, 2009, 3:06pm

on Sep 14th, 2009, 2:15pm, Richard Russell wrote:
I have uploaded the latest version (0.22) of BB4Wforth:

http://groups.yahoo.com/group/bb4w/files/Miscellaneous/forth.zip



Perhaps this thread should now be entitled BB4th? wink

Fern examples works as intended.

In terms of EMIT16 the U/MOD word wasn't something
I knew about, but my graphics code was planning on doing that as well.

I'll post my graphics code later, (the reason for ROLL)
was to do with some VDU commands like viewports
which need a rectangle (i.e 2 XY pairs rather than a single)

Having an indication of a stack underflow is useful. smiley


Quote:
Changes in this version include:

1. The following standard Forth words, which work incorrectly in Jonesforth (v45), have been corrected: ROT, -ROT, ALLOT, DEPTH, HERE, MOD, / and U. (etc.)

2. The following standard Forth words, which aren't present at all in Jonesforth (v45) have been added: ROLL, DO, ?DO, LOOP, +LOOP, I, J, LEAVE, UNLOOP, <BUILDS, DOES>



I will have to do some reading to understand these in more depth.

Quote:
3. The following custom Forth words (specific to this version) have been added: ERR, OSCLI, SYSCALL, HWND, VERSION$, LoadLibrary, FreeLibrary, GetProcAddress, EMIT16, XY, MODE, CLS, CLG, COLOUR, GCOL, ORIGIN, PLOT, MOVE, DRAW, FILL, MOVEBY, DRAWBY, EXEC


And the documentation is remarkably clear smiley.

It' should not be that hard to add more advanced
commands..

Digging out the MIDITEST example is something else I might look at, given that there isn't an AMPLE like system on Windows...
(Reimplementing all of AMPLE is beyond me, (some of it being Intterurpt driven 6502 code, but I could at least have a go at seeing if something is possible with simple
MIDI maybe...)


Quote:
4. Operation of the following Forth words has been slightly modified: DEPTH, .S


I assume what this now does is explained in the code?
I must go and read it smiley

The Fern demo worked fine for me smiley






Re: BB4W FORTH Thoughts...
Post by admin on Sep 14th, 2009, 4:45pm

Quote:
I assume what this now does is explained in the code?

Nope, no explanations! You'll have to find out by experiment what the difference is; sorry. This was a 'minimum effort' exercise which has already taken up more of my time than I intended.

Richard.
Re: BB4W FORTH Thoughts...
Post by knudvaneeden on Sep 14th, 2009, 5:17pm

I have put on my wish list (to maybe todo one time) and am playing with the thought to create a Forth implementation in pure BBCBASIC for Windows (thus not assembler).

Maybe base it on some existing BASIC implementation somewhere to be found.

There is or there seems to be no Backus Naur Form or formal syntax for Forth. If that would have existed that would maybe have made the implementation a little bit more streamlined and to be created more automated.

But I might diverge soon, as usual.

with friendly greetings,
Knud van Eeden
Re: BB4W FORTH Thoughts...
Post by knudvaneeden on Sep 14th, 2009, 6:51pm

For those wanting maybe to compare the Forth source code in fern.f versus an equivalent BBCBASIC, here an approximate equivalent.

MODE 8
GCOL 0, 2
VDU 29, 639; 0;
X = 0: Y = 0
COLOUR 15
PRINT TAB( 1, 1 ); "Fractal Fern"
PRINT TAB( 1, 2 ); "from PC Magazine"
FOR I = 1 TO 40000
:
R = RND( 1 )
:
IF (R <= .01) THEN
A = 0: B = 0: C = 0: D = .16: E = 0: F = 0
ELSEIF R > .01 AND R <= .86 THEN;
A = .85: B = .04: C = -.04: D = .85: E = 0: F = 1.6
ELSEIF R > .86 AND R <= .93 THEN;
A = .2: B = -.26: C = .23: D = .22: E = 0: F = 1.6
ELSE
A = -.15: B = .28: C = .26: D = .24: E = 0: F = .44
ENDIF
:
NEWX = (A * X) + (B * Y) + E
NEWY = (C * X) + (D * Y) + F
:
PLOT 69, 100 * X, 100 * Y
:
X = NEWX: Y = NEWY
:
NEXT I
:
END

Re: BB4W FORTH Thoughts...
Post by David Williams on Sep 14th, 2009, 8:11pm

on Sep 14th, 2009, 6:51pm, knudvaneeden wrote:
For those wanting maybe to compare the Forth source code in fern.f versus an equivalent BBCBASIC, here an approximate equivalent.



Didn't Richard do a one-line version of that program?
Re: BB4W FORTH Thoughts...
Post by admin on Sep 14th, 2009, 9:23pm

Quote:
Didn't Richard do a one-line version of that program?

Indeed so:

Code:
MODE8:GCOL2:OFF:x=0:y=0:FORI=1TO80000:r=RND(1):s=r>.1:t=r>.86:u=r>.93:A=-.86*s+.65*t+.35*u:B=-.04*s+.3*t-.54*u:C=.04*s-.27*t-.01*u:D=.16-.69*s+.63*t-.02*u:F=-1.6*s+1.16*u:z=A*x+B*y:y=C*x+D*y+F:x=z:LINE600+96*x,32+96*y,600+96*x,32+96*y:NEXT 

Richard.
Re: BB4W FORTH Thoughts...
Post by admin on Sep 14th, 2009, 9:29pm

Quote:
here an approximate equivalent

Very approximate (your program uses floating-point values, whereas the Forth version is integer only of course). Here is the actual BBC BASIC program from which the Forth version was translated:

Code:
      MODE 8
      OFF
      GCOL 2
      :
      X%=0
      Y%=0
      :
      FOR I%=1 TO 80000
        R% = RND(100)
        :
        CASE TRUE OF
          WHEN R%<=10 A%=0: B%=0: C%=0: D%=16: F%=0
          WHEN R%>10 AND R%<=86 A%=85: B%=4: C%=-4: D%=85: F%=160
          WHEN R%>86 AND R%<=93 A%=20: B%=-26: C%=23: D%=22: F%=160
          WHEN R%>93 A%=-15: B%=28: C%=26: D%=24: F%=44
        ENDCASE
        :
        Z%=A%*X%DIV100+B%*Y%DIV100
        Y%=C%*X%DIV100+D%*Y%DIV100+F%
        X%=Z%
        MOVE 600+X%, Y%
        DRAW 600+X%, Y%
        :
      NEXT I% 

Richard.
Re: BB4W FORTH Thoughts...
Post by afarlie on Sep 15th, 2009, 10:11am

This was what I'd worked out so far on accessing MIDI.

This is NOT complete code yet, as I was unsure on some points..

Code:
\  MIDI Functions - NOT Quite AMPLE but may be 
workable...

\ TODO:  GM-Style Instrument numbering
1 CONSTANT  'Grand_Piano' 

\ TODO:  GM-Style Drum Mapping....
\ These would be pitch values used by Channel 10.

S" WINMM.DLL" LoadLibrary CONSTANT WinMM \Load WinMM  Library


\ Obtain addresses for relevant functions in WinMM

WinMM S" midiOutOpen" GetProcedureAddress CONSTANT midiOpenOut
WinMM S" midiOutShortMsg" GetProcedureAddress CONSTANT midiOutShortMsg
WinMM S" midiOutClose" GetProcedureAddress CONSTANT midiOutClose


VARIABLE MidiHandle
0 MidiHandle ! \Variable Initialisation
\ Is this correct way  to set up variable to hold midichannels?


\ Per MIDITEST.BBC
:GetMidi
0 0 0 -1  \ Params in order on stack needed.
MidiHandle \
\ Probably need to test return value here...
;

:_SendShortMsg
MidiHandle @    \ Contents NOT address...
midiOutShortMsg SYSCALL
;

:PlayNote (note --)  \ Based on PlayNewNote in MIDITEST.BBC
256 * 144 +  
127 16 LSHIFT  + \ dwmsg
_SendShortMsg
;


:StopNote  \ (note  --) StopNoteBased on StopPlay in MIDITEST.BBC
256 * 128 + 
_SendShortMsg
;


:Insturment (voice --) \ Change Instrument
1 -  256 *  192 + \ Setup voice change.
127 16 LSHIFT + \ Question do we have LSHIFT/ RSHIFT?
_SendShortMsg
;

:CloseMidi
MidiHandle @
DUP \ Because we need it for closing the midi device
IF    \ I.E Non Zero handle
 midiOutClose SYSCALL \  Close the device using it.
THEN ;
DROP \Drop duplicate param...
;

 

Re: BB4W FORTH Thoughts...
Post by afarlie on Sep 15th, 2009, 10:35am

Further VDU related words... :
(modified)

If you find a bug or misunderstanding please LMK smiley

0 CONSTANT NULL \ This can be defined directly.
27 CONSTANT ESC \ This can be defined directly.

:
EMIT_LPT (n --) \ Emit 1 Character to the printer.
1 EMIT EMIT
;

:
PRINTER_ON (--) \Enable printer.
2 EMIT
;

:
PRINTER_OFF (--) \Disable printer.
3 EMIT
;

:
PRINTER_FF (--) \ Form feed to printer.
12 LPT_EMIT
;


:
SPLIT_CURSORS (--) \Text cursor is seperate
4 EMIT
;

:
JOIN_CURSORS (--) \ Text cursor joined with graphics.
5 EMIT
;

:
SHOW_VDU (--) \ Enable VDU
6 EMIT
;

:
HIDE_VDU (--) \Disable VDU
21 EMIT
;

:
BELL (--) \ ASCII BELL - Warning tone etc...
7 EMIT
;


\ Defining the following as constants, rather than fixing
them in the implementation

8 CONSTANT _left
9 CONSTANT _right
10 CONSTANT _down
11 CONSTANT _up

:
CUR_LEFT
_left EMIT
;

:
CUR_RIGHT
_right EMIT
;

:
CUR_UP
_up EMIT
;

:
CUR_DOWN
_down EMIT
;

:
LINE_HOME
\ Actual behaviour is listed as return to col 0 in current row... as opposed to full LF CR..
13 EMIT
;


:
DEFINECHAR
\ (n1 n2 n3 n4 n5 n6 n7 n8 char --- )
\(This makes NO checks on the input, it probably should..)

23 EMIT EMIT
7 ROLL EMIT \n1
6 ROLL EMIT \ n2
5 ROLL EMIT \ n3
4 ROLL EMIT \ n4
3 ROLL EMIT \ n5
2 ROLL EMIT \ n6
1 ROLL EMIT \ n7
EMIT \n8


:
_EMIT_RECT (x y x y --)
2SWAP \ Move first pair over top pair (I am not sure 2 SWAP is per standard though)
XY \ First coordiante pair
XY \Second coordinate pair.
;


:
VIEWPORT ( x1 y1 x2 y2 --) \ Define graphics viewport.
0 0 ORIGIN \ Use Absolute coordinates.
24 EMIT \ VDU command
_EMIT_RECT \ Rectangular region to use.
CLG \ Clear graphics viewport.
;


Re: BB4W FORTH Thoughts...
Post by admin on Sep 15th, 2009, 11:06am

Quote:
7 ROLL 256 MOD EMIT

Surely there's no need to use '256 MOD' before EMIT (since EMIT outputs just a single byte)? In any case the parameters you supply to DEFINECHAR are presumably all in the range 0-255 anyway!

There are many typos and other errors in your code, but presumably you are aware of that. Maybe in future it would be better to check that Forth at least accepts it before listing it here.

Richard.
Re: BB4W FORTH Thoughts...
Post by afarlie on Sep 15th, 2009, 1:13pm

on Sep 15th, 2009, 11:06am, Richard Russell wrote:
Surely there's no need to use '256 MOD' before EMIT (since EMIT outputs just a single byte)? In any case the parameters you supply to DEFINECHAR are presumably all in the range 0-255 anyway!

There are many typos and other errors in your code, but presumably you are aware of that. Maybe in future it would be better to check that Forth at least accepts it before listing it here.

Richard.


OK. Question to the FORTH people here, what are the more obvious glaring misunderstandings I have?



Re: BB4W FORTH Thoughts...
Post by admin on Sep 16th, 2009, 8:44pm

Quote:
This is NOT complete code yet, as I was unsure on some points..

Here is a complete, tested, working version:

Code:
\ MIDI Functions - NOT Quite AMPLE but may be workable...

\ TODO:  GM-Style Instrument numbering
1 CONSTANT 'Grand_Piano' 

\ TODO:  GM-Style Drum Mapping....
\ These would be pitch values used by Channel 10.

\ Obtain addresses for relevant functions in WinMM

Z" WINMM.DLL" LoadLibrary ( Load WinMM library )
DUP Z" midiOutOpen" GetProcAddress CONSTANT midiOutOpen
DUP Z" midiOutShortMsg" GetProcAddress CONSTANT midiOutShortMsg
DUP Z" midiOutClose" GetProcAddress CONSTANT midiOutClose
FreeLibrary DROP ( Free WinMM library )

Z" Kernel32.DLL" LoadLibrary ( Load Kernel32 library )
DUP Z" Sleep" GetProcAddress CONSTANT Sleep
FreeLibrary DROP ( Free Kernel32 library )

VARIABLE MidiHandle 

: OpenMidi ( -- )
  0 0 0 -1 MidiHandle midiOutOpen SYSCALL
  IF
    ." Failed to open MIDI output device" CR
    ABORT
  THEN
;

: CloseMidi ( -- )
  MidiHandle @ midiOutClose SYSCALL
  DROP
;

: SendOutShortMsg ( msg -- )
  MidiHandle @ midiOutShortMsg SYSCALL
  DROP
;

: Delay ( ms -- )
  Sleep SYSCALL DROP
;

HEX
: StartNote ( note -- )
  100 * 7F0090 +
  SendOutShortMsg
;
DECIMAL

: StopNote ( note -- )
  256 * 128 +
  SendOutShortMsg
;

: PlayNote ( note time -- )
  SWAP TUCK 
  StartNote
  Delay
  StopNote
; 

HEX
: Instrument ( voice -- )
  100 * 7F00C0 +
  SendOutShortMsg
;
DECIMAL

: CE3K
  OpenMidi
  'Grand_Piano' Instrument
  70 500 PlayNote
  72 500 PlayNote
  68 500 PlayNote
  56 500 PlayNote
  63 1000 PlayNote
  1000 Delay
  CloseMidi
;

CE3K 

Can you guess what it plays? To find out, 'EXEC' it into BB4Wforth!

Richard.
Re: BB4W FORTH Thoughts...
Post by admin on Sep 20th, 2009, 9:35pm

I have uploaded the latest version (0.25) of BB4Wforth here:

http://groups.yahoo.com/group/bb4w/files/BB4Wforth/BB4Wforth.zip

This version implements the following additional words: UM*, INKEY, OPENIN, OPENOUT, OPENUP, BGET, BPUT, CLOSE, ABS, MAX, MIN, TABXY, MS. The following aliases are also provided: PAGE (same as CLS), AT-XY (same as TABXY) and TYPE (same as TELL). The following variables are now available (corresponding to the similarly-named 'system variables' in BB4W): hwnd, memhdc, prthdc, hcsr, hpal, midiid, hfiles, flags, vduvar, ox, oy, cmd$, dir$, lib$, tmp$, usr$.

It is not my intention to make any more changes to BB4Wforth, unless a major bug or omission is reported. Although the full source code is provided in the above ZIP file, I would ask that changes are submitted to me for incorporation, rather than multiple incompatible versions being proliferated.

Richard.
Re: BB4W FORTH Thoughts...
Post by admin on Sep 22nd, 2009, 09:50am

I've updated BB4Wforth to version 0.26:

http://groups.yahoo.com/group/bb4w/files/BB4Wforth/BB4Wforth.zip

This version fixes a couple of bugs:

1. Using *LIST (S" list filename" OSCLI) caused an 'abort error'.

2. If 'Close' was clicked whilst a Forth program was executing, the window would go into an 'unresponding' state.

Richard.

Re: BB4W FORTH Thoughts...
Post by admin on Oct 1st, 2009, 08:19am

I've updated BB4Wforth to version 0.30:

http://groups.yahoo.com/group/bb4w/files/BB4Wforth/bb4wforth.zip

This version has the LEAVE bug corrected, and also implements the following new Forth words: M* */ */MOD U< U> S>D 2* 2/ U2/ SOURCE >IN UM/MOD SM/REM FM/MOD R@ D+ D- [CHAR] 2OVER CELL+ CHARS CHAR+ 2! LSHIFT RSHIFT COUNT DIGIT >NUMBER

Richard.

Re: BB4W FORTH Thoughts...
Post by admin on Oct 2nd, 2009, 10:16pm

How about this then....

Code:
BB4Wforth version 0.33 adapted from Jonesforth version 45
Corrections and additions by R.T. Russell, September 2009
244681 cells remaining
OK
S" tester.fr" INCLUDED
S" core.fr" INCLUDED

TESTING CORE WORDS
TESTING BASIC ASSUMPTIONS
TESTING BOOLEANS: INVERT AND OR XOR
TESTING 2* 2/ LSHIFT RSHIFT
TESTING COMPARISONS: 0= = 0< < > U< MIN MAX
TESTING STACK OPS: 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP
TESTING >R R> R@
TESTING ADD/SUBTRACT: + - 1+ 1- ABS NEGATE
TESTING MULTIPLY: S>D * M* UM*
TESTING DIVIDE: FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD
TESTING HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2! ALIGN ALIGNED +! ALLOT
TESTING CHAR [CHAR] [ ] BL S"
TESTING ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE
TESTING IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE
TESTING DO LOOP +LOOP I J UNLOOP LEAVE EXIT
TESTING DEFINING WORDS: : ; CONSTANT VARIABLE CREATE DOES> >BODY
TESTING EVALUATE
TESTING SOURCE >IN WORD
TESTING <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL
TESTING FILL MOVE
TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:
 !"#$%&'()*+,-./0123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`
abcdefghijklmnopqrstuvwxyz{|}~
YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:
0 1 2 3 4 5 6 7 8 9 
YOU SHOULD SEE 0-9 (WITH NO SPACES):
0123456789
YOU SHOULD SEE A-G SEPARATED BY A SPACE:
A B C D E F G 
YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:
0  1  2  3  4  5  
YOU SHOULD SEE TWO SEPARATE LINES:
LINE 1
LINE 2
YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:
  SIGNED: -80000000 7FFFFFFF 
UNSIGNED: 0 FFFFFFFF 
TESTING INPUT: ACCEPT

PLEASE TYPE UP TO 80 CHARACTERS:
The quick brown fox jumps over the lazy dog.

RECEIVED: "The quick brown fox jumps over the lazy dog."
TESTING DICTIONARY SEARCH RULES

End of Core word set tests 


Richard.
Re: BB4W FORTH Thoughts...
Post by admin on Oct 3rd, 2009, 4:20pm

I'm pleased to announce the release of BB4Wforth version 0.33:

http://groups.yahoo.com/group/bb4w/files/BB4Wforth/bb4wforth.zip

This version passes the Hayes CORE tests successfully (see previous message).

Richard.

Re: BB4W FORTH Thoughts...
Post by admin on Oct 4th, 2009, 4:13pm

I'm pleased to announce the release of BB4Wforth version 0.35:

http://groups.yahoo.com/group/bb4w/files/BB4Wforth/bb4wforth.zip

This version runs somewhat more quickly than version 0.33 (but is otherwise functionally equivalent).

Richard.

Re: BB4W FORTH Thoughts...
Post by admin on Oct 7th, 2009, 10:05am

I've updated BB4Wforth to version 0.36:

http://groups.yahoo.com/group/bb4w/files/BB4Wforth/bb4wforth.zip

This version fixes a couple of minor bugs:

1. The conditions for terminating a DO...LOOP were subtly incorrect.

2. EVALUATE locked up if passed an empty string.

The following additional CORE EXT words are implemented: C" 2>R 2R> CONVERT.

Version 0.36 passes both the Hayes CORE test and the (non-Hayes) COREPLUS test. It also passes CORE EXT tests of words which are implemented.

Richard.

Re: BB4W FORTH Thoughts...
Post by admin on Oct 10th, 2009, 1:33pm

I'm pleased to announce the release of BB4Wforth version 0.37:

http://groups.yahoo.com/group/bb4w/files/BB4Wforth/bb4wforth.zip

There is now support for handling Windows events (equivalent to ON CLOSE, ON MOUSE, ON MOVE, ON SYS and ON TIME in BB4W). Rather than allowing genuinely asynchronous interrupts, which could have had an adverse effect on execution time, Windows events are made synchronous by means of the POLL word.

For example, to incorporate an ON TIME handler you would write a Forth word called ONTIME containing the code you wish to execute. Then, within your 'main' program, you would put POLL wherever you want a pending event to be processed:

Code:
: ONTIME ." ON TIME!" CR ;
: TEST BEGIN POLL 0 MS AGAIN ;
TEST 

(here 0 MS avoids 'burning' the processor).

Additionally, v0.37 allows you to specify the name of a Forth program in the command line (or via a shortcut), causing it to be executed directly:

Code:
  forth progname.f 

Richard.

Re: BB4W FORTH Thoughts...
Post by knudvaneeden on Oct 20th, 2009, 5:21pm

To learn Forth:

Leo Brodie 'Starting Forth' book (a classic) online:

http://forth.com/starting-forth/

(source: magazine 'Dr. Dobb's journal')

with friendly greetings,
Knud van Eeden