What's new

Space Invaders

hap

New member
If you think CHIP8 is too easy, or GameBoy/NES/MasterSystem is too hard, writing a Space Invaders emulator is not. Most work will be put into creating an Intel 8080 CPU emulator (shouldn't be too hard for the GameBoy crowd :p ), the rest is peanuts.

Code:
Space Invaders, (C) Taito 1978, Midway 1979

CPU: Intel 8080 @ 2MHz (CPU similar to the (newer) Zilog Z80)

Interrupts: $cf (RST 8) at the start of vblank, $d7 (RST $10) at the end of vblank.

Video: 256(x)*224(y) @ 60Hz, vertical monitor. Colours are simulated with a
plastic transparent overlay and a background picture.
Video hardware is very simple: 7168 bytes 1bpp bitmap (32 bytes per scanline).

Sound: SN76477 and samples.

Memory map:
	ROM
	$0000-$07ff:	invaders.h
	$0800-$0fff:	invaders.g
	$1000-$17ff:	invaders.f
	$1800-$1fff:	invaders.e
	
	RAM
	$2000-$23ff:	work RAM
	$2400-$3fff:	video RAM
	
	$4000-:		RAM mirror

Ports:
	Read 1
	BIT	0	coin (0 when active)
		1	P2 start button
		2	P1 start button
		3	?
		4	P1 shoot button
		5	P1 joystick left
		6	P1 joystick right
		7	?
	
	Read 2
	BIT	0,1	dipswitch number of lives (0:3,1:4,2:5,3:6)
		2	tilt 'button'
		3	dipswitch bonus life at 1:1000,0:1500
		4	P2 shoot button
		5	P2 joystick left
		6	P2 joystick right
		7	dipswitch coin info 1:off,0:on
	
	Read 3		shift register result
	
	Write 2		shift register result offset (bits 0,1,2)
	Write 3		sound related
	Write 4		fill shift register
	Write 5		sound related
	Write 6		strange 'debug' port? eg. it writes to this port when
			it writes text to the screen (0=a,1=b,2=c, etc)
	
	(write ports 3,5,6 can be left unemulated, read port 1=$01 and 2=$00
	will make the game run, but but only in attract mode)

I haven't looked into sound details.

16 bit shift register:
	f              0	bit
	xxxxxxxxyyyyyyyy
	
	Writing to port 4 shifts x into y, and the new value into x, eg.
	$0000,
	write $aa -> $aa00,
	write $ff -> $ffaa,
	write $12 -> $12ff, ..
	
	Writing to port 2 (bits 0,1,2) sets the offset for the 8 bit result, eg.
	offset 0:
	rrrrrrrr		result=xxxxxxxx
	xxxxxxxxyyyyyyyy
	
	offset 2:
	  rrrrrrrr	result=xxxxxxyy
	xxxxxxxxyyyyyyyy
	
	offset 7:
	       rrrrrrrr	result=xyyyyyyy
	xxxxxxxxyyyyyyyy
	
	Reading from port 3 returns said result.

Overlay dimensions (screen rotated 90 degrees anti-clockwise):
	,_______________________________.
	|WHITE            ^             |
	|                32             |
	|                 v             |
	|-------------------------------|
	|RED              ^             |
	|                32             |
	|                 v             |
	|-------------------------------|
	|WHITE                          |
	|         < 224 >               |
	|                               |
	|                 ^             |
	|                120            |
	|                 v             |
	|                               |
	|                               |
	|                               |
	|-------------------------------|
	|GREEN                          |
	| ^                  ^          |
	|56        ^        56          |
	| v       72         v          |
	|____      v      ______________|
	|  ^  |          | ^            |
	|<16> |  < 118 > |16   < 122 >  |
	|  v  |          | v            |
	|WHITE|          |         WHITE|
	`-------------------------------'
	
	Way of out of proportion :P

attachments:
8080asm.7z: i8080 assembly programming manual, needed for 8080 emulation,
8080ds.pdf: i8080 datasheet, the table on page 8 and 9 is handy,
76477.pdf: SN76477 (I've hardly looked at that)
 

Attachments

  • 8080asm.7z
    6.9 MB · Views: 2,770
Last edited:
OP
hap

hap

New member
Here's mine :D .. source code only.

*edit* made a mistake in the documentation: Read 0 should be 1, 1 should be 2, 2 should be 3. The above post has been corrected, but I won't release an updated version of "It's a trap!". (it's fine in the code)
 
Last edited:

Exophase

Emulator Developer
Looks good. This should only be a little bit harder than chip8, not counting sound. Is "attract mode" auto-play demonstration?

Other small question - this shouldn't make a difference for Space Invaders (and probably almost any software) but the way you're storing flags, as represented by the result of the previous calculation - it should be possible for the program to compute flags (using pop psw) and thus have both zero, negative, etc set at the same time. IE, if the user did (assume b is already something like 0xFF, loaded from memory or something)

push b
pop psw
push psw
pop b

You'd end up with a different b. Like I said, I doubt this matters because no sane programmers would construct the flags, it's just something I've thought about before.
 
Last edited:
OP
hap

hap

New member
Yes, it's like having no pocket change.

*edit* you're right, I didn't think of that. I'm using the same method on my 6502 emulator (NES)... and should probably change that considering the large library of NES games.
 
Last edited:

bronxbomber92

New member
Looks like something I can try next after I finish the chip8 :)... And looking at you source briefly it seems like space invaders would be easier, would it not?
 
OP
hap

hap

New member
If you've successfully created a CHIP8 interpreter, you've gained experience. In that sense, it's easier to create a Space Invaders emulator. I mean, going from zero to CHIP8 is harder than going from CHIP8 to Space Invaders, get it?
 

ShizZy

Emulator Developer
Nice plastic transparent overlay :) This looks like a good project for a rainy day though sometime when I'm bored. Thanks for all of the docs. Oh, and by the way, is the rom PD? If not, you have any more specific name or something so it can be located? :p
 

Garstyciuks

New member
I think that I'm going to make space invaders emulator :) It looks quite interesting. But can someone explain me why does nes, gameboy, space invaders, and a lot of other systems need "RAM mirror"?
 

Exophase

Emulator Developer
I can't say the specific reasons, I can only guess the following two things..

- It's easier/faster to implement in hardware. Seems counterintuitive, but throwing out bits on an address bus is a lot easier to do than detecting bits and having it do something else. That's basically what happens with mirroring, it's like a big binary AND off the top bits, so you can just ignore them.

- Sometimes different mirrored region have different specifications, like on GBA the different cartridge spaces have different wait state configurations, and on PSP the different mirrors of VRAM affect swizzling somehow (I don't totally recall at the moment)
 

|\/|-a-\/

Uli Hecht
hmm, i don't understand anything about the scroll reg... but that belongs in another thread..... they tried to explain it to me in the gameboy thread....
 

blueshogun96

A lowdown dirty shame
Wow, that does look rather easy. No wonder the guy who wrote that emu programming tutorial that I posted on my sig decided to use space invaders as the tutorial example. :party:
 

ShizZy

Emulator Developer
Question for you hap. This may be kind of stupid of me for not seeing it, or lazy of me for not checking your source, but I didn't see what location in memory the read and write ports are? Could you explain? Thanks.
 
OP
hap

hap

New member
I found another helpful page for those willing to read it:
http://www.darkpact.com/proj/siemu/is/report2.html
Nice find. And indeed, the best information source is probably the MAME source. The hardware description I posted in the 1st post was gathered from MAME too.

ShizZy: You already know of the concept memory mapped IO. Space Invaders (and plenty of other hardware) also uses port mapped IO, with opcodes OUT ($D3) and IN ($DB), both taking a port number (0-255) as parameter.

eg. OUT 2 writes A to port 2, and IN 2 reads from port 2 and puts the value into A. Read and write ports having the same number doesn't necessarily mean they're connected to the same IO device. (these opcodes are also available in the Z80, but were removed for the GameBoy CPU)
 

ShizZy

Emulator Developer
Ahh thanks... I was assuming it was mapped right into main memory, as on gb and nes, as well as many other more complex systems. That makes sense though.
 

smcd

Active member
There's an interesting approach called "tickle" that does things by emulating at the hardware level, Tickle(click here) interesting to look at if nothing else
 
Last edited:

Top