Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include "emul.h"
  4. #include "vars.h"
  5. #include "fdd.h"
  6. #include "upd765.h"
  7.  
  8. //=============================================================================
  9.  
  10. #if 0
  11. #define dprintf printf
  12. #else
  13. #define dprintf(...)
  14. #endif
  15.  
  16. //=============================================================================
  17.  
  18. #pragma pack(push, 1)
  19.  
  20. //=============================================================================
  21. union TDiskInfo
  22. {
  23.     struct
  24.     {
  25.         char Sig[34];
  26.         char Name[14];
  27.         u8 c;
  28.         u8 h;
  29.         u16 TrackSize; // ╥юы№ъю фы  dsk (эх фы  edsk)
  30.         u8 TrackOffsets[]; // c * h, ╥юы№ъю фы  edsk
  31.     };
  32.     u8 Raw[256];
  33. };
  34. //=============================================================================
  35.  
  36. #ifndef __ICL // icl 19 яюф win эх шьххЄ __builtin_offsetof
  37. static_assert(offsetof(TDiskInfo, TrackOffsets) == 0x34);
  38. //static_assert(offsetof(TDiskInfo, TrackOffsets) == 0x34,"");  NEDOREPO
  39. #endif
  40.  
  41. //=============================================================================
  42. struct TSecInfo
  43. {
  44.     u8 c;
  45.     u8 h;
  46.     u8 r;
  47.     u8 n; // sector size code
  48.     u8 St1;
  49.     u8 St2;
  50.     u16 DataLen; // ╥юы№ъю фы  edsk
  51. };
  52. //=============================================================================
  53. union  TTrackInfo
  54. {
  55.     struct
  56.     {
  57.         char Sig[13];
  58.         char Reserved[3];
  59.         u8 c;
  60.         u8 h;
  61.         char Reserved2[2];
  62.         u8 n; // sector size code
  63.         u8 NumSec;
  64.         u8 Gap3Len;
  65.         u8 Filler;
  66.         TSecInfo SecInfoList[];
  67.     };
  68.     u8 Raw[256];
  69. };
  70. //=============================================================================
  71.  
  72. #pragma pack(pop)
  73.  
  74. //=============================================================================
  75. int FDD::read_dsk()
  76. {
  77.     dprintf("read_dsk\n");
  78.  
  79.     const auto DiskInfo{ (const TDiskInfo *)snbuf };
  80.  
  81.     auto IsExtended{ memcmp(DiskInfo->Sig, "EXTENDED", 8) == 0};
  82.     if(!IsExtended && memcmp(DiskInfo->Sig, "MV - CPC", 8) != 0)
  83.     {
  84.         return 0;
  85.     }
  86.  
  87.     newdisk(DiskInfo->c, DiskInfo->h);
  88.  
  89.     unsigned Offset{ sizeof(TDiskInfo) };
  90.     for(unsigned c = 0; c < DiskInfo->c; c++)
  91.     {
  92.         for(unsigned h = 0; h < DiskInfo->h; h++)
  93.         {
  94.             auto TrkSize{ IsExtended ? unsigned(DiskInfo->TrackOffsets[c*DiskInfo->h + h] << 8U) : DiskInfo->TrackSize };
  95.             if(TrkSize == 0)
  96.             {
  97.                 continue;
  98.             }
  99.             t.seek(this, c, h, JUST_SEEK);
  100.  
  101.             const auto TrackInfo{ (const TTrackInfo *)(snbuf + Offset) };
  102.             const auto SecDataStart{ snbuf + Offset + sizeof(TTrackInfo) };
  103.             auto SecData{ SecDataStart };
  104.             u8* PrevSecData{ };
  105.  
  106.             bool IsOverlappedSec = false; // Capitan Blood, License to kill
  107.             if(IsExtended)
  108.             {
  109.                 IsOverlappedSec = true;
  110.                 constexpr unsigned SecLen[]{ 128, 256, 512, 1024, 2048, 4096, 6144 };
  111.                 for(unsigned s = 0; s < min(size_t(TrackInfo->NumSec), _countof(SecLen)); s++)
  112.                 {
  113.                     const auto &SecInfo{ TrackInfo->SecInfoList[s] };
  114.                     if(SecLen[s] != SecInfo.DataLen)
  115.                     {
  116.                         IsOverlappedSec = false;
  117.                         break;
  118.                     }
  119.                 }
  120.             }
  121.  
  122.             for(unsigned s = 0; s < TrackInfo->NumSec; s++)
  123.             {
  124.                 const auto &SecInfo{ TrackInfo->SecInfoList[s] };
  125.                 auto SecInfoDataLen{ SecInfo.DataLen };
  126.                 t.hdr[s].c = SecInfo.c;
  127.                 t.hdr[s].s = SecInfo.h;
  128.                 t.hdr[s].n = SecInfo.r;
  129.                 t.hdr[s].l = SecInfo.n;
  130.                 t.hdr[s].c1 = 0;
  131.                 t.hdr[s].c2 = 0;
  132.                 t.hdr[s].wp = nullptr;
  133.                 t.hdr[s].data = SecData;
  134.  
  135.  
  136.                 t.hdr[s].datlen = IsExtended ? SecInfoDataLen : 128U << SecInfo.n;
  137.                 if(t.hdr[s].datlen == 0)
  138.                 {
  139.                     t.hdr[s].data = nullptr;
  140.                 }
  141.  
  142.                 // ╟р∙шЄ√ Єшяр ъръ т golden axe (яхЁт√щ ёхъЄюЁ эр ЄЁ¤ъх (ъюф 6, ЁрчьхЁ 8192)
  143.                 // яЁхт√°рхЄ ЁрчьхЁ ЄЁ¤ър, фры№°х шфєЄ юс√э√х ёхъЄюЁр)
  144.                 // ▌ЄюЄ яхЁт√щ ёхъЄюЁ ёюфхЁцшЄ яюыэє■ шэЇюЁьрЎш■ ю тёхщ фюЁюцъх (юёЄры№э√х ёхъЄюЁр ёЇюЁьшЁютрэ√ т чюэх фрээ√ї ¤Єюую ёхъЄюЁр)
  145.                 // ╥ръє■ фюЁюцъє эрфю ёЁрчє чруЁєцрЄ№ т udi ЇюЁьрЄх тюёёЄрэютшт ёшэїЁюшьяєы№ё√ яю срщЄрь A1A1A1 FE/FB
  146.                 // └ шэЇюЁьрЎш■ ю Ёрёъырфъх ш ЁрчьхЁрї ёхъЄюЁют тч Є№ шч юяшёрэш  т dsk (Єрь тё  шэЇюЁьрЎш  яЁюфєсышЁютрэр яю 2 Ёрчр)
  147.                 // ╤эрўрыр т сюы№°юь ёхъЄюЁх, р яюЄюь т ьрыхэ№ъшї ёхъЄюЁрї (ъюЄюЁ√х ЇръЄшўхёъш  ты ■Єё  ёё√ыърьш эр ъєёъш сюы№°юую)
  148. /*
  149.                 // ╩Ёштю ёэ Є√х юсЁрч√ ё чр∙шЄющ юЄ opera soft (эряЁшьхЁ mot)
  150.                 // ╧Ёртшы№эю ёэ Є√щ юсЁрч (corsarios + mutant zone)
  151.                 if(IsExtended && c == 40 && SecInfo.n == 8 && SecInfoDataLen == 0)
  152.                 {
  153.                     const auto &SecInfo{ TrackInfo->SecInfoList[s-1] };
  154.                     auto SecInfoDataLen{ SecInfo.DataLen };
  155.                     t.hdr[s].data = PrevSecData - 0x512;
  156.                     t.hdr[s].datlen = IsExtended ? SecInfoDataLen : 128U << SecInfo.n;
  157.                 }
  158. */
  159.                 if((SecInfo.St1 & TUpd765::ST1_DE)) // crc error in address or data
  160.                 {
  161.                     if((SecInfo.St2 & TUpd765::ST2_DD)) // crc error in data
  162.                     {
  163.                         t.hdr[s].c2 = 2;
  164.                         if(IsOverlappedSec)
  165.                         {
  166.                             t.hdr[s].data = nullptr;
  167.                         }
  168.                     }
  169.                     else
  170.                     {
  171.                         t.hdr[s].c1 = 2; // crc error in address
  172. //                    t.hdr[s].data = nullptr;
  173.                     }
  174.                 }
  175.  
  176.                 if(SecInfo.St2 & TUpd765::ST2_CM)
  177.                 {
  178.                     t.hdr[s].Flags = SECHDR::FL_DDAM;
  179.                 }
  180.                 else
  181.                 {
  182.                     t.hdr[s].Flags = 0;
  183.                 }
  184.                 PrevSecData = SecData;
  185.                 SecData += IsExtended ? SecInfoDataLen : 128U << SecInfo.n;
  186.             }
  187.             t.s = TrackInfo->NumSec;
  188.             t.format();
  189.             Offset += TrkSize;
  190.         }
  191.     }
  192.     return 1;
  193. }
  194. //=============================================================================
  195.