Saturday, September 21, 2013

SNES flash cartridge SFC-32

A year ago I have acquired a pure SNES console without any additional peripherals (joypad, power supply, video cable etc.). The console was untested. Some months later I've also found some cartridges for it (Super Mario World), thus the story continued: connected the console to TV, inserted a cart and turned it on: IT WORKED! Perfect! ;)

Thousands games are available for this great console; most of them have superb 2D classic pixel graphics and perfect stereo digital audio. The graphical and sound capabilites are much better than Amiga 500; 256 colors on the sreen at once, multi hardware layers, extra large sprites, 8 channel audio D/A, mode 7 etc. 

After testing some games in emulator the results were fantastic. Chaos Engine looked similar to the A1200 version (it has 2 frame scroll, why?!), but Street Fighter, Final Fight and Mortal Kombat 2 were exactly the same as the original arcade versions! 

The next step was straightforward: purchase or develop a flash cartridge for the SNES. A brand new Super UFO costs 70-80 USD, others also have similar price.

Below You can watch the preview video of my own developed SNES SFC-32 flash cartridge.

Another usual problem with me: if I order the Super UFO, the delivery time will be 30-40 days. Once it arrives, I'll test it, play 1-2 hours and the whole stuff will not be interesting anymore. I know myself. So what to do? The available options were:

1. Build a flash cart based on someone else's design or
2. Develop a completely own cartridge

Of course, option 2 has been selected. The development procedure is much more interesting than playing games with a factory made cartridge. Not mentioning the required 2-3 months of hard work. ;)

There are many cart hacking schemes available freely on the Internet. 90% of them replace the mask programmed ROM with a flash ROM. The flash programming requires EPROM programmer. Some of them has it's own programmer hardware (USB etc.). The most perfect ones use SD card for data storage and games are selectable on the TV screen using the SNES gamepad.

I needed an optimal solution for my design: not the most complicated one, but either not a primitive realization. The requirements became clear quickly:

  • SD card with FAT 16 filesystem support, max. 512 files in root directory
  • Self programmable system with microcontroller 
  • Cheap display hardware (3x7 segment LED display instead of a 2x16 LCD) 
  • 5V 4 MB flash chip (the max. game ROM size is 4 MB)
  • LOROM, HIROM support with or without header

The first step was to obtain a few 256 kByte 8 bit parallel flash EPROMs  and wire one of them to a PIC 16F873 microcontroller for initial tests. These chips are available from various old PC motherboards (Pentium 1 category).

256k x 8 parallel flash EPROM

After learning the flash chip datasheet I have managed to write low level routines in C (with MPLAB) to read, write and erase the flash content.

Once this worked, connecting the SD card was the next step. I have made an adapter cable to quickly connect the SD card slot to the breadboard.

Open source SD libraries are available for larger microcontrollers, but not for a 4k PIC 16F873. As usual there are tons of documents available on the Internet how to initialize the SD card, how to read / write data etc. The most useful document was the Sandisk SD user manual.

Once the SD read operations worked, I have copied (with dd) a SNES game ROM dump to the card from sector 0 and invoked the flash writer routine. The system copied the ROM file to the flash memory successfully. The SNES booted up with it (the first tested stuff was Top Gear, it is a 512 kB ROM).

It was time to order a 4 MB (32 Mbit) 8 bit flash EPROM for the final design (M39F032D).

32M x 8 parallel flash EPROM

As the design became more complex, the microcontroller has been replaced with a larger one: PIC 16F887 with 8 kiloword program memory. Buttons and LED display have been added to the breadboard design.

At this point I needed a FAT 16 filesystem. There is no such library available for a small device like a 8 k PIC, so I decided to write my own FAT 16 implementation (read only).  Once it worked properly, the breadboard design achieved 95% of completion.

Breadboard version running Street Fighter II
During the test cca. 90% of games were running without any problem. Games not working were which require FX chip, check SRAM (copy protection) etc.

The next step was to design a 2 layer prototype PCB.


Current status

The system is working perfectly, without any issue. The original goal has been achieved, I can play almost every SNES game I would like.

You can find the v 1.1 schematic diagram and some additional images below.
SFC-32 v 1.1 schematic diagram

Future plans, ideas:
  • Redesign the PCB and fix the routing errors
  • Use CPLD to reduce the number of components and the size of PCB
  • Add SRAM for save game feature
  • Redesign the complete system to use SNES program for selecting games on the TV screen
  • Use DRAM instead of the slow flash (SRAM is still expensive, even in 2013!)

All materials presented on this page are Copyright © 2013. Viktor K. All rights reserved.

Sunday, September 8, 2013

How to repair a broken ethernet interface on Mikrotik Routerboard 433

Recently I have acquired some faulty Mikrotik Routerboards (RB 433 etc.). After few minutes of inspection it was clear all ethernet ports are broken on the board. One ethernet port connector has also been physically damaged. I have removed the broken connector to be 100% sure it doesn't cause short circuit. Other ports were in partially working condition, but they produced heavy packet loss (50-80%). The conclusion was the ethernet controller chip is broken. The manufacturer is IC+, part type is IP 175 (C/D).

A broken Mikrotik RB 433

So I have desoldered the broken chip from the faulty board and the good chip from the donor board (which was also hit by a thunder, but fortunately only the PSU module has been damaged).

Donor board: the ethernet controller chip has been removed

The next step was to solder the good chip to the board to get repaired.

Mounted chip on the "better" board

Repaired RB 433

After powering up the system all ethernet ports worked immediately. The packet loss has disappeared.
No more packet loss

This was a short description of the steps to do in order to repair a such board. Required tools and parts are:
  • Broken board to get repaired
  • A donor board
  • Temperature controlled soldering station (Weller WTCP 50 or similar)
  • Desoldering wire
  • Good quality flux
  • Isopropyl alcohol for cleaning up the board after desoldering and soldering the components

SMD soldering is a tricky thing, it requires lots of experience to complete it successfully. Do it on your own risk!

Sunday, June 30, 2013

Home made printed circuit board (PCB) for prototypes

Finally I have purchased a Positiv 20 spray, thus making prototype PCBs became reality. It was a real challenge to etch a SMD compatible drawing (line width is 12-14 mils).

On the photographs below You can see it is realizable without any special equipment. The results can be improved in a dust free environment or using a photoresist PCB.

Blank PCB of RS 232 TTL level converter
PCB of 72 pin SIMM adapter
72 pin SIMM adapter with soldered SIMM socket
Mounted SMD flash chip
The TSOP 40 adapter is required for the upcoming project (SNES flash cartridge), while the SIMM adapter will be used in the Amiga RAM expander (one 72 pin SIMM for 4-8MB).

More information are coming soon. Stay tuned! :)

Sunday, June 23, 2013

Amiga 500 buffered IDE controller

This is not the latest project, but the description was still missing, so here are the details of my own developed IDE controller. 

The original goal of this project was to connect an IDE HDD to the CPU bus of the Amiga 500 and try to send a command to it.

I have started to work on the hardware in 2012. december. The first version used a simple address decoder to map the disk registers to $200000 in the Amiga memory map. No data line buffers were used.

The test hard disk was an old Western Digital disk. The test program was written in assembly, using Devpac assembler.

Here are some pictures of the first version:

I was very happy once the hard disk accepted the first command sent to it. It was a motor down command, to turn the motor off and go to standby mode.

When it worked, I have tried to read the disk parameters and some data from the HDD.

The original goal has been achieved, but why not to enhance the system a bit? :) Thus, the next step was to create a more complex program: a music player which uses audio.device and plays some RAW audio data, reading the disk sectors directly (no filesystem is involved). The development was done on Amiga 4000, while the testing was realized on the final hardware, using my own developed serial downloader system.

This system also worked properly. Here is the Youtube video about the initial version: 

Meanwhile I also began to develop a device driver for the IDE system. On the Internet there are many open source drivers available for similar interfaces (Spartan etc.), all written in pure assembly. But I wanted to create a driver written in ANSI C (using SAS C compiler) and to fully avoid assembly. Unfortunately a such C based IDE driver template was unavailable. I have worked on the software cca. 2 months (writing it from the scratch) while the first version began to work. Here I send greetings and thanks to Ralph Babel for his help in the stack pointer issue.

The driver development was done using an A4000, while for testing first WinUAE, later a real A500 was used. Own developed downloader software has been used to transfer the binary files to the Amiga via a serial cable.

Driver development setup with Amiga 4000 and WinUAE
Driver testing setup with Amiga 4000 and Amiga 500
The next step was to test the system with various disks. Some disks worked, some didn't, CF cards also produced data corruption problems.

When data bus drivers were added some disks were still unusable. I have googled a lot to find a proper documentation about the IDE timing while finally found a solution: the /CS signal should be delayed after the address and data lines are asserted. After adding a quick a dirt fix (the delay signal is got from /DTACK, which is fixed on A500) every CF cards started to work properly.

The driver is still not optimized. The disk read speed is ~350 kB/sec on a plain Amiga 500 (measured with SysInfo 3.24). Adding real fast RAM the read speed is increased up to ~450 kB/sec. Don't forget, this is a simple PIO mode device, no DMA is available, thus this transfer rate is acceptable.

Current status

The IDE controller still sits on a breadboard, connected to the 4 MB fast RAM expander. The whole system is under testing. My lab Amiga 500 has Kickstart v 3.1 EPROM, 1 GB CF IDE "disk" and 4 MB fast RAM. Quite enough for playing WHDLoad games, isn't it? :)

IDE controller with 4 MB Fast RAM expander
Master / slave configuration is also supported, IDE IRQ is separated with an own IRQ register (all realized with TTLs). The IDE system maps to $e80000 and uses 64k block of memory with many aliased addresses (simple hardware).

WHDLoad games are working fine, however the 7 MHz CPU is very slow when then the disk image is compressed with XPK. Some games support exiting to Workbench, some don't (68020 is required for full support). Anyway, it is usable.

I have also tested this configuration to build a program written with SAS C 6.58. The compiling and linking is unusable slow, even the system has enough RAM available (GSTs are also enabled). SAS C requires a 020 or 030 CPU for comfortable work. 

The schematic diagram is available on the picture below.
Amiga buffered IDE controller schematic diagram

Future plans

Adding autoconfig feature, intergrate it with the DRAM controller and put the complete logic into FPGA to reduce the number of integrated circuits (and the size of the board).


Now go back in time and let's calculate a bit from the point of view of a programmer: in 1990-1992 40 MB HDD, 4 MB RAM and at least 68020 CPU was required to work with SAS C (maybe a bit less, older versions consume less resources - comments are welcome). The total price of hardware was 3000 DEM or more?! So, why people used assemblers to write programs (including commercial ones)? I think the answer is straightforward. ;)

Thursday, June 6, 2013

Mikrotik v3.x compatible updater script

The blog is called Amiga Projects, but this post is an exception: it is about the Mikrotik scripting.

I have "googled" a lot to find a working and dyndns updater scripts which work on Mikrotik v 3.x. In Mikrotik forums there is a working NoIP updater script only for MT v 5.x. ChangeIP scripts are available for MT v 2.9, v 3.x and v 5.x (all tested).

So I have decided to adapt the ChangeIP script to work with NoIP dyndns records on Mikrotik v 3.x.

Here is the complete and updated (v 1.1) script. This version is more stable than v 1.0. It compares the IP address resolved by DNS server with the local IP address present on the dynamic interface. It sends update if the IP addresses are different.

# updater script
# v 1.1, 2013-08-29

# User variables
:local noipuser "username"
:local noippass "password"
:local noiphost "hostname"
:local noipinterface "interface"

# Get the current IP address
:local curip [ /ip address get [/ip address find interface=$noipinterface ] address ]

# Strip the net mask
:for i from=( [:len $curip] - 1) to=0 do={
  :if ( [:pick $curip $i] = "/") do={
    :set curip [:pick $curip 0 $i]

# Did we get an IP address to compare?
:if ([ :typeof $curip ] = nil ) do={
   :log info ("NoIP: No IP address present on " . $noipinterface)
} else={
  :local dnsip [:resolve $noiphost];
  :if ($curip != $dnsip) do={
    :log info ("NoIP: Sending update " . $dnsip)
    /tool fetch address="" src-path="nic/update\3Fhostname=$noiphost&myip=$curip" user=$noipuser password=$noippass keep-result=no
  } else={
    :log info "NoIP: No update required"

The current version updates only one NoIP host (NoIP supports 3 free hosts).

Tuesday, May 21, 2013

4 MB fast RAM expander with SIMM modules (TTL version)

Long time ago (more precisely around 1993) when I bought my first Amiga 1200 it was a wonderful machine for a reasonable price (~800 DEM): fast, 32 bit CPU, 2 MB RAM, integrated IDE controller, everything I have ever dreamed about. But I soon confronted the reality: it hasn't got enough memory available, the HDD is not included in the base product price etc. The 2.5" 120 MB HDD costed 600 DEM in those times (~300 USD). It was a "regular" price for a 2.5" device then.

But the RAM was a completely different thing. 1 MB SIMM module costed ~70 DEM (~30-40 USD), while a 4 MB RAM expander for the Amiga 1200 400-500 DEM! 4x 70 = 280 DEM. Perfect, Commodore f***d it up again: they didn't add a standard SIMM socket to the motherboard, so You have no chance to add a cheap RAM module to the system.

Are You wondering why Commodore didn't survive the 90's and why it couldn't become a leading PC manufacturer (PC is not equal with IBM compatible in this context, but a Personal Computer)? Partial answer is: it costed a lot more than any "Taiwan assembled" IBM clone. Only Apple was able to sell the 2-3x overpriced Macintosh machines... till 1997... then there was a big chance they will also follow the C=... But this is a completely different story. Lets go back to the original topic.

In 1993 I've got the original John Kamchen 8 MB Fast RAM expander schematic with description. The next step was clear: adapt it somehow to fit in Amiga 1200. But it wasn't as easy as it looked to be. It was designed for an Amiga 500 which is a 16 bit machine while Amiga 1200 has a 32 bit CPU. Duhh!

I was seeking for help everywhere: asked various electronic engineers, everybody who ever worked with digital electronic... Needless to say, no one was able to help me to redesign the project, or at least to understand how it works. So the memory expander project was cancelled, I sold my Amiga 1200 in 1995 with it's original 2 MB RAM and 120 MB HDD to pull out some money from the obsolete thing.

In 2000 I began again to collect Amiga hardwares, including A2000, A1200, A4000, A500 etc. A2000 has an original C= fast RAM expander (A2058) etc.

It 2011 I've got an idea: why to not try again to build the original John Kamchen RAM expander, but now in original form, for an Amiga 500?

I've installed all components on a veroboard.

The first test results were promising: the Amiga booted up successfully, the CPU did not burn out etc. ;)

I have checked the RAM at location $200000 with MasterSeka 1.8 and found it! It was readable and writable, but the content was always corrupt. It forgot the data soon after I have entered it. I have tried to fix the hardware for 2 weeks, without any success. And I gave up... till January 2013.

Then I began to build a new RAM board with an entirely new approach. It was clear: without completely understanding the theory of the operation of dynamic RAM and the MC 680000 on a hardware level it is impossible to realize a such project.

The first thing was to collect all available manuals about DRAMs and MC 680000 CPU. In the first phase I have designed a simple 8 bit DRAM controller connected to Amiga, located at $20000.

This testing and development phase lasted cca. 2 months, until I have fully understood the DRAM systems and implemented the refresh circuitry. The refresh circuit on the original John Kamchen schematic does almost nothing: it activates the refresh cycle when the CPU accesses the Chip RAM (every 20 ms when interrupts are executed in idle state). But it is not enough at all. Each DRAM cell requires refresh in every 8 ms, but the original design executes one refresh cycle in every 20 ms (a burst like, but it never refreshes all cells within the 8 ms period)..

So, I have designed a completely new refresh circuit and the content of RAM has not been corrupted anymore.

The $AA is the valid upper Byte content of the DRAM

 The next phase was to implement the 16 bit version on a breadboard. First, a 2 MB version:

And a 4 MB version:

16 bit 4 MB breadboard version

And the problems began. The board worked properly for hours, but sometimes the Amiga crashed strangely. It became clear the system crashed when I launched Turbo Imploder, Hippoplayer or any other music player software.

Meanwhile I have tried every possible and impossible combinations to fix it. A new, veroboard based prototype has been built to check the noise level with different PCB layouts. The veroboard produced 3-4 times less noise than the plastic breadboard version but the same bug was still there.

After 6 weeks of testing and debugging (daily 8-10 hours) it became clear there is a mistake in my design: I didn't check carefully the CPU timing diagrams and I have used the same timing for bus master cycle case 2 as for case 1 which led to a shortened RAM access cycle (200 ns RAM access cycle is used, the remaining cycle is for the refresh). You can see the strange thing on the screenshots below: when the code is executed step by step, it works perfectly. In high speed execution the CPU fetches wrong data from the RAM.

For some strange reason the problem appeared only after accessing the $a00000 or $b00000 area: the next fetched instruction was corrupt (some Bytes have been skipped).

Once the reason was found it took only 15 minutes to fix it. But by then I already spent 420 hours trying to find the cause of problem. Great!

Currently I'm testing the 4 MB RAM board combined with the IDE interface. On the picture below You can see the RAM board fitted in Amiga 500.

Schematic diagram of the 4 MB Fast RAM expander

I have also started to design the PCB version. Further plans:

-design the Autoconfig version
-implement logic functions with PALs to reduce the number of TTLs
-combine it with the IDE controller