Neolithic Tiny Basic

Programming the 6502 microprocessor and its relatives in assembly and other languages.
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Neolithic Tiny Basic

Post by drogon »

barnacle wrote:
Well as a first cut, here it is. A couple of issues that I know about:
  • There are some combinations of values for which for/next never stops. Still investigating; I may rewrite the whole chunk.
  • Code to list single lines or group of lines still to be done
  • As far as I know, execution stops on an error, with a message, but does not yet list the line number
  • There is no 'oops' (e.g. ctrl-C) or warm restart

Code: Select all

; assemble with as65, http://www.kingswood-consulting.co.uk/assemblers/
; use: as65 tiny.asm -h0 -ltiny.lst -s2 -x -m
; (or remove -s2 for binary output)
;
; THIS BUILD FOR SYMON EMULATOR - check ACIA register locations
It builds to just under 4k, starting $e000.

Enjoy, please let me know if you find (or fix!) any bugs. It's explicit in the code, but, FreeBSD licence to avoid future worries.

Neil
Thanks. I'll have a look soon - however while he provides a version of as65 for Linux, it's a binary a very old 32-bit system as far as I can tell which renders it useless for me right now, so I'll have to look at using the ca65 assembler instead.

Cheers,

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: Neolithic Tiny Basic

Post by barnacle »

I have no issue running it, but it's possible I have the 32-bit libraries installed.

Converting to other assemblers should be reasonable (and may indeed be easier; they may have a way to deal with 16 bit absolute addresses which don't want to decay to 8 bits if they're less than 256). There is a potential gotcha: the assembler tries to optimise JMP to BRA if the target is in range; I'm not sure it always gets it right.

It's for 65c02 only, of course; too much (zp),y addressing.

Neil
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Neolithic Tiny Basic

Post by barrym95838 »

That's great, Neil! I have some ideas to save you a couple hundred bytes, but it makes little sense to optimize until it's working bug-free, and I'm not nearly as good at debugging as I am in code golfing. Maybe golfing it isn't even your goal, so I'll definitely hold off for now. I'm also not used to seeing macro names like INC and DEC that in normal cases would be valid 65c02 mnemonics. Case-sensitive for the win, I suppose ... ;-)
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: Neolithic Tiny Basic

Post by barnacle »

Yup, as I may have mentioned elsewhere, I'm no great fan of upper case, either for assembly or Basic. The assembler has a switch to make case insensitive, but here, if it's upper case it's a MACRO.

Not all the macros I define are used, I think; I pulled some out (the ones for the SMBx, which I don't use anywhere but which the assembler doesn't understand). For curiosity: is the (zp) mode a WDC specific instruction? It's very handy... this code would be much longer without it.

Neil
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Neolithic Tiny Basic

Post by barrym95838 »

AFAIK, the (zp) mode is available on all of the CMOS 65xx variations.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: Neolithic Tiny Basic

Post by barnacle »

Thanks, I've never used any of the others. Thinking about it, it's likely that they are, and that as65 is a generic cmos assembler that doesn't know about the wdc part (it doesn't understand the bit instructions, for example).

Neil
User avatar
BigDumbDinosaur
Posts: 9426
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Neolithic Tiny Basic

Post by BigDumbDinosaur »

barnacle wrote:
Thanks, I've never used any of the others. Thinking about it, it's likely that they are, and that as65 is a generic cmos assembler that doesn't know about the wdc part (it doesn't understand the bit instructions, for example).
Which bit instructions?
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Neolithic Tiny Basic

Post by GARTHWILSON »

barnacle wrote:
Thanks, I've never used any of the others. Thinking about it, it's likely that they are, and that as65 is a generic cmos assembler that doesn't know about the wdc part (it doesn't understand the bit instructions, for example).
See http://wilsonminesco.com/NMOS-CMOSdif/#sw
Quote:
Yup, as I may have mentioned elsewhere, I'm no great fan of upper case, either for assembly or Basic. The assembler has a switch to make case insensitive, but here, if it's upper case it's a MACRO.
IMO, rather than mix them, the better way to do it is that if it's three letters, like LDA or INC, it's an assembly-language mnemonic, whereas macro names are something other than three.

Getting that whole think in 4K is impressive though.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: Neolithic Tiny Basic

Post by barnacle »

BigDumbDinosaur wrote:
Which bit instructions?
BBRx, BBSx, SMBx and RMBx

In retrospect, using INC and DEC as macro names has the potential for confusion; I'll sort that after sorting the for/next issue. In my defence, it seemed like a good idea at the time, m'lud.

Just for info: the majority of the routines here take and return a sixteen bit parameter in Y:A; where two parameters are used, the first is pushed on the stack and referenced directly by abs,x instructions. Single byte parameters come and go in A; logic values are returned in C (carry set = true).

There are a couple of cases where tail recursion is used - a routine either drops through or jumps to the following routine rather than calling it, returning from it, an then returning directly. But only a couple...

The parsing keeps track of its position in the text of a line using 'mem_ptr' and 'look'; expression turns a string like '(a+b)*c' into a value by calling itself (indirectly; term, factor, expression) recursively so the opening brace causes first a+b to be evaluated, then multiplying by c, pushing and popping the result on the stack, and ending with the final result in Y:A.

Neil
User avatar
BB8
Posts: 57
Joined: 01 Nov 2020
Location: Tatooine

Re: Neolithic Tiny Basic

Post by BB8 »

I see that you chose "!=" as the operator for "not equal"; in Basic it's usually "<>". Anyway "!=" is more clear today.
User avatar
BigDumbDinosaur
Posts: 9426
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Neolithic Tiny Basic

Post by BigDumbDinosaur »

barnacle wrote:
BigDumbDinosaur wrote:
Which bit instructions?
SMBx and RMBx

WDC wasn’t the one that came up with those.  They were added by Rockwell subsequent to when WDC licensed them to produce the 65C02—they are described in Rockwell’s data sheet that was published in October 1984.

65c02_1984_rockwell.pdf
Rockwell 65C02 Data Sheet (Oct 1984)
(13.12 MiB) Downloaded 178 times

Rockwell had a particular interest in using the 65C02 with their line of modem chipsets and wanted to streamline the way in which bit-level processing could be done.  Hence the inclusion of BBR, BBS, RMB and SMB.  There is no mention of them in WDC’s 1990 data sheet.

65c02_1990.pdf
WDC 65C02 Data sheet (Feb 1990)
(2.32 MiB) Downloaded 189 times

During the early 1990s, when WDC converted the 65C02 to a static core and the geometry was reduced to 0.8µ, the Rockwell extensions were added to the 65C02 ISA, thus making them official.

Quote:
In retrospect, using INC and DEC as macro names has the potential for confusion; I'll sort that after sorting the for/next issue.  In my defence, it seemed like a good idea at the time, m'lud.

Even when an assembler has permitted it, I have avoided giving macros the same name as instructions or pseudo-ops.  That’s a computing train wreck just waiting to happen.  The one exception was when I was using Commodore’s HCD65 assembler on a C-128 to write 65C02 code.  I wrote macros to replace the ADC, LDA, etc., group of instructions so I could use the (<zp>) addressing mode, which was not supported by the assembler.  I also added macros to implement the new C02 instructions, such as BRA and TSB.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: Neolithic Tiny Basic

Post by barnacle »

BB8 wrote:
I see that you chose "!=" as the operator for "not equal"; in Basic it's usually "<>". Anyway "!=" is more clear today.
That was my thought; though I kept '=' for both equality and assignment. Both are easy to change in the token list; because it's tokenised, it comes out to the same token code in any case, but it's important to keep the comparison operators in the same order, or at least with the first and last the same. There is some testing that compares against the first and last.

Dr Crenshaw's parsing method makes it _very_ simple to handle what appear to be syntactic ambiguity like that. Equally, there's no problem making the listing upper case instead lower (though I think there's a line that lower-cases the token matching which would need changing).

Neil
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: Neolithic Tiny Basic

Post by barnacle »

Curse this lying in bed of a morning, unable to either go back to sleep or properly wake up...

Upon contemplation, I think both for/next and do/while need looking it. Do/while is working as expected, but I'm not sure if it's what I want, and for next is broken.

The main difference between the two is that do/while doesn't include a loop variable nor auto-increment of it, and always executes at least once, while for/next (broken on mine) includes a loop variable which is auto-incremented. I think that therefore for/next should always do _at least_ one iteration, irrespective of start values; the completion test should be at the end of the loop.

But as do/while also executes at least once, it defeats its own purpose; I think I shall replace it with while/endwhile which tests before execution and permits a zero-pass operation.

Neil
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Neolithic Tiny Basic

Post by BigEd »

(Perhaps notably, the BBC's request for a modern structured Basic included a while..endwhile, but between the proposal and the implementation it became a repeat..until, I would say very probably because of implementation concerns. Hopefully a useful point of reference - not intending to derail your dev thread!)
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: Neolithic Tiny Basic

Post by barnacle »

Curious - the repeat/until would be logically the same as my existing do/while; the test is at the end of the loop (as it is with for/next).

While/endwhile has the test at the beginning of the loop, of course.

Neil

(not derailed at all; all input is welcome!)
Post Reply