What's new

Space Invaders

TRS

Member
I wouldn't recommend using the OnPaint-event for graphical output. Sure it can be done, I did so in my first version of a NES-emulator, but since emulating these 'simple' system will most likely leave you with loose pixels being generated, no objects. The only way I could think of was to generate a bitmap and render this on screen. It works, but is slow as hell.

You'd be better of start reading XNA. This will give you all you need to render simple systems and eventually maybe more advanced systems and is way simpler to learn and more natural in combination with C# then DirectX or OpenGlide.
 

leonardo2204

New member
I have used XNA for a long time, and yes, it is a lot easier to use. But I'm trying to make it in pure C# (if possible) as a challenge. OnPaint is ridiculously slow, I know, but for SI I don't think that would be a big problem, right ? Thanks for the answer, but I'm still waiting for some instructions regarding drawing on the screen.
 

TRS

Member
What kind of instructions are you looking for? Like I said in my previous post, generate a bitmap and render it on screen.

If you need a full code example, do a little google search and you should have tons of examples :unsure:.

[EDIT]
What is pure C# in your opinion? XNA is nothing more then an extension on the .Net framework so it still would be pure c# imho.
[/EDIT]
 
Last edited:

leonardo2204

New member
TRS, thanks for the reply, I managed to get it working. Now I'm having another head scratching problem. Until the game gets to the attract mode (demo play ?) it runs just fine, draws everything without a problem. But as I've seen in another emulator, the screen is cleared (mid part only) and then the demo starts. Mine is not clearing and it overlaps images and then crashes. Debbuging I've seen that my code runs until the address 0x1421 (which is a return). But my pop is returning a strange value (0x23f0 if I'm not mistaken) It seems to me that it is pushing but not popping some value.

From CA:

Code:
1400: 00              NOP                         ; Time/size pad to match CPL in EraseShiftedSprite
1401: CD 74 14        CALL    CnvtPixNumber       ; Convert pixel number to coord and shift
1404: 00              NOP                         ; Time/size pad to match CPL in EraseShiftedSprite
1405: C5              PUSH    BC                  ; Hold count
1406: E5              PUSH    HL                  ; Hold start coordinate
1407: 1A              LD      A,(DE)              ; Get the picture bits
1408: D3 04           OUT     ($04),A             ; Store in shift register
140A: DB 03           IN      A,($03)             ; Read the shifted pixels
140C: B6              OR      (HL)                ; OR them onto the screen
140D: 77              LD      (HL),A              ; Store them back to screen
140E: 23              INC     HL                  ; Next colummn on screen
140F: 13              INC     DE                  ; Next in picture
1410: AF              XOR     A                   ; Shift over ...
1411: D3 04           OUT     ($04),A             ; ... to next byte in register (shift in 0)
1413: DB 03           IN      A,($03)             ; Read the shifted pixels
1415: B6              OR      (HL)                ; OR them onto the screen
1416: 77              LD      (HL),A              ; Store them back to screen
1417: E1              POP     HL                  ; Restore starting coordinate
1418: 01 20 00        LD      BC,$0020            ; Add 32 ...
141B: 09              ADD     HL,BC               ; ... to coordinate (move to next row)
141C: C1              POP     BC                  ; Restore count
141D: 05              DEC     B                   ; All done?
141E: C2 05 14        JP      NZ,$1405            ; No ... go do all rows
1421: C9              RET                         ; Done

Some parts of the code:

Code:
private void POP(ref ushort reg)
        {
            reg = ReadWord(SP.Value);
            SP.Value += 2;
            cycles += 10;
        }

        private void PUSH(ushort reg)
        {
            SP.Value -= 2;
            WriteWord((ushort)(SP.Value), reg);
            cycles += 11;
        }
        private void CALL()
        {
            PUSH((ushort)(PC.Value + 2));
            PC.Value = ReadWord(PC.Value);
            cycles += 6;
        }
       private void RET()
        {
            POP(ref PC.Value);
        }

I'm not pretty of what's happening, I think it might be somewhere around those codes.

Thanks for the help
 

suanyuan

New member
I made a Space Invaders emulator with C++:

* 8080 CPU emulation
* 8080 disassembler
* using GDI for display,
* windows API for keyboard
* windows API for sound
* compile with CodeBlock + mingw

Current progress:

* 8080 CPU 100%
* GFX 100%
* AUDIO 100%
* INPUT 100%


Screen.png


Emulator binary and source code download:
 
Last edited:

Danny

Programmer | Moderator
Wow, last post was a while ago now!

I have just started my Space Invaders emulator, after completing the Chip8 emulator (will add in SChip support when I feel like it).
I'll update as I progress (or get stuck :p)
 

shutterbug2000

New member
Wow, last post was a while ago now!

I have just started my Space Invaders emulator, after completing the Chip8 emulator (will add in SChip support when I feel like it).
I'll update as I progress (or get stuck :p)

Going to make a Space Invaders emulator for android, using LibGDX. I'll be posting here as well :D.
 

shutterbug2000

New member
Quick question here: I've been implementing the first opcode that needed flags, but I'm not entirely sure how the AC flag is set/cleared. It's apparently used for binary-coded decimal arithmetic, but exactly how is unspecified. Zack, could you explain how you did it(or anyone else)?
 

shutterbug2000

New member
Something else: How does the stack pointer work on the 8080? From what I can tell, it doesn't have a dedicated "stack", so... where is it retrieving the values from?
 

Exophase

Emulator Developer
Something else: How does the stack pointer work on the 8080? From what I can tell, it doesn't have a dedicated "stack", so... where is it retrieving the values from?

Most CPUs don't have a dedicated area of memory for the stack, the stack pointer just points somewhere in the address space (normally, somewhere in RAM). It's up to the program to manage where the stack pointer points.

I can't find in the 8080 manual what the stack pointer defaults to, if it's there it's not obvious but it's hard to really know for sure without the ability to search the document. It's a Trap! sets it to 0, which would have it pointing into ROM on Space Invaders. I'm sure the game properly initializes it from there so it's moot.
 

shutterbug2000

New member
Ah, that helps! I guess I just thought that all CPUs had a dedicated "stack" after working on chip8, which just had a stack array. Didn't even think of it just being in RAM(although that does make sense).

Also, do you happen to know how the AC flag works? If you could explain that, it'd be appreciated!

Thanks!
 
Last edited:

Exophase

Emulator Developer
Also, do you happen to know how the AC flag works? If you could explain that, it'd be appreciated!

Auxiliary carry is set after additions or subtractions if a carry or borrow occurs in the 4th bit. You can calculate this by performing the operation with all but the bottom four bits of the operand set, then checking if bit 4 is set. For example, for addition:

Code:
if(((a & 0xF) + (b & 0xF)) & 0x10)
  aux_carry = 1;
else
  aux_carry = 0;

The 8080 manual linked in the first page has a good description on pages 15-16 of how aux carry works with the DAA instruction.
 

tangomar

New member
Hi,

trying to emulate Space Invaders in Javascript, inspired by Thibault Imbert.
Does anybody know why the 8080 ANA instruction the AC flag gets set? How?

Thanks
 

shutterbug2000

New member
Hi,

trying to emulate Space Invaders in Javascript, inspired by Thibault Imbert.
Does anybody know why the 8080 ANA instruction the AC flag gets set? How?

Thanks

Not sure entirely what you're asking, but if you're just asking how to set or clear the AC flag, the post right above your post should tell you what you need.
 

tangomar

New member
AND doesn't generate any half carry propagation (neither other logic instructions). Are we assuming to set to 0 the AC bit?

thanks
 

Top