Jump to content
tschak909

ESP32 as a cartridge emulator

Recommended Posts

I still think it's a bad idea, but since @rbairos's MovieCart has come along since the early discussions about box art in this thread, I wanted to drop a MovieCart version of box art in here just for review. It could just be a static image using the fundamental 10-sprite routine. This is what it would look like... captured from Stella displaying the MVC file.

 

1567559899_ScreenShot2021-10-19at12_15_23pm.thumb.png.9c2694c46e97e88fae9d69da1d5c2dfc.png  1254137760_ScreenShot2021-10-19at12_22_26pm.thumb.png.3a36804921a6413205f5788a7edaeb6a.png  1501252902_ScreenShot2021-10-19at12_34_04pm.thumb.png.8c1ffaa74864ed2927bb82c895772eed.png

 

enduro.mvc

Edited by Andrew Davie
  • Like 5

Share this post


Link to post
Share on other sites

I have thought of $4C4C (and also, $6C6C for JMP indirect), but I believe a mirror of INPT4 lives there in both cases. The TIA read register is what we need to be concerned with, not the TIA write register. The TIA only drives bit 7 there, but bit 7 will almost certainly be 1 unless the joystick button is pushed on boot.

 

There are limited areas in TIA areas that aren't driven ($xE and $xF), and there are possibly some addresses in the RIOT timer areas, but overall I think the best results (and most useful instructions) will be those that correspond to addresses in cartridge space, with an opcode with an odd first digit (1, 3, 5, 7, 9, B, D, F).

Share this post


Link to post
Share on other sites
13 hours ago, tschak909 said:

@batari

 

Having some discussions with @mozzwald, @jeffpiep and @48kRAM.

 

A couple potential possibilities have come to mind:

 

* Using shift registers like the 597. @jeffpiep did a schematic for one, see attached. main-rc201903.pdf

* Using a really small CPLD (like a https://www.latticestore.com/products/tabid/417/categoryid/12/productid/408/default.aspx coupled with a bus transciever like: https://www.ti.com/product/SN74LXCH8T245

Thoughts?

The shift register idea has 7 extra ICs. It may work but this seems far, far more complex than it needs to be?

 

A CPLD by itself should be enough with suitable programming, no bus transceiver needed if you can find a 5v one (or 5v tolerant 3.3v one) instead of the 1.8v one as shown.

 

Maybe even a single SPLD would work. I will think about that one.

 

A bus transceiver may be enough on its own with supporting resistors, with no CPLD needed (I think I mentioned a possible way this could work earlier.)

Share this post


Link to post
Share on other sites

 

On 9/26/2021 at 2:01 PM, tschak909 said:

Has anyone tried anything yet? I'm itching to write some firmware :)

 

In case I wasn't clear, putting $11 on the data bus would be the very first thing done by the custom bootloader. It would then do its normal boot process, and finally put the bytes for NOP, JMP(RESET) on the data bus.  No extra hardware would be required, so you could attempt the firmware now.

  • Like 1

Share this post


Link to post
Share on other sites


Hey guys, just thought I'd chip in what I learned building the moviecart hardware.

First of all. Wow, the esp32 is 5v tolerant as mentioned earlier???

https://www.ridiculously-simple.com/2021/05/19/are-the-esp32-and-esp8266-5v-tolerant-yes-they-officially-are/


That may very well changed how I implemented the next version of the cart

For version 1, I was able to simulate a 1K rom using a 16 mips pic microcontroller and 1K dual port RAM.
However the dual port ram is expensive ($15) and soon to be obsolete.
The pic updated 128-byte sections of the ROM asynchronously and only needed to monitor 3 address lines (a12 for ROM access, A7 for 128-byte page boundaries, and A10 for signalling joystick + switch button back to the cart).

https://github.com/lodefmode/moviecart/tree/main/pic

It was all 5v through hole parts, and it worked well.

For the next version, Im considering a 70 mips through hold 5v pic from microchip.
I *think* I can get away with avoiding the dual port ram with this increased bandwidth.

Luckily the pic had an extremely short bootup time, so what I did was just copy a short 5-byte code to the dual port ram, to keep it continuously resetting:

; -- FB   --- $00    // nmi (brk)
; FC FD   $FB $F3    // reset
; FE FF   $FB $F3    // irq/brk
; (should start looping with those 5 consecutive bytes)

Then I delayed some time to make sure the 6507 was in that loop, while I setup the rest of the 1k ram.

Then when ready I changed the $00 to $20 (1 bit difference) to change it to a JSR.


In early days I considered holding the bus with something like: Clear Carry Flag (hex 0x18) which is always a single byte, so you wouldn't have to worry about which byte in a multi-byte sequence you were interrupting:


 

Edited by rbairos

Share this post


Link to post
Share on other sites
3 minutes ago, rbairos said:


Hey guys, just thought I'd chip in what I learned building the moviecart hardware.

First of all. Wow, the esp32 is 5v tolerant as mentioned earlier???

https://www.ridiculously-simple.com/2021/05/19/are-the-esp32-and-esp8266-5v-tolerant-yes-they-officially-are/


That may very well changed how I implemented the next version of the cart

For version 1, I was able to simulate a 1K rom using a 16 mips pic microcontroller and 1K dual port RAM.
However the dual port ram is expensive ($15) and soon to be obsolete.
The pic updated 128-byte sections of the ROM asynchronously and only needed to monitor 3 address lines (a12 for ROM access, A7 for 128-byte page boundaries, and A10 for signalling joystick + switch button back to the cart).

https://github.com/lodefmode/moviecart/tree/main/pic

It was all 5v through hole parts, and it worked well.

For the next version, Im considering a 70 mips through hold 5v pic from microchip.
I *think* I can get away with avoiding the dual port ram with this increased bandwidth.

Luckily the pic had an extremely short bootup time, so what I did was just copy a short 5-byte code to the dual port ram, to keep it continuously resetting:

; -- FB   --- $00    // nmi (brk)
; FC FD   $FB $F3    // reset
; FE FF   $FB $F3    // irq/brk
; (should start looping with those 5 consecutive bytes)

Then I delayed some time to make sure the 6507 was in that loop, while I setup the rest of the 1k ram.

Then when ready I changed the $00 to $20 (1 bit difference) to change it to a JSR.


In early days I considered holding the bus with something like: Clear Carry Flag (hex 18) which is always a single byte, so you wouldn't have to worry about which byte in a multi-byte sequence you were interrupting:


 

Yup, I had a lengthy conversation with Teo Swee Ann (the founder of Espressif, and the designer of the 8266 and ESP32), to which he stated that the ESP32 is indeed +5v tolerant.

It does have some small side effects (such as DAC values being slightly DC biased), but we've now had almost 2000 FujiNet devices out in the wild, with no ill effects being driven by the Atari's +5V TTL.

 

-Thom

  • Like 1

Share this post


Link to post
Share on other sites
On 10/22/2021 at 5:51 PM, tschak909 said:

Yup, I had a lengthy conversation with Teo Swee Ann (the founder of Espressif, and the designer of the 8266 and ESP32), to which he stated that the ESP32 is indeed +5v tolerant.

It does have some small side effects (such as DAC values being slightly DC biased), but we've now had almost 2000 FujiNet devices out in the wild, with no ill effects being driven by the Atari's +5V TTL.

 

-Thom


So is the ESP8266 also 5v tolerant inputs?
 

Share this post


Link to post
Share on other sites
On 8/8/2021 at 11:34 AM, rossum said:

 

A custom bootloader is your friend, should get you to < 100ms boot times. A nice step by step on how to setup bootloader/bare metal/GDB here:

https://vivonomicon.com/2019/03/30/getting-started-with-bare-metal-esp32-programming/

 

Agree that using the ESP32 alone would be really cool. I built an Atari 800 / NES / SMS on one of those that generated composite audio/video entirely in software and still had plenty of time for a full emulation with bluetooth peripherals: https://rossumblog.com/2020/05/10/130/

 

One core will need to be pretty locked down to meet timing and some faffing will be needed if you still want wifi and bluetooth to keep working. If you wanted a single core version (ESP32S) you would probably need a modal strategy to be either running wifi or 2600 but not both simultaneously.

 

Jeroen Domburg is the right guy to ask about any ESP32 challenges / opportunities. Has built STM32F411 carts and is the heart and soul of ESP32 software.
https://spritesmods.com/?art=veccart&page=1

 

I really love these parts. A ESP32 dual core module with 4M of flash built can be had for $2.50 unit 1:

https://www.mouser.com/datasheet/2/891/esp32_wroom_32e_esp32_wroom_32ue_datasheet_en-1855879.pdf

The schematic for a cart would be preposterously simple: just the module and a voltage regulator.

 

 

Sir when said

 

"Agree that using the ESP32 alone would be really cool. I built an Atari 800 / NES / SMS on one of those that generated composite audio/video entirely in software and still had plenty of time for a full emulation with bluetooth peripherals: https://rossumblog.com/2020/05/10/130/"

 

Could you put the Atari2600 on that chip?

 

 

  • Like 2

Share this post


Link to post
Share on other sites

DAMN. IT. You guys are missing the point as to why I would want the ESP32 there in the first place.

 

If you're bypassing to the bare metal, you can't leverage any of the IDF functions.

 

-Thom

 

Share this post


Link to post
Share on other sites
On 10/26/2021 at 4:36 AM, tschak909 said:

f you're bypassing to the bare metal, you can't leverage any of the IDF functions.

I can so relate to this, as I think the ESP32 with it's two cores is perfect for project, where you need the hard real-time code running on one core and the the "OS" providing Wifi, etc. on the other. This way you get best of both worlds. The only downer is the slow response time on GPIO changes (compared to ATmega, for example).

Share this post


Link to post
Share on other sites

I did a quick proof of concept with a 16v8 SPLD. I found that even this simple chip can not only boot, but can represent around 24 bytes of code for as long as you want. This is literally a 16v8 wired to the cart port, no EPROM at all:

 

IMG_3118.jpg.1f3dc9bfa2379c0ab1da82059dadebec.jpg

 

This particular example represents the following code encoded to the PLD (only A0-A5, A12 and D0-D7 are connected, so the below is mirrored across the entire cart space):

ORG $1FE0
loop: 
	LDA    #$0E    ;each '1' bits generate a VSYNC ON line (bits 1..3)
	STA WSYNC
	STA VSYNC
	LSR
	BNE    VSLP1    ;branch until VYSNC has been reset
screen:
	DEX
	STX COLUBK
	STA WSYNC
	BNE screen
	BEQ loop
ORG $1FFC
	.word loop

 

The logic is not fully utilized here. The 16v8 can use up to 7 product terms per output and I got the above 20 bytes with no more than 6. One might be able to get VBLANK in there too for a proper display. The PLD also disables the outputs on A12 so it can run as long as it needs to like this.

 

So if you want a single chip solution using cheap commodity parts, something like this would work.

  • Like 1

Share this post


Link to post
Share on other sites

That...is most intriguing.

 

We're also looking at hooking up the ESP32 with some 595/597s too...

 

-Thom

Edited by tschak909

Share this post


Link to post
Share on other sites
2 hours ago, tschak909 said:

That...is most intriguing.

 

We're also looking at hooking up the ESP32 with some 595/597s too...

 

-Thom

Interesting, I would not have thought of using shift registers for booting, but yes there is probably a way to make that work.

 

If you want to try the PLD-boot route, I will share how I got it working. I wrote the code above and assembled it, then created a spreadsheet of the individual bits D0-D7 with addresses 0-31. Then I made eight 5-bit karnaugh maps (used an online tool, did not do them by hand.) I used don't cares whenever possible (For instance, for STA WSYNC, the STA can be STA/STX/STY/SAX, and WSYNC can be $02 or $42, meaning bits 0-1 are don't care for the first and bit 6 is don't care for the second.) For each bit I created a logic equation.

 

Also all of the unused space above in the 32 byte range is "don't care" for better logic minimization.

 

This is the PLD code (ABEL syntax):

 

D7 = /A2 * /A0 + /A1 * /A0 + A2 * A1 * A0 + A3 * /A2 * /A1 + A4 + A3 * A2 * A1;

D6 = A2 * A1 + A3 * /A2 * /A1 + A4

D5 = /A2 * /A1 * /A0 + A3 * A2 * A1 * A0 + A4;

D4 = A2 * A1 * A0 + A3 * /A2 * /A1 * /A0 + A3 * A2 * A1 + A4 * /A3 * /A0 + A4 * A2 * A0;

D3 = /A4 * /A2 * /A1 + /A3 * A2 * A1 * /A0 + A3 * A1 * A0 + /A2 * /A1 * A0;

D2 =/A3 * /A2 * /A1 * A0 + /A2 * A1 * /A0 + /A4 * A2 * /A1 * /A0;

D1 = /A3 * A1 * /A0 + /A2 * A1 * /A0 + /A3 * /A2 * A0 + A3 * /A1 * A0;

D0 = /A3 * A2 * /A1 + A3 * A1 * A0 + /A4 * /A1 * /A0;

D7.oe = A12
D6.oe = A12
D5.oe = A12
D4.oe = A12
D3.oe = A12
D2.oe = A12
D1.oe = A12
D0.oe = A12

 

I was surprised you could represent the above 20 bytes (with don't cares as needed) this way and not even use all of the logic on the PLD. There are even unused inputs on the PLD that can be used for disabling PLD output permanently (the .oe lines on a 16v8 can use a complete product term so you can add another input aside from A12 to each, giving a true single-chip solution.)

 

I am sure it could be taken a step further and use the PLD for a short routine to copy code to RIOT RAM, which would make it easier to take over the bus when ready.

 

It was a fun exercise ;)

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...