User Tools

Site Tools


sd-8516_stellar_basic_v1.0

This is an old revision of the document!


SD-8516 Stellar Basic V1.0

Dennis Allison’s 1975 article in Dr. Dobb’s Journal was a key moment in the history of Computer Science. It contained a formal specification of Tiny BASIC, a BASIC that could be implemented in less than 4 KB.

Stellar BASIC is very much in the same vein as Tiny BASIC, and is intended to evolve over time. However, Tiny BASIC itself is only a specification. One way is to compile a list of IL (intermediate language) statements. Once you have the IL interpretation you compile it and interpret it from there. On a machine with limited ram this approach can require up to 50% of the memory of a standard BASIC program. This is problematic. So machines like the C64 tokenized the statements on entry and executed them that way. The other issue with IL is that you have this compiled version and you also have the text lying around. That's two copies of the program. Which one is the 'real' program? If you remove the original text you can't necessarily LIST your code. Therefore, tokenization was settled on as a standard.

Therefore, when it came time to compile the IL into a program we instead chose a C64 style tokenization, and added $99 as PRINT as a subtle homage to the adventure, the love, and the magic of the C64 era.

Core features

  • Line-numbered programs
  • LET (often optional)
  • PRINT
  • INPUT
  • IF-THEN
  • GOTO
  • GOSUB and RETURN
  • FOR-NEXT
  • Usually only access to integer variables and integer based math
  • Single letter variables (ex. A, B, Z)
  • No floating-point math
  • Very limited strings
  • No arrays
  • No file I/O
  • Minimal error messages
  • Very limited editing commands

Some versions stored programs as text, some as tokenized program code to save space.

Notable Tiny BASIC implementations

  • Palo Alto Tiny BASIC (Dennis Allison)
  • Li-Chen Wang’s Tiny BASIC
  • 6800 Tiny BASIC
  • NASCOM Tiny BASIC
  • Apple I BASIC (inspired by Tiny BASIC ideas)
  • Micro-Soft 8080 BASIC (larger, but influenced by Tiny BASIC work)

Stellar Basic is based on the intermediate language specs for Pao Alto Tiny Basic, written by Dennis Allison in 1975.

Example BASIC program

10 LET A = 1
20 PRINT A
30 A = A + 1
40 IF A <= 10 THEN GOTO 20
50 END

Stellar BASIC will allow this even shorter form:

10 A=1
20 ?A
30 A=A+1
40 IF A<=10 GOTO 20

(? is shorthand for PRINT.)

Implementation Diary

Stack-based design

Everything in PATB is stack-based. This is a core design principle. There are three stacks:

  1. Expression Stack - Arithmetic evaluation
    • “5 + 3 * 2” is “push 5”, “push 3”, “push 2”, “multiply” (pop 2 values, push result), “add” (pop 2 values, push result).
  2. GOSUB Stack - Subroutine calls
    • “GOSUB 1000” – push current line number, jump to 1000
    • “RETURN” – pop line number, jump back
  3. FOR Stack - Loop context
    • “FOR I=1 TO 10” – push (I, 10, 1)
    • “NEXT I” – peek stack, increment I, check if done, pop if finished

The Plan

The plan was to implement the IL as a service library so it could be used by other languages later on too.

  • Phase 1: Variable management (3 functions: get, set, clear_all)
  • Expression stack (4 functions: push, pop, peek, clear)
  • I/O & String Helpers (ex. IO_GETNUM)
  • String comparison, number parsing (ex. STR_SKIP_SPACE)
  • Phase 2: Stack Operations
  • GOSUB/RETURN stack (3 functions)
  • FOR/NEXT stack (4 functions)
  • Phase 3: Program Line Management
  • Find line by number
  • Insert/delete lines
  • Navigate through program (first line, next line)
  • Program storage with line markers (opcode 251)
  • Phase 4: IL Interpreter Core;
  • Design IL bytecode table (~30-40 IL opcodes)
  • Command tokenizer (major hurdles to pass – this was hard)
  • IL fetch/decode/execute loop
  • Expression evaluation using the stack
  • Control flow (GOTO, GOSUB, IF/THEN, FOR/NEXT)
  • Phase 5: BASIC Commands
  • PRINT, INPUT, LET
  • RUN, LIST, NEW, CLEAR
  • Integrate with term.ts to highlight a “Boot-to-basic” experience.
  • Phase 6: Testing & Polish
  • End-to-end BASIC program tests
  • Error handling and status messages
  • Bug fixes
  • Performance tuning

Up until around Phase 4 things were going fine. Oh, how naieve I was. After I finished and tested the IL, a work in itself, I began to have a lot of trouble getting the tokenizer and execution loop to work together. After weeks of tracing through the code I decided to remove the tokenizer. At that point I was able to pinpoint the last 3 or 4 core bugs and fix them. It finally worked! It's amazing, you know, to see these things being brought up from scratch.

Implementing GOTO

in basic_execution_loop the ELM pointer is stored via push-pop since many operations such as PRINT will modify it. The thing is, ELM is also our current-line pointer. So I created a PATB_GOTO_POINTER and every execution loop I check if it is zero or has a number. If it has a number I pull that line instead of NEXT_LINE. Simple! I thought about trying to use a different pointer, but this was the easiest and fastest solution. I take heart in that I seem to have avoided going down the rabbithole of premature optimization on this one. As long as I can keep making steady progress like that things should be ok.

Implementing BREAK

A rather simple thing, I just checked for a keypress every run loop.

  ; Check for ESC key
  LDAH $00                ; Read char (non-blocking)
  INT $10
  JZ @continue            ; ZF=1 = no key
  CMP AL, #27             ; ESC?
  JNZ @continue
  ;; print break message and RET

How PATB spec became Stellar BASIC

During the implementation phase I made several by-the-way changes to PATB in order to support a more advanced integration with the SD-8516. I added LINE_FIND_REVERSE and LINE_PREV as well as LINE_MAKE_SPACE and LINE_REMOVE_SPACE for line management. I am not sure how PATB does those things. I worked from example code and the specs but I did not really understand what I was doing. After the tests for the IL implementation passed I added string helpers. All of these have been moved into INT 12h now.

I had so much trouble with the tokenizer I decided to ditch it. It was just added complexity. I can add one in later by allowing short form commands. No biggie.After I finally got the execution loop working I got GOTO working then focused on printing immediate mode strings. I will need to code an expression parser next and I am not sure where to start. Back to the docs?

sd-8516_stellar_basic_v1.0.1771389545.txt.gz · Last modified: by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki