@@ -125,16 +125,19 @@ TfrmMain = class(TForm)
125125 function AddTree (Parent: TTreeNode; Text: string; ImageIdx: integer; NodeObject: TObject): TTreeNode;
126126 function AddListInfo (Key: string; Value : string): TListItem;
127127 function AddListTrack (Track: TDSKTrack; ShowModulation: boolean; ShowDataRate: boolean): TListItem;
128- function AddListSector (Sector: TDSKSector): TListItem;
128+ function AddListSector (Sector: TDSKSector; ShowCopies: boolean ): TListItem;
129129 function AddListSides (Side: TDSKSide): TListItem;
130- procedure SetListSimple ;
131130 function GetSelectedSector (Sender: TObject): TDSKSector;
132131 function GetTitle (Data: TTreeNode): string;
133132 function GetCurrentImage : TDSKImage;
134133 function IsDiskNode (Node: TTreeNode): boolean;
135134 function AddColumn (Caption: string): TListColumn;
136135 function AddColumns (Captions: array of string): TListColumnArray;
137136 function FindTreeNodeFromData (Node: TTreeNode; Data: TObject): TTreeNode;
137+ function MapByte (Raw: byte): string;
138+
139+ procedure WriteSectorLine (Offset: integer; SecHex: string; SecData: string);
140+ procedure SetListSimple ;
138141 procedure OnApplicationDropFiles (Sender: TObject; const FileNames: array of string);
139142 procedure UpdateRecentFilesMenu ;
140143 public
@@ -587,19 +590,30 @@ procedure TfrmMain.RefreshListMessages(Messages: TStringList);
587590procedure TfrmMain.RefreshListImage (Image: TDSKImage);
588591var
589592 SIdx: integer;
590- ImageFormat, Protection: string;
593+ Side: TDSKSide;
594+ ImageFormat, Protection, Features: string;
591595begin
592596 SetListSimple;
593597 if Image <> nil then
594598 with Image do
595599 begin
596600 AddListInfo(' Creator' , Creator);
597- ImageFormat := DSKImageFormats[FileFormat];
598601
602+ ImageFormat := DSKImageFormats[FileFormat];
599603 if Image.HasV5Extensions then ImageFormat := ImageFormat + ' v5' ;
600604 if Corrupt then ImageFormat := ImageFormat + ' (Corrupt)' ;
601-
602605 AddListInfo(' Image Format' , ImageFormat);
606+
607+ Features := ' ' ;
608+ for Side in Image.Disk.Side do
609+ begin
610+ if Side.HasDataRate then Features := Features + ' Data Rate, ' ;
611+ if Side.HasRecordingMode then Features := Features + ' Recording Mode, ' ;
612+ if Side.HasVariantSectors then Features := Features + ' Variant Sectors, ' ;
613+ end ;
614+ if not Features.IsEmpty then
615+ AddListInfo(' V5 features' , Features.Substring(0 , Features.Length - 2 ));
616+
603617 AddListInfo(' Sides' , StrInt(Disk.Sides));
604618 if Disk.Sides > 0 then
605619 begin
@@ -770,17 +784,21 @@ procedure TfrmMain.RefreshListSector(Track: TDSKTrack);
770784 lvwMain.PopupMenu := popSector;
771785
772786 AddColumns([' Sector' , ' Track' , ' Side' , ' ID' , ' FDC size' , ' FDC flags' , ' Data size' ]);
787+
788+ if Track.HasMultiSectoredSector then
789+ AddColumn(' Copies' );
790+
773791 with lvwMain.Columns.Add do
774792 begin
775793 Caption := ' Status' ;
776794 AutoSize := True;
777795 end ;
778796
779797 for Sector in Track.Sector do
780- AddListSector(Sector);
798+ AddListSector(Sector, Track.HasMultiSectoredSector );
781799end ;
782800
783- function TfrmMain.AddListSector (Sector: TDSKSector): TListItem;
801+ function TfrmMain.AddListSector (Sector: TDSKSector; ShowCopies: boolean ): TListItem;
784802var
785803 NewListItem: TListItem;
786804begin
@@ -789,28 +807,32 @@ function TfrmMain.AddListSector(Sector: TDSKSector): TListItem;
789807 begin
790808 Caption := StrInt(Sector.Sector);
791809 Data := Sector;
792- SubItems.Add(StrInt(Sector.Track));
793- SubItems.Add(StrInt(Sector.Side));
794- SubItems.Add(StrInt(Sector.ID));
795- SubItems.Add(StrInt(Sector.FDCSize));
796- SubItems.Add(Format(' %d, %d' , [Sector.FDCStatus[1 ], Sector.FDCStatus[2 ]]));
797- if (Sector.DataSize <> Sector.AdvertisedSize) then
798- SubItems.Add(Format(' %d (%d)' , [Sector.DataSize, Sector.AdvertisedSize]))
799- else
800- SubItems.Add(StrInt(Sector.DataSize));
801- SubItems.Add(DSKSectorStatus[Sector.Status]);
810+ with SubItems do
811+ begin
812+ Add(StrInt(Sector.Track));
813+ Add(StrInt(Sector.Side));
814+ Add(StrInt(Sector.ID));
815+ Add(Format(' %d (%d)' , [Sector.FDCSize, FDCSectorSizes[Sector.FDCSize]]));
816+ Add(Format(' %d, %d' , [Sector.FDCStatus[1 ], Sector.FDCStatus[2 ]]));
817+ if (Sector.DataSize <> Sector.AdvertisedSize) then
818+ Add(Format(' %d (%d)' , [Sector.DataSize, Sector.AdvertisedSize]))
819+ else
820+ Add(StrInt(Sector.DataSize));
821+ if ShowCopies then
822+ Add(StrInt(Sector.GetCopyCount));
823+ Add(DSKSectorStatus[Sector.Status]);
824+ end ;
802825 end ;
803826 Result := NewListItem;
804827end ;
805828
806829procedure TfrmMain.RefreshListSectorData (Sector: TDSKSector);
807830var
808- Idx, LastIdx : integer;
831+ Idx, RowOffset, Offset, TrueSectorSize, VariantNumber : integer;
809832 Raw: byte;
810- SecData, SecHex, NextChar: string;
833+ HasVariants: boolean;
834+ RowData, RowHex: string;
811835begin
812- SecData := ' ' ;
813- SecHex := ' ' ;
814836 lvwMain.Font := Settings.SectorFont;
815837
816838 with lvwMain.Columns do
@@ -835,44 +857,80 @@ procedure TfrmMain.RefreshListSectorData(Sector: TDSKSector);
835857 end ;
836858 end ;
837859
860+ RowOffset := 0 ;
861+ RowData := ' ' ;
862+ RowHex := ' ' ;
863+
864+ HasVariants := Sector.GetCopyCount > 1 ;
865+ TrueSectorSize := FDCSectorSizes[Sector.FDCSize];
866+ VariantNumber := 0 ;
867+
868+ Offset := 0 ;
869+
838870 for Idx := 0 to Sector.DataSize - 1 do
839871 begin
840- if (Idx mod Settings.BytesPerLine = 0 ) and (Idx > 0 ) then
841- begin
872+ // If we're starting a new sector variant label it
873+ if HasVariants and (Idx mod TrueSectorSize = 0 ) then
842874 with lvwMain.Items.Add do
843875 begin
844- Caption := StrInt(Idx - Settings.BytesPerLine);
845- Subitems.Add(SecHex);
846- Subitems.Add(SecData);
876+ Inc(VariantNumber);
877+ Subitems.Add(' Sector variant #' + IntToStr(VariantNumber));
847878 end ;
848- SecData := ' ' ;
849- SecHex := ' ' ;
850- LastIdx := Idx;
879+
880+ // Emit a new line every X bytes depending on setting
881+ if (Offset mod Settings.BytesPerLine = 0 ) and (Offset > 0 ) then
882+ begin
883+ WriteSectorLine(RowOffset, RowHex, RowData);
884+ RowOffset := Offset;
885+ RowData := ' ' ;
886+ RowHex := ' ' ;
851887 end ;
852888
889+ // Gather up the data for the next line we'll write
853890 Raw := Sector.Data[Idx];
891+ RowData := RowData + MapByte(Raw);
892+ RowHex := RowHex + StrHex(Raw) + ' ' ;
893+ Inc(Offset);
854894
855- NextChar := Chr(Raw);
856- if (Settings.Mapping = ' None' ) and (Raw > 127 ) then NextChar := Settings.UnknownASCII;
857- if (Settings.Mapping = ' 437' ) then NextChar := CP437ToUTF8(NextChar);
858- if (Settings.Mapping = ' 850' ) then NextChar := CP850ToUTF8(NextChar);
859- if (Settings.Mapping = ' 1252' ) then NextChar := CP1252ToUTF8(NextChar);
895+ // Flush and reset the offset for every variant sector
896+ if HasVariants and (Offset = TrueSectorSize) then
897+ begin
898+ WriteSectorLine(RowOffset, RowHex, RowData);
899+ RowOffset := 0 ;
900+ RowData := ' ' ;
901+ RowHex := ' ' ;
902+ Offset := 0 ;
903+ end ;
904+ end ;
860905
861- if Raw <= 31 then
862- SecData := SecData + Settings.UnknownASCII
863- else
864- SecData := SecData + NextChar;
906+ // Flush any leftover gathered data
907+ if RowData <> ' ' then
908+ WriteSectorLine(RowOffset, RowHex, RowData);
909+ end ;
910+
911+ procedure TfrmMain.WriteSectorLine (Offset: integer; SecHex: string; SecData: string);
912+ begin
913+ with lvwMain.Items.Add do
914+ begin
915+ Caption := StrInt(Offset);
916+ Subitems.Add(SecHex);
917+ Subitems.Add(SecData);
918+ end ;
919+ end ;
865920
866- SecHex := SecHex + StrHex(Raw) + ' ' ;
921+ function TfrmMain.MapByte (Raw: byte): string;
922+ begin
923+ if Raw <= 31 then
924+ begin
925+ Result := Settings.UnknownASCII;
926+ exit;
867927 end ;
868928
869- if SecData <> ' ' then
870- with lvwMain.Items.Add do
871- begin
872- Caption := StrInt(LastIdx);
873- Subitems.Add(SecHex);
874- Subitems.Add(SecData);
875- end ;
929+ Result := Chr(Raw);
930+ if (Settings.Mapping = ' None' ) and (Raw > 127 ) then Result := Settings.UnknownASCII;
931+ if (Settings.Mapping = ' 437' ) then Result := CP437ToUTF8(Result);
932+ if (Settings.Mapping = ' 850' ) then Result := CP850ToUTF8(Result);
933+ if (Settings.Mapping = ' 1252' ) then Result := CP1252ToUTF8(Result);
876934end ;
877935
878936// Menu: Help > About
@@ -1130,7 +1188,7 @@ procedure TfrmMain.SaveImageAs(Image: TDSKImage; Copy: boolean; NewName: string)
11301188 begin
11311189 AbandonSave := False;
11321190 if Image.HasV5Extensions and (MessageDlg(
1133- ' This image has modulation or data rate info that "Standard DSK format" does not support. ' +
1191+ ' This image has modulation, data rate that "Standard DSK format" does not support. ' +
11341192 ' Save anyway and lose this information?' , mtWarning, [mbYes, mbNo], 0 ) <> mrOk) then
11351193 AbandonSave := True;
11361194
0 commit comments