Skip to content

timmoorhouse/mega65-forth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MEGA65 Forth (MEGA654th?)

An attempt at Forth for the MEGA65. This is heavily influenced by FIG FORTH release 1.1

This publication has been made available by the 
Forth Interest Group, P. O. box 1105, San Carlos, CA 94070

screenshot

Note that we have actually switched to font A (the ASCII font). The \ word shows up correctly on screen but the screenshot from m65 assumes the default font.

This is still in the early stages of developement - check the status table below for details on what is and is not supported so far. The most important missing pieces right now are likely support for MARKER and/or FORGET, an editor and an assembler word set. Programs can be entered manually or read from pre-existing sequential files, however, and much of the core dictionary is implemented and fairly stable.

The next priorities are:

  • MARKER has been implemented, but it might be worth trying to get a working FORGET too.
  • We can now run the complete preliminary, core, core plus and core extension tests unmodified, but there are a number of failures that need to be addressed.
  • Move more of the implementation from assembler to Forth. As this happens, getting a functional SEE is becoming more and more important (even if it's just a hex dump at first).

My apologies if this isn't the greatest Forth implementation. I don't really have much experience with Forth. I'm doing this because I've always been intrigued by Forth, and with a new MEGA65 sitting on the dining room table, it seemed the perfect project to learn about Forth, shake decades of dust off my 6502 programming skills, and learn about some of the MEGA65-specific features.

An attempt will be made to:

  • Be more Forth 2012 compliant, or at least ANS Forth (94). Things that have been removed in 2012 (such as TIB) almost certainly won't be implemented. Things that are obsolescent in 2012 (such as [COMPILE]) may not be implemented either.
  • Provide access to MEGA65 features. I'll likely look at least at SUPER FORTH 64 (which was based on MVP-FORTH) for API ideas here, and possibly others, but I may not retain compatability.

I haven't looked at geoForth yet, but intend to at some point. Making some sort of equivalent for the MEGA65 GEOS might be interesting, and give me an excuse to dig into GEOS a bit. No promises here though.

Eventually, I want to sort out how to take advantage of more than 64K without breaking compliance with the Forth 2012 specification. It would be nice if we could move much of the standard dictionary to bank 1, for example.

BUILDING

Requirements

  • ACME: I was using the one from MEGA65 github but switched to the svn version to get access to some of the more recent features, but I'm not certain I ended up using them. It could be that the MEGA65 one will still work.

There is a build script in bin/build.sh that can be used. Right now it doesn't do a huge amount, but eventually I expect that the build process will get more involved:

  • Compiling the builtins
  • Use a MEGA65 or xemu to compile the rest of the standard dictionary, possibly for multiple configurations (a minimal set, a complete set, etc)
  • Run a test suite
  • Run benchmarks
  • Building tools (an assembler word set? an editor?)
  • Assembling a disk image with various build configuration, source code, examples, tools

Recommendations

RANDOM TODOs

These should get us to the point of bootstrapping with a dictionary written in forth and running unit tests:

  • CORE
    • Need to reimplement the multiplication/division operations using the math unit.
  • EXCEPTION
    • Need to be able to throw exceptions from assembler. This likely means changing the THROW implementation to be native code instead of Forth bytecode.
    • Many bits of code need to be updated to throw an exception for error conditions.
  • FILE
    • Handle file access modes.
    • Fix I/O status handling (when is status from READSS reset?).
    • Fix handling of I/O error cases.
  • Error checking (and throwing the appropriate exception)
    • Unaligned address.
    • Divide by zero.
    • Pictured numeric output string overflow.
    • Parsed string overflow?
    • Mismatched control structures.
    • Invalid name.
    • File I/O error.
    • Unexpected EOF.
  • Moving more of the implementation from assembler to Forth.
    • READ-LINE
    • ACCEPT
    • REFILL
    • EVALUATE possibly? (would need to tweak the bootstrap code)
      • SAVE-INPUT
      • RESTORE-INPUT
      • SOURCE
    • UNUSED possibly? would need access to DAREA
  • Tests
    • Test suite
    • Some reasonable way of capturing test results.
      • It might make sense to have a way to redirect EMIT to a file. gforth makes EMIT a deferred, which might be the cleanest option.
  • Benchmarks
    • Compiling the dictionary?
    • Something without I/O?

There'll be lots more to do after that.

STATUS

Note that some of these are implemented in Forth and the bootstrap process is not yet automated.

Word Set Implemented Not (Yet?) Implemented
BLOCK BLK BLOCK BUFFER FLUSH LOAD SAVE-BUFFERS UPDATE
BLOCK-EXT EMPTY-BUFFERS LIST SCR THRU
CORE ! # #> #S ' ( * */ */MOD /MOD + +! +LOOP , - . ." / 0< 0= 1+ 1- 2! 2* 2/ 2@ 2DROP 2DUP 2OVER 2SWAP : ; < <# = > >BODY >IN >NUMBER >R ?DUP @ ABORT ABORT" ABS ACCEPT ALIGN ALIGNED ALLOT AND BASE BEGIN BL C! C, C@ CELL+ CELLS CHAR CHAR+ CHARS CONSTANT COUNT CR CREATE DECIMAL DEPTH DO DOES> DROP DUP ELSE EMIT ENVIRONMENT? EVALUATE EXECUTE EXIT FILL FIND FM/MOD HERE HOLD I IF IMMEDIATE INVERT J KEY LEAVE LITERAL LOOP LSHIFT M* MAX MIN MOD MOVE NEGATE OR OVER POSTPONE QUIT R> R@ RECURSE REPEAT ROT RSHIFT S" S>D SIGN SM/REM SOURCE SPACE SPACES STATE SWAP THEN TYPE U. U< UM* UM/MOD UNLOOP UNTIL VARIABLE WHILE WORD XOR [ ['] [CHAR] ]
CORE-EXT .( .R 0<> 0> 2>R 2R> 2R@ :NONAME <> ?DO ACTION-OF AGAIN BUFFER: C" CASE COMPILE, DEFER DEFER! DEFER@ ENDCASE ENDOF ERASE FALSE HEX HOLDS IS MARKER NIP OF PAD PARSE PARSE-NAME PICK REFILL RESTORE-INPUT ROLL SAVE-INPUT SOURCE-ID S\" TO TRUE TUCK U.R U> UNUSED VALUE WITHIN \
CORE-EXT obsolescent [COMPILE]
DOUBLE 2CONSTANT 2LITERAL D+ D- D. D.R D>S DABS DNEGATE 2VARIABLE D0< D0= D2* D2/ D< D= DMAX DMIN M*/ M+
DOUBLE-EXT 2ROT 2VALUE DU<
EXCEPTION CATCH THROW
FACILITY PAGE AT-XY KEY?
FACILITY-EXT K-DELETE K-DOWN K-F1 K-F10 K-F11 K-F12 K-F2 K-F3 K-F4 K-F5 K-F6 K-F7 K-F8 K-F9 K-HOME K-INSERT K-LEFT K-RIGHT K-UP +FIELD BEGIN-STRUCTURE CFIELD: EKEY EKEY>CHAR EKEY>FKEY EKEY? EMIT? END-STRUCTURE FIELD: K-ALT-MASK K-CTRL-MASK K-END K-NEXT K-PRIOR K-SHIFT-MASK MS TIME&DATE
FILE BIN CLOSE-FILE INCLUDE-FILE INCLUDED OPEN-FILE1 R/O R/W READ-LINE W/O WRITE-FILE WRITE-LINE CREATE-FILE DELETE-FILE FILE-POSITION FILE-SIZE READ-FILE REPOSITION-FILE RESIZE-FILE
FILE-EXT INCLUDE FILE-STATUS FLUSH-FILE RENAME-FILE REQUIRE REQUIRED
FLOATING >FLOAT D>F F! F* F+ F- F/ F0< F0= F< F>D F@ FALIGN FALIGNED FCONSTANT FDEPTH FDROP FDUP FLITERAL FLOAT+ FLOATS FLOOR FMAX FMIN FNEGATE FOVER FROT FROUND FSWAP FVARIABLE REPRESENT
FLOATING-EXT DF! DF@ DFALIGN DFALIGNED DFFIELD DFLOAT+ DFLOATS F** F. F>S FABS FACOS FACOSH FALOG FASIN FASINH FATAN FATAN2 FATANH FCOS FCOSH FE. FEXP FEXPM1 FFIELD: FLN FLNP1 FLOG FS. FSIN FSINCOS FSINH FSQRT FTAN FTANH FTRUNC FVALUE F~ PRECISION S>F SET-PRECISION SF! SF@ SFALIGN SFALIGNED SFIELD: SFLOAT+ SFLOATS
LOCALS (LOCAL) TO
LOCALS-EXT {:
LOCALS-EXT obsolescent LOCALS|
MEMORY ALLOCATE FREE RESIZE
SEARCH DEFINITIONS FORTH-WORDLIST GET-CURRENT GET-ORDER SEARCH-WORDLIST SET-CURRENT SET-ORDER WORDLIST
SEARCH-EXT ALSO FORTH ONLY ORDER PREVIOUS
STRING /STRING BLANK CMOVE CMOVE> COMPARE SLITERAL -TRAILING SEARCH
STRING-EXT UNESCAPE REPLACES SUBSTITUTE
TOOLS .S ? DUMP SEE1 WORDS
TOOLS-EXT AHEAD BYE CS-PICK CS-ROLL N>R NAME>COMPILE NAME>INTERPRET NAME>STRING NR> TRAVERSE-WORDLIST [DEFINED] [ELSE] [IF] [THEN] [UNDEFINED] ;CODE ASSEMBLER CODE EDITOR SYNONYM
TOOLS-EXT obsolescent FORGET
XCHAR X-SIZE XC!+ XC!+? XC, XC-SIZE XC@+ XCHAR+ XEMIT XKEY XKEY?
XCHAR-EXT +X/STRING -TRAILING-GARBAGE CHAR EKEY>XCHAR X-WIDTH XC-WIDTH XCHAR- XHOLD X\STRING-
Extensions BACKGROUND BORDER FOREGROUND LATEST MON SAVESYSTEM SP@

TEST STATUS

The code is getting to the point where automating the test suite makes sense. I do want to have some way to redirect output to make extracting results simpler.

Test Status Comments
Preliminaries PASS 1 expected2 error reported.
BLOCK TBD Too early to attempt
CORE, CORE plus FAIL Some problems with UM/MOD. 17 errors reported, 9 of which are expected2.
CORE-EXT PASS 4 expected2 errors reported.
DOUBLE TBD Too early to attempt
EXCEPTION PASS
FACILITY TBD Too early to attempt
FILE TBD Too early to attempt
LOCALS TBD Too early to attempt
MEMORY TBD Too early to attempt
SEARCH PASS
STRING TBD Too early to attempt
TOOLS TBD Too early to attempt

Failures to look at

The cause of these failures has not yet been determined.

From core plus:

INCORRECT RESULT: t[ 0 max-uint 0 ustep gd8 -> 256 ]t
INCORRECT RESULT: t[ 0 0 max-uint -ustep gd8 -> 256 ]t
INCORRECT RESULT: t[ 0 max-int min-int step gd8 -> 256 ]t
INCORRECT RESULT: t[ 0 min-int max-int -step gd8 -> 256 ]t
INCORRECT RESULT: t[ 0 0 0 ustep +uwrap? 256 gd9
INCORRECT RESULT: t[ 0 -max-int negate -max-int over gd8 -2> 2 ]t
INCORRECT RESULT: t[ 0 min-int 1+ 1 min-int gd8 -> 2 ]t

From string (looks like PETSCII things?):

INCORRECT RESULT: t[ s11 s12 compare -> 1 ]t
INCORRECT RESULT: t[ s12 s11 compare -> -1 ]t

PETSCII

Because we are using the PETSCII character set and not ASCII some tests are expected to fail. I'm not considering these as errors.

From preliminaries:

error #47: testing [CHAR]

From core:

INCORRECT RESULT: t[ char X -> 58 ]t
INCORRECT RESULT: t[ char HELLO -> 48 ]t
INCORRECT RESULT: t[ gc1 -> 58 ]t
INCORRECT RESULT: t[ gc2 -> 48 ]t
INCORRECT RESULT: t[ gc3 -> 58 ]t
INCORRECT RESULT: t[ gc4 drop dup c@ swap char+ c@ -> 58 59 ]t
INCORRECT RESULT: t[ gp1 -> <true> ]t

From core plus:

INCORRECT RESULT: t[ 'z' -> 122 ]t
INCORRECT RESULT: t[ 'z' -> 7a ]t

From core extensions:

INCORRECT RESULT: t[ ssq3 drop  1 chars + c@ ->   8 ]t \ \b BS Backspace
INCORRECT RESULT: t[ ssq3 drop  3 chars + c@ ->  12 ]t \ \f FF Form feed
INCORRECT RESULT: t[ ssq3 drop 14 chars + c@ ->  97 ]t \ a  a  Hex follow on
INCORRECT RESULT: t[ ssq3 drop 16 chars + c@ -> 120 ]t \ x  x  Non hex follow on

UM/MOD

INCORRECT RESULT: t[ max-uint max-uint um* max-uint um/mod -> 0 max-uint ]t

CREDITS

Footnotes

  1. Partial support only (so far) 2

  2. Some failures will occur because we are using PETSCII and not ASCII. See this section for details. 2 3