“Large” VDU coordinates
nemo (145) 2552 posts |
There’s a known limitation with the range of coordinates available to four crucial VDU sequences:
The two graphics commands are limited to signed 16bit coordinates. The two text commands to unsigned 8bits. This limits text displays to 255 rows or columns, and graphics (including sprites) to 32,767 pixels or lines. Though those numbers were sky-high when the BBC Micro was designed, they’re getting inconvenient now: Some inkjet printers can achieve 2880dpi – at that resolution RISC OS couldn’t reach the end of a piece of A4! Embarrassing. This problem is quite distinct from the implementation limit of OS_Plot which, despite taking 32bit parameters, is subject to the above hard limit when indirecting through WrchV, and internal 16bit limitations when calling the VDU code direct. Implementation limits can be ‘easily’ changed, but the hard limits of the VDU sequences cannot. I wrote a prototype module (VDULarge) some time ago that implemented extended versions of these four commands as SWIs, but despite it working I did not like that solution. Not least because there was no simple mechanism for Printer Drivers to implement those new graphics interfaces. I have a better solution now – VDUExtend (I’ll be amazed if that’s not already taken). There are a number of competing requirements:
The approach taken is that in addition to the 8bit text and 16bit graphics VDU commands, new VDU commands are coined that take 16bit text and 24bit graphics coordinates. 24bit is not 32bit, but it’s 256 times longer than A4 at 2880dpi and that’ll do me. First the big ticket item: VDU sequences are a bit old hat, so OS_Plot is extended with four new reasons:
OS_Plot has always ignored reasons outside the 0-255 range allowed by VDU25, so nothing can have been using large values of R0 expecting to get the same effect as bits0-7 would have. These four reasons are more pleasant to use than VDU sequences and take 32bit signed parameters (note that -24 and -28 take four coordinates, not two). Though OS_Plot will still be subject to implementation limits, these new VDUs extend them considerably. Internally, OS_Plot does its nasty WrchV check to see if it can call the VDU code direct. If so, these new calls jump to the obvious places. Otherwise, WrchV indirection is required: If the text coordinates are 8bit unsigned or the graphics coordinates are 16bit signed, the existing VDU sequences are issued. Hence 100% backwards compatability. If the text coordinates are greater than 16bit unsigned or the graphics coordinates are greater than 24bit signed, then the existing VDU sequences are issued (achieving the same useless wrap-around behaviour that was always inevitable). However, if the coordinates fit in the new 16bit/24bit range, new VDU sequences are issued: VDU23;31;x;y;0; Extended range text cursor position This enables text coordinates of up to 65536 lines and columns. VDU23,28,left;bottom;right;top; Extended range text window Coordinates of text windows are inclusive, so this supports 65536 lines and columns. VDU23;25,op,loX,mdX,hiX,loY,mdY,hiY Extended range PLOT ‘Standard’ OS_Plots with 0<=op<=255 and 16bit<coordinates<=24bit use this new form. This produces a different kind of broken behaviour in old printer drivers – previously very large coordinates would erroneously wrap around, but this will cause them to be ignored in old drivers. I do not consider this a problem. VDU23;24,op,loX,mdX,hiX,loY,mdY,hiY Extended range graphics operation This general-purpose call is required for the graphics origin and graphics window. Four 24bit coordinates is too much to fit in a single VDU sequence, so two sequences must be used. Therefore this VDU has three defined ops:
Advantages
I’m tidying up a new prototype, but I’d welcome feedback. |
Rick Murray (539) 13850 posts |
’bout bloody time.
Not half as embarrassing as being unable to position the cursor in text mode all the way across the screen in “big” modes, like QHD. 2560 pixels divided by 8 gives a possible 320 characters across the screen… Will you be fixing this at source level this time? |
nemo (145) 2552 posts |
This is not complicated code from the Kernel POV, it’s the API that needs careful consideration. Small amount of tweaking to some Printer Drivers and job done. The compatibility module though is harder, I’m polishing that now. VDULarge worked by finding the VDU dispatch table inside UtilityModule, but VDUExtend works by intercepting JVecs, which is my new favourite thing. Intercepting OS_Plot is easiest with VectorExtend but I’m not releasing that yet, so it has to do it the awkward way. Putting this API into RO5 is trivial. |
Jeffrey Lee (213) 6048 posts |
One of my pet peeves is text editors which can’t cope with lots of text without failing in some way (text wrapping in an odd manner, inability to scroll to the end of a long line, inability to scroll to the end of a file, etc.). Since we’re bumping graphics coordinates up to 24bit, why not go the extra mile and bump text coordinates up to 24bit as well? On a machine with a 32bit logical address space you’re not likely to have a bitmap large enough to need text coordinates larger than 16bit, but for rendering a small part of a (very) large window (either within the Wimp or for printing) the extra 8 bits might make all the difference. Extending OS_Plot sounds like a reasonable approach, but I’d like to propose the following VDU sequences be used instead: VDU23;0,op,loX,mdX,hiX,loY,mdY,hiY Extended range PLOT VDU 23,0,action is a bit of a mess, with only actions of 8, 10 and 11 defined (at least according to the RISC OS 3 PRMs). ROL’s docs also suggest that action 9 is/was erroneously implemented. Adding actions 24, 25 and 31 will make further allocations from this space harder – it’s better to bundle them together at the start of the range. VDU23;0 is the same as your VDU23;25. VDU23;1 is the same as your VDU23;24. VDU23;2 is a 24bit-wide combination of your VDU23,28 and VDU23;31. op takes the same value as the graphics equivalent (0=bottom left corner, 1=top right corner, 2=origin), allowing some of the code related to packing/unpacking the values to be reused. This allocation also avoids using one of the “reserved for future expansion” VDU23,n numbers. (n.b. I’m not particularly attached to the VDU23;0, VDU23;1, VDU23;2 numbering & allocation, the main thing I wanted was to try and pack them all together to make future VDU23;n use easier) |
nemo (145) 2552 posts |
I take your point, and I don’t have strong feelings about the numbers – part of the exercise is to have a better API than strings of bytes sent one at a time down WrchV (and having to remember what they might be). Reasons 0-7 were used on the Beeb for CRTC programming, and I find the fact that they are not sent down UKVDU23V telling – I’d recommend using them last. 9 is indeed ‘implemented’, though I’ve never quite decided whether it’s deliberate or not. It falls through into 11. 12-17 also date back to the Beeb, but are sent down UKVDU23V, perhaps because they could conceivably be implemented for compatibility (the light pen for example). One of the gravest problems with VDU23,0 is that the kernel only looks at b0-4 of the reason code. I suppose that must have been due to some similar wrapping in the MOS, but I find it hard to believe anything relied on it. I have been tempted to pre-filter reasons 32-255 and send them straight down UKVDU23V before the Kernel gets at them. 18 is cursor width in BBC BASIC for Windows (so consider that defined) How about deprecating the folding-over of reasons 32-255, and allocate new third-party sequences from that new range? That would leave 0-31 for the Kernel, as was always the case.
I was trying to limit the double-shot sequence to the graphics window case. A 65536 column mode requires half a million pixels – even at 2880dpi that’s over 15 foot wide (and each character would be 0.07mm wide!). My feeling is that if we need 24bit text coordinates we can coin three extra reasons on the Extended Range Graphics Operation sequence which is currently used for the 24bit graphics ops. VDU23,28,l;b;r;t; is neat isn’t it – the 24bit equivalent would not be. SWI"OS_Plot",-28,l,b,r,t is ok though, and maybe BASIC can be persuaded to |
nemo (145) 2552 posts |
I think we all agree though that anyone choosing to use the ‘OS_WriteN’ version of this API over OS_Plot is going to need an excuse note from their mummy and daddy. |
Jeffrey Lee (213) 6048 posts |
Sounds sensible to me.
I’d prefer to have 24bit text window coordinates right off the bat. As you say, anyone using VDU / OS_WriteN to issue the sequences needs their head examining, so it doesn’t matter if the mapping to/from VDU sequences is a bit ugly. But we have OS_Plot, which works fine whether we’re going to use 16bit or 24bit text coordinates, so we might as well future-proof things by making it 24bit (or at least 21bit, assuming min font size of 8×8) Combining the “extended range text” and “extended range graphics” entries makes sense, especially if the usable VDU23;n space is limited. |
Jeffrey Lee (213) 6048 posts |
Actually, forget my text editor argument – I was thinking that the text window worked like the graphics window (e.g. allowing you to set an origin which is outside the window). And if you’re in the Wimp you’d be using VDU 5 mode text rather than VDU 4. It might still be nice to have text coordinates 24bit for API consistency, however. |
Rick Murray (539) 13850 posts |
Mmm… but “fixing” behaviour by use of an extension leaves an inadequate thing still inadequate.
My REdit simply refuses to use modes with >255 characters across the screen. It already has enough quirks, thanks. ;-)
Why? Somebody, it might have been Clive?, was mentioning that cursor editing and such did not work on his enormous monitor.
Mmm… <nods> Do the job once…
I see the AND instruction in the OS source, but there’s no mention of this behaviour in the PRMs. As such, I too, think that it shouldn’t be a problem to extend this to allow new behaviour. |
nemo (145) 2552 posts |
I’m expecting RO5 will incorporate these modest changes into the Kernel, together with a VDUExtend stub module, so that apps that require the functionality can RMEnsure if they so wish. The actual module is for older OSes – and specifically for apps that require the greater range. It will be distributable.
That argument in support of 24bit text coordinates was specious (as apps don’t draw VDU4 text into a sprite and then display the sprite – they display VDU5 text direct) but the general point is somewhat valid. Over-cautious I think, in that I don’t believe 24bit VDU4 text positions can ever be feasible. However, my argument that the BASIC VDU sequence is slightly nicer when 16bit is also laughable. True, though.
O_o There you go using those words again. I do not think they mean what you think they mean. |