Update 1541-IDE

Date: 2009-01-05 13:48:09

Hallo allemaal,
Again an update on my project. It still isn't running but at least I
know the cause of all my trouble. I never understood how the 1541
exactly handled the BAM and still don't :( For this reason I always
replaced the BAM routines by my own. With my own routines almost all
common things worked fine but there was always a catch somewhere, like
the problems with COPY and SCRATCH I reported before.
Saturday I started another try to handle 16 MB disks. In this case I
decided to leave the BAM routines "as is" and to solve the problem in
another way. Dealing with 16 MB disks means I need a bigger BAM. The
idea was to use track 0 for storing the BAM as I cannot use it for
regular operations like saving files. So first I persuaded the 1541 to
use track 1 as BAM/directory. In this way I found out that, although
they should use a pointer stored at $FE85, some routines used an hard
coded pointer (LDA #18 instead of LDA $FE85). After replacing these by
$FE85, things ran fine. But I lost valuable time to find out why I only
had 662 free blocks instead of the usual 664 :( 
The next step was moving the whole to track 0. This worked out fine
although my test program collapsed. Using track 0 means I need four
extra bytes in the BAM table. In this case the very first four bytes.
And the first three are nomally used for "next directory track", "next
directory sector" and "1541 code A". My program reads the directory as a
sequentail file and collapsed on the now not existing pointers.
Creating, copying and saving of PRGs, sequential and relative files, as
well as loading the directory in the normal way, worked fine.
I still want to use track 18 / sector 0 (18/0) for storing the label and
disk-ID. The 8x50 drives behave in the same way; they only use other
tracks to store the BAM and directory. For showing the directory I need
to read 18/0, for calculating the number of free blocks I need to read
0/0. The trouble is that the 1541 checks if buffer 4 is already in use.
If that is the case, it assumes the BAM is already loaded and skips the
loading routine. In the version I am working at now, I reached this
point yesterday evening: if I ask for the directory, the 1541 first
loads 18/0 for the label and then I tell it load 0/0 to count the free
blocks. And that action is skipped with as result 0 free blocks. But I
have dealt with this problem in a previous version so I think I can
solve it. "Think" because in this previous version I didn't test things
to well and ran into serious trouble after having changed to much code
:( The main idea is to load the BAM and when 18/0 is needed, to "park"
the contents of the buffer on a unused sector on track 0 and to restore
it after the action. The problem is that I haven't found all routines
needing the label and/or ID yet (and therefor those problems).
Next part is for the techies amongst us. For those who understand old
Dutch: "Ter leeringh ende vermaek!". 
When a sector has to be allocated, the routine at $EF90, 'AllocSector',
is called. This routine first checks whether the BAM has to be written
to the disk or not ($EFF1). Weird thing: the 'FreeSector' routine at
$EF5F does NOT call this function, why? Even weirder: at $EF5C, just
before FreeSector, you find the call to $EFF1 as if this used to be the
original entrance to FreeSector.
Both AllocSector and FreeSector then call a routine at $EFCF, which gets
the state of the bit in the BAM representing the sector to be allocated,
'GetBitBAM'. GetBitBAM immediatly calls a routine at $F011,
'GetBamField', to find the four bytes in the BAM representing the track
where the sector is located. At $F02C the track is compared with two
values of a group of four (the last two are for drive 1) called TBAM,
found from $029D on. If the track isn't equal to one of the two values,
the BAM can be loaded, if not loaded yet. 
Wanting to be in full control, I thought I could skip these equations.
Wrong! When ommiting this check, nothing works anymore. And I haven't
found out why yet.
If the equations don't work out, a routine at $F05B is called. BTW, this
is the only place where this routine is called. In some earlier versions
I saved some bytes (and stack space when running) by replacing the
original JSR by the routine itself. This routine loads the BAM, if not
loaded yet. If loaded, I'm a bit in trouble because in the future I have
to deal with more sectors. So I have to convince it yet to load the
needed sector in one or another way.
F05B calls the routine 'VerifyBamEntry' at $F0A5. At the start the TBAM
is used to check whether or not to perform the routine. If the routine
is performed, TBAM is cleared. At $F0BE you'll find a puzzling piece of
code: it copies 4 bytes from a block of 16 located at $02A1, BAMimage,
into the buffer where the BAM is. Which 4 bytes of the firts 8, the
other eight are for drive 1, depends on the earlier mentioned equation
and the variable UBAM, $029B.  
Now 4 bytes of the BAM are copied somewhere into this BAMimage and the
copied bytes are replaced by zeros. FYI, in an earlier version I ommited
the VerifyBamRoutine to save space and the noticed, too late of course,
that the BAM was filled with all zeros.
Then one of the first two TBAM bytes is filled with the track number.
At the end, if there hasn't been tempered with the BAM by another
routine, the BAM with those 4 zeros is saved to disk.
After calling F05B the variable UBAM is set. Then the pointer BMPNT is
set to point to the 4 bytes in use in BAMimage.
The control is given back to GetBitBAM where the exact byte and bit are
looked up. AllocSector and FreeSector do the rest.
Writing the above made even more understand what is going on. But the
"why ????". It looks to me as if an airline wants to fly passengers from
New York to San Fransico but drops them in Chicago and then sends
another plane to fly those passengers from Chicago to San Fransisco. And
to make it weirder, the next flight drops the passengers in Dallas and
the next one in Chicago again. At least it makes no sense to me.
And the weird behaviour around TBAM haven't been explained as well.
What is even worse, there must be connections between these weird
routine and other routines. Unfortunately I haven't found them :(

    / __|__
   / /  |_/     Groetjes, Ruud
   \ \__|_\
    \___|       URL: Ruud.C64.org


De informatie in dit e-mailbericht is vertrouwelijk en uitsluitend bestemd voor de 
geadresseerde. Wanneer u dit bericht per abuis ontvangt, verzoeken wij u contact op te 
nemen met de afzender per kerende e-mail. Verder verzoeken wij u in dat geval dit 
e-mailbericht te vernietigen en de inhoud ervan aan niemand openbaar te maken. 
Wij aanvaarden geen aansprakelijkheid voor onjuiste, onvolledige dan wel ontijdige 
overbrenging van de inhoud van een verzonden e-mailbericht, noch voor daarbij 
overgebrachte virussen.

APG Algemene Pensioen Groep NV is gevestigd te Heerlen en is ingeschreven in het handelsregister van de Kamer van Koophandel Limburg onder nummer 14099617

The information contained in this e-mail is confidential and may be privileged. 
It may be read, copied and used only by the intended recipient. 
If you have received it in error, please contact the sender immediately by 
return e-mail; please delete in this case the e-mail and do not disclose it's 
contents to any person. We don't accept liability for any errors, omissions, 
delays of receipt or viruses in the contents of this message which arise as a 
result of e-mail transmission.

APG Algemene Pensioen Groep NV is registered in the trade register of the Chamber of Commerce Limburg, The Netherlands, registration number: 14099617

       Message was sent through the cbm-hackers mailing list

Archive generated by hypermail pre-2.1.8.