Jump to content

Photo

Anyone have an APX Extended Fig-Forth manual?

apx fig forth manual

26 replies to this topic

#26 Atari_Ace OFFLINE  

Atari_Ace

    Chopper Commander

  • 111 posts
  • https://ksquiggle.neocities.org/
  • Location:Seattle, WA

Posted Mon Mar 12, 2018 10:09 AM

I was curious how this might have happened, so I did some further investigation.
 
DCM works by setting up a 128 byte sector buffer, and then continually modifying it to generate the sectors. Whenever the next sector is similar to the last sector, it can achieve compression.
 
For sector 176, the last sector was all spaces, and this sector has just 3 non-spaces, so the compression is substantial.  In fact, it represents the sector in only 5 bytes.
 
.. .. c1 02 3e 2d 2d .. ..
 
The first byte, c1 = 0x80 | 0x41, means this is a new sector (0x80), and that the first (and in this case only transformation) is to modify the beginning of the sector (0x41). 02 means to start at offset 2 in the buffer, and then copy the next three bytes into the buffer backwards.  So the buffer should be transformed like so:
 
     0  20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20 ...
     0  20 20 3e 20 20 20 20 20-20 20 20 20 20 20 20 20 ...   >
     0  20 2d 3e 20 20 20 20 20-20 20 20 20 20 20 20 20 ...  ->
     0  2d 2d 3e 20 20 20 20 20-20 20 20 20 20 20 20 20 ... -->
 
The code for this might look like (from dcm2atr.c v0.1, circa 1998)
 
case DCM_CHANGE_BEGIN:      /* 0x41 */
    cnt_41++;
    offset = get_byte();
    do                      /* Reverse copy to beginning    */
    {
        sec_buf[offset] = get_byte();
    } while( offset-- );
    PRINT( ("Beginning of sector reached\n") );
    break;
 
Now, how would you write the code so that instead of this happening, you'd end up with the last character repeated throughout the sector. Well, let's look at the code in dcmtoatr.c (v1.4 circa 1995, which I happened to have archived as dcmatr14.tar.gz).
 
void decode_C1(void)
{
    int secoff,tmpoff,c;
    tmpoff=read_offset(fin);
    c=fgetc(fin);
    for (secoff=0; secoff<secsize; secoff++) {
        buf[secoff]=c;
    }
    c=tmpoff;
    for (secoff=0; secoff<tmpoff; secoff++) {
        c--;
        buf[c]=fgetc(fin);
    }
    write_sector(fout);
}
 
This code copies the first byte in the stream to the entire sector, and then copies the remaining bytes backwards into the buffer, so the buffer transforms like so:
 
     0  20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20 ...
     0  3e 3e 3e 3e 3e 3e 3e 3e-3e 3e 3e 3e 3e 3e 3e 3e ... >>>>>>>>>>>>>>>>
     0  3e 2d 3e 3e 3e 3e 3e 3e-3e 3e 3e 3e 3e 3e 3e 3e ... >->>>>>>>>>>>>>>
     0  2d 2d 3e 3e 3e 3e 3e 3e-3e 3e 3e 3e 3e 3e 3e 3e ... -->>>>>>>>>>>>>>
 
Clearly these two routines fundamentally disagree on the meaning of this transformation, and the dcmtoatr version is almost certainly the incorrect interpretation. It's likely this code is the source of these problems, and I suspect it was in active use in the late 1990s, generating the occasional broken ATR file.


#27 MrFish OFFLINE  

MrFish

    River Patroller

  • 4,811 posts
  • Location:1010-1010

Posted Mon Mar 12, 2018 7:39 PM

I've always used Atari800WP to convert DCM and XFD to ATR, but they didn't have the luxury of that option back then.

 

Information like this shows how important all the archiving that's being done between Farb, Atarimania, and elsewhere is so important (aside from the desire to get uncracked versions).






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users