mattgodbolt/jsbeeb

Screen mode alignment

ojwb opened this issue · 9 comments

ojwb commented

There seem to be some discrepancies in the alignment of the display in different screenmodes.

This program tries each screen mode in turn showing the mode number in the top left corner and a same-sized block in the other corners, and demonstrates the differences in alignment:

0MODE0:?&D0=2:VDU23,-1;-1;-1;-1;-1
10REPEAT
20PROCM(0,76,31)
30PROCM(1,38,31)
40PROCM(2,19,31)
50PROCM(3,76,24)
60PROCM(4,38,31)
70PROCM(5,19,31)
80PROCM(6,38,24)
90PROCM(7,38,24)
100UNTIL0
110DEFPROCM(M,X,Y)
120VDU22,M,48+M,31,X;FNB(X),31;Y,FNB(X),31,X,Y,FNB(X)
130Q=INKEY100
140ENDPROC
150DEFFNB(X)
160IFX=76VDU-1;
170IFX>19VDU-1
180=-1

As well as MODE7 being shifted to the right by one column, the bottom edge of the screen seems to be ~one row higher in the 25 row screen modes (3,6,7).

I don't have a real BBC micro to hand, so I can't test if any of this behaviour is actually faithful to the original.

The horizontal shift of MODE7 is an issue which affects bbcmicrobot - in MODE7 the bot loses the right most column of the display and captures a blank column on the left side instead, because it records the area where it expects the display to be based on other modes.

Thanks for filing this! I'm hoping either @richtw1 or @scarybeasts can comment as they have spent the most time recently in video output.

The hi-rate modes, eg 1 start furthest to the left by default, with the low-rate modes eg 4 half a mode 1 character over and then MODE 7 starts a whole character over from that, 1.5 mode 1 characters over. from MODE 1. MODE 7 has 250 displayed lines, where as the others except 3 and 6 have 256, so, it finishes 3/4 a character earlier (higher). At least on my Master and CRT.

ojwb commented

So assuming that's also true for a BBC micro, for capturing screen output like the bot does you really need to peek at the emulator memory before capturing each frame to determine what the current screen mode is (location &355 according to the Advanced User Guide) and adjust the captured area of the emulated screen to match.

That would probably be fine for basic BASIC programs, but if they do anything a little fancy, it might be safer just to capture "a bit extra". e.g. In case they wiggle or bounce the screen. If you have CPU time to spare, you could clip to the used region for the whole capture.

ojwb commented

The bot source code is now released, so I've been investigating further.

Looking at the framebuffer the jsbeeb Video object fills in, the first and last pixels which get set in each screen mode are:

 MODE       topleft  bottomright

 0,1,2,4,5  65736    589639  
 3,6        65736    573255
 7          65752    577367

So at least for a BBC Model B, it seems jsbeeb puts the top left of the screen at the same position on the virtual monitor for all modes except mode 7 - there it's offset 16 pixels to the right (which is one mode 7 character). This doesn't completely match Richard's observations, but could be a Master vs Model B difference.

The numbers above give 500 rows for mode 7 and 512 for the graphics modes, which is consistent with what Richard reports for the Master (as this buffer has 2 rows per scanline).

From the numbers above, modes 3 and 6 appear to have 496 rows, but the stripes seem to come out transparent so there's probably a 4 pixel stripe below the final line, making those really 500 rows too.

I'm going to send in a patch to the bot to adjust for the mode7 offset. It's possible jsbeeb's positioning isn't entirely faithful to real hardware (someone would need to test on a real Model B) but I don't think this detail will matter to anyone, so at least as far as I'm concerned this ticket can be closed. (And if the offset does get adjusted, the bot will need to adjust to compensate.)

Fantastic: thanks so much @ojwb :)

Do we think this is now fixed?

ojwb commented

I don't have a real machine to hand to compare to, but I fixed bbcmicrobot for the original issue that led to me opening this issue and the current jsbeeb behaviour seems reasonable, so I think this can be closed.

Thanks @ojwb