<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lefteris Giannaros</title>
    <description>The latest articles on DEV Community by Lefteris Giannaros (@lefosg).</description>
    <link>https://dev.to/lefosg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F596658%2Fd3c9ffb9-44db-4ffb-93b2-fad8ea273834.jpg</url>
      <title>DEV Community: Lefteris Giannaros</title>
      <link>https://dev.to/lefosg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lefosg"/>
    <language>en</language>
    <item>
      <title>Bridging a Real PS1 to RetroAchievements With a Raspberry Pi Pico 2W</title>
      <dc:creator>Lefteris Giannaros</dc:creator>
      <pubDate>Mon, 17 Aug 2026 13:42:24 +0000</pubDate>
      <link>https://dev.to/lefosg/bridging-a-real-ps1-to-retroachievements-with-a-raspberry-pi-pico-2w-jh0</link>
      <guid>https://dev.to/lefosg/bridging-a-real-ps1-to-retroachievements-with-a-raspberry-pi-pico-2w-jh0</guid>
      <description>&lt;p&gt;Spent the week trying to get RetroAchievements working on a real PS1.&lt;/p&gt;

&lt;p&gt;What if we could read PSX memory somehow? Old models have the parallel port, all of them have the serial port, there are memory card exploits, so what if we added a WiFi-enabled device somewhere in between to read memory values and send them to the RetroAchievements API?&lt;/p&gt;

&lt;h2&gt;
  
  
  The parallel port attempt
&lt;/h2&gt;

&lt;p&gt;With that in mind I went head on trying to print a parallel port adapter. After five hours of test prints, 68 pins were hard to fit even at 0.12mm so I set that option aside.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SIO port
&lt;/h2&gt;

&lt;p&gt;Moved on to the SIO (Serial I/O) port. Easier print, 8 pins from which I only need 3. Connected the Raspberry Pi Pico 2W, wrote a Python script bridging to the RA API over WiFi. Then I patched game executables to send the memory addresses needed for their specific achievement sets. Got responses successfully for Devil Dice and Kula World, it updated the last played game and showed me achievements. Kinda works. Worth mentioning: the Pico only has 264KB of RAM so it can't fit the whole JSON response with all achievements for a game. For now I picked only the headers I needed to make it work. That part will need proper testing across games eventually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F03k3ywyjbubkdf5bzmuk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F03k3ywyjbubkdf5bzmuk.jpeg" alt="Pico 2W on the SIO port three wires, WiFi bridge to RA." width="400" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The dead end
&lt;/h2&gt;

&lt;p&gt;Made it exist first. But this is a very bad way to program something and I also ran out of blank CDs with all that testing. The issue is I had literally hardcoded an extra memory function that loads and sits in a specific memory heap for the whole runtime. If the game ever needs that address, it crashes. It worked for Kula World and Devil Dice but games like Crash Bandicoot exploit any means of memory available on the PSX. Not a real solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sunday morning POST
&lt;/h2&gt;

&lt;p&gt;Stepped back on Sunday morning with a coffee and a clear head.&lt;/p&gt;

&lt;p&gt;Devices POST and check stuff. The parallel port used to load cheats via Action Replay, which added a payload to the BIOS before the game started and that's how they modded RAM. Then I remembered, if you plug a memory card in after the console boots it won't read it. So the BIOS is doing something with the memory card very early, before the game ever loads.&lt;/p&gt;

&lt;p&gt;FreePSXBoot exploits a buffer overflow in the BIOS memory card boot handler, letting a crafted memory card inject a payload before the game runs. That payload could install a timer interrupt handler that periodically reads whatever RAM addresses RA needs and sends them over SIO to the Pico, which forwards to the RA API over WiFi. Original disc completely untouched.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyn0rguz9k62v73yi4i4g.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyn0rguz9k62v73yi4i4g.jpeg" alt="Memory card path taped Dupont cables" width="400" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it's paused
&lt;/h2&gt;

&lt;p&gt;So I could buy a pre-flashed memory card, or get the memory port off a dead PSX, or solder wires to my RPi5. I tried taping some Dupont cables to a memory card reader but stopped because I wasn't going to risk burning my Pi and my only memory card. If I do this I'll do it properly.&lt;/p&gt;

&lt;p&gt;Paused for now but pretty close. One thing worth saying, AI gave me a wrong SIO pinout from a plain text site it had clearly been trained on and cited it confidently. Always check multiple hardware sources before you connect anything.&lt;/p&gt;

&lt;p&gt;Repo is private for now.&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>retroachievements</category>
      <category>hardware</category>
      <category>python</category>
    </item>
  </channel>
</rss>
