to speak specifically to the card flow from the machine's point of view, here are the things that happen with NAOMI-based IDAS.
the available options are dictated by the previously polled card hopper state [such as, don't suggest that a card can be purchased when the hopper is empty]. this state is polled upon each attract loop, at the segarosso logo.
machine prompts "do you have a card?"
have a card:
machine prompts "insert card"
machine polls the CRW for sensor state [0x20], checking the status bitfield for card position
if a card is detected at the right position, the CRW is instructed to pull in the card, then close the shutter [0xD0]. once loaded, magnetic data is read [0x33]
if a card is not detected at the right position, the CRW is instructed to close the shutter [0xD0], and new car selection begins
don't have a card:
CRW is instructed to close the shutter [0xD0]
machine prompts "do you want to purchase a card?"
yes:
requests a blank card from the hopper [0xB0] and positions it within the reader
new car selection begins
racer data entered
no:
new car selection begins
some time ago, i spent a good bit of races on my machines, performing game changes [IDASv1 to IDASv2, IDASv2 to IDASv3] with different regions. this testing and racing led me to modify the script in several ways. i don't claim to write python, so, some things [like creating the right bitfields on the fly to CRW state] aren't done in a mature way. i'm a sysadmin, not a programmer. i did, however, analyse the SANWA documentation in regards to how the bitfields and commands were used on the CRP CRW windows DLLs. lots of commands explained in the SANWA documentation, which further explained what the script was doing.
list of things this script now does in comparison to the original:
a bit more CRW state tracking. whether or not the shutter is open or closed, whether or not the card moved within the reader, whether or not a card is busy, or waiting. the game reading the CRW state now does not "virtually" have the shutter and card in wrong positions from read to read. state is more consistent.
annotations of the script commands, so that it is clear what these commands are doing, and what they mean.
when an empty file is supplied to it, the card flow does not assume when the game is talking to the CRW that it now needs to start simulating CRW actions of a new card [which led to a confused script, and a pissed off game]
when an empty file is supplied to it, and the racer elects to not purchase a card on that game launch, the card flow does not get lost and keep expecting a new card to have been requested. a new game launch will re-present the same choice, because the card flow preserves that there was no card loaded from hopper or inserted into it, same as a normal CRW.
when 0x7A [CRWRegisterFont] commands are received, reply appropriately, ingesting the supplied font payload data [not currently saving it for future rendering/use]. this is needed when doing multiple font bank changes when writing to a card face to update.
when 0x7C [CRWPrintL] commands are received, reply appropriately, simulating printing onto the card face. previously, if you had the nerve to race and complete multiple courses on one play [akina and akagi, for example], the script wouldn't know how to handle multiple print commands, and the code would freak, resulting in the game erroring out. not knowing how to rescue where the game thought the CRW should be resulted in losing your gameplay.
the script can now complete the CRW test within the settings menu on all versions! caution, supply a blank file, because it will load a new card from hopper and overwrite.
the script can now complete the CRW clean within the settings menu on all versions! enters a special card clean loop when command 0xA0 [CRWCleaning] is requested. some JP games, upon game change, will block game start, saying a card cleaning must be done, and won't allow boot to continue. [had to hastily implement this when trying to play IDASv1 JP for the first time]
card migrations work! card renewals work! this required significant decoupling of magic sequences within the script to break them out more into specific CRW function calls. flows such as "CRWRegisterFont, CRWSetPrint, CRWPrintL, CRWDischargeCard, CRWTakenCardDispenser" now all work appropriately. tested all forward migrations to all versions in all regions. tested card renewals on all versions in all regions. this includes migrations with pending renewals.
it took so long for me to even write this message because this code still isn't done. life and work has gotten in the way many many times. i have a CRW implementation in progress for an ATMega-based board, to allow a small board to track all of the CRW logic, and the only thing a computer would have to do is push and receive card data to the board. there's still too much magic in the code.
i attached both the SANWA CRP DLL documentation [6806A05.pdf], along with a version i forced through google translate [6806A05_translated.pdf], to better understand what we were doing and why.
i get that this version may have diverged quite a bit from what people are trying to do personally. sorry. hope this helps.
i had video/image logged a bit of this development on my instagram, b0psaturnnights. lots of NAOMI/system 573 testing on there [along with some car stuff].