The Learning of Rust
During the last months I was rather busy with another project. On 21.08.2022 I've decided to finally start learning Rust, as I wanted to learn more about the powers it possesses. As a professional C++ developer I've noticed certain flaws of the way C handles concurrency. It doesn't matter if it is a Linux daemon with threads or an embedded project with interrupts. Concurrency can lead to stochastic bugs difficult to pin down. Rust doesn't have this issue as the compiler itself makes use of formal verification to ensure that no data structures are shared globally without mutual exclusive protection.
tl;dr Rust is very safe.
I wanted to learn that language and needed a project to do so.
The Project
My SlamySTM32Floppy project was now finished for a long time. But I wasn't happy anymore with its state. The code is messy and copy protected images were never fully verified after being written. Also new projects have entered the game by now. There is the Greaseweazle and also the KryoFlux. If it wasn't for my desire to cleanup my old project and my love for old technology I would have just bought a Greaseweazle. It is open source and prebuilt hardware is not very expensive.
As I had the old hardware lying around I decided to just go with it and start the firmware and the host tools from scratch. Also my solution never had any housing. A fine remainder:
This was the state during 2016 and it was still like this in my closet by now. That was about to change.
The goal
- Yet another USB floppy flux thing project because there wasn't one before. lol.
- Writing of copy protected images as correct as possible
- Make use of write precompensation this time
- Verification of all written data to the level of a single flux reversal
- Writing of images as fast as possible. No rotation of the disk shall be wasted.
- Have some integration tests to check for regressions during development
- Adding features can break previous accomplishments easily
- Have a proper documentation about its usage
- Utilize DMA this time for better performance
-
USB communication is not stalled during flux operations
A different approach to write flux data
The way the Greaseweazle approaches its task is vastly superior to my old technique. The SlamySTM32Floppy used code in its firmware for very specific tasks. GCR and MFM are handled by different functions. DMA was not used to write and collect pulses. Verification of written data was performed by parsing known track formats. There was a verify function for Amiga sectors and for ISO sectors. The code is open source and can be used to learn from my old mistakes.
The Greaseweazle on the other hand has a very basic firmware with only one task to solve: The correct writing of raw fluxes and reading of those. This keeps the firmware simple as all intelligence is on the host side. This however means that more data needs to be transferred between STM32 and PC. But I've decided to go with this approach as well as it seems to be very flexible.
A different approach to verify written flux data
However I was not happy with the way, the Greaseweazle verifies the written tracks. A whole track is read back to the PC and then cross correlation is performed to check the equality of any possible flux stream. I like this idea but I wanted to do the verification on the firmware itself. My goal here is different. As before, this project is targeted to be optimized for writing speed, so this simply won't do. Instead I needed an algorithm for cross correlation which is performed on the device while the just written track is read back from disk.
The idea of the Greaseweazle with cross correlation was good, but it needed to be scaled down. By the time of writing I went with reading the first 200 flux pulses after the index signal and cross correlating them against the first 20 pulses of the groundtruth data. As soon as both match up both flux streams are considered in sync and are compared until no groundtruth data is left to compare against.
200 flux pulses might sound like a lot, but it had to be as this floppy writer is capable of working without the index pulse to support flipped 5.25" disks. The larger amount of data allows more room for fluctuation in the rotation of the disk.
Usage of write precompensation
Early on, I've never thought about write precompensation but it really
improves the quality of the written data. For more information, I've written
a
markdown file about this topic in the github repo. This must be performed for every drive and can be essential for games
like the Amiga version of Turrican II.
A smaller board
Originally this project was started using the STM32F4DISCOVERY. This eval board still performs well today but it's size makes it difficult to fit into a case. I've decided use a smaller one this time: A board without microphone, a headphone amplifier, an acceleration sensor and an integrated stlink.
The Diymore STM32F4 seemed to be the right choice. It is exactly the same microcontroller - the STM32F407 - but reduced to the essentials. All this project needs, is I/O and a USB port.
In the end, I've wasted space nonetheless as the used perfboard could've been smaller.
But still look for yourself:
A much smaller board with only the relevant components |
A case made from wood to properly store the electronics
Early state of the case viewed from the top. Some rails added for the
drives to sit on |
Viewed from the front |
And the back. |
Small piece of wood to keep the PicoPSU in place |
Connected the PicoPSU to the small piece of wood |
The case and the top piece |
The whole case fitted together. A view inside. |
The Result
This project is open source from the start and can be inspected on github.
I've also decided to maintain a list of correctly written images so compatibility is properly documented.
No comments:
Post a Comment