Showing posts with label Arcade. Show all posts
Showing posts with label Arcade. Show all posts

Monday, 20 June 2022

How to write a Space Invaders Emulator - Part 2


Part 2


The Intel 8080 Processor


Disclaimers / Information:

1. I am using Space Invaders ROM sets under the "Fair Use" policy for demonstration purposes only.

2. Blitz3D has no means to directly work with binary or hexadecimal values and therefore all code uses decimal calculations.

3. I am writing this as one single simple longhand piece of code so that all levels can read and understand.

4. I am using Blitz3D for coding which is a derivative of Blitz Basic, an older language but still a capable one for some projects, and its easy for all to read and understand.


Frequently Asked Questions

1. Do I need to be super switched on to understand this and write an emulator?

a. No. I can do it and believe me, I am no genius!

2. Do I need to have any prior understanding of how processors work?

a. No, you can pick it up as you go.

3. Do I need to understand the Space Invaders code?

a. No. We are writing an emulator, not rewriting the game.



I thoroughly recommend the freely available PDF manual linked here as a reference guide for use while writing the processor emulator. It contains detailed descriptions about every aspect of the Intel 8080 including very simple straight explanations of what each part of it and each opcode does.


The Intel 8080a processor is an 8-bit processor with 16-bit memory addressing. This means that it reads instructions or "Opcodes" that are 1 byte in length, but it can read from, and write to memory addresses that are 2 bytes or 16 bits in length meaning that it can support up to 64 kB of memory area. Lets look at some of the other features that this processor has.


Registers

Registers are small areas of memory within the processor where values can be stored, used and manipulated. The Intel 8080 processor has eight 8-bit registers (A, B, C, D, E, H, L and Flags) and two 16-bit registers (Program Counter and Stack Pointer).

As you would expect, 8 bit registers deal with bytes of data, and 16 bit registers deal with memory addresses, however some of the 8 bit registers are often used in pairs to store memory addresses e.g. BC, DE and HL.

Program Counter - This 16 bit register points to the memory location of the current Opcode being executed. On completion, it increments to the next instruction address.

Stack Pointer - This points to the current memory location of the stack. The stack is an area of RAM where the processor stores useful stuff that it will need later. I will talk more about the stack further on.

Register A - Register A, also known as the Accumulator, is a special register that allows the processor to carry out all sorts of logical functions on the 8 bit value being stroed in there, as well as other standard register functions.

Registers B, C, D, E, H and L - These registers are similar to the Accumulator, being able to store an 8 bit value in each, but lack the functionality of the Accumulator when it comes to what the processor can do to these values.

Flags - This register stores the state of the five "Conditional Flags" within the processor. These will be explained later.

Note: I get all of my information from google and manuals. I have read two opposing explanations of "Flags"; one states that they are contained in an eight bit register, the other states that they ar just individual bits / switches in the processor. It doesn't matter which is correct as we can still emulate them.

To further explain how registers work, lets have a couple of examples.

Example 1:

You have just started a game and have shot your first invader. Your current score needs to have the score of that invader added to it.

1. Read the memory location of your current score in registers D and E. This will be somewhere in the general purpose RAM.
2. Read the memory location of the value of that invader into registers H and L. This may be in general purpose RAM or somewhere in the ROM.
3. Read the value stored at the memory location stored in register pair DE into register A.
4. Read the value stored at the memory location stored in register pair HL into register B.
5. Add the value in Register B to the value in Register A. 6. Write the value stored in Register A to the memory location stored in register pair DE.


Example 2:

You are copying a 100 byte area of ROM to the general purpose RAM.

1. Set register pair DE to the first memory location to be cread from in ROM.
2. Set register pair HL to the first memory location to be written to in RAM.
3. Set register B to 100.
4. Read the value stored at the memory location stored in register pair DE into register A.
5. Write the value stored in Register A to the memory location stored in register pair HL.
6. Increment DE by 1.
7. Increment HL by 1.
8. Decrement Register B by 1.
9. Repeat until Register B=0.


As far as coding goes, all of the registers can be variables within our emulator.

; 8 Bit Registers

Local A=0
Local B=0
Local C=0
Local D=0
Local E=0
Local H=0
Local L=0

Local flags=0

; 16 Bit Registers

Local PC=0
Local SP=0

Note: Program Counter can start at 0 because the space invaders code is executed from memory location 0, but this is not always the case with all Intel 8080 programs.


Conditional Flags

Conditional flags are single bits that are set or reset depending on the output of a processor function.

The conditional flags are:

1. Zero or Z flag - Set to 1 if the result of an operation is 0, otherwise its reset to 0.

2. Sign or S flag - Set to 1 if the result of an operation is a minus value, otherwise its reset to 0.

3. Carry/Borrow or C flag - Set to 1 if there is a carry i.e. if the result is greater than 255, or if there is a borrow i.e. if the result is less than 0, otherwise its reset to 0.

4. Parity or P flag - Set to 1 if the number of 1's in the byte is an odd number, otherwise its reset to 0.

5. Auxiliary Carry flag - Difficult to explain in a one liner. This flag is used in conjunction with Binary Coded Decimal and is only really used by one Opcode, so is better explained when we come to code the opcode itself.


Again as far as coding goes, all of the conditional flags can be variables within our emulator. Despite the fact that they exist in an 8-bit register, it is easier to have them as individual values and then calculate the value of the register as a whole only when we need to.

; Conditional Flags:

Local Z=0
Local S=0
Local P=0
Local C=0
Local AC=0


Opcodes

A stated above, Opcodes are processor instructions. They are read from the code in the memory area and then carried out by the processor. The Intel 8080 is an 8-bit processor so it can only take 8-bit instructions. This means that it is capable of carrying out 256 different instructions. DON'T PANIC! Most of these instructions are very simple and repeats of previous instructions with very minor changes.

Some Opcodes have a byte of data attached to it so for example if the Opcode basically broke down as "Put this value in register A.", the second byte would be "This value".

Some Opcodes have two bytes of data attached to them so again for example if the Opcode basically broke down to "Put the value in register A into this address.", then the two bytes after would be "This address".

The bytes following the instruction are called "Operands" and the overall length of the Opcode is counted in "Opbytes".

Example - Opcode 0x00 (Opcode 0 in decimal) which is a "NOP" or "No Operation" has no operands and a length of one opbyte. Example - Opcode 0xC6 (Opcode 198 in decimal) which is an "ADI" or "Add Immediate" has one operand and a length of two opbytes. The data immediately after the opcode is added to Register A.


Processor Speed / Clock Cycles

The processors speed is dictated by its "Clock". The clock feeds the processor pulses at a specific rate, and for each pulse the processor carrys out part of an Opcode. The Intel 8080a is clocked at around 2 MHz or 2 million pulses per second. Each Opcode takes a certain amount of pulses or clock cycles to complete e.g. our "NOP" opcode takes 4 clock cycles to execute, whilst our "ADI" opcode takes 7.

There are some really good websites around with Opcode tables that show each Opcode, how many Opbytes and how many clock cycles for each Opcode.

Below is an Opcode table from www.pastraiser.com which shows the name of each Opcode, how many Opbytes, how many clock cycles and what conditional flags are affected for each Intel 8080 Opcode.

The Space Invaders screen runs at 60 Hz, or 60 updates a second (60 FPS) and therefore if the processor is clocked at 2000000 cycles a second, and the screen is 60 FPS then we need to update the screen every 33333 clocks of processor time and so as we run opcodes, we must count how many clocks have been used so that we can time the screen refresh accurately.

So with all of the above in mind, we can now start writing our processor emulator code. We have already stated the register and conditional flag variables, but we need some more variables to be able to start and then we need an outer processor shell to put our opcode interpreters into.

; Processor Variables:
Local opcode
Local opbytes
Local clock_cycles
Local clock_cycle_counter
Local display_update_constant=33333

repeat

repeat

opcode=memory_array(PC,0)

; Insert Opcode Interpreter Here.

pc=pc+opbytes

clock_cycle_counter=clock_cycle_counter+clock_cycles

until clock_cycle_counter>=33333

clock_cycle_counter=clock_cycle_counter-33333

; Insert Display Update Routine Here.

Until keyhit(1)

We read the opcode value at memory location (program counter). On completion of executing the opcode we increment program counter ready to read the next opcode, and we keep a count of how many clock cycles we have used. When we have used enough clock cycles, we stop executing opcodes and update the display.

Note: Program Counter will not always increment by the number of opbytes. There may be cases where we need to skip this, or modify it to change program counter to a different location in the memory, but for now, this will do.


Lets now do some code for a typical opcode. We will do a really simple one, a "NOP" or No operation. All that this opcode does is waste 4 cycles of processor time. Its the first opcode called up in the space invaders code.
; Insert Opcode Interpreter Here.

select true

; Opcode 0x00 or 0 - "NOP"
case opcode=0
opbytes=1
clock_cycles=4

end select

And thats our first opcode done. 255 to go...Actually thats not quite true as if you check the opcode table above, you will see that there's 13 NOPs at opcodes 0x00 (0), 0x08 (8), 0x10 (16), 0x18 (24), 0x20 (32), 0x28 (40), 0x30 (48) and 0x38 (56). In this case, its more like:

; Insert Opcode Interpreter Here.

select true

; Opcode 0x00 or 0 - "NOP"
case opcode=0
opbytes=1
clock_cycles=4

; Opcode 0x08 or 8 - "NOP"
case opcode=0
opbytes=1
clock_cycles=4

; Opcode 0x10 or 16 - "NOP"
case opcode=0
opbytes=1
clock_cycles=4

; Opcode 0x18 or 24 - "NOP"
case opcode=0
opbytes=1
clock_cycles=4

; Opcode 0x20 or 32 - "NOP"
case opcode=0
opbytes=1
clock_cycles=4

; Opcode 0x28 or 40 - "NOP"
case opcode=0
opbytes=1
clock_cycles=4

; Opcode 0x30 or 38 - "NOP"
case opcode=0
opbytes=1
clock_cycles=4

; Opcode 0x38 or 56 - "NOP"
case opcode=0
opbytes=1
clock_cycles=4

end select

Ok, I think we can wrap up part 2 there. Look out for part 3 where we will be looking into opcodes that are a bit more complex than our NOP opcode above.





Friday, 28 January 2022

How to write a Space Invaders Emulator - Part 1


Part 1


Introduction, Overview, Dip Switches, Input Ports and Memory Map.


Disclaimers / Information:

1. I am using Space Invaders ROM sets under the "Fair Use" policy for demonstration purposes only.

2. Blitz3D has no means to directly work with binary or hexadecimal values and therefore all code uses decimal calculations.

3. I am writing this as one single simple longhand piece of code so that all levels can read and understand.

4. I am using Blitz3D for coding which is a derivative of Blitz Basic, an older language but still a capable one for some projects, and its easy for all to read and understand.


Frequently Asked Questions

1. Do I need to be super switched on to understand this and write an emulator?

a. No. I can do it and believe me, I am no genius!

2. Do I need to have any prior understanding of how processors work?

a. No, you can pick it up as you go.

3. Do I need to understand the Space Invaders code?

a. No. We are writing an emulator, not rewriting the game.


When you look at the Space Invaders circuit boards or the Space Invaders circuit diagrams, it looks like an incredibly complicated machine. There are all sorts of electronic components working together to ensure that you can blast away at the oncoming invading hoards, and an emulator of the system can seem like an impossible task.

1979 Space Invaders Circuit Boards

Space Invaders Circuit Board Schematic

Fortunately, to write an emulator, you don't need to recreate all of the electronics within the machine, but rather the logic of the machine, and writing an interpreter program that reads the space invaders code in a similar fashion to how the real machine does, and then interpreting it into something that your current system can do, emulation of the machine can become a fairly straight forward task.

From the complex circuit diagrams above, we can water the system down to a simple block diagram which will include all of the parts of the machine that we will need to emulate or simulate. Note there will be some simulation within the emulator. The processor can be emulated however the video output needs to be simulated because the video output involves converting a bitmap within memory into an analogue wave for a CRT monitor to display, something that we cannot do here. 

What an Artist! Yup Shit-Block-Diagrams-R-US

The block diagram above shows all of the different parts of a Space Invaders cabinet that we need to take into account when writing an emulator. Lets go through them one by one:

1. Memory Area (far left) - This is a 16 kB area of ROM space and RAM. The lower 8 kB is the Rom area and the upper 8 kB is the RAM area. Whilst this 16 kB of ROM and RAM would be scattered across the circuit boards in various size chips, the processor addresses this memory area as a 16 kB block.

2. Intel 8080 processor - The intel 8080a processor is an 8 bit processor with a 16 bit memory address bus. It has 8 x input ports and 8 x output ports for communicating with other parts of the Space Invaders hardware. It can execute 256 different instructions (known as Opcodes).

3. Video Output - This part is simulation. The Space Invaders graphics output exists as a 1-bit bitmap in the top 7 kB of RAM. The video output reads this bitmap and converts it into a display. The video output unit also generates processor Interrupts at a rate of 2 interrupts per frame drawn.

4. Processor Dip Switches - These are hardware switches on the processor board and can be used to adjust various parameters of the game being played. For Space Invaders, the number of lives can be set between 3 and 6, the score at which a bonus life can be earned can be either 1000 or 1500, coin info can be displayed or not displayed during attract mode and a diagnostic service mode can be switched on or off. These are read using the Intel 8080 Input Port 0 and Input Port 2.

5. Video Dip Switches - This is a guess. Somewhere in the Space Invaders hardware is a switch that sets the game to upright cabinet mode or table top cabinet mode. I don't know where this switch is but I am guessing its on the video board somewhere.

6. Coin Mechanism - The coin mechanism is read by the Intel 8080 Input Port 1 during one of the two processor Interrupts per frame drawn. This means that if Space Invaders display runs at 60 frames per second, the coin mechanism is checked for a coin deposited 60 times a second. I believe that the coin mechanism also contains a tilt switch which would activate if the machine is tilted during game play and end the game. This may not be located in the coin mechanism...

7. Coin mechanism Dip Switches - Some later coin mechanisms had their own Dip Switches to enable arcade operators to allow multiple credits per coin, or to charge multiple coins per credit.

8. Joystick and Buttons - These are the game controls that allow the player to interact with the game. There is a joystick, a fire button, an 1 player button and a 2 player button. These are read by the Intel 8080 Input Port 1 and Input Port 2. Again they are read like the coin mechanism at a rate of once every display frame update during an interrupt.

9. 16-Bit Shift Register - This is a separate piece of logic hardware that shifts bits quicker than the processor can do. The Intel 8080 input and output ports are used to write to and read from the 16-bit shift register.

10. Sound Output - Sound output for Space invaders uses a specialist chip which is not the easiest thing to emulate. At this point, I will be using the MAME space invaders sound samples for sound output.

11. Watchdog - It is not essential to emulate the Watchdog, however for completeness the Watchdog is essentially a count down to resetting the processor. It counts down from 255 to 0 at a rate of one count per display frame and if the code is running correctly, it will reset the watchdog countdown to stop the reset. If the machine is suffering from a temporary code or hardware glitch, the countdown gets to zero, the processor is reset and hopefully the error is cleared.

That is the list of hardware that we need to consider to write a complete Space Invaders emulator. The Watchdog and Coin Mechanism dip switches are not essential, but pretty much everything else is.

Before we get started, its worth considering that there is more than one Space Invaders ROM set out there, in fact there are six different ROM sets for monochrome space invaders. There are also different variants on the hardware. However, if we write a good emulator, it will run all of the different ROM sets available. The differences between the ROM sets are shown in the diagram below. Its also worth noting that some of the ROM sets are 4 x 2 kB ROMs and others are 6 x 1 kB ROMs. In either case, the ROM set will be in the lower 8 kB of the memory area. For 6 kB rom sets, kB's 5 and 6 are left empty in the ROM area whereas 8 kB ROM sets populate the whole 8 kB ROM area.


To write an emulator, you will need to acquire one of the MAME ROM sets shown above, that is sitv1, sisv2, invaders, sitv, sisv3 or sisv. 

https://www.planetemu.net is a good MAME ROM source to try for one of these ROM sets.

And so, armed with a ROM set and a small amount of knowledge, we can start the process of emulation.

Its going to be a while before we have anything that will give us any notable output, but its important to get the first bits in place to avoid false starts.



Before we start writing actual code, I will give you a few quick pointers about the code itself and the notation that I use.

Note 1: Remarks / Comments are prefixed with a ";" and are in cyan. Actual code is in orange.

Note 2: You will see in the remarks below that I am using Intel 8080 hexidecimal notation. "0x00" etc. The "0x" is a prefix to state that its Intel 8080 hexidecimal, the 00 is the hexidecimal value, so 0x00=0, 0x01=1, 0x02=2, 0x04=4, 0x08=8, 0x10=16, 0x20=32, 0x40=64 and 0x80=128. These values relate to each single bit in a byte being set. As I stated above, Blitz3D doesn't have any way of directly using either binary or hexidecimal so in the code, the actual values will be in decimal.

Dip Switches

We will start by setting the Dip Switches to the values that we require. This isn't essential for ROM sets that don't have a Diagnostics mode (see diagram above) but is essential for ROM sets that do have a diagnostic mode. If we don't disable the diagnostics mode before we start, the game will boot into a sweeping bit pattern which could be misunderstood as the emulator not functioning correctly.

There are 8 dip switches on the processor board, and each of these DIP switches will be linked with a bit in one of the Intel 8080 input ports. Depending on the hardware variant you get the dip switch settings from, different dip switches may be assigned to the functions that they do however the function will always be assigned to the same input port bit.

Example:

In one Space Invaders hardware variant, Dip Switches 1 and 2 set the number of lives.
In another hardware variant, Dip Switches 3 and 5 set the number of lives.
In either case, the dip switches setting the number of lives are linked to bits 0 and 1 on Input Port 2.

So you can see from the above example that you can name the dip switches literally anything, as long as you link them to the correct Input Port bit.

I am going to take the Dip Switch numbering from computerarcheology.com's website which states that:

Dip Switch 3 - Number of Lives
Dip Switch 5 - Number of Lives 2
Dip Switch 4 - Diagnostics / service mode On or Off.
Dip Switch 6 - Extra life at 1000 or 1500 score.
Dip Switch 7 - Coin Info On or Off during Attract Mode.

Dip switches are set either to On or Off. When they are set to On, the associated bit in the Input port is at 0, and when they are set to Off, the associated Input Port bit is set to 1.

So if we didn't set the Dip Switches, and then read the settings across to the Input Ports, we would start with the Diagnostic mode set to 0, or ON, and this is what we don't want.

So code time to declare the Dip Switches as Local variables and set them on or off.

; *** SERVICE MODE ***
; Dip Switch 4 On (Input Port 0 - 0x00) - Service Mode On.
; Dip Switch 4 Off (Input Port 0 - 0x01) - Service Mode Off.

Local dip_switch_4=1

; *** NUMBER OF LIVES PER GAME ***
; Dip Switch 3 On (Input Port 2 - 0x00) / Dip Switch 5 On (Input Port 2 - 0x00) = 3 Lives.
; Dip Switch 3 Off (Input Port 2 - 0x01) / Dip Switch 5 On (Input Port 2 - 0x00) = 4 Lives.
; Dip Switch 3 On (Input Port 2 - 0x00) / Dip Switch 5 Off (Input Port 2 - 0x02) = 5 Lives.
; Dip Switch 3 Off (Input Port 2 - 0x01) / Dip Switch 5 Off (Input Port 2 - 0x02) = 6 Lives.

Local dip_switch_3=0
Local dip_switch_5=0

; *** SCORE TO EARN BONUS LIFE ***
; Dip Switch 6 On (Input Port 2 - 0x00) = Bonus Base At Score of 1500
; Dip Switch 6 Off (Input Port 2 - 0x08) = Bonus Base At Score of 1000

Local dip_switch_6=0

; *** COIN INFO ON / OFF ***
; Dip Switch 7 On (Input Port 2 - 0x00) = Display Coin Info
; Dip Switch 7 Off (Input Port 2 - 0x80) = Don't Display Coin Info

Local dip_switch_7=0

; *** Other Dip Switches ***
; Dip Switch 1 - Unknown
; Dip Switch 2 - Unknown
; Dip Switch 8 - Unknown

This has set the Service Mode to off, the number of lives to 3, the score to earn a bonus life at 1500 and the coin info on.


Input Ports

Now that we have the Dip Switches set, we can now set up the Input Ports default values based on the Dip Switch settings. We need a default value as the dip switches won't be changed during the game running, but other things such as coins / game controls will adjust the input port values, so rather than resetting the input port values back to 0 after coins have been inserted or game controls have been used, they are reset back to their default values based on the Dip Switch settings.

; ***** Input Port 0 *****
;0x01 - Sets service / diagnostic mode on or off from Dip Switch 4.
;0x02 - Unknown.
;0x04 - Unknown.
;0x08 - Unknown.
;0x10 - Unknown.
;0x20 - Unknown.
;0x40 - Unknown.
;0x80 - Unknown.

;Default Input Port 0 value is either 0 (Service Mode) or 1 (Game Mode).

in_0_value=0
If dip_switch_4=1 Then in_0_value=in_0_value+1
Input0=in_0_value

; ***** Input Port 1 *****
;0x01 - Coin Slot 1 - Nominally set to 0. Set to 1 when coin inserted.
;0x02 - 2 Player Start Button - Nominally set to 0. Set to 1 when 2P game start button pressed.
;0x04 - 1 Player Start Button - Nominally set to 0. Set to 1 when 1P game start button pressed.
;0x08 - Unknown
;0x10 - Player 1 fire button - Nominally set to 0. Set to 1 when fire button is pressed during Player 1 gameplay.
;0x20 - Player 1 Joystick Right - Nominally set to 0. Set to 1 when Joystick is left during Player 1 gameplay.
;0x40 - Player 1 Joystick Left - Nominally set to 0. Set to 1 when Joystick is right during Player 1 gameplay.
;0x80 - Unknown

;Default Input1 value is 0.

in_1_value=0
input1=in_1_value

; ***** Input Port 2 *****
;0x01 - Coins Per Credit from Dip Switch 3.
;0x02 - Coins Per Credit from Dip Switch 5.
;0x04 - Tilt Switch
;0x08 - Bonus Ship Score from Dip Switch 6.
;0x10 - Player 2 fire button - Nominally set to 0. Set to 1 when fire button is pressed during Player 2 gameplay.
;0x20 - Player 2 Joystick Left - Nominally set to 0. Set to 1 when Joystick is left during Player 2 gameplay.
;0x40 - Player 2 Joystick Right - Nominally set to 0. Set to 1 when Joystick is right during Player 2 gameplay.
;0x80 - Coin Info On / Off from Dip Switch 7.

;Default Input2 value depends on Dip Switch Settings.

in_2_value=0
If dip_switch_3=1 Then in_2_value=in_2_value+1; - Number of lives
If dip_switch_5=1 Then in_2_value=in_2_value+2; - Number of lives
If dip_switch_6=1 Then in_2_value=in_2_value+8; - Bonus Ship
If dip_switch_7=1 Then in_2_value=in_2_value+128; - Coin Info
input2=in_2_value

So now we have Input Ports 0 and 2's default values set. Input Port 1's default value can be 0 as no Dip Switches are linked to this Input Port. Computerarcheology.com states that bit 3 (0x08) in Input Port 1 is permanently set to a 1, however setting this bit to 1 or 0 does not affect the Space Invaders gameplay. It also states that Input Port 0 Bits 1,2 and 3 (0x02, 0x04 and 0x08) are permanently set to 1. Again whether they are set to 1 or 0 has no affect on the Space Invaders gameplay.

So now that we have the Dip Switches set, and the associated Input Port bits set, we can now look at setting up the Space Invaders memory area.


Memory Area

Space Invaders ROM sets come on 6 x 1 kB ROMs or 4 x 2 kB ROMs depending on which ROM set that you have downloaded. Either way, all of the ROMs will sit in the bottom 8 kB of the memory area, and the RAM then sits in the top half.

Despite the ROM and RAM chips being scattered around the Space Invaders board in the real machine, the processor addresses the ROMs and RAM as one 16 kB lump of memory.

So we can start with a 16 kB array, and then load the bytes from the ROM files into the array in the correct order and correct area leaving the top 8 kB available to the emulator as RAM. We should also have a write protect bit in the array to stop the emulator overwriting values in the ROM area.

I will give two examples here, one for the ROM set "sitv1" which is 4 x 2 kB ROMs and one for ROM set "sisv" which is 6 x 1 kB ROMs.

Example 1 - 4 x 2 kB ROM set - sitv1

; Two dimensional array. All array slots with ROM bytes in them have second dimension slot set to 1 to block writes to the ROM. 

Dim mem(16384,2)

; Read all of the bytes from the ROMs into the emulators memory array.
rom_size=2048
rom_start=0
number_of_roms=4

For rom_select_loop=1 To number_of_roms
If rom_select_loop=1 Then filein=ReadFile("roms\sitv1\tv01.s1")
If rom_select_loop=2 Then filein=ReadFile("roms\sitv1\tv02.rp1")
If rom_select_loop=3 Then filein=ReadFile("roms\sitv1\tv03.n1")
If rom_select_loop=4 Then filein=ReadFile("roms\sitv1\tv04.m1")

For rom_read_loop=rom_start To rom_start+rom_size-1
mem(rom_read_loop,0)=ReadByte(filein)
; Wherever a ROM byte is entered into the array, set the array second dimension for that array value to 1
mem(rom_read_loop,1)=1
Next

CloseFile(filein)
rom_start=rom_start+rom_size

Next


Example 2 - 6 x 1 kB ROM set - sisv

; Two dimensional array. All array slots with ROM bytes in them have second dimension slot set to 1 to block writes to the ROM. 

Dim mem(16384,2)

; Read all of the bytes from the ROMs into the emulators memory array.
rom_size=1024
rom_start=0
number_of_roms=6

For rom_select_loop=1 To number_of_roms

If rom_select_loop=1 Then filein=ReadFile("roms\sisv\sv0h.36")
If rom_select_loop=2 Then filein=ReadFile("roms\sisv\sv11.35")
If rom_select_loop=3 Then filein=ReadFile("roms\sisv\sv12.34")
If rom_select_loop=4 Then filein=ReadFile("roms\sisv\sv04.31")
If rom_select_loop=5 Then filein=ReadFile("roms\sisv\sv13.42")
If rom_select_loop=6 Then filein=ReadFile("roms\sisv\sv14.41")

For rom_read_loop=rom_start To rom_start+rom_size-1
mem(rom_read_loop,0)=ReadByte(filein)
; Wherever a ROM byte is entered into the array, set the second dimension to 1
mem(rom_read_loop,1)=1
Next

CloseFile(filein)
rom_start=rom_start+rom_size

; Skip 2 x 1kB ROM spaces after the first 3 ROMs are in place
if rom_select_loop=3 then rom_start=rom_start+2048

Next

You can see from the code above the order that the ROMs go into the memory area. There are a number of website that will give you arcade game Memory Maps of where each game ROM sits in its respective ROM area. Try arcaderestoration.com or you can look at the MAME drivers in the MAME source code which also list where all of the ROMs for a particular game sit within the memory area.

And that wraps up Part 1 of how to write a Space Invaders emulator. We now have Dip Switches, Input Port Default Values and a Memory Map.

If you have any questions, please post them in the comments below.

In Part 2, we will be dealing with the Processor.





Thursday, 27 January 2022

Lunchtime Coder #11 - Space Invaders II Emulator (Not Space Invaders Part II)

When you write a Space Invaders emulator, if its been written correctly then it's actually a Taito/Midway Intel 8080 arcade platform emulator, and providing that you add the ROM sets into the memory area correctly and tie the dip-switches to the Intel 8080 input ports for that specific game, you should be able to run and play a number of official and unofficial bootleg arcade games.

Having got my Space Invaders emulator running perfectly (or so I thought), I decided to try some different ROM sets in the emulator to see how well they played.

One of the ROM sets I tested was Space Invaders II, a follow up to Space Invaders written and released by Midway but I believe unlicensed by Taito.

Its a two players at once style Space Invaders game which allows you to play against both Invaders and the other player.

Space Invaders II has six 2 kB ROMs, four of which sit in the bottom 8 kB ROM area and then two sit above the 8 kB RAM area.

I had two false starts by adding the ROMs into the wrong memory area… perks of using a programming language that doesn’t deal directly with binary or hex values, and converting them to decimal in your head on the fly, but to be fair, I’ve been doing this long enough now so no excuses really…

With the ROMs added in the correct place in the memory area, I then set Input Ports 0, 1 and 2 to a default value of 0 and ran the emulator up.

I got a test pattern that swept from left to right across the screen. Great! Looked like it was running in some kind of diagnostic / test mode.

This is the fun of Dip Switches. They run from switch 1 through to switch 8, and when they are off, the associated bit in the Input Port is set to 1, and when they are on, the associated bit in the Input Port is 0. By setting the Input Port 0 total value to 0, you are essentially turning on any dip switches tied to it...

From my previous experience with Space Invaders diagnostic mode, I knew that one of the dip-switches would be mapped to a bit on the Intel 8080 Input Port 0. A quick look at the debug log confirmed that the code was reading Input Port 0 early on. It turned out to be the same bit in Input Port 0 as Space Invaders uses, Bit 0. Setting Bit 0 in Input Port 0 to 1 switches the test mode off, as it denotes that the Dip Switch is in the off position.

So with this sorted, I ran the emulator again.

I got the basic Space Invaders 2 screen in attract mode, but Invaders moving randomly around the screen, over the top of each other with no collisions between shots and invaders or guns.

Some colourful language.....

After a bit of thought and some serious chugging on the vape, I came back in and decided to attack the issue with a logical approach, rather than trying to trawl through the debug log and find problems that way.

I double checked that the emulator was set up correctly and then made an assumption that part of the Intel 8080 emulator had a bug in it. The emulator has been tested using the Intel 8080 diagnostic test program CPUDIAG, but not all of the processor functionality is checked e.g. Halt and Interrupts aren’t checked as there is no way to send the processor an interrupt when you are testing just the processor. Interrupts are generated externally from the processor so a processor test program cannot generate an interrupt itself.

So time for some detective work.

Logical deduction - Always start with what you do know:

1. The test/diagnostic mode seemed to be working fine. Possibly a clue there.

2. Space Invaders works perfectly on this emulator but probably only uses around 150 of the 256 opcodes that the processor runs.

Conclusion - the bug is in an opcode that Space Invaders doesn’t use. Seems reasonable.

I ran through a full attract mode and two player game of Space Invaders with an array logging and counting which opcodes the code was using.

I then did the same with Space Invaders II up until the bugs becomes apparent.

I then used an excel spreadsheet to work out what opcodes Space Invaders II used that Space Invaders didn’t. I came away with a list of around 20 opcodes.

There was a second clue though. The test / diagnostic mode worked perfectly, and if the test mode was like the Space Invaders test/diagnostic mode, it doesn’t use interrupts.

Could the problem be Interrupt related?

I checked the list of identified opcodes for anything interrupt related and Bingo! One of the opcodes was DI or Disable Interrupts.

A quick check of one of the easiest and briefest opcodes in my emulator showed a syntax error….The interrupts weren’t being disabled.

With this fixed, Space Invaders II works perfectly, and without a lengthy debug trawl.

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.

Example:

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.

Example:

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.

Example:

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
    else
    
Aux. Carry flag=0
end if

Accumulator=Accumulator + value to be added

if Accumulator>255D then
    Accumulator=Accumulator-256D
    Carry flag=1
    else
    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
        else
        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.