Tuesday, 30 November 2021

Lunchtime Coder #12 - Space Invaders Colour Overlay

EUGH! Now I remember... That's how they looked, only not even that good...

Once you have a good functional monochrome emulator, the next step is to add a splash of colour!

Space Invaders used several different ways to add colour, before finally including colour map EPROMs in Space Invaders Colour.

The first way was using a colour cellophane overlay stuck onto the front of the cathode ray tube so that the monochrome graphics were tinted various colours in bands.

I decided to try and simulate this style of colour, but when I googled the subject to try and find some more information, I found that the subject is somewhat confused with many different alleged colour overlay schemes all differing slightly.

The challenge for me was to:

(1) Find the proper original colour scheme for the Space Invaders Upright and Cocktail cabinets.

(2) Find a pleasing way to simulate this colour overlay on my emulator.

1. Finding the right colour scheme for Space Invaders Cocktail arcade cabinet and implement into emulator.

Well the Cocktail cabinet was easy. I downloaded a package of MAME Space Invaders artwork, and the Cocktail cabinet overlay was amongst the artwork. A google image search for Space Invaders Cocktail Overlays showed that this overlay matches with some pictures of actual Space Invaders Cocktail cabinets. This overlay also matches what I thought it would be for a Cocktail cabinet being banded identically from the centre of the screen outwards.

The Cocktail cabinet colour overlay from MAME artwork

Validating this as 100% correct is difficult, as despite there being a number of pictures of alleged original Space Invaders table top/cocktail cabinets, a lot of the overlays differ with each other. Whether this is because they are third party reproductions, or there were several options available at the time, I don't know, however some of them are pretty similar to the MAME overlay, similar enough for me to settle with it.

Close enough for Government work

And so to test with my emulator...

A hint of colour with an alpha'd Cocktail cabinet colour overlay

You can see that it only really provides a hint of colour, and being a Gen-X this was exactly how I remembered the colour overlays being, to the point that you almost wondered why they bothered?

And with some simulated scan lines

2. Finding the right colour scheme for Space Invaders upright arcade cabinet and implement into emulator.

This one was fairly straight forward too being that I had seen them numerously as a kid.

From what I do remember, I was pretty surprised at how bad they were. I assumed that the overlay had been fitted badly as I remember there being gaps between some of the colour bars where you could see white graphics, and that the overlay didn't even cover the whole of the screen, with white graphics poking out of the bottom. I also remember that two of the colours were very garish yellow and purple.

Luckily Taito gave away how the overlay actually looked in numerous later Space Invaders releases including the arcade Space Invaders DX and on the PS1 with Space Invaders 2000, 1500, The Invader and SD Gundam Invaders, as well as a bunch of other releases on other various platforms.

PS1 Space Invaders 2000 - The Top Right option shows Space Invaders with Colour Overlay
PS1 Space Invaders 2000 - In Game with Colour Overlay

For some strange reason, PS1 Space Invaders 2000 shows the colour overlay from the upright cabinet on a cocktail cabinet... No idea why? Its clearly the upright cabinet one as it matches exactly with the one I remember.

So taking this as the pattern for an upright cabinet, I made my own overlay based on the colour scheme that Taito supplied.

My own Upright Cabinet Overlay

Now this can be added over the screen as an alpha'd overlay, however it could also be implemented just as colour bands to change the colours of the pixels as they are drawn.

There are pros and cons to both of these methods:

Overlay - Pros: Authentic looking. Cons: Not aesthetically pleasing.

Pixel Colour - Pros: More Aesthetically Pleasing. Cons: Not authentic looking.

Lets try both.

Standard Overlay Style - Looks pretty authentic although I'm sure the colours need tweaking slightly
And with simulated scanlines
No overlay but pixels coloured the same as the overlay would be
And with scanlines

My personal opinion, the overlay looks better. More garish and less colour tint to the pixels, just like the real thing.

I found a colour chart on google for Space Invaders correct colour scheme, so I may try and adjust the base colours on my overlay to make it a bit less garish and more authentic.

There are at least two other monochrome arcade titles that had colour overlays, Space Invaders II and Space Invaders Deluxe, so the next task is to try and bottom those two overlays out.

Thursday, 14 October 2021

Lunchtime Coder #10 - Space Invaders RAM Mirror

Whilst I was gathering information to write my Space Invaders emulator, I came across some information that completely baffled and stumped me.

It was on the computerarcheology.com website under the Space Invaders Hardware page.

It was under the title "Memory Map" and stated the words "RAM mirror".

I had never heard of a RAM mirror before and had absolutely no idea of what it was, or what the term meant.

Did I need to allow for more RAM in my emulator? Was my emulator written incorrectly?

After a lot of reading from various different sites, I managed to put together the full picture of what a RAM mirror is and why it occurs, and I thought that it would be useful to explain this for other budding emulator enthusiasts.

Does It Affect Space Invaders Emulation?

The good news is that the RAM mirror will not need to be considered in a Space Invaders emulator.

Despite someone on an emulation forum insisting that a Space Invaders emulator needed more than 16 kB of memory to work correctly, it doesn't.

An 8 kB ROM area and an 8 kB RAM area arranged in one 16 kB memory area is all that is needed for a Space Invaders emulator. If your emulator is addressing above 16 kB, you have a bug.

So It Only Affects Space Invaders Hardware Then?

Well, no not really. An arcade Space Invaders machine doesn't contain a RAM mirror either, but it does have the potential to contain one.

Well What The F%&! Is It Then?

It was a way of saving time, money and resources when making the Space Invaders circuit boards.

The Intel 8080 processor has a 16 bit memory address bus, meaning that it can read and write to up to 64 kB of memory.

This address bus is accessed using 16 pins on the Intel 8080 processor. The address bus itself is just wires, or tracks on a circuit board.

16-Bit Address Bus Accessed Using Pins A0 to A15

But Space Invaders only uses a 16 kB memory area, and 16 kB can be accessed using only a 14 bit address.

To save time, money and resources, only 14 of the 16 address pins are wired or have tracks present on the circuit board to the memory area. Pins A14 and A15 are left unwired or untracked as reading from or writing to addresses beyond 16 kB will never be required in the Space Invaders cabinet. 

This means that at the memory end of the address bus, A14 and A15 are undefined; they are neither a 1 or a 0.

Because of this, If you write to RAM, all combinations of pins A14 and A15 will be written to RAM.


A RAM write of the value 0xff to address 0x3988 will result in a write to:

1. 0xff written to 0x3988 (A14=0 A15=0)
2. 0xff written to 0x7988 (A14=1 A15=0)
3. 0xff written to 0xb988 (A14=0 A15=1)
4. 0xff written to 0xf988 (A14=1 A15=1)

The RAM is mirrored every 16 kB and hence the term RAM mirror.

It would be the same case if the processor code was trying to make a write to 0x7988 or 0xb988 or 0xf988. Because the top two bits of the 16 bit memory address are undefined, the memory area will see all 4 addresses as the same address, with two undefined bits.

If it was only the 16th pin (A15) that hadn't been wired, then you would have a RAM mirror that mirrored every 32 kB, and likewise if it was the 14th, 15th and 16th pins (A13, A14 and A15) that hadn't been wired, you would have a RAM mirror that mirrored every 8 kB.

And that's the RAM mirror (or potential RAM mirror) in an arcade Space Invaders cabinet.

Friday, 1 October 2021

Lunchtime Coder #09 - Testing and Debugging a Space Invaders / Intel 8080 Emulator

It can be very frustrating when the code you have written doesn't do what you want it to do!

With an Intel 8080 emulator, you have 256 opcodes to write code for, meaning that all sorts of logic, syntax or just general brain fart errors can be buried in there somewhere causing all manner of unexpected behaviour when you try to run your emulator.

Fortunately help is at hand, and that help comes in the form of CPUDIAG.

CPUDIAG is an old Intel 8080 test program designed for use on CP/M machines. Its visual output is designed for sending ASCII characters to a printer, however once you get a basic idea of how the program works, you can use your own error monitoring to point out groups of opcodes that potentially have an issue.

I thought that a simple tutorial was in order to explain how this program can be used in a far simpler fashion than was originally intended, and to show how to get the most of of this useful test program.

In this tutorial, we will cover the following topics:

1. Preparation for using CPUDIAG.
2. Loading CPUDIAG into your emulator.
3. Interpreting the results.

1. Preparation for using CPUDIAG.

All good emulators should be able to generate a debug log. Its a valuable part of being able to determine your emulator output at a processor level, and can be very useful in tracking down bugs and issues.

A debug log should include all of the processor key parameters such as:

  • An opcode Count
  • Program Counter
  • Stack Pointer
  • Opcode Hex Value
  • Opcode Name
  • Operand or Operands
  • Register Values
  • Flag Values
  • I also include the value in the memory location stored in register pair HL

CPUDIAG only checks the functions of processor Opcodes, so if your Intel 8080 emulation is buried amongst other emulator parts e.g. Shift register / Display Output etc. then these can all be disabled.

CPUDIAG will run clusters of Opcodes and then do comparison checks. If the comparison checks come out incorrect, the program does a conditional call to 0x0689 to give an error report.

Rather than trying to code the output of the error report, it is much simpler to have a monitor program checking to see if Program Counter is set to 0x0689 and stopping the CPUDIAG code running if it does.

You will also need a binary file of CPUDIAG.

Download CPUDIAG.BIN Here!

2. Loading CPUDIAG into your emulator.

CPUDIAG needs loading into your emulators memory with the first byte at 0x0100.

You will then need to set your Program Counter to start reading the code at 0x0100.

3. Interpreting the results.

So, you run your emulator with CPUDIAG loaded into its memory. CPUDIAG runs then stops because the routine that you added to stop emulator execution if Program Counter is set to 0x0689 has activated, meaning that CPUDIAG has found an error in an opcode.

Its time to consult the debug log. Look at where the code has come to a grinding halt, then backtrack up the opcodes to the last opportunity that the program had to CALL to 0x0689 but didn't. The error is in an opcode between these two points.

Example Debug Log Output:

We can see that at Opcode Count 177 (Highlighted Green), a CNZ opcode was run. Fortunately the Z flag was set and so the program didn't call an error.

For the purposes of the example, we can see that at Opcode Count 193 (Highlighted Yellow), again a CNZ is run which will Call to the error routine if Z is not set. If we assume that Z isn't set and that's where your emulator stopped, we can see that there has been 16 Opcodes executed, so the error must lie in one of these opcodes.

Furthermore, we can see what each opcode did, and the affect it had on the processor key values. Opcode Count 180 shows an MVI C, D8 0x03 or move the immediate value 0x03 into register C. We can see on the next line that 0x03 is in register C and so this Opcode appears to be working correctly.

It can be seen that CPUDIAG is a useful tool to debug emulators. Even when I had Space Invaders fully working correctly, CPUDIAG still found two small errors in my Opcodes caused by incorrect syntax, so its always worth running your Intel 8080 emulator through it.

There is also a very good test program for 6502 emulators. Its designed specifically around 6502 emulators for the NES and so doesn't test decimal functionality, but it comes with its own debug log ready run and supports a number of "Illegal" opcodes so its simply a case of comparing your debug log against theirs and applying fixes until they are both the same. The program is called NESTEST.NES and was invaluable when I was trying to get my head around indirect addressing.

Lunchtime Coder #8 - Emulating the Intel 8080 DAA Opcode

There seems to be a real stigma around emulating the DAA opcode for reasons that I cannot understand.

I have even seen websites telling you not to bother emulating either the DAA opcode, or the Auxiliary Carry flag as their uses are limited and its not worth the hassle...

For me it was tricky but not that bad. Once you understand what DAA and the Auxiliary Carry flag do, it becomes pretty straight forward to code.

I decided to write a brief tutorial on both to assist other budding emulator coders and to show that it ain't that bad.

This tutorial assumes that you have an understanding of both Binary and Hexadecimal and will cover the following topics:

  • The basics of the DAA Opcode.
  • Usage of the DAA opcode
  • The Auxiliary Carry Flag.
  • Advanced DAA and Aux. Carry Flag.

1. The Basics Of The DAA Opcode.

The DAA or "Decimal Accumulator Adjuster" opcode is used to make the value in the accumulator look like, and behave like a decimal value.

It takes a binary value and converts it into a "Binary Coded Decimal" value.

As we know, in a byte we have 8 bits that can be set to 1 or 0. This is clumsy and awkward to work with directly and so Base 16 or Hexadecimal is used to represent the 8 bits in a simple two figure value.


Binary Value - 11010010
Hexadecimal Value - d2 or d2H or 0xd2 or $d2 depending on what notation you are using.
Decimal value - 210

To convert the binary value into a Hexadecimal value, the binary value is split into two 4 bit words known as nibbles. The byte is split into a higher and lower nibble, and each nibble is then converted into a single Hexadecimal digit.

What the DAA Opcode does is check the value of the higher and lower nibble, and if the values are not within the decimal range i.e. 0 to 9, it adds 6 to that value to bring it back into the decimal range.


Decimal range - 0 1 2 3 4 5 6 7 8 9
Hexadecimal range - 0 1 2 3 4 5 6 7 8 9 a b c d e f
Binary Value - 11010010
Hexadecimal Value - d2
Lower Nibble - 2 falls into the decimal range and so remains unchanged by DAA
Higher Nibble - d falls outside of the decimal range and therefore 6 is added, resulting in the value 3 with a carry.
DAA Hex Value - 32 with a carry

By adding six to a value outside of the Decimal range, the value is "skipping" over the a, b, c, d, e and f Hexadecimal counts, and making each figure look and behave like a decimal value.

Simple Pseudo code example:

Split Accumulator into High and Low Nibble.
If low nibble>9 then low nibble=low nibble+6
If high nibble>9 then high nibble=high nibble+6

This example is a vast over simplification, as there would be a carry from the low to the high nibble if the low nibble were greater than 9 and then 6 was added, and the same would go for the high nibble, but it illustrates the basic principal of the DAA opcode.

The carry from the low to the high nibble every time the value is outside of the decimal range is the important part of both DAA and the auxiliary carry bit. It is saying that if the value is greater than 9, then in decimal, the value would be 10 or above and so skip over the non decimal values to get to 10 or above so that the Hexadecimal looks like decimal, and also carries to the high nibble as if it were decimal.

2. Usage of the DAA Opcode.

Because the DAA opcode can make values in the Accumulator appear to be decimal values, the uses for early video games were normally values that required displaying on screen and were required to increment or decrement in a decimal style.

These would be items like your Score, number of credits remaining, fuel left etc.

Because the Binary Coded Decimal value can only contain numbers in the decimal range, a byte can have a maximum Binary Coded Decimal value of 99.

For routines like decrementing credits, 99 would be added to the current credits value to decrement the value by 1 e.g. 99+99=98 and a carry.

For score routines, the general routine would go something like this:

1. You shoot an invader.
2. The "Current Score" in RAM is read into the accumulator.
3. The fixed score in ROM for the invader you have shot is added to the Accumulator, and the flags set accordingly.
4. The DAA opcode is run to convert the value in the Accumulator into Binary Coded Decimal.
5. The new current score is stored from accumulator back to its RAM location.

Lets look at some examples:

Example 1 - DAA does nothing.

Current score=20 (This is Hexadecimal 20, but looks like Decimal 20).
Score for Invader shot=20 (Again Hexadecimal 20 but looks like Decimal 20)
New score=20H + 20H = 40H (This looks and behaves like Decimal, so no actions for DAA to do)

Example 2 - DAA into action.

Current Score=25 (Hexadecimal 25, but looks like Decimal 25).
Score for Invader shot=25 (The same as above).
New Score= 4a Hexadecimal
The low nibble (a) is greater than 9, so DAA will add 6 to the low nibble making it 0 with a carry to the high nibble.
New Score=50 (Hexadecimal 50 but looks like decimal 50, and 25D + 25D = 50D. All good.).

Example 3 - DAA needs help!

Current score=28 (Hexadecimal 28 but looks like decimal 28)
Score for Invader shot=28 (The same as above)
New Score=50H (The lower nibble is in the decimal range and so DAA does nothing).
Decimal 28 + Decimal 28 does not equal Decimal 50. The final value is 6 out.

Because of the carry between the low nibble and the high nibble during the ADD opcode that DAA isn't aware of, 6 hasn't been added to the lower nibble to skip over the a, b, c, d, e and f hexadecimal values in the range, and therefore the final score is 6 values too low.

DAA needs a "trigger" to tell it to add 6 to the lower nibble if this happens, and that trigger is the Auxiliary Carry Flag.

3. The Auxiliary Carry Flag.

The Auxiliary Carry Flag is similar to the Carry Flag in that it indicates where a carry has occurred, but it indicates a carry from the low nibble to the high nibble of the Accumulator.

Its pretty easy to test this, especially when carrying out an ADD opcode.

Before you add the value to the contents of the Accumulator, add the low nibble of the value to be added to the low nibble of the Accumulator, and if the value is greater than 15D set the Aux. Carry Flag to 1, else set it to 0. Its pretty much that simple.

Then the ADD can be carried out and after this, the Carry flag can be set appropriately.

It is critical that there is no action that will reset either the Carry bit or the Aux. carry bit between it being set by the preceding arithmetic opcode, and it being used within the DAA opcode. The DAA opcode should follow on directly after the Arithmetic opcode, and there should be nothing in your code for the DAA opcode that can reset the Aux. Carry flag before the Accumulator low nibble has been checked or reset the Carry Flag before the High nibble is checked.

Pseudocode for ADD

if Accumulator low nibble + value to be added low nibble > 15 then
    Aux. Carry flag=1
Aux. Carry flag=0
end if

Accumulator=Accumulator + value to be added

if Accumulator>255D then
    Carry flag=1
    Carry flag=0
end if

Zero Flag check
Parity Flag Check
Sign Flag Check

4. Advanced DAA and Aux. Carry Flag.

And so with everything now in place, we can revise our Pseudo code for the DAA opcode, assuming that we have just executed an ADD opcode (All numeric are in decimal):

'Process Accumulator Low Nibble
If Accumulator low nibble>9 or Aux. Carry flag=1 then
    Accumulator low nibble=Accumulator_low_nibble+6
    if Accumulator low nibble>15 then
        Accumulator low nibble=Accumulator_low_nibble-16
        Accumulator high nibble=Accumulator_high_nibble+1
        if Accumulator high nibble>15 then
            Accumulator high nibble=Accumulator high nibble-16
            Carry Flag=1
            ' NOTE - At this point you DO NOT
 DO "Else Carry Flag=0"
            ' There should be no mechanism that can reset Carry flag between being set in the ADD opcode
            ' and being used in the processing of the high nibble in the DAA opcode.

        end if
    end if
end if

'Process Accumulator High Nibble
If Accumulator high nibble>9 or Carry flag=1 then
    Accumulator high nibble=Accumulator_high_nibble+6
    if Accumulator high nibble>15 then
        Accumulator high nibble=Accumulator_high_nibble-16
        Carry Flag=1
        Carry Flag=0
    end if
end if

This process is obviously long winded and functions / binary notation etc would be used in reality, however that is the basic requirement.

And that is how to emulate the DAA Opcode and Auxiliary Carry flag.

Wednesday, 30 June 2021

Lunchtime Coder #7 - Space Invaders Emulator - High Score Load / Save

The original Space Invaders arcade cabinet doesn't have a high score save facility built into it.

The high score would be kept until the machine was switched off, and when it was powered up again, the high score would be reset to 0000.

But this is emulation, so we can do what we want, right ? ( providing that the brain power to do it exists... ).

So lets add a High Score save routine into the emulator.

I wanted to do this without any external website help, relying instead on already gained knowledge and educated assumptions.

The plan is for the high score to be saved in a small external file. This would be loaded as you start the game and would be poked into the Space Invaders Emulator memory.

Periodically, the values in the save file would be checked against the live high score values, and the file values updated if required on the fly.

I don't know a massive amount about how the Space Invaders code executes. I mean, I wrote an emulator yes, but that was an Intel 8080 processor machine code interpreter. I didn't actually write Space Invaders itself.

It's akin to writing a German to English book translator. Just because the program you have written translates a German book into an English book, it doesn't mean that you have read and understood the contents of the book.

So how to set about being able to load and save the high score?

Well, Here's what I do know:

  1. The high score displayed is in BCD or Binary Coded Decimal. Its 4 digits long and as the maximum value a byte can store in BCD is 99, this means that there are two bytes to the high score.

  2. The score looks like decimal, but the value is actually a hexadecimal value.

  3. Space Invaders has an 8 kB ROM area and then 8 kB of RAM. This is addressed by the processor as one 16 kB lump of memory. The lower 8 kB being the ROM area, the next 1 kB being general purpose RAM and then the top 7 kB being a 1 bit bitmap of the display.

  4. Early on in the Space Invaders code, an area of ROM is copied byte by byte to an area in the general purpose RAM.

  5. As the high score changes in game, its certain that the two High Score bytes must be in the general purpose RAM area.

Based on what I do know, I can now make some educated guesses to fill in the blanks:

  1. Lets make an assumption that the two bytes are next to each other in the general purpose RAM.

  2. Lets also assume that these two bytes exist in the ROM (as 0 and 0), and are copied across to the RAM area at the beginning of the code execution. (You may ask why I would assume that 0's would be copied from ROM to RAM, when the RAM should already be at 0? Well, I do know that after the ROM area is copied to RAM, the code then writes 0's to the whole of the bitmap RAM area to ensure that the screen is blank to start with, so I am guessing that late 70's RAM wasn't massively reliable on what state it was at on power up.)

With what we do know, and what we have made assumptions on, It should now be possible to play the game and get a known BCD value high score, and then do a reverse BCD conversion from the high score displayed, to what's stored in the two bytes.

We can then do a mid game RAM search for those two High Score bytes.

Once the locations of the high score bytes are identified, we can then go back to the beginning of the code execution when ROM is being copied to RAM, and trace the ROM location that the bytes are copied from.

And finally, we can then test what we have found by poking the two ROM locations with some set values, and seeing if the game starts with a high score equivalent to those values that we have put in the ROM.

Time to test the theory.

Lets say that our high score is 1580.

Split that into two bytes: 15 and 80. Remember these values are Binary Coded Decimal so the maximum value per byte is 99.

But BCD is hexadecimal, so we need to reverse the hexadecimal to find the true decimal value in the bytes. (Note: I am programming in a language that does not allow me to deal with binary values directly, and hence the whole emulator works in decimal).

In the case of 80 we do: 80+(integer(80/10)x6) or 128.

In the case of 15 we do: 15+(integer(15/10)x6) or 21.

Having played a game and achieved a high score of 1580, we now pause the game and do a search across the 1 kB of ram for the two high score values. I don't know which order they would appear, MSB or LSB first, so am looking for the LSB, and if found will check each side for the MSB.

And we have a winner! RAM memory locations 0x20f4 and 0x20f5 contain the High Score LSB and MSB.

Ok, so now to take a slow look at the beginning of the code executing.

The routine that copies bytes from the ROM area to RAM basically goes:

  1. Load the accumulator with the byte value at the 16 bit ROM address stored in register pair DE.

  2. Load the memory location at the 16 bit ROM address stored in register pair HL, with the value in the accumulator.

  3. Increment the value in register pair HL by 1. This moves the RAM destination address up by one byte.

  4. Increment the value in register pair DE by 1. This moves the ROM source address up one byte.

  5. Decrement the value in register B. Register B counts off how many bytes have been copied. When it gets to 0, the copying stops.

By running this routine slowly until register pair HL = 0x20f4, The next instruction in the code should increment register pair DE to the ROM source location of the first byte of the initial high score value.

And this works like a charm. 0x1bf4 and 0x1bf5 are the magic locations in the ROM with the very important task of storing two zeros for the initial high score value.

To use this in a practical way within the emulator, the values need to be poked into the Space Invaders emulator ROM area.

The emulator ROM and RAM area are represented by a 16 kB array. The ROMS are loaded into the bottom 8 kB, and once this is done, the two high score bytes can then be written to the correct ROM area.

Once this is done, the game will start with the high score value already set to the values poked into the ROM area, and these values can be read from a small pre-saved file.

For writing any new high scores to the file; After each screen update, the combined value of the two bytes in the file are compared with the combined value of the two bytes in the RAM at 0x20f4 and 0x20f5, and if the later is a larger quantity, the bytes in the file are replaced with the values in the RAM, and this achieves a continuous high score.

Space Invaders Variants.

As I mentioned at the beginning of this post, this routine has been developed for Space Invaders ROM sets with a four digit score, but what about other variants of Space Invaders? Will it work for them?

Space Invaders ROM sets with a five digit Score.

Fortunately, the routine for five digit score Space Invaders is exactly the same as four digit score Space Invaders.

Initially, poking the two ROM bytes with set values seemed to work, but the score was offset by a multiple of 10 i.e. putting in a value of 6 into the LSB got a high score of 60.

And the I twigged what they had done...

All of the scores in Space Invaders are multiples of 10, so the lowest digit is always 0 no matter what.

So, the game always draws a 0 at the lowest end of the high score, and then divides all the scores you actually earn from shooting things by 10.

This means that if you shoot an invader worth 20 points, you now get 2 points in reality, plus the fixed zero at the end of the score which displays 20 points.

Pretty clever really. A five digit score stored in two bytes.

Super Earth Invasion with six digit score.

Again this is much like the 5 digit score.

All scores in Super Earth Invasion are multiples of 100 and therefore the two lowest digits are fixed at 0, and then two bytes are used to store the high score.

Again you would only score two points for a 200 point invader, and the score then puts two fixed zero's after the score to show 200.

Theses bytes are in the exact same rom and ram areas as in Space Invaders.

Space Invaders Colour with five digit Score.

Space Invaders Colour is basically Space Invaders Monochrome with two colour EPROMs included.

So it would be logical to assume that Space Invaders Colour would behave in the same way as Space Invaders Monochrome, when it comes to poking values into the ROM area...

Unfortunately this is not the case. Poking high score values into the ROM area appears to work initially, with the values appearing on the intro screen and attract mode.

But when I start a game, the emulator closes.

To be fair, I coded my "HALT" Opcode to end program. So to be more accurate, the Space Invaders code is calling up the Halt Opcode.

If I disable the halt Opcode, the game just resets back to the intro screen.

I'm not sure exactly why it does this. It runs perfectly if you leave the High Score at 0.

I have several theories as to why this is happening, but it probably comes down to a flag, probably the Z flag being set to 0 rather than 1 because of the High Score in ROM or RAM not being at 0, and this is causing a CNZ or JNZ to Call or JUMP that wouldn't normally happen when the Z flag is set.

There may be a way to hack this on the fly, but for now its a no go.

Space Invaders Part II / Space Invaders Deluxe with five digit Score and 10 character High Scorer Name.

So this variant has a five digit score, and the high score ROM and RAM locations work in the same way as Space Invaders Monochrome 5 digit score.

But... There is also the High Score name to save. This is 10 characters and by default is set to "MIDWAY" or "TAITO" depending on the ROM set used.

The high score name is stored in 10 bytes, one byte per character. By entering the name "ABCDEFGHIJ" I was able the find the bytes in the RAM area, and then back trace it to the ROM locations that they are written from.

So what's the problem?

Well, the high score name on loading the game has spaces at the front so that the word TAITO or MIDWAY appears centred with the score underneath i.e. the actual bytes stored are space-space-T-A-I-T-O-space-space-space ( A to Z are 0D to 25D, and then full stop is 26D and space is 27D).

If you then earn a high score and enter a name, lets say "ACE", then the letters appear in the first three bytes, but there is also an "X Offset" byte that is located one byte before the characters in the RAM, and this centres the name over the high score.

But the centring byte is only read when a game has been played, not when the game is initially loaded. Its not required initially as the default high score names are already padded at the front with spaces to centre them. This means that if you enter the name "ACE" and then save the 10 bytes as they stand in the RAM, when you load the bytes back in at the beginning of running the emulator the next time, the word "ACE" will be offset from the high score to the left.

The solution to this is that when you save the high score name bytes, you don't save them as you appear in the RAM. You save them by taking half of the spaces from the end of the name, and adding them to the front of the name, so that if its required to be loaded back into the emulator next time its loaded, its already padded with spaces at the front and will appear centred i.e. A-C-E-space-space-space-space-space-space-space in RAM is saved as space-space-space-A-C-E-space-space-space-space in the high score save file.

Its also worth mentioning that the trigger to save the high score values and name should be a change in the high score value, but a change in the name byte value. When the high score value changes, the new high score name has not been entered yet, and the high score name bytes are 10 spaces at that point.

Friday, 23 April 2021

Lunchtime Coder #6 - Space Invaders Part II /Deluxe Emulator in Blitz3D / Blitz Basic

So once you have a few games running on your emulator successfully, the process of adding more games gets easier right? Wrong!

Every game added comes with its own individual issues to resolve, but then that's the fun of writing emulators.

The Space Invaders Part 2 romset comes as five 2 kB roms and two 1 kB eproms.

The first four 2 kB roms go into the bottom 8 kB of the memory area 0x0000 to 0x1FFF (as per Space Invaders and Space Invaders CV). The fifth 2 kB rom goes in above the screen ram area at 0x4000 to 0x47ff.

The two 1 kB eproms are colour maps for "Everything but player two playing" and "Player two playing".

I took a quick peek at the colour map eproms expecting similar / the same as for Space Invaders CV.

This time, the values are offset by 8 so instead of the eight different colours ranging from 0 to 7, they now range from 8 to 15.

The colour maps themselves also differ from Space Invaders CV slightly.

The screen turns red on the fly when a base is hit, so again I used the Intel 8080 Output Port 3 Bit 0x04, the trigger for sound sample for base being hit to control the trigger and duration of screen going red. Basically the same method that I used in Space Invaders CV.

I also used the same method to detect when Player two is on screen as I did with Space Invaders CV. This is the cocktail screen flip bit in Intel 8080 Output Port 5, Bit 0x20. When set to 1, player 2 is playing.

All good so far. So with the roms in place, the eproms integrated into the drawing routine and a few tweaks to the dip switch settings, I ran up the game.

I should point out that my Intel 8080 emulator now has all 256 opcodes and all 5 conditional bits / flags implemented, so no additional opcodes to throw into the code this time.

Issue 1: There was an erroneous manufacturers logo on the opening screen. This shouldn't be there.

Issue 2: When that logo is meant to be there on completion of the opening screen drawing, it should flash between the manufacturers name and the word "HI-SCORE". This wasn't happening either. Just a fixed manufacturers name.

Issue 3: All sorts of bizarre effects when you get in game / attract mode game, from graphic artefacts to resetting back to the opening screen.

It seemed to me that the interrupts were occurring too quickly, as in before the code had reached the point that it was waiting for an interrupt.

My first attempted resolution was to speed up the processor clock by allowing more processor clock pulses between each interrupt. This actually resolved issue 3, and the game became playable without any artefacts. The speed of the processor was now at 3.125 MHz which by chance is the same speed that an Intel 8080b runs at.

However MAME insists that this game should run on a 2 MHz Intel 8080, and I still had the issues with the manufacturers logo on the opening screen. Something was definitely not right.

I decided to go back to basics, and activate the debug log, and this was what saved the day.

I noticed an IN 0 opcode being run which means that the processor is reading Input Port 0. The romset versions of Space Invaders / Space Invaders CV / Super Earth Invasion didn't read Input Port 0, so for emulation purposes, Input 0 can be set to 0, or just ignored.

But...If its being read by the code, then there must be something to read in Input 0.

By a process of elimination, I set each bit in turn on Input 0 to 1, and ran the game... and Bingo! 0x40 set to 1 cleared all 3 issues.

There was some paranoia about people typing in rude names when they achieved the high score, so Taito supplied a "Reset High Score" button which is tied to 0x40 of Input Port 0.

The reason that the emulator hadn't been working correctly was that I was running it with this button permanently pushed down. This meant that additional code was running between interrupts and the program wasn't ready for the interrupts to happen, and this is why running it with more time between interrupts solved some of the issues.

Setting this bit to 1 resolved all of the issues.

Taito also provided a "Preset Mode" which I found by accident by setting what I thought was the bonus score dip switch.

The Preset mode enables you to set a score before you start the game, so in effect, cheat! This was so that arcade operators could set high scores higher and put in their own custom names as the high scorers.

Interestingly, The manuals for Space Invaders part 2 and Space Invaders Deluxe do not mention the High Score reset button. The preset mode is mentioned in the Space Invaders Deluxe manual.

Another game successfully emulated.

Thursday, 25 March 2021

Lunchtime Coder #5 - Space Invaders Colour Emulator in Blitz3D / Blitz Basic

Having written a Space Invaders emulator based around an early and late version of the various romsets available, I decided to up the game and try some other similar romsets in my emulator to see how they ran.

The first different romset I tried was Super Earth Invasion, a UK bootleg/clone of Space Invaders with different graphics for the Invaders, houses instead of shields, and also some code changes that enabled motherships to drop super bombs on you, and for shot invaders to split and multiply. It was designed to run on the Space Invaders Deluxe hardware, and in some ways has more in common with this game than with the original Space Invaders.

There was some minor differences in the DIP switch settings and how they related to the processor input ports, but with a few tweaks and adjustments it ran perfectly.

I added some colour to simulate the coloured gel treated mirror
effect seen in Space Invaders upright cabinets.

On the back of this success, I went for the Space Invaders Colour (CV) romset fully expecting some heavy additional coding to be required, at least in the screen drawing routine.

I was surprised to find that the romset contained 4 x 2 kB roms (similar to the original Space Invaders romset), and when I ran them I got monochrome Space Invaders out of them.

Also included in this romset are 2 x 1 kB eprom images. A bit of on line investigation showed that these two eproms hold the colour maps for a Player 1 and Player 2 game screen. Essentially the 1-bit bitmap is generated in ram, and then the colour is added during the video processing stage of the hardware.

To be more accurate, the player 1 colour map is really everything but player 2 playing colour map. The player 2 colour map changes the colour of the bases and highlights the player two score in white. The rest of the colour map is the same as the 'Everything else' colour map.

I wrote a small program that read the bytes from these eprom images and arranged them in a 32 by 32 square that showed that each square had a value of between 0 and 7 representing one of 8 different colours (Black, Red, Green, Blue, Cyan, Magenta, Yellow and White).

Each byte corresponds to an 8 x 8 pixel square in the game remembering that the Space Invaders screen is rotated 90 degrees anticlockwise so the screen drawing starts from bottom left to top left and continues moving right across the screen.

A quick update of my emulator code to read the eprom map as it was drawing the bits gave me glorious colour-o-vision.

After playing Space Invaders Colour on MAME a few times, I noticed that when a base is hit by an invader bomb, all of the on screen graphics turn red for a short duration. This must mean that the colour video processing can turn the whole screen a single colour 'on the fly'. I also noticed that the player colour maps change pretty much spot on the player change.

Making the colour change to red when a base gets hit was pretty easy. I used Intel 8080 Output Port 3 bit 0x04. This is the trigger for the 'Base Hit' sound sample to play, but this bit is set for a specific duration, so it seems that when its set to 1, all of the on screen graphics are red.

To flip between player colour maps, I used the Intel 8080 Output Port 5, Bit 0x20 which is for tabletop cabinet screen flipping. By default it is set to 0, but when Player 2 is playing, it flips to 1. This means that it must be the trigger for both cocktail mode screen flipping, and for changing between player 1 and Player 2 colour maps.

Player 1 Colour Map
Player 2 Colour Map

Near perfect.. Well you cant have 100 % perfection without having the original arcade machine running in front of you...