Track reading (Sedoric / FDC)
Track reading (Sedoric / FDC)
This is driving me crazy .
I'm trying to get a reliable way to read a track, to make a universal disk transfer tool.
So thanks to Fabrice, I'm using the Sedoric routines (at $CFCD in Sedoric kernel - see Sedoric à Nu page 179 for details).
This is done by setting some parameters (drive, track, data storage buffer), then sending a $E0 (read track) command at the FDC with the $CFCD routine.
All seems to be fine except that some bytes, always at value $C2, are either inserted in the reading, either crush existing bytes. Ouch.
I tried this on NightBird's hardware at the last meeting and we had those $C2 bytes too, so my hardware is not to blame (or both are to blame )
By using Nibble, which reads tracks too, I noticed this didn't seem to happen.
I took a look at the code and the track reading is similar to the code I used, except there was 1st a $18 command (set the head on the right track). So I modified my code but still have the same problem.
I made a small program counting the $C2 bytes in the reading buffer once the track has been read. Here are the results:
- on Euphoric, both my method and Nibble read the track, 4 bytes at $C2 are read
- on a real Oric, tried twice, with my method 144 (!!!) bytes at $C2 are read
- on a real Oric, tried twice, with Nibble 2.4, 19 or 20 bytes at $C2 are read
I absoutely don't understand why there are such errors ans differences.
Any idea on what happens?
2022 sum-up edit for better understanding: actually Nibble performs a Read Track command, but afterwards reads each sector individually and replaces the data from the Read Track command to remove the bad reading (explained in the manual). Thus much less $C2 bytes in the final result, but some $C2 still appear outside the sectors data. The $C2 are misinterpretation of syncrho bits from the Read Track command and can't be avoided it seems
I'm trying to get a reliable way to read a track, to make a universal disk transfer tool.
So thanks to Fabrice, I'm using the Sedoric routines (at $CFCD in Sedoric kernel - see Sedoric à Nu page 179 for details).
This is done by setting some parameters (drive, track, data storage buffer), then sending a $E0 (read track) command at the FDC with the $CFCD routine.
All seems to be fine except that some bytes, always at value $C2, are either inserted in the reading, either crush existing bytes. Ouch.
I tried this on NightBird's hardware at the last meeting and we had those $C2 bytes too, so my hardware is not to blame (or both are to blame )
By using Nibble, which reads tracks too, I noticed this didn't seem to happen.
I took a look at the code and the track reading is similar to the code I used, except there was 1st a $18 command (set the head on the right track). So I modified my code but still have the same problem.
I made a small program counting the $C2 bytes in the reading buffer once the track has been read. Here are the results:
- on Euphoric, both my method and Nibble read the track, 4 bytes at $C2 are read
- on a real Oric, tried twice, with my method 144 (!!!) bytes at $C2 are read
- on a real Oric, tried twice, with Nibble 2.4, 19 or 20 bytes at $C2 are read
I absoutely don't understand why there are such errors ans differences.
Any idea on what happens?
2022 sum-up edit for better understanding: actually Nibble performs a Read Track command, but afterwards reads each sector individually and replaces the data from the Read Track command to remove the bad reading (explained in the manual). Thus much less $C2 bytes in the final result, but some $C2 still appear outside the sectors data. The $C2 are misinterpretation of syncrho bits from the Read Track command and can't be avoided it seems
Last edited by Symoon on Wed May 18, 2022 6:58 am, edited 2 times in total.
Re: Track reading (Sedoric / FDC)
Are you reading using an IRQ, or by polling the registers - and if polling, have you disabled the IRQs ?
Re: Track reading (Sedoric / FDC)
I must confess I don't really know (as I don't really know what polling registers means )
I (as well as Nibble it seems) don't handle anything, just set a few parameters and call the reading routine.
The reading routine (quite big) is described in Sedoric à Nu from page 179 to page 186. Unless I spend a few days on it, it is so far a bit beyond my understanding. It seems to read FDC registers (in page 3) and use IRQs but I'm not sure it is what you asked.
What puzzles me is that apprently this routine is called in the same way by both programs, and gives such different results
I (as well as Nibble it seems) don't handle anything, just set a few parameters and call the reading routine.
The reading routine (quite big) is described in Sedoric à Nu from page 179 to page 186. Unless I spend a few days on it, it is so far a bit beyond my understanding. It seems to read FDC registers (in page 3) and use IRQs but I'm not sure it is what you asked.
What puzzles me is that apprently this routine is called in the same way by both programs, and gives such different results
-
- Squad Leader
- Posts: 774
- Joined: Sat May 21, 2011 7:21 pm
- Location: Between UK and France
- Contact:
Re: Track reading (Sedoric / FDC)
polling mean that you have a tight loop where you read the register and exit the loop when the value you want is set on this register.
The difference between polling and IRQ approach is the first is a synchrone way to synchronise, the other is an asynchrone way.
Both have advantages and disavantages.
Polling/synchrone consume a lot of CPU time and power and you can't do anything when waiting, but the code is easier to make.
IRQ/asynchrone consume less CPU as you don't read the register, just "wait" for the IRQ to trigger and you can do whatever you want during the wait time. The drawback is that the code could be much complexe than polling.
The difference between polling and IRQ approach is the first is a synchrone way to synchronise, the other is an asynchrone way.
Both have advantages and disavantages.
Polling/synchrone consume a lot of CPU time and power and you can't do anything when waiting, but the code is easier to make.
IRQ/asynchrone consume less CPU as you don't read the register, just "wait" for the IRQ to trigger and you can do whatever you want during the wait time. The drawback is that the code could be much complexe than polling.
My Projects: Replic'Oric Project - StratoCumulus Project
Re: Track reading (Sedoric / FDC)
I am a bit confused...
You say that nibble does not have this problem, but in your tests it does include the spurious bytes?
Maybe if you could post the code, it would help. I am not used to complete track reading routines in Sedoric...
However to seek for a track+sector (put the heads at the correct position) my code is a bit different. It uses command $1c, not $18 and you must wait for the command to complete successfully or with some error. This is done by reading $0314 until the highest bit is clear and check $0310 for any error:
I don't know if there is a different command to seek for a track or you have to order the seek of track+sector with sector 0 (or was it 1?).
And after reading, I check the success of the operation by reading $0310 this way:
But I guess this is all useless, as you are using built-in routines, which I don't know how they work... but should work... There must be some kind of initialization missing...
You say that nibble does not have this problem, but in your tests it does include the spurious bytes?
Maybe if you could post the code, it would help. I am not used to complete track reading routines in Sedoric...
However to seek for a track+sector (put the heads at the correct position) my code is a bit different. It uses command $1c, not $18 and you must wait for the command to complete successfully or with some error. This is done by reading $0314 until the highest bit is clear and check $0310 for any error:
Code: Select all
seek_track
lda #$1C
jsr wait_completion
and #$18 ; seek error or CRC error ?
beq seek_ok
jsr restore_track0
beq seek_track
seek_ok
rts
wait_completion
lda $0314
bmi wait_completion
lda $0310
rts
And after reading, I check the success of the operation by reading $0310 this way:
Code: Select all
lda $0310 ; gets status
and #$7c
beq success
dec restart_counter
bne again
success
Re: Track reading (Sedoric / FDC)
Thanks to all for the replies.
By counting in memory I could realize the problem is also there with Nibble but in a significantly lower amount.
I'm not looking to read sectors, but whole tracks (which should help the tool reading any disk)
- it evaluates the command
- displays "reading" message
- stops the blinking cursor
- then reads the track this way:
On my side Fabrice sent me almost the same code to read a track last year (it didn't have the command $18). I added the command $18 just before the command $E0 but it didn't change anything.
Maybe Nibble does something before indeed, but that seems quite strange.
I should try (next weekend ?) to let Nibble read a track, exit, immediately launch my program to see if it reads it better (hoping Nibble's reading won't crush my basic code).
Hehe, it didn't seem to happen Because at 1st I didn't notice it visually, except very few mistakes here and there (and at 1st I thought the hardware / old disk was to blame)Chema wrote:I am a bit confused...
You say that nibble does not have this problem, but in your tests it does include the spurious bytes?
By counting in memory I could realize the problem is also there with Nibble but in a significantly lower amount.
I'm not looking to read sectors, but whole tracks (which should help the tool reading any disk)
The code is quite simple, here's for Nibble, from the moment CTRL P is pressed:Chema wrote:Maybe if you could post the code, it would help. I am not used to complete track reading routines in Sedoric...
- it evaluates the command
- displays "reading" message
- stops the blinking cursor
- then reads the track this way:
Code: Select all
98BE AD 8B A3 LDA $A38B reads / stores the selected drive
98C1 8D 00 C0 STA $C000
98C4 AD 8A A3 LDA $A38A same for the track
98C7 8D 01 C0 STA $C001
98CA AD D2 AA LDA $AAD2 sets the destination buffer (C002, used for sector, is unused here)
98CD AE D3 AA LDX $AAD3
98D0 8D 03 C0 STA $C003
98D3 8E 04 C0 STX $C004
98D6 A2 18 LDX #$18 set head on track command
98D8 20 CD CF JSR $CFCD Sedoric routine
98DB A2 E0 LDX #$E0 read track command
98DD 20 CD CF JSR $CFCD Same Sedoric routine
98E0 A9 18 LDA #$18
98E2 A2 80 LDX #$80 not sure what the rest is used for (display?)
98E4 8D 90 A3 STA $A390 but anyway the track must already have been read there
98E7 8E 8F A3 STX $A38F
98EA A9 31 LDA #$31
98EC 8D 91 A3 STA $A391
98EF AD 91 AA LDA $AA91
98F2 F0 01 BEQ $98F5
98F4 60 RTS
Maybe Nibble does something before indeed, but that seems quite strange.
I should try (next weekend ?) to let Nibble read a track, exit, immediately launch my program to see if it reads it better (hoping Nibble's reading won't crush my basic code).
Re: Track reading (Sedoric / FDC)
This is very strange because you always get $C2 bytes.
$C2 is a SYNC byte (of course you can find some in the datas).
I think there is one $C2 somewhere on a sector, so Euphoric is right because there is 3 $C2 bytes at the beginning of each track.
On a real hardware you should find only 2 $C2 bytes or less (the first one start the sync process of the FDC and can't generally be transferred to the data register) + the one on the sector.
Maybe the FDC has some trouble reading the track and retry.
Did you try to read a track on the other side or elsewhere on the disk (at the beginning, some in the middle, and at the end)?
Off topic, I can't get Nibble working with oricutron, CTRL+P seems to be a never ending loop, don't know why...
$C2 is a SYNC byte (of course you can find some in the datas).
I think there is one $C2 somewhere on a sector, so Euphoric is right because there is 3 $C2 bytes at the beginning of each track.
On a real hardware you should find only 2 $C2 bytes or less (the first one start the sync process of the FDC and can't generally be transferred to the data register) + the one on the sector.
Maybe the FDC has some trouble reading the track and retry.
Did you try to read a track on the other side or elsewhere on the disk (at the beginning, some in the middle, and at the end)?
Off topic, I can't get Nibble working with oricutron, CTRL+P seems to be a never ending loop, don't know why...
Re: Track reading (Sedoric / FDC)
What's even more puzzling is that somtimes the C2 bytes crush other bytes, and sometimes they are inserted between two bytes (I could see that by saving the reading buffer and comparing several readings of the same track)
Interesting: I had saved two readings on NightBird's equipment, and it seems there are much less of those C2 bytes, less than 10 that differ from one reading to the other. Same on older readings on my own hardware.
That doesn't explain anything though!
I mostly tried on track 8 or 9 (repeating the same read) but I tried it on different drives and different disks (and even on 3" and 3.5").christian wrote:Did you try to read a track on the other side or elsewhere on the disk (at the beginning, some in the middle, and at the end)?
Interesting: I had saved two readings on NightBird's equipment, and it seems there are much less of those C2 bytes, less than 10 that differ from one reading to the other. Same on older readings on my own hardware.
That doesn't explain anything though!
Are you using Nibble 2.4? It was a fix made by Fabrice, I think Nibble had trouble with double-sided disks or something like that.christian wrote:Off topic, I can't get Nibble working with oricutron, CTRL+P seems to be a never ending loop, don't know why...
Re: Track reading (Sedoric / FDC)
Does it means you don't have the same number of bytes read every time?Symoon wrote:What's even more puzzling is that somtimes the C2 bytes crush other bytes, and sometimes they are inserted between two bytes (I could see that by saving the reading buffer and comparing several readings of the same track)
Maybe some kind of interference (power supply)?
Can you try with a HxC, I know it isn't the intent, but I think this can help the troubleshooting:
- if there are no errors, the issue is probably the floppy drive (bad speed, dirty heads,...)
- if you still have errors, maybe the controller interface or some interrupts
You're right, it was the 2.3Symoon wrote:Are you using Nibble 2.4? It was a fix made by Fabrice, I think Nibble had trouble with double-sided disks or something like that.
Re: Track reading (Sedoric / FDC)
I watched the code at $CFCD, it disable only T1 interrupts but this should be sufficient:
Reading is done by polling the DRQ register ($318) then reading the Data Register ($313) and so on until the FDC issues an IRQ indicating the end of the command or an error (subroutine at $D081)
That is exactly the opposite of what FTDOS does
It would be interesting to adapt your program to the Jasmin controller and see if there is the same problem.
Code: Select all
CFD4- LDA #$40
CFD6- STA #$30E
That is exactly the opposite of what FTDOS does
It would be interesting to adapt your program to the Jasmin controller and see if there is the same problem.
Re: Track reading (Sedoric / FDC)
Are there any technical docs for FT-DOS, just like l'Oric à Nu for Sedoric?christian wrote:It would be interesting to adapt your program to the Jasmin controller and see if there is the same problem.
I've never been an ASM expert and it always takes me ages to understand rough code.
I can either try the track reading on Jasmin, or I could try to reproduce FT-Dos' reading strategy in Sedoric. In both cases I need more information about FT-Dos
I have the manual stored somewhere (away from where I am) but never read it, does it goes that deep and detail the track reading?
Re: Track reading (Sedoric / FDC)
In case you're wondering why it never worked in Oricutron, its because I never implemented track read/write. I didn't have anything to test it with, and would just have been guessing, so I'll probably bookmark this thread for useful info
-
- Squad Leader
- Posts: 774
- Joined: Sat May 21, 2011 7:21 pm
- Location: Between UK and France
- Contact:
Re: Track reading (Sedoric / FDC)
I don't think the Jasmin manual will help..
Christian asked a good question, is, how "reliable" is multiple run of the same code?
Also, if the floppy have some defect, it is possible that the hardware try to resync (the $c2)
Do you have a floppy with a well known content (for example a floppy that you write on your PC and you exactly know it's content)
A test floppy with easy to spot value (like buffers or $A5 / $5A, and some nice value like this) could be a good test media.
There is one thing I'm not sure to understand, some bytes are sometimes replaced by $C2, sometimes between valid bytes, there is some $C2 added?
It really sound like the controller have difficulty to read your floppy.
Could you measure the time needed to read the track? It may help to understand if there is some read errors.
Edit: I think this is the answer:
The FDC Read Track is not 100% reliable, I suspect that nibble will read the same track multiple times, and do some check before "validate" it.
(both extract come from FDC 179x datasheet: http://www.lupinek.com/soubory/wd2797.pdf or http://dev-docs.atariforge.org/files/WD1772.pdf )
Christian asked a good question, is, how "reliable" is multiple run of the same code?
Also, if the floppy have some defect, it is possible that the hardware try to resync (the $c2)
Do you have a floppy with a well known content (for example a floppy that you write on your PC and you exactly know it's content)
A test floppy with easy to spot value (like buffers or $A5 / $5A, and some nice value like this) could be a good test media.
There is one thing I'm not sure to understand, some bytes are sometimes replaced by $C2, sometimes between valid bytes, there is some $C2 added?
It really sound like the controller have difficulty to read your floppy.
Could you measure the time needed to read the track? It may help to understand if there is some read errors.
Edit: I think this is the answer:
The FDC Read Track is not 100% reliable, I suspect that nibble will read the same track multiple times, and do some check before "validate" it.
(both extract come from FDC 179x datasheet: http://www.lupinek.com/soubory/wd2797.pdf or http://dev-docs.atariforge.org/files/WD1772.pdf )
My Projects: Replic'Oric Project - StratoCumulus Project
Re: Track reading (Sedoric / FDC)
I think you got it Godzil. And that explains why this routine is seldom used in real programs.
Symoon, what are you trying to do? I could try to provide some routines to read full tracks sector by sector if you wish...
Symoon, what are you trying to do? I could try to provide some routines to read full tracks sector by sector if you wish...
Re: Track reading (Sedoric / FDC)
He probably want to write a program that can do a raw copy of the floppy, independently of the number of sectors, tracks, special gaps, protections, etc...
Like what we had on the ST with the various copy programs.
Like what we had on the ST with the various copy programs.