• Please review our updated Terms and Rules here

Level III Basic

Bruce Tomlin

Experienced Member
Joined
Jan 6, 2010
Messages
358
Location
San Antonio, TX
Has this been properly archived somewhere yet? I couldn't find anywhere in my old floppy disk rips that I had saved a copy, so yesterday I ripped my tape (and found out I have a really good cassette player!) I also was itching for something new to disassemble.

I hadn't realized there were minor variations in the disk version. It doesn't load or save files to disk, but it does have CMD "D" to exit back to DOS.
 

Attachments

  • img297..png
    img297..png
    216.5 KB · Views: 8
That looks like the dump I got. I still have yet to decode what I recorded on the "blank" side. It seems I recorded three copies of EDTASM on the blank side.
 

Attachments

  • img298..jpg
    img298..jpg
    140.7 KB · Views: 5
  • img302..jpg
    img302..jpg
    184 KB · Views: 5
  • img303..jpg
    img303..jpg
    187.1 KB · Views: 3
  • img304..jpg
    img304..jpg
    65.4 KB · Views: 1
  • img305..jpg
    img305..jpg
    60.9 KB · Views: 2
Last edited:
I finally finished scanning all the paper. Fortunately I had a long-feed scanner for the reference card, but it still took a few times to get it right. I made a .rtf version of both the manual and the reference card since automatic OCR is never good, and the reference card had a lot of light green text that wouldn't OCR, and a few obvious typos too. I was also able to comment big chunks of the disassembly, and I can generate both cassette and disk versions from the same source.

 
Nicely done! By the way, if you haven't tried Bruce's disx, please do. It is a joy to use!
 
Thank you for uploading the disassembly. What are you using to compile it back into working binaries? (Cross-compiler or original TRS-80 assemblers?)
 
Thank you for uploading the disassembly. What are you using to compile it back into working binaries? (Cross-compiler or original TRS-80 assemblers?)
My own assembler, look down at my sig. And you really, really want to use the svn version, as apparently the last time I made a "release" was well over a decade ago. I've been working on it actively, but thanks mostly to my disassembler to bounce code both ways, the to-do list keeps growing.

And the latest svn patch allows proper .cas files to be generated with the "-T 128" switch. Oh, and I see that the example command in the comments at the top of the .asm file is wrong, so the zip has been re-pushed.
 
Here is a bit of Level III basic trivia. Back in the 80's, I beta tested an early release of Level III. I just came across the disk :)
Oooh, cool. I'll have to do some comparisons. Good chance for some insight into the development process. If you happen to remember any bugs it'll help me know where to look first.
 
I know I found some - I think they were in the field handling for disk I/O. That's about all I can remember.
 
After a quick start on disassembly, here are some things I've noticed:

- no relocation header at the start (not all that useful for a disk version, and it's more annoying to disassemble)
- MUCH bigger, because it has disk support in it
- three versions... I seem to call that BASICR had the NAME (aka RENUM) code in it so you didn't need it wasting memory all the time, but there is also a BASL3S version that is another 500 bytes larger, maybe it adds the updated cassette code

There's also conveniently a regular BASIC and BASICR in the disk image for comparisons.
 
Holy moly! That beta is the rumored but never-released merge of Level III with Disk Basic commands. You can have the graphics extensions and disk files at the same time. Plus, looking at the demo files and the binary reveals never-before-seen keywords:

DUMP - prints a cross-ref of all simple variables. DUMP() does the same for array variable.
CHAIN - to another program. A feature from the bigger Microsoft Basic. (Although many DOS Basics added that too.)
COMM - probably for the RS232, but with "ON" used as COMMON variables for CHAIN above.
TRANSFER - ?
FIND - ?
CHANGE - ?
MENU - Automatic menu combines variables of choices text with ON GOSUB and cursor selection.

The only clues are from the demo files. Daverand, if you have more information it would be appreciated!

It acts like TRSDOS 2.3's Basic--same banner, and locks up if it doesn't think it's TRSDOS. (Crashes on NewDos. Might be OK on LDOS.)

They probably never fixed all the bugs before Microsoft lost interest in the TRS-80 market. But bugs or not, if this program got loose on the bulletin boards in the 80's, I bet it would have been very popular.
 
This is just so much amazing alternate history for me, since I've hacked on various MS BASIC versions for so long, but Model I first and most. I would like to know the context of when they came out with this, possibly after the cassette version? I wonder if they might have given up on it because RS had an objection, but it seems that the DOS version check stuff might have been the real reason since there were so many alternative DOSes, and probably even the Model III as well by then.

I've been looking at this strictly from a disassembled code point of view so far, and haven't looked at the examples yet.

There also seems to be some double-precision transcendental math functions, looks like &SQR etc. (in BASL3R BASL3S) There's also a version of that &SQR stuff with a second parameter that uses the hole made by the RND keyword, but then it seems to forget which keyword started it. Also LSET and RSET will apparently both do the key macro thing since it doesn't check the saved carry flag. I'm still mapping out what's in each version to find out the difference between BASL3R and BASL3S.

Also in one of the BASICs somewhere (I think one of the RS BASICs!) I noticed that the LOC keyword was broken. Instead of getting information about the file number it immediately called one of the error functions, but I haven't had the time to explore that yet.

I was wondering that that SYNCHK '(' / SYNCHK ')' pair was for. And yes "COMM" is for "COMMON".

The beginning part of the code correlates very strongly with Disk BASIC 2.2. When there's stuff that uses the same keyword like SAVE/LOAD PUT/GET, the original code is left in place, then the new code does a quick check and jumps back to do the disk version.

As for those new commands, did you notice that they set up a new interpreter inner loop for that? Look for the '<' / '>' of the TRON output. I recognized it because that's what I had to do long ago when I was experimenting with adding stuff to BASIC, like "RESTORE <lineno>" and DPOKE. (I made a FORGET keyword based on a joke in a magazine, probably Byte. But I had to do a FORGET ON / FORGET OFF because it really slowed stuff down to rescan the code every time you went to a new line.)

It's very interesting to see an "official" implementation of replacing the inner loop. I need to compare it with what I did.
 
Last edited:
I'm pleased that this is getting some interest! Today I will be looking through the documentation boxes to see if I can find the additional sheets that came with the disk.
 
No luck with finding that cover letter which came with the floppy, unfortunately, so it does look like that's all I have.

A question, however - are the double precision math functions the same as in the 26-1704 cassette double precision math pack?
 
This is just so much amazing alternate history for me, since I've hacked on various MS BASIC versions for so long, but Model I first and most. I would like to know the context of when they came out with this, possibly after the cassette version? I wonder if they might have given up on it because RS had an objection, but it seems that the DOS version check stuff might have been the real reason since there were so many alternative DOSes, and probably even the Model III as well by then.
Sorry - missed your question earlier. The date on the disk is 03/16/81, and that roughly agrees with my memory (spring of '81).
It was well and truly after the cassette version (which I had a couple of copies of by that time - found my original manuals :)
By that time, I was heavy into the extended basics that came with Newdos and Newdos/80, and writing a lot of code using that.
 
I think I've figured out the difference between the three versions.

BASL3 doesn't have renum (the NAME command) or double float
BASL3R has everything
BASL3S has everything, but many differences in the TRANSFER/COPY and CHANGE/FIND commands, and two big buffers after CHANGE/FIND (those pairs of commands share code with each other)

The 3R/3S changes are a big mess, were these received at the same time or could one be an earlier version?

I think I also found a bug: PRINT #-3 (all versions) doesn't check the '#', so you could do PRINT X-3 or even PRINT CLOAD-3 and it would think you did PRINT #-3. This bug was not in the cassette version.

And the bug I found in LOC was in both BASIC.CMD and BASICR.CMD, but none of the BASL3 versions. I found it because I was marking error jumps everywhere, so it kind of stuck out. I guess that might be one reason why we got TRSDOS 2.3.

are the double precision math functions the same as in the 26-1704 cassette double precision math pack?
I don't know what's in that, but I doubt it. From the descriptions I see, that was subroutines written in BASIC. These are in proper Z-80 code, presumably from Microsoft's other versions of BASIC.
 
The 3R/3S changes are a big mess, were these received at the same time or could one be an earlier version?

I think I also found a bug: PRINT #-3 (all versions) doesn't check the '#', so you could do PRINT X-3 or even PRINT CLOAD-3 and it would think you did PRINT #-3. This bug was not in the cassette version.

And the bug I found in LOC was in both BASIC.CMD and BASICR.CMD, but none of the BASL3 versions. I found it because I was marking error jumps everywhere, so it kind of stuck out. I guess that might be one reason why we got TRSDOS 2.3.

The image I posted was the disk as received from Microsoft, so all at the same instant.
 

Attachments

  • mslev3.png
    mslev3.png
    5.5 MB · Views: 10
I'd like to extend what Bruce Tomlin found above in BASL3 programs with what I found when disassembling and experimenting. Since there won't be any official instructions for the new commands, here are some.

Part 1: applies to all 3 "BASL3" versions.

TRANSFER and COPY program lines
-------------------------------

TRANSFER [ linenum [ - endlinenum ] ] [ > newlinenum ] [ , linestep ]
COPY [ linenum [ - endlinenum ] ] [ > newlinenum ] [ , linestep ]

"Transfer" moves, and "Copy" duplicates, single or multiple lines to a new starting number.
(Note the ">" character. It's not all comma-separated like most line-renumbering commands.)

First number after the command is assumed to be the source line(s). It can be a single line, or a range. The same rules for LIST apply: if you use "-" for a range, you can leave off either the start or end of a range. Period "." can also work, with limitations. If no source lines are given, it affects the entire program: TRANSFER renumbers it, COPY will duplicate (double its length).

">" marks the starting line number of the destination. It can't be a range. If left off, the new line(s) will be numbered after the current line number of the program. (Which fails if that line is in the middle of the program.)

"," is the step rate for each new line number. If left off, 10 is the default.

Together, they're more than just a "super-renumbering", but a cut/copy & paste for program lines. Like DU and DI in NewDOS but much more powerful.


FIND and CHANGE text inside program
-----------------------------------

FIND [ linenum [ -endlinenum] , ] "text"/stringvar
CHANGE [ linenum [ -endlinenum] , ] "oldtext"/stringvar [ TO "newtext"/stringvar ]

These find or replace text anywhere in the program. That's anywhere--including keywords, comments, quoted text, and even referenced line numbers. (But not the actual line numbers.) Powerful, but CHANGE is dangerous!

Note that FIND does work, but not the way you expect. It does not list all the matching lines at once. It lists only the first line, after the current line, that contains the text you ask for. Retyping the same FIND command then lists the next line that contains that text. You use it one line at a time. Once you reach the last matching line, it will show "Not Found" after any further attempts. What's more confusing is that it starts from or after the current line, like the "." of LIST. So if you LIST your program before experimenting, it will always say "Not Found" because it's positioned past the end of the program! If you get confused, use a low starting line number like FIND 10-,"blah".

CHANGE, on the other hand, is global by default. CHANGE "I" TO "J" changes all I variables (and text with "i", and ruins all IF keywords) everywhere on the whole program at once. All changed lines will then be listed. If you drop the TO "newtext" part, the oldtext is erased everywhere! Unless you're playing around, I'd recommend including a specific line range at the beginning of the command.

(Although all 4 commands will run inside a program, like LIST they abort the program afterwards. So it doesn't quite allow for self-modifying code. CHANGE comes really close, though! If only you could CONT.)

Together, these commands make Basic development much more convenient. It would have been very competitive had it been released.
 
Part 2: only to BASL3R and BASL3S. (I disassembled BASL3S mostly, but checked on results on both.)

"&" Double-precision functions
------------------------------

&SQR | &LOG | &EXP | &COS | &SIN | &LOG | &TAN | &ATN (exp1 [ , exp2] )

Used with a single parameter or expression such as &SQR(2), these return double-precision answers vs the usual single precision SQR(2).

The bad news is that the &ATN function is broken, and using two parameters breaks them all!

With &ATN(), if the parameter is between -1 and 1, it seems OK. &ATN(1)*4 has the correct digits of pi. But the ATN function can be used with values greater than 1, and if you compare params >1 between ATN() and &ATN(), the answers for &ATN() are wildly different! That's a major bug.

I found this out by trying the "Savage" floating-point benchmark. With the line "B=&TAN(&ATN(&EXP(&LOG(&SQR(A*A)))))/A-1", it seemed tailor-made to test these functions. DTACK Grounded #25 Page 12 http://www.easy68k.com/paulrsm/dg/dg25.htm gives the program and various times, and issue #26 explains that results almost entirely depend on the ATN function. But when I got the worst error of all machines including single precision, that made me look at &ATN() closer. The other functions seem OK.

All the & functions also check for a "," and allow a second parameter. I have NO idea what that's intended for: it seems to put it into the second floating point register WRA2 and does other processing. But don't try it, because it gives nonsense answers on all these functions! &COS(1) is correct, but &COS(1,1) is... something else. Even worse, keep printing "?&COS(1,1)" repeatedly: you'll get different answers every time for the same input! Any result of two parameters is completely wild & inconsistent.

Verdict on BASL3R and BASL3S: ambitious (like the rest of Disk Level 3), but clearly not "ready for prime time".


Other findings:
---------------

The disk they came in is bootable! It identifies itself as "TRSDOS VER 2.3A"
I haven't investigated any differences from plain 2.3. For all I know there's no change except the version number. At least it's not the infamous incompatible 2.3B.
 
Back
Top