@@ -125,16 +125,19 @@ TfrmMain = class(TForm)
125
125
function AddTree (Parent: TTreeNode; Text: string; ImageIdx: integer; NodeObject: TObject): TTreeNode;
126
126
function AddListInfo (Key: string; Value : string): TListItem;
127
127
function AddListTrack (Track: TDSKTrack; ShowModulation: boolean; ShowDataRate: boolean): TListItem;
128
- function AddListSector (Sector: TDSKSector): TListItem;
128
+ function AddListSector (Sector: TDSKSector; ShowCopies: boolean ): TListItem;
129
129
function AddListSides (Side: TDSKSide): TListItem;
130
- procedure SetListSimple ;
131
130
function GetSelectedSector (Sender: TObject): TDSKSector;
132
131
function GetTitle (Data: TTreeNode): string;
133
132
function GetCurrentImage : TDSKImage;
134
133
function IsDiskNode (Node: TTreeNode): boolean;
135
134
function AddColumn (Caption: string): TListColumn;
136
135
function AddColumns (Captions: array of string): TListColumnArray;
137
136
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 ;
138
141
procedure OnApplicationDropFiles (Sender: TObject; const FileNames: array of string);
139
142
procedure UpdateRecentFilesMenu ;
140
143
public
@@ -587,19 +590,30 @@ procedure TfrmMain.RefreshListMessages(Messages: TStringList);
587
590
procedure TfrmMain.RefreshListImage (Image: TDSKImage);
588
591
var
589
592
SIdx: integer;
590
- ImageFormat, Protection: string;
593
+ Side: TDSKSide;
594
+ ImageFormat, Protection, Features: string;
591
595
begin
592
596
SetListSimple;
593
597
if Image <> nil then
594
598
with Image do
595
599
begin
596
600
AddListInfo(' Creator' , Creator);
597
- ImageFormat := DSKImageFormats[FileFormat];
598
601
602
+ ImageFormat := DSKImageFormats[FileFormat];
599
603
if Image.HasV5Extensions then ImageFormat := ImageFormat + ' v5' ;
600
604
if Corrupt then ImageFormat := ImageFormat + ' (Corrupt)' ;
601
-
602
605
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
+
603
617
AddListInfo(' Sides' , StrInt(Disk.Sides));
604
618
if Disk.Sides > 0 then
605
619
begin
@@ -770,17 +784,21 @@ procedure TfrmMain.RefreshListSector(Track: TDSKTrack);
770
784
lvwMain.PopupMenu := popSector;
771
785
772
786
AddColumns([' Sector' , ' Track' , ' Side' , ' ID' , ' FDC size' , ' FDC flags' , ' Data size' ]);
787
+
788
+ if Track.HasMultiSectoredSector then
789
+ AddColumn(' Copies' );
790
+
773
791
with lvwMain.Columns.Add do
774
792
begin
775
793
Caption := ' Status' ;
776
794
AutoSize := True;
777
795
end ;
778
796
779
797
for Sector in Track.Sector do
780
- AddListSector(Sector);
798
+ AddListSector(Sector, Track.HasMultiSectoredSector );
781
799
end ;
782
800
783
- function TfrmMain.AddListSector (Sector: TDSKSector): TListItem;
801
+ function TfrmMain.AddListSector (Sector: TDSKSector; ShowCopies: boolean ): TListItem;
784
802
var
785
803
NewListItem: TListItem;
786
804
begin
@@ -789,28 +807,32 @@ function TfrmMain.AddListSector(Sector: TDSKSector): TListItem;
789
807
begin
790
808
Caption := StrInt(Sector.Sector);
791
809
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 ;
802
825
end ;
803
826
Result := NewListItem;
804
827
end ;
805
828
806
829
procedure TfrmMain.RefreshListSectorData (Sector: TDSKSector);
807
830
var
808
- Idx, LastIdx : integer;
831
+ Idx, RowOffset, Offset, TrueSectorSize, VariantNumber : integer;
809
832
Raw: byte;
810
- SecData, SecHex, NextChar: string;
833
+ HasVariants: boolean;
834
+ RowData, RowHex: string;
811
835
begin
812
- SecData := ' ' ;
813
- SecHex := ' ' ;
814
836
lvwMain.Font := Settings.SectorFont;
815
837
816
838
with lvwMain.Columns do
@@ -835,44 +857,80 @@ procedure TfrmMain.RefreshListSectorData(Sector: TDSKSector);
835
857
end ;
836
858
end ;
837
859
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
+
838
870
for Idx := 0 to Sector.DataSize - 1 do
839
871
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
842
874
with lvwMain.Items.Add do
843
875
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));
847
878
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 := ' ' ;
851
887
end ;
852
888
889
+ // Gather up the data for the next line we'll write
853
890
Raw := Sector.Data[Idx];
891
+ RowData := RowData + MapByte(Raw);
892
+ RowHex := RowHex + StrHex(Raw) + ' ' ;
893
+ Inc(Offset);
854
894
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 ;
860
905
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 ;
865
920
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;
867
927
end ;
868
928
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);
876
934
end ;
877
935
878
936
// Menu: Help > About
@@ -1130,7 +1188,7 @@ procedure TfrmMain.SaveImageAs(Image: TDSKImage; Copy: boolean; NewName: string)
1130
1188
begin
1131
1189
AbandonSave := False;
1132
1190
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. ' +
1134
1192
' Save anyway and lose this information?' , mtWarning, [mbYes, mbNo], 0 ) <> mrOk) then
1135
1193
AbandonSave := True;
1136
1194
0 commit comments