Apple II DISK Emulator using STM32

243 posts / 0 new
Last post
Offline
Last seen: 1 week 3 days ago
Joined: Apr 1 2020 - 16:46
Posts: 996
Why the RX needs a form of PLL based clock ...

In post #47, 'VIBR' wrote:

 

" I understand the use of the 74LS123 (channel B) to trigger a clock on the stm32 side. I assume that the clock will clear the 74LS393 buffer after 16us ? after that I am a bit lost. I would need a step by step to understand the way the SPI RX will be fed ... "

 

Uncle Bernie comments:

 

Sorry I can't provide step-by-step instructions for that because I don't know what the ST32 can do internally, and what needs to be done with an external circuit. But I can provide some theoretical background as to the "why" and "how to do RX = write mode":

 

Unless your ST32 has a master clock that is phase locked to the Apple II motherboard clock, which most likely is the case, as it can't be done from the 20 pin floppy cable itself, you have got what is called a "plesiochronous system":

 

https://en.wikipedia.org/wiki/Plesiochronous_system

 

This problem with such systems is that their clock frequencies, even if nominally being the same, will never be exactly the same (even if you would use two or more very accurate atomic clocks) and this inevitably means the relative phase of the different clock domains will wander and this will occasionally cause a "clock slip" or "sync slip" in which clock domain #1 has seen N clocks and clock domain #2 has seen N+1 or N-1 clocks. Unless measures are taken to handle this situation, the state machines in the two different clock domains will get out of lockstep, or out of sync, and so they won't properly "talk" to each other anymore.

 

It is not trivial to handle this situation because signals from one clock domain need to be synchronized with signals from the other clock domain, and so, occasionally, the synchronizer flipflop will get metastable and its output is unknown, neiter logic "0" nor logic "1". The number of so-called "patent solutions" to this metastability problem are legend, but none really works as claimed. All they can do is to decrease the probability of such a metastable event happening. The system must always be designed to be able to detect when things go astray and then the communication protocols must have a way to reset and recover and resume normal operation. Which for real time systems with required guaranteed response times can be a formidable design challenge.

 

Note that any floppy disk storage system has exactly this problem because the data stream coming from the read head is jittery, and not phase locked to anything. So the synchronizer flipflops WILL get metastable from time to time, the read attempt will fail, and the system will detect that and initiate another read attempt.

 

In the DISK II system, this was a reliability issue because of the low synchronizer clock frequency of 2 MHz (Q3 on the bus). It was good enough to sell, and worked reasonably OK (otherwise APPLE, the corporation, would not exist anymore) but the issue was known and Apple engineers made numerous changes to Apple's floppy disk systems over time. For instance, the IWM increased the clock frequency of the synchronizer flipflop from 2MHz to 3.5, 4, 7 or 8 Mhz, depending on the configuration of the IWM and whether it was set to SLOW or FAST mode having 4us vs. 2us bit cells.

 

For your ST32 based floppy emu, you don't have any motherboard clock available on the 20 pin floppy disk cable, so you need to derive the SPI clock in write mode (receiving the bit stream from the DISK II controller) from the WRDATA signal, which toggles for each flux change, and this is governed by the famous "Woz machine" on the DISK II card which is clocked by Q3 (actually, the inverted Q3). The crude digital phase locking technique with the counter which I proposed in the above thread cannot be avoided. Note that it won't be 100% failsafe because of the plesiochronous nature of the system and because of possible metastability of the synchronizer which in this case is the counter. To avoid metastability would require to use a clock signal from the Apple II motherboard to phase lock your ST32 master clock  to. Which you only have if you would put your floppy emu on a slot card. But I think the proposed solution with the counter can be made robust enough to be acceptable for typical users ... it's not a life support system or an autopilot for airliners.

 

Such is the nature of this kind of system design. The plesiosaur went extinct for a reason (... just joking ;-)   . . .   but the bottom line of this post is that even with a humble floppy emu we are dealing with a system design that is not trivial, and we need to avoid pitfalls which for the ignorant are inevitable.

 

So if you ST32 can generate the SPI RX clock from WRDATA all by itself, fine, just detect the WRDATA change(s) and reset the counter for each change. Use the appropriate counter output which gives you a rising edge SPI clock in the middle of a bit cell (2us after the WRDATA changes). The ability of the counter to run for four bit cells (or 16 us) would allow to handle cases where no WRDATA change occurs for 2 or more bit cells. Apple II GCR allows for no more than 2 "0" bit cells in a row but violations of this rule are possible. The problem, as I see it, and why the counter must be "longer" than a single bit cell, is the clock frequency of the Apple II (14.3181818 MHz) which, depending on the clock of your ST32, may not lead to a power of 2 for the required counter rollover. It may be necessary to add some logic to make all of that work correctly. Hence, my suggestion to use a GAL, which is flexible. If you tell me which clocks you can make on a ST32 pin, I can run some simulations to see how long the counter must be and which logic is required. Of course, if the ST32 could do some kind of digital PLL by itself to phase lock the SPI clocks to WRDATA changes, then you can do everything with proper configuration of the ST32. Not that due to the nature of the WRDATA signal, you will NOT get a change for each bit cell. So some form of phase locked SPI clock generator is required. You could do that with a real PLL (such as the CD4046) but this is analog / mixed signal design which is not well suited for your plugboard. 

 

(Disclaimer: 25 years ago I have designed CMOS ICs for plesiochronous fiber optical communications systems with clock speeds up to 3.125 GHz - data rates in the optical fiber were of course much higher - and have some patents on the special circuit solutions and sampling phase control to deal with very small "eye" openings in the communication channel. Just mentioning that I see this problem in the floppy emu as sort of child's play for bloody beginners ... not implying that 'VIBR' is one of those, as he might be a communications electronics engineer, but the problem with the plesiochronous nature of the system at hand is there and cannot be ignored. And also be assured that there is absolutely no way to make the problem go away 100% unless the ST32 clock is phase locked to the Apple II motherboard clock.... but as mentioned, this needs a signal not available on the 20 pin cable, so a robust alternate solution must be sought, and the WRDATA signal is the only way to do that.)  

 

- Uncle Bernie

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Bingo !After endless hours of

Bingo !

After endless hours of testing, adjusting, I was feeling desperate and I found my mistake (a stupid condition not executed because the prev value was not updated!!!)

It is not a big deal, but I succeed loading Apple Dos with my first woz file using a STM32F4 and I did the same with Pros Dos. 

I still need to clean up but in it self you can not imagine the pleasure to see something on the screen !

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
For the moment, I am able to

For the moment, I am able to make some of the woz file (v2.0  & 2.1) to work and not all. 

I suspect using STM32 High Abstraction Level functions, it take to much time to load data from the SDCard, 

I have written my own functions and I have pretty good result with not error when I do memory compare between the 2 approach ;)

 

Good i:13

timelapse cmd18GetDatablock 4133176 cycles

timelapse cmd18GetDatablockBareMetal 625022 cycles

Good i:14

timelapse cmd18GetDatablock 4361529 cycles

timelapse cmd18GetDatablockBareMetal 668222 cycles

Good i:15

timelapse cmd18GetDatablock 4629097 cycles

timelapse cmd18GetDatablockBareMetal 711413 cycles

I variable is the number of 512 block read, cycle is the CPU cycles number, 

In a nutshell it means that reading a full 16 block track is taking:

72 ms with the HAL function and 11 ms with the baremetal 

 

I will continue to tune it & do some testing to see if it is changing. 

I have read somewhere that head move is < 20 ms so 11ms should be fine

Using DMA I am able to pause the transfer, record the position and resume with the new DMA Buffer at the same position. 

Vincent 

 

 

 

 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
I can now read and execute

I can now read and execute some woz version 1 and version 2 

Woz version 1 is a bit painful because data stream is not aligned a 512 block addr...

I try to execute Lode Runner (woz 1)  or Zaxxon (woz 2), and it is not running.

Looking at my head moving log :

ph:35 newTrak:255, prevTrak:09, 254-255-256 01 1-1-1 48

ph:21 newTrak:08, prevTrak:06, 07-08-09 01 0-0-0 1243499

ph:09 newTrak:255, prevTrak:03, 254-255-256 01 0-0-0 1243935

ph:07 newTrak:255, prevTrak:02, 254-255-256 01 1-1-1 48

ph:01 newTrak:01, prevTrak:00, 00-01-02 01 0-0-0 1243611

ph:00 newTrak:00, prevTrak:00, 00-00-01 00 0-1-1 43

ph:04 newTrak:01, prevTrak:01, 00-01-02 01 1-1-1 45

ph:11 newTrak:02, prevTrak:02, 01-02-03 02 1-1-0 762508 

 

(ph = physical track, newTrack is the value in the TMAP, prev =prev track in the TMAP, number after are the loaded trks in the 3 adjacent buffer, 01 is the index in the track in the 3 adjacent buffer  1-1-1 is flag to determine if already in memory and  last is the processing time

Is there a specific protection schema I need to manage ? 

I can see newTrack=255 in the TMAP table, how should I manage this as a blank track ?

thanks 

Vincent 

mmphosis's picture
Offline
Last seen: 2 weeks 1 day ago
Joined: Aug 18 2005 - 16:26
Posts: 442
TMAP Chunk

TMAP Chunk

The ‘TMAP’ chunk contains a track map. This allows you to map physical drive tracks with the track data contained within the image file ‘TRKS’ chunk. This system is used because, on a 5.25 drive, the physical drive head is larger than the width of the written track and so the track is also visible from neighboring quarter tracks. For example, the data of track 1.00 is actually visible while reading from track 0.75 or 1.25. Instead of storing copies of track data for every possible quarter track, we use the map to point multiple quarter tracks to a single track image.

Track0.000.250.500.751.001.251.501.752.002.252.502.753.00
Maps0000FF010101FF020202FF0303

The data of the ‘TMAP’ chunk begins at byte 88 of the file and is 160 bytes long.

Each map entry contains an index number for the track data contained within the ‘TRKS’ chunk. If the map entry is 0, then the correct track data to be using is the first entry in the ‘TRKS’ chunk. Any blank tracks are given a value of 255 (0xFF) in the map and the emulator should be outputting random bits in this case.

The mapping changes slightly between 5.25 and 3.5 disks. This is the format for the table for the layout of a 5.25 disk. The table only shows to track 35, but can also accommodate 40 track disks. All unused map entries should have a 255 (0xFF) value.

https://applesaucefdc.com/woz/reference2/

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Thanks mmphosis, I am now

Thanks mmphosis, 

I am now sending random bit but still I can not load some games, this might be copy protection mecanism

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
 I have started working on

 

I have started working on the write data function for the Disk II Emulator:

Below is the first draft of WRDATA based on Uncle Bernie explaination.

WRDATA is inversed (74LS06) to channel 2 of the 74LS123

The 74LS123 will trigger a pulse based on WRDATA that will reset a counter (74LS393),

The counter is clock by a STM32 clock at 1Mhz (1 us) to Pin 1 CP of the Counter

Every 4 clock cycles the counter is reset (PIN 6 Q3  to PIN 2 MR ), Every 4 clock cycle SPI1 is as well clock

WRDATA is link to SPI1_MISO to gather input.

I used a schotty diode to avoid WRDATA to clock the SPI when resetting the counter 

Do I get it right ? 

Quote: 

"Size the counter such that it can count at that clock for at least 4 bit cells (16 us) before it rolls over" => this is not clear for me as I reset the counter every 4 cycles to trigger the SPI clk

 

thanks for your feedback

Vincent

 

 

 

Offline
Last seen: 1 week 3 days ago
Joined: Apr 1 2020 - 16:46
Posts: 996
WRDATA to SPI clock recovery circuit

In post #58, 'VIBR' wrote:

 

WRDATA is inversed (74LS06) to channel 2 of the 74LS123

The 74LS123 will trigger a pulse based on WRDATA that will reset a counter (74LS393),

The counter is clock by a STM32 clock at 1Mhz (1 us) to Pin 1 CP of the Counter

Every 4 clock cycles the counter is reset (PIN 6 Q3  to PIN 2 MR ), Every 4 clock cycle SPI1 is as well clock

WRDATA is link to SPI1_MISO to gather input.

I used a schotty diode to avoid WRDATA to clock the SPI when resetting the counter 

Do I get it right ?

 

Uncle Bernie comments:

 

Almost right, with a few bugs and a few weaknesses.

 

1. The 74LS06 has an open collector output and would need a pullup resistor for a good 'H' signal.

2. It would be better to use a Schmitt trigger in lieu of the 74LS06, because the cable may cause poor signal integrity. The "B" inputs of the 74LS123 are Schmitt Trigger inputs. Positive edge triggered, but this is OK, as the WRDATA signal toggles for each "1" bit sent to the disk. You may connect WRDATA directly to "B".

3. Counter clock of 1 MHz seems fast enough (faster, such as 2, 4, 8 Mhz would be better to get a more accurate "hit" of the bit cell center) but the nature of this plesiochronous system must be studied to see if clock slips can happen.

4. Do not reset the counter with itself, let it just roll over 11111111->00000000, which will only happen if there are no WRDATA changes for a longer time, which means that the write mode is off anyways (do not use this clock source for read mode)

5. A bit cell is 4us wide, so for reaching the middle of the bit cell, two 1 Mhz clocks are needed. Here is how the counter would react:

 

0000 Reset state (WRDATA rising edge causing a short (i.e. 50ns) aysnchronous reset pulse of counter.

0001 1us later

0010 2 us later (half bit cell)

0011 3 us later

0100 4 us later (end bit cell, start new bit cell)

0101 5 us later

0110 6 us later (half bit cell)

0111 7 us later

 

So you would use the rising edge of Q1 (the 2nd bit) to clock your SPI.

 

The 1N4148 protection diode on the 74LS123 is not needed, as advertised in the datasheet. Earlier oneshots needed it only for larger capacitors. You should also check your timing components to have more realistic values. Look at Figure 4 of the 74LS123 datasheet which can be downloaded from the TI website. You do not want a reset pulse which is too wide, aim for something below 500ns, and more than what the 74LS393 needs as a minimum clear pulse width.  Try 47pF and 10 kOhm (from the chart). The C should be large enough to swamp the parasitics on the Cext pins and traces (keep them as short as possible, plugboard NOT recommended, but if you insist to use it, you could lift the pins by bending them and solder the 47pF to them) and the R should be larger than 5 kOhm. You should get something around 250ns pulse width from that, but be aware that the chart in the datasheet is for "typical" silicon, and your results may vary. Do not try to use smaller capacitors. Instead, change the resistor to get your target pulse width.

 

The Apple II Q3 clock is 14.31818 MHz / 7 = 2.04 MHz, so the bit cells will come in faster than your 1 Mhz clock advances the counter. Each bit cell is 8 Q3 clocks, or 3.91 us wide. The error per bit cell is 89ns, so after 4 bit cells with no WRDATA rising edge (which should never happen in normal DISK II operation outside of writing copyprotection trickery) the accumulated error is 355ns, and so the SPI clock will still be only off from bit cell center by this amount, which is harmless.

 

Keep in mind that this system only captures the WRDATA stream and you need to detect the bit changes (compared to the previous bit) to arrive at the bit cells with a "1" in them. If you can do that in software, fine. Doing it in hardware would be easier for the software, but would cost more ICs.

 

- Uncle Bernie

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Thanks Uncle Bernie, I will

Thanks Uncle Bernie, 

I will update the schema to make sure I get it right.

- Ok for the open collector, 

- Ok for the 74LS123 RC Value

- Ok for the B Channel

- I will use a 74LS14 in lieu of 74LS06

 

Write Quick questions:

- why not using a 2Mhz pulse for better accuracy and to clock the counter and to have the SPI linked to QC instead (Counting to 4 instead) ? 

- track the change would mean using a XOR between the RDDATA & WRDATA like the 74LS86 ?

- I will need to use a 3rd SPI interface (1 for SDCard, 1 for RDDATA TX 250 kHz as Master, 1 for WRDATA as slave):

   - when in write mode, I will get a full track with only change ?

   - in that case it would be a 13 block of 512 Byte (6656 aligned with the RDData size for woz)

   - What is the best software setup & procedure  to test the write process ? any recommandations ?

 

 Read Questions:

- I have imporved the way to manage track change, 255 woz track with white noise, I can pause and resume DMA SPI keep the byte index position, and ... but still I can not read all woz images (I guess due to copy protection). 

 

- Is there test images with unit copy protection tests to check if the emulator is passing successfully each test ?

 

Thanks 

Vincent

 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
I think I found a way to

I think I found a way to adjust the output bitstream frequency to address 1 type of copy protection. 

Normally bitstream period is 4us, which means on a 200ms revolution : 50 000 Bits, but some protection use up to 52000 Bits, between 3.8 & 3.9 period. 

SPI is master mode is aligned to CPU Frequency and divided by a prescaler. 

I use so far 64 MHz with a prescaler of 256 => 4us data stream (with outside circuitery to manage 1us pulse inside 4us).

In Master SPI mode there is no way to adjust the period which a fine granularity. 

 

The way to do it (I need to do some testing) would be : 

- Using SPI in slave mode (meaning the clock of the SPI is external)

- Using a timer on the STM32 (there are 10 configurable timers :) ) to generate a PWN to a pin

- Wiring the timer pin  to et SPI CLK pin and have NSS manage the same way. 

This way I am able to define timer with a very fine granularity. 

 

Regarding the copy protection : I found a very good reading copy protection

to be continued 

Vincent 

 

Offline
Last seen: 1 week 3 days ago
Joined: Apr 1 2020 - 16:46
Posts: 996
Just a few quick answers / comments:

- no need to add a 74LS14 if you use the B input of the 74123. Which already IS a Schmitt Trigger input.

- 2 MHz clock and use of the next higher Q output of the counter indeed would make the whole system more robust

- to detect a signal change on WRDATA with external logic, you need a flipflop to capture the "old" state of WRDATA and then a XNOR gate to compare that old state with the current WRDATA. You can use a XOR an the /Q of the flipflop to the same effect. Clock the flipflop with the inverted SPI clock coming from the counter  (such that the output of the XOR = SPI input does not change in the vicinity of the active SPI clock edge). You may need a second flipflop after the XOR ... with the same clock, to prevent WRDATA changes spitting into the soup. Once you have built the hardware, you will see what is needed and what not.

 

For tracing writes, you need another track buffer which is for this "write" SPI channel. You will need some gating of the SPI input signal with WRREQ to receive only '0' bytes when nothing is written. WRDATA will toggle erratically even if WRREQ is off. Where it gets tricky is when WRREQ is turned off. You need to hurry and copy the written bytes to the "real" track buffer at the correct positions of that track. Again, the always running timer which corresponds to the revolving floppy disk is your friend here, to determine where the write was started and where it stopped (interrupt or timer capture by WRREQ changes ?).

 

What happens during writes is that the RWTS software looks for the correct sector header which it reads from the "read" track. Once the correct header is found, it will turn on the WRREQ and write the sector data including a leader and a trailer. You do not need to worry about deciphering any of that, it's just a bit cell stream like any other. But for testing purposes, you may put some backdoor into your ST32 code to be able to access the write track buffer ... and this debugging ability is why I recommend a separate write track buffer. Theoretically, you could watch WRREQ and then reconfigure peripherals in the ST32 to write directly into the read track buffer at the right place. But if anything goes wrong with this, your read track buffer contents may get ruined and the sector headers may be gone, and everything falls apart. Hence, keep it simple. Have  a separate write track buffer with its own DMA channel.

 

Note that none of the known copyprotections using "fat tracks" or "spiral tracks" ever writes into these special  tracks, and only these need more track buffers to be kept in memory at the same time. For normal read / write operations, you just need two track buffers, one for reading, one for writing, and once you have debugged the writing process, you might be able to combine them into one track buffer. But even I would not dare to try to pull this feat off before the process works with the two buffers. There are just too many plates spinning (nice metaphor for floppy emulator work ...), too many moving parts, so the "divide and conquer" approach is probably the better one.

 

For the testing of copy protections I can't give any specific advice. In the end it boils down to finding WOZ files, and then testing, testing, testing ... the BMOW Floppy Emu IMHO is the most mature product of this type out there, and certainly worth its money (I wonder how Steve can do that at this low price). But at least for my own mission (integrating a floppy emu into the Replica IIe project) his floppy emu is too elaborate and too powerful, and hence, too expensive to put into my planned kits. It's just a BOM problem. More parts cost more money to buy and to install. On-motherboard floppy emus could avoid a lot of these parts, i.e. the little display could be gone, and all the buttons, and could be replaced with some built-in software running on the 6502. You could start this from the keyboard and then choose a set of disks you want to emulate from a menu provided by the ST32. The display would be the normal Apple II screen. For a given game, there will be a number of disks and sides (1A, 1B, 2, ...) and these could be displayed on a single digit 7-segment display and two LEDs for the side (A or B). The keyboard would "talk" to the ST32 and allow to choose which of them. If you want to change to another game, you neeed to reboot the Apple II anyways. I think such simplifications could bring number of hardware components and costs down. But these simplifications of course are not possible with any stand-alone floppy emu like the BMOW one. It must have the display, the buttons, the acrylic case, the flat band cable, and all these components cost money and drive costs. Frankly, I don't think you can make a lower cost stand alone floppy emu than the BMOW. But when a floppy emu gets integrated on a Replica 2e motherboard, your ST32 based version sure can save some components and some costs. This ST32 could also handle the keyboard and mouse interface conversion (to be able to use industry standard PS/2 keyboards and mice, and maybe USB ones, too). At the moment I'm only 'dreaming' about synergistic effects but I will watch your project for progress !

 

Good luck !

 

- Uncle Bernie

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Actually I am also working on

Actually I am also working on a project to use a STM32 as keyboard and mouse for the Apple II with either a USB / PS2 devices (a prototype is already woring with a ATMEGA328P & CH555 usb interface). Porting this to STM32 is almost done. but I am quite sure we can have a single chip to do disk, keyboard and mouse

 

Regarding the WRDATA, I will try to draw a schema to make sure I get it right 

Vincent 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
This is the draft of drawing

This is the draft of drawing incuding the write part

- SPI1 is in Slave Mode Transmit Only, (RDDATA output)

- SPI1 Clock is manage by a timer TIM3 (256 Clock period, 128 Pulse period)

- SPI3 is in Slave Mode Receive Only (NEW_WRDATA)

- TIM4 is 2 MHz PWN connected to counter (half self is on QC(2) counting to 4)

- /TIM3 is the inverted TIM3 on the output of the 74LS06

- 1 flipflop getting the WRDATA signal, 

- XOR 74LS86 with result of the flipflop & WRDATA

- the 2nd flip flop on the output of XOR

- Flip Flop 1, Xor, Flip Flop 2 connected to /TIM3

- Output of Flipflop 2 (NEW_WRDATA) to SPI3_MOSI  

 

Note: I use a timer on SPI to be able to adjust the bitrate of the SPI (instead of a PRESCALER)

 

What do you think ?

 

What I do not get, is why do I need to use the previous version of WRDATA ? why not using RDDATA to compare ?

Can you please help me to understand more the WR process, I am missing something.

 

Vincent

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
The project code is hosted on

The project code is hosted on github here :

https://github.com/vibr77/AppleIISDiskII_stm32f401/

Offline
Last seen: 1 week 3 days ago
Joined: Apr 1 2020 - 16:46
Posts: 996
Some suggestions on th schematic in post #64

Hi Vincent -

 

to answer your questions in your post #64:

 

1. Get the timing RC of U2A right. Datasheet demands R >= 5kOhm. Suggest to start with 10 kOhm / 330pF and then adjust R for desired pulse width.

 

2. Remove 1N4148 diodes at the oneshots. These are NOT needed for the 74123. The 74121 and 122 need them but only for larger capacitors having much charge inside.

 

3. Check timing requirements for the CLR input of the 1st oneshot (U2A). I can't tell because I don't know how TIM3 works.

 

4. The write protect pulldown is too weak. You may ground that signal to turn write protect off. But I think it might be worthwhile to dedicate an output of the ST32 to drive it. This allows choice of write protect from the emulator or the WOZ file. I don't know if the following foul "copy protection" method I saw on the Atari maybe 42+ years ago ever was used on the Apple:

in this protection, the original disk had no notches so it was write protected. But a copy, since it was written by the "software pirate" had to have a notch to allow writing. The "copy protection" would detect the absence of the write protect after booting it, and clandestinely wrote trash to a sector needed later in the game. The "software pirate" of course would see the early stages of the game running fine and declare victory and send the copies out to his pirate friends. (Ouch). I would call this a "poison pill copy protection". One of the very simple ways to protect a floppy disk without any copy protection formatting. Once the "scene" learned about this, added manual write protect turn on / turn off switches were put in. The most elaborate ones hat three positions, PROTECT, NORMAL, UNPROTECT. The middle one would take the signal from the write protect sensor, and the other two would override it. The same mechanism could be put into your floppy emu.

 

5. Suggested WR channel circuit here:

 

 

Note that I changed it a little bit over your circuit and my previous suggestion. Now, both D-FFs are clocked by the mid-bitcell clock Q2 made by the 74393, and the EOR output will go '1' for each change on WRDATA detected. This information is held in the 2nd D-FF until the next bit cell clock. Consequentially, the SPI now must be clocked by the inverted Q2 (or programmed to grab the data on SPI data input at a negative edge, if that is possible). This clocking scheme avoids issues with SPI setup and hold time violations. I've also added a function where WRREQ will keep the SPI input "0", if WRREQ is deasserted ("H", it is actually active "L", to enable write, but Apple's schematics often have no inversion bar over the signal name). You also need to use WRREQ based interrupts to handle the write operation turn on and turn off, but this little CLR circuit is faster and will turn all 'trailer' bit cells after WRREQ deassertion to zero bits in the write track buffer.

 

I did not simulate or test this circuit, so no guarantees of any kind given or implied. But I think it should work OK.

 

Depending on which clock(s) you can generate with the ST32, all the logic could be put into a single small PLD, such as a 16R6 or so. This would do away with the nasty oneshots and make your floppy emu not only cheaper to own, but also more bulletproof to build one without having an oscilloscope to check the oneshots. Can you make a ~2 MHz clock ?

 

You also may have noticed that some copy protections require different bit cell densities. It may be worthwhile to check if the SPI clocks in the ST32 can be programmed to such a fine resolution. But this is not mandatory. The effect of different bit cell densities can also be faked in the WOZ file by manipulating the bit sequence. This is because the DISK II controller's "Woz Machine" always samples the RDDATA stream at the Q3 clock frequency and it has no PLL.  So knowing what the "Woz Machine" does could be used to get the same effects  (seen by the copyprotection check) as if there were a "density frequency modulation" on the floppy disk itself. But this is my conjecture ... I don't know what the various existing floppy disk emulators do. All I know - and only from the "Tome" book - is that some Apple II copy protections use different bit cell densities and the check counts the CPU cycles needed to read certain portions of the track. I do not have any such original disk in my collection to verify any of that. But from knowing how the RDDATA stream gets sampled at a fixed frequency, a bit stream at another frequency can be constructed which has the same effect (back to "plesiochronous systems"). There will be a clock slip effect from time to time. The question is how the copyprotection nit-picks about the details it "sees". The real floppy disk will have a slight timing jitter for the clock slip event to happen, and this could be used to construct 'instable' bits which sometimes register as a "0" and sometimes as a "1". I don't know if they exploited that and how the WOZ file would handle that properly. This is for the "Apple II copyprotection experts" on the lofty "Applesauce" level or higher ranks. And I don't belong there ... different type of expertise. I just wanted to alert you that these things / tricks may or may not exist.

 

Tell us about your progress with the write process !

 

- Uncle Bernie

 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Hello Uncle Bernie, I am

Hello Uncle Bernie, 

I am making some good progress: 

- I can generate a pretty stable PWM at 2Mhz or even 4Mhz, (TIM4)

- As well I can change the SPI output frequency (RDData) based on the woz file (32 * 0.125ns) 

I am now testing the Write process: 

I am struggling because the WR_REQ which is active low is never High ... 

I can see the WR DATA bit stream.

WR_REQ is sent from the Controller to the disk emulator ? I have even put a 10K pup resistor ? 

I must miss something ? Any suggestion ? 

 

 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
I did more investigation I

I did more investigation 

I clamp the 74LS05 pin 04 on the Disk controller card to understand what is happening. 

When I use the original Disk II, and I init (format) a disk I can see fluctuation of WR_REQ. It means at least the card is working well. 

 

When I do the same with the emulator: I can see reading of track between 0 & 1, nothing on WR_REQ (same clamping) and I received a I/O Error...

 

I would need some help to understand the reason why. 

 

Thanks 

Vincent 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
More informationthis is the

More information

this is the card clamped to the logic analyzer

The card in the Apple II 

This is the Logic analyzer trace for disk init process 

The detailed view on a write process 

This is the Salae Logic analyzer row data if someone would need it Package iconDISKII_Init_dsk_trace_full.sal_.zip

Let's continue the journey, 

Vincent 

 

 

 

 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Using the same clamping to

Using the same clamping to get the trace on the emulator

so I try to init a disk and I received an I/O Error without WR_REQ, see below the trace 

The Detailed trace :

I need some help to understand the data process flow :

- What is the sequence of WR_REQ Data pulse, when it starts, when it ends

- WRDATA & RDDATA

 

I am a bit lost with the write process

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
This is the capture at

This is the capture at different point of the write circuit: 

LS74_9_Q_NewData is never showing any data as the WR_REQ is never low...

I am stucked

 

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
Check if your DISK II

Check if your DISK II controller is still oprational for writing with a physical DISK II drive with a diskette inside. Check that this setup is still operational when you add your "emulator" to the DRIVE 2 connector of the controller card.

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Hello Retro_devices, I have

Hello Retro_devices, 

I have tested see above with the original DISK II and I can see a WR_REQ signal but not on my emulator. 

I will recable the prototype as it become a bit messy. it must be a short somewhere 

Vincent 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
I have rewire everything

I have rewire everything clean

when I do on the Apple II "init diskname" I received a I/O Error and no WR_REQ Falling / Rising ....

When I use the DISK II I receive WR_REQ !!! this is crazy #1@#ARG!!! ;)

I do not understand

 

 

 

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
Still you haven't done the

Still you haven't done the tests I proposed. 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Well sorry, It is working

Well sorry, 

It is working with a classic DISK II with a floppy inside => I can init a disk 

It is working with a class DISK II with a floppy inside and the emulator connected to drive B

It is not working with a classic DISK II and a floppy and the emulator on drive B issueing INIT DRIVET,D2

 

 

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
I remember of an old simple

I remember of an old simple emualtor based on Atmel that explicitly did not support "diskette" formatting. But writing on a formatted "diskette" was working with it. You can try to see how Locksmith 6.0 Fast backup tries to write to your "emulator".  I am inlcined to think that a very short WRREQ single attempt is made which is not within the logging scope of your logical analyzer. This attempt is sufficient to dislike your "emulator" and signal an I/O ERROR.

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Thanks Retro_devices, I found

Thanks Retro_devices, I found the error using Locksmith, the I/O Error is for write protected error

It was the WR_PROTECT that was wrong floating between +5/GND. 

I change the WR_PROCTECT switch and adding a dedicated pin with the LS125 

and now I receive WR_REQUEST which is very very good, now serious things starts. 

The corrected schema

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
This is the output from the

This is the output from the Logic Analyzer based on the above schema:

more zoom: 

The good news:

- I have a good spi clock to receive data

- I have a good WR_REQ signal that put LS74_CLR2 to low 

- I receive WRDATA with LS74_12_D (input of the 2nd D Flipflop)

The bad news:

The new WRRDATA encephalogram is flat except few spark !

EDIT 1: 

If I change LS74_13_CLEAR2 from /WR_REQ to WR_REQ (not inverse directly from counter out) this is what I have 

more zoom 

this is the table of Truth of the LS74

 

Here I do not get why I do not have NEWDATA Low when the LS74_CLK2 is L, LS74_12_D is L, and LS74_CLR2 is H

 

The software piece is getting there as I can received data chunk, isolate the data chunk and copy at the right place to the RDDATA Buffer and send a SDCard write request ! 

The only thing that left is the right WRDATA and 

 

Uncle Bernie, I need a bit of  your Magic please here ;)

 

 

Vincent

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
You cannot expect any newdata

You cannot expect any newdata when " LS74_CLK2 is L". Only on the rising edge of the clock pulse (e.g. for the shortest moment when the clock signal changes from 0 to 1) the '74 memorizes the logical state of its D input. During the rest of the time (e.g. the majority of time) it is idle and simply ignores all changes that happen on the D pin.

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Ok, If you look at moment A &

Ok, 

If you look at moment A & moment B 

On both moment, CLK2 is rising (positive edge), D is LOW and CLR is HIGH

It should gives NEWDATA to low according to the table of truth ? do I miss something ? 

Vincent 

 

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
Either for some setup reason

Either for some setup reason your logic analyzer is not showing/missing short pulses/glitches, or the wiring is bad, or the 74LS74 is defective, or you have unintentionally connected the logic analyzer to different signals. But your clock must be dependent on the WRDATA as far as I understood but instead the clock is absolutely regular?..

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Well what you see is with

Well what you see is with logic Analyzer directly connected to the LS74 pin 

Vincent 

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
I was writing about all

I was writing about all signals, not only one. Looking at your breadboard setup one can never be sure for connections. I advise you to use soldering instead.

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
I have soldered direcly to

I have soldered direcly to the IC and it makes no difference, the issue is somewhere else...

Vincent

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
While continuing to

While continuing to investigate the WRDATA issue, 

I am implementing the Buffer management for the WRITE DATA,

so I have 2 buffer DMA_BIT_TX_BUFFER (RDDATA of the current track) and DMA_BIT_RX_BUFFER (WRDATA of the current track)

TX index is the current position of the DMA_BIT_TX_BUFFER, RX is for the other one 

Here is the log gathering the Write Data bufffer while erasing the disk with LockSmith:

 

WR_REQ Starts 0 Tx indx:5708

ph:68 newTrak:17, prevTrak:14, 16-17-18 1 1-0-1 d1:830999 d2:1766984WR_REQ Ends RX:0 TX Indx:2017

ph:72 newTrak:18, prevTrak:17, 17-18-19 2 1-1-1 d1:33589 d2:935530

WR_REQ Starts 0 Tx indx:506

WR_REQ Ends RX:6527 TX Indx:3343

ph:76 newTrak:19, prevTrak:18, 18-18-20 0 1-1-1 d1:33664 d2:1726102WR_REQ Starts 6527 Tx indx:1833

WR_REQ Ends RX:6526 TX Indx:4670

ph:80 newTrak:20, prevTrak:19, 19-20-21 1 1-1-1 d1:33520 d2:1733188

WR_REQ Starts 6526 Tx indx:3161

WR_REQ Ends RX:6527 TX Indx:5998

 

The good news if that the RX index is 6527 (the size if 6527+1 => 16*408 => 402 NIBBLE + 6 trailling FF signature)

What I do not understand is that it does not start writing at the begining of the TX track buffer (tx index is volatile)

 

Does it means that it does not care as it is a full track ? 

 

Is it always a full track when writing changes ?

 

Any clue about this ? 

Vincent 

 

 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Well after some further

Well after some further digging, I was too quick and things are not Matching Numbers...

When I look at the Logic Analyzer, I have on the clock side 12204 rising edge, on the buffer dump 654 Bytes, and on the counter 6226 which make no sense.

I need to further understand what is happening on the software side !

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
after some investigations:

after some investigations: 

Unclie bernie was right on the 74LS_13 WR_REQ signal that should be inverted, I was miss reading the logic analyzer. 

What I considered as write zone was read, and the way around. 

And it explain why I have a buffer of 66XX Bytes length coming to the SPI.

Erasing the floppy seems to be aligned with the WRDATA (00) on this picture 

I need to check if it is always the case...

to be continued

 

Edit 1: 

this is the output NEW_DATA when copying a disk (note I change the WR_REQ signal back to uncle bernie recommandation on this trace => WR_REQ is inverted)

More zoom :

 

It seems not too bad at all, but I need the eye of the expert :)

Quick question for uncle bernie:

- the RDDATA is a circular buffer send endlessy to the SPI output the size of the buffer is 13*512 = 6656 Bytes.

- Thus the index (position of the current bytes send in the spi) can varie from 0-6655

A1/ When the write process start, WR_REQ gets LOW, I assume I have to save the RDDATA index, and the same at the end of the write process WR_REQ gets High ? 

A2/ I record the WRDATA from the incoming SPI when WR_REQ gets LOW and I stop when WR_REQ gets High ?

B/ I copy the WRDATA to the RDDATA at the begining of the index (A/). ? 

If space left from the index is not enough I copy the remaining part at the begining of the buffer. 

C/ I copy the track to the SDCard ? 

 

Is this correct ? 

 

Other querstions: 

The role of the LS123_5_Q to reset the LS393, is because it is not automatically auto rolling to 0 after 15 steps ? 

Why using one of the remaining input of the LS125 to filter WRDATA only when WR_REQ is getting LOW ?  WDYT.?

 

 

thanks 

Vincent 

 

 

 

 

 

 

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
VIBR wrote:The role of the
VIBR wrote:

The role of the LS123_5_Q to reset the LS393, is because it is not automatically auto rolling to 0 after 15 steps ? 

No. 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Sorry is to get the pulse in

Sorry is to get the pulse in the middle of the WRDATA ?

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Last version of the Schema

Last version of the Schema with LS125 on WRDATA

Offline
Last seen: 1 week 3 days ago
Joined: Apr 1 2020 - 16:46
Posts: 996
Uncle Bernie's comments on the above posts #67, #88, and #91

Hi Vincent -

 

to answer your question in your post #67, here are my comments based on the schematic there. The thread now has progressed to 91 posts, so I'm late, but I will also inspect your schematic in post #91 in due time. Here my hints for the schematic in post #67:

 

C1 should be pF, not nF

 

Use 74LS14 in lieu of 74LS06, as you want Schmitt Triggers to condition all the signals coming from the flat band cable. This also saves the pullup resistors.

 

The WRDATA to the 74LS74 change detector should come from a Schmitt Trigger, too. Polarity does not matter, as it's a change detector.

 

Also, avoid high resistance pull down or pull ups (some in your schematic have 100k). Instead, size their resistance such that they can make good TTL "L" or "H" levels for any expected LSTTL load in these nodes. This may look as an superflous effort, but why not ... if you put resistors in at all, why not maximize their usefulness. You never what you or other people later want to wire to these nodes.

 

Don't use the 10k series resistors on switches. Instead, use pullup resistors such that the switch grounds them and has to draw current (some single digit mA) to establish a "L" level. This allows for easy detection of failing switches whose contacts got too high ohmic due to corrosion, wear and tear, especially if you could measure the logic level with an ADC. For some types of switch contacts, having a few mA of "working current" may also be beneficial to maximize their life time.

 

One word of caution on 5V tolerance: I've downloaded the ST32 datasheet but so far had no time to digest it. You need to exercise some care about the alleged "5V" tolerance they promise for the ST32 I/O ports on the front page of the datasheet. The key question to be answered is whether this 5V tolerance also exists when the ST32 has no power supply voltages, or insufficient power supply voltages to make the inner circuitry work as expected.

I know, I know, as an IC designer, that 5V tolerance under all conditions is possible with some process technologies, and very careful and competent circuit and layout design, but I've blown up enough CMOS ICs whose manufacturers made bold claims as to their latch-up robustness: for instance, Lattice claimed for their first mid Y1980's GAL16V8 that they would "not latch up under any condition". This bold claim disappeared from later data books. And I had to redesign one of my products whose GALs blew up all too often in the field. The issue was that their substrate charge pump which was meant to accomplish this robustness needed a power supply to work its "magic", and of course hot-socketing of the PCB could blow those GALs up before the charge pump had pumped the substrate down. Much the same mayhem could be wrought with the first CMOS based DRAMs. All of which used substrate charge pumps to avoid the negative power supply pins. One negative voltage spike on any of their pins caused by transmission line effects (reflections) during or shortly after power up (before the charge pumps could complete their job) could blow these ICs up. And of course the power supplies of these DRAM banks were powerful enough to make them smoke, once the latched-up condition was established. The bottom line is that all claims from any manufacturerer as to the robustness of their ICs must be put under scrutiny. But ST had gained a stellar reputation for the toughness of their ST62 MCU family. If they did not lose the know-how, the ST32 may also be tough and hard to kill. Still, with the specific dangers lurking on the 20-pin flat band cable when connected to a DISK II controller card, we should probably add some protection circuits to avoid blowing up the floppy emu when the cable is inserted turned 180 degrees. I can help you with that, if you want.

 

Comments on the new schematic of post #91:

 

After a short glimpse on your schematic in post #91, I don't think the LS125 to gate off the WRDATA signal is a good idea. The LS125 does not have Schmitt Trigger inputs, so it's not smart to use it for conditioning signals coming from a long flat band cable.

 

WR_REQ deassertion clearing the 2nd D-FF in the 74LS74 is enough to keep its output low during that time (SPI will receive all '0' bytes, but the SPI clock still will run, otherwise the last byte in the pipeline before WR_REQ deassertion (ending the write) may get stuck in the SPI machinery. But I'd think you want to capture this byte, too. It's typically a trailer byte of 0xFF the RWTS sends to the floppy drive just before turning off the WR_REQ.

 

To handle the start and stop of the write process properly, you need an interrupt on change of WR_REQ anyways, and you need to be able to discern if the WR_REQ was asserted (active low !) or deasserted, to start or stop the write process. The reason why I suggested the 'forever running' write receiving process is that this gives you plenty of time to deal with write process start and stop without ever losing any bytes sent by the DISK II controller. The write buffer can't be made smaller anyways, because you need to be able to capture a whole track during the formatting process. Only for writing regular sectors, you could use a smaller write track buffer and start / stop DMA based on WR_REQ. But when you turn off the SPI clock (and the rest of the write channel circuitry) then you are guaranteed to lose a few bytes in the beginning of any write. Typically, these are gaps involving SYNC bytes (1111111100 1111111100 ...) so you could make a guess on what you have lost, and replace them, but why if you can just keep the machinery running all the time ? It's a needless complication, IMHO. The machinery I proposed will write always into the write track buffer, even when the WR_REQ is deasserted, and the system is reading, but it will only write bytes of all zeros (0x00) as long as WR_REQ is deasserted, and this can help your software to find out what was written where.

 

This leads to the questions in your post #88:

 

It is correct that you keep the RDDATA generating process from the 'read track buffer' and the read index timer runnig all the time, including the wraparound to the begin of the track buffer when one revolution is complete. A timer interrupt could do this BEFORE the pipeline runs dry, as even a blazing fast ST32 will need some time to process the interrupt and to restart the DMA at exactly the currect point in time, without losing any byte, and without adding any byte. This would be the ideal case, a seamless rotation of the same track forever, like in the real floppy disk drive. But IMHO the timing in the software may get tricky unless you have a hardware FIFO between the DMA channel and the SPI peripheral.

 

Here are your questions and my comments:

 

A1/ When the write process start, WR_REQ gets LOW, I assume I have to save the RDDATA index, and the same at the end of the write process WR_REQ gets High ?

 

You can do this, as you have the interrupt reacting to the WR_REQ changes. You could also record the state of the DMA channel into the write track buffer at that time. This information will help to look for the exact positions in the write track buffer where the WR_REQ actually started and stopped. You certainly have some latency in the interrupt process so you need to go "looking" for the all zero bytes before and after the actually written bytes which were moved into the buffer automatically (by SPI and DMA). What I think you can get from the typical peripherals is an approximate position and the fine positioning must be done by looking at the bytes being all zeros (WR REQ was off, or the place never was written) or non zero bytes (something was written there). 

 

A2/ I record the WRDATA from the incoming SPI when WR_REQ gets LOW and I stop when WR_REQ gets High ?

 

Actually, as discussed above, your WR_REQ interrupt process most likely would be too slow to capture the whole story. So it's better to keep the machinery running all the time.

 

B/ I copy the WRDATA to the RDDATA at the begining of the index (A/). ?

 

No. At least after each WR_REQ deassertion, you need to look for what was written into the write track buffer, and then copy the non-zero bytes there into the right positions of the read track buffer (which is the actual image of the emulated track). This must happen fast enough such that when the RWTS starts to look for what it just wrote, that the data must be updated and ready. Even for a ST32 this may be too much to handle in the time available. So I would recommend that after WR_REQ has been asserted, start copying the information from the write track buffer into the read track buffer, which can be done with a background process. Do not forget to set the position of any non-zero byte you took out from the write buffer in this copy process to zero, so mark it as "taken / fresh / empty space". I think this process will work fine with plenty of time for regular sector writes. But for a full track formatting process it still might be too slow, I can't say, as I don't write the software. So you might detect a track formatting process and then just flip the read and write buffers once the WR_REQ is deasserted. You still need to clear the new write buffer to all zeros before the next write happens.

 

If space left from the index is not enough I copy the remaining part at the begining of the buffer.

 

If you can't close the 'ring' by manipulating DMA in due time, to restart at the begin of the write buffer upon completion of a revolution, you need to allow the DMA to overshoot the buffer end a little bit (have enough spare bytes there) and you restart the DMA past the begin of the buffer. While the write process commences there automatically (by SPI/DMA interaction) your software can figure out how to 'heal' the wraparound splice by copying appropriate bytes from the overrun area to the beginning of the buffer. Let me emphasize again that you can't lose or add even one byte in the process, except for all zero bytes, which indicate that at this part of the track buffer, WR_REQ was deasserted and write was turned off. Oh, and forget about notions of "index". The Apple II disk system has no index hole sensor, so there is no "index". The tracks can start and stop anywhere. But some copy protections check for the relative angle between tracks, so this must be accounted for.

 

C/ I copy the track to the SDCard ?

 

Once a track has been written to, mark it as 'dirty'. Only when the head moves away from that track, initiate the flush to SD card process for that dirty track (you now can see why having a pool of track buffers is helpful, if you have them, you can allocate and deallocate track buffers very quickly. Having a lot of RAM is your friend...)

 

So far my comments / suggestions. Hope they get you back on the right track (no pun intended ;-)

 

You are making good progress.

 

- Uncle Bernie

 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Thanks Uncle, You were right,

Thanks Uncle, 

You were right, it is a real journey but it is fun to learn something new and thank you for your support. this is the first project I do with a STM32 and I have to say that I am blown away by this small SOC capability compared to the old AVR (ATMEGA). 

Regarding the schematic: 

- Small mistake it is in fact pF and not nF, but the value is right to get 1.250 uS data pulse,

- I have some 74LS14, will use it  in lieu of 74LS06 and remove th pup resistor,

- Ok for the 100k,

- for the 10k what would be your recommendation ? 

- Regarding the LS125 with the WR_REQ, this is done this way in the orginal analogic card on the DISKII, but ok I will remove it 

- Based on the below and above, no need to have SPI3_NSS because of circular endless flow

New Schema: 

R13 is not needed anymore, I guess...

 

 

Regarding 5V tolerant GPIO and the STM32. I started the project with the so called Blue pill (STM32F01) with has a CORTEX M0+ (72 Mhz) and 20K of SRAM. Using the bluepill, one needs to be extra careful because all GPIO are not 5V tolerant, this is well hidden in the 400^2 pages reference document. 

Due to memory needs for this project (approx 6 K for the RDDATA SPI Buffer, 3*6K for prebuffering 3 adjacents track for rapid swap, 6K for WRDATA, 1K of prog varaible) approx 35 Kbytes, the blue pill is not the best one. Of course, playing with the DMA and partial tracks and some complexitiy to load & unload partial track we can have something below 20K but at a cost of debugging time. It is already complex enough to avoid additionnal complexity. By the way, reading the TOME book, I am not even sure managing partial track in the DMA works with some spiral protection because the loading time of the next partial track will not help. Long story short, I needed to find an alternative and I found the so called black pilled that is also a little beauty (84 Mhz) & 64 Kb for the STM32F401 with a cortex M4 and there is also the STM32F411 with pretty much the same M4 running at 100 Mhz and 100 Kb of memory. Both share the same pinout. (it is not the same pinout between the blue pill and the black pill PB11 does not exist on the black pill as an exemple). The good news is that all GPIO are 5V tolerant on the black pills which makes my life easier. 

If you look at the reference documentation on the STM32F1/2/3/4, you wil find the description of the DMA. 

The DMA can be Memory to Memory or Peripheral to Memory, but the interesting thing is the mode : Normal vs Circular. Using the normal mode, at the end of the DMA flow (end of the given size when started), you have to retrigger the DMA which cost a few cycles (16 from my experience);  But in Circular mode, the DMA is endless with a loop at the end to the begining without loosing any CPU cycle; this is fully transparent and on top we can have half buffer interrupt and complete interrupt every circular cycle. 

the other good thing is that we can Pause the DMA and resume the DMA at the Pause index, in between changing the DMA data (which is what I do when changing the track).

 

Based on what I just wrote and your message above, it would make sense to:

- Use a circular buffer for NEW_WRDATA on SPI3, capturing the endless flow of what is coming from the circuitery (either 0 when WR_REQ is HIGH and real data when WR_REQ is LOW). Doing so I am not missing any data due the potential gap between the interrupt and the real start of the WR_DATA. The good news is that it is easy to find the start of the flow due to 0 before and after. 

- I need to stop the DMA for the WRDATA to avoid while copying the WRDATA buffer to get cleared out by the next DMA cycle. 

- Once I have identifed the right part of the NEW_WRDATA, I copy it at the right place in the RDDATA circular buffer, what I do not get is how I can very precisely identify where to copy this data. I can record the RDDATA DMA index when WR_REQ interrupt is happening, is this the right position ? 

- the copy process is ultra fast with a memcpy the cost is about less than 50 CPU cycles for a full track which is < 1uS.  

- clearing with 0 the WRDATA buffer (to avoid partial data remaining in the buffer);

- I started over the DMA for WRDATA.

this is a small schema of the 2 buffer process : 

the below screenshot is the track copy process using Locksmith: between 2 write we have someting like 4s which is enough to do stuff

 

My understanding: 

- Index between read and write buffer and not synced,

- before point C I will get 0 in the buffer, the same after D

- when WR_REQ get asserted, I record index A, and at the end index B. the destination zone is between A and B,

- I will copy the segment CD to AB, if B index is before A I need split the copy in 2 parts.

is this correct ? What is not clear for me is to know the very precise position at the begining of segment AB

 

Another case: 

- If you erase the full track using LockSmith, then the WR_DATA will be full of 0 how to determine the right start and the right end ? 

 

Thanks for all your explainations and efforts spent with me, it make me going into the right direction. I never thought it would be such a complexity for such an old technology....

 

Vincent 

 

 

 

 

 

 

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
VIBR wrote:- If you erase the
VIBR wrote:

- If you erase the full track using LockSmith, then the WR_DATA will be full of 0 how to determine the right start and the right end ? 

To make your life more complicated a fully erased media track still produces read pulses due to the noise in DISK II floppy drives.

This is just an example example when using advanced contemporary technology with fast processors is not enough to make an effective realtime machine to "fool" a 40 year's old 1 MHz computer. 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
This part of the project is

This part of the project is really really tricky (much more difficult than the read process). 

The way I would manage it is the following : 

Having the emulator on drive 1, a real disk II in drive 2. 

Start by working on a single track with a copy from drive 2 to drive 1

First step is to validate that what the emulator is receiving is the same as what the drive 1 is sending.

Second step After validating first step, I would do the same with a full disk track by track, 

Third step would validate the index in the RDDATA buffer. 

Fourth step is to work with a full erase (managing 0)

Fifth step is to copy a disk and boot from it on the emulator 

Vincent  

Offline
Last seen: 1 week 3 days ago
Joined: Apr 1 2020 - 16:46
Posts: 996
Some more comments / hints:

Hi Vincent -

 

Sorry I can't respond quicker because of the way I work (no internet at home, fully intentionally, otherwise it would suck me into its "black hole" as I'm a very curious guy, and on top of that the spying by internet providers who build "personality profiles" they sell to third parties, which may include gangsters / scammers) does not allow me to respond quickly. I drive to the public library where I can get anonymous internet access, load the pages and download the stuff I need, and then take it home to digest it. The charge of my notebook  battery is limited, so this also limits the time the internet can "steal" from my RQLT per day.

An arrangement I can recommend for anyone, especially internet junkies. IMHO the internet is more addictive than Cocaine. Most of the populace are now internet zombies whose life time gets stolen by 'social media' and the like. And it's a trap for smart and curious people, too. Because the internet "knows" everything. You can discover and learn and discover more and learn more ... until you have wasted your whole life without doing anything productive, but you will think you have learned a lot... the real world is different. The "pod" allegory in the Y1999 movie "THE MATRIX" was meant as a warning. When being "plugged in", people can waste their whole life living in an illusion and never experiencing the real world. Internet is TV mind control on steroids. But now back to your Floppy Emu project.

 

Yesterday I have downloaded the ST32 datasheet and started to read half of it. I noticed that the DMA can do ring buffers, which is a great feature. A lot of problems with the Floppy Emu coding effort go away. But still, there are some caveats:

 

1. It is good that the "read channel" runs all the time with perfect closing of the loop at the end of the revolution of the simulated floppy disk. The status of the DMA or a timer running in lockstep with the DMA can be used to determine where on the track we are, all the time.

 

2. The "write channel" running all the time is also good. But note that with the current circuitry it can't run in lockstep with the revolution of the simulated floppy disk, because once the WR_REQ is deasserted, the digital PLL (in the 74393) will lose sync soon. But as it will continue to produce SPI clocks, you will not lose the last byte, nor lose the first byte once write commences. The benefit of the digital PLL is that one active edge on WRDATA is enough to get it perfectly in lockstep with the DISK II controller. Note that due to the plesiochronous nature of the system, the phase will vary due to the clock frequency difference, but it will be restored on every acive WRDATA edge detected by the 74LS123 oneshot.

 

The consequence of this is twofold:

 

- First, you need to take the position information for any data write event (WR_REQ gets asserted) from the read channel, and not from the write channel. But with the interrupt routine for WR_REQ falling (getting asserted, write starts) you also need to grab the position information where the DMA is in the write track buffer, to later find the chunk of data that was written, and to copy it to the read track buffer at the position there.

 

- Second, since the write channel runs all the time, even when WR_REQ gets deasserted, the write track buffer will be overwritten with all zeros even when the DISK II system is reading from the read track buffer. This is not a bug. It's a feature that is inevitabe if you want to avoid losing write data due to write channel startup and stop events and their latency. What you need to do with any written data is to copy it into the read track buffer as soon as possible. No DMA channel needed for that. The ST32 is fast enough.

 

What I recommend for the debugging phase is that you don't do the copy yet but use the WR_REQ change interrupt for the deassertion (write ended) case to turn off the wite channel DMA. Then read all the relevant information (read track buffer, write track buffer, position information) into a host system and analyze what you got. Then figure out algorithms to do the fine positioning of pointers to the written data (source) and into the read data buffer (where it belongs and shall be copied). The state of the DMA you grabbed when WR_REQ was asserted will help to find these locations in memory but due to the latency in the system some adjustment by smart algorithms may be necessary. Finding the write data chunk is easy (it begins with a trail of zero bytes and ends with a trail of zero bytes) but finding out where it shall be copied into the read track buffer may be more tricky ... the algorithm most likely must search backwards in the read buffer to find where the sector's gaps and data fields start. I can't tell no more as I don't know the latency of the DMA / FIFO / SPI data path. But the offset you will find should be fairly consistent. If that fails we need to add some more hardware do deal with the situation.

 

When LOCKSMITH produces an all zero write track buffer, you did not copy the data the DMA put into it in due time, so it was overwritten. But during the debugging phase you sure could use a WR_REQ desassertion interrupt to kill the DMA which will preserve the buffer contents for analysis.

Note that keeping the write channel DMA running all the time is not mandatory. You could use a delayed turn-off after WR_REQ is deasserted even in the final system. But then you run into the problem with starting the DMA up quickly again at the next WR_REQ assertion. What ws the value of the bytes you have lost due to that startup latency ? (See the reason why I'd like to have it running all the time).

 

What I would do if I was the developer of that floppy emu software would be to figure out the proper way to write single sectors first. Not formatting yet. You start with a formatted image. The topic of how the floppy emu should handle the formatting of a track (and LOCKSMITH etc.) comes later. It may entail a completely different approach in handling the track buffers.

 

So far my comment on the software development.

 

Did not inspect your new schematic yet, but the first thing I saw is that the WRDATA signal to the change detector should come from the output of the 74LS14 Schmitt Trigger. Polarity does not matter, so one Schmitt Trigger inverter shall do.

 

There is more about the hardware, I think the ST32 is not 5V tolerant under all conditions, as I suspected in some posts above. Here is what I found in the datasheet:

 

Table 11 on page 57 tells the truth about their "5V tolerance". As I suspected, it does not exist when the power supply VDD is turned off. The FT pins are specified for VDD + 4.0V, so VDD must be 1V minimum for 5V tolerance. What's worse is the VSS-0.3V spec for all pins, with a max. injected current of -5mA. This means if a pin goes negative and more than 5 mA is pulled out while doing so, the IC exceeds absolute maximum ratings and bad things can happen (permanent damage / blowing up / smoke). They claim that positive injection is not possible if the max voltage on the pin is not exceeded (this is supposed to be the VDD+4V limit). Would be interesting to test what happens if that voltage limit is exceeded (remember, the 20pin floppy disk cable has +12V and -12V on it, and bad things can happen if these 24V can find a sneak path to zap things).

Overall the picture is not bad, though. Some protection cicuits and current limiting resistors at appropriate places can take care of all the possible mishaps. The worst of which probably is inserting the floppy disk cable turned 180 degrees, but plugging it in offset by one or more pins also needs to be addressed. This sounds silly but it happens more often than you would think. Mountains of dead DISK II floppy disk drives and piles of zapped IWMs give testimony of these crimes against innocent hardware. Sure, the connectors on original Apple hardware were mostly keyed but alas, human ham fisted hands can excert enough force to make wrong connections possible even with keyed conenctors. Another cuplrit are the Taiwanese clone DISK II controller cards which rarely had keyed connectors. There also are lots of third party flat band cable assemblies with a type of press-on connector that can be plugged into the pin headers with an offset. The more foolproof type of these connectors have a plastic body which is wide enough to interfere with pins of the header, theoretically preventing offset insertion, but with enough applied brute force the end pins of the pin header will just be bent out of the way and the connector will mate on all remaining pins in an offset way. None of that is user friendly / foolproof. So for any "kit", proper choice of connectors is mandatory. But this does not help if the floppy emu cable is plugged into a Taiwanese DISK II card clone which allows plugging in the cable in a wrong way.

 

- Uncle Bernie

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Hello Uncle, Regarding your

Hello Uncle, 

Regarding your last post, I have to say that I am very impressed by your routine. It is not everybody that follow and apply to themself  such strong personnal rules. I have teenagers under my roof and I share the same exasperation with Internet and the generation of zombies created by socials. Passivity behind the screen is killing our people in silence. Anyway... It gives us the opportunity to act differently with our children.

I think we have the same approach on the software part, and yes the STM32 is a marvel of engineering.  

On the schema, I have followed your guidance, and I can easily adapt to add the LS14 between WRDATA and LS74.

Something like this ? 

 

 

I will continue doing some testing on the software piece and build the tools to dump memory needed to validate the writing process

Vincent

 

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Uncle B, I am working on the

Uncle B, 

I am working on the soft part and really not an easy piece. no real progresses, I need to build some tools to be able to check what is happening. 

I used the Logic analyzer on the NEWDATA pin to check what data I received and I can not find the typical D5 AA 96 signature... 

 

I would like to understand a specific part of the schema that is still for me unclear => the one in red. 

Why do we need to XOR WRDATA (PIN 1 U8A) with the previous WRDATA (LS74 PIN 5) ? 

I do not get the reason why and I need a bit of detailed and step by step explaination if you have time for that.

Thanks Vincent 

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
VIBR wrote: I have teenagers
VIBR wrote:

 I have teenagers under my roof ... 

I think we have the same approach on the software part, and yes the STM32 is a marvel of engineering.  

I thought you were a teenager who is doing his first steps in electronics... The STM is just one of the thousand ARM implementations polluting the IC market now, nothing more. 

 

The idea of the XOR is to get 1 on pin 9 of the '74 when WRDATA changes and 0 if no change occured from previous COUT clock rising edge.

 

Offline
Last seen: 8 hours 24 min ago
Joined: Nov 19 2023 - 15:28
Posts: 190
Ok thanks for your pleasant

Ok thanks for your pleasant comment... 

regarding the change if WRDATA this I got, what I do not got is why do we track change and not the data itself ?

 

Offline
Last seen: 3 days 20 hours ago
Joined: Jan 31 2024 - 06:40
Posts: 229
VIBR wrote:Ok thanks for your
VIBR wrote:

Ok thanks for your pleasant comment... 

regarding the change if WRDATA this I got, what I do not got is why do we track change and not the data itself ?

No, you did not get the XOR meaning, at least be honest. Now for the next question  -- refer to figure 9.6 in Jim Sather's book Understanding the Apple II and read (again?) message #39 in this topic.  When WRDATA signal changes logical state 1 is written on the diskette, lack of  WRDATA change means 0 is written.

 

 

Pages

Log in or register to post comments