0% found this document useful (0 votes)
103 views

Implementing FORTH On My 6502 Computer - Export

The document describes the author's implementation of the FORTH programming language on their 6502 breadboard computer. It provides background on the 6502 architecture including registers, addressing modes, and stack. It then details the author's FORTH implementation, including how it uses the zero page for a data stack and dictionary, and how words are executed via an inner and outer interpreter using direct threaded code. It notes current features and limitations before concluding with an invitation to demo the FORTH system.

Uploaded by

A dum
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
103 views

Implementing FORTH On My 6502 Computer - Export

The document describes the author's implementation of the FORTH programming language on their 6502 breadboard computer. It provides background on the 6502 architecture including registers, addressing modes, and stack. It then details the author's FORTH implementation, including how it uses the zero page for a data stack and dictionary, and how words are executed via an inner and outer interpreter using direct threaded code. It notes current features and limitations before concluding with an invitation to demo the FORTH system.

Uploaded by

A dum
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

Implementing FORTH

on my 6502 computer

Alexandre Dumont #FORTH2020


@adumont Dec, 11th, 2021
Content
● Introduction
○ Motivation
○ My 6502 breadboard computer
● 6502 basics
○ Registers, ZP, Stack
○ Addressing Modes
● My FORTH Implementation
○ Dictionary, Inner interpreter, Data stack
○ Development methodology
○ Features & current limitations
● Quick Demo
Motivation

● Enjoy!
● Learn something new
○ 6502 assembly
○ FORTH internals
○ Eventually learn some FORTH
● Make my 6502 computer usable
My 6502 computer Clock ACIA

Data bus
● WDC 65c02s
● 1.8432 MHz crystal oscillator (clock)
● 32KB EEPROM, 16KB SRAM 6502 RAM ROM
Addr bus
● 6551 ACIA (serial port) ← User interface
● 6522 VIA (Versatile Interface Adapter) ≈ GPIO
● 20x4 LCD display
● No keyboard, no VGA display

● EEPROM Programmer: VIA

ROM
A computer... in need of some software

● I began coding simple 6502 assembly programs:


○ From simple registers manipulation to writing a “Hello World” on the LCD display

● I developed my own ROM monitor:


○ Read/write to memory (or I/O)
○ Jump to code at a specified address
○ Return to monitor on BRK and then resume
○ Dump and Edit registers

Around that time (April 2021) is when I then discovered the FORTH language
6502 basics*

*Relevant to my FORTH implementation ;-)


6502 Registers

● 8 bits CPU, 16 bits wide address bus

● It can address 64KB of memory space


(RAM+ROM+I/O devices)

● 8 bits registers:
○ A: Accumulator: general purpose, ALU
○ X, Y: indexes, used in addressing modes
○ S: Stack pointer ($01xx)
○ P: processor flags
● PC: program counter (16 bits)

● Zero Page ($00xx): 1 byte address! Can act


as 16 bits registers in complex addressing
modes
6502 hardware stack

● Resides in memory page 1: $0100:$01FF ● Instructions to push/pop 8 bit registers


on/off the stack:
● Register S is a pointer into the stack ○ pha / pla
○ $0100+S is the next available location in the ○ phx / plx, phy / ply (*)
stack memory area ○ php / plp

● The stack is used by the 6502:


○ Calls to subroutines (store return address)
○ Responding to interrupts (store status
register and return address)
* 65c02 specific instructions
6502 addressing modes (1)

● Zero page indexed with X or Y zp,X /zp,Y

Example: LDA $B0,X


Loads content of address $00B0+X ($00B2)
into A.

(Later we’ll see we use this to address our FORTH


data stack)
6502 addressing modes (2)

● Zero page indirect indexed with Y (zp),Y

Example: LDA ($B2),Y


Take what’s in:
$00B2 → low byte: 00
$00B3 → high byte: D1
And forms the base address: $D100

Then loads the byte at $D100+Y into register A.

● Also: Zero page indirect (unindexed) (zp)


Implementing FORTH

(My own implementation)


What did I need to implement a minimal FORTH?

● A minimum set of words ● And to make it interactive:


→ a dictionary ○ An outer interpreter
○ A way to lookup words in the
● A minimal program to be run: dictionary
→ a “thread” ○ A way to compile new words

● A way to read and interpret the


program, ie. move along the thread:
→ the inner interpreter ● Design choices
○ DTC: Direct Threaded Code
● A data stack and a return stack ○ 16 bits cells
Dictionary

ENTER EXIT
Data Stack
● The Data Stack is build using Zero Page. It starts
at the top of ZP (just below the FORTH registers
W, IP, G1 and G2), and grows downwards.

● Accessing the Data Stack is easy using the


Zero Page Indexed with X addressing mode

● 0,X & 1,X → next free cell of Data Stack


● 2,X & 3,X → cell at Top of the Stack

● Pushing a cell on the stack: storing the Low byte


at 0,X, and the high byte at 1,X, and then
decrementing X twice (DEX).
● DROP is simply two inx
Inner Interpreter

● Two Registers:
○ IP: (next) Instruction Pointer
○ W: (current) Word Address

● Routines:
● NEXT
● ENTER (“COLON” in my implementation)
● EXIT (“SEMI” in my implementation)
Inner Interpreter - NEXT
● NEXT does 3 things:
○ (IP) --> W IP: (next) Instruction Pointer
○ IP+2 --> IP W: (current) Word Address
○ JMP (W)

NEXT:
; (IP) --> W
LDA (IP) ← Zero page indirect (unindexed)
STA W
LDY #1
LDA (IP),y ← Zero page indirect indexed with Y
STA W+1
; IP+2 --> IP
CLC
LDA IP
ADC #2
STA IP
BCC @skip
INC IP+1 ENTER EXIT
@skip:
JMP (W) ← Absolute indirect Dictionary representation of “,”
Inner Interpreter - ENTER
W

defword "ENTER",,
; push IP to Return Stack
LDA IP+1 ; HI ← I use the HW stack
PHA
LDA IP ; LO as FORTH return stack
PHA
; W+3 --> IP
; (Code at W was a JMP)
CLC
ENTER EXIT
LDA W
ADC #3 IP ← W+3
STA IP
LDA W+1
ADC #0
STA IP+1
JMP NEXT Jump to NEXT
Inner Interpreter - EXIT

defword "EXIT",,
; POP IP from Return Stack
PLA
← I use the HW stack for
STA IP
PLA FORTH return stack
STA IP+1
; JMP NEXT
JMP NEXT ← Jump to NEXT
(My) Development Methodology

● Iterative: start small and grow incrementally

● First test in emulation:


○ I started with Kowalsky 6502 emulator
○ Then I build my own tools in Python with py65
emulator library

● Then test on hardware:


○ Slow and cumbersome: rom flashing, replace the
rom chip
○ Fragile: lots of cables, and breadboard not ideal
(I should learn how to do a PCB)

● Commit everything on Github


My 6502 emulator for developing Alex FORTH for the Cerberus2080
My FORTH Features (for now)
● : ; EXIT
● JUMP EXEC
● IF ELSE THEN
● DO LOOP +LOOP LEAVE
● BEGIN AGAIN, BEGIN UNTIL, BEGIN WHILE REPEAT
● VARIABLE and Local Variables
● MARKER FORGET
● CREATE DOES>
● Comments \ and ( )
● WORDS, HIDE, REVEAL, HIDDEN, RECURSIVE
Limitations (at the moment)

● Doesn’t adhere to any standard


● Only Integer numbers (no floating points)
● Only Hexadecimal representation (no BASE/conversions)
● No stack overflow/underflow verification. Easy to crash!
● Only one dictionary (no contexts)
● Case sensitive words, all predefined words are capital case
● No mass storage, no block feature, no save/restore
Demo time!
Links & how to contact me

My site: https://adumont.github.io/
My FORTH:
● Alex FORTH for 6502 Breadboard Computer
○ Test it in your browser (py65 emulation)

● Alex FORTH for the Cerberus2080 (6502)

Twitter: @adumont
Thank you!

You might also like