Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - BBC Basic on the SMS

Reply to topic
Author Message
  • Joined: 05 Jun 2010
  • Posts: 760
  • Location: Pennsylvania, USA
Reply with quote
BBC Basic on the SMS
Post Posted: Sat Jul 24, 2021 3:24 am
Someone sent this to me today and thought it was worth sharing. BBC Basic on the SMS: https://old.reddit.com/r/retrobattlestations/comments/oow1d6/bbc_basic_z80_on_a_...
15sbw6ns0mc71.jpg (1.01 MB)
15sbw6ns0mc71.jpg

  View user's profile Send private message Visit poster's website
  • Joined: 05 Jun 2010
  • Posts: 760
  • Location: Pennsylvania, USA
Reply with quote
Post Posted: Sat Jul 24, 2021 3:26 am
Here's the relevant text in case reddit disappears someday...

Quote

A few more pictures of the adaptors I built here: https://imgur.com/a/e6ZFvpD

When this month's program was first announced I tried running it on my only unarguably retrobattlestation, my Cambridge Z88, but the screen's low (vertical) resolution didn't do the program much justice.

I thought this gave me two options:

Control some external piece of retro tech to produce higher-resolution output (e.g. a printer or a plotter.
Port a BASIC interpreter to another retro system with a higher resolution display and run the program on that.

Unfortunately, I don't own any old printers or plotters (or a Logo-like turtle!) so option 2 seemed my best option. I had some experience adapting Richard Russell's BBC BASIC (Z80) to run on the TI-83 Plus calculator so I thought I should pick the Sega Master System as that also has a Z80 CPU in it. Here are some rough specs:

3.58(ish)MHz Z80 CPU.
8KB work RAM.
TMS9918A-derived VDP for video with 16KB dedicated VRAM accessed via I/O port.
SN76489-derived PSG for sound.
Two controller ports with six input pins and two pins that could be configured as inputs or outputs.
Software loaded from ROM cartridge or card slot with a small BIOS ROM that detects whether a cartridge or card is inserted (and if not, runs its own built-in game).

There is some precedence to this endeavour with the computer version of Sega's SG-1000, the SC-3000, which came with a keyboard and had BASIC ROM cartridges.

I wanted to try to keep this project as retro as possible, so no modern microcontrollers as I've been accused of cheating by using them in the past.

Loading BASIC onto the Master System

The first problem was getting BASIC onto the Master System at all. As my Master System doesn't have BASIC in ROM (it comes with Hang-On, which is perhaps more fun but less likely to handle the Mandelbaum set) I'd need to load the program onto a cartridge or card. Master System cartridges usually contain a mapper circuit to handle bank switching in the lower 48KB of the Z80's address space (the upper 16KB contains the 8KB work RAM, appearing twice) which is normally integrated directly into the ROM chip for the game, however there are a handful of games that have separate mapper chips and ROM chips and the ROM chips that Sega used have a pinout that is extremely close to that used by common EEPROMs (e.g. 29F010, 49F040) with only a couple of pins needing to be swapped around. After Burner is one such cartridge, so I've modified an old copy to let me plug in flash memory chips that I can program with the version of BASIC I'm working on. A switch at the top of the cartridge lets me switch back to the original pin configuration if I want to play the original copy of After Burner.

Typing commands into BASIC

With a flashable cartridge to hand I was able to assemble a version of Richard Russell's BBC BASIC (Z80) with some simple code stubs in place to direct text output to the screen. Output is useful but only half the story, we still need to be send commands to BASIC!

The Master System doesn't have its own keyboard, so I'd need to find some way to interface one to it. I have previously used PS/2 keyboards in a number of projects, as they are pretty simple to deal with. Electrically, they use two open collector I/O lines for bidirectional data transfer (one as clock, one as data), and fortunately each controller port of the Master System has two pins that can be configured as outputs which can therefore be used to interface with a keyboard (either left as inputs and pulled weakly high in their idle state, or driven low as outputs for their active state).

Here's my keyboard adaptor. It acts as a pass-through cable so you can still have a regular controller plugged in when using the keyboard.

The two pins on the Master System control port that can act as outputs are TH and TR; TH is normally used by light guns to latch the horizontal counter in the video chip so is unused with normal controllers so it's no great loss here, but TR is the right action button (marked "2") so by using this pass-through adaptor you do unfortunately lose one of the controller buttons. However, you do gain a hundred or so keyboard keys, so I don't think it's too bad a compromise...

For the software side of things I adapted my Emerson AT device library, previously written for the TI-83 Plus calculators, to the Sega Master System hardware. This library handles the low-level AT device protocol and also translates the raw keyboard scancode values to the corresponding characters.

Saving and loading programs

At this point I was able to type in BASIC programs and run them on the Master System, which was pretty neat! However, I was still working on adding new features (e.g. drawing commands for graphics) and having to type in the entire Mandelbaum program after every change was going to get pretty exhausting. I could bake it into the ROM but that seemed like cheating, so I thought I should try to find a way to load the file from an external source. A floppy disk or tape cassette would seem authentically retro but adding a floppy drive controller to the Master System would be a fairly complicated task and I don't have a suitable data cassette recorder to even attempt loading from tape so I thought some sort of file store accessible over a serial port would be a good option.

The Z88 has a serial port and can act as a remotely-controlled file store when running the PC Link software (with the protocol documented here). This seemed like a good choice, if not for the fact that the Sega Master System doesn't have a serial port of its own. To get around this, I added one, using a MAX232 chip to adapt the Master System's 5V logic levels to RS-232 compatible ones so I could plug in a null modem cable from the Z88 or my PC without accidentally frying the Master System with -12V.

I wrote some code that bit-bangs the serial data over the controller port lines using the timing loop code I wrote for a previous BASIC Month (Crisps Tunes) to support rates between 19200 and 300 baud. 19200 baud is somewhat unreliable but that's OK because the Z88's 19200 baud is unreliable too, so the default 9600 baud speed does a good job. RTS/CTS handshaking has to be implemented, as there is no hardware serial support on the Master System and it needs to be actively polling the port to receive any data. In doing so I noticed one awkward fact about my PC's serial port - if you de-assert RTS it will continue sending data until its buffer is empty, presumably only checking the RTS line when it's about to top up the buffer. In practice this means that even if I change RTS virtually as soon as the start bit for the first byte is received, the PC will continue to send up to 256 bytes before stopping. To get around this I added a serial receive buffer that immediately checks for the next byte even after asserting RTS, and this seems to have done the trick.

The protocol used by PC Link requires acknowledgement after every single byte so is very slow but at least it's reliable. I plumbed the PC Link code into BASIC's LOAD and SAVE which makes loading and saving programs as transparent and easy as if you had a floppy disk in the system instead!

Pressed for size

The Master System has 8KB of RAM. Of this, 16 bytes are mapped to special hardware functions and BBC BASIC reserves 768 bytes for itself, so we're already down to 7,408 bytes. I initially reserved 256 bytes for my own needs (display settings, VDU command buffer, serial port status, keyboard status etc) bringing it down to 7,152 bytes. The 16KB of display memory is not directly accessible to the CPU, so it can't be used for additional work RAM, and having to access it indirectly via I/O ports is very slow but I can't afford to mirror parts of it in RAM for speed.

Initially the Mandelbaum program ran well enough by stripping out comments, but I then added sound support (with eight 13-byte envelope definitions, and four channels with their own state, copy of their active envelope and a command queue for 32 bytes per channel, adding around another 140 bytes of memory usage) and the program stopped running with a "No room" error during execution (performing a square root operation, of all things!) so I guess the tolerances were very tight. I went and combine more lines of code into single lines and replaced two-letter variable names with single-letter ones (no, really) and it was able to run again but I don't think 8KB is a particularly comfortable amount of RAM for a BASIC computer!
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14959
  • Location: London
Reply with quote
Post Posted: Sat Jul 24, 2021 7:11 am
It’s by benryves who is an old friend of the site. Hopefully he’ll be along soon with more details :) or you can visit http://benryves.com/journal/3763166
  View user's profile Send private message Visit poster's website
  • Joined: 25 Feb 2006
  • Posts: 904
  • Location: Belo Horizonte, MG, Brazil
Reply with quote
Post Posted: Sat Jul 24, 2021 10:22 am
Pretty awesome!
  View user's profile Send private message Visit poster's website
  • Joined: 12 Apr 2005
  • Posts: 391
  • Location: London, United Kingdom
Reply with quote
Post Posted: Tue Jul 27, 2021 6:49 pm
Thank you for sharing, Maraakate, and thanks for linking to my site, Maxim! :) Hope everyone's been well here.

I'd been meaning to post something about this over here once I'd got it into a slightly more sensible state, I had been rushing it together to get something working for the RetroBattlestations competition hence the reliance on other retro hardware (such as the Cambridge Z88).

Since then I've done quite a lot of additional work, mostly on improving the graphics support (filled/outline circles and ellipses, filled rectangles and triangles are now implemented in both TMS9918 Graphics II and SMS Mode 4) along with getting the SOUND and corresponding ENVELOPE statements working as close to the BBC Micro versions as I can.

I've also moved the main BASIC and host interface variables to the high end of memory and put PAGE (the start of memory, where programs are loaded to) to $C000. When booting on-cartridge backup memory is enabled and tested to see if a) it's writable and b) whether it's mirrored to get an idea of its size. If present PAGE is then moved down by the appropriate amount to expand memory.

On a plain ROM-only cartridge this means you're still limited to an 8KB environment but if there's an 8KB or 16KB you can end up with a 16KB or 24KB BASIC machine, which is a lot more room to play in! So far I've only got that working on emulators as I don't have a cartridge with SRAM on-board to test with, but one additional side-effect is that if your program is smaller than your cartridge's battery-backed RAM it will be preserved when you switch the console off; when you switch back on just make sure you type in OLD and your program will be there!

I still need to make some decisions about connected hardware, though. At the moment a PS/2 keyboard is required in controller port 1 (using TH and TR; the other joystick buttons are passed through so you can still use the d-pad and a single fire button) and an RS-232 serial port is implemented in controller port 2 (using TH, TR, Up and Down, so no practical controller pass-through is supported there).

I think the keyboard is going to be a necessary requirement, and it's quite nice that you can still have most of a joystick working with one plugged in. The serial port is also pretty useful, but the way that it takes up four pins instead of two is a shame as it means you can't use it as a joystick pass-through. I think that maybe using the second controller port as an I²C bus interface would be a good plan, as I²C would only take up two pins (TH and TR again, same as the keyboard) and allow for the attachment of inexpensive EEPROM chips for file storage, a real-time clock so TIME$ can be implemented, as well as other common I²C peripherals that could be attached to the bus easily (e.g. ADCs or thermometers) to extend the machine.

One thing I really haven't worked on properly is the OSCLI implementation, which allows you to pass strings to the host's command line interface (either directly via a * command, or passing a string to OSCLI in a BASIC program). At the moment I have a handful of single-character commands that can perform some basic tasks (e.g. *T runs a terrible serial terminal, *H sends a "hello" message to the Cambridge Z88 using the PC Link 2 protocol to check it's there, *F:RAM.1/ lists all files on :RAM.1 on the Z88) but I think there should be commands to set up the environment, e.g. to define what controller or device is plugged into which port. At the very least being able to specify the keyboard layout, but also have commands to set the serial port baud rate, specify which device should be used by default to load or save programs from, define which joystick is plugged into which port.

Sticking a microcontroller in here would make life easier, but I'm somewhat keen to avoid that as it makes it a lot more challenging for others to replicate the project and it comes back to this idea of "cheating"! :)
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14959
  • Location: London
Reply with quote
Post Posted: Tue Jul 27, 2021 9:00 pm
I should also say I’m a big fan of the Z88 :) I’ve had mine since about 1994, sadly it doesn’t get much use and needs some repairs but it’s a really awesome little computer and probably the only electronics I own that was made in the UK :)
  View user's profile Send private message Visit poster's website
  • Joined: 12 Apr 2005
  • Posts: 391
  • Location: London, United Kingdom
Reply with quote
Post Posted: Tue Jul 27, 2021 11:08 pm
I hope your repairs aren't too tricky! I need to buy some more conductive ink/glue to repaint the corroded traces on the keyboard membrane on my "spare" Z88, I've had to do it two or three times already but it's just disintegrating with age (the rubber keyboard mat is also shrinking). They are great little computers but I wish Sinclair had used somewhat more reliable keyboards on their machines.

I'd really love to have a BBC Micro as that's what got me into computers in the first place but in the meantime running BBC BASIC on a Master System is providing some of that charm. :)
  View user's profile Send private message Visit poster's website
  • Joined: 12 Apr 2005
  • Posts: 391
  • Location: London, United Kingdom
Reply with quote
Post Posted: Mon Aug 16, 2021 1:14 am
I'm still working on this, I posted this video on Twitter a few days ago and people seemed interested in it so I thought I'd share it here - loading BBC BASIC programs from "tape" (well, a phone playing a tape image) onto the Sega Master System:



There's an accompanying journal post on my site here: https://benryves.com/journal/3763171

Now that I'm loading programs designed specifically for the BBC Micro I'm running into more obvious discrepancies between the systems. Has there ever been much done into finding a safe area for the screen to output text to before material gets lost in the overscan?

At the moment I've reduced the TMS9918 text mode to 38/40 characters width and moved the left edge over two characters. This seems to match what BASIC on the SC-3000 does.

I've also reduced the other modes to 28/32 characters width, bringing in both the left and right margins by two characters.

On my TV the left and right columns in the 32-character modes are definitely off screen and half of the second column is also off screen. If I could enlarge the text viewport to the central 30 characters then I'd also need to apply a half-character fine-scroll adjustment to get all 30 characters fully on screen which seems like a bit of a hack, especially as that much of a difference can also be accounted for by switching between SCART and composite cables. On the other hand, I know that my TV has particularly bad (wide) overscan as a lot of games lose stuff in their status bars off the sides of the screen so maybe I'm overthinking this. If you're using a modern TV and some sort of HDMI-scaling box then these tend to show you the entire picture too!

If I could at least use a 30x24 text area then that would be great as it would match the aspect ratio of the graphics plotting area. It would be 240x192 pixels and BBC BASIC expects a logical screen size of 1280x1024. It would mean dividing logical coordinates by 5⅓ to get the physical coordinates, but that's the same as multiplying by 48/256 (or 3/16) so not too tricky.

My current approach is to use the entire 256 pixel width of the screen and divide logical coordinates by 5, which means some BBC Micro programs draw stuff just off the top edge of the screen.
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!