KIMForth

KIMForth is an implementation of the 6502 FIG-FORTH 1.1 specifically for KIM-1 systems with additional memory starting at $2000. There are many versions of the 6502 FIG-FORTH source code floating around the internet in both PDF and machine-readable form. Most of these are coded for the AIM-65 or Apple II. Starting with one of these, I cleaned up the source and implement the following changes to create a version optimized to running on an expanded KIM-1 system.

Patches for KIM-1 Operation

1. Backspace character changed from Rubout $7F to Backspace $08 for proper operation with VT-100 terminal emulators

2. EXPECT modified replacing the EMIT charter echo with DROP since the KIM-1 echos in hardware.

3. Modified XEMIT, XKEY and XCRLF to call the KIM-1 terminal functions. XEMIT also clears bit 7 to be compliant with FIG standard.

4. XQTER Break function implemented. Since UART is in software it is not perfect, but works adequately. Because of the sampling interval a key may need to be pressed several times before it is recognized

5. MON – breaks to the KIM monitor at $1C4F

6. R/W – is implemented as a NOP merely DROPing its parameters from the stack. This keeps all the disc functions (with eight 128-byte blocks) operational, but with no changes to the block buffer contents occurs

fig-FORTH bug patches

1.  U* – patched

2.  U/ – patched

3.  U< – patched

There are well documented bugs in the original fig-FORTH 6502 distribution for U* and U/  These have been included in this file. Details can be found at the links below.

http://6502org.wikidot.com/errata-software-figforth

http://forum.6502.org/viewtopic.php?f=9&t=689&start=30

http://6502.org/source/integers/ummodfix/ummodfix.htm

This link covers multiple bugs including the U< bug.    http://forum.6502.org/viewtopic.php?f=9&t=2197 

The U< described in the link above is less thoroughly documented and referenced.  Independently discovered it when setting MEM to greater than $7FFF. The buggy U<  causes CREATE to fail if there was more than 32K available for the dictionary because CREATE does a test for available space. There is an addition subtle bug in the CREATE code. Below is the original code.

  • CREAT    .WORD DOCOL
  •               .WORD TIB       
  •               .WORD HERE    
  •               .WORD CLIT     ;  6502 only, assures
  •               .BYTE $A0       ;  room exists in dict.
  •               .WORD PLUS    
  •               .WORD ULESS   
  •              .WORD TWO     
  •              .WORD QERR    

The test ensures that HERE + $A0 is less than TIB which is used as an upper memory limit. This would be fine if the implementation followed the memory model in the Nov. 1980 Fig-Forth installation manual, which shows the User variables being located below the disk buffers. However, almost every version of 6502 Fig-Forth places the User variables at the top of memory and the disk buffers below i.e.:

MEM       .EQU $FF00         ; top of assigned memory+1 byte.

UAREA     .EQU MEM-128       ; 128 bytes of user area

DAREA     .EQU UAREA-BMAG    ; disk buffer space.

This means it is possible for the dictionary to grow into the disk buffer area. If any of the disk functions were accessed, part of the dictionary could be over written. While this is unlikely since it would require a lot of Forth code to get that far up in memory. If the memory map puts the disk buffers below the User variables, then it would be more appropriate to test against FIRST as the upper limit. This change has been made by replacing TIB with FIRST.

5. ?STACK – patched

Explanation and patch are from:

http://forum.6502.org/viewtopic.php?f=9&t=2187&start=32

?STACK is supposed to issue an error message if the stack is out of bounds.  But 6502 FIG Forth’s ?STACK is coded incorrectly. Here is the FIG version compared to a debugged version.

FIG : ?STACK  9E   SP@ U< 1 ?ERROR      9E is the TOS. Error 1 is Empty Stack

                SP@  20  U< 7 ?ERROR      20 is the BOS. Error 7 is Stack Full

NEW : ?STACK  SP@  9E  SWAP U< 1 ?ERROR   <– do not re-order to eliminate the SWAP !!

            SP@  20       U< 7 ?ERROR 

There’s an empty-stack test and a full-stack test. For the empty-stack test, FIG’s ?STACK begins by placing $9E on stack and then attempts to decide whether the stack is empty! That’s why the stack can actually underflow by one item and yet go unflagged. The new, corrected version calls SP@ first, so as to get the true picture.  The other parameter and the test are coded subsequently.

6. VLIST

 VLIST prints the last ASCII character of each name with bit 7 set.  This minor issue really isn’t a bug. It only occurs when the character-out routine you’ve installed fails to mask off bit 7 as required in the Fig spec.  XKEY includes clearing bit 7 to align with the standard

http://forum.6502.org/viewtopic.php?f=9&t=2197

Extensions

I have also integrated the full Bill Ragsdale 6502 assembler into the system. For more information on this assembler see http://www.forth.org/fd/FD-V03N5.pdf

I have also added a few words to make developing and saving Forth code on a KIM-1 system a little easier.

n U. – Prints the number (n) on the top of the stack as an unsigned integer

n1 n2 U.R – Prints the number n1 as a unsigned integer in a field of width n2

addr count DUMP – prints out count bytes starting at addr in rows of 8 bytes. Despite being documented in the FIG vocabulary this command was missing from the 6502 implementation.

MEMORY – displays the Bytes Used and Bytes Free

end start KIMDUMP – dumps the contents of memory from start to end in the KIM-1 papertape format which can be loaded in using the L command.

LOCK – updates the startup values for last word in dictionary, fence address, top of dictionary and vocabulary pointers.

4THDUMP – LOCKs the current compiled FORTH code and dumps the entire FORTH image in KIM-1 papertape format. This allows FORTH code to be compiled on the KIM-1 and then saved to be reloaded ready to run.

n +SHIFT – performs a logical left shift on the 16-bit value on the top of the stack.

n -SHIFT – performs a logical right shift on the 16-bit value on the top of the stack. Does not use the ROR instruction.

n BSWAP – swaps the bytes in the 16-bit value on the top of the stack.

Memory Model

The standard FIG-FORTH model places disk buffers and user variable in high memory and Forth definitions grow from low memory towards high memory. In the 6520 FIG-Forth implementation the upper memory boundary is hard coded and used in several places throughout the code. So, at this time, I created four versions representing different memory expansion starting at $2000 and stopping just short of the upper memory boundary to not interfere with any interrupt vectors or their mirrored addresses. In all cases, Cold start is at $2000 and Warm start is at $2004.

In the future I hope to create a version of 6502 Forth that is ROMable by splitting the memory space into volatile and non-volatile regions. Check back for future updates.

Development Environment

I have found with modern terminal emulators that allow you to easily download a file, one can develop Forth code on a KIM-1 reasonably effectively without any disk capabilities.

The first thing to do is slow down your download speed to give time for the Forth interpreter to keep up. I use RealTerm 3.0.1.45 and I have found setting the download character delay to 10ms and line delay to 1000ms works reliably well, even with long downloads.

I then create a short portion of Forth code in a text file using Notepad++, saving the file but leaving Notepad++ open. Then I download the file using the RealTerm “Send File” function. I can test the code, make any changes in Notepad++, click save file and then simply click on “Send File” in RealTerm again to download the corrections. Once I have a block of code working, I can merge it into a larger file of Forth source. I then FORGET all my test version, or simply do a Cold start and download the larger Forth application.