Page 1 of 2

Double buffering?

Posted: Sat May 11, 2024 10:16 pm
by Chain-Q
As I read at various places, with the original QL ROMs, video double buffering cannot be utilized, because the OS keeps its (some?) of its variables in the same memory area.

Is there a "best practice" about putting the OS "gently" out of business? Maybe in a way, that it can be restored later? Or at least, that my code can take over, use double buffering, and not crash & burn in the process? I want to do some experiments with graphics, and for that, the OS is not a concern.

I guess, I have to switch to supervisor mode, disable interrupts and/or redirect them to my code. And I guess I have to save/restore the relevant memory contents to somewhere else, if I ever want a fighting chance to restore things, if that is even possible. Anything else? Is there an example for this somewhere?

I tried to search it here in the forum, but what I've found so far is that Minerva makes this possible... I hope the original ROM doesn't point some unchangeable interrupt trampolines into the relevant area, because that would be a problem...

Re: Double buffering?

Posted: Sat May 11, 2024 10:53 pm
by Derek_Stewart
Hi

Minerva implements a second screen that if enabled. Take the memory location of the System Variables.

The System Variables are moved to another memory location.

There is a QDOS Management Trap: MT.INF that returns the location of of the System Variables.

Maybe just calling this Trap will solve the problem.

Re: Double buffering?

Posted: Sat May 11, 2024 11:08 pm
by Peter
Derek_Stewart wrote: Sat May 11, 2024 10:53 pm There is a QDOS Management Trap: MT.INF that returns the location of of the System Variables.
Maybe just calling this Trap will solve the problem.
Unfortunately not.

It is perfectly allowed for the OS to place the system variables at a different location, and Minerva does that in order to allow the second screen.
But in this case, it is desired to use QDOS. So MT.INF would just tell you that the system variables are whe you do not want them.

I'm quite pessimistic about a "nice" solution under QDOS. Can not remember any second screen software under QDOS which returned to a working system.

Re: Double buffering?

Posted: Sat May 11, 2024 11:12 pm
by Peter
Chain-Q wrote: Sat May 11, 2024 10:16 pm I want to do some experiments with graphics, and for that, the OS is not a concern.
Naive question, but if it is just experimental, why not use Minerva?
As far as I know, Minerva ROM adaptors are still available for the QL.
And on the newer machines like Q68, which also support the second screen, Minerva is simply a ROM image on SD card.

Re: Double buffering?

Posted: Sat May 11, 2024 11:26 pm
by Chain-Q
Peter wrote: Sat May 11, 2024 11:12 pm Naive question, but if it is just experimental, why not use Minerva?
I admit, it's a bit along the lines of "why climb that mountain" - "because it's there"... :ugeek: If returning to QDOS wasn't possible, that's fine actually. Theoretically speaking, the code eventually could even detect, if it's running with Minerva, or an original ROM, and in the former case "play nice" and in the later case, just go destructive... But that still leads us back to the original question, on how to do it in the least un-elegant way, for the original ROM.

Re: Double buffering?

Posted: Sat May 11, 2024 11:59 pm
by M68008
Chain-Q wrote: Sat May 11, 2024 10:16 pm I guess, I have to switch to supervisor mode, disable interrupts and/or redirect them to my code. And I guess I have to save/restore the relevant memory contents to somewhere else, if I ever want a fighting chance to restore things, if that is even possible. Anything else? Is there an example for this somewhere?
You got it: switch to supervisor and disable interrupts. Also, don't call the OS.
Saving the screen area somewhere else and restoring it before re-enabling interrupt and going back to user mode also works. Most old games that disable the OS don't bother doing that, also because it would require 32 KB more memory, and just rely on users resetting the QL when they want to go back to QDOS.

The problem is in case you want to read the keyboard or play a sound. On a QL with Sinclair ROM, you can call TRAP #1 D0=$11 even with no variables in place and it typically works, but Minerva crashes (it would be nice to fix this in a future version of Minerva, along with a few other minor bugs and incompatibilities). One workaround is to use your own code to communicate with the IPC, typically copying it from QDOS or Minerva.

Re: Double buffering?

Posted: Sun May 12, 2024 7:31 am
by Derek_Stewart
Hi,

There are references to the Second Screen in:

QDOS Companion, Andrew Pennel: Appendix A Doing Without QDOS

Link to PDF: https://www.qlforum.co.uk/download/file.php?id=7006

QL Advanced User Guide, Adian Dickens: 10.8 Toggling between screen 0 and 1

No PDF available, I am still awaiting Copyright advice from Adrian Dickens.

Re: Double buffering?

Posted: Sun May 12, 2024 7:51 am
by Peter
M68008 wrote: Sat May 11, 2024 11:59 pm Saving the screen area somewhere else and restoring it before re-enabling interrupt and going back to user mode also works.
Which means 96 KB of 128 KB used for the dual screens and the save area. And further memory also needs to stay untouched. Depending on the mass storage used, this may shrink usable code/data to a few KB. At least on an unexpanded QL - but if Q-Chain targets QDOS, he probably targets that, too ;)

Maybe less than the full 2nd screen area could be saved. Could be a nice challenge... write a QDOS program that uses the second screen and returns to a working system.

Re: Double buffering?

Posted: Sun May 12, 2024 7:55 am
by tofro
Even if Peter says there isn't, here is a working example of how you can make the second screen usable in QDOS machine code programs. Software that wants to do that needs, however, jump through some hoops to work and come back to a working system. You will also likely need a memory expansion to have enough memory for the save buffers.
  1. Allocate some memory (32k) as a buffer area to save system variables and 32k beyond
  2. Switch to supervisor mode and disable interrupts (The latter is maybe not absolutely necessary in all QDOS versions if you can live with some artifacts on your second screen). Some QDOS versions (rather: all I tried) and SMSQ/E seem to tolerate enabled interrupts, Minerva doesn't.
  3. Copy system variables +32k to your allocated buffer
  4. DON'T use any QDOS functions while the second screen is active and the system variables are not where they belong (You will find that the code above has, for example, a direct keyboard request handler to avoid that)
  5. Play as you like switching between screen buffers, but adhere to the above
  6. Once you're done, copy everything back to where you saved it from, enable interrupts, return to user mode
After that, the system should continue to work as before.

You might want to have a look at the assembly files in the linked project, they do most of the heavy lifting. There's , however, not much happening when the second screen is displayed (except switching between screens and waiting for a key), so your mileage may vary.

If I'd have to write the same piece of code today, I would first detect if the code is running on Minerva, and if yes, use Minerva's second screen MT.DMODE traps to operate it, and ask the user to enable Minerva's 2nd screen. Would probably save me from some of the hoop-jumping.

Re: Double buffering?

Posted: Sun May 12, 2024 8:03 am
by Peter
tofro wrote: Sun May 12, 2024 7:55 am Even if Peter says there isn't, here is a working example of how you can make the second screen usable in QDOS machine code programs.
I didn't say there isn't. Just that I can not remember - which is a difference over 50 ;)

I wonder how much room your procedure would leave for the actual code and data on an unexpanded QL...