| |
Fungus
Registered: Sep 2002 Posts: 626 |
CBM tape routines reverse engineering
I've spent a little over a week reverse engineering the CBM tape routines code. The read timing correction code is not entirely clear to me, I've made some guesses on how it works. Chuck Peddle never documented it, and in interviews he said 3 other Commodore programmers were supposed to do so and never did. With his passing I guess it would never get done, so I took it upon myself to do so. It's one of the last things about the C64 that is currently not completely documented, or not to a level that I feel it deserves.
I've messaged enthusi, but he doesn't seem to be about to have a look at it. I was wondering if any of the other expert coders would like to take a look privately and go over it looking for errors or adding any additional knowledge to it before I package it up in a document to release publicly.
Full acknowledgement and credit for any help/feedback will be added with gratitude.
Shoot me a message or reply if anyone is willing to have a go. |
|
| |
Martin Piper
Registered: Nov 2007 Posts: 645 |
I figured this out a while ago... From memory the important location is $b0
http://unusedino.de/ec64/technical/aay/c64/zpb0.htm
Stores to $b1 derive from values in $b0, so $b1 can be ignored. $b1 is basically used during CIA timer calculation.
I was able to test this empirically by taking a tap file and adjusting all the pulse lengths by a constant amount and noting the changes in b0 after the load finished.
Making the pulse lengths much longer results in larger tweaks being calculated for b0 compared to small pulse length changes.
$b0 is only really updated by inc/dec in response to testing the result of read pulse length calculations stored in $92, this is the routine at $f9d5
This means the pulse adjustment happens gradually over time (due to inc/dec only being +1/-1) in response to testing if the current read pulse is longer or shorter than the expected value. $b0 is of course initialised to 0 during the start of tape read. |
| |
Martin Piper
Registered: Nov 2007 Posts: 645 |
Interestingly, this adjustment to $b0 even happens during the tape file lead pulses, which are repeated short pulses. |
| |
Martin Piper
Registered: Nov 2007 Posts: 645 |
It's also interesting to note that the countdown sequence counting from $89 to $81 and for the second verify block counting from $09 to $01 does not have to include all numbers to be read by the kernal. I find this by manipulating the bytes written using my TapeTool. |
| |
Martin Piper
Registered: Nov 2007 Posts: 645 |
Tape with full $89-$81/$09-$01 countdown headers...
..\..\bin\TapeTool.exe wn "test.tap" ocl$6a10 ocn $89 $88 $87 $86 $85 $84 $83 $82 $81 ocnr $03 $00 $04 $07 $04 @"Loaders.bin" 0 187 ! oce ocl$4f ocn $9 $8 $7 $6 $5 $4 $3 $2 $1 ocnr $03 $00 $04 $07 $04 @"Loaders.bin" 0 187 ! oce ocl$1500 ocn $89 $88 $87 $86 $85 $84 $83 $82 $81 ocnr $00 $01 $02 $03 $04 $05 $06 ! oce ocl$4f ocn $9 $8 $7 $6 $5 $4 $3 $2 $1 ocnr $00 $01 $02 $03 $04 $05 $06 ! oce ocl$1500 c
Tape with just $81/$01 as the headers...
..\..\bin\TapeTool.exe wn "test.tap" ocl$6a10 ocn $81 ocnr $03 $00 $04 $07 $04 @"Loaders.bin" 0 187 ! oce ocl$4f ocn $1 ocnr $03 $00 $04 $07 $04 @"Loaders.bin" 0 187 ! oce ocl$1500 ocn $81 ocnr $00 $01 $02 $03 $04 $05 $06 ! oce ocl$4f ocn $1 ocnr $00 $01 $02 $03 $04 $05 $06 ! oce ocl$1500 c
Both will load. |
| |
Martin Piper
Registered: Nov 2007 Posts: 645 |
Creating long tapes with just short or medium pulses, the adjustment value in $b0 remains within a narrow range, $fe-$01.
However if the tape just contains long pulses, the $b0 adjustment value quickly escapes the normal range and starts rapidly increasing way beyond what would be considered to be normal.
This behaviour indicates the kernal is able to differentiate and calibrate on short and medium pulses, but cannot handle calibration using repeated long pulses. |
| |
Fungus
Registered: Sep 2002 Posts: 626 |
The timing delta is calculated based on drift from the mean time for each pulse. I believe the multiplication by 4 is to account for the load instruction, which 1 cycle = 4 cycles. Basically it tries to keep the deviation between wow/flutter inside a center range. It can adjust the timing in either direction. It can compensate for tapes saved with any commodore computer on any video standard. The PET, VIC20 and C128 all have different timings to a C64 and depending on region. The loader can compensate for all of them. It can change during loading too but only if the loader detects a pair of long pulses, which are also added to each file between each copy of the file and between each file. |
| |
Martin Piper
Registered: Nov 2007 Posts: 645 |
There are some multiplies in there but doesn't seem to be any mean calculation. It just nudges the adjustment to fit the recent measurement. |
| |
Martin Piper
Registered: Nov 2007 Posts: 645 |
The "adjustment code" at $f9d5 reads the accumulated value from $92, if it's zero then it doesn't change the adjustment value.
Otherwise it nudges (+/- 1) the adjustment value at $b0, based on if the value at $92 is positive or negative, and then resets the accumulated value at $92 to zero.
The "adjustment code" is executed every other bit received from the tape by the $f9a4 eor and $f9a8 beq test.
This means the accumulated value in $92 has two "variations between received and expected" timings accumulated into it. |
| |
Fungus
Registered: Sep 2002 Posts: 626 |
OK, then my guesses are correct.
Never thought I would be thanking you, but thanks. |
| |
Oswald
Registered: Apr 2002 Posts: 5026 |
ammazing I have no idea what you are talking about |
| |
Fungus
Registered: Sep 2002 Posts: 626 |
I'll post the document later when I convert it to PDF, I still want to go over it a bit first. It's basically a raw commented disasm with some other info on structure.
I want to work out a flow chart for the code so that I understand it completely first. |
| |
Richard
Registered: Dec 2001 Posts: 619 |
Intriguing :) Are you intending to make a tape turbo yourself? |
| |
Fungus
Registered: Sep 2002 Posts: 626 |
I've made several tape turbos. I've documented dozen of loaders and cracked thousands of tapes (but never released much of them).
I might make a new one that's fast but works somewhat like bleepload and mixed with other stuff that the modern games can use to make the "cracking" scene work a little bit. |