All you always wanted to know about IPF

3rd Party Software, Tools & Add-ons for KryoFlux
Post Reply
User avatar
IFW
Posts: 2634
Joined: Mon Nov 08, 2010 2:42 pm

Re: All you always wanted to know about IPF

Post by IFW » Fri Feb 03, 2012 11:25 am

1, Yes that is one thing no other controller could do, ie perfectly stream data continuouly; now you see why it is very important :)
Yes, connection is guaranteed for all sizes, BUT...
Remember, data is fully analysed and understood in all IPF files (at least in the ones produced by the original analyser), therefore it is possible to know where gap can be safely extended or shrunk at runtime by the library. That's why it is possible to request 1, 8, or 16 bit aligned results - and the extremely complex mechanism mastering the gap :lol:
I'd like to draw your attention that it is possible to request 1 bitcell correctly alignment.
Data locked that way MUST be processed as bits, not bytes, e.g. take the returned stream size in bits seriously and wrap the buffer reading in your code at the exact bit position returned, otherwise you WILL get incorrect data.

2, You need to lock a track each time a "rotation" occurs in your emulation code. The library is guaranteed to alter any weak data - if at all - that is affected. Note, that the track had to be locked with the correct flags in the first place. For emulation you normally want this behaviour for other uses you normally don't want it :)

3, Not by heart...you probably want a Xelok protected game for data over index though; there should be tons of examples for tracks shorter than normal (larger bitcell width), and not so many examples for more dense tracks (smaller bitcell width).

User avatar
DrCoolZic
Posts: 164
Joined: Tue Jul 26, 2011 10:44 am

Re: All you always wanted to know about IPF

Post by DrCoolZic » Fri Feb 03, 2012 12:03 pm

IFW wrote:That's why it is possible to request 1, 8, or 16 bit aligned results - and the extremely complex mechanism mastering the gap :lol:
I'd like to draw your attention that it is possible to request 1 bitcell correctly alignment.
Data locked that way MUST be processed as bits, not bytes, e.g. take the returned stream size in bits seriously and wrap the buffer reading in your code at the exact bit position returned, otherwise you WILL get incorrect data.
Not in the documentation, but in the code :( really need to work on doc
DI_LOCK_TRKBIT => trklen is in bit ? and I suppose one entry for each bit in trkbuf?
3, Not by heart...you probably want a Xelok protected game for data over index though; there should be tons of examples for tracks shorter than normal (larger bitcell width), and not so many examples for more dense tracks (smaller bitcell width).
Yes I know I am lazy :roll:

User avatar
IFW
Posts: 2634
Joined: Mon Nov 08, 2010 2:42 pm

Re: All you always wanted to know about IPF

Post by IFW » Fri Feb 03, 2012 12:22 pm

Yes, as the comment says:
// 12: tracklen is in bits, and the track buffer is bit sized

The buffer starts at position 0 (buffer[0]: b7), ie left aligned, and you should restart reading there as soon as the next bit to be read from the buffer would equal the size of the buffer returned.

User avatar
DrCoolZic
Posts: 164
Joined: Tue Jul 26, 2011 10:44 am

Re: All you always wanted to know about IPF

Post by DrCoolZic » Sat Feb 04, 2012 9:53 pm

Here is an alpha release v0.0a of ipfdump. This program dump the content of an IPF file using the CAPS API.

It interprets the bit stream read through the CAPS API in three sections for EACH track of the IPF file
- a read track section that emulates the read_track command of a WD1772
- read address section that emulates multiple read_address commands of a WD1772
- read sectors section that emulates multiple read secor commands (one for each sector) of a WD1772

The output is large: typically about 5MB
Note this program should only work for Atari ST and PC because the sync mark detection is only done on 4489 and 5224. The rest of the mfm decoding is pretty standard

This is an ALPHA version only tested on few files so it may crash (please report)

Important side note
CAPSLib uses MFC => MFC is pretty old MS technology with a lot of idiosyncrasies => the includes of the release source is a pain because it drags the all MFC ...
Bottom line the original ipfinfo program that I have released did not use neither MFC nor CAPLib but was including static MFC because only using some .h files! So program was 1.6MB+
I have created new clean .h files to include CAPSLib in a program that does not use MFC and the result is that now IPFdump went from 1.6MB to 16KB !!!
and the new IPFDump is only 26KB
I do not know if there are interest in "my" CAPSLib that compile under VC2010?
I now have a new version that removes partially the obsolete and not really portable Windows defines (the CHAR, BYTE, SDWORD and co) - still work to do.
I have also started to clean definitions to use type declaration and checking. For example it is nice to use an enumeration for the density but it is even better to create a type for it and to use it in the CapsImage so type checking can be perform ....
My problem is the following:
- The release I heve done 4.2A is extremely close to original as it only contains bare minimum to compile under VC2010 ( I would recommend that it is included in the official release) ;)
- My new working version is already a bit more far away from original ... and therefore it would be more difficult to update if original from SPS is updated
should I stick to the pain of original or not?

I forgot to mention an important information: many .h files have been updated to contain doxygen documentation in order to provide minimum online html documentation of CAPSLib

Also released IPFLib.dll (this should be exactly the same as CAPSImg.dll but I put it just incase) that must be in same directory as ipfdump.exe
usage: ipfdump <input_ipf_file> [<outputfile>]
Attachments
IPFDump.rar
IPFDump 0.0a + ipflib.dll
(620.13 KiB) Downloaded 188 times
IPFInfo.rar
IPFInfo 0.3b
(7.99 KiB) Downloaded 206 times

User avatar
DrCoolZic
Posts: 164
Joined: Tue Jul 26, 2011 10:44 am

Re: All you always wanted to know about IPF

Post by DrCoolZic » Mon Feb 06, 2012 4:09 pm

IFW wrote:..... fUZZY BITS ......
2, You need to lock a track each time a "rotation" occurs in your emulation code. The library is guaranteed to alter any weak data - if at all - that is affected.
so CAPSLockTrack() CAPSUnlockTrack() CAPSLockTrack() CAPSUnlockTrack() CAPSLockTrack() would do three reads with different data
Note, that the track had to be locked with the correct flags in the first place.
Not sure what are correct flags? is it the non documented flag only found in source: #define DI_LOCK_UPDATEFD DF_8

Is there an easy indication to find out if sector/track contains fuzzy bits or do you need to make multiple lock/unlock to find out.
If not would be nice to add a flag because if I understand correctly this information is in IPF file

User avatar
IFW
Posts: 2634
Joined: Mon Nov 08, 2010 2:42 pm

Re: All you always wanted to know about IPF

Post by IFW » Mon Feb 06, 2012 6:12 pm

The track type will have CTIT_FLAG_FLAKEY bit set.

Note, that Unlock should NOT be called on tracks containing weak bits between subsequent Locks as that woud cause the weak bit generator to re-initialize at the next Lock.
Also note, that each track currently locked has its own private weak bit generator state.

DI_LOCK_UPDATEFD is the flag to set if you want to enable weak bit and track overlap handling - the latter is about the write splice of the track.

You can set arbitrary seed values to the weak bit generator using DI_LOCK_SETWSEED; this is useful for emulators when they save/restore emulation state.

Don't forget to set DI_LOCK_TYPE and the correct structure type before the calls.

User avatar
DrCoolZic
Posts: 164
Joined: Tue Jul 26, 2011 10:44 am

Re: All you always wanted to know about IPF

Post by DrCoolZic » Tue Feb 07, 2012 10:57 am

IFW wrote:The track type will have CTIT_FLAG_FLAKEY bit set.
Whaooo. I thought type could take values 1-3 (noise, auto, var) but looks like if you want to know the type of the track you first have to test the CTIT_FLAG_FLAKEY then do
type = type & CTIT_MASK_TYPE to find (noise, auto, var)
I guess this is required because you can have fuzzy && (noise, auto, var) ?
Note, that Unlock should NOT be called on tracks containing weak bits between subsequent Locks as that woud cause the weak bit generator to re-initialize at the next Lock.
Also note, that each track currently locked has its own private weak bit generator state.
so it is not CAPSLockTrack() CAPSUnlockTrack() CAPSLockTrack() CAPSUnlockTrack() CAPSLockTrack()
but CAPSLockTrack() CAPSLockTrack() CAPSLockTrack() to read three times?
The documentation says
The locking of tracks is done using some attributes – flags – supplied with the call.
Some flags can result in different data being returned by the call. As long as the track
is not unlocked directly or indirectly, each subsequent lock on the same track returns
the very same data generated the first time the track was originally locked, regardless
of the flags later supplied.
But if weak bits the track does NOT return the very same data :roll:
DI_LOCK_UPDATEFD is the flag to set if you want to enable weak bit and track overlap handling - the latter is about the write splice of the track.
???
You can set arbitrary seed values to the weak bit generator using DI_LOCK_SETWSEED; this is useful for emulators when they save/restore emulation state.
!!!
Don't forget to set DI_LOCK_TYPE and the correct structure type before the calls.
This must be related to the above. From what I understand if DI_LOCK_TYPE is set the type is used to specify the track structure and you have to use the corresponding structure in the call
0 => CapsTrackInfo
1 => CapsTrackInfoT1
2=> CapsTrackInfoT2

So if you use T2 you can set wseed as the seed
What is weakcnt? returned value?

overlap is probably about track write splice but I don't know the detail? I guess it allow to check if there is a perfect filling or a gap or an overlap ??? and to get info you have to use CapsTrackInfo or CapsTrackInfoT1 ???

startbit? position on the track of the first SYNC? / ID block / DATA block ?

User avatar
DrCoolZic
Posts: 164
Joined: Tue Jul 26, 2011 10:44 am

Re: All you always wanted to know about IPF

Post by DrCoolZic » Tue Feb 07, 2012 11:14 am

I have in the code

Code: Select all

	uint32_t flag=DI_LOCK_DENVAR|DI_LOCK_UPDATEFD;
...

			CAPSLockTrack(&ti, image, track, head, flag);
			bool fuzzy = ti.type & CTIT_FLAG_FLAKEY;
			fprintf(out, "\nTrack %02d.%d type=%d (%s) sectors=%d size=%d cnt=%d buflen=%d timelen=%d%s%s\n", 
				ti.cylinder, ti.head, ti.type & CTIT_MASK_TYPE, track_type[ti.type & CTIT_MASK_TYPE], ti.sectorcnt, ti.sectorsize, 
				ti.trackcnt, ti.tracklen, ti.timelen, ti.timelen ? " Timing" : "", fuzzy ? "Fuzzy" : "");
ThemeParkMystery has an No Flux Area and therefore should have week bits but my variable fuzzy is not set to true? What am I doing wrong?

User avatar
IFW
Posts: 2634
Joined: Mon Nov 08, 2010 2:42 pm

Re: All you always wanted to know about IPF

Post by IFW » Tue Feb 07, 2012 11:49 am

That's correct.
NF areas would always yield the exact same data, therefore it is not needed to call an upate for each revolution - what the flag represents.

User avatar
IFW
Posts: 2634
Joined: Mon Nov 08, 2010 2:42 pm

Re: All you always wanted to know about IPF

Post by IFW » Tue Feb 07, 2012 12:13 pm

1,
type = type & CTIT_MASK_TYPE to find (noise, auto, var)
I guess this is required because you can have fuzzy && (noise, auto, var) ?
Correct.

2,
But if weak bits the track does NOT return the very same data :roll:
The documentation was written about 8 years ago... apart from basic functionality and theory of operation the library is very different from what it was like then... pretty much all the developers using it discussed things with me directly, and many of the new functions are based on their feedback (Toni, Simon, Dave, John et al), so admittedly updating the API document got neglected. :roll:

3,
write splice of the track.
The library simulates (if requested) the write splice artefact of a written disk, namely a few cells changing there.
You can set arbitrary seed values to the weak bit generator using DI_LOCK_SETWSEED; this is useful for emulators when they save/restore emulation state.
Actually, the recommended way is to obtain the current seed value (returned in a CapsTrackInfoT2.wseed after a lock) when saving state, and set the same value (and the same mode flags plus DI_LOCK_SETWSEED) when locking again after a state restore. Ie the wseed value can be set by the user and is always written by the decoder.

4,
So if you use T2 you can set wseed as the seed
Correct.
What is weakcnt? returned value?
The number of (separate) weak bit areas on the locked track; it is useful for CAPSGetInfo or as an alternate way of testing whether the tracks should be locked/updated, ie not 0.

5, Unless you are using legacy code, you are always better off using the last version specific to any structure. The rest is only there to keep backwards compatibility with any version of any host software using the library.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest