Better plotting modes, text anywhere on the screen and double-height characters for Sega Master System BBC BASIC
Monday, 9th August 2021
I've made quite a few changes to the way colours and plotting modes are handled in the Sega Master System version of BBC BASIC; previously this was handled on a per-graphics-mode driver basis, but this resulted in a lot of duplicated code and some inconsistencies. The new code is a bit more straightforward but also adds quite a few new features, most obviously different plotting modes:
Plotting with the OR mode
The above screenshot shows the result of filling three circles with the OR plotting mode. The red circle is colour 9, the blue one is colour 10 and the green one is colour 12. Where the colours overlap they are ORed together when drawing, so for example red OR blue is 9 OR 10 which is 11, the colour code for magenta, hence the colour between the two is magenta. Where all three colours mix, that's 9 OR 10 OR 12 which is 15, the colour code for white.
It's the logical colours (the palette indices) that are combined by these plotting operations, rather than the RGB values, it just happens that the stock palette lines up neatly with the RGB values!
Another addition I've made is support for VDU 5. In normal operation, text sent to the display is displayed at the text cursor position. In VDU 5 mode the text is instead drawn at the graphics cursor position, which allows text to be drawn anywhere on the screen, outside the confines of its usual grid. It also takes into account the graphics plotting modes mentioned above and so you can blend text with other graphics operations. Here's an example:
The somewhat blurry text has been drawn in two passes slightly offset from one another, once with colour 1 and again with colour 2, ORed together so that where the text overlaps you get colour 3, which is white. The program for this is as follows:
10 REM Draw wavy text in a watery style. 20 MODE 2 30 REM Set up a suitably watery palette. 40 COLOUR 0,0,0,64 50 COLOUR 1,0,64,128 60 COLOUR 2,0,128,255 70 COLOUR 3,255,255,255 80 REM Draw text at the graphics cursor position. 90 VDU 5 100 REM How many lines of text will we draw? 110 RESTORE 120 L%=-1 130 REPEAT READ L$ 140 L%=L%+1 150 UNTIL L$="" 160 REM Draw in two passes, slightly offset, in OR mode for a blurry effect 170 FOR C%=1 TO 2 180 GCOL 1,C% 190 RESTORE 200 Y%=(960+L%*50)/2 210 REPEAT READ L$ 220 IF LEN(L$)>0 AND L$<>"-" PROCWAVES(L$, C%*4, Y%-C%*4) 230 Y%=Y%-50 240 UNTIL L$="" 250 NEXT C% 260 REM Restore normal text operation. 270 VDU 4 280 REM Wait for a key then exit. 290 REPEAT UNTIL INKEY(0)=TRUE 300 REPEAT UNTIL INKEY(0)<>TRUE 310 END 320 REM Draw some wavy text at X%,Y% 330 DEFPROCWAVES(TEXT$,X%,Y%) 340 LOCAL I% 350 X%=X%+(1280-(LEN(TEXT$))*35)/2 360 FOR I%=1 TO LEN(TEXT$) 370 MOVE X%,Y%+20*SIN(X%/80+Y%/160) 380 X%=X%+35 390 PRINT MID$(TEXT$,I%,1); 400 NEXT I% 410 ENDPROC 420 REM Text strings to display. 430 DATA "VDU 5 can be used to place text" 440 DATA "anywhere you like on the screen," 450 DATA "not just aligned to the main" 460 DATA "text grid." 470 DATA "-" 480 DATA "This is fun, isn't it?" 490 DATA
When you're finished you can use VDU 4 to return to the normal text mode. In the video modes where I've had enough free VRAM to spare for it I've also added support for user-defined characters. You can send 23, then a character number, then eight bytes of pixel data for the 8×8 character bitmap to the VDU and then use that data for subsequent text operations (the characters from &80..&FF can be redefined). These user-defined characters can also be used as 8×8 sprites when combined with VDU 5.
I'm having quite a lot of fun writing my own test programs but it's also been useful to be able to run existing software as a test. I've tried to improve my sound handling and it now sounds a bit more faithful to the BBC Micro (though the Master System is a slower machine, so it can't quite keep up with more adventurous pieces of music).
The BBC Disc System "Welcome" screen and the Bones demo
With the new graphics plotting modes and VDU 5 support the BBC Disc System "Welcome" program runs, for example, though it looks a bit rough around the edges due to mismatches in the video modes. Bones also runs, however the mismatch is even more severe here and half way through the skeleton turns red as it's running in the four-colour video mode and COLOUR 1 is mapped to red, not the white in the monochrome mode the demo is expecting. The misalignment comes from differences in the number of rows and columns of text that are available; the demo mixes graphics commands (which are mapped reasonably closely to the BBC Micro's screen) and text; if the demo expects the screen to be 40 columns wide and the best I can offer with this hardware is 32 columns, it won't line up! Of course, the BASIC program can be tweaked to get it working properly, but it's fun to see just how close it gets without any tweaking...
One recurring issue, however, is with programs that expect to be able to use Teletext features. The BBC Micro's default video mode used a Teletext character generator, which allows for bright colourful text and some limited graphics support in very little memory. I had previously mapped this mode to the TMS9918A text mode, which allows for 40 characters in 24 rows, just one row short of the BBC Micro's 40×25. It's a fast mode and is good for program editing due to the large number of text characters on screen at a time (all other modes are 32×24) however it is very limited - there's no support for colour, for example, other than the global foreground and background colours.
To provide some colour support I loaded the character set into memory twice, once normally and once inverted, so via the COLOUR statements it's possible to inject some variety into this mode. The BBC Micro's Teletext MODE 7 doesn't support the COLOUR statement, it relies on embedding special control codes in character positions on the screen that affects the rendering of the rest of the text in the line – for example, a command might change the colour, or cause the rest of the line to flash. As I can't possibly support such codes, I just ignore them, and the programs run fine but look a bit bland.
The main exception to this, I've found, is the double-height text mode. You can switch this on within a line by storing the value 141 in a character cell and then off again with 140 afterwards. This will only display the top halves of the characters, so to display the bottom halves you need to output the same content on the line below. A lot of BBC Micro programs seems to take advantage of this feature, so most programs I'd tried ended up having doubled-up text like you can see in the screenshot above.
The character set I'm using is only 96 characters long (32-127) but I had avoided investigating this as I assumed I'd need to triple the number of characters - the regular-height ones, plus the top and bottom halves of the doubled characters. 96×3=288 which is more than the 256 characters we have available, so I didn't think this would fit.
However, I did think that maybe some characters shared parts - for example, the top halves of the colon and semicolon are the same, and the bottom halves of the semicolon and comma are the same, so I wrote a quick program to count how many unique patterns would be needed and found that it would only take 225 patterns in total, well within our 256 pattern budget!
I set up a new video mode based on the original TMS9918 text mode. This generates these 129 additional patterns for the double-height characters when initialised, and also checks the nametable when outputting characters to see if there's a "double height" control character in the same line to determine whether it should pick one of the stretched characters (picking a top or bottom half depending on whether there are an even or odd number of lines above it that also contain the double height control character).
This new mode does lose the inverted text, but I think the double-height text will be more useful in practice – or at least is better at making programs look less broken!