From 732cd85ce55b7e61a958cdd48b8a7e9c7d460656 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Sat, 3 Jan 2009 19:02:13 +0000 Subject: [PATCH] CP/M: added support for Microsoft Softcard "data only" disks. CP/M: correctly identify 3.x disks Updated some copyright notices. --- DIST/with-mdc.deploy | 4 ++-- LICENSE.txt | 2 +- app/CiderPress.rc | 32 ++++++++++++++++---------------- app/Help/CIDERPRESS.HLP | Bin 295476 -> 295476 bytes app/Help/CiderPress.hmp | Bin 329108 -> 329108 bytes app/MyApp.h | 2 +- diskimg/CPM.cpp | 26 +++++++++++++++++++------- diskimg/DiskImg.h | 4 ++-- diskimg/DiskImgDetail.h | 7 +++++-- mdc/mdc.clw | 4 ++-- mdc/mdc.rc | 14 +++++++------- 11 files changed, 55 insertions(+), 40 deletions(-) diff --git a/DIST/with-mdc.deploy b/DIST/with-mdc.deploy index f6fd29d..57193f2 100644 --- a/DIST/with-mdc.deploy +++ b/DIST/with-mdc.deploy @@ -5,9 +5,9 @@ http://www.faddensoft.com/ CiderPress http://ciderpress.sourceforge.net/ 3.0.1 -39815 +39816 C:\DATA\faddenSoft\fs.ico -Copyright © 2009 faddenSoft, LLC. All rights reserved. +Copyright © 2009 CiderPress project authors. All rights reserved. C:\Src\CiderPress\DIST\ReadMe.txt C:\Src\CiderPress\DIST\License.txt diff --git a/LICENSE.txt b/LICENSE.txt index e08f947..e7adc74 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2007, FaddenSoft, LLC +Copyright (c) 2009, CiderPress project authors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/app/CiderPress.rc b/app/CiderPress.rc index 233d568..2378fb7 100644 --- a/app/CiderPress.rc +++ b/app/CiderPress.rc @@ -217,27 +217,27 @@ END // Dialog // -IDD_ABOUTDLG DIALOGEX 0, 0, 212, 154 +IDD_ABOUTDLG DIALOGEX 0, 0, 237, 154 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "About CiderPress" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,7,132,50,14 - PUSHBUTTON "Credits",IDC_ABOUT_CREDITS,63,132,50,14,0,0, + PUSHBUTTON "Credits",IDC_ABOUT_CREDITS,77,132,50,14,0,0, HIDC_ABOUT_CREDITS - PUSHBUTTON "Enter registration code",IDC_ABOUT_ENTER_REG,119,132,86, + PUSHBUTTON "Enter registration code",IDC_ABOUT_ENTER_REG,144,132,86, 14 CONTROL 106,IDC_STATIC,"Static",SS_BITMAP,7,6,64,59 LTEXT "CiderPress v%d.%d.%d%s%s",IDC_CIDERPRESS_VERS_TEXT,77,7, - 128,9 - LTEXT "Copyright © 2009 by FaddenSoft, LLC.\rAll Rights Reserved.", - IDC_STATIC,77,20,128,19 - ICON IDR_MAINFRAME,IDC_STATIC,77,45,20,20 - ICON IDI_FILE_NUFX,IDC_STATIC,106,45,20,20 - ICON IDI_FILE_BINARY2,IDC_STATIC,136,45,20,20 - ICON IDI_FILE_DISKIMAGE,IDC_STATIC,166,45,20,20 - GROUPBOX "Libraries",IDC_STATIC,7,71,198,56 + 153,9 + LTEXT "Copyright © 2009 by CiderPress project authors\rAll Rights Reserved.", + IDC_STATIC,77,20,153,19 + ICON IDR_MAINFRAME,IDC_STATIC,77,45,21,20 + ICON IDI_FILE_NUFX,IDC_STATIC,106,45,21,20 + ICON IDI_FILE_BINARY2,IDC_STATIC,136,45,21,20 + ICON IDI_FILE_DISKIMAGE,IDC_STATIC,166,45,21,20 + GROUPBOX "Libraries",IDC_STATIC,7,71,223,56 LTEXT "Using NufxLib DLL v%d.%d.%d",IDC_NUFXLIB_VERS_TEXT,16, 82,170,10 LTEXT "Using DiskImg DLL v%d.%d.%d",IDC_DISKIMG_VERS_TEXT,16, @@ -1577,16 +1577,16 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "The end is nigh.\0" - VALUE "CompanyName", "FaddenSoft, LLC\0" + VALUE "CompanyName", "CiderPress Project\0" VALUE "FileDescription", "CiderPress\0" - VALUE "FileVersion", "2, 4, 6, 0\0" + VALUE "FileVersion", "3, 0, 1, 0\0" VALUE "InternalName", "CiderPress\0" - VALUE "LegalCopyright", "Copyright © 2007 FaddenSoft, LLC\0" + VALUE "LegalCopyright", "Copyright © 2009 CiderPress project authors\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "CiderPress.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "CiderPress\0" - VALUE "ProductVersion", "2, 4, 6, 0\0" + VALUE "ProductVersion", "3, 0, 1, 0\0" VALUE "SpecialBuild", "\0" END END @@ -1609,7 +1609,7 @@ GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD_ABOUTDLG, DIALOG BEGIN - RIGHTMARGIN, 205 + RIGHTMARGIN, 230 VERTGUIDE, 7 VERTGUIDE, 16 VERTGUIDE, 77 diff --git a/app/Help/CIDERPRESS.HLP b/app/Help/CIDERPRESS.HLP index 206bc16318ae9b60078f91fc46120566ff0b7839..27173d22dad0104611ee0da1dc04a7a1995eb685 100644 GIT binary patch delta 3399 zcmZ8jeN>cH8o&3xb1wtTj0u_pqKqI&g`^#jNTmS;VdP7aAP))%q+5#6s%a+Q3W5Up zsH3s@wWV%W>RyZR1ENR=L`b(nYuk;JwwBh~**tqXN$zuBpg;CK=Xd6Jf4}E>?tSmq zJEv;APStod`)kdA%{>{gb-K?vUqYr+hpy?feXSt|G8uorJ`d?|ldOt3PPww; zu>*@>hBYk@DvlAI5j} z;^?KWil_8T$<_E-H%jVdMS3CQ zQ#>iTD!NR|Fv9W(5!o**N0s;tU9MTJt$u`nlV z;&^i`B{_&R%nC)QVmYuf%fXei9nNI=jo*&!Ys6FN&p@d7ui?;kDb8`N|cxwVB zSLF9gV<~S)q9hV#=H-bi4oa3RfWb{xIG$(ZkqankhqHM(VhOVAx?xs(Y#gE;r6`EY zPZ!sb z48gT!W#T1dfvKYd5kuIlNriKH55ZdnkBPukO5PlH?-dwD4L04=z@zXP@g~wo)AXUJ zne;-qr%_S`jfJWFQDj3fSXgSRQmlG-#v!8!m#pYBjVtxE%=yFnnoy>tUiz*|W&Ct4 zCDC%#>PMKc)KlWsB=?o}F&@2*l1HF)&7jGv30dc8wY6Antwx1X7k27H@xmkeB_(=L zfjqGe&&NWHp9vqX@8$&`QIZYK8v^*uE=nq8>xQXJWFz%)$-#{~D6c$^GOXWJz;FHRSoS&?tM)0ec zAR17+uZNhQ#=7GX*HFrYr4fCh-zvFUUz%5t^x8QOfiK1sR)hK{h)m zSL%Sgyd{qYD{~TFocjIok@xU9y5Tli-!SSPQDz5Z)!Fy}V`MSBT=zIvnq9Wl4KltM z=?`*$!%@oZf{|32ygi4CAKVyO=f2}rU&}sR?DdFLcSgo}%Fi43P_YjA98YwivDwJS zc{03#TADXfF$d{&6B_0goVNvtvnEE$A#TTRaUIzav-0Mku8v)~nUQZmK%_W=%+rFN zvm&1v-M+!*z!>Ii%4b$t18-B|X<@`<#{getAjJTD8y_6lf3T9$f?(+`D^%^eCzP8K zgTb(Gw~+_MFwz9acFz?l$XbOKmIWn?S7;|v$+ z$WH3s9qbRc0NIMlK{;m6Ey_zeR(U=UYA6Z9F0Bjtl zwZe|0Q-rd-x5&1mk_j|OK%IQym^OiXn#B6ZJ!dH|vUl_4109xo)apl+4-C)8g=4588q)$L9m)Xm6u;NKC* zJCTLM{Eh_i9kQGrjEA>7j6A%Dktlh(<0=(7Nb`GDA)F{O2@%!H$YJQ{w2ORXeaZv> z4~_gVwi;#Vhi9nhL;7ByN=n288=|p~k>6lkSDbhcS#ZDdG`wuT!tM4ODiKiAb;%Um zkBn*~lk{;2uEbipWIN5!DYM=m@@ zMKAJDZ8UR}%g7CyhBt1#Ypw`IW)||2YcJ!)$P?xB7iUpn78)sW8%Z(Sap+b=qMJre zKws}{QG)F1sBa0w;TsVrP!;Yn@=^%?pFkewKH6z{pOFi9jrXCi&m~GAi~UpJy7akb~Kg2tSiX4#1(ySz;bC zm-2lr@tEq5IDnGbBBxz>k_s2{2#ao?K&u{MwrF_c$en*XL_wnyeIxYt@FJ+uX$Yl- z+f|zRB&IYVOm>ajkWHVxMMXGL{09{?5WsK5Xk-Jd7+5aMu^Kt3L|^##fRS&&W;5Iy z_+A`D_I{jRi{lRXC)R3?)5y6$dtYPxePmmu^~(#4pNrSXPxAU#1sdO)i0dem2WK(y z(*linRLZ(<&Qnups^TNtCG|!KRNeRoS7L)K`u1hUm3Kvcdoz~thH4Fu^z>Up;>u=? zOs<6)wD#_c6-EJ&PI(`o3!CCRUOWmx=GYCVT3DlH9~#g!x5OS+D>~v z8xQqA&*m!N0QCIqH{k#>(+3(^gkkE-r_!+P{GbOzz3$El7!6Q{3Q&*I=3tc)HqeodltLl3}I0h8bXQnW$k{D}Bl^Fj0kk XQ9NAy`#%~oXzQX9!%FS{WQXN{R4EHA delta 3594 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 PX8ID#BIEz)RL@@l43p2>}Nk kMaxUserNumber) { + /* + * Usually userNumber is 0, but sometimes not. It's expected to + * be < 0x20 for a normal file, may be 0x21 or 0x22 for special + * entries (volume label, date stamps). + */ + if (*dptr > kMaxSpecialUserNumber) { dierr = kDIErrFilesystemNotFound; break; } @@ -70,11 +77,6 @@ TestImage(DiskImg* pImg, DiskImg::SectorOrder imageOrder) dierr = kDIErrFilesystemNotFound; break; } - /* value in S1 must be zero */ - if (dptr[13] != 0) { - dierr = kDIErrFilesystemNotFound; - break; - } /* check for a valid filename here; high bit may be set on some bytes */ unsigned char firstLet = *(dptr+1) & 0x7f; @@ -214,6 +216,11 @@ DiskFSCPM::ReadCatalog(void) if (fDirEntry[i].userNumber == kNoDataByte || fDirEntry[i].extent != 0) continue; + if (fDirEntry[i].userNumber > kMaxUserNumber) { + /* skip over volume label, date stamps, etc */ + WMSG1("Skipping entry with userNumber=0x%02x\n", + fDirEntry[i].userNumber); + } pFile = new A2FileCPM(this, fDirEntry); FormatName(pFile->fFileName, (char*)fDirEntry[i].fileName); @@ -620,8 +627,13 @@ A2FDCPM::Read(void* buf, size_t len, size_t* pActual) /* * Read one CP/M block (two ProDOS blocks) and pull out the * set of data that the user wants. + * + * On some Microsoft Softcard disks, the first three tracks hold + * file data rather than the system image. */ prodosBlock = DiskFSCPM::CPMToProDOSBlock(fBlockList[blkIndex]); + if (prodosBlock >= 280) + prodosBlock -= 280; dierr = fpFile->GetDiskFS()->GetDiskImg()->ReadBlock(prodosBlock, blkBuf); diff --git a/diskimg/DiskImg.h b/diskimg/DiskImg.h index 462a93e..151cc80 100644 --- a/diskimg/DiskImg.h +++ b/diskimg/DiskImg.h @@ -42,8 +42,8 @@ namespace DiskImgLib { /* compiled-against versions; call DiskImg::GetVersion for linked-against */ #define kDiskImgVersionMajor 4 -#define kDiskImgVersionMinor 5 -#define kDiskImgVersionBug 2 +#define kDiskImgVersionMinor 6 +#define kDiskImgVersionBug 0 /* diff --git a/diskimg/DiskImgDetail.h b/diskimg/DiskImgDetail.h index 44d02b7..8e6e336 100644 --- a/diskimg/DiskImgDetail.h +++ b/diskimg/DiskImgDetail.h @@ -2217,7 +2217,7 @@ public: }; // Contents of the raw 32-byte directory entry. // - // From http://www.seasip.demon.co.uk/Cpm/format22.html + // From http://www.seasip.demon.co.uk/Cpm/format31.html // // UU F1 F2 F3 F4 F5 F6 F7 F8 T1 T2 T3 EX S1 S2 RC .FILENAMETYP.... // AL AL AL AL AL AL AL AL AL AL AL AL AL AL AL AL ................ @@ -2225,13 +2225,16 @@ public: // If the high bit of T1 is set, the file is read-only. If the high // bit of T2 is set, the file is a "system" file. // + // An entry with UU=0x20 indicates a CP/M 3.1 disk label entry. + // An entry with UU=0x21 indicates a time stamp entry (2.x or 3.x). + // // Files larger than (1024 * 16) have multiple "extent" entries, i.e. // entries with the same user number and file name. typedef struct DirEntry { unsigned char userNumber; // 0-15 or 0-31 (usually 0), e5=unused unsigned char fileName[kDirFileNameLen+1]; unsigned short extent; // extent (EX + S2 * 32) - unsigned char S1; // reserved, should be zero + unsigned char S1; // Last Record Byte Count (app-specific) unsigned char records; // #of 128-byte records in this extent unsigned char blocks[kDirEntryBlockCount]; bool readOnly; diff --git a/mdc/mdc.clw b/mdc/mdc.clw index a2992f9..aed7367 100644 --- a/mdc/mdc.clw +++ b/mdc/mdc.clw @@ -11,10 +11,10 @@ LastPage=0 ClassCount=2 ResourceCount=4 -Resource1=IDC_MDC +Resource1=IDD_ABOUTBOX Class1=AboutDlg Resource2="IDD_CHOOSE_FILES" -Resource3=IDD_ABOUTBOX +Resource3=IDC_MDC Class2=ProgressDlg Resource4=IDD_PROGRESS diff --git a/mdc/mdc.rc b/mdc/mdc.rc index 8cc523c..c8946c5 100644 --- a/mdc/mdc.rc +++ b/mdc/mdc.rc @@ -70,19 +70,19 @@ END // Dialog // -IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 133, 111 +IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 156, 111 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU CAPTION "About" FONT 10, "MS Sans Serif" BEGIN ICON IDI_MDC,IDC_MYICON,7,7,20,20 - LTEXT "MDC version %d.%d.%d",IDC_ABOUT_VERS,33,7,93,8, + LTEXT "MDC version %d.%d.%d",IDC_ABOUT_VERS,33,7,116,8, SS_NOPREFIX - LTEXT "Copyright © 2007 by FaddenSoft, LLC.\rAll Rights Reserved.", - IDC_STATIC,7,31,119,19 - DEFPUSHBUTTON "OK",IDOK,41,90,50,14 + LTEXT "Copyright © 2009 by CiderPress project authors.\rAll Rights Reserved.", + IDC_STATIC,7,31,142,19 + DEFPUSHBUTTON "OK",IDOK,53,90,50,14 LTEXT "This utility scans Apple II disk images and creates formatted listings of the files in them.", - IDC_STATIC,7,58,119,26 + IDC_STATIC,7,58,142,26 LTEXT "Multi-Disk Catalog",IDC_STATIC,33,15,55,8 END @@ -148,7 +148,7 @@ BEGIN IDD_ABOUTBOX, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 126 + RIGHTMARGIN, 149 VERTGUIDE, 33 TOPMARGIN, 7 BOTTOMMARGIN, 104