6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 10, 2024 7:24 pm

All times are UTC




Post new topic Reply to topic  [ 28 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Mar 03, 2024 3:17 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
While some of you were talking about the tiniest Tiny BASIC, I have been busy paraphrasing TSC Micro BASIC Plus to the 6502.

https://ia903409.us.archive.org/34/item ... asic_a.pdf

It is a relatively powerful integer BASIC running on the SWTPC 6800 computer. It was designed to be loaded from tape. User programs may be saved or loaded by escaping to the system monitor and using its "punch" and "load" capabilities, then warm starting back into the interpreter.

I am happy to be able to report that enough progress has been made that it is an ongoing project instead of a speculative experiment.

The following features have been implemented:

* Enter, list, delete and replace program lines
* Run program
* Print a number, variable or a constant text string (it does not support string variables)
* Assign a number or a variable to a variable including "implied" LET
* GOTO, GOSUB, RETURN, ON GOTO and ON GOSUB

I am currently working on FOR and NEXT.

Features still to be implemented:

* Most of expression handling including operators and the functions RND, ABS and SGN
* DIM for arrays
* IF
* DATA, READ and RESTORE
* INPUT

The original 6800 version utilizes self-modifying code in several places so it cannot reside in ROM. I do not do any of that.

Micro BASIC Plus allows use of a variable or expression as the target of a GOTO or GOSUB. You can write code like:
Code:
100 A = 1000
200 GOTO A
300 END
1000 PRINT 1000

As far as I know, no other BASIC can do this. Not even Microsoft.


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 03, 2024 3:26 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
This line was kind of funny:
"Spaces are not permitted i nternal to numbers or keywor ds but may be used freel y el sewhere."


BillG wrote:
Micro BASIC Plus allows use of a variable or expression as the target of a GOTO or GOSUB. You can write code like:
Code:
100 A = 1000
200 GOTO A
300 END
1000 PRINT 1000

As far as I know, no other BASIC can do this. Not even Microsoft.

I had to check the reference manual for my HP-71's BASIC.  It does not have that, but I normally used labels anyway rather than line numbers, and for a GOTO's label identifier, you can use anything that evaluates to a string.

_________________
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?


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 03, 2024 4:27 am 
Offline
User avatar

Joined: Fri Jan 26, 2024 5:47 am
Posts: 40
Location: Prague; Czech Republic; Europe; Earth
BillG wrote:
As far as I know, no other BASIC can do this. Not even Microsoft.


BBC Micro BASIC had it and when I was lookin for it online, I found this manual

https://www.4corn.co.uk/archive/docs/BBC%20BASIC%20Reference%20Manual-opt.pdf see here, on page numbered 84 (95. page of the PDF, but it is counting preface and index too)

Quote:
GOTO instructions send the control of the program either forwards or backwards
The specified line number may be given as an expression For example

10 Start:% = 100
20 GOTO (start%+10)
30 PRINT " This line should not be executed "
100 REM start of the action
110 PRINT " Hello"
120 END

Using a variable, however, as the destination for a GOTO is not recommended
because while RENUMBER changes the line numbers. it does not alter GOTO
destinalions that are given as anything other than a simple number. lf you must
use an expression. it is best to put in inside brackets since BASIC may get
confused if the expression starts with a number.

_________________
http://micro-corner.gilhad.cz/, http://8bit.gilhad.cz/6809/Expanduino/Expanduino_I.html, http://comp24.gilhad.cz/Comp24-specification.html, and many others


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 03, 2024 5:21 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8480
Location: Midwestern USA
GARTHWILSON wrote:
BillG wrote:
Micro BASIC Plus allows use of a variable or expression as the target of a GOTO or GOSUB. You can write code like:

Code:
100 A = 1000
200 GOTO A
300 END
1000 PRINT 1000

As far as I know, no other BASIC can do this. Not even Microsoft.

I had to check the reference manual for my HP-71's BASIC.  It does not have that, but I normally used labels anyway rather than line numbers, and for a GOTO's label identifier, you can use anything that evaluates to a string.

Most dialects of business BASIC from the later 1980s and onward, such as the Thoroughbred Dictionary-IV environment in which I’ve done a lot of development, allow the use of labels as GOTO and GOSUB targets.  Writing GOSUB PRINT is not only more informative than writing GOSUB 1000, it’s faster-executing.

Thoroughbred, in particular, builds several alphanumerically-sorted symbol tables at the end of the program text, one of which is a lookup table for statement labels—these tables are saved as part of the program, so they only get built while entering/editing program code.  When a GOSUB PRINT statement is encountered, the Thoroughbred P-code engine does a binary search on the statement symbol table.  Needless to say, that is a much faster process than in a typical micro-BASIC interpreter that has to scan program text to find a line number.  If in a Thoroughbred program, the statement GOSUB 1000 is encountered, the P-code engine has to search the program text for the actual line number, which perceptively slows down a program that makes a lot of such calls.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 03, 2024 5:34 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1485
Location: Scotland
BillG wrote:
Micro BASIC Plus allows use of a variable or expression as the target of a GOTO or GOSUB. You can write code like:
Code:
100 A = 1000
200 GOTO A
300 END
1000 PRINT 1000

As far as I know, no other BASIC can do this. Not even Microsoft.


It's pretty standard in TinyBasics - my own one works like this too. Here is a example from my xmas tree lights on the 6507:

Code:
2IF L<0 OR L >17 RETURN
3GOTO10+L

5IF L<0 OR L >17 RETURN
6GOTO30+L

REM On

10?A=?A OR&10:RETURN
11?A=?A OR&01:RETURN
12?A=?A OR&40:RETURN
13?A=?A OR&08:RETURN

14?A=?A OR&04:RETURN
15?A=?A OR&02:RETURN
16?A=?A OR&20:RETURN
17?A=?A OR&80:RETURN

18?B=?B OR&80:RETURN
19?B=?B OR&02:RETURN
20?B=?B OR&10:RETURN
21?P=?P AND&F1OR&0E:RETURN

22?B=?B OR&04:RETURN
23?B=?B OR&40:RETURN
24?B=?B OR&20:RETURN
25?B=?B OR&08:RETURN

26?P=?P AND&1EOR&E0:RETURN
27?B=?B OR&01:RETURN


It works in the main program as:

Code:
  L = 5 : REM Set Lamp 5 ON
  GOSUB 2


-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 03, 2024 11:43 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
Got bogged down in NEXT as it makes use of the ADD and SUB parts of the complex and voluminous expressions and operators package.

Took a detour and implemented INPUT then DATA, READ and RESTORE.

The Micro BASIC Plus rendering of DATA statements is quite different from other BASICs.

In most of the others, all of the DATA statements within a program are treated as if they were one data pool.

Micro BASIC Plus remembers the most recently encountered DATA statement as the "current" data pool. An error results if READ is used before any DATA statement has been encountered. Reading more values than exists in the current statement restarts at the first item in the statement. RESTORE also sets the next READ to get that first item.

It is not clear why it was done this way. Existing code to search the program for a line number can be easily modified to search for DATA statements. Maybe they were tight on code space and could not afford that.

The only advantage I can see is that data can be localized to the code which uses it. Some other BASICs allow specifying a line number with the RESTORE statement to indicate where the next READ picks up. That would be an equivalent way to do the same thing.


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 04, 2024 1:07 am 
Offline

Joined: Mon Sep 17, 2018 2:39 am
Posts: 138
Hi!

BillG wrote:
Micro BASIC Plus allows use of a variable or expression as the target of a GOTO or GOSUB. You can write code like:
Code:
100 A = 1000
200 GOTO A
300 END
1000 PRINT 1000

As far as I know, no other BASIC can do this. Not even Microsoft.


This is standard in Atari BASIC, where you even see code like GOTO STICK(0)*10+200 for processing the joystick. In Atari BASIC each number is encoded in 6 bytes, so doing "L1000=1000" and then multiple "GOTO L1000" used less memory, this technique was used in a lot of BASIC games.

Have Fun!


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 05, 2024 9:49 pm 
Offline

Joined: Tue Oct 24, 2017 1:08 am
Posts: 10
Apple integer BASIC (and, I assume Apple 1 basic which it was derived from) allows this as well.


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 06, 2024 1:37 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
Thank you for enlightening me as to which BASICs also allow specifying a target with a variable expression.

Now why do some prohibit that? Clearly it is slower than an absolute line number. Why not just document that fact and allow it anyway?

The compiler writer in me says that compiling a variable target is much more difficult. Essentially, a list of the addresses corresponding to the set of line numbers much be stored and searched when the jump is made.

By the way, FOR/NEXT now works for the simple case. More testing is needed. I can see the finish line from here...


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 06, 2024 7:59 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1485
Location: Scotland
BillG wrote:
Thank you for enlightening me as to which BASICs also allow specifying a target with a variable expression.

Now why do some prohibit that? Clearly it is slower than an absolute line number. Why not just document that fact and allow it anyway?


I suspect it's explicitly tested for - ie. when you parse a GOTO/GOSUB then you either look for a number explicitly, or almost lazily just call your generic expression evaluator to get that number. Once you have then number the rest of the processing is the same.

And if you can GOTO an expression then it eliminates the need for ON x GOTO a,b,c ...

Or conversely if you really want ON x GOTO, then deliberately block GOTO expression...

Quote:
The compiler writer in me says that compiling a variable target is much more difficult. Essentially, a list of the addresses corresponding to the set of line numbers much be stored and searched when the jump is made.


But in BASICs you have a generic expression evaluator, so you save space by just calling it to get the number. There are very few BASICs that store a separate list of line numbers -> addresses. Most (at least in the 8-bit world) have just a line number and end of line token, or line number + length. The latter is in my TinyBasic - so GOTO/GOSUB involves a linear search, but at least it can skip lines as it knows their length.

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 06, 2024 8:14 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
drogon wrote:
BillG wrote:
Thank you for enlightening me as to which BASICs also allow specifying a target with a variable expression.

Now why do some prohibit that? Clearly it is slower than an absolute line number. Why not just document that fact and allow it anyway?


I suspect it's explicitly tested for - ie. when you parse a GOTO/GOSUB then you either look for a number explicitly, or almost lazily just call your generic expression evaluator to get that number. Once you have then number the rest of the processing is the same.

And if you can GOTO an expression then it eliminates the need for ON x GOTO a,b,c ...

ON GOTO is arguably a bit more "structured" because the number of possible targets is limited. GOTO X can go anywhere...

drogon wrote:
Quote:
The compiler writer in me says that compiling a variable target is much more difficult. Essentially, a list of the addresses corresponding to the set of line numbers much be stored and searched when the jump is made.


But in BASICs you have a generic expression evaluator, so you save space by just calling it to get the number. There are very few BASICs that store a separate list of line numbers -> addresses. Most (at least in the 8-bit world) have just a line number and end of line token, or line number + length. The latter is in my TinyBasic - so GOTO/GOSUB involves a linear search, but at least it can skip lines as it knows their length.

I was talking about compiling the program into a binary image. There is no source code, even in tokenized form, to search.

Another of my many projects is a BASIC compiler to translate a program written in the TSC FLEX BASIC or XBASIC dialect into 6800 or 6502 assembly language.

The initial prototype generated code at the beginning of each line of source to store the line number into a variable for error reporting. Later versions quit doing that, but generated a list of line number/address couplets which is binary searched in case of error reporting. The run-time overhead is moved from normal execution to only in case there is an error.


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 06, 2024 4:38 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
Run-time error reporting in an 8-bit compiled binary? That's very fancy, at least in my limited experience. How common is that, really?

_________________
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)


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 06, 2024 4:46 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
drogon wrote:
Most (at least in the 8-bit world) have just a line number and end of line token, or line number + length. The latter is in my TinyBasic - so GOTO/GOSUB involves a linear search, but at least it can skip lines as it knows their length.

I added the length feature to VTL02, and included a condition that would allow "find" to start the linear search at the next line rather than the first line, making forward "GOTO"s less clunky. It worked so well that I decided to re-use it to find the next line during normal execution as well, at the expense of a handful of clocks.

_________________
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)


Top
 Profile  
Reply with quote  
PostPosted: Thu Mar 07, 2024 11:13 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
barrym95838 wrote:
Run-time error reporting in an 8-bit compiled binary? That's very fancy, at least in my limited experience. How common is that, really?

ON ERROR needs to know the number of the line executing when an error occurs so that it can RESUME back to the correct line. Since that information is already available, an unhandled error is reported with the error number along with the number of the line.


Top
 Profile  
Reply with quote  
PostPosted: Thu Mar 07, 2024 12:04 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1485
Location: Scotland
barrym95838 wrote:
drogon wrote:
Most (at least in the 8-bit world) have just a line number and end of line token, or line number + length. The latter is in my TinyBasic - so GOTO/GOSUB involves a linear search, but at least it can skip lines as it knows their length.

I added the length feature to VTL02, and included a condition that would allow "find" to start the linear search at the next line rather than the first line, making forward "GOTO"s less clunky. It worked so well that I decided to re-use it to find the next line during normal execution as well, at the expense of a handful of clocks.


It might be interesting to know just how many forward references there are in a program - however this may vary during writing of that program. Would the overhead of saying "is the target greater than the current line number, or less than or equal?" and picking the appropriate algorithm worth the time to do the test and the extra RAM needed (in a minimal RAM system) ?

I think you might need a good selection of old BASIC programs to find out...

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 28 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: