It has been almost a year and a half since I defended my diploma thesis about Galaksija, the now almost forgotten Yugoslavian microcomputer from the 1980's.
My replica has been mostly gathering dust all this time, since I hadn't had much time to play with it since I got employed by Zemanta. Recent work by Stefano Bodratto on the Galaksija port of z88dk however reminded me again of the good old 8 bit days.
Then, during the 25C3 in Berlin, I listened to Michael Steil's Ultimate Commodore 64 Talk. His detailed description of Commodore's graphics modes and the hacks to get more pixels and colors pushed through the VIC made me remember some ideas I had on how to get a higher resolution graphics out of an unmodified hardware of the original Galaksija. Just to be clear, I'm not talking about Galaksija Plus here. Plus was the later model that supported high resolution graphics out of the box due to a modified character generator circuit.
I opened up my electronics projects folder and dug out the schematics and documentation I've written. And in about two weeks of on and off evening work I got it to work. So, 25 years after Galaksija was introduced to public here is the first-time demonstration of this computer displaying more than just the ordinary low-resolution 64 by 48 character graphics.
(watch the video on YouTube)
How did I do this?
Video generation in Galaksija involves a carefully tuned combination of hardware and software. In short, the Z80 CPU is used as a video address generator. Since it's too slow to bit-bang pixels directly on the screen, its dynamic memory refresh counter is used as a way to sequentially read contents of the frame buffer to the screen. The bytes of data from the buffer get transformed to the actual pixels by a character ROM. The refresh counter runs continuously and can't be direct controlled by the software. It's period depends a little bit on the instructions that the CPU is executing and can only be reset to a known value by a relatively expensive load instruction.
Controlling Galaksija's video hardware is a matter of high precision programming. The code must have perfect timing. Each instruction must be accounted for, down to each cycle of the clock and except for the horizontal blanking period between two consecutive scan lines there are severe restrictions on which instructions can be executed to keep the refresh counter running deterministically.
The original video driver manages to perform this job in a wonderful way. As if timing restrictions weren't enough it also saves a bit of ROM space by having a part of the code also serve as an ASCII string "BREAK" and a 1.0 floating point constant.
Without being restricted by the lack of space in ROM the video driver can be done in a better way. The original video driver re-reads a single 32-byte line from the frame buffer for 13 scanlines, to construct one line of characters on the screen. With 512 bytes of RAM reserved as a framebuffer, this gives 32 x 16 characters. Since there are 2 x 3 graphics symbols available in the character set, the full resolution is 64 x 48.
However apart from the lack of CPU time there is no theoretical reason why it can't read a different frame buffer line for each scan line. You're still limited by the pixel combinations in the character ROM on the horizontal of course, but on the vertical you can do the full PAL resolution.
The first reality check is the amount of RAM available for the video buffer. The original Galaksija has 6 kB, so you get to choose either more pixels on the screen or more space for code to actually do something with those pixels.
I opted for a trick here: since I'm already limited on the horizontal with the character ROM, I decided to stay with Galaksija's character graphics, but I only read three scan lines from each character. This compresses the character set vertically and removes empty scanlines between rows. I decided to go with a 2 kB framebuffer, giving an effective resolution of 64 x 192 and 6 pixels per byte.
The second problem is how to control the video interrupt routine since the Z80's hardwired interrupt vector resides inside the ROM. Luckily, this problem has already been solved on ZX Spectrum and a similar solution is applicable on Galaksija. This however takes additional 260 bytes for the vector trampoline area, which I decided to put in place of the original framebuffer.
I won't go into much detail about how the high-res video driver is written as I'll be releasing the assembly source code in a few days. I only managed to get the timing right after unrolling the scanline loop a little, but the code still takes a little less than 170 bytes of RAM. So even with a conservative estimate you still have around 3.5 kB RAM free for any software that uses the new graphics mode.
One interesting point here is that I don't use the A7 clamp in the new video driver. The original software uses a tricky little piece of hardware to clamp the 7th CPU bus address line to 0, which effectively remaps upper halves of all 256 byte blocks of RAM to their lower halves. I always found this technique interesting because it made the original driver even harder to design - you also had to make sure that no code path ventured outside of the lower blocks when remapping was active. The rationale was that this is a work-around for Z80's feature of not incrementing the 7th address bit of the memory refresh counter. However my work here shows that a hardware solution is not necessary as this can be also worked around in software, by resetting the R register with correct values at the correct moments.
So, I invite any owners of the original hardware to test out this demo themselves. It has currently been tested on my CMOS replica, but I'm confident that its circuits exactly reproduce the function of the original, so it should work correctly on vintage hardware as well.
There is a GTP and a WAV file available for download. WAV file should be suitable for directly uploading into Galaksija through an audio port. The GTP file has to be first converted to audio using my gtp2wav utility.
No Galaksija emulators are currently able to run this demo since they do not emulate the video hardware in enough detail.
Finally I would also like to invite anyone that has any evidence that this has been done before to drop me a mail. I've heard numerous rumors of Galaksija software that used some kind of high resolution graphics. But in my studies I never found any reliable evidence that any ever existed and most rumors turned out to be inconsistent with the capabilities of the hardware.