Page 4 of 15
Re: Neolithic Tiny Basic
Posted: Tue Feb 04, 2025 12:20 pm
by Yuri
p.s. shame the 6502 doesn't have a complement carry instruction...
Maybe something like so?
Code: Select all
is_alpha:
ora #$20
cmp #$7B
ror
eor #$80
rol
rts
EDIT: I'll get the right values in there sooner or later... @_@
Blah, still flawed with values less than 'A', feel like you don't need 4 compares tho....
Here we go, few more tweaks:
Code: Select all
is_alpha:
cmp #'A'
bcc not_letter
ora #$20
cmp #$7B
ror
eor #$80
rol
not_letter:
rts
I presume you want carry set if it is a letter, and clear if not.
Re: Neolithic Tiny Basic
Posted: Tue Feb 04, 2025 1:03 pm
by barnacle
First make it work, then make it smaller/faster/prettier/more elegant!
Neil
p.s. my initial take covered all the 'is' routines with a 96-entry table with the appropriate bits set for isalpha, isspace, isupper etc but it turns out smaller this way; most of the options aren't actually required.
p.p.s.
Code: Select all
isalpha:
ora #$20 ; make it lower case
cmp #'a'
bcc is_no
cmp #'z' + 1
bcc is_yes ; it's alpha
might be a quick optimisation.
Re: Neolithic Tiny Basic
Posted: Tue Feb 04, 2025 4:36 pm
by barrym95838
I think you may be flirting with the optimal ASCII solution Yuri, but I don't have time to assist right now ... dumb job always ruining the fun!
Re: Neolithic Tiny Basic
Posted: Tue Feb 04, 2025 4:55 pm
by barnacle
I think Yuri's approach will work, but I already have is_yes and is_no for other 'is...' tests close to this one.
Neil
Re: Neolithic Tiny Basic
Posted: Tue Feb 04, 2025 5:11 pm
by Yuri
...dumb job always ruining the fun!
They can be pesky like that.

Re: Neolithic Tiny Basic
Posted: Wed Feb 05, 2025 7:52 am
by barnacle
It looks as if assignment of both variables and the string $ are now working. That enabled me to continue and I think complete print, which includes unformatted and column-aligned variables, and the string $ and a zero-based index $ which prints the ith character of $.
That's pretty much all of the immediate commands finished. Now for the hard bit...
Neil
Re: Neolithic Tiny Basic
Posted: Fri Feb 07, 2025 9:33 pm
by barnacle
We have some progress.
I can enter and list a program, in any order, and delete or replace existing lines correctly.
I can print complex expressions in immediate mode (i.e. without a line number) and assign them to a numeric variable.
Ditto for setting the string variable and printing it either as a whole or printing an indexed character therein.
I can run a program... provided it uses only assignment or printing (all I've written so far), and with an odd bug: a second assignment doesn't seem to assign. More investigation required.
Neil
edit: ah, it's not doing assignments at all, if running. Should be easier to find. They work fine in immediate mode.
Re: Neolithic Tiny Basic
Posted: Sat Feb 08, 2025 7:16 am
by barnacle
Well that was easy. I didn't use the formal 'let' for assignment, and the default of not using 'let' is handled by code which calls assignment and not by assignment itself. And while I had written that test (if the line starts with alpha, call assignment) in the immediate mode, I hadn't yet got around to it in the execution loop.
Oops
Next steps: add that default handling, then start on the loop constructs.
Neil
(it is remarkable both how easy and how frustrating it is to translate a working C program by hand, as it were. I _know_ that the logic is correct, but I still make silly errors like forgetting an # in an instruction. And some of the primitives appeared to work the first time around but turned out to have subtle flaws - see the discussion of 'isalpha' recently.)
Re: Neolithic Tiny Basic
Posted: Sat Feb 08, 2025 11:05 am
by barnacle
1) ' (rem) works
2) end works
3) goto works
Now everything else needs an equivalence routine, so I'd better get on with that. I just excised a load of helper code, which isn't required now I'm using Symon, and the current code size is 3084 bytes.
Neil
Neil
Re: Neolithic Tiny Basic
Posted: Sat Feb 08, 2025 11:31 am
by drogon
1) ' (rem) works
2) end works
3) goto works
Now everything else needs an equivalence routine, so I'd better get on with that. I just excised a load of helper code, which isn't required now I'm using Symon, and the current code size is 3084 bytes.
Not bad!
-Gordon
Re: Neolithic Tiny Basic
Posted: Tue Feb 11, 2025 9:41 pm
by barnacle
Finally got gosub working:
That took a long time to debug... this while statement originally had an issue in that depending on the values of Y and A it might fail to pull one of them from the stack, so the bug appeared depending exactly on the basic code I wrote.
Code: Select all
; while ((NULL != where) && (ERR_NONE == err));
lda err
bne gos_99 ; ERR_NONE == 0 so bne = an error
pla
sta maths1
ply
sty maths1+1 ; where is now in maths1
ora maths1+1 ; NULL?
beq gos_99 ; yup, break
lda maths1 ; Y:A should have 'where'
phy
pha
jmp gos_1
Can't help feeling there's a way to check that Y:A isn't zero without killing one or the other, or as I've done here, used a spare pair of variables. (gos_1 is above this and contains the bit where a line is interpreted by the gosub routine).
It might be that I can refactor the C version to check things in different places...
Neil
Re: Neolithic Tiny Basic
Posted: Thu Feb 13, 2025 4:25 pm
by barrym95838
p.s. shame the 6502 doesn't have a complement carry instruction...
Maybe something like so?
Code: Select all
is_alpha:
ora #$20
cmp #$7B
ror
eor #$80
rol
rts
EDIT: I'll get the right values in there sooner or later... @_@
Blah, still flawed with values less than 'A', feel like you don't need 4 compares tho....
I haven't tested it yet, but I think we can do it with one compare (please correct me if I whiffed on any of the magic constants):
Code: Select all
isalpha:
pha ; (optional)
ora #$20 ; xlate upper to lower
clc
adc #$85 ; 'z' should be $ff now
cmp #$e6 ; only 7-bit ASCII alphas should set carry
pla ; (optional)
rts
P.S. Here are a few more, untested of course:
Code: Select all
islower:
pha ; (optional)
clc
adc #$85 ; 'z' should be $ff now
cmp #$e6 ; only 7-bit ASCII lowers should set carry
pla ; (optional)
rts
isupper:
pha ; (optional)
clc
adc #$a5 ; 'Z' should be $ff now
cmp #$e6 ; only 7-bit ASCII uppers should set carry
pla ; (optional)
rts
isdigit:
pha ; (optional)
clc
adc #$c6 ; '9' should be $ff now
cmp #$f6 ; only 7-bit ASCII digits should set carry
pla ; (optional)
rts
isxdigit:
pha ; (optional)
clc
adc #$c6 ; '0' = $f6 ... '9' = $ff
cmp #$f6 ; only 7-bit ASCII digits should set carry
bcs isxdigit9
ora #$20 ; xlate upper to lower
adc #$d3 ; 'a' = $fa, 'f' = $ff
cmp #$fa ; only 'A' - 'F' or 'a' - 'f' should set carry
isxdigit9:
pla ; (optional)
rts
P.S. Bah, I got a little too big for my britches on isxdigit ... it looks like it's going to treat ctrl-P to ctrl-Y as valid hex digits unless I rearrange slightly ... done, I reckon.
Re: Neolithic Tiny Basic
Posted: Thu Feb 13, 2025 8:43 pm
by barnacle
Hmm, seven bytes instead of ten; it's worth looking at, thanks.
Um - what happens to $00 to $40?
Neil
Re: Neolithic Tiny Basic
Posted: Thu Feb 13, 2025 8:51 pm
by barrym95838
Um - what happens to $00 to $40?
They should clear the carry if I'm not horribly mistaken.
$40 | $20 = $60
$60 + $85 = $e5
$e5 < $e6, clears carry
(I think I might have an off-by-one in my magic constants ... if I get it figured out during my lunch break I'll correct my code above ... done.)
Re: Neolithic Tiny Basic
Posted: Thu Feb 13, 2025 10:03 pm
by barnacle
Yeah, I'll check later. Trying to quantify a year's incomings and outgoings at the moment
Neil