Atari 8-bit games on Tiny FPGA BX Games Console


#1

I have been looking into what it would take to run Atari 2600 games on our Tiny FPGA BX Games Console.

Most of the work is in the TIA (Television Interface Adapter) which uses a small number of registers to generate a TV picture on the fly. It supports the playfield (background), 2 sprites (players), a ball and 2 missiles using a palette of 16 colours and 8 luminosity levels, using less than 64 bytes of registers.

The screen is 160 x 192 which we could map onto 320 x 192 on our display. We would need to allow a small amount of code to be executed between every horizontal line.

There are VHDL implementations of the TIA, but I haven’t seen a Verilog one. We would need a custom implementation of it anyway to fit in with our display and with PicoSoC.

There is a good description of the TIA and programming the Atari 2600 in the Stella Programming Guide.

As the Atari 2600 uses very little RAM and not much ROM, we could fit it in my RAM version of PicoSoC.

I have been looking at the Source code of Adventure, to see how the games were programmed.

I was thinking that we could reimplement some games in C, but using the same register API that the original uses. The audio output and button input doesn’t look very hard to do.

Once we have a working TIA, it also looks quite feasible to replace picorv32 with a 6502 CPU and run the original games.

I also quite like the idea of running the Deepmind AI software that learns to play a selection of these games, in real time using our console. Again, that looks as if it might be feasible to me. The Deepmind software is on Github. We could send the keystrokes over the uart and perhaps send the screen back over the uart or the usb connection. Or we might be able to send back the register set and use the PC emulator to reconstruct the screen.


#2

Here is a start of the Adventure Game. I started with a software implementation with direct driving of the LCD from the RAM version of PicoSoC.

The drawing of a new room is slow. I will look at the hardware implementation of TIA when I have the first level working in software.


#3

I have been pondering building a 6502 version of the SoC for a little while now too… It should free up (quite) a few more resources, but at the cost of being a bit more difficult to program… I’m happy coding in 6502 ASM, but I was brought up on a C64, and I’m weird :slight_smile:

That TIA chip is something else. :slight_smile: have you seen the “ultimate atari 2600 talk”? It’s well worth a watch… The people who wrote games for those things were absolute wizards … :mage:


#4

I don’t think I have programmed in 6502 assembler, but I have used Z80 and 68000 assembler. I downloaded the DASM assembler and assembled Adventure in it, and then ran it in the Stella emulator. That all looks straightforward and gives an effective development environment for Atari 2600 games.

So are you going to produce a C64 clone for the console? We don’t have enough RAM for a full version of that, but presumably you could produce something close, with a subset of VIC-II features? Or perhaps that is close to what you have in your latest version of video hardware (which I am still waiting eagerly to see).


#5

I now have a playable first level of the Atari 2600 Adventure Game on the FPGC.

To run it do:

git clone https://github.com/lawrie/atari_tia_soc
cd atari_tia_soc/games/adventure
make

It looks pretty much identical to the original as it uses the same graphics. It has a few screen glitches and there is no sound. Also the dragons don’t so much bite you as push you onto a wall like a sumo wrestler. So the gameplay needs some work on it and level 1 of Adventure is rather boring. The magnet does not work. The Easter Egg room is there, but I have removed the wall so you can wander in and take a look around.

The X and Y keys act as Start and level select. The A button drops items.

It uses the BRAM SoC, so no there is use of flash memory and just a hardware.bin, no firmware.bin.

The LCD is driven directly from C code, not in the VGA style of tinyfpga-game-soc, but there is some TIA-like hardware acceleration that makes displaying rooms instantaneous.

I am reaching the 14k limit of the BRAM SoC so getting the other levels in this version may be challenging.

Level 2 of Adventure is more interesting to play, and level 3 is the same as two, but with random object placement.

The source code for other Atari 2600 games is available, e.g. for Pitfall, so making those work with the original graphics shouldn’t be hard.


#6

I have started looking at porting Pitfall. It is just some of the the graphics at the moment, not the gameplay.


#7

More complete pitfall game now, although lots of details to get right to play like the original.


#8

OMG that looks amazing! Well done!!!


#9

I seem to be able to get a 4k Atari 2600 game into the 14k PicoSoc BRAM Risc-V C implementation. It gets very tight so I have to optimise the code a bit but I haven’t had to resort to Risc-V assembler yet.

The graphics are done with a mixture of TIA-like hardware acceleration and some direct draw_pixel calls from C. It would only be sensible to implement the exact TIA interface if I used a 6502 processor as TIA is tightly-coupled with the 6502 timing. I read the book “Racing the Beam”, which is about Atari 2600 history and game development.

The TIA audio is very simple, so I think I could add that, but I haven’t tried yet.

I have implemented the same algorithm as the original Pitfall!, so the screens should be the same. There are currently lots of little details wrong in the graphics and gameplay with my implementation. Getting those right takes time and investigation.

I have the Stella emulator running which includes a debugger, and I have the annotated Pitfall! disassembled source, so it is possible to investigate things in detail. However, spending a lot of time to recreate the original exactly is probably not sensible. It has been interesting to see how Atari 2600 games were written though, and to attempt to recreate a couple of them.


#10

I am thinking of making a start on a 6502 implementation.

There is a project that @lukevalenty started a while ago that implements a 6502 processor using a Wishbone Bus. I have never tried using a Wishbone bus so I thought that might be a good learning exercise.

I am thinking of trying to implement a very simple Atari 2600 game with this, so the one I am looking at is a version of Pong in 256 bytes of 6502 assembler:

http://www.bjars.com/source/pong256b.asm

It will need at least a subset of the interface to the TIA and PIA chips to get this to write to the LCD and read from the buttons. I don’t know yet if I need to get everything clock-cycle accurate to make this simple game work a bit.


#11

Hopefully not :slight_smile: It was the “clock cycle accurate” part of things that caused me to pause and rethink my desire to build a 6502… It turns out they’re actually pretty complicated beasts really - with multiple bits of instructions in-flight at any given time. I mean I guess I should have known or at least suspected, but sometimes it’s only when you go digging that you get faced with the true scale of your ignorance :slight_smile:

There’s some really interesting doco floating about now though - eg. CCC comes to the rescue again with a fantastic talk about the 6502:

… and there’s also this document which contains a useful block diagram that shows a the internal control lines that are used - supposedly fairly accurate: https://projects.ncsu.edu/wcae/WCAE1/hanson.pdf

When I was looking, I found that there were some verilog implementations of the 6502 available, but most of the ones I could find seemed like they were pretty incomplete (didn’t handle lots of the instructions; weren’t cycle accurate).

Then there was this one:

http://www.aholme.co.uk/6502/Main.htm

Which was auto-generated from the actual gate-level version of the hardware. It’s supposed to be half-cycle accurate, but it’s also really complicated, and needs a FPGA clock that runs at multiples of the actual CPU clock speed to give signals time to propogate and settle.

I’ve been distracted with other non-FPGA stuff lately, but that’s kind of where I left my 6502 thoughts - a little bit sadder and less bullish than when I started looking into it, but also a little more enlightened :).

I think that using a non-cycle accurate 6502 core is probably a good place to start for pong though. I suspect that pong probably isn’t doing anything too fancy - eg. modifying the TIA registers mid-line, so hopefully you’ll be okay… :crossed_fingers:


#12

I have made a start on this now.

I am using the Artlet 6502 CPU as this was used by Luke’s project and the mystorm Ice40Atom and Ice40Beeb projects that I am slightly familiar with.

I had a bit of a problem with the Wishbone implementation that @lukevalenty’s project uses, as it was built with Lattice tools and needed changes to work with icestorm. The biggest change was that icestorm does not support “wor” variables. “wor” is like “wire” but you can do multiple assignments to it and they get ORed together. But I now have a wb_bus.v implementation that appears to work.

I implemented the ROM, reading it from a hex file. TIA and PIA are currently just RAM implementations. I need to add the interfaces to the LCD, buttons, timers etc.

I changed wb_6502_bridge.v quite a bit. It is the wishbone wrapper to the Arlet Ottens CPU. I made it a bit more like the way Ice40Atom works, registering the outputs from the CPU, and slowing the CPU down with a clock divider.

I currently have the CPU running at one instruction per second so that I can watch the data bus on an 8-led display (a digilent Pmod).

So now I need to implement enough of TIA and PIA to get the 256 byte Pong implementation to run.

Thanks for all that stuff - it was very useful. I will probably have to use the cycle-accurate CPU some time.

The MISTer project has an Atari 2600 implementation and uses this VHDL implementation that claims to be cycle-accurate:


#13

Here’s a Verilog 6502 that was automatically generated from scans of the 6502 die. It should be very accurate…including undocumented instructions and behaviors/bugs.

http://www.aholme.co.uk/6502/Main.htm


#14

Ohh yeah…that’s the same one @gundy posted earlier! :laughing:


#15

This might be helpful. I recently ran across MicroCore’s MCL65. It is uses a micro-sequencer and claims to be “cycle-exact with the original processor”. It has been tested successfully in original 80’s hardware and claims to have a small footprint:

MCL65


#16

Yes.that looks interesting. It might take some work to get it going with icestorm.


#17

Still a lot of work to get the TIA and PIA chip emulations fully working but the 6502 CPU is running and writing to the screen.

This version with the Arlet Ottens CPU will only do vertical beam racing. To get horizontal beam racing I will need to use one of the cycle-accurate CPUs.


#18

I moved the project to a new repository.

I have some vertical beam racing working now, but still a long way to go:


#19

I conitinue to make progress on this. The TIA chip emulation is nearly complete. I can do the moving ball, missiles, sprites, including large sprites and multiple copies.

The main things missing from it are collision detection and audio.

The PIA chip needs a bit more work on it. The RAM seems to work fine. I am not sure if the timers are working correctly. Not all the input modes have been emulated. The direction button input for the joysticks is working. The fire buttons are implemented by the TIA.

I need to do some more work on timing even before looking at the cycle-accurate CPU implementation.

The pong256.asm 256-byte implementation of Pong has proven hard to use as it does do horizontal beam racing and it has some very obscure code, even by Atari 2600 standards, so I am implementing my own simpler version.

Not sure how many original or newer homebrew games I will be able to run, without getting cycle-accurate timing.

I’m not sure if games that use paddles can be supported on the FPGC as on the Atari 2600 they used a potientiometer to charge a capacitor and calculated the position by timing how long the capacitor took to discharge. It might be possible to attach similar hardware to the TX pin which is broken out on a header. Otherwise I will need to stick to games that use joysticks. I think that is what the portable Atari 2600 device I bought does.


#20

A very simple version of Pong is now running. It is currently a little slow.

This shows that most of the TIA functionality, including collision detection is now working.

It is a bit hard to see the ball the picture. I will probably make it bigger. A video would show the ball bouncing between the two bats.