Compare commits

...

8 Commits

Author SHA1 Message Date
Marcio T 4793ffc0d8 Adopt standard GPL header. 2022-03-08 06:57:14 -07:00
Marcio T b6fa1cad7a Updated README 2022-03-06 17:41:39 -07:00
Marcio T 7d96b63ef0
Update README.md 2022-02-13 18:04:13 -07:00
Marcio T c719c8d7dd Major enhancements for Jaz drives
- Added command to spin down cartridges to command line
- Improved console diagnostics
  - Report SCSI short reads
  - Report last error
  - Report media change
  - Report disk at speed
  - Report spare sectors
  - Report detailed testing steps
- Supress unsuported commands on Jaz drive while:
  - Enabling early recovery
  - Reading defects list
- Fix short reads on Jaz drives during:
  - Cartridge status
  - Set error recovery
2022-02-13 17:34:14 -07:00
Marcio T dcfa0958a6 Added link to Steve Gibson's video. 2021-12-09 10:03:59 -07:00
Marcio T bfa9014432
Update README.md 2021-12-07 20:35:46 -07:00
Marcio T 6b36dfdc0e
Update README.md 2021-12-07 20:31:13 -07:00
Marcio T 49ce1bc093 Bug fixes; added YouTube image. 2021-12-07 20:24:17 -07:00
16 changed files with 260 additions and 80 deletions

View File

@ -8,6 +8,15 @@ This is the repository for a Macintosh port of [Gibson Research Corp]'s
Jaz Drives. A big thanks goes to Steve Gibson for the x86 source that
made this project possible!
[![Trouble in Paradise Demonstration](https://github.com/marciot/mac-tip/raw/main/images/youtube.png)](https://youtu.be/vtBlOaG2pNw)
:tv: See a demo on [YouTube]!
[![Mention in Steve Gibson's Security Now Podcast](https://github.com/marciot/mac-tip/raw/main/images/security-now.png)](https://twit.tv/shows/security-now/episodes/845)
:tv: Watch Steve Gibson react to my unusual request in the November 16th
episode of the "Security Now" podcast at the 1:05:10 mark.
Compatibility
-------------
@ -20,17 +29,19 @@ Power Macintosh G3, released in 1997.
It has been tested in on the following environments:
| Computer | Memory | System | Drive | Firmware |
|------------------- |--------|--------|-------------------------|----------|
| Macintosh Plus | 4MB | 7.0.1 | Zip Plus 100 Ext. SCSI | J.66 |
| PowerBook 3400c | 144MB | 8.6 | Zip 100 Ext. SCSI | E.08 |
| Power Macintosh G3 | 256MB | 9.2.1 | Zip 100 Ext. SCSI | C.22 |
| Power Macintosh G3 | 256MB | 9.2.1 | Zip 100 Int. SCSI | J.03 |
| Computer | Memory | System | Drive | Firmware |
|------------------- |--------|--------|-------------------------------------|----------|
| Macintosh Plus | 4MB | 7.0.1 | Zip Plus 100 Ext. SCSI | J.66 |
| PowerBook 3400c | 144MB | 8.6 | Zip 100 Ext. SCSI | E.08 |
| PowerBook 3400c | 144MB | 8.6 | Jaz 2GB Ext. SCSI w/ 1GB media | E.17 |
| PowerBook 3400c | 144MB | 8.6 | Jaz 2GB Ext. SCSI w/ 2GB media | E.17 |
| Power Macintosh G3 | 256MB | 9.2.1 | Zip 100 Ext. SCSI | C.22 |
| Power Macintosh G3 | 256MB | 9.2.1 | Zip 100 Int. SCSI | J.03 |
What will not work or is missing:
* USB connected Zip drives have been reported to not work.
* The functionality for operating with password or write protected disks is missing.
* The functionality for operating with password or write protected disks has not been ported.
* The partition recovery feature has been removed, since it is meant for PC disks.
</details>
@ -47,13 +58,9 @@ port.**
Where are the binaries?
-----------------------
Once they are ready, compiled binaries will be made available on the
releases page for people who have signed up for
Compiled binaries are available on the releases page for people who have signed up for
[beta testing in the discussion forum]
There is always a risk of data loss with a tool like this, so please
use it only on non-critical data if you decide to beta test.
How can you help?
-----------------
@ -61,8 +68,14 @@ You can help this project in one of the following ways:
* Star this project on GitHub to show your support!
* Sign up to [beta testing in the discussion forum]!
* Donate a 1 or 2GB Jaz cartridge for testing (I have a 2GB SCSI Jaz drive, but no cartridges!).
* Become a GitHub sponsor to help fund my work with this and other open-source projects!
* Become a GitHub sponsor to help fund my various open-source projects!
Other Vintage Macintosh Stuff
-----------------------------
* [MiniVNC]: A remote desktop server for vintage Macintoshes!
* [ScreenChooser]: A dynamic background changer for vintage Macintoshes!
* [Retroweb Vintage Computer Museum]: A web-based museum of vintage computers, including the Macintosh!
Got work?
---------
@ -82,7 +95,8 @@ Then, insert the cartridge at the testing screen which indicates "Awaiting media
will recognize it if Mac OS mounts newly inserted cartridge and will give you the choice to
unmount it.
Alternatively, you can use the command line to unmount a disk **prior to** starting TIP.
Alternatively, you can use the command line from the "Advanced" menu to unmount a disk
**prior to** starting a test.
<details>
<summary>Click here to learn how to use the command line</summary></br>
@ -141,6 +155,7 @@ Credits
* Thank you to [Stone Table Software] for providing the tool I used to convert the Windows RTF docs into SimpleText...
* ...and to the Internet Archive's Wayback Machine for allowing me to access it long after the website was shut down!
* Thank you to Thomas Tempelmann sharing his [LaunchLib code] which I used to open the documents
* Thank you to Grant Hutchinson and Nikola Biscan for sending me 1GB and 2GB Jaz cartridges for testing.
The Original TIP For Windows
----------------------------
@ -174,3 +189,9 @@ his code in this repository with his permission.
[beta testing in the discussion forum]: https://github.com/marciot/mac-tip/discussions/1
[LaunchLib code]: http://www.tempel.org/macdev/index.html#Libs
[Stone Table Software]: https://web.archive.org/web/20010308062807/http://www.stonetablesoftware.com/rtf2text.html
[ScreenChooser]: https://archive.org/details/screen-chooser
[YouTube]: https://youtu.be/vtBlOaG2pNw
[Retroweb Vintage Computer Museum]: http://retroweb.maclab.org
[MiniVNC]: https://github.com/marciot/mac-minivnc

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

BIN
images/security-now.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 KiB

BIN
images/youtube.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 KiB

View File

@ -14,7 +14,8 @@ void mac_list_volumes() {
for (;;) {
OSErr err = PBHGetVInfo(&paramBlock, false);
if (err == nsvErr) break;
printf(" %d: %#s\n", paramBlock.volumeParam.ioVolIndex, paramBlock.volumeParam.ioNamePtr);
size_t size = paramBlock.volumeParam.ioVAlBlkSiz * paramBlock.volumeParam.ioVNmAlBlks;
printf("%4d: [%7.2f MBs] %#s\n", paramBlock.volumeParam.ioVolIndex, float(size)/1024/1024, paramBlock.volumeParam.ioNamePtr);
paramBlock.volumeParam.ioVolIndex++;
}
}
@ -23,7 +24,7 @@ OSErr mac_get_drive_volumes(int driveNum, Str255 str) {
HParamBlockRec paramBlock;
Str255 volName;
Boolean first = true;
str[0] = '\0';
paramBlock.volumeParam.ioCompletion = 0;
paramBlock.volumeParam.ioNamePtr = volName;
paramBlock.volumeParam.ioVRefNum = 0;
@ -65,6 +66,38 @@ OSErr mac_unmount_drive(int driveNum) {
}
}
OSErr mac_mount_drive(int driveNum) {
ParamBlockRec paramBlock;
paramBlock.volumeParam.ioVRefNum = driveNum;
OSErr err = PBMountVol(&paramBlock);
return err;
}
OSErr mac_mount_drives() {
const QHdrPtr qh = GetDrvQHdr();
for(DrvQElPtr qe = (DrvQElPtr) qh->qHead; qe; qe = (DrvQElPtr) qe->qLink) {
OSErr err = mac_mount_drive(qe->dQDrive);
switch(err) {
case volOnLinErr: continue;
default: printf("Error %d while mounting drive %d\n", err, qe->dQDrive);
}
}
return noErr;
}
OSErr mac_list_drives() {
Str255 volumeNames;
const QHdrPtr qh = GetDrvQHdr();
for(DrvQElPtr qe = (DrvQElPtr) qh->qHead; qe; qe = (DrvQElPtr) qe->qLink) {
size_t size = size_t(qe->dQDrvSz) | ((qe->qType == 1) ? size_t(qe->dQDrvSz2) << 16 : 0) ;
mac_get_drive_volumes(qe->dQDrive, volumeNames);
printf("%4d: [%7.2f MBs] %#s\n", qe->dQDrive, float(size)/2/1024, volumeNames);
}
return noErr;
}
void mac_unmount(int id) {
HParamBlockRec paramBlock;
paramBlock.volumeParam.ioCompletion = 0;

View File

@ -3,3 +3,6 @@ void mac_unmount(int id);
void mac_eject(int id);
OSErr mac_get_drive_volumes(int driveNum, Str255 str);
OSErr mac_unmount_drive(int driveNum);
OSErr mac_mount_drive(int driveNum);
OSErr mac_mount_drives();
OSErr mac_list_drives();

View File

@ -38,19 +38,24 @@ bool process_command() {
printf("\n");
char *arg_str = strchr(cmd, ' ');
while(*arg_str == ' ') arg_str++;
if(arg_str) arg_val = atoi(arg_str);
if(arg_str) {
while(*arg_str == ' ') arg_str++;
arg_val = atoi(arg_str);
}
switch( tolower(cmd[0]) ) {
case 'h': print_help(); break;
case 'l': scan_bus(); break;
case 's': iomega_spin_up_cartridge(arg_val); break;
case 'p': iomega_spin_down_cartridge(arg_val); break;
case 'r': scsi_reset(); break;
case 'e': mac_eject(arg_val); break;
case 'i': dev_info(arg_val); break;
case 'v': mac_list_volumes(); break;
case 'u': mac_unmount(arg_val); break;
case 'q': return false;
case 'd': mac_list_drives(); break;
case 'm': if(arg_str) mac_mount_drive(arg_val); else mac_mount_drives(); break;
default: printf("Unknown command, type 'h' for help\n");
}
return true;
@ -62,10 +67,15 @@ void print_help() {
" help : print this help\n"
" quit : exit the command line\n"
"\nMacintosh commands:\n"
"\nMacintosh volume commands:\n"
" volumes : list Mac volumes\n"
" unmount [n] : unmount a volume\n"
" eject [n] : eject a volume\n"
" unmount [n] : unmount a volume\n"
"\nMacintosh drive commands:\n"
" drives : list all drives\n"
" mount [n] : mount a drive\n"
" mount : mount all drives\n"
"\nGeneral SCSI operations:\n"
" reset : reset the SCSI bus\n"
@ -74,6 +84,7 @@ void print_help() {
"\nIomega device operations on SCSI device:\n"
" spin [n] : spin up a cartridge\n"
" pause [n] : spin down a cartridge\n"
);
}
@ -84,9 +95,9 @@ void scan_bus() {
for( id=0; id<8; id++ ) {
err = scsi_inquiry( id, 0, &reply);
if( err != 0 ) {
printf( " %hd: (Not installed)\n", id );
printf( "%4hd: (Not installed)\n", id );
} else {
printf( " %hd: ", id );
printf( "%4hd: ", id );
printn( reply.vend, 8 );
printf( ", " );
printn( reply.prod, 16 );

View File

@ -29,6 +29,19 @@ OSErr iomega_spin_down_and_eject( int id ) {
return scsi_cmd(id, cmd, sizeof(cmd), 0, 0, 0, 0);
}
OSErr iomega_spin_down_cartridge( int id ) {
// issue an Asynchronous STOP command to induce spindown
char cmd[6] = {
SCSI_Cmd_StartStopUnit,
1, // set the IMMED bit for offline
0,
0,
0,
0
};
return scsi_cmd(id, cmd, sizeof(cmd), 0, 0, 0, 0);
}
OSErr iomega_set_prevent_removal( int id, bool lock) {
OSErr err;
char cmd[6] = {

View File

@ -4,5 +4,6 @@ typedef Boolean bool;
OSErr iomega_spin_up_cartridge(int id);
OSErr iomega_spin_down_and_eject(int id);
OSErr iomega_spin_down_cartridge(int id);
OSErr iomega_set_prevent_removal(int id, bool lock);
OSErr iomega_eject_cartridge(int id);

View File

@ -61,8 +61,11 @@ OSErr scsi_cmd(int id, void *cmd, size_t clen, void *buff, size_t siz, size_t cn
case SCSI_READ: io_err = SCSIRead( (Ptr) TIB ); break;
default: break;
}
if (io_err != noErr) {
printf("SCSI Read/Write Error: %d\n", io_err);
if (io_err == scPhaseErr && flags & SCSI_READ) {
printf("\nSCSI phase error; less data delivered than requested\n");
}
else if (io_err != noErr) {
printf("\nSCSI Read/Write Error: %d\n", io_err);
}
} else {
printf("SCSICmd Error: %d\n", err);

View File

@ -118,9 +118,6 @@ void WndProc(long iMessage, uint16_t wParam) {
LineTo(LOGO_1_LEFT+0, LOGO_1_TOP+32);
LineTo(LOGO_1_LEFT+0, LOGO_1_TOP+35);
// show the current logo bitmap
SplashTheBitmap();
// paint the 3D program title
Paint3DHeadline(szIntroTitle, BODY_LEFT, TITLE_TOP);
@ -135,6 +132,9 @@ void WndProc(long iMessage, uint16_t wParam) {
SetRect(&rect, WH_RECT(BODY_LEFT, BODY_TOP+64, BODY_WIDTH, 115));
TETextBox(szIntroText, strlen(szIntroText), &rect, teFlushDefault);
// show the current logo bitmap
SplashTheBitmap();
ReleaseDC(hIntroWnd);
}
@ -161,7 +161,7 @@ void WndProc(long iMessage, uint16_t wParam) {
SpinUpIomegaCartridge(CurrentDevice);
break;
case DISK_AT_SPEED:
printf("Testing the disk\n");
printf("\nTesting the disk\n");
if(TestingPhase != READY_TO_TEST) {
PrepareToBeginTesting();
}
@ -177,6 +177,7 @@ void WndProc(long iMessage, uint16_t wParam) {
EjectIomegaCartridge(CurrentDevice);
break;
case DISK_LOW_SPARES:
CartridgeStatus = DISK_AT_SPEED;
SetRichEditText(szNotRunning);
SetWindowText(hTestButton, szPressToStart);
PrepareToBeginTesting();
@ -338,6 +339,15 @@ void PaintCenteredValue(int Xleft, int Ytop, int XWidth, int YHeight, long value
*
* This paints the two columns of testing statistics on the test minitor window.
*******************************************************************************/
char *FindErrorString(long error) {
char *errStr = 0;
for (int i = 0; errorTypeList[i].str; i++) {
errStr = errorTypeList[i].str;
if (errorTypeList[i].code == error) break;
}
return errStr;
}
void PaintTestStatistics(bool Active) {
char szString[40];
// assemble and paint the sector testing range
@ -360,12 +370,7 @@ void PaintTestStatistics(bool Active) {
PaintCenteredString(76, 155, 126, 14, szString, Active);
// show the LastError
char *errStr = 0;
for (int i = 0; errorTypeList[i].str; i++) {
errStr = errorTypeList[i].str;
if (errorTypeList[i].code == LastError) break;
}
PaintCenteredString(76, 172, 126, 14, errStr, Active);
PaintCenteredString(76, 172, 126, 14, FindErrorString(LastError), Active);
// show the elapsed time
CvrtSecondsToHMSstring(szString, SecondsElapsed);

View File

@ -282,6 +282,8 @@ void PaintTheBarGraphs(bool Active);
void PaintTestStatistics(bool Active);
void CvrtSecondsToHMSstring(char *szString, long seconds);
char *FindErrorString(long error);
void UpdateCurrentSector();
void UpdateRunTimeDisplay();
void UpdateRunPhaseDisplay();
@ -301,9 +303,9 @@ void GetCommandDetails(char command, char &cmd_flags, char &cmd_length);
long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, size_t IoBufLen);
long EnumerateIomegaDevices(uint8_t *DrivesSkipped);
long GetModePage(short Device, short PageToGet, void *pBuffer, short BufLen);
long SetModePage(short Device, void *pBuffer);
long SetModePage(short Device, void *pBuffer, short BufLen);
void ModifyModePage(char *PageBuff, char eec, char retries);
void SetErrorRecovery(bool Retries, bool ECC, bool Testing);
long SetErrorRecovery(bool Retries, bool ECC, bool Testing);
long GetNonSenseData(short Device, short DataPage, void *Buffer, short BufLen);
long LockCurrentDrive();
long UnlockCurrentDrive();

View File

@ -6,8 +6,28 @@
#include "tip.h"
//#define DEMO
/* The original TIP seems to request more data than is supplied by
* certain commands. While this appears to be allowed, it causes
* SCSI phase errors to be reported. Setting NO_EXCESS_READS will
* adjust the reads to to the max size before such errors occur.
*/
#define NO_EXCESS_READS
/* The original TIP will always try to enable Early Recovery. This
* fails on certain Jaz drives. While the original TIP will then
* retry without Early Recovery, this will cause many errors to be
* reported. Enable SUPRESS_ER_ERRORS to prevent this from problem
* from happening as frequently
*/
#define SUPRESS_ER_ERRORS
/* The original TIP will always try to read the defects list, but
* not all drives support this, causing many errors to be shown.
* Setting SUPPRESS_DEFECTS_ERROR will silence these errors.
*/
#define SUPPRESS_DEFECTS_ERROR
#define MAKE_LITTLE_ENDIAN(a) a // Don't do anything on 68000
#define MAKE_BIG_ENDIAN(a) a // Don't do anything on 68000
@ -96,6 +116,13 @@ long DriveCount = 0;
long JazDrive = 0; // true if the current drive
long CartridgeStatus = DISK_NOT_PRESENT;
#ifdef SUPRESS_ER_ERRORS
Boolean SupressEarlyRecovery = false;
#endif
#ifdef SUPPRESS_DEFECTS_ERROR
Boolean SupressDefectsError = false;
#endif
unsigned long StartingInstant;
// ----------------------------- Run Time Variables ------------------------------
@ -215,6 +242,7 @@ long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, size_t IoBufLen) {
(long(sense_data.ascq) << 8) |
(long(sense_data.key) );
if(res == MEDIA_CHANGE_CODE) {
printf("Media change signalled. Most recent error can be ignored\n\n");
int index = GetDriveEntryOffset(Device);
DriveArray[index].flags |= MEDIA_CHANGED;
return 0;
@ -312,13 +340,18 @@ long GetModePage(short Device, short PageToGet, void *pBuffer, short BufLen) {
/*******************************************************************************
* SET MODE PAGE
*******************************************************************************/
long SetModePage(short Device, void *pBuffer) {
char* ebx = (char*) pBuffer; // get a pointer to the top of buffer
char ecx = ebx[0] + 1; // adjust it up by one
long SetModePage(short Device, void *pBuffer, short BufLen) {
unsigned char* ebx = (unsigned char*) pBuffer; // get a pointer to the top of buffer
unsigned char ecx = ebx[0] + 1; // adjust it up by one
ebx[0] = 0; // now clear the two reserved bytes
ebx[2] = 0;
if(ecx != BufLen) {
printf("Length error in SetModePage %d != %d\n\n", BufLen, (int) ecx);
return 0;
}
char Scsi[6] = {0}; // init the SCSI parameter block
Scsi[0] = SCSI_Cmd_ModeSelect; // set the command
Scsi[1] = 0x10; // set the Page Format bit
@ -343,16 +376,21 @@ void ModifyModePage(char *PageBuff, char ecc, char retries) {
ebx[8] = retries; // then set the write count too
}
void SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
long SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
char PageBuff[40];
#ifdef NO_EXCESS_READS
// Limit reads to 20 bytes on Zip to prevent controller errors
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, JazDrive ? sizeof(PageBuff) : 20);
// Limit reads to 20 bytes on Zip (24 bytes on Jaz) to prevent controller errors
const short pageBuffLen = JazDrive ? 24 : 20;
#else
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, sizeof(PageBuff));
const short pageBuffLen = sizeof(PageBuff);
#endif
long eax = GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, pageBuffLen);
if(eax) {
printf("SetErrorRecovery failed\n");
return eax;
}
#define EARLY_RECOVERY 0x08
#define PER 0x04
#define SUPPRESS_ECC 0x01
@ -360,6 +398,9 @@ void SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
// set the ECC fields
char ecc = SUPPRESS_ECC; // presume ECC suppression
if(ECC) {
#ifdef SUPRESS_ER_ERRORS
if(!SupressEarlyRecovery)
#endif
ecc = EARLY_RECOVERY; // enable ECC and Early Recovery
if(Testing) {
ecc = EARLY_RECOVERY | PER; // we're testing, so EER & PER
@ -374,14 +415,22 @@ void SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
retries = 0;
ModifyModePage(PageBuff, ecc, retries);
const long eax = SetModePage(CurrentDevice, PageBuff);
eax = SetModePage(CurrentDevice, PageBuff, pageBuffLen);
// if we had an invalid field in the CDB (the EER bit was on)
if (eax == 0x00260005) {
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, sizeof(PageBuff));
ecc &= ~0x08; // same, *BUT*NOT* Early Recovery
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, pageBuffLen);
ecc &= ~EARLY_RECOVERY; // same, *BUT*NOT* Early Recovery
ModifyModePage(PageBuff, ecc, retries);
SetModePage(CurrentDevice, PageBuff);
eax = SetModePage(CurrentDevice, PageBuff, pageBuffLen);
#ifdef SUPRESS_ER_ERRORS
if(!eax) {
printf(" Early recovery not supported on this drive. Ignoring.\n\n");
SupressEarlyRecovery = true;
}
#endif
}
return eax;
}
/*******************************************************************************
@ -468,7 +517,18 @@ long GetSpareSectorCounts(char checkPassword) {
Scsi[0] = SCSI_Cmd_ReadDefectData;
Scsi[2] = 0x1e; // 0b00011110 defect format, G/P bits
Scsi[8] = 4; // ask for only FOUR bytes
#ifdef SUPPRESS_DEFECTS_ERROR
if(SupressDefectsError)
eax = INCOMPATIBLE_MEDIA;
else
#endif
eax = SCSICommand(CurrentDevice, Scsi, &DefectHeader, sizeof(DefectHeader));
#ifdef SUPPRESS_DEFECTS_ERROR
if(!SupressDefectsError && eax == INCOMPATIBLE_MEDIA) {
printf("Defects list not supported on this drive. Ignoring.\n\n");
SupressDefectsError = true;
}
#endif
if ((!eax) || (eax == INCOMPATIBLE_MEDIA)) {
// we could read its defect list ... so show it!
// --------------------------------------------------------------------------
@ -635,7 +695,7 @@ uint8_t GetCartridgeStatus(long Device, uint8_t flags) {
long eax;
char DiskStat[72];
#ifdef NO_EXCESS_READS
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, (flags & JAZ_DRIVE) ? sizeof(DiskStat) : 63);
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, 4);
if (eax) return DISK_STATUS_UNKNOWN;
#else
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, sizeof(DiskStat));
@ -674,6 +734,7 @@ void SetCartridgeStatusToEAX(long eax, uint8_t flags) {
SetRichEditText(szNotRunning);
goto DisableActions;
case DISK_AT_SPEED:
printf("Disk at speed\n");
eax = GetSpareSectorCounts(true); // update the Cart Condition
if(eax == MEDIA_NOT_PRESENT) {
goto DisableActions;
@ -686,10 +747,14 @@ void SetCartridgeStatusToEAX(long eax, uint8_t flags) {
FirmErrors = 0;
// check to see if we have enough spares to start
if(JazDrive) {
printf("Spare Sectors: %ld/%d\n", Side_0_SparesCount, MAXIMUM_JAZ_SPARES);
if(Side_0_SparesCount < MINIMUM_JAZ_SPARES)
goto InsufficientSpares;
}
else {
printf("Spare Sectors:\n");
printf(" Side 1: %ld/%d\n", Side_0_SparesCount, MAXIMUM_ZIP_SPARES);
printf(" Side 2: %ld/%d\n", Side_1_SparesCount, MAXIMUM_ZIP_SPARES);
if(Side_0_SparesCount < MINIMUM_ZIP_SPARES) {
goto InsufficientSpares;
}
@ -761,6 +826,12 @@ void PrepareToBeginTesting() {
HardErrors = 0;
UserInterrupt = 0;
LastError = 0;
#ifdef SUPRESS_ER_ERRORS
SupressEarlyRecovery = false;
#endif
#ifdef SUPPRESS_DEFECTS_ERROR
SupressDefectsError = false;
#endif
#ifdef DEMO
LastLBAOnCartridge = 99999;
SoftErrors = 6;
@ -820,12 +891,12 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
char Scsi[10] = {0}; // clear out the SCSI CDB
const long InitialHardErrors = HardErrors;
SetErrorRecovery(false, false, true); // disable Retries & ECC
long eax = SetErrorRecovery(false, false, true); // disable Retries & ECC
Scsi[0] = XferCmd;
SET_DWORD_AT(Scsi, 2, MAKE_BIG_ENDIAN(FirstLBASector)); // WHICH LBA's to read, BIG endian
SET_WORD_AT (Scsi, 7, MAKE_BIG_ENDIAN(NumberOfLBAs)); // HOW MANY to read, BIG endian
long eax = SCSICommand(CurrentDevice, Scsi, pBuffer, NumberOfLBAs * BYTES_PER_SECTOR);
eax = SCSICommand(CurrentDevice, Scsi, pBuffer, NumberOfLBAs * BYTES_PER_SECTOR);
// if we failed somewhere during our transfer ... let's zero in on it
if (eax) {
if ( eax == SS_ERR || // if it's a CONTROLLER ERROR, skip!
@ -834,6 +905,8 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
goto Exit;
}
printf("Starting detailed search...\n");
//--------------------------------------------------------------------------
// Save error and current Soft + Hard Error count to see if we do FIND the glitch ...
const long GlitchError = eax; // save the error which stopped us!
@ -863,6 +936,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
if (eax & 0xFF == 1) goto PostTheError; // did we recover?
printf(" Found error, retesting with retries\n");
SetErrorRecovery(true, false, true); // enable retries
eax = SCSICommand(CurrentDevice, Scsi, LocalBuffer, BYTES_PER_SECTOR);
if (eax) {
@ -870,7 +944,8 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
if (eax & 0xFF == 1) goto PostTheError; // did we recover?
SetErrorRecovery(true, true, true); // enable retries AND EEC
printf(" Found error, retesting with retries & ECC\n");
eax = SetErrorRecovery(true, true, true); // enable retries AND EEC
eax = SCSICommand(CurrentDevice, Scsi, LocalBuffer, BYTES_PER_SECTOR);
if (eax) {
// failed with retries and EEC
@ -888,6 +963,8 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
}
PostTheError:
printf(" %s (Sector %ld)\n", FindErrorString(eax), SingleTransferLBA);
printf("--------------------------------------------\n");
BumpErrorCounts(eax); // given eax, count the errors
GetSpareSectorCounts(false); // update the Cart's Condition
UpdateRunTimeDisplay();
@ -897,6 +974,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
ProcessPendingMessages();
}
printf("... detailed search finished\n");
// now see whether we *did* found something to complain about ...
eax = SoftErrors + HardErrors;
if (eax == GlitchCount) {
@ -907,6 +985,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
long ebx = eax & 0x00FF00FF; // strip the ASCQ byte
if(ebx == 0x00110003) // if we're about to say "unrecovered read"
eax = 0x170101; // change it to: "Read with Retries"
printf("%s\n", FindErrorString(eax));
BumpErrorCounts(eax); // given eax, count the errors
HardErrors = SavedHardErrors; // restore the counts
SoftErrors = SavedSoftErrors;
@ -917,6 +996,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
eax = 0; // now let's return happiness to our caller
if (HardErrors != InitialHardErrors) // UNRECOVERABLE errors!
eax = -1;
printf("\n");
}
Exit:

View File

@ -83,9 +83,11 @@ void run_tip() {
}
} while (!gDone);
EjectAllMedia();
DisposeTipWindow();
DisposeRgn(cursorRgn);
// Remount any drives we may have unmounted
mac_mount_drives();
}
void NewTipWindow() {

View File

@ -1,16 +1,19 @@
/************************************************************
pstring.c
AUTHOR: Marcio Luis Teixeira
CREATED: 9/17/94
LAST REVISION: 11/25/21
(c) 1994-1995 by Marcio Luis Teixeira.
All rights reserved.
*************************************************************/
/****************************************************************************
* Common Libraries (c) 1994 Marcio Teixeira *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "pstring.h"
#include <ctype.h>

View File

@ -1,16 +1,19 @@
/************************************************************
pstring.h
AUTHOR: Marcio Luis Teixeira
CREATED: 9/17/94
LAST REVISION: 11/25/21
(c) 1994-1995 by Marcio Luis Teixeira.
All rights reserved.
*************************************************************/
/****************************************************************************
* Common Libraries (c) 1994 Marcio Teixeira *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
short pstrlen( unsigned char *str );
void psetlen( unsigned char *str, short len );