Jump to content
phaeron

Altirra Extended BASIC

Recommended Posts

I'd like to introduce my latest project: Altirra Extended BASIC, a Turbo-Basic XL compatible interpreter implemented in a banked MaxFlash 1Mbit cartridge.

 

Often when I need to do testing on the physical hardware I just end up using BASIC when the speed and control of assembly isn't needed, as I can just type in the program instead of hooking up the tether to upload one. Problem is, Atari BASIC is missing useful features like hex values, and the Altirra BASIC cartridge is packed like a can of sardines, so I couldn't add anything substantial there.

 

Thus, the idea came to take Altirra BASIC and split it across cartridge banks so that it could be expanded. At the same time, experience had shown that much of the BASIC XL subset wasn't that useful due to the small pool of people who had used it and could run it, but with the extra space I could implement a far more expansive and available language: Turbo-Basic XL. Therefore, once I had gotten the interpreter reorganized into a banked cart, it was then possible to begin reversing TBXL's token format and reimplementing the extended language.

 

Details:

  • Uses a MaxFlash 1Mbit (128KB) cartridge. I chose this cartridge type because of its address-based banking mechanism, which turned out to be faster than data-based banking. Figuring out a usable long jump mechanism was a big obstable to getting this off the ground. Also, I have one of these carts and it's fairly widely emulated in the mega-carts.
  • Currently 7 8K banks are used, 6 of which are split with a 4K shared bank and a 4K variable bank, and the last one being a special full bank for the help system. Half the cartridge is thus currently unused.
  • Unlike Turbo-Basic XL, Altirra Extended BASIC does not occupy memory at MEMLO or memory under the OS ROM. This means that its memory layout is closer to Atari BASIC and it will run on a 400/800, even with 16K. Some TBXL programs are incompatible because they hardcode addresses in the $A000-BFFF range which Altirra Extended BASIC occupies.
  • ATXBasic is binary compatible with Turbo-Basic XL 1.5 save files. However, this means that it is not binary compatible with Altirra BASIC's BASIC XL subset. Conflicting token values, couldn't do both. Some statements like LOMEM have been relocated to new token values above TBXL's.
  • The AltirraOS math routines have been hoisted into the cartridge and reworked for speed. They are not necessarily as fast as TBXL's yet -- haven't touched division or transcendentals yet -- but it should be in competitive range overall. The OS math pack is not used so results are consistent between OSes.
  • I implemented as much of the Turbo-Basic XL language as I could find documented or tokens for, and tried to match TBXL's behavior when it diverged from Atari BASIC, such as the ON statement. One deliberate incompatibility: TIME$ uses the accurate frame rates for NTSC and PAL, no way I was going to use hardcoded 50.0Hz.

There is also a built-in help system, which I plan to fill out QBasic-style -- mainly because I am tired of turning away from the Atari to look up OS and hardware addresses. Writing the help directly is a pain, though, so it only has two pages right now. Need to write a help compiler. Preliminary docs are attached, though I still need to edit some old stuff from Altirra BASIC that needs to be changed.

 

All that being said, I could use help testing the TBXL subset. I have a large collection of Atari BASIC programs and have already gotten my classic test suite working (Nazz, SpyPlane, Quadrato, Escape from Epsilon, Valiant, Jenny of the Prairie, etc.) but I have very few TBXL programs. I'd like to get the TBXL subset more solid before jumping into more optimizations or adding more commands, and with Altirra BASIC the community was very good at pointing stuff I didn't know about Atari BASIC. One lengthy TBXL program I've gotten running is Rocket Rescue -- that was fun to fix (PAINT leaks, ugh).

 

atxbasic.bin

atxbasic.pdf

post-16457-0-65306900-1539760912.png

  • Like 23

Share this post


Link to post
Share on other sites

I rarely use BASIC or any other high-level language these days but it's great to see new interpreters, compilers and IDEs being produced right now. They're intriguing to follow as technical exercises and I'm sure this one is going to become extremely powerful given all the available ROM space.

 

As usual the documentation looks excellent; clearly you've been busy. Altirra BASIC is already my favourite interpreted BASIC owing to its remarkable size/power ratio. :)

Share this post


Link to post
Share on other sites

Hi!

 

I'd like to introduce my latest project: Altirra Extended BASIC, a Turbo-Basic XL compatible interpreter implemented in a banked MaxFlash 1Mbit cartridge.

 

...

 

All that being said, I could use help testing the TBXL subset. I have a large collection of Atari BASIC programs and have already gotten my classic test suite working (Nazz, SpyPlane, Quadrato, Escape from Epsilon, Valiant, Jenny of the Prairie, etc.) but I have very few TBXL programs. I'd like to get the TBXL subset more solid before jumping into more optimizations or adding more commands, and with Altirra BASIC the community was very good at pointing stuff I didn't know about Atari BASIC. One lengthy TBXL program I've gotten running is Rocket Rescue -- that was fun to fix (PAINT leaks, ugh).

Great!!!

 

When people here asked for modifying TBXL (to make it cart-capable or simply bugfixing) I always tough that would be a lot better to write a modern replacement (that was why I ended up writing Fastbasic), but your effort is just amazing.

 

For testing, I suggest all the TBXL ten-liners, many corner cases were tested in TBXL with those :)

 

I don't have much time now, but a simple bug-report, with my tenliner "Carrera3D", entering the listing does not work, because the abbreviation for "ENDIF" and parsing lower-case exponents, see:

post-18634-0-97692300-1539780070_thumb.png

 

Note that the listing was produced with my TBXL parser tool, so it is hard to read. Loading the TBXL saved file works!

carrera3d.lst

Edited by dmsc
  • Like 2

Share this post


Link to post
Share on other sites

This is awesome. I've been thinking of diving into Turbo Basic XL and learning it's extensions, but this sounds even better! I'll try to make some time to work on it!

Share this post


Link to post
Share on other sites

Very nice!

 

I was able to get my ten-liners to work just by adjusting memory locations to avoid the A000-BFFF range.

 

CAV10AXB.LST

JUMPAXB.LST

 

Cavern10 needs temp space to assemble the compressed data. I was able to move this from $A000 to $9000. This new version works on TBXL and AXB.

 

Jump foolishly assumes the display list and screen are at fixed locations. So this new version only works on AXB and the original only works on TBXL.

  • Like 1

Share this post


Link to post
Share on other sites

Not sure if it's my program behaving badly or a bug in ATXBasic but I'm seeing corruption when typing "LIST". Steps:

  1. ENTER "D2:CAV10AXB.LST
  2. LIST (OK Here)
  3. RUN
  4. Hit RESET
  5. LIST (Some corruption. Several hearts in listing.)
  6. RUN
  7. Hit RESET
  8. LIST (Major corruption)

After step 2:

post-21021-0-90472800-1539812456.png

After step 5:

post-21021-0-26501000-1539812464.png

After step 8:

post-21021-0-44840600-1539812471.png

Share this post


Link to post
Share on other sites

Cool! I found that the PAL version of Cavern10 works both in PAL And NTSC under ATXBasic. It exceeded the frame time under TBXL so I had to make a trimmed down NTSC version. So ATXBasic appears to be faster than TBXL at least in this case.

  • Like 1

Share this post


Link to post
Share on other sites

Super!

 

All that being said, I could use help testing the TBXL subset.

 

All of these are Turbo-BASIC XL programs: AtariMania - Games (Turbo-BASIC XL)

 

Some of the commercial ones might have their directories scrambled, and I'm not sure

if the list includes Compiled Turbo-BASIC XL programs (probably does); but there should

be plenty of useful material to test there.

  • Like 1

Share this post


Link to post
Share on other sites

Not sure if it's my program behaving badly or a bug in ATXBasic

 

This maybe an issue with the cart reset protection not being quite right.

 

Each 8K bank ends with the cartridge vectors as technically any of the 16 banks could be active when the user hits the Reset button.

Currently they look like this:

 

BFE9: 99 00 D5 STA $D500,Y

BFEC: 60 RTS
BFED: 6C FE 00 JMP ($00FE)
BFF0: 8D 00 D5 STA $D500
BFF3: 4C 08 A0 JMP $A008
BFF6: 60 RTS
BFF7: EA NOP
BFF8: EA NOP
BFF9: EA NOP
BFFA/B: $A000
BFFC: 00
BFFD: 05
BFFE/F: $BFF6
So in all banks this is going through the vector at $BFFE to the RTS at $BFF6 which leads to jumping through the vector at $BFFA to $A000.
In all Banks, this looks like:
A000: JMP $BFF0
Which executes:

BFF0: 8D 00 D5 STA $D500

Setting the visible bank to Bank Zero.

Because each bank holds this same pattern, the next instruction is executed:
BFF3: 4C 08 A0 JMP $A008
So I haven't looked further in, but maybe the Basic needs an initialisation to be run on h/w reset but on s/w reset should detect this has already been done and skip over it?
  • Like 2

Share this post


Link to post
Share on other sites

This is awesome. Will this work on the myIDE II cartridge or only the MaxFlash carts?

 

What are the plans for extensions?

Functions? Local variables? Compiler?

 

Looking forward to seeing more!

  • Like 1

Share this post


Link to post
Share on other sites

This is a great way to work, put it all on cartridge and lift the load off the programmer.

 

Compiled languages could be done the same, put all the runtime onto the cartridge and have minimal code for the dev.

 

Imagine a language with really high level constructs like playSample or playRmt.

 

Great work Avery, innovative thinking at its best.

  • Like 1

Share this post


Link to post
Share on other sites

I don't have much time now, but a simple bug-report, with my tenliner "Carrera3D", entering the listing does not work, because the abbreviation for "ENDIF" and parsing lower-case exponents, see:

 

Ugh, ENDIF again. That was the keyword I had the most trouble with because it breaks the Atari BASIC shortcut rules. Basic XL doesn't allow ENDIF to be abbreviated but TBXL does, so I had to modify the parser. Guess I'll have to tweak it some more. Have the exponent fixed already (though I found another number parsing bug to fix).

 

Not sure if it's my program behaving badly or a bug in ATXBasic but I'm seeing corruption when typing "LIST". Steps:

 

This is a bug in the init code left over from when I thought I could use a RAM bank, before I got burnt by GINTLK and had to back it out. It's causing LOMEM to be modified, which then causes the VNT to be corrupted. Have it switched over for the next version, no need to be dropping the boot code at MEMLO.

 

This is awesome. Will this work on the myIDE II cartridge or only the MaxFlash carts?

 

What are the plans for extensions?

Functions? Local variables? Compiler?

 

Looking forward to seeing more!

 

It will not work on the MyIDE-II because that cart uses a different banking mechanism.

 

Don't have any plans for extensions yet, though the ones that you've listed are unlikely. Most likely I'd work on ease of use features rather than new language features that would have low uptake. A major reason I adopted the TBXL superset is because then the programs are largely compatible with the existing TBXL interpreter, compiler, and parsing utilities.

  • Like 2

Share this post


Link to post
Share on other sites

Don't have any plans for extensions yet, though the ones that you've listed are unlikely. Most likely I'd work on ease of use features rather than new language features that would have low uptake. A major reason I adopted the TBXL superset is because then the programs are largely compatible with the existing TBXL interpreter, compiler, and parsing utilities.

 

Is it possible to eventually have a RAM version for those of us who would like to run AEB on a machine with an U1M and SIDE2?

Share this post


Link to post
Share on other sites

 

Is it possible to eventually have a RAM version for those of us who would like to run AEB on a machine with an U1M and SIDE2?

 

No, because the interpreter size requires banking and the extended memory window at $4000-7FFF is a really unsuitable location for BASIC interpreter code. A cartridge with RAM on it is more viable but all of the ones I know of require data writes for banking and SIDE 2 doesn't have that support anyway.

  • Like 1

Share this post


Link to post
Share on other sites

How critical is an address-based banking mechanism to inter-bank JSR performance? With regard to running the interpreter on carts with different banking schemes, part of the reason it's difficult to - say - replace the loader on the SIDE cart's external cart ROM space with Action! or MAC/65 is that said application would have to be recompiled for the target hardware. But that's not an issue for something which can be compiled for different banking schemes with the aid of a few macros and conditional assembly. It just strikes me that a build for SIDE's external cart would work very nicely for users running the SIDE cart stand-alone and running the HDD via the SDX SIDE.SYS driver. The interpreter would be launched via the SDX 'CAR' command.

 

As I say: I have no idea how cycle-critical the inter-bank jump mechanism is. I only know that it's probably more efficient than what I came up with for the GOS, which targets half a dozen different banking schemes. Instead of loading up A,X and Y with bank number and target address, I ended up placing the bank number and target address in-line with a JSR to the long JSR function. Most of the registers are preserved and while it's good enough, it's fairly expensive.

  • Like 1

Share this post


Link to post
Share on other sites
  • Some TBXL programs are incompatible because they hardcode addresses in the $A000-BFFF range which Altirra Extended BASIC occupies.

 

Doh! Most of my TurboBasic XL tenliner games have the screen, DL and such addresses hardcoded in that range for obvious reasons. That could be fixed, but they won't run directly from the ATR.

Share this post


Link to post
Share on other sites

A clarification question.

To develop in ATX BASIC, you will need the MF1M cartridge. To just run ATX BASIC program, you will need MF1M cartridge too. Right?

Share this post


Link to post
Share on other sites

A clarification question.

To develop in ATX BASIC, you will need the MF1M cartridge. To just run ATX BASIC program, you will need MF1M cartridge too. Right?

are you asking if it's the 1 megabit cart or the 8 megabit cart he is planning to use?

Share this post


Link to post
Share on other sites

I guess he's asking if BASIC programs can be run without the ROM-based interpreter, to which I suppose the answer is no until such time as there's a compiler available.

 

Yes, that's exactly what I was asking.

Share this post


Link to post
Share on other sites

How critical is an address-based banking mechanism to inter-bank JSR performance?

 

It's not just about speed, but also how much space and registers a long call takes.

 

ATXBasic's bank mechanism works as follows:

  • The long jsr macro encodes an LDY #nn instruction with the ID of the target within the destination bank and a JSR to the thunking routine.
  • The thunking routine resides within a block of 4x4 thunks, for the four source and destination banks (only four banks are 'core' banks supported by the fast mechanism). Each thunk encodes a JSR to the dispatch routine, an STY to bank-switch back, and an RTS. These routines are identical and in the same location in all four banks, except for the redundant row which is replaced by the dispatchers.
  • The dispatchers do an STY to write to the low byte of a long jump vector followed by another STY to switch banks and a JMP (abs) through that vector.
  • The banks also contain a thunking table which is targeted by the JMP (abs) instruction.

So basically, each long call takes 5 bytes at the call site instead of the 3 for a normal JSR, and the overhead is 2+6+3+4+5+4+6 = 30 cycles, which is not actually particularly fast. But the really important part is that only the Y register is affected on entry and no registers or flags are modified on exit, which makes it much easier to retrofit onto existing code or move code between banks without redoing the call sites completely. With a data-based banking mechanism, more registers are needed which complicates the calling convention for routines that already use a couple of registers for inputs/outputs. This isn't to say that it's impossible to retarget onto such a cartridge, but it's an additional hassle I don't want to deal with at the moment.

 

Some routines can't tolerate bank switching overhead, regardless of the scheme. Decimal addition, for instance, is on the order of 120 cycles, for which a bank switch would be a major speed hit. Those routines go into the shared bank. Some routines in the shared bank also have a calling bank restriction so they can quickly bank switch the lower half to access data tables. The expression evaluator is in the shared bank but is universally called from the statement code in bank 3, so it can use just two store instructions to switch in and out of bank 4 where the precedence tables and function handlers reside. Since the bank switching is done by store to address with arbitrary data, no registers or flags are polluted by this. The help code is not speed-critical, OTOH, so it resides in the auxiliary banks where an "extra long" call is required, and it accesses its data by a small copy routine that will be shared across the help banks.

  • Like 7

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...