I've started port of Microsoft Basic V2 for developing computer Cerberus 2100.
It's totally open project that will be available for manual builds or for manufacturing by companies(there're no limitations). It have TWO main CPUs - Z80 and 65C02.
If Basic interpreter for Z80 CPU already exists(it was creates for prev. iteration of this computer - Cerberus 2080) - BBC Basic by Dean Belfield (aka Break Into Program). But 6502 part was without basic and I've tried make port.
I had no 6502 experience before but I've tried and when I've got running and stable working in emulator basic - I've got no power to stop myself and started extending it.
LOCATE, low resolution graphics(
LINE) and some other extensions and when I've started adding tiles(or user defined graphics) support - I've found that after adding additional command basic freezes on parsing code.
I've found that token table limited with indexed addressing(using register Y - just 255 bytes maximum, including ending zero-byte).
I had no plans extend basic to spaceship but I've wished have possibility add some tokens for simplifying usage for end users. So I've found solution and patched basic - about it in next part of article.
I will talk around my fork of this repo.
I think this method will be acceptable for any basic for 6502 that based on Microsoft Basic.
Important point to understand - I don't want limitless tokens, I just need a bit more but this method allows use twice larger table(up to 512 bytes).
It located in
program.s file. Most simple way locate it - label
L2496. Here located
iny instruction - increments register Y. This register used for reading token name table.
In nearest code we'll see:
It's used for comparing current character from input buffer and from token table.
What we should do? Introduce variable that will store flag of usage additional page of tokens and swap tables when increment will overflow register.
iny instruction will be replaced with call of this subroutine:
sbc TOKEN_NAME_TABLE, y
sbc TOKEN_NAME_TABLE+$100, y
For stable work this routine we need just a bit more - single preparation. In routine labeled
L248C we should found
dey instruction(just before
stx TXTPTR) and store Y value(it will be here $ff) to our
Just because in
L2496 we'll call our increment routine and Y register will be zero and we'll switch to our initial token page.
Our next station is label
L24DB. It's linked routine that looks for next token in our table.
iny will be replaced with
increment_token_list call. But what we see next? Some kind of black magic with
MATHTBL+28+1. It looks awful but honestly it's just
TOKEN_NAME_TABLE - 1 address.
So, we should replace this
LDA MATHTBL+28+1,y with routine that will read byte from our token name tables with offset
LDA TOKEN_NAME_TABLE,y with direct reading.
;; Reads byte from one of the tokens table
lda TOKEN_NAME_TABLE, y
lda TOKEN_NAME_TABLE+$100, y
;; Reads prev. byte from token table
lda TOKEN_NAME_TABLE-1, y
lda TOKEN_NAME_TABLE+$ff, y
After replacement increment and couple of load statement this part of code will look like:
Now it parses, but
LIST command crashes. And fix for it will be dead simple.
Look for label named
L25F2 and just before it store Y register to our
EXTRA_TABLE_FLAG variable(for selecting on first increment our initial table start).
Next you'll see couple times this lines of code(labels
They should be replaced with:
Well, now we got working parser and list command.
And everything executes.
But how to add myown token to Basic?
If you want add your own command to basic you should use
keyword_rts macros and add your new keyword to
tokens.s file. Just before
For example it can look like:
keyword_rts "CLS", clear_screen ;; Just call our BIOS/KERNEL code for cleaning screen
keyword_rts "LOCATE", LOCATE
keyword_rts "PSET", PSET
keyword_rts "LINE", DRAW_LINE
keyword_rts "TILEDEF", DEF_TILE
keyword_rts "TILE", TILE
Usually it's just classical assembly routine. If you'll need work with parameters - you can easily find required routines in other tokens code(for example,
GETBYT - eval current argument to number that will be for 0 to 255,
CHKCOM - check that next will be comma).
Simple commands can look like:
lda #<commit ;; Here located string contains that basic built
ldy #>commit ;; from commit XXXXXX
Happy hacking! Use it for good of all beings!