Jump to content
IGNORED

Created English translation of the Extended Turbo Basic (Turex.com) documentation


markmiller

Recommended Posts

I figure at some point, I'll grow beyond the Atari's limitations

 

Hahahahah. Hahahaha. Oh, sorry. I was just thinking that I'll not likely ever move beyond all that even an 8-bit Atari can do. But, again, kudos to those who can and do. That's why we have this great world of software products, hardware, and games. There are a lot of really talented and determined geeks out there.

 

And it's amusing and gratifying to see them turn right around and begin applying some of that knowledge to the Old School stuff. I haven't tried FujiNet for the Atari yet, and have no plans to. But I've learned about it and it's quite an amazing device and system. Much of this new stuff (to my mind) is overkill. But that particular device seems a nice balance of features. It keeps the Old School but allows it to go a little further. As does the AVGCART. It expands the Atari but seems to be in the original spirit of it. It's simple and it seems to work in a straightforward way. Kudos to the guy who made that as well.

 

So we, in our selfish interest, hope that FastBasic, for example, will continue to be developed and perhaps add a few things (such as auto-indenting of loops) – if only because Turbo-BASIC XL (as nice as it is in its apparently final form) isn't going anywhere.

Link to comment
Share on other sites

@Brad Nelson - A fascinating thing about display lists (and the Atari) is it's actually a simple kind of machine code for the Antic processor (yes, the Antic is a processor). Its instruction set is really small. I'm guessing, but I think it only has about 10 instructions. It's also got an address bus and program counter that are a bit funky, and you have to be mindful of their limitations, or else you'll get results you don't expect.

 

Another thing I realized, once I came to understand it, is that every time you use the Graphics command in Basic, the operating system sets up a display list for the screen you're viewing. It's placed just below screen memory (so, what you see on screen is the result of Antic reading screen memory and the display list, just below that).

 

Even when you're in Graphics 0, the operating system has set up a display list for that. So, there's always a display list operating when the screen is "on."

 

There's a way to turn the Antic chip off, turning the screen black, or "off." This is sometimes used in computing-intensive tasks, since it speeds up execution time by about 30%. The reason for this is that the 6502 and the Antic chip share the same "master" memory bus. So, there's actually a "tag team" action going on between the 6502 and Antic. Every 60th of a second, the 6502 processor is switched off, and Antic takes over the memory bus, so it can read screen memory, and the display list, to redraw the screen. The exception is if there is a display list interrupt active. In which case, the 6502 is switched back on before each scan line is drawn (and then turned back off while the scan line is drawn by Antic).

This was kind of a revelation, because this is a lot like how the Atari 2600 video game console operates. All of the code that the 6502 executes actually happens while the screen is not being drawn! It has to be this way, because the 6502 and Antic are sharing the same address space, and they can't be accessing it simultaneously.

 

Once Antic is done drawing the screen, it "goes to sleep," and the 6502 is switched back on, to continue program execution. This is also when a vertical blank interrupt happens.

This is all oriented around the way old analog display monitors operated. The electron beam scans the screen, as it's being drawn, going from left to right. When one scan line is done, it takes time for the electron beam to reset to the left side, to draw the next scan line. This is when a display list interrupt would happen (if set). You can execute a bit of code while this is going on.

When the monitor is done drawing the screen, the electron beam has to reset from the lower-right side of the screen to the upper-left. This was called a "vertical blank" period in the monitor's display cycle. Hence the name of the vertical blank interrupt on the Atari. Again, code is executed during that period.

 

When you change graphics modes, what's actually happening is the operating system makes sure there's enough screen memory for it, and then sets up another display list, to display that graphics mode. It sort of helped me understand programs I used to type in that would do things with the display list to get different screen effects. What they'd typically do is find the display list (there are a couple Peeks for that), and then, understanding the typical scheme the operating system uses to set one up, would use offsets to Poke certain values into the display list, causing the screen effects. That was the typical thing to do. It's easier, less code than creating a whole new display list (which can also be done).

 

Even though I understand it conceptually, I still have trouble setting up display lists of my own without running into problems (the screen looking weird), or locking things up. Fortunately, there's always the Reset button to erase my screw-ups. :)

 

When I was first learning about the display list, I watched this technical video on how Atari implemented its vector graphics in some of its arcade game systems (like Asteroids, Star Wars, Tempest, etc.). They used a display processor in an analogous way to how the Antic chip is used in the Atari, which used its own instruction set. It was a different technology, for a different kind of display, but similar concept. What's neat is at the end, you can watch as it demonstrates how the screen for Tempest was drawn, for each frame, using this instruction set.

 

 

 

I also really liked the way this guy explained things. I thought it was very approachable (on the YouTube channel "8-bit and more").

 

 

Edited by markmiller
  • Like 1
Link to comment
Share on other sites

8 hours ago, Brad Nelson said:

I figure at some point, I'll grow beyond the Atari's limitations

(Quoting myself) It's happened to me before. I had an Atari STe in the 1990s, and I got interested in building a particle model. I built a minimalist one on the STe, but the STe (even at 16 Mhz) wasn't nearly powerful enough for what I was trying to do. I moved over to an old 33 Mhz 386 DOS PC, and that improved things quite a bit. Finally, I moved it over to a new, 266 Mhz Windows PC I got in 1997, which really gave it the "oomph" I was looking for, and I stayed there for quite a while, developing Windows software, and then developing for the web for a little bit. I got sick of that, and moved over to the Mac, learning about Common Lisp, Scheme, and Squeak.

 

I finally wanted to get into some system-level stuff, and that's when I made the move back to the 8-bit, because a lot of what I'd done before was at the application level. I'd done hardly any system programming, looking at operating system code, what the hardware is doing, etc. So, I wanted to go with something simple and familiar. I've enjoyed the return :), but I have occasionally run into memory limitations, where I think, "Hmm. Maybe I need to 'bust this cap' and go to something more powerful."

Edited by markmiller
  • Like 1
Link to comment
Share on other sites

Thanks for the overview of the mechanics of display lists, Mark. There is some kind of voodoo involved because I did manage to have some success with them but always ran into what you said:

 

Even though I understand it conceptually, I still have trouble setting up display lists of my own without running into problems (the screen looking weird), or locking things up.

 

I know there are certain page boundaries the display list cannot cross. But I still couldn't grasp the entire programmatic concept of how to do them. Much of the fault is my own, of course. But I wonder if I'm the only one out there that notices that the people who do are not always the best people to teach. Very often the instructions for doing things (display lists or something else) are not particularly clear, or even complete, especially from a beginner's standpoint.

 

So (and I know this is not just me) you often have to decrypt someone's instructions as if you were playing a game of Black Box. Still, I think just for the exercise if it (and if I can do it, can I then explain it clearly myself?), I might try to do some kind of split-screen where I have Graphics 7 on the top drawing an ellipse (can't have too many of those) and the bottom have drawing on in Graphic 8. I had bookmarked a couple pages that tried to explain display lists. Here. Here. And Here.

 

And to stay reasonably on-topic, I'll try to do this in both Turbo-BASIC XL and FastBasic. But we'll see. If this becomes too much like eating one's spinach, there's no use aggravating myself.

 

 

 

 

 

 

Edited by Brad Nelson
Link to comment
Share on other sites

but I have occasionally run into memory limitations, where I think, "Hmm. Maybe I need to 'bust this cap' and go to something more powerful."

 

Obviously things such as building a particle model are going to benefit from gigaflops. But I think the challenge for many proficient programmers is finding out how much they can accomplish given the limitations. And when you have these limitations (in any walk of life, whatever the pursuit), this both provides motivation to overcome the limitations and the necessary focus. If there are no (or few) limitations, the sky is certainly the limit. But that lack of limits itself can be a bit overwhelming. Where do you start? Having infinite possibilities sounds nice on a greeting card but being able to pare things down a bit almost always smooths the way to a creative solution.

Edited by Brad Nelson
Link to comment
Share on other sites

7 hours ago, Brad Nelson said:

I know there are certain page boundaries the display list cannot cross. But I still couldn't grasp the entire programmatic concept of how to do them.

When I was researching this, an annoying thing I saw a lot was the examples used for how to construct display lists were "safe," in that they used a couple text modes, and a certain number of scan lines of Graphics mode 7, something like that. The reason I say this is the examples steered clear of the addressing complications I talked about, so that you could just deal with a straight display list. With what I was trying to do with display lists (similar to what you're talking about, except I was trying to do a split screen between Graphics 8 and Graphics 0), you really have to deal with these addressing issues, because of the amount of memory you use for the display list and screen memory in the higher resolution modes.

 

There are two things to watch out for: One has to do with screen memory addressing. The other has to do with the Antic's reading of the display list itself. Both are simple to "fix," but it's easy to forget about them, and so run into unexpected problems. What feels complicated is keeping track of the addresses you're using, which is necessary for dealing with this issue.

 

The Antic chip has a 10-bit program counter (so, it can handle relative addresses from 0-1023 decimal). This affects its reading of display lists. Once it hits its 10-bit limit for reading the display list, it needs help getting to the 1024th byte, for it to continue. All this really means is it needs a JMP instruction (whose opcode is 1). Looking at my notes, it looks like JMP is a 3-byte instruction ($01, followed by the low- and high-byte of the address to jump to).

 

You need to test for this before inserting each instruction in your display list. So, you need to be keeping an address counter in your code for where you are in constructing your display list, so you can do this test. You initialize it to the address where the display list starts, and then as you're adding instructions, you update it with the number of bytes used for each.

 

The test is basically done using a modulo operation on your address counter, as the display list is being constructed. Any display list that crosses a 1K boundary needs this done. You will particularly see this in the higher graphics modes, as the amount of memory you need for the display list will likely cross a 1K boundary.

 

When I say "1K boundary," I'm talking about 1K sections out of the absolute address space that's used to reference elements in the list. So, if, for example, you have a display list that crosses address 4096 decimal (4 x 1024), you'd need to do this.

 

There is a formula you can use to check whether you need to do this. This is what I have from my notes:

 

====================================================

To test if you need to deal with the 1K boundary, while creating your display list, use:

 

X = GPOS - INT(GPOS/1024) * 1024 - 3

 

GPOS being the next address where you're going to add a display list instruction.

 

If X = 0, then you need to insert a JMP instruction to get ANTIC to the address that is a multiple of 1024.

====================================================

 

Since you're using Turbo Basic/FastBasic, you can use X = GPOS MOD 1024 - 3 for the test. Same thing.

 

Really what it amounts to is the JMP instruction literally referencing the address for the cell just after it, where you were going to plant the next display list instruction, "before you were interrupted."

 

It's a similar drill for the Antic's addressing of screen memory, since it has a 12-bit memory scan counter (so, it can handle relative addresses from 0 to 4095). It needs help getting over 4K boundaries. In this case, you use an LMS (Load Memory Scan) instruction to help it do that (whose opcode is 64).

 

LMS combines its opcode with the Antic mode number for the next mode line, by adding it (this is followed by two bytes for the screen memory address). So, to use this instruction for Graphics mode 0 (whose Antic mode number is 2), for example, you'd use the number 66 (64 + 2).

 

Like your tracking of the address used to insert the next display list instruction, you need a memory counter, to track the screen memory your display list is using to display its mode lines. After each mode line instruction (and any LMS instruction(s), since it combines a mode line into itself) is inserted into the display list, you need to add the amount of screen memory that mode line uses to your memory counter. But before you insert your next mode line instruction in your display list, you need to test whether there's enough screen memory to display it that does not cross a 4K boundary.

 

Here is what I have from my notes:

=======================================================

 

To test if you need to insert an LMS instruction to get over a 4K boundary, use:

 

X = DS - INT(DS/4096) * 4096 - MEMPERLINE(MODE)

 

(I'm using some pseudocode here)

 

DS = your screen memory counter

MEMPERLINE(MODE) = the amount of memory the next mode line takes up in screen memory

 

If X < 0, it means there isn't enough room between the address in your screen memory counter and a 4K boundary, and you need to insert an LMS instruction to get ANTIC over the gap.

 

You also need to adjust your screen memory counter, as you'll use this in the address portion of the LMS instruction:

 

DS = DS - X

 

This will add to DS, since X is now negative. This calculation fills in the displacement value for getting over the gap.

=======================================================

 

Again, since you're using Turbo Basic/FastBasic, you can use: X = DS MOD 4096 - MEMPERLINE(MODE) for the test.

 

A lot to think about, but I think that covers it.

 

Looking over the articles you referenced, wow, that second one, from playermissile.com, looks advanced! I've come across it before. I didn't read much of it, since it got into more stuff than I wanted to know. The stuff I read was more like the (3rd) Compute! article, "simplified."

 

This was implied in my first paragraph, but I found extremely little on using display lists with Graphics 8, which was striking to me. Most of the articles I read said nothing about dealing with the addressing issues I talked about here. I was lucky to find a couple that did. I largely had to figure out how to use display lists with Mode 8 for myself.

 

I think the reason is, as you can see from most of the discussion on AtariAge, most retro-Atari programmers are interested in video games, and most of them don't use Mode 8. So, there's very little coverage of it, for an advanced topic like this. That's something I was realizing, that Mode 8 has been rather like an "ugly stepchild" on the Atari, not used much. I was surprised by this, because even when I was younger, Mode 8 was the neatest thing, a nice high-resolution mode (though, it was too bad it only has 2 colors. If you want more, you have to resort to artifacting tricks, or using player/missiles to "add" color on a part of the screen, as I recently found out playing "Shanghai," a version of the Mahjong game on the 8-bit).

Edited by markmiller
  • Like 1
Link to comment
Share on other sites

Miracle of miracles, I was finally able to get the FastBasic cross-compiler working with this Starter Project. You can find a pre-built version of the FastBasic cross-compiler here (lucky thing since I would have no idea how to do so from scratch). I had read somewhere on these forums of a fellow using the cross-compiler via Visual Studio and just had to give it a try.

 

The problem I encountered were the ambiguous (to me) instructions about how this all worked, including just exactly what constituted the path for customization to be pasted into the build.bat file. Did the path simply mean the folder going to the executable or should it include the name of the executable as well at the end? (The latter).

 

And do you open that build.bat file in a text editor (I guess you can)? Well, as it turns out, the you can just open the entire sample project folder in Visual Studio (File>Open Folder...) and edit it that way, gaining access to the file via the tree to the left. Again, this is all obvious knowledge to geeks but not to newbies.

 

There's a lot of assumed knowledge to make something like this work. And whether the paths had to be pasted into both the build.bat file and the build file as well, I was unsure about. The instructions mention only the build.bat file but if you look at the build file, it looks as if it needs the proper path pasted in there as well...which I did.

 

Granted, full instructions that take you from the installation of Visual Studio, Altirra, and all the way to getting the FastBasic cross-compiler up and running would be voluminous which is probably why such a thing is rarely done.

 

The Cross-compiler documentation can be found here.

The starter project and instructions can be found here.

 

The advantage to doing things this way are likely 99% beyond me at this point. But you do get the more sophisticated editor of Visual Studio and I guess I no longer have to bug dmsc for auto-indenting of loops in FastBasic, although that would still be nice. :) And I'm sure there are a myriad of other bells and whistles in Visual Studio of which I am not aware.

 

Running your program via Visual Studio (which processes your basic program via the FastBasic cross-compiler which then produces an XEX file which is then automatically run in an instance of Altirra) may be no great gain over running it from inside Altirra, at least for simple stuff. But it does at least work. Hit Ctrl+Shift+B and your FastBasic program listing in Visual Basic is compiled and then run in Altirra.

 

Given that this dumps anything you had running in that instance of Altirra, you probably need to reserve one instance of it and bring it to the front (of any other instances of Altirra if you have more than one) before compiling via Visual Studio. Like I said, other than using the superior editor of Visual Studio, this method might be overkill for simple things.  However, the FastBasic cross-compiler does have various parameters that you feed to it. But how you do that from Visual Studio, I know not.

Edited by Brad Nelson
Link to comment
Share on other sites

Mark, thanks for your detailed exposition on display lists. That brings back some memories, especially the LMS instruction. I think I was tackling this a couple years ago. I had some success modifying some example display lists. But when I went to do something new, my logic all fell apart. It was apparent that there was a thing or two I wasn't grasping.

 

I mean, no, I'm not Albert Einstein but sometimes it peeves me a little that they couldn't have made this a little more straightforward. I mean, yes, they were dealing with constrains of memory and ROM space. But does Color 1 really need to be set via register zero? Whose idea was that? And I am absolutely certain there is a reason. I'm just not sure it's a good one. :)

 

I actually did a simple instance of player-missile graphics on the Commodore 64. Bless this fine fellow for dispensing quite a bit of useful information in just 10 minutes. I think the Commodore 64 does make a few things easier. I could do this. I did do this. I use the C64 Forever emulator, which I purchased. I know it's usually ridiculed by Those Who Know Best as crippled and not as powerful as VICE. But I find it's simple, fairly straightforward, and works well.

 

Anyway, end-of-rant. I know there are some programs out there for the Atari that automate some of this stuff, including (I'm pretty sure) some programs for constructing display lists. So perhaps that aspect is already solved.

Link to comment
Share on other sites

11 hours ago, Brad Nelson said:

I know there are some programs out there for the Atari that automate some of this stuff, including (I'm pretty sure) some programs for constructing display lists.

I heard of one when I was researching display lists. I forget what it was called, but I gave it a try, and I wasn't that impressed with it. What I remember is it was written in Atari Basic. It set up a Graphics 8 screen, where you selected what mode lines you wanted, and where you wanted them on the screen, and it generated Atari Basic code that would construct that display list. My problem with it was the interface was clunky, and I wasn't sure if it was generating the screen I wanted. There didn't seem to be any documentation on how to use the generated code, and there was a lot of it. I was working on my own display list code at the time, and it wasn't as many lines as this. So, it felt like overkill.

 

You may know about Thomas Cherryhomes from Fujinet. Many years ago, he did some videos on the Forth language on the Atari 8-bit. One part of that was writing what he called an Antic disassembler, or turning a display list into mnemonics you can read. He didn't go the other way, writing an Antic assembler, but it's not that hard to imagine that one could do that in Forth. It came to mind, but I have other things at the fore for me right now.

11 hours ago, Brad Nelson said:

does Color 1 really need to be set via register zero?

Maybe you were using a metaphor here. I was just translating/reading an article by Ostrowski recently on the TB compiler (translating using Google Translate), where he talked about the color register (for plotting/drawing) being 200 decimal/$C8 hex.

 

I have had an urge to see a better programming environment on the Atari, now that it has access to much more, cheaper memory. I think that's what would really be necessary to make it more straightforward, making a programming environment that exploits the extended memory, to allow more control over the machine, but in a way that's more understandable and readable.

 

Even today, it feels odd to me that 8-bit computers offered Basic, but to get to the real power in the system, you have to drop into machine code. To most of the older programmers of the day, this didn't feel odd at all. It was just how things were. If you wanted maximal power in the system, you pretty much had to program in assembly. As I look back on it, it seems like Basic was often used as a "scripting" or "macro" language for stuff programmers really wanted to accomplish at the lower level.

 

There were programmers who operated in certain domains where they never needed to go down to assembly, and didn't have any desire to do that. They could use Fortran, Cobol, or Pascal. If they wanted to get down to the system level, many of them could use C. On 8-bits, we had Basic. That's where I stayed for years, not getting down to the lower level much, until I got into high school, and college. I knew about assembly and machine code, but that felt scary, because I'd hear horror stories about some bug someone had written in machine code that erased their floppy disk, or burned out some chip on the motherboard (I forget which, but there was some 8-bit computer I heard about where if you executed a certain pattern of machine instructions, it would literally burn out some chip). I lost that fear many years later.

 

6502 assembly feels clunky, because you only have 3 CPU registers, and they have very specific purposes to them. So, you have to understand the CPU's operating scheme to program it effectively, but it doesn't have that many instructions. The instruction set feels easy enough to learn. I think the challenge is interfacing that with the Atari's OS, and its hardware. Even so, I've found that the OS only allows so much flexibility. I had the thought, working on my Graphics 8/Graphics 0 splitscreen project that to really get what I wanted out of the system, I'd need to rework a part of the OS, because what was really getting in my way was the way the OS handles the cursor. Though, I eventually realized that I could accomplish what I wanted for my project by exploiting some features of what the OS was already doing. It isn't the cleanest solution. It's not something that could be expanded into other applications that easily, but it would work.

 

I still like the idea of digging into the OS, to make it better in a certain way, but I don't want to get into that yet. Maybe somewhere down the road.

Edited by markmiller
  • Like 1
Link to comment
Share on other sites

You may know about Thomas Cherryhomes from Fujinet. Many years ago, he did some videos on the Forth language on the Atari 8-bit. One part of that was writing what he called an Antic disassembler, or turning a display list into mnemonics you can read. He didn't go the other way, writing an Antic assembler, but it's not that hard to imagine that one could do that in Forth. It came to mind, but I have other things at the fore for me right now.

 

I was surprised to read recently that some of my favorite Atari 8-bit computer games or programs were written in Forth. I've not heard of this fellow, Thomas, but there is a thread here at AtariAge about games written in Forth. A fellow names Carston writes:

 

"Forth is fun to work with, but you need to re-wire your brain a bit and forget almost all you have learned about programming before, else you get mad about it."

 

From what little familiarity I have with the language, I believe him. :D But an Antic disassembler with mnemonics for the display list sounds like just the ticket.

 

Maybe you were using a metaphor here.

 

No, really. You use Setcolor 0,x,x (color resister zero) to set the color provided by the Color 1 command. And Setcolor 1,x,x defines the color for the Color 2 command, etc. And, of course, the background and/or border is set with Setcolor 4 (why not?) via Color 0 (makes perfect sense).

 

I have had an urge to see a better programming environment on the Atari, now that it has access to much more, cheaper memory. I think that's what would really be necessary to make it more straightforward, making a programming environment that exploits the extended memory, to allow more control over the machine, but in a way that's more understandable and readable.

 

Honest to goodness, if I had Elon Musk money, I would pay you and a crack team of programmers to do just that. It would be a marvelous project. An enhanced version of Turbo-BASIC XL would be the built-in language with FastBasic as a sort of side option. We would somehow add proper string arrays as well, very good utilities or commands for Player-Missile, etc.

 

I mean, don't get me wrong. I'm quite aware I don't have the talent and skills to program a game in assembly or even to do one of those amazing 10-line games in BASIC. I wouldn't say this stuff is easy for many people, but it is doable (obviously). But there's the other side of the coin whereby there are those who just want to get something done and do not necessarily want to bow at the knee of the Geek Aristocracy who quite often consider something being difficult or obscure to be a feature, not a bug.

 

It is certainly more than possible (I would imagine) to create some kind of Display List built-in utility or commands for Atari OS Rev. D (or whatever the next version would be). Imagine, for instance:

 

10: DISPLAY, GR. 8 (50%), GR.7 (25%), GR.0 (4 text).

 

The DISPLAY command is invoked with parameters as to the percentage of screen (top to bottom) to be divided per various invoked Graphics modes, with the special case of the text modes being invoked in terms of the number of text lines.

 

Okay, obviously a talented programmer is going to tell me why this or that won't work or that there is a better way. And I'm quite sure there is. But something like that is what I'd want to see. It's similar to how on a Mac or PC you can partition volumes by sliding a little divider widget up and down.

 

Can you actually have as (relatively, after lopping off the 4 lines of Graphic O text) 50% of the screen in Graphics 8 and 25% in Graphics 7? Almost certainly the scanlines and such will not divide like that evenly. But you could have the nearest legal equivalent. And you could certainly add a (!50%) parameter to force that 50% to be an absolute 50% of the screen while the other invoked non-text graphics modes could be relative to whatever space is left over.

 

As I look back on it, it seems like Basic was often used as a "scripting" or "macro" language for stuff programmers really wanted to accomplish at the lower level.

 

I don't disagree, which is why Turbo-BASIC XL and (especially) FastBasic are important. They have the potential (or already are) to be a means to produce useful software (including games) without the need to drop into machine code.

Edited by Brad Nelson
Link to comment
Share on other sites

3 hours ago, Brad Nelson said:

10: DISPLAY, GR. 8 (50%), GR.7 (25%), GR.0 (4 text).

 

The DISPLAY command is invoked with parameters as to the percentage of screen (top to bottom) to be divided per various invoked Graphics modes, with the special case of the text modes being invoked in terms of the number of text lines.

It seemed like whoever wrote that Basic program I was describing earlier was driving toward that. It put me in a Gr. 8 screen, with some numbers down one side, giving a sparse scan line count, and an arrow lined up along the side, showing which was the current scan line being programmed. You would (I think) type a number for the graphics mode line you wanted. You could move the arrow up and down with arrow keys, and change the mode lines as you went. Though, to me, it wasn't clear whether it was setting things up the way I wanted.

 

So, I think your idea is doable. I think it's clearer than the tool I was trying to use. It would be up to the runtime to figure out how many mode lines to use for each mode, based on the percentages.

 

Such a command would need to also allow the programmer to assign screen memory for each section, if they wanted, or else the runtime would do it, itself. Though, it would be nice if the programmer could interrogate the runtime to see where the screen memory is, since they may want to put some machine code somewhere, and wouldn't want to stomp on the screen memory, or have their routine overwritten.

 

There should also be provision for the other things programmers want to do with a display list, like set up interrupts, implement fine or course scrolling, and, of course, be able to go in and alter individual mode lines.

 

An interesting challenge would be finding a way, within a high-level language, to implement handlers for interrupts.

 

3 hours ago, Brad Nelson said:

Can you actually have as (relatively, after lopping off the 4 lines of Graphic O text) 50% of the screen in Graphics 8 and 25% in Graphics 7? Almost certainly the scanlines and such will not divide like that evenly. But you could have the nearest legal equivalent.

I don't see why not. I know the 50% in Graphics 8 is doable, since I worked on splitting the screen half-and-half between Mode 8 and 0. Putting the 25% in for Mode 7 would work, too. I don't know that it would be exact, but I don't see a problem mixing these modes.

 

A nagging problem I ran into using Mode 0 was I wanted to use the OS's text I/O routines (using Basic's Print and Input commands). I kept trying to relocate the screen memory for the Mode 0 portion, before I realized I couldn't do that while using the I/O routines, because all they knew was the hard address of $BC40 for the lower part of screen memory. So, I ended up using a different part of RAM for the Gr. 8 portion. I'd "open" up screen access by using a Graphics 0 command, which would initialize the text screen memory, and open the S: channel, so I could use Plot and Drawto commands; so the text I/O routines would work, and then I'd modify the display list to display the Gr. 8 portion, and use graphics commands with it.

 

That's another thing I learned: To really start using your display list, you need to use a Graphics command, even Graphics 0 (even though you think you wouldn't need that, because, "I'm already in Graphics 0"), because otherwise, you'll get an error trying to use graphics commands, like Plot, and Drawto in the graphical portions of the display list.

 

So, in this alternative we're talking about, the runtime would need to handle how to initialize all of this, which, again, I think is doable. There would just need to be some logic that would assess the display list(s) that have been programmed, and decide how to initialize the screen system, plus the screen memory, so that the display lists being used will work as expected.

 

Re. Forth

 

I spent some time with it, using Leo Brodie's book, "Starting Forth." It was instructive, but kind of frustrating after a while, because I kept feeling like, "Okay, when is this book going to get to the part where I start doing something REAL with this?!", since it was all about exercises with certain words (that's what the primitives and extensions to the language are called), but nothing ever felt like a "complete program." It was like doing little exercises in immediate mode in Basic all the time.

 

I realized later I needed to get into a book I'd seen advertised many years ago, called "Atari Forth" (it has quite the dramatic cover). I looked at that a little, and saw Atari Forth has a word for RAM access. It probably has a way to execute machine language routines, as well, but haven't gotten that far.

 

I answered a Quora question a while back on how Atari used Forth (and some other companies that used Forth to write games for the Atari 8-bit, and the 7800 console), and a little trivia about a pinball game Atari had under development, but never released, which was supposed to have been programmed in Forth.

 

https://www.quora.com/Did-Atari-use-the-Forth-language-for-any-of-their-software/answer/Mark-Miller-89

 

The main adjustment for me was having everything be stack-based. You do everything in Forth using one or more stacks. To set up the computations you need, you need to use stack manipulation words. The command structure is also in postfix notation, as a result.

 

I had a feel for this already, since I'd spent quite a bit of time with Lisp, where everything is in prefix notation.

 

The weirdest thing I saw in it is its if-then-else logic, because it's formatted like:

 

<test> IF <then-part> ELSE <else-part> THEN <code-always-executed>;

 

A good way of not getting confused about this is to think of the THEN keyword as really being like "ENDIF".

Edited by markmiller
Link to comment
Share on other sites

I never understood the need to split the Setcolor and Color commands. Why not just "Color 1" if you want to invoke it or "Color 1(x,x) where you can on-the-fly give new color and luminescence values to Color 1? I never understood why this was so over-complicated.

 

It would be up to the runtime to figure out how many mode lines to use for each mode, based on the percentages.

 

Yes, and clearly the programmer is going to want to know some absolute values for the size of the various graphics modes in the display list so that he or she can plan accordingly for code inside the game (especially if the modes are created relatively instead of absolutely)

 

That proposed command – DISPLAY, GR. 8 (50%), GR.7 (25%), GR.0 (4 text) – could return that information in a system variable that you could access. Whatever vertical size was allocated to Graphics 8 could be found in GRHEIGHT(1) . . . the first partition, if you will, in the display (in whatever unit of measure was most convenient for game programmers). GRSIZE could return the size of your total screen memory with GRSIZE(1) returning the address of the first byte and last byte of screen memory for that particular "partition."

 

GRMODES would return the number of different graphic modes used in the display list (if needed). Not being a game programmer, I suspect there are some glaring flaws in the logic of all this. But something like this might work.

 

There should also be provision for the other things programmers want to do with a display list, like set up interrupts, implement fine or course scrolling, and, of course, be able to go in and alter individual mode lines.

 

You're right.

 

That's another thing I learned: To really start using your display list, you need to use a Graphics command, even Graphics 0 (even though you think you wouldn't need that, because, "I'm already in Graphics 0"), because otherwise, you'll get an error trying to use graphics commands, like Plot, and Drawto in the graphical portions of the display list.

 

That sounds like a very important thing to know and keep in mind.

Link to comment
Share on other sites

Speaking of using the Visual Studio IDE for FastBasic in combination with the FastBasic cross-compiler, there are some issues:

 

1) If you have a syntax error in the program, you will get an error messages inside the Terminal window and it won't create an XEX or try to run it. But I don't find these Visual Studio-based error messages of much use. I think it is more straightforward (if still cryptic) when the program and its "parsing error" message from within FastBasic in Altirra simply transports you to the offending error, even if it doesn't explain it.

 

For example, I misspelled a command as "free()" and got this error message from within Visual Studio:

 

parse error, expected: ',', ';', 'COLOR', 'RTAB', 'TAB'

? "hello";<--- HERE -->free()

 

So...you expected all that and didn't get what you wanted? I'm not surprised.

 

2) If you're also doing work in Altirra (or just playing a game), one of your instances of Altirra will be wiped out when Visual Studio (via the FastBasic cross-compiler) steals one of these windows and then leaves it erased and blank. I hope you saved whatever you were doing in that instance of Altirra.

 

3) There is no good FastBasic syntax highlighting for Visual Studio. You do get some of the advantages of the Visual Studio editor. But, for example, in "IF/ELIF/ELSE/ENDIF" loops, it doesn't highlight the ELIF in the same colors as the other words. And I can't find any way to edit that or add a word. In Notepad++, this is relatively easy and I've started work on my own FastBasic syntax highlighter for it (attached).

 

4) Any file you create in Visual Studio cannot be opened directly in FastBasic (in Altirra) without first exporting the file in a way that FastBasic (or Turbo-BASIC XL, for that matter) will handle the line endings. In Notepad++ (now that I've made the effort), it was relatively trivial to make a macro to add proper line endings (in order to be able edit the text) and then to strip them out again (and replace them with the needed line-ending character). I'm sure you can do this in Visual Studio. But the program is just a honkin' beast that you might have to spelunk in the settings for some time to find it.

 

As I mentioned, all this may be trivial and quite beside the point for large projects where the downsides of working in Visual Studio are more than made up for by its ample bells-and-whistles. But for smaller projects (or even medium ones), all of these become an annoyance...so much so that I don't offhand see the advantage of using Visual Studio as a front end for FastBasic.

 

However, there is much to be said for using an external editor rather than typing in an emulator. I think Notepad++ works fairly well. And I'm working on a syntax highlighter right now. I exported (and attached) an xml file which theoretically you can import into your Notepad++ and try it out.

 

To install, it should be something like (menus): Language>User Defined Language>Define Your Language… and then you can import from there. In theory. I haven't tried it yet. But if Notepad++ can export your custom syntax highlighting, I imagine it should import it successfully as well.

 

Not all command words have been given a special color nor am I likely to do so. I think the loops need to stand out (is the red too much?) but nothing tends to stand out if you're just looking at a big rainbow of colors. So I've kept it minimalist. The only thing for sure I want to add are different colors for nested parenthesis but I haven't figure out how to do that yet.

 

The syntax highlighting works fine with Turbo-BASIC-XL as well.

FB-TB Syntax NPPP.xml

Link to comment
Share on other sites

If anyone is playing along at home and likes using Notepad++ as a code editor, attached is a revised version of the syntax highlighter for both Turbo-BASIC XL and FastBasic. You should be able to import it into Notepad++ via (menus): Language>User Defined Language>Define Your Language…

 

Regarding coloring nested parenthesis a different color, I'm not actually sure you can do that to match the default syntax highlighting in Visual Studio. However, a pair of parentheses will (with the cursor inserted next to a parenthesis) highlight in the same color when editing. That's nice. I didn't do it. It seems to come for free.

 

I'm sure there could be a few more commands or types to highlight. But I thought making the various loops, processes, and if/thens stand out was a priority. And this one supports dark mode.

FB-TB Syntax 3.xml

Edited by Brad Nelson
  • Thanks 1
Link to comment
Share on other sites

9 minutes ago, Brad Nelson said:

If anyone is playing along at home and likes using Notepad++ as a code editor, attached is a revised version of the syntax highlighter for both Turbo-BASIC XL and FastBasic. You should be able to import it into Notepad++ via (menus): Language>User Defined Language>Define Your Language…

 

Regarding coloring nested parenthesis a different color, I'm not actually sure you can do that to match the default syntax highlighting in Visual Studio. However, a pair of parentheses will (with the cursor inserted next to a parenthesis) highlight in the same color when editing. That's nice. I didn't do it. It seems to come for free.

 

I'm sure there could be a few more commands or types to highlight. But I thought making the various loops, processes, and if/thens stand out was a priority. And this one supports dark mode.

FB-TB Syntax 3.xml 5.12 kB · 0 downloads

Thanks - I have been an avid fan of Notepad++ for longer than I can remember now!  It;s a day one install on any PC I put together.

  • Like 1
Link to comment
Share on other sites

Thanks, Stephen. If you use it, feel free to give me feedback on the color/font choices. You can obviously edit these things yourself (choose the same menu path as previously given, and choose "FastBasic" in the top left popup menu if needed). But always glad to hear a possibly better idea.

 

I was going to have numbers appear in the same blue as PROC/ENDPROC but it was inconsistent in how it colors the digits. Most were fine but some were not colored. If they were preceded and directly followed (no space) they would not turn blue. I read the official instructions but couldn't divine a solution. I thought the blue numbers worked particular well in dark mode so I'd love to be able to make that work.

Edited by Brad Nelson
Link to comment
Share on other sites

Okay, I don't want to go nuts here with options. But here's one I like better as a syntax highlighter for FastBasic and Turbo-BASIC XL for Notepad++. It is tilted to work a bit better in a dark mode.

 

I've been able to fix the number problem so that they are all blue. I like this option because then it makes the rest of the statements, operators, and variables stand out better.

 

I had to switch the PROC/END PROC from the blue to the green (and vice versa for the For/Next and Repeat/Until type of loops). I wanted to keep the blockier font for the procedure names. But it didn't work to share that color/style with the numbers.

 

If you were going to use this with a white background, I would darken that blue a bit and probably darken the grey of the comments a bit as well.

 

But I do find this in dark mode to be particularly readable and clear.

FB-TB Syntax 4.xml

Link to comment
Share on other sites

We'll call this syntax highlighter scheme for FastBasic/Turbo-BASIC XL for Notepad++ mostly done. I personally like it and I think it makes the listing much more readable at-a-glance. I remembered to add "EXIT" for the loops. And I added a light orange to floating point variables.

 

I admit to not fully understanding the inner workings of Notepad++'s syntax highlighting rules. There are a few instances where you won't get the correct highlighting if there is not a space before the command (such as line 31 with "?" print). Perhaps this could be used to good effect if you don't want the highlighting in a particular instance. Or this could be annoying. I haven't quite figured that out yet.

 

The same will happen if you have a second IF/THEN on the same line. If you need that second IF/THEN highlighted in red, put a space between the colon and that second "IF".

 

Many useful customizations can be made (to any theme you're running) via the Settings>Style Configurator… menu, especially in terms of how selected text is highlighted (I copy the color method of Visual Studio...a sort of light slate blue) and the color for selected"Smart Highlighting" (I use a lime green). You can also change the "Selected Line" style to as I have it: Settings>Preferences...>Editing>/Frame. You can then adjust the color of this via Settings>Style Configurator...>Current Line Background>Background color.

 

Is it worth all the fuss? Well, why not? :)

 

 

Example Syntax FB-TB.png

FB-TB Syntax 7.xml

Edited by Brad Nelson
  • Like 1
Link to comment
Share on other sites

Hi!

On 11/21/2023 at 2:07 AM, markmiller said:

Alright. Answering my own question, it looks like this doesn't work for floats. Got a parse error when I tried it.

I added this to the current development version: you can now take the address of a floating-point var, and you can use %() to read a float from the address.

 

This example is now working:

' Procedure to sum N elements of an array:
PROC SUM P N
  SUM% = 0
  WHILE N>0
    DEC N
    SUM% = SUM% + %(P)
    P = P + 6
  WEND
ENDPROC

DIM A%(2)
A%(0) = 0.125
A%(1) = 0.0625
A%(2) = 0.03125

' Test passing an array:
@SUM &A%, 3
? SUM%

' Test passing only one number:
X%=1234.5
@SUM &X%, 1
? SUM%

 

You can try this by compiling the code from https://github.com/dmsc/fastbasic

 

I will try to make a "beta" release during the weekend.

 

Have Fun!

  • Like 2
Link to comment
Share on other sites

Here's a puzzler.

 

I'm trying to create a Turbo-BASIC XL program that will (without going to DOS) allow you to change the directory.

 

The command is straightforward enough. And if you type this in direct mode, it will work fine: XIO 44,#1,0,0,"D1:TBFOLDER"

 

If you want to back up in the directory, it would be: XIO 44,#1,0,0,"D1:.."

 

The problem I'm having is getting this to work in deferred mode (by running the program). The code below doesn't work. The XIO command will not work using a string variable. And I'm out of ideas. Does anyone know a way to make this work?

 

And it's not a case of the E$ string being bad. I've tried this out in another version where it just prints out the whole command (including the XIO part) via a print statement. You can then enter the cursor into this line in direct mode and the command will work. But the XIO command doesn't like taking a string as the directory path in any mode.

 

20 REM MODE DOWN A DIRECTOR: H:FOLDER
30 REM MOVE UP DIRECTORY: H:..
40 DIM DIR$(20),C$(5),E$(40)
50 C$=CHR$(34):REM QUOTE CHARACTER
60 PRINT "ENTER DIRECTORY INFO"
70 PRINT "(NO QUOTES) ";
80 INPUT DIR$
90 REM E$="XIO 44,#1,0,0,"
100 E$(LEN(E$)+1)=C$
110 E$(LEN(E$)+1)=DIR$
120 E$(LEN(E$)+1)=C$
130 DIM A$(100),B$(6)
150 XIO 44,#1,0,0,E$

 

Link to comment
Share on other sites

16 hours ago, dmsc said:
' Procedure to sum N elements of an array:
PROC SUM P N
  SUM% = 0
  WHILE N>0
    DEC N
    SUM% = SUM% + %(P)
    P = P + 6
  WEND
ENDPROC

Just to clarify, I was trying to figure out how, on one hand, you were inputting a float array, and on the other, a single float, having the routine access them the same way. I see with your increment of P (while N>0) that you're actually doing pointer arithmetic, since the way the math package formats floats is as 6-byte BCD. So, rather than just incrementing an index in the array, you're traversing over the individual bytes in it (6 bytes per cell).

 

This takes me back to what I researched re. programming in C on the Atari. I remember the CC8 documentation talked about creating arrays of 6 bytes (6 char's) for each float, and I think the runtime, or a library you linked in, provided wrappers for the math package. So, all float calculations had to be done with function calls. The native arithmetic operators only worked on integers (not standard C behavior).

 

It was possible to create typedef's (user-defined types). So you could say:

typedef char [6] float;
.
.
.
float someNum;
float someNums[5];

CC8 would auto-increment over each 6-byte array for something like someNums[3];, giving you the 4th element (arrays in C are zero-based), which would be a 6-byte char array.

Link to comment
Share on other sites

@dmsc - I'm running into some parse errors.

 

I've tried copying this code from your manual:

A$="Long string"
B$=A$[2,2]
IF B$ <> A$[3,3] THEN ? "GOOD"

and I'm getting a parse error on line 1 (A$="Long string"). I dimensioned A$ above this.

 

Also, I'm getting a parse error when I try to do:

INPUT D$

This seems like a no-brainer, but what am I doing wrong? There is a DIM D$(20) statement before this.

 

The way I read your manual, this should work.

 

I'm also getting a parse error if I try:

D$=""

 

If I change the input statement to:

INPUT A

it works.

 

Also, I'm getting a parse error when I try:

E$(2)=D$

 

Though, I notice that this works.

E$(1)=CHR$(34)

 

I'm currently using build version 4.6.

Edited by markmiller
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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...