A multipurpose card that emulates ROM and RAM. The ROM content is loaded from the SD card, as well as single-part programs in machine code stored in the CAS format. Below I provide a complete guide on how to make own Flexi Card.


Flexi card (hereinafter FC) would probably never have been created if I had not come across the pages of Kernelcrash1, who inspired me with his projects and from which FC is based. Some parts of his code are used in my project without changes. I thank KernelCrash for not keeping his knowledge to himself, and for allowing me to draw on his experience. Therefore, I am also making this project available to others.


FC uses a Chinese development board DevEBox.2 The advantages of this board are its small size, low price3, the presence of a slot for a micro SD card. It has a large number of IO ports and, most importantly, and this is also the reason for choosing this processor, that most of its GPIO ports are 5V tolerant, which is essential for cooperation with TTL logic. It is also very easy to flash and contains a debug port. The heart of this board is the STM32F407 processor from the Arm Cortex-M4 family2. Specifically, the VET6 variant, which has 512 KB of Flash memory3. It goes without saying that the use of a development board is not essential for the project, if you are able to design your own PCB with a minimal circuitry of the processor plus the necessary components for the operation of the SD card. I chose a development board, which is more convenient for prototyping and contains everything necessary.

Pin wiring

The choice of pins used seems messy, but it should be pointed out that each pin in the STM serves several functions that are activated/deactivated in software. So it depends what peripherals you want to use.

Sord GPIO pin
* marks pins not yet used in fw
used by FLASH
used by SWD
user LEDS
used by SD

debugging output (not used in normal mode except PA1 for LED) PA0-PA3

The FC power supply can be implemented in several ways. For the final operation, the board is ready to use the Sord's power supply. However, if you need flash or connect the FC using the STLINK dongle, you must first disconnect JMP1, otherwise you may damage the FC or Sord!


After reset or power on, the FC tests for the presence of the SD card. If the sordm5  directory is found in the root, which is a kind of indicator that the SD card contains compatible programs, the presence of the menu.rom file in the root of the card is tested. If it is found, it is loaded at address 2000H (i.e. as a ROM cartridge) and run. This then shows the user the contents of the SD card and allows the user to select programs. Alternatively, if a file called debug.cas  is found in the root, it is loaded into memory as well. I have often used this to debug z80 code.

If any of this testing fails, FC goes into Basic – F + 32kB RAM and the SD card is not used.

The program has a time-critical part written in arm assembler. This is the MREQ handler,
where we emulate RAM and ROM. The rest is written in C, which is easier to write, although I personally don't like it, so please excuse any nonsense in the code. That being said, without the SD card, the FC behaves like a 64KBF DIY card (I may redo it in the future to a slightly different mode), which in the modified Sord4 allows you to reach up to 64kB of RAM by disabling the MONITOR ROM and the cartridge. In the unmodified Sord, of course, only 32kB. To prevent damage to the unmodified Sord, there is a ROM0 jumper on the FC which, when disconnected, prevents control of the ROM0 signal used to disable MONITOR ROM. The memory modes are controlled via port 30h as follows:

If a falling edge is detected on MREQ, an interrupt is generated, in which it is determined by reading the MWR and MRD signals whether it is a read or write to RAM or ROM memory. The time required to start the interrupt service routine is about 83nS and lasts ~583nS at the maximum processor frequency.
Furthermore, it is determined according to the set memory mode whether the memory area is under the control of FC and whether it is a RAM type area in case of writing. Otherwise, the interrupt is quickly terminated to leave the processor time to the main thread.

This is formed by an infinite loop, in which the state of the variable main_thread_cmd is tested, which indicates whether Sord requires something from the FC card (or vice versa). This variable is set in the interrupt activated by the falling edge on IOWR, which is initiated by writing a command to port 81h. Then, depending on the command, data is sent or read on port 80h. Currently, FC recognizes these commands:

0BREAK Breaks current command
1GET_COUNT Returns the file count
2SET_INDEXSets pointer position on file number
3GET_INDEX Gets pointer position
4NEXT_FILEIncrease pointer position by 1
5PREV_FILEDecrease pointer position by 1
6FIRST_FILEResets pointer
7GET_FILENAMEReads filename at pointer position from buffer
8LOAD_FILELoads file to memory
9RESET_SORDNot implemented yet
10DIR_SORDDirs SD card to buffer
11OFFSET_RAM_ONOffsets FC ram region 7000-7FFF to 8000-8FFF
12OFFSET_RAM_OFFDisables FC ram offset

Program menu.rom is written in z80 assembler. The program provides a list of programs located on the SD card in a pageable menu. After the user selects a program cmd8  is used to load the selected program into the RAM area. However, if the program is located in the area 7000-7fff, it is “covered” by the Sord's internal RAM. For these purposes cmd11  is used, which can temporarily offset the “covered" area by +1000h, i.e. to the area 8000-8fff. Then it is up to menu.rom  to copy the data from here to the Sord's internal memory and then cancel the offset with cmd12 .This trick is mainly used for the MSX programs, where the MSX bios is located in the area 7000-7fff

Another task of the main loop is to test the RST signal. If its activity is detected, the duration of the press is recorded. If it is shorter than about 3s, only Sord is reset (FC does not react). If it is longer, FC is also reset. Another way to reset FC independently of Sord is to use the RST button under the SD slot.

For communication of FC with SD card, the open source library FatFs is used.5


You will need the arm cross compiler. A description of how to get one for your platform is beyond the scope of this article. I use WSL, so the following description will use the Linux environment.

Most Linux distributions will install it:

Next, you will need the firmware package for the STM32F4DISCOVERY board from st.com.
It is called STSW-STM3206866, unzip it somewhere and set this directory in the Makefile in the STM_COMMON variable  .

Then you will need the Basic-F rom, copy it to the roms directory, rename it to basic-f.rom. If you want to run MSX, you will also need msx.rom. Once you have everything together, follow these steps to start the compilation.

To compile menu.rom you will need the z80 cross compiler. I use pasmo7which you can install using

And then you compile with the command

Firmware flashing

There are basically two ways to flash. Either via the built-in USB port in DFU mode, which you switch the card to by switching the BOOT0 pin from GND to 3V3. Then you connect to your computer and flash using the dfu-util8 on Linux with the make flash-dfu command, or using the DfuSe Demo for Windows. In this case you will need your compiled code in dfu format. To create the dfu format you can use this utility: hex2dfu9.

Original programmer
Chinese clone

The second way requires the STLINK programmer. In this case you don't need to switch BOOT0 at all, the programmer will do everything by itself. I used the Linux program st-flash10which you will run by command make flash.

SD card preparation

Format the card to FAT32 format. KernelCrash recommends cards with small capacity, or at least format them to a smaller size, because they are then less problematic. I have been using a 4GB card without any problems during testing.

Place menu.rom and optionally debug.cas in the root of the card. Create a directory here called sordm5 and copy the files you want to run into it. Remember, however, that the sorting is not alphabetical, but according to the order in which you wrote them to the card. To properly recognize the programs, you need to adjust the extensions of the programs as follows:

  • ROM or BIN: ROM cartridges
  • CAS: programs with autostart in machine code
  • MSX: MSX programs that run under MSX. They are stored in the classic CAS format.

PCB fabrication

Well, it depends on where you want to make the board. I used PCB Prototype & PCB Fabrication Manufacturer – JLCPCB, you just need to use the Gerber file from the repository from the pcb folder and set the desired board properties. The minimum number of boards is 5 pieces, but the service is quite cheap, considering how much trouble it saves you.


And that’s it. You can find the source codes here github.com/dlabi/sordm5-flexicard.git.

There are many ways to use the potential of the STM board, so there is room for improvement. So far, FC can do the basics. Maybe in the future I will change the functionality a bit, depending on how the current solution works (or not).

If you would like me to elaborate or add something, write in the comments. And if you haven’t seen it yet, there is also a pseudo advertisement for Flexi Card which I've created for fun :-)

  1. www.kernelcrash.com ↩︎
  2. https://stm32-base.org/boards/STM32F407VET6-STM32F4XX-M ↩︎
  3. např. https://www.aliexpress.com/item/1005005124722843.html ↩︎
  4. https://dlabi.cz/programove-odepinani-monitor-rom-pro-sord-m5/ ↩︎
  5. http://elm-chan.org/fsw/ff/ ↩︎
  6. https://www.st.com/en/embedded-software/stsw-stm32068.html ↩︎
  7. https://pasmo.speccy.org ↩︎
  8. sudo apt install dfu-utils ↩︎
  9. https://github.com/encedo/hex2dfu ↩︎
  10. sudo apt install stlink-tools ↩︎