Saturday, 23 November 2013

BASIC on the Sega Master System

I decided to do some hacking on the Sega Master System, to see if I could get it running BASIC. It has long been a dream of mine to program the Master System. When I first got my Master System in 1992, I saw it as an upgrade on the ZX Spectrum I previously used, the kind of upgrade on the graphics I had wanted since the Spectrum 128K came out in 1986. I didn't know anything about the differences between the two machines back then, about sprite graphics, hardware scrolling, tile mode versus bitmap mode graphics, but the Master System taught me about those.

In principle it should be very simple running BASIC on the Master System. The Master System is backwards compatible with an earlier console called the SG-1000 and a home computer called the SC-3000. Versions of BASIC exist for both the SG-1000 with SK-1100 keyboard attachment and the SC-3000.

However, the Master System I have is a UK PAL version, referred to by Sega in their documentation as an Export version, and that has a completely different cartridge slot from the Japanese models. Furthermore, the BIOS in export Master Systems checks for the presence of a ROM header in the last 16 bytes of a cartridge, checks that the ROM is intended for export Master Systems and performs a checksum on the ROM. Domestic (i.e. Japanese) Master System cartridges and all SG-1000 and SC-3000 cartridges (whether domestic or export) do not contain this header.

Thus, my UK PAL Master System will not run SG-1000 BASIC Level 2 or SC-3000 BASIC Level 3 images without some hacking.

First I tried running BASIC Level 2 and BASIC Level 3 images in my Tototek flash cartridge. The Tototek DreamWriter software had problems identifying the ROM images; it seems it too was relying on the header information, and the lack of a header in the ROMs was causing DreamWriter to make incorrect assumptions about the images.

So first I tried patching the images using a hex editor to include a correct export version header. This would be something like:

54 4D 52 20 53 45 47 41 20 20 -- -- 00 00 00 4C

where -- -- is the checksum of the image (from $0000 - $7FEF for 32K ROMs) in little endian format.

Well this worked for the DreamWriter software, and I was able to load BASIC Level 2 and BASIC Level 3 into my flash cartridge, correctly recognised as 32K ROMs. These ROMs would now start in the Master System, but they didn't get as far as the Ready prompt. BASIC Level 2 would give a black screen with a repeating single beep error code and BASIC Level 3 would give a black screen with a repeating double beep error code.

So I disassembled the two ROMs and found the cause of BASIC Level 2's single beep. There is a checksum routine in the code of BASIC Level 2. It sums all the contents of the ROM from $0000 to $7FFF and checks that the least significant byte of the result is zero. Looking at the final 16 bytes of the ROM before I inserted the header, most of the unused bytes in the ROM are FF but the final byte in the ROM is something else - 38h. This was clearly intended to make that checksum byte equal zero.

Since there's already a checksum operating on this ROM at BIOS level now, I decided to remove the jump for this now redundant checksum and after updating the checksum in the header to account for this change to the ROM, the BASIC Level 2 image would now run in my flash cartridge, giving the following startup screen.

The 32K ROM now works fine and the image runs as a BASIC Level IIA cartridge, with 2K internal RAM at $C000 - $C7FF.

I couldn't get BASIC Level 3 to work, however. Even with the checksum jump patched out and the correct header in place, it would fail with a two beep error code. So I studied the BASIC Level 3 RAM checking routines and I found one of the first things BASIC Level 3 does is set the stack pointer to 8B30h. A few instructions later it does some stack operations and checks to see that the stack can be written to and read from properly. If this fails, then it jumps to the two beep error code routine.

So BASIC Level 3 expects to find, and indeed relies on, RAM at $8000 - $BFFF. I decided to build a cartridge to support BASIC Level 3, using a game cartridge PCB, a 27256 EPROM and a 62256 SRAM. I used a Miracle Warriors PCB, mainly because it provides two sockets, one for the ROM and one for the RAM. Using the pinout diagrams now available on I worked out that there were four pins that needed changing on the ROM socket and four on the RAM socket. I took out the battery and battery backup circuit, made three PCB track cuts and made the new connections with wire. A 74LS32 quad 2 input OR gate was used to decode the address ranges for the EPROM and SRAM. The EPROM goes at $0000 - $7FFF, fortunately there is a signal M0-7# on the cartridge slot which goes low in this address range when MREQ# is low. I combined this with the chip enable pin for that cartridge slot, CE3#, using one of the OR gates and applied the result to the CS# pin on the EPROM. I connected the output enable pin OE# to RD# of the Z80 processor. For the SRAM I used the address range $8000 - $BFFF and the signal M8-B#. This was combined with CE3# in the same way and the RAM socket already had OE# connected to RD# and WE# connected to WR#.

The Japanese version of the Master System / Mark III and the SC-3000 computer all have a signal on the cartridge slot called CSRAM# which allows the internal SRAM in the console to be disabled. That's how BASIC Level IIIB disables the internal 2K SRAM of the SC-3000 in the $C000 - $FFFF address space and puts 16K DRAM in that space. The export Master System has no such signal on the cartridge slot; instead the internal 8K RAM in that address space can be disabled by writing a bit to I/O port 3Eh. However, this requires that any cartridge that wishes to put RAM in that space has a 315-5235 mapper chip, so that the cartridge RAM can be enabled only once the internal RAM has been disabled.

My simple EPROM and SRAM cartridge has no mapper chip and so half of the 32K SRAM is unused in this design. BASIC has access to RAM at $8000 - $BFFF from the cartridge and at $C000 - $DFFF from the internal RAM (mirrored at $E000 - $FFFF). This comes to a total of 24K, higher than the 18K of BASIC Level IIIA but lower than the 32K of BASIC Level IIIB. The machine actually has 40K of RAM in total, but only half of the 32K SRAM is accessible.

I tried this cartridge with a BASIC Level 3 ROM image burnt onto an EPROM and it still failed with a two beep error code so I tried an SMS Boot Loader EPROM I had previously burnt and that worked fine so confirming that the address decoding for the EPROM worked okay. Next I tried a BASIC Level 2 ROM image and got this screen:

This is the startup screen for BASIC Level IIB. Having now studied the RAM checking routines in BASIC Level 2, it looks for 2K of RAM between $C000 - $C7FF and 2K of RAM between $8000 - $87FF. It runs as BASIC Level IIB (with 2043 bytes free) if it finds both and as Level IIA (with 515 bytes free) if it only finds the latter. It fails with a two beep error code if it doesn't find any RAM at all, and with a three beep error code if the 16K VRAM is not working properly.

So both my EPROM and SRAM address decoding were working fine. I wondered if the different RAM size in my design versus the original BASIC Level IIIA and IIIB cartridges was causing the problem so I examined the BASIC Level 3 RAM checking routine and sure enough, it had been hard coded to write to RAM at $C000 and then at $C800, and see whether separate results could be stored at those two locations. If they could, it assumed it was running on a 32K RAM machine and if they couldn't, it assumed 18K RAM. My 24K system was passing the test at $C800 and so BASIC Level 3 was assuming a 32K machine and failing another memory test later on. So I modified the code to check $C000 and $E000 instead, for 24K RAM, and finally BASIC Level 3 booted.

In conclusion, for now at least, I have a 24K version of BASIC Level 3 running on my Sega Master System. I still need to put together a keyboard to type on this system; for now you can type a few characters on the 12 switches of two control pads, but it really needs an SC-3000 keyboard with an Intel 8255 PPI chip and a 74LS145 open collector decoder/driver to read the keyboard properly. I have some ideas about how to build one of these reversibly out of an SC-3000H computer and connect it to this Master System which I will try next. I also have some ideas about doing some more ROM hacking to BASIC Level 3 to get my Tototek flash cartridge to recognise it as a 32K ROM 32K RAM cartridge with the 315-5235 mapper hardware emulated at the appropriate addresses.

No comments: