mirror of
https://github.com/marciot/mac-tip.git
synced 2024-06-11 01:29:27 +00:00
Compare commits
20 Commits
v0.2-beta-
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
4793ffc0d8 | ||
|
b6fa1cad7a | ||
|
7d96b63ef0 | ||
|
c719c8d7dd | ||
|
dcfa0958a6 | ||
|
bfa9014432 | ||
|
6b36dfdc0e | ||
|
49ce1bc093 | ||
|
afb8d6fe8f | ||
|
efd84f0ebc | ||
|
4ab4a0cc90 | ||
|
bfdf0d8171 | ||
|
a90cdf000f | ||
|
98edb49670 | ||
|
37dab8d0b7 | ||
|
b5f0328beb | ||
|
1af5e74aea | ||
|
5ab24df256 | ||
|
b00a01b948 | ||
|
d21a0c277b |
75
README.md
75
README.md
|
@ -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
|
Jaz Drives. A big thanks goes to Steve Gibson for the x86 source that
|
||||||
made this project possible!
|
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
|
Compatibility
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
@ -20,17 +29,19 @@ Power Macintosh G3, released in 1997.
|
||||||
|
|
||||||
It has been tested in on the following environments:
|
It has been tested in on the following environments:
|
||||||
|
|
||||||
| Computer | Memory | System | Drive | Firmware |
|
| Computer | Memory | System | Drive | Firmware |
|
||||||
|------------------- |--------|--------|-------------------------|----------|
|
|------------------- |--------|--------|-------------------------------------|----------|
|
||||||
| Macintosh Plus | 4MB | 7.0.1 | Zip Plus 100 Ext. SCSI | J.66 |
|
| 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 | Zip 100 Ext. SCSI | E.08 |
|
||||||
| Power Macintosh G3 | 256MB | 9.2.1 | Zip 100 Ext. SCSI | C.22 |
|
| PowerBook 3400c | 144MB | 8.6 | Jaz 2GB Ext. SCSI w/ 1GB media | E.17 |
|
||||||
| Power Macintosh G3 | 256MB | 9.2.1 | Zip 100 Int. SCSI | J.03 |
|
| 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:
|
What will not work or is missing:
|
||||||
|
|
||||||
* USB connected Zip drives have been reported to not work.
|
* 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.
|
* The partition recovery feature has been removed, since it is meant for PC disks.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@ -47,13 +58,9 @@ port.**
|
||||||
Where are the binaries?
|
Where are the binaries?
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Once they are ready, compiled binaries will be made available on the
|
Compiled binaries are available on the releases page for people who have signed up for
|
||||||
releases page for people who have signed up for
|
|
||||||
[beta testing in the discussion forum]
|
[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?
|
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!
|
* Star this project on GitHub to show your support!
|
||||||
* Sign up to [beta testing in the discussion forum]!
|
* 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 various open-source projects!
|
||||||
* Become a GitHub sponsor to help fund my work with this and other 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?
|
Got work?
|
||||||
---------
|
---------
|
||||||
|
@ -74,20 +87,22 @@ for vintage Macs. If you have a project in mind, please hit me up via my
|
||||||
Unmounting volumes
|
Unmounting volumes
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
**To avoid data corruption, you must "unmount" the cartridge prior to
|
**To avoid data corruption, a cartridge must be unmounted prior to
|
||||||
starting a test with TIP!**
|
starting a test with TIP!**
|
||||||
|
|
||||||
There is no way to unmount a cartridge (without also ejecting it) in the
|
The best way to accomplish this is to start TIP without a disk in the drive you want to test.
|
||||||
Finder, but you can either:
|
Then, insert the cartridge at the testing screen which indicates "Awaiting media...". TIP
|
||||||
|
will recognize it if Mac OS mounts newly inserted cartridge and will give you the choice to
|
||||||
|
unmount it.
|
||||||
|
|
||||||
1) Start TIP without a disk in the drive. TIP will recognize when Mac OS mounts newly inserted cartridges and will give you the choice to unmount it.
|
Alternatively, you can use the command line from the "Advanced" menu to unmount a disk
|
||||||
2) Use the command console to unmount a disk **prior to** starting TIP
|
**prior to** starting a test.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Click here to learn how to use the Command Console</summary></br>
|
<summary>Click here to learn how to use the command line</summary></br>
|
||||||
|
|
||||||
The Command Console shows up when you first start the program. This is a
|
The command line is accessible by selecting run "Run Command Line..." from the "Advanced"
|
||||||
unique feature of this port and is not present in the original TIP:
|
menu. This is a unique feature of this port and is not present in the original TIP:
|
||||||
|
|
||||||
![Command Line][mac-screenshot2]
|
![Command Line][mac-screenshot2]
|
||||||
|
|
||||||
|
@ -104,15 +119,10 @@ cartridge will remain in the drive. To unmount a drive:
|
||||||
*The unmount process will fail if you have any open files or applications in
|
*The unmount process will fail if you have any open files or applications in
|
||||||
the volume; if this happens, close those files and try again.*
|
the volume; if this happens, close those files and try again.*
|
||||||
|
|
||||||
### Starting TIP
|
### Listing SCSI devices
|
||||||
|
|
||||||
To start TIP, you will need to tell it which SCSI device to use:
|
|
||||||
|
|
||||||
* Type `list` to show a numbered list of all SCSI devices by SCSI ID.
|
* Type `list` to show a numbered list of all SCSI devices by SCSI ID.
|
||||||
* Type `tip` followed by a SCSI ID to run TIP on that device.
|
|
||||||
|
|
||||||
Future versions of this tool may eliminate the Command Console, if I can find
|
|
||||||
the right way to automate all these steps in MacOS :grin:
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
About the code
|
About the code
|
||||||
|
@ -145,6 +155,7 @@ Credits
|
||||||
* Thank you to [Stone Table Software] for providing the tool I used to convert the Windows RTF docs into SimpleText...
|
* 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!
|
* ...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 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
|
The Original TIP For Windows
|
||||||
----------------------------
|
----------------------------
|
||||||
|
@ -164,7 +175,7 @@ his code in this repository with his permission.
|
||||||
![TIP Running on a Mac Plus][mac-plus]
|
![TIP Running on a Mac Plus][mac-plus]
|
||||||
|
|
||||||
[GitHub account]: https://github.com/marciot
|
[GitHub account]: https://github.com/marciot
|
||||||
[mac-screenshot1]: https://github.com/marciot/mac-tip/raw/main/images/mac-tip1.png "Mac TIP Testing Screen"
|
[mac-screenshot1]: https://github.com/marciot/mac-tip/raw/main/images/mac-tip1.gif "Mac TIP Animation"
|
||||||
[mac-screenshot2]: https://github.com/marciot/mac-tip/raw/main/images/mac-cmd.png "Mac TIP Command Line"
|
[mac-screenshot2]: https://github.com/marciot/mac-tip/raw/main/images/mac-cmd.png "Mac TIP Command Line"
|
||||||
[mac-screenshot3]: https://github.com/marciot/mac-tip/raw/main/images/mac-tip-cw8.png "Mac TIP Build Environment"
|
[mac-screenshot3]: https://github.com/marciot/mac-tip/raw/main/images/mac-tip-cw8.png "Mac TIP Build Environment"
|
||||||
[win-screenshot1]: https://github.com/marciot/mac-tip/raw/main/images/win-tip1.gif "Windows TIP About Screen"
|
[win-screenshot1]: https://github.com/marciot/mac-tip/raw/main/images/win-tip1.gif "Windows TIP About Screen"
|
||||||
|
@ -178,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
|
[beta testing in the discussion forum]: https://github.com/marciot/mac-tip/discussions/1
|
||||||
[LaunchLib code]: http://www.tempel.org/macdev/index.html#Libs
|
[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
|
[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
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
images/mac-tip1.gif
Normal file
BIN
images/mac-tip1.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 264 KiB |
Binary file not shown.
Before Width: | Height: | Size: 101 KiB |
BIN
images/security-now.png
Normal file
BIN
images/security-now.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 693 KiB |
BIN
images/youtube.png
Normal file
BIN
images/youtube.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 465 KiB |
|
@ -12,32 +12,13 @@ void main() {
|
||||||
SIOUXSettings.leftpixel = 8;
|
SIOUXSettings.leftpixel = 8;
|
||||||
SIOUXSettings.toppixel = 44;
|
SIOUXSettings.toppixel = 44;
|
||||||
|
|
||||||
printf(
|
|
||||||
"\n\n"
|
|
||||||
"Trouble in Paradise\n"
|
|
||||||
"===================\n\n"
|
|
||||||
"A Macintosh port of \"Trouble in Paradise\" for Windows, made possible by a\n"
|
|
||||||
"generous code donation by Steve Gibson from Gibson Research Corporation.\n\n"
|
|
||||||
"This freeware utility determines whether an Iomega Zip or Jaz drive is prone\n"
|
|
||||||
"to developing the dreaded \"Click of Death\" (COD) syndrome. Steve Gibson's\n"
|
|
||||||
"research into the maintenance, repair and data recovery of Iomega's removable\n"
|
|
||||||
"media mass storage products led to this capability.\n\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
printf( "------------------------------------------------------------------------------\n" );
|
printf( "------------------------------------------------------------------------------\n" );
|
||||||
printf( "This Mac port (c) 2021 Marcio Teixeira http://github.com/marciot/mac-tip\n" );
|
printf( "This Mac port (c) 2021 Marcio Teixeira http://github.com/marciot/mac-tip\n" );
|
||||||
printf( "Based on code (c) 2006 Gibson Research Corp http://grc.com/tip/clickdeath.htm\n" );
|
printf( "Based on code (c) 2006 Gibson Research Corp http://grc.com/tip/clickdeath.htm\n" );
|
||||||
printf( "------------------------------------------------------------------------------\n" );
|
printf( "------------------------------------------------------------------------------\n" );
|
||||||
|
printf("\nStarting tip ...\n");
|
||||||
|
|
||||||
SIOUXSetTitle("\pTrouble in Paradise for Macintosh (" __DATE__ ")");
|
SIOUXSetTitle("\pTrouble in Paradise for Macintosh (" __DATE__ ")");
|
||||||
|
|
||||||
// Confirm that the user wants to run TIP
|
run_tip();
|
||||||
|
|
||||||
char cmd[80];
|
|
||||||
printf("\n\nThis program is in BETA TESTING and may cause data loss!\n\nProceed [Y/N]? ");
|
|
||||||
gets( cmd );
|
|
||||||
if(tolower(cmd[0]) == 'y') {
|
|
||||||
run_tip();
|
|
||||||
printf("\n\nYou may need to REBOOT your Mac before cartridges are recognized by Mac OS.");
|
|
||||||
}
|
|
||||||
}
|
}
|
Binary file not shown.
Binary file not shown.
|
@ -14,7 +14,8 @@ void mac_list_volumes() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
OSErr err = PBHGetVInfo(¶mBlock, false);
|
OSErr err = PBHGetVInfo(¶mBlock, false);
|
||||||
if (err == nsvErr) break;
|
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++;
|
paramBlock.volumeParam.ioVolIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +24,7 @@ OSErr mac_get_drive_volumes(int driveNum, Str255 str) {
|
||||||
HParamBlockRec paramBlock;
|
HParamBlockRec paramBlock;
|
||||||
Str255 volName;
|
Str255 volName;
|
||||||
Boolean first = true;
|
Boolean first = true;
|
||||||
|
str[0] = '\0';
|
||||||
paramBlock.volumeParam.ioCompletion = 0;
|
paramBlock.volumeParam.ioCompletion = 0;
|
||||||
paramBlock.volumeParam.ioNamePtr = volName;
|
paramBlock.volumeParam.ioNamePtr = volName;
|
||||||
paramBlock.volumeParam.ioVRefNum = 0;
|
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(¶mBlock);
|
||||||
|
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) {
|
void mac_unmount(int id) {
|
||||||
HParamBlockRec paramBlock;
|
HParamBlockRec paramBlock;
|
||||||
paramBlock.volumeParam.ioCompletion = 0;
|
paramBlock.volumeParam.ioCompletion = 0;
|
||||||
|
|
|
@ -3,3 +3,6 @@ void mac_unmount(int id);
|
||||||
void mac_eject(int id);
|
void mac_eject(int id);
|
||||||
OSErr mac_get_drive_volumes(int driveNum, Str255 str);
|
OSErr mac_get_drive_volumes(int driveNum, Str255 str);
|
||||||
OSErr mac_unmount_drive(int driveNum);
|
OSErr mac_unmount_drive(int driveNum);
|
||||||
|
OSErr mac_mount_drive(int driveNum);
|
||||||
|
OSErr mac_mount_drives();
|
||||||
|
OSErr mac_list_drives();
|
|
@ -130,6 +130,9 @@ bool TBMouseDown( TBHandle tb, Point where, WindowPtr whichWindow ) {
|
||||||
HLock( (Handle) tb );
|
HLock( (Handle) tb );
|
||||||
TBRec &my = **tb;
|
TBRec &my = **tb;
|
||||||
|
|
||||||
|
// Return if hidden
|
||||||
|
if((*my.scroll)->contrlVis == 0) return 0;
|
||||||
|
|
||||||
ControlHandle whichCntl;
|
ControlHandle whichCntl;
|
||||||
short partCode = FindControl(where, whichWindow, &whichCntl);
|
short partCode = FindControl(where, whichWindow, &whichCntl);
|
||||||
if (partCode) {
|
if (partCode) {
|
||||||
|
@ -189,7 +192,7 @@ void TBSetScroll( TBHandle tb, short scroll ) {
|
||||||
my.lastV = scroll;
|
my.lastV = scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSErr TBReadSimpleText( TBHandle tb, const FSSpec *docSpec) {
|
OSErr TBReadSimpleText( TBHandle tb, const FSSpec *docSpec, bool redraw) {
|
||||||
short fRefNum;
|
short fRefNum;
|
||||||
|
|
||||||
TBSetScroll(tb, 0);
|
TBSetScroll(tb, 0);
|
||||||
|
@ -236,7 +239,7 @@ OSErr TBReadSimpleText( TBHandle tb, const FSSpec *docSpec) {
|
||||||
Handle hStyle = Get1Resource('styl', 128);
|
Handle hStyle = Get1Resource('styl', 128);
|
||||||
if (hStyle) {
|
if (hStyle) {
|
||||||
HNoPurge(hStyle);
|
HNoPurge(hStyle);
|
||||||
TEUseStyleScrap(0, dataSize, (StScrpHandle) hStyle, true, my.tbox);
|
TEUseStyleScrap(0, dataSize, (StScrpHandle) hStyle, redraw, my.tbox);
|
||||||
TECalText(my.tbox);
|
TECalText(my.tbox);
|
||||||
ReleaseResource(hStyle);
|
ReleaseResource(hStyle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,4 +28,4 @@ void TBUpdate( TBHandle html );
|
||||||
void TBResize( TBHandle html, const Rect *r );
|
void TBResize( TBHandle html, const Rect *r );
|
||||||
void TBSetScroll( TBHandle html, short scroll );
|
void TBSetScroll( TBHandle html, short scroll );
|
||||||
bool TBMouseDown( TBHandle html, Point where, WindowPtr whichWindow );
|
bool TBMouseDown( TBHandle html, Point where, WindowPtr whichWindow );
|
||||||
OSErr TBReadSimpleText( TBHandle tb, const FSSpec *docSpec);
|
OSErr TBReadSimpleText( TBHandle tb, const FSSpec *docSpec, bool redraw);
|
||||||
|
|
|
@ -38,19 +38,24 @@ bool process_command() {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
char *arg_str = strchr(cmd, ' ');
|
char *arg_str = strchr(cmd, ' ');
|
||||||
while(*arg_str == ' ') arg_str++;
|
if(arg_str) {
|
||||||
if(arg_str) arg_val = atoi(arg_str);
|
while(*arg_str == ' ') arg_str++;
|
||||||
|
arg_val = atoi(arg_str);
|
||||||
|
}
|
||||||
|
|
||||||
switch( tolower(cmd[0]) ) {
|
switch( tolower(cmd[0]) ) {
|
||||||
case 'h': print_help(); break;
|
case 'h': print_help(); break;
|
||||||
case 'l': scan_bus(); break;
|
case 'l': scan_bus(); break;
|
||||||
case 's': iomega_spin_up_cartridge(arg_val); 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 'r': scsi_reset(); break;
|
||||||
case 'e': mac_eject(arg_val); break;
|
case 'e': mac_eject(arg_val); break;
|
||||||
case 'i': dev_info(arg_val); break;
|
case 'i': dev_info(arg_val); break;
|
||||||
case 'v': mac_list_volumes(); break;
|
case 'v': mac_list_volumes(); break;
|
||||||
case 'u': mac_unmount(arg_val); break;
|
case 'u': mac_unmount(arg_val); break;
|
||||||
case 'q': return false;
|
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");
|
default: printf("Unknown command, type 'h' for help\n");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -62,10 +67,15 @@ void print_help() {
|
||||||
" help : print this help\n"
|
" help : print this help\n"
|
||||||
" quit : exit the command line\n"
|
" quit : exit the command line\n"
|
||||||
|
|
||||||
"\nMacintosh commands:\n"
|
"\nMacintosh volume commands:\n"
|
||||||
" volumes : list Mac volumes\n"
|
" volumes : list Mac volumes\n"
|
||||||
" unmount [n] : unmount a volume\n"
|
|
||||||
" eject [n] : eject 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"
|
"\nGeneral SCSI operations:\n"
|
||||||
" reset : reset the SCSI bus\n"
|
" reset : reset the SCSI bus\n"
|
||||||
|
@ -74,6 +84,7 @@ void print_help() {
|
||||||
|
|
||||||
"\nIomega device operations on SCSI device:\n"
|
"\nIomega device operations on SCSI device:\n"
|
||||||
" spin [n] : spin up a cartridge\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++ ) {
|
for( id=0; id<8; id++ ) {
|
||||||
err = scsi_inquiry( id, 0, &reply);
|
err = scsi_inquiry( id, 0, &reply);
|
||||||
if( err != 0 ) {
|
if( err != 0 ) {
|
||||||
printf( " %hd: (Not installed)\n", id );
|
printf( "%4hd: (Not installed)\n", id );
|
||||||
} else {
|
} else {
|
||||||
printf( " %hd: ", id );
|
printf( "%4hd: ", id );
|
||||||
printn( reply.vend, 8 );
|
printn( reply.vend, 8 );
|
||||||
printf( ", " );
|
printf( ", " );
|
||||||
printn( reply.prod, 16 );
|
printn( reply.prod, 16 );
|
||||||
|
|
|
@ -29,6 +29,19 @@ OSErr iomega_spin_down_and_eject( int id ) {
|
||||||
return scsi_cmd(id, cmd, sizeof(cmd), 0, 0, 0, 0);
|
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 iomega_set_prevent_removal( int id, bool lock) {
|
||||||
OSErr err;
|
OSErr err;
|
||||||
char cmd[6] = {
|
char cmd[6] = {
|
||||||
|
|
|
@ -4,5 +4,6 @@ typedef Boolean bool;
|
||||||
|
|
||||||
OSErr iomega_spin_up_cartridge(int id);
|
OSErr iomega_spin_up_cartridge(int id);
|
||||||
OSErr iomega_spin_down_and_eject(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_set_prevent_removal(int id, bool lock);
|
||||||
OSErr iomega_eject_cartridge(int id);
|
OSErr iomega_eject_cartridge(int id);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define READ_TIMEOUT 60 /* 300 ticks = 5 seconds */
|
#define READ_TIMEOUT 180 /* 300 ticks = 5 seconds */
|
||||||
|
|
||||||
OSErr scsi_reset() {
|
OSErr scsi_reset() {
|
||||||
return SCSIReset();
|
return SCSIReset();
|
||||||
|
@ -61,18 +61,21 @@ 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;
|
case SCSI_READ: io_err = SCSIRead( (Ptr) TIB ); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
if (io_err != noErr) {
|
if (io_err == scPhaseErr && flags & SCSI_READ) {
|
||||||
printf("SCSI Read/Write Error: %d\n", io_err);
|
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 {
|
} else {
|
||||||
printf("SCSICmd Error: %d\n", err);
|
printf("SCSICmd Error: %d\n", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complete the transaction and release the bus */
|
/* Complete the transaction and release the bus */
|
||||||
short cstat, cmsg;
|
short cstat = 0, cmsg = 0;
|
||||||
OSErr comperr = SCSIComplete( &cstat, &cmsg, READ_TIMEOUT );
|
OSErr comperr = SCSIComplete( &cstat, &cmsg, READ_TIMEOUT );
|
||||||
if(status) *status = cstat;
|
if(status) *status = cstat;
|
||||||
if (comperr != noErr) {printf("SCSIComplete Error: %d (status: %d)\n", err, cstat); return err;}
|
if (comperr != noErr) {printf("SCSIComplete Error: %d (status: %d)\n", comperr, cstat); return err;}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,17 @@
|
||||||
|
|
||||||
#include "tip.h"
|
#include "tip.h"
|
||||||
|
|
||||||
// ----------------------- Test Monitor Panel Definitions -------------------
|
#define TITLE_TOP 11
|
||||||
#define SET_RECT(LEFT, TOP, RIGHT, BOTTOM) {TOP, LEFT, BOTTOM, RIGHT}
|
#define BODY_TOP 54
|
||||||
|
#define BODY_LEFT 156
|
||||||
|
#define BODY_RIGHT 445
|
||||||
|
#define BODY_BOTTOM 280
|
||||||
|
|
||||||
Rect CS_Stat = SET_RECT(114, 8, 242, 28);
|
#define BODY_WIDTH (BODY_RIGHT - BODY_LEFT)
|
||||||
Rect TP_Perc = SET_RECT( 12, 56, 409, 72);
|
#define BODY_HEIGHT (BODY_BOTTOM - BODY_TOP)
|
||||||
Rect SS_Jaz = SET_RECT( 12, 94, 409, 126);
|
|
||||||
Rect SS_Sid0 = SET_RECT( 12, 94, 409, 110);
|
#define LOGO_1_LEFT 157
|
||||||
Rect TL_Sect = SET_RECT( 75, 154, 203, 170);
|
#define LOGO_1_TOP 57
|
||||||
Rect ES_Read = SET_RECT(346, 154, 409, 170);
|
|
||||||
Rect SE_Rect = SET_RECT(222, 154, 255, 221);
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* WinMain
|
* WinMain
|
||||||
|
@ -41,6 +42,22 @@ void WinMain(uint8_t *DrivesSkipped) {
|
||||||
StartApplicationTimer();
|
StartApplicationTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* PAINT 3D HEADLINE
|
||||||
|
*******************************************************************************/
|
||||||
|
void Paint3DHeadline(const char *pszText, int Xleft, int Ytop) {
|
||||||
|
TextSize(24);
|
||||||
|
TextFace(bold);
|
||||||
|
TextFont(helvetica);
|
||||||
|
SetColor(WHITE_COLOR);
|
||||||
|
TextOut(Xleft, Ytop, pszText);
|
||||||
|
SetColor(BLACK_COLOR);
|
||||||
|
TextOut(Xleft+1, Ytop+1, pszText);
|
||||||
|
TextFont(applFont);
|
||||||
|
TextFace(0);
|
||||||
|
TextSize(10);
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* WndProc
|
* WndProc
|
||||||
*
|
*
|
||||||
|
@ -53,17 +70,80 @@ void WndProc(long iMessage, uint16_t wParam) {
|
||||||
if (iMessage == WM_PAINT) {
|
if (iMessage == WM_PAINT) {
|
||||||
// Draw the Lower Horz Button Divider
|
// Draw the Lower Horz Button Divider
|
||||||
|
|
||||||
|
GetDC(hMainWnd);
|
||||||
SetColor(GRAY_COLOR);
|
SetColor(GRAY_COLOR);
|
||||||
MoveTo(15, 289);
|
MoveTo(15, 289);
|
||||||
LineTo(446, 289);
|
LineTo(446, 289);
|
||||||
SetColor(WHITE_COLOR);
|
SetColor(WHITE_COLOR);
|
||||||
LineTo(446, 290);
|
LineTo(446, 290);
|
||||||
LineTo(14, 290);
|
LineTo(14, 290);
|
||||||
|
ReleaseDC(hMainWnd);
|
||||||
|
|
||||||
|
// Draw the Gibson 'G' Logo
|
||||||
|
if(CurrentPage == INTRO_PAGE) {
|
||||||
|
GetDC(hIntroWnd);
|
||||||
|
SetColor(GRAY_COLOR, GRAY_COLOR);
|
||||||
|
MoveTo(LOGO_1_LEFT+1, LOGO_1_TOP+29);
|
||||||
|
LineTo(LOGO_1_LEFT+14, LOGO_1_TOP+29);
|
||||||
|
LineTo(LOGO_1_LEFT+14, LOGO_1_TOP+0);
|
||||||
|
SetColor(WHITE_COLOR, LTGRAY_COLOR);
|
||||||
|
LineTo(LOGO_1_LEFT+12, LOGO_1_TOP+0);
|
||||||
|
LineTo(LOGO_1_LEFT+0, LOGO_1_TOP+12);
|
||||||
|
LineTo(LOGO_1_LEFT+0, LOGO_1_TOP+30);
|
||||||
|
|
||||||
|
SetColor(GRAY_COLOR, GRAY_COLOR);
|
||||||
|
MoveTo(LOGO_1_LEFT+18, LOGO_1_TOP+14);
|
||||||
|
LineTo(LOGO_1_LEFT+46, LOGO_1_TOP+14);
|
||||||
|
LineTo(LOGO_1_LEFT+46, LOGO_1_TOP+12);
|
||||||
|
LineTo(LOGO_1_LEFT+34, LOGO_1_TOP+0);
|
||||||
|
SetColor(WHITE_COLOR, LTGRAY_COLOR);
|
||||||
|
LineTo(LOGO_1_LEFT+17, LOGO_1_TOP+0);
|
||||||
|
LineTo(LOGO_1_LEFT+17, LOGO_1_TOP+15);
|
||||||
|
|
||||||
|
SetColor(GRAY_COLOR, GRAY_COLOR);
|
||||||
|
MoveTo(LOGO_1_LEFT+33, LOGO_1_TOP+46);
|
||||||
|
LineTo(LOGO_1_LEFT+46, LOGO_1_TOP+46);
|
||||||
|
LineTo(LOGO_1_LEFT+46, LOGO_1_TOP+29);
|
||||||
|
LineTo(LOGO_1_LEFT+34, LOGO_1_TOP+17);
|
||||||
|
SetColor(WHITE_COLOR, LTGRAY_COLOR);
|
||||||
|
LineTo(LOGO_1_LEFT+32, LOGO_1_TOP+17);
|
||||||
|
LineTo(LOGO_1_LEFT+32, LOGO_1_TOP+47);
|
||||||
|
|
||||||
|
SetColor(GRAY_COLOR, GRAY_COLOR);
|
||||||
|
MoveTo(LOGO_1_LEFT+1, LOGO_1_TOP+35);
|
||||||
|
LineTo(LOGO_1_LEFT+12, LOGO_1_TOP+46);
|
||||||
|
LineTo(LOGO_1_LEFT+29, LOGO_1_TOP+46);
|
||||||
|
LineTo(LOGO_1_LEFT+29, LOGO_1_TOP+32);
|
||||||
|
SetColor(WHITE_COLOR, LTGRAY_COLOR);
|
||||||
|
LineTo(LOGO_1_LEFT+0, LOGO_1_TOP+32);
|
||||||
|
LineTo(LOGO_1_LEFT+0, LOGO_1_TOP+35);
|
||||||
|
|
||||||
|
// paint the 3D program title
|
||||||
|
Paint3DHeadline(szIntroTitle, BODY_LEFT, TITLE_TOP);
|
||||||
|
|
||||||
|
// now the rest of the stuff ...
|
||||||
|
SetColor(BLACK_COLOR);
|
||||||
|
#define WH_RECT(L,T,W,H) L, T, L + W, T + H
|
||||||
|
|
||||||
|
Rect rect;
|
||||||
|
SetRect(&rect, WH_RECT(221, BODY_TOP, 230, 60));
|
||||||
|
TETextBox(szIntroSubTitle, strlen(szIntroSubTitle), &rect, teFlushDefault);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
// Paint the Copyright Notice
|
// Paint the Copyright Notice
|
||||||
|
GetDC(hMainWnd);
|
||||||
SetColor(GRAY_COLOR);
|
SetColor(GRAY_COLOR);
|
||||||
TextOut(15, 298, szCopyright_1);
|
TextOut(15, 298, szCopyright_1);
|
||||||
TextOut(15, 311, szCopyright_2);
|
TextOut(15, 311, szCopyright_2);
|
||||||
|
ReleaseDC(hMainWnd);
|
||||||
}
|
}
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// WM_COMMAND : a button was pressed
|
// WM_COMMAND : a button was pressed
|
||||||
|
@ -81,7 +161,7 @@ void WndProc(long iMessage, uint16_t wParam) {
|
||||||
SpinUpIomegaCartridge(CurrentDevice);
|
SpinUpIomegaCartridge(CurrentDevice);
|
||||||
break;
|
break;
|
||||||
case DISK_AT_SPEED:
|
case DISK_AT_SPEED:
|
||||||
printf("Testing the disk\n");
|
printf("\nTesting the disk\n");
|
||||||
if(TestingPhase != READY_TO_TEST) {
|
if(TestingPhase != READY_TO_TEST) {
|
||||||
PrepareToBeginTesting();
|
PrepareToBeginTesting();
|
||||||
}
|
}
|
||||||
|
@ -97,6 +177,7 @@ void WndProc(long iMessage, uint16_t wParam) {
|
||||||
EjectIomegaCartridge(CurrentDevice);
|
EjectIomegaCartridge(CurrentDevice);
|
||||||
break;
|
break;
|
||||||
case DISK_LOW_SPARES:
|
case DISK_LOW_SPARES:
|
||||||
|
CartridgeStatus = DISK_AT_SPEED;
|
||||||
SetRichEditText(szNotRunning);
|
SetRichEditText(szNotRunning);
|
||||||
SetWindowText(hTestButton, szPressToStart);
|
SetWindowText(hTestButton, szPressToStart);
|
||||||
PrepareToBeginTesting();
|
PrepareToBeginTesting();
|
||||||
|
@ -110,18 +191,6 @@ void WndProc(long iMessage, uint16_t wParam) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BtnList tipBtns[] = {
|
|
||||||
{IDB_BACK, szBack, 157, 301, 80, 24},
|
|
||||||
{IDB_NEXT, szNext, 236, 301, 80, 24},
|
|
||||||
{IDB_QUIT, szQuit, 402, 301, 45, 24},
|
|
||||||
// For Mac TIP only
|
|
||||||
{IDB_TEST, szPressToStart, 157, 301, 150, 24},
|
|
||||||
{IDB_EXPL, "Explain", 330, 301, 60, 24},
|
|
||||||
{IDB_OKAY, "Okay", 380, 301, 65, 24},
|
|
||||||
{IDB_READ, "Open in SimpleText...", 210, 301, 160, 24},
|
|
||||||
{0, 0, 0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SUNKEN FIELDS
|
* SUNKEN FIELDS
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -270,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.
|
* 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) {
|
void PaintTestStatistics(bool Active) {
|
||||||
char szString[40];
|
char szString[40];
|
||||||
// assemble and paint the sector testing range
|
// assemble and paint the sector testing range
|
||||||
|
@ -292,12 +370,7 @@ void PaintTestStatistics(bool Active) {
|
||||||
PaintCenteredString(76, 155, 126, 14, szString, Active);
|
PaintCenteredString(76, 155, 126, 14, szString, Active);
|
||||||
|
|
||||||
// show the LastError
|
// show the LastError
|
||||||
char *errStr = 0;
|
PaintCenteredString(76, 172, 126, 14, FindErrorString(LastError), Active);
|
||||||
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);
|
|
||||||
|
|
||||||
// show the elapsed time
|
// show the elapsed time
|
||||||
CvrtSecondsToHMSstring(szString, SecondsElapsed);
|
CvrtSecondsToHMSstring(szString, SecondsElapsed);
|
||||||
|
@ -369,7 +442,10 @@ void TestMonitorWndProc() {
|
||||||
PaintTextArray(TestGrayText, GRAY_COLOR);
|
PaintTextArray(TestGrayText, GRAY_COLOR);
|
||||||
PaintTestPhase();
|
PaintTestPhase();
|
||||||
|
|
||||||
// TODO: paint the little speaker icon
|
// paint the little speaker icon
|
||||||
|
Rect theRect;
|
||||||
|
SetRect(&theRect, 232, 191, 232+16, 191+16);
|
||||||
|
PlotIconID(&theRect, atTopLeft, 0, 129);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -436,5 +512,7 @@ void AllowProgramExit() {
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
void ErrorSound() {
|
void ErrorSound() {
|
||||||
SysBeep(10);
|
if(SendMessage(hSoundCheckbox, BM_GETCHECK) == BST_CHECKED) {
|
||||||
|
SysBeep(10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,22 @@
|
||||||
|
#include <stdlib.h>
|
||||||
#include "ctype.h"
|
#include "ctype.h"
|
||||||
|
|
||||||
extern WindowPtr tipWindow;
|
extern WindowPtr tipWindow;
|
||||||
|
|
||||||
void run_tip();
|
void run_tip();
|
||||||
|
|
||||||
|
typedef enum TipPage {
|
||||||
|
INTRO_PAGE,
|
||||||
|
PERFORM_TEST_PAGE,
|
||||||
|
EXPLAIN_RESULTS,
|
||||||
|
} TipPage;
|
||||||
|
|
||||||
#define MINIMUM_JAZ_SPARES 500
|
#define MINIMUM_JAZ_SPARES 500
|
||||||
#define MAXIMUM_JAZ_SPARES 2557
|
#define MAXIMUM_JAZ_SPARES 2557
|
||||||
#define MINIMUM_ZIP_SPARES 50
|
#define MINIMUM_ZIP_SPARES 50
|
||||||
#define MAXIMUM_ZIP_SPARES 126
|
#define MAXIMUM_ZIP_SPARES 126
|
||||||
|
|
||||||
|
extern TipPage CurrentPage;
|
||||||
extern long CurrentDevice;
|
extern long CurrentDevice;
|
||||||
extern long DriveCount;
|
extern long DriveCount;
|
||||||
extern long JazDrive; // true if the current drive
|
extern long JazDrive; // true if the current drive
|
||||||
|
@ -16,6 +24,7 @@ extern long CartridgeStatus;
|
||||||
extern long LastLBAOnCartridge;
|
extern long LastLBAOnCartridge;
|
||||||
extern uint32_t StartingInstant;
|
extern uint32_t StartingInstant;
|
||||||
extern long NumberOfLBAs;
|
extern long NumberOfLBAs;
|
||||||
|
extern long AdapterMaxSectors;
|
||||||
extern long Side_0_SparesCount; // JAZ has only one count
|
extern long Side_0_SparesCount; // JAZ has only one count
|
||||||
extern long Side_1_SparesCount; // ZIP has counts for both sides
|
extern long Side_1_SparesCount; // ZIP has counts for both sides
|
||||||
extern long Initial_Side_0_Spares;
|
extern long Initial_Side_0_Spares;
|
||||||
|
@ -74,6 +83,8 @@ enum {
|
||||||
#define WM_COMMAND 2
|
#define WM_COMMAND 2
|
||||||
#define SW_SHOW 1
|
#define SW_SHOW 1
|
||||||
#define SW_HIDE 2
|
#define SW_HIDE 2
|
||||||
|
#define BM_GETCHECK 1
|
||||||
|
#define BST_CHECKED 1
|
||||||
|
|
||||||
void SetRGBColor(long color, RGBColor *rgbColor);
|
void SetRGBColor(long color, RGBColor *rgbColor);
|
||||||
void SetColor(long color);
|
void SetColor(long color);
|
||||||
|
@ -91,6 +102,7 @@ void SetWindowText(int id, const char *str);
|
||||||
void EnableWindow(int id, bool enabled);
|
void EnableWindow(int id, bool enabled);
|
||||||
void ShowWindow(ControlHandle hCntl, int state);
|
void ShowWindow(ControlHandle hCntl, int state);
|
||||||
void ShowWindow(int id, int state);
|
void ShowWindow(int id, int state);
|
||||||
|
long SendMessage(int id, int msg);
|
||||||
void InvalidateRect(int id);
|
void InvalidateRect(int id);
|
||||||
void Rectangle(int left, int top, int right, int bottom);
|
void Rectangle(int left, int top, int right, int bottom);
|
||||||
void DrawEdge(Rect *qrc, int edge, int grfFlags);
|
void DrawEdge(Rect *qrc, int edge, int grfFlags);
|
||||||
|
@ -99,6 +111,8 @@ void StopApplicationTimer();
|
||||||
void PostQuitMessage();
|
void PostQuitMessage();
|
||||||
unsigned long GetSystemTime();
|
unsigned long GetSystemTime();
|
||||||
bool PrepareDC(int which);
|
bool PrepareDC(int which);
|
||||||
|
void SplashTheBitmap();
|
||||||
|
void Paint3DHeadline();
|
||||||
|
|
||||||
#define GetDC(h) {GrafPtr oldPort; \
|
#define GetDC(h) {GrafPtr oldPort; \
|
||||||
GetPort(&oldPort); \
|
GetPort(&oldPort); \
|
||||||
|
@ -141,6 +155,9 @@ enum {
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* STRINGS
|
* STRINGS
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
extern const char *szIntroTitle;
|
||||||
|
extern const char *szIntroSubTitle;
|
||||||
|
extern const char *szIntroText;
|
||||||
|
|
||||||
extern const char *szWindowTitle;
|
extern const char *szWindowTitle;
|
||||||
extern const char *szCopyright_1;
|
extern const char *szCopyright_1;
|
||||||
|
@ -221,15 +238,18 @@ extern const char *szQuit;
|
||||||
#define IDB_EXPL 0xFF04
|
#define IDB_EXPL 0xFF04
|
||||||
#define IDB_OKAY 0xFF05
|
#define IDB_OKAY 0xFF05
|
||||||
#define IDB_READ 0xFF06
|
#define IDB_READ 0xFF06
|
||||||
|
#define IDB_BEEP 0xFF07
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
hDefault,
|
hDefault,
|
||||||
hMainWnd,
|
hMainWnd,
|
||||||
hTestMonitor,
|
hTestMonitor,
|
||||||
hTestButton = IDB_TEST,
|
hTestButton = IDB_TEST,
|
||||||
hExitButton = IDB_QUIT,
|
hExitButton = IDB_QUIT,
|
||||||
|
hSoundCheckbox = IDB_BEEP,
|
||||||
// Extras added by MLT
|
// Extras added by MLT
|
||||||
hExplainWnd = IDB_EXPL
|
hIntroWnd = 5,
|
||||||
|
hExplainWnd = IDB_EXPL
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -239,10 +259,13 @@ typedef struct {
|
||||||
int y;
|
int y;
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
|
int type;
|
||||||
ControlHandle hndl;
|
ControlHandle hndl;
|
||||||
} BtnList;
|
} BtnList;
|
||||||
extern BtnList tipBtns[];
|
extern BtnList tipBtns[];
|
||||||
|
|
||||||
|
extern Rect CS_Stat, TP_Perc, SS_Jaz, SS_Sid0, TL_Sect, ES_Read, SE_Rect;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* FUNCTION PROTOTYPES
|
* FUNCTION PROTOTYPES
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -259,6 +282,8 @@ void PaintTheBarGraphs(bool Active);
|
||||||
void PaintTestStatistics(bool Active);
|
void PaintTestStatistics(bool Active);
|
||||||
void CvrtSecondsToHMSstring(char *szString, long seconds);
|
void CvrtSecondsToHMSstring(char *szString, long seconds);
|
||||||
|
|
||||||
|
char *FindErrorString(long error);
|
||||||
|
|
||||||
void UpdateCurrentSector();
|
void UpdateCurrentSector();
|
||||||
void UpdateRunTimeDisplay();
|
void UpdateRunTimeDisplay();
|
||||||
void UpdateRunPhaseDisplay();
|
void UpdateRunPhaseDisplay();
|
||||||
|
@ -267,6 +292,7 @@ void AllowProgramExit();
|
||||||
void ErrorSound();
|
void ErrorSound();
|
||||||
void ProcessPendingMessages();
|
void ProcessPendingMessages();
|
||||||
void WinMain(uint8_t *DrivesSkipped);
|
void WinMain(uint8_t *DrivesSkipped);
|
||||||
|
void Paint3DHeadline(const char *pszText, int Xleft, int Ytop);
|
||||||
void WndProc(long iMessage, uint16_t wParam);
|
void WndProc(long iMessage, uint16_t wParam);
|
||||||
void TestMonitorWndProc();
|
void TestMonitorWndProc();
|
||||||
void ApplicationTimerProc();
|
void ApplicationTimerProc();
|
||||||
|
@ -274,12 +300,12 @@ void TestButtonClicked();
|
||||||
|
|
||||||
int GetDriveEntryOffset(short Device);
|
int GetDriveEntryOffset(short Device);
|
||||||
void GetCommandDetails(char command, char &cmd_flags, char &cmd_length);
|
void GetCommandDetails(char command, char &cmd_flags, char &cmd_length);
|
||||||
long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, short IoBufLen);
|
long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, size_t IoBufLen);
|
||||||
long EnumerateIomegaDevices(uint8_t *DrivesSkipped);
|
long EnumerateIomegaDevices(uint8_t *DrivesSkipped);
|
||||||
long GetModePage(short Device, short PageToGet, void *pBuffer, short BufLen);
|
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 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 GetNonSenseData(short Device, short DataPage, void *Buffer, short BufLen);
|
||||||
long LockCurrentDrive();
|
long LockCurrentDrive();
|
||||||
long UnlockCurrentDrive();
|
long UnlockCurrentDrive();
|
||||||
|
@ -287,9 +313,9 @@ void UnlockAllMedia();
|
||||||
long SpinUpIomegaCartridge(short Device);
|
long SpinUpIomegaCartridge(short Device);
|
||||||
void EjectAllMedia();
|
void EjectAllMedia();
|
||||||
long GetSpareSectorCounts(char);
|
long GetSpareSectorCounts(char);
|
||||||
uint8_t GetCartridgeStatus(long Device);
|
uint8_t GetCartridgeStatus(long Device, uint8_t flags);
|
||||||
void HandleDriveChanging();
|
void HandleDriveChanging();
|
||||||
void SetCartridgeStatusToEAX(long eax);
|
void SetCartridgeStatusToEAX(long eax, uint8_t flags);
|
||||||
void EjectIomegaCartridge(int Device);
|
void EjectIomegaCartridge(int Device);
|
||||||
long PerformRegionTransfer(short XferCmd, void *pBuffer);
|
long PerformRegionTransfer(short XferCmd, void *pBuffer);
|
||||||
void TestTheDisk();
|
void TestTheDisk();
|
||||||
|
|
|
@ -6,8 +6,28 @@
|
||||||
#include "tip.h"
|
#include "tip.h"
|
||||||
|
|
||||||
//#define DEMO
|
//#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
|
#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_LITTLE_ENDIAN(a) a // Don't do anything on 68000
|
||||||
#define MAKE_BIG_ENDIAN(a) a // Don't do anything on 68000
|
#define MAKE_BIG_ENDIAN(a) a // Don't do anything on 68000
|
||||||
|
|
||||||
|
@ -71,10 +91,10 @@ struct DEFECT_LIST_HEADER {
|
||||||
|
|
||||||
#define DRIVE_A_SUPPORT_BIAS 32 // reduce total by 32 for DRIVE A support
|
#define DRIVE_A_SUPPORT_BIAS 32 // reduce total by 32 for DRIVE A support
|
||||||
|
|
||||||
#define BYTES_PER_SECTOR 512
|
#define BYTES_PER_SECTOR 512
|
||||||
#define MAX_SECTORS_PER_TEST 25
|
#define MAX_SECTORS_PER_TEST 128
|
||||||
|
|
||||||
#define BADNESS_THRESHOLD 10
|
#define BADNESS_THRESHOLD 10
|
||||||
|
|
||||||
#define SS_ERR 0x00000004
|
#define SS_ERR 0x00000004
|
||||||
#define DEFECT_LIST_READ_ERROR 0x001c0003
|
#define DEFECT_LIST_READ_ERROR 0x001c0003
|
||||||
|
@ -89,12 +109,20 @@ struct DEFECT_LIST_HEADER {
|
||||||
|
|
||||||
#define CHECK_CONDITION 0x02
|
#define CHECK_CONDITION 0x02
|
||||||
|
|
||||||
|
TipPage CurrentPage;
|
||||||
long CurrentDevice = -1; // the device that's been recognized
|
long CurrentDevice = -1; // the device that's been recognized
|
||||||
long DriveCount = 0;
|
long DriveCount = 0;
|
||||||
|
|
||||||
long JazDrive = 0; // true if the current drive
|
long JazDrive = 0; // true if the current drive
|
||||||
long CartridgeStatus = DISK_NOT_PRESENT;
|
long CartridgeStatus = DISK_NOT_PRESENT;
|
||||||
|
|
||||||
|
#ifdef SUPRESS_ER_ERRORS
|
||||||
|
Boolean SupressEarlyRecovery = false;
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPRESS_DEFECTS_ERROR
|
||||||
|
Boolean SupressDefectsError = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long StartingInstant;
|
unsigned long StartingInstant;
|
||||||
|
|
||||||
// ----------------------------- Run Time Variables ------------------------------
|
// ----------------------------- Run Time Variables ------------------------------
|
||||||
|
@ -108,6 +136,7 @@ long TestingPhase = 0; // 0 = not testing, no data ...
|
||||||
long PercentComplete;
|
long PercentComplete;
|
||||||
long FirstLBASector;
|
long FirstLBASector;
|
||||||
long NumberOfLBAs;
|
long NumberOfLBAs;
|
||||||
|
long AdapterMaxSectors;
|
||||||
long LastLBAOnCartridge;
|
long LastLBAOnCartridge;
|
||||||
long SecondsElapsed;
|
long SecondsElapsed;
|
||||||
long SoftErrors;
|
long SoftErrors;
|
||||||
|
@ -188,12 +217,14 @@ void GetCommandDetails(char command, char &cmd_flags, char &cmd_length) {
|
||||||
* length to an IoBuffer for the command. It returns the complete
|
* length to an IoBuffer for the command. It returns the complete
|
||||||
* three-byte sense code from the command.
|
* three-byte sense code from the command.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, short IoBufLen) {
|
long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, size_t IoBufLen) {
|
||||||
char cmd_length, cmd_flags, cmd_status;
|
char cmd_length, cmd_flags, cmd_status;
|
||||||
GetCommandDetails(lpCmdBlk[0], cmd_flags, cmd_length);
|
GetCommandDetails(lpCmdBlk[0], cmd_flags, cmd_length);
|
||||||
// call the SCSI interface to forward the command to the device
|
// call the SCSI interface to forward the command to the device
|
||||||
OSErr err = scsi_cmd(Device, lpCmdBlk, cmd_length, lpIoBuf, IoBufLen, 0, cmd_flags, &cmd_status);
|
OSErr err = scsi_cmd(Device, lpCmdBlk, cmd_length, lpIoBuf, IoBufLen, 0, cmd_flags, &cmd_status);
|
||||||
if(err != noErr) {
|
if(err != noErr) {
|
||||||
|
// else, if it's *NOT* a "Sense Data" error (SS_ERR)
|
||||||
|
LastError = err | 0x00FFFF00; // [00 FF FF er]
|
||||||
return SS_ERR;
|
return SS_ERR;
|
||||||
}
|
}
|
||||||
if(cmd_status == 0) {
|
if(cmd_status == 0) {
|
||||||
|
@ -207,15 +238,16 @@ long SCSICommand(short Device, char *lpCmdBlk, void *lpIoBuf, short IoBufLen) {
|
||||||
printf("SCSI CHECK CONDITION (KEY %x, ASC %x, ASCQ %x)\n", sense_data.key, sense_data.asc, sense_data.ascq);
|
printf("SCSI CHECK CONDITION (KEY %x, ASC %x, ASCQ %x)\n", sense_data.key, sense_data.asc, sense_data.ascq);
|
||||||
// okay, we have an SS_ERR condition, let's check the SENSE DATA
|
// okay, we have an SS_ERR condition, let's check the SENSE DATA
|
||||||
// assemble [00 ASC ASCQ SenseKey]
|
// assemble [00 ASC ASCQ SenseKey]
|
||||||
long res = (long(sense_data.asc) << 16) |
|
const long res = (long(sense_data.asc) << 16) |
|
||||||
(long(sense_data.ascq) << 8) |
|
(long(sense_data.ascq) << 8) |
|
||||||
(long(sense_data.key) );
|
(long(sense_data.key) );
|
||||||
if(res == MEDIA_CHANGE_CODE) {
|
if(res == MEDIA_CHANGE_CODE) {
|
||||||
|
printf("Media change signalled. Most recent error can be ignored\n\n");
|
||||||
int index = GetDriveEntryOffset(Device);
|
int index = GetDriveEntryOffset(Device);
|
||||||
DriveArray[index].flags |= MEDIA_CHANGED;
|
DriveArray[index].flags |= MEDIA_CHANGED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return res;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// else, if it's *NOT* a "Sense Data" error (SS_ERR)
|
// else, if it's *NOT* a "Sense Data" error (SS_ERR)
|
||||||
|
@ -274,7 +306,7 @@ long EnumerateIomegaDevices(uint8_t *DrivesSkipped) {
|
||||||
|
|
||||||
// On the Mac, we want to ignore drives that have media in them at
|
// On the Mac, we want to ignore drives that have media in them at
|
||||||
// program entry, as this means the volume is mounted in Mac OS
|
// program entry, as this means the volume is mounted in Mac OS
|
||||||
const bool driveEmpty = GetCartridgeStatus(Device) == DISK_NOT_PRESENT;
|
const bool driveEmpty = (GetCartridgeStatus(Device, flags) == DISK_NOT_PRESENT);
|
||||||
if(driveEmpty) {
|
if(driveEmpty) {
|
||||||
DriveArray[DriveCount].flags = flags;
|
DriveArray[DriveCount].flags = flags;
|
||||||
DriveArray[DriveCount].scsi_id = Device;
|
DriveArray[DriveCount].scsi_id = Device;
|
||||||
|
@ -308,13 +340,18 @@ long GetModePage(short Device, short PageToGet, void *pBuffer, short BufLen) {
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SET MODE PAGE
|
* SET MODE PAGE
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
long SetModePage(short Device, void *pBuffer) {
|
long SetModePage(short Device, void *pBuffer, short BufLen) {
|
||||||
char* ebx = (char*) pBuffer; // get a pointer to the top of buffer
|
unsigned char* ebx = (unsigned char*) pBuffer; // get a pointer to the top of buffer
|
||||||
char ecx = ebx[0] + 1; // adjust it up by one
|
unsigned char ecx = ebx[0] + 1; // adjust it up by one
|
||||||
|
|
||||||
ebx[0] = 0; // now clear the two reserved bytes
|
ebx[0] = 0; // now clear the two reserved bytes
|
||||||
ebx[2] = 0;
|
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
|
char Scsi[6] = {0}; // init the SCSI parameter block
|
||||||
Scsi[0] = SCSI_Cmd_ModeSelect; // set the command
|
Scsi[0] = SCSI_Cmd_ModeSelect; // set the command
|
||||||
Scsi[1] = 0x10; // set the Page Format bit
|
Scsi[1] = 0x10; // set the Page Format bit
|
||||||
|
@ -339,16 +376,21 @@ void ModifyModePage(char *PageBuff, char ecc, char retries) {
|
||||||
ebx[8] = retries; // then set the write count too
|
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];
|
char PageBuff[40];
|
||||||
|
|
||||||
#ifdef NO_EXCESS_READS
|
#ifdef NO_EXCESS_READS
|
||||||
// Limit reads to 20 bytes on Zip to prevent controller errors
|
// Limit reads to 20 bytes on Zip (24 bytes on Jaz) to prevent controller errors
|
||||||
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, JazDrive ? sizeof(PageBuff) : 20);
|
const short pageBuffLen = JazDrive ? 24 : 20;
|
||||||
#else
|
#else
|
||||||
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, sizeof(PageBuff));
|
const short pageBuffLen = sizeof(PageBuff);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
long eax = GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, pageBuffLen);
|
||||||
|
if(eax) {
|
||||||
|
printf("SetErrorRecovery failed\n");
|
||||||
|
return eax;
|
||||||
|
}
|
||||||
|
|
||||||
#define EARLY_RECOVERY 0x08
|
#define EARLY_RECOVERY 0x08
|
||||||
#define PER 0x04
|
#define PER 0x04
|
||||||
#define SUPPRESS_ECC 0x01
|
#define SUPPRESS_ECC 0x01
|
||||||
|
@ -356,6 +398,9 @@ void SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
|
||||||
// set the ECC fields
|
// set the ECC fields
|
||||||
char ecc = SUPPRESS_ECC; // presume ECC suppression
|
char ecc = SUPPRESS_ECC; // presume ECC suppression
|
||||||
if(ECC) {
|
if(ECC) {
|
||||||
|
#ifdef SUPRESS_ER_ERRORS
|
||||||
|
if(!SupressEarlyRecovery)
|
||||||
|
#endif
|
||||||
ecc = EARLY_RECOVERY; // enable ECC and Early Recovery
|
ecc = EARLY_RECOVERY; // enable ECC and Early Recovery
|
||||||
if(Testing) {
|
if(Testing) {
|
||||||
ecc = EARLY_RECOVERY | PER; // we're testing, so EER & PER
|
ecc = EARLY_RECOVERY | PER; // we're testing, so EER & PER
|
||||||
|
@ -370,14 +415,22 @@ void SetErrorRecovery(bool Retries, bool ECC, bool Testing) {
|
||||||
retries = 0;
|
retries = 0;
|
||||||
|
|
||||||
ModifyModePage(PageBuff, ecc, retries);
|
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 we had an invalid field in the CDB (the EER bit was on)
|
||||||
if (eax == 0x00260005) {
|
if (eax == 0x00260005) {
|
||||||
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, sizeof(PageBuff));
|
GetModePage(CurrentDevice, ERROR_RECOVERY_PAGE, PageBuff, pageBuffLen);
|
||||||
ecc &= ~0x08; // same, *BUT*NOT* Early Recovery
|
ecc &= ~EARLY_RECOVERY; // same, *BUT*NOT* Early Recovery
|
||||||
ModifyModePage(PageBuff, ecc, retries);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -464,7 +517,18 @@ long GetSpareSectorCounts(char checkPassword) {
|
||||||
Scsi[0] = SCSI_Cmd_ReadDefectData;
|
Scsi[0] = SCSI_Cmd_ReadDefectData;
|
||||||
Scsi[2] = 0x1e; // 0b00011110 defect format, G/P bits
|
Scsi[2] = 0x1e; // 0b00011110 defect format, G/P bits
|
||||||
Scsi[8] = 4; // ask for only FOUR bytes
|
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));
|
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)) {
|
if ((!eax) || (eax == INCOMPATIBLE_MEDIA)) {
|
||||||
// we could read its defect list ... so show it!
|
// we could read its defect list ... so show it!
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
@ -570,10 +634,11 @@ Rescan:
|
||||||
do {
|
do {
|
||||||
// clear media changed status
|
// clear media changed status
|
||||||
DriveArray[i].flags &= ~MEDIA_CHANGED;
|
DriveArray[i].flags &= ~MEDIA_CHANGED;
|
||||||
GetCartridgeStatus(scsi_id);
|
GetCartridgeStatus(scsi_id, DriveArray[i].flags);
|
||||||
} while(DriveArray[i].flags & MEDIA_CHANGED); // do it until NO media change!
|
} while(DriveArray[i].flags & MEDIA_CHANGED); // do it until NO media change!
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
status = GetCartridgeStatus(scsi_id);
|
status = GetCartridgeStatus(scsi_id, DriveArray[i].flags);
|
||||||
|
if (status == DISK_STATUS_UNKNOWN) continue; // added by MLT
|
||||||
// if the device we have is NOT the currently selected one
|
// if the device we have is NOT the currently selected one
|
||||||
if(scsi_id != CurrentDevice) {
|
if(scsi_id != CurrentDevice) {
|
||||||
// if the disk is ANYTHING other than not present ...
|
// if the disk is ANYTHING other than not present ...
|
||||||
|
@ -589,6 +654,7 @@ Rescan:
|
||||||
// then set the current drive ...
|
// then set the current drive ...
|
||||||
else if ((DriveArray[i].flags & DISK_EJECTING) == 0) {
|
else if ((DriveArray[i].flags & DISK_EJECTING) == 0) {
|
||||||
CurrentDevice = scsi_id;
|
CurrentDevice = scsi_id;
|
||||||
|
printf("Selected SCSI ID %ld\n", CurrentDevice);
|
||||||
TestingPhase = 0;
|
TestingPhase = 0;
|
||||||
Selecting = true;
|
Selecting = true;
|
||||||
//goto Rescan;
|
//goto Rescan;
|
||||||
|
@ -604,13 +670,13 @@ Rescan:
|
||||||
// it is *NOT* empty! If it *IS* empty, kill current
|
// it is *NOT* empty! If it *IS* empty, kill current
|
||||||
if(status == DISK_NOT_PRESENT) {
|
if(status == DISK_NOT_PRESENT) {
|
||||||
CurrentDevice = -1;
|
CurrentDevice = -1;
|
||||||
SetCartridgeStatusToEAX(status);
|
SetCartridgeStatusToEAX(status, DriveArray[i].flags);
|
||||||
}
|
}
|
||||||
// if it's not already set correctly *and* either
|
// if it's not already set correctly *and* either
|
||||||
// the cart status is one of the pre-test ones, or
|
// the cart status is one of the pre-test ones, or
|
||||||
// the NEW status from the cart is NOT "at speed" ...
|
// the NEW status from the cart is NOT "at speed" ...
|
||||||
if((status != CartridgeStatus) && ((CartridgeStatus <= DISK_STALLED) || (status != DISK_AT_SPEED))) {
|
if((status != CartridgeStatus) && ((CartridgeStatus <= DISK_STALLED) || (status != DISK_AT_SPEED))) {
|
||||||
SetCartridgeStatusToEAX(status);
|
SetCartridgeStatusToEAX(status, DriveArray[i].flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -618,18 +684,18 @@ Rescan:
|
||||||
if ((CurrentDevice == -1) &&
|
if ((CurrentDevice == -1) &&
|
||||||
(status == DISK_NOT_PRESENT) &&
|
(status == DISK_NOT_PRESENT) &&
|
||||||
(CartridgeStatus != DISK_NOT_PRESENT)) {
|
(CartridgeStatus != DISK_NOT_PRESENT)) {
|
||||||
SetCartridgeStatusToEAX(status);
|
SetCartridgeStatusToEAX(status, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// GET CARTRIDGE STATUS
|
// GET CARTRIDGE STATUS
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
uint8_t GetCartridgeStatus(long Device) {
|
uint8_t GetCartridgeStatus(long Device, uint8_t flags) {
|
||||||
long eax;
|
long eax;
|
||||||
char DiskStat[72];
|
char DiskStat[72];
|
||||||
#ifdef NO_EXCESS_READS
|
#ifdef NO_EXCESS_READS
|
||||||
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, JazDrive ? sizeof(DiskStat) : 63);
|
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, 4);
|
||||||
if (eax) return DISK_STATUS_UNKNOWN;
|
if (eax) return DISK_STATUS_UNKNOWN;
|
||||||
#else
|
#else
|
||||||
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, sizeof(DiskStat));
|
eax = GetNonSenseData(Device, DISK_STATUS_PAGE, DiskStat, sizeof(DiskStat));
|
||||||
|
@ -646,7 +712,9 @@ uint8_t GetCartridgeStatus(long Device) {
|
||||||
// SetCartridgeStatusToEAX
|
// SetCartridgeStatusToEAX
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void SetCartridgeStatusToEAX(long eax) {
|
void SetCartridgeStatusToEAX(long eax, uint8_t flags) {
|
||||||
|
JazDrive = flags & JAZ_DRIVE;
|
||||||
|
|
||||||
long PriorStatus = CartridgeStatus;
|
long PriorStatus = CartridgeStatus;
|
||||||
CartridgeStatus = eax;
|
CartridgeStatus = eax;
|
||||||
|
|
||||||
|
@ -666,6 +734,7 @@ void SetCartridgeStatusToEAX(long eax) {
|
||||||
SetRichEditText(szNotRunning);
|
SetRichEditText(szNotRunning);
|
||||||
goto DisableActions;
|
goto DisableActions;
|
||||||
case DISK_AT_SPEED:
|
case DISK_AT_SPEED:
|
||||||
|
printf("Disk at speed\n");
|
||||||
eax = GetSpareSectorCounts(true); // update the Cart Condition
|
eax = GetSpareSectorCounts(true); // update the Cart Condition
|
||||||
if(eax == MEDIA_NOT_PRESENT) {
|
if(eax == MEDIA_NOT_PRESENT) {
|
||||||
goto DisableActions;
|
goto DisableActions;
|
||||||
|
@ -678,10 +747,14 @@ void SetCartridgeStatusToEAX(long eax) {
|
||||||
FirmErrors = 0;
|
FirmErrors = 0;
|
||||||
// check to see if we have enough spares to start
|
// check to see if we have enough spares to start
|
||||||
if(JazDrive) {
|
if(JazDrive) {
|
||||||
|
printf("Spare Sectors: %ld/%d\n", Side_0_SparesCount, MAXIMUM_JAZ_SPARES);
|
||||||
if(Side_0_SparesCount < MINIMUM_JAZ_SPARES)
|
if(Side_0_SparesCount < MINIMUM_JAZ_SPARES)
|
||||||
goto InsufficientSpares;
|
goto InsufficientSpares;
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
if(Side_0_SparesCount < MINIMUM_ZIP_SPARES) {
|
||||||
goto InsufficientSpares;
|
goto InsufficientSpares;
|
||||||
}
|
}
|
||||||
|
@ -753,6 +826,12 @@ void PrepareToBeginTesting() {
|
||||||
HardErrors = 0;
|
HardErrors = 0;
|
||||||
UserInterrupt = 0;
|
UserInterrupt = 0;
|
||||||
LastError = 0;
|
LastError = 0;
|
||||||
|
#ifdef SUPRESS_ER_ERRORS
|
||||||
|
SupressEarlyRecovery = false;
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPRESS_DEFECTS_ERROR
|
||||||
|
SupressDefectsError = false;
|
||||||
|
#endif
|
||||||
#ifdef DEMO
|
#ifdef DEMO
|
||||||
LastLBAOnCartridge = 99999;
|
LastLBAOnCartridge = 99999;
|
||||||
SoftErrors = 6;
|
SoftErrors = 6;
|
||||||
|
@ -782,7 +861,7 @@ void BumpErrorCounts(long ErrorCode) {
|
||||||
LastError = eax;
|
LastError = eax;
|
||||||
if (eax == 0x320003 || eax == 0x328F03)
|
if (eax == 0x320003 || eax == 0x328F03)
|
||||||
CartridgeStatus = DISK_LOW_SPARES;
|
CartridgeStatus = DISK_LOW_SPARES;
|
||||||
if (eax & 0xFF == 1) // recovered error
|
if ((eax & 0xFF) == 1) // recovered error
|
||||||
SoftErrors++;
|
SoftErrors++;
|
||||||
else
|
else
|
||||||
HardErrors++;
|
HardErrors++;
|
||||||
|
@ -812,12 +891,12 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
||||||
char Scsi[10] = {0}; // clear out the SCSI CDB
|
char Scsi[10] = {0}; // clear out the SCSI CDB
|
||||||
const long InitialHardErrors = HardErrors;
|
const long InitialHardErrors = HardErrors;
|
||||||
|
|
||||||
SetErrorRecovery(false, false, true); // disable Retries & ECC
|
long eax = SetErrorRecovery(false, false, true); // disable Retries & ECC
|
||||||
|
|
||||||
Scsi[0] = XferCmd;
|
Scsi[0] = XferCmd;
|
||||||
SET_DWORD_AT(Scsi, 2, MAKE_BIG_ENDIAN(FirstLBASector)); // WHICH LBA's to read, BIG endian
|
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
|
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 we failed somewhere during our transfer ... let's zero in on it
|
||||||
if (eax) {
|
if (eax) {
|
||||||
if ( eax == SS_ERR || // if it's a CONTROLLER ERROR, skip!
|
if ( eax == SS_ERR || // if it's a CONTROLLER ERROR, skip!
|
||||||
|
@ -826,6 +905,8 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Starting detailed search...\n");
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// Save error and current Soft + Hard Error count to see if we do FIND the glitch ...
|
// 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!
|
const long GlitchError = eax; // save the error which stopped us!
|
||||||
|
@ -855,6 +936,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
||||||
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
|
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
|
||||||
if (eax & 0xFF == 1) goto PostTheError; // did we recover?
|
if (eax & 0xFF == 1) goto PostTheError; // did we recover?
|
||||||
|
|
||||||
|
printf(" Found error, retesting with retries\n");
|
||||||
SetErrorRecovery(true, false, true); // enable retries
|
SetErrorRecovery(true, false, true); // enable retries
|
||||||
eax = SCSICommand(CurrentDevice, Scsi, LocalBuffer, BYTES_PER_SECTOR);
|
eax = SCSICommand(CurrentDevice, Scsi, LocalBuffer, BYTES_PER_SECTOR);
|
||||||
if (eax) {
|
if (eax) {
|
||||||
|
@ -862,7 +944,8 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
||||||
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
|
if (eax == SS_ERR) goto Exit; // if it's a CONTROLLER ERROR, skip!
|
||||||
if (eax & 0xFF == 1) goto PostTheError; // did we recover?
|
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);
|
eax = SCSICommand(CurrentDevice, Scsi, LocalBuffer, BYTES_PER_SECTOR);
|
||||||
if (eax) {
|
if (eax) {
|
||||||
// failed with retries and EEC
|
// failed with retries and EEC
|
||||||
|
@ -880,6 +963,8 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PostTheError:
|
PostTheError:
|
||||||
|
printf(" %s (Sector %ld)\n", FindErrorString(eax), SingleTransferLBA);
|
||||||
|
printf("--------------------------------------------\n");
|
||||||
BumpErrorCounts(eax); // given eax, count the errors
|
BumpErrorCounts(eax); // given eax, count the errors
|
||||||
GetSpareSectorCounts(false); // update the Cart's Condition
|
GetSpareSectorCounts(false); // update the Cart's Condition
|
||||||
UpdateRunTimeDisplay();
|
UpdateRunTimeDisplay();
|
||||||
|
@ -889,6 +974,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
||||||
ProcessPendingMessages();
|
ProcessPendingMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("... detailed search finished\n");
|
||||||
// now see whether we *did* found something to complain about ...
|
// now see whether we *did* found something to complain about ...
|
||||||
eax = SoftErrors + HardErrors;
|
eax = SoftErrors + HardErrors;
|
||||||
if (eax == GlitchCount) {
|
if (eax == GlitchCount) {
|
||||||
|
@ -899,6 +985,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
||||||
long ebx = eax & 0x00FF00FF; // strip the ASCQ byte
|
long ebx = eax & 0x00FF00FF; // strip the ASCQ byte
|
||||||
if(ebx == 0x00110003) // if we're about to say "unrecovered read"
|
if(ebx == 0x00110003) // if we're about to say "unrecovered read"
|
||||||
eax = 0x170101; // change it to: "Read with Retries"
|
eax = 0x170101; // change it to: "Read with Retries"
|
||||||
|
printf("%s\n", FindErrorString(eax));
|
||||||
BumpErrorCounts(eax); // given eax, count the errors
|
BumpErrorCounts(eax); // given eax, count the errors
|
||||||
HardErrors = SavedHardErrors; // restore the counts
|
HardErrors = SavedHardErrors; // restore the counts
|
||||||
SoftErrors = SavedSoftErrors;
|
SoftErrors = SavedSoftErrors;
|
||||||
|
@ -909,6 +996,7 @@ long PerformRegionTransfer(short XferCmd, void *pBuffer) {
|
||||||
eax = 0; // now let's return happiness to our caller
|
eax = 0; // now let's return happiness to our caller
|
||||||
if (HardErrors != InitialHardErrors) // UNRECOVERABLE errors!
|
if (HardErrors != InitialHardErrors) // UNRECOVERABLE errors!
|
||||||
eax = -1;
|
eax = -1;
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
|
@ -921,14 +1009,25 @@ Exit:
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
void TestTheDisk() {
|
void TestTheDisk() {
|
||||||
void *pPatternBuffer = malloc(MAX_SECTORS_PER_TEST * BYTES_PER_SECTOR);
|
// setup the initital maximum tranfer ...
|
||||||
void *pUserDataBuffer = malloc(MAX_SECTORS_PER_TEST * BYTES_PER_SECTOR);
|
AdapterMaxSectors = MAX_SECTORS_PER_TEST; // limit to our max
|
||||||
|
|
||||||
if(pPatternBuffer == NULL || pUserDataBuffer == NULL) {
|
void *pDataBuffer = 0;
|
||||||
printf("Allocation error\n");
|
for(;;) {
|
||||||
return;
|
pDataBuffer = malloc(AdapterMaxSectors * BYTES_PER_SECTOR * 2);
|
||||||
|
if(pDataBuffer) break;
|
||||||
|
AdapterMaxSectors >>= 2; // we need to make it smaller
|
||||||
|
if(AdapterMaxSectors == 0) {
|
||||||
|
printf("Test buffer allocation failed!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Allocated buffer of %ld bytes\n", AdapterMaxSectors * BYTES_PER_SECTOR);
|
||||||
|
|
||||||
|
void *pPatternBuffer = pDataBuffer;
|
||||||
|
void *pUserDataBuffer = (char*) pDataBuffer + AdapterMaxSectors * BYTES_PER_SECTOR;
|
||||||
|
|
||||||
StopApplicationTimer();
|
StopApplicationTimer();
|
||||||
|
|
||||||
PreventProgramExit();
|
PreventProgramExit();
|
||||||
|
@ -939,17 +1038,17 @@ void TestTheDisk() {
|
||||||
InvalidateRect(hTestMonitor);
|
InvalidateRect(hTestMonitor);
|
||||||
|
|
||||||
LockCurrentDrive(); // prevent media removal
|
LockCurrentDrive(); // prevent media removal
|
||||||
|
|
||||||
GetSpareSectorCounts(false); // update the Cart's Condition
|
GetSpareSectorCounts(false); // update the Cart's Condition
|
||||||
UpdateRunTimeDisplay();
|
UpdateRunTimeDisplay();
|
||||||
|
|
||||||
// Standard Testing Operation
|
// Standard Testing Operation
|
||||||
StartingInstant = GetSystemTime();
|
StartingInstant = GetSystemTime();
|
||||||
|
long eax;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ProcessPendingMessages();
|
ProcessPendingMessages();
|
||||||
|
|
||||||
NumberOfLBAs = MAX_SECTORS_PER_TEST;
|
NumberOfLBAs = AdapterMaxSectors;
|
||||||
|
|
||||||
if(LastLBAOnCartridge) {
|
if(LastLBAOnCartridge) {
|
||||||
if (FirstLBASector + NumberOfLBAs > LastLBAOnCartridge + 1) {
|
if (FirstLBASector + NumberOfLBAs > LastLBAOnCartridge + 1) {
|
||||||
|
@ -966,7 +1065,7 @@ void TestTheDisk() {
|
||||||
|
|
||||||
// get a random pattern of data to write
|
// get a random pattern of data to write
|
||||||
const long DataPattern = rand();
|
const long DataPattern = rand();
|
||||||
memset(pPatternBuffer, DataPattern, MAX_SECTORS_PER_TEST * BYTES_PER_SECTOR);
|
memset(pPatternBuffer, DataPattern, AdapterMaxSectors * BYTES_PER_SECTOR);
|
||||||
|
|
||||||
// update the cartridge's status
|
// update the cartridge's status
|
||||||
GetSpareSectorCounts(false); // update the Cart's Condition
|
GetSpareSectorCounts(false); // update the Cart's Condition
|
||||||
|
@ -975,7 +1074,7 @@ void TestTheDisk() {
|
||||||
|
|
||||||
UpdateRunTimeDisplay();
|
UpdateRunTimeDisplay();
|
||||||
|
|
||||||
long eax = PerformRegionTransfer(SCSI_Cmd_ReadMany, pUserDataBuffer);
|
eax = PerformRegionTransfer(SCSI_Cmd_ReadMany, pUserDataBuffer);
|
||||||
|
|
||||||
if(eax == 0) {
|
if(eax == 0) {
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
@ -995,6 +1094,10 @@ void TestTheDisk() {
|
||||||
// if we hit the end of the disk ... exit gracefully!
|
// if we hit the end of the disk ... exit gracefully!
|
||||||
goto GetOut;
|
goto GetOut;
|
||||||
}
|
}
|
||||||
|
else if (eax == SS_ERR) {
|
||||||
|
// added by MLT, exit on controller errors
|
||||||
|
goto GetOut;
|
||||||
|
}
|
||||||
if (CartridgeStatus != DISK_TEST_UNDERWAY) {
|
if (CartridgeStatus != DISK_TEST_UNDERWAY) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1004,8 +1107,7 @@ void TestTheDisk() {
|
||||||
// show that we're post-test
|
// show that we're post-test
|
||||||
|
|
||||||
GetOut:
|
GetOut:
|
||||||
free(pPatternBuffer);
|
free(pDataBuffer);
|
||||||
free(pUserDataBuffer);
|
|
||||||
|
|
||||||
TestingPhase = UNTESTED;
|
TestingPhase = UNTESTED;
|
||||||
UnlockAllMedia();
|
UnlockAllMedia();
|
||||||
|
@ -1015,24 +1117,24 @@ GetOut:
|
||||||
AllowProgramExit();
|
AllowProgramExit();
|
||||||
|
|
||||||
// compute the number of serious troubles
|
// compute the number of serious troubles
|
||||||
const char *eax;
|
const char *result;
|
||||||
long errors = FirmErrors + HardErrors;
|
long errors = FirmErrors + HardErrors;
|
||||||
if (errors >= BADNESS_THRESHOLD) {
|
if (errors >= BADNESS_THRESHOLD) {
|
||||||
eax = szBadResult;
|
result = szBadResult;
|
||||||
}
|
}
|
||||||
else if (UserInterrupt) {
|
else if (UserInterrupt || (eax == SS_ERR)) {
|
||||||
eax = szInterrupted;
|
result = szInterrupted;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// it wasn't interrupted, nor seriously bad, was it perfect?
|
// it wasn't interrupted, nor seriously bad, was it perfect?
|
||||||
errors += SoftErrors;
|
errors += SoftErrors;
|
||||||
if(errors) {
|
if(errors) {
|
||||||
eax = szExplainResult;
|
result = szExplainResult;
|
||||||
} else {
|
} else {
|
||||||
eax = szPerfectResult;
|
result = szPerfectResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetRichEditText(eax);
|
SetRichEditText(result);
|
||||||
InvalidateRect(hTestMonitor);
|
InvalidateRect(hTestMonitor);
|
||||||
Exit:
|
Exit:
|
||||||
StartApplicationTimer();
|
StartApplicationTimer();
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <SIOUX.h>
|
#include <SIOUX.h>
|
||||||
|
|
||||||
|
#include <Menus.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <Quickdraw.h>
|
#include <Quickdraw.h>
|
||||||
|
|
||||||
|
#include "TrapAvail.h"
|
||||||
#include "pstring.h"
|
#include "pstring.h"
|
||||||
#include "LaunchLib.h"
|
#include "LaunchLib.h"
|
||||||
#include "mac_vol.h"
|
#include "mac_vol.h"
|
||||||
|
@ -15,17 +17,13 @@
|
||||||
#include "tip.h"
|
#include "tip.h"
|
||||||
#include "command_line.h"
|
#include "command_line.h"
|
||||||
|
|
||||||
enum TipPage {
|
|
||||||
kTestingPage,
|
|
||||||
kExplainPage,
|
|
||||||
} page;
|
|
||||||
|
|
||||||
static int gDone;
|
static int gDone;
|
||||||
static bool allowColor;
|
static bool allowColor;
|
||||||
static bool inited = false;
|
static bool inited = false;
|
||||||
static bool timerEnabled = false;
|
static bool timerEnabled = false;
|
||||||
static WindowPtr tipWindow;
|
static WindowPtr tipWindow;
|
||||||
static MenuHandle tipMenu;
|
static MenuHandle tipMenu;
|
||||||
|
static PicHandle tipIntroPic;
|
||||||
static TBHandle richText;
|
static TBHandle richText;
|
||||||
static const char *textFileName;
|
static const char *textFileName;
|
||||||
|
|
||||||
|
@ -34,13 +32,14 @@ void DisposeTipWindow();
|
||||||
void AddTipMenus();
|
void AddTipMenus();
|
||||||
void RunCommandLine();
|
void RunCommandLine();
|
||||||
void DoEvent(EventRecord &event, RgnHandle *cursorRgn);
|
void DoEvent(EventRecord &event, RgnHandle *cursorRgn);
|
||||||
void DoMenuEvent(EventRecord &event);
|
void DoMenuEventPostSIOUX(EventRecord &event);
|
||||||
|
bool DoMenuSelection(long choice);
|
||||||
void DoUpdate(WindowPtr window);
|
void DoUpdate(WindowPtr window);
|
||||||
void DoMouseDown(EventRecord &event);
|
void DoMouseDown(EventRecord &event);
|
||||||
void DoMouseMove(EventRecord &event, RgnHandle *cursorRegion);
|
void DoMouseMove(EventRecord &event, RgnHandle *cursorRegion);
|
||||||
void DoDiskEvent(EventRecord &event);
|
void DoDiskEvent(EventRecord &event);
|
||||||
void SetPage(TipPage page);
|
void SetPage(TipPage page);
|
||||||
ControlHandle FindControl(int id);
|
ControlHandle FindCntlHandle(int id);
|
||||||
OSErr GetExplanationFSSpec(const char *name, FSSpec *docSpec);
|
OSErr GetExplanationFSSpec(const char *name, FSSpec *docSpec);
|
||||||
void OpenExplanationInSimpleText();
|
void OpenExplanationInSimpleText();
|
||||||
|
|
||||||
|
@ -55,15 +54,13 @@ void run_tip() {
|
||||||
|
|
||||||
NewTipWindow();
|
NewTipWindow();
|
||||||
EnableWindow(hTestButton, false);
|
EnableWindow(hTestButton, false);
|
||||||
SetRichEditText(szInstructions);
|
|
||||||
|
|
||||||
gDone = false;
|
gDone = false;
|
||||||
do {
|
do {
|
||||||
EventRecord event;
|
EventRecord event;
|
||||||
if (WaitNextEvent(everyEvent, &event, GetCaretTime(), cursorRgn)) {
|
if (WaitNextEvent(everyEvent, &event, GetCaretTime(), cursorRgn)) {
|
||||||
DoEvent(event, &cursorRgn);
|
DoEvent(event, &cursorRgn);
|
||||||
if(!inited && page == kTestingPage) {
|
if(!inited && CurrentPage == PERFORM_TEST_PAGE) {
|
||||||
printf("Starting tip\n");
|
|
||||||
// Start TIP as soon as the user dismisses the intro screen
|
// Start TIP as soon as the user dismisses the intro screen
|
||||||
inited = true;
|
inited = true;
|
||||||
uint8_t drivesSkipped;
|
uint8_t drivesSkipped;
|
||||||
|
@ -88,6 +85,9 @@ void run_tip() {
|
||||||
|
|
||||||
DisposeTipWindow();
|
DisposeTipWindow();
|
||||||
DisposeRgn(cursorRgn);
|
DisposeRgn(cursorRgn);
|
||||||
|
|
||||||
|
// Remount any drives we may have unmounted
|
||||||
|
mac_mount_drives();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewTipWindow() {
|
void NewTipWindow() {
|
||||||
|
@ -128,10 +128,12 @@ void NewTipWindow() {
|
||||||
tipBtns[i].y + tipBtns[i].h - mainWndOrigin.v
|
tipBtns[i].y + tipBtns[i].h - mainWndOrigin.v
|
||||||
);
|
);
|
||||||
StrToPascal(title, tipBtns[i].name);
|
StrToPascal(title, tipBtns[i].name);
|
||||||
tipBtns[i].hndl = NewControl(tipWindow, &rect, title, false, 0, 0, 0, 0, tipBtns[i].id);
|
tipBtns[i].hndl = NewControl(tipWindow, &rect, title, false, 0, 0, 1, tipBtns[i].type, tipBtns[i].id);
|
||||||
}
|
}
|
||||||
|
|
||||||
page = kExplainPage;
|
SetControlValue(FindCntlHandle(IDB_BEEP),1); // Check the sound control
|
||||||
|
|
||||||
|
CurrentPage = EXPLAIN_RESULTS;
|
||||||
GetDC(hExplainWnd);
|
GetDC(hExplainWnd);
|
||||||
|
|
||||||
// Create the text edit widget
|
// Create the text edit widget
|
||||||
|
@ -140,10 +142,20 @@ void NewTipWindow() {
|
||||||
|
|
||||||
ReleaseDC(hExplainWnd);
|
ReleaseDC(hExplainWnd);
|
||||||
|
|
||||||
SetPage(kTestingPage);
|
// Load the About box picture
|
||||||
|
tipIntroPic = GetPicture(128);
|
||||||
|
|
||||||
|
SetPage(INTRO_PAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddTipMenus() {
|
void AddTipMenus() {
|
||||||
|
if(!TrapAvailable(0xAA66)) {
|
||||||
|
// If MenuChoice is available, we can let SIOUX handle the menus,
|
||||||
|
// otherwise we have to handle it ourselves
|
||||||
|
SIOUXSettings.setupmenus = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add our menu
|
||||||
tipMenu = GetMenu(128);
|
tipMenu = GetMenu(128);
|
||||||
InsertMenu(tipMenu, 0);
|
InsertMenu(tipMenu, 0);
|
||||||
DrawMenuBar();
|
DrawMenuBar();
|
||||||
|
@ -166,7 +178,7 @@ void DisposeTipWindow() {
|
||||||
DisposeWindow(tipWindow);
|
DisposeWindow(tipWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlHandle FindControl(int id) {
|
ControlHandle FindCntlHandle(int id) {
|
||||||
for(int i = 0; tipBtns[i].name; i++) {
|
for(int i = 0; tipBtns[i].name; i++) {
|
||||||
if (tipBtns[i].id == id)
|
if (tipBtns[i].id == id)
|
||||||
return tipBtns[i].hndl;
|
return tipBtns[i].hndl;
|
||||||
|
@ -177,11 +189,14 @@ ControlHandle FindControl(int id) {
|
||||||
bool PrepareDC(int which) {
|
bool PrepareDC(int which) {
|
||||||
SetPort(tipWindow);
|
SetPort(tipWindow);
|
||||||
switch(which) {
|
switch(which) {
|
||||||
|
case hIntroWnd:
|
||||||
|
if(CurrentPage != INTRO_PAGE) return false;
|
||||||
|
break;
|
||||||
case hExplainWnd:
|
case hExplainWnd:
|
||||||
if(page != kExplainPage) return false;
|
if(CurrentPage != EXPLAIN_RESULTS) return false;
|
||||||
break;
|
break;
|
||||||
case hTestMonitor:
|
case hTestMonitor:
|
||||||
if(page != kTestingPage) return false;
|
if(CurrentPage != PERFORM_TEST_PAGE) return false;
|
||||||
SetOrigin(-20, -10);
|
SetOrigin(-20, -10);
|
||||||
break;
|
break;
|
||||||
case hMainWnd:
|
case hMainWnd:
|
||||||
|
@ -204,36 +219,54 @@ void DoEvent(EventRecord &event, RgnHandle *cursorRgn) {
|
||||||
case osEvt: DoMouseMove(event, cursorRgn); break;
|
case osEvt: DoMouseMove(event, cursorRgn); break;
|
||||||
}
|
}
|
||||||
} else { // Trap unhandled SIOUX menu events
|
} else { // Trap unhandled SIOUX menu events
|
||||||
DoMenuEvent(event);
|
DoMenuEventPostSIOUX(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoMenuEvent(EventRecord &event) {
|
void DoMenuEventPostSIOUX(EventRecord &event) {
|
||||||
// SIOUX will handle the menu event, but we can check after the fact
|
if(!SIOUXSettings.setupmenus) return;
|
||||||
// to see whether the user selected one of our menus
|
|
||||||
|
/* If MenuChoice is available, it is best to let SIOUX handle the menu
|
||||||
|
* event so Copy and Paste will work. We can check after the fact
|
||||||
|
* to see whether the user selected one of our menus using MenuChoice.
|
||||||
|
* However, if that trap is not available, we must handle the menu
|
||||||
|
* ourselves and certain menu items will not work
|
||||||
|
*/
|
||||||
|
|
||||||
WindowPtr thisWindow;
|
WindowPtr thisWindow;
|
||||||
if(event.what == mouseDown && FindWindow(event.where, &thisWindow) == inMenuBar) {
|
if((event.what == mouseDown) && (FindWindow(event.where, &thisWindow) == inMenuBar)) {
|
||||||
long int choice = MenuChoice();
|
DoMenuSelection(MenuChoice());
|
||||||
int menuId = HiWord(choice);
|
}
|
||||||
int itemId = LoWord(choice);
|
}
|
||||||
switch(menuId) {
|
|
||||||
case 32000: // Apple menu
|
bool DoMenuSelection(long choice) {
|
||||||
SysBeep(10);
|
bool handled = false;
|
||||||
break;
|
int menuId = HiWord(choice);
|
||||||
case 32001: // File menu
|
int itemId = LoWord(choice);
|
||||||
if (itemId == 9) {
|
//printf("Menu choice: %d, %d\n", menuId, itemId);
|
||||||
WndProc(WM_COMMAND, IDB_QUIT);
|
switch(menuId) {
|
||||||
}
|
case 32000: // Apple menu SysBeep(10);
|
||||||
break;
|
break;
|
||||||
case 32002: // Edit menu
|
case 32001: // File menu
|
||||||
case 128: // TIP menu
|
if (itemId == 9) { // Quit
|
||||||
switch(itemId) {
|
WndProc(WM_COMMAND, IDB_QUIT);
|
||||||
case 1: HiliteMenu(0); RunCommandLine(); break;
|
handled = true;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
case 32002: // Edit menu
|
||||||
|
break;
|
||||||
|
case 128: // TIP menu
|
||||||
|
switch(itemId) {
|
||||||
|
case 1: // Run Command Line...
|
||||||
|
HiliteMenu(0);
|
||||||
|
RunCommandLine();
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
HiliteMenu(0);
|
HiliteMenu(0);
|
||||||
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoUpdate(WindowPtr window) {
|
void DoUpdate(WindowPtr window) {
|
||||||
|
@ -257,6 +290,7 @@ void DoUpdate(WindowPtr window) {
|
||||||
DrawEdge(&(*richText)->frame, BDR_SUNKENOUTER, BF_RECT);
|
DrawEdge(&(*richText)->frame, BDR_SUNKENOUTER, BF_RECT);
|
||||||
ReleaseDC(hExplainWnd);
|
ReleaseDC(hExplainWnd);
|
||||||
|
|
||||||
|
SetColor(BLACK_COLOR);
|
||||||
UpdateControls(window, window->visRgn);
|
UpdateControls(window, window->visRgn);
|
||||||
|
|
||||||
EndUpdate(window);
|
EndUpdate(window);
|
||||||
|
@ -280,22 +314,32 @@ void DoMouseDown(EventRecord &event) {
|
||||||
GetPort(&oldPort);
|
GetPort(&oldPort);
|
||||||
SetPort(thisWindow);
|
SetPort(thisWindow);
|
||||||
GlobalToLocal(&mouse);
|
GlobalToLocal(&mouse);
|
||||||
const bool hitButton = (!TBMouseDown(richText, mouse, thisWindow)) &&
|
int part;
|
||||||
(FindControl(mouse, thisWindow, &thisControl) == inButton) &&
|
const bool hitCntl = (!TBMouseDown(richText, mouse, thisWindow)) &&
|
||||||
(TrackControl(thisControl, mouse, 0) == inButton);
|
(FindControl(mouse, thisWindow, &thisControl)) &&
|
||||||
|
(part = TrackControl(thisControl, mouse, 0));
|
||||||
SetPort(oldPort);
|
SetPort(oldPort);
|
||||||
if(hitButton) {
|
if(hitCntl && (part == inButton) || (part == inCheckBox)) {
|
||||||
int id = GetControlReference(thisControl);
|
int id = GetControlReference(thisControl);
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case IDB_OKAY:
|
case IDB_OKAY:
|
||||||
SetPage(kTestingPage);
|
SetPage(PERFORM_TEST_PAGE);
|
||||||
break;
|
break;
|
||||||
case IDB_EXPL:
|
case IDB_EXPL:
|
||||||
SetPage(kExplainPage);
|
SetPage(EXPLAIN_RESULTS);
|
||||||
|
break;
|
||||||
|
case IDB_NEXT:
|
||||||
|
SetRichEditText(szInstructions);
|
||||||
break;
|
break;
|
||||||
case IDB_READ:
|
case IDB_READ:
|
||||||
OpenExplanationInSimpleText();
|
OpenExplanationInSimpleText();
|
||||||
break;
|
break;
|
||||||
|
case IDB_BEEP:
|
||||||
|
SetPort(thisWindow);
|
||||||
|
SetControlValue(thisControl, 1 - GetControlValue(thisControl));
|
||||||
|
SetPort(oldPort);
|
||||||
|
printf("Value: %d\n", GetControlValue(thisControl));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
WndProc(WM_COMMAND, id);
|
WndProc(WM_COMMAND, id);
|
||||||
break;
|
break;
|
||||||
|
@ -311,6 +355,14 @@ void DoMouseDown(EventRecord &event) {
|
||||||
gDone = true;
|
gDone = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case inMenuBar:
|
||||||
|
if(!DoMenuSelection(MenuSelect(event.where))) {
|
||||||
|
SysBeep(10);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case inDrag:
|
||||||
|
DragWindow(thisWindow, event.where, &(*GetGrayRgn())->rgnBBox);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,10 +410,21 @@ void StrToPascal(Str255 pStr, const char *str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPage(TipPage newPage) {
|
void SetPage(TipPage newPage) {
|
||||||
if(page == newPage) return;
|
if(CurrentPage == newPage) return;
|
||||||
page = newPage;
|
CurrentPage = newPage;
|
||||||
switch(page) {
|
switch(CurrentPage) {
|
||||||
case kTestingPage:
|
case INTRO_PAGE:
|
||||||
|
ShowWindow(IDB_TEST, SW_HIDE);
|
||||||
|
ShowWindow(IDB_BACK, SW_HIDE);
|
||||||
|
ShowWindow(IDB_EXPL, SW_HIDE);
|
||||||
|
ShowWindow(IDB_BEEP, SW_HIDE);
|
||||||
|
ShowWindow(IDB_OKAY, SW_HIDE);
|
||||||
|
ShowWindow(IDB_READ, SW_HIDE);
|
||||||
|
ShowWindow((*richText)->scroll, SW_HIDE);
|
||||||
|
ShowWindow(IDB_QUIT, SW_SHOW);
|
||||||
|
ShowWindow(IDB_NEXT, SW_SHOW);
|
||||||
|
break;
|
||||||
|
case PERFORM_TEST_PAGE:
|
||||||
ShowWindow((*richText)->scroll, SW_HIDE);
|
ShowWindow((*richText)->scroll, SW_HIDE);
|
||||||
ShowWindow(IDB_BACK, SW_HIDE);
|
ShowWindow(IDB_BACK, SW_HIDE);
|
||||||
ShowWindow(IDB_NEXT, SW_HIDE);
|
ShowWindow(IDB_NEXT, SW_HIDE);
|
||||||
|
@ -370,13 +433,15 @@ void SetPage(TipPage newPage) {
|
||||||
ShowWindow(IDB_TEST, SW_SHOW);
|
ShowWindow(IDB_TEST, SW_SHOW);
|
||||||
ShowWindow(IDB_EXPL, SW_SHOW);
|
ShowWindow(IDB_EXPL, SW_SHOW);
|
||||||
ShowWindow(IDB_QUIT, SW_SHOW);
|
ShowWindow(IDB_QUIT, SW_SHOW);
|
||||||
|
ShowWindow(IDB_BEEP, SW_SHOW);
|
||||||
break;
|
break;
|
||||||
case kExplainPage:
|
case EXPLAIN_RESULTS:
|
||||||
ShowWindow(IDB_TEST, SW_HIDE);
|
ShowWindow(IDB_TEST, SW_HIDE);
|
||||||
ShowWindow(IDB_BACK, SW_HIDE);
|
ShowWindow(IDB_BACK, SW_HIDE);
|
||||||
ShowWindow(IDB_NEXT, SW_HIDE);
|
ShowWindow(IDB_NEXT, SW_HIDE);
|
||||||
ShowWindow(IDB_EXPL, SW_HIDE);
|
ShowWindow(IDB_EXPL, SW_HIDE);
|
||||||
ShowWindow(IDB_QUIT, SW_HIDE);
|
ShowWindow(IDB_QUIT, SW_HIDE);
|
||||||
|
ShowWindow(IDB_BEEP, SW_HIDE);
|
||||||
ShowWindow(IDB_OKAY, SW_SHOW);
|
ShowWindow(IDB_OKAY, SW_SHOW);
|
||||||
ShowWindow(IDB_READ, SW_SHOW);
|
ShowWindow(IDB_READ, SW_SHOW);
|
||||||
ShowWindow((*richText)->scroll, SW_SHOW);
|
ShowWindow((*richText)->scroll, SW_SHOW);
|
||||||
|
@ -478,10 +543,10 @@ void SetRichEditText(const char *name) {
|
||||||
|
|
||||||
// Load the text from the file
|
// Load the text from the file
|
||||||
|
|
||||||
TBReadSimpleText(richText, &docSpec);
|
TBReadSimpleText(richText, &docSpec, false);
|
||||||
|
|
||||||
if (name != szRunning && name != szNotRunning) {
|
if (name != szRunning && name != szNotRunning) {
|
||||||
SetPage(kExplainPage);
|
SetPage(EXPLAIN_RESULTS);
|
||||||
} else {
|
} else {
|
||||||
InvalidateRect(hDefault);
|
InvalidateRect(hDefault);
|
||||||
}
|
}
|
||||||
|
@ -666,7 +731,7 @@ unsigned long GetSystemTime() {
|
||||||
void SetWindowText(int id, const char *str) {
|
void SetWindowText(int id, const char *str) {
|
||||||
Str255 pStr;
|
Str255 pStr;
|
||||||
StrToPascal(pStr, str);
|
StrToPascal(pStr, str);
|
||||||
ControlHandle hCntl = FindControl(id);
|
ControlHandle hCntl = FindCntlHandle(id);
|
||||||
if(hCntl) {
|
if(hCntl) {
|
||||||
GetDC(hDefault);
|
GetDC(hDefault);
|
||||||
SetCTitle(hCntl, pStr);
|
SetCTitle(hCntl, pStr);
|
||||||
|
@ -678,7 +743,7 @@ void SetWindowText(int id, const char *str) {
|
||||||
* ENABLE WINDOW
|
* ENABLE WINDOW
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void EnableWindow(int id, bool enabled) {
|
void EnableWindow(int id, bool enabled) {
|
||||||
ControlHandle hCntl = FindControl(id);
|
ControlHandle hCntl = FindCntlHandle(id);
|
||||||
if(hCntl) {
|
if(hCntl) {
|
||||||
GetDC(hDefault);
|
GetDC(hDefault);
|
||||||
HiliteControl(hCntl, enabled ? 0 : 255);
|
HiliteControl(hCntl, enabled ? 0 : 255);
|
||||||
|
@ -696,7 +761,7 @@ void ShowWindow(ControlHandle hCntl, int state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowWindow(int id, int state) {
|
void ShowWindow(int id, int state) {
|
||||||
ControlHandle hCntl = FindControl(id);
|
ControlHandle hCntl = FindCntlHandle(id);
|
||||||
if(hCntl) {
|
if(hCntl) {
|
||||||
GetDC(hDefault);
|
GetDC(hDefault);
|
||||||
ShowWindow(hCntl, state);
|
ShowWindow(hCntl, state);
|
||||||
|
@ -704,6 +769,19 @@ void ShowWindow(int id, int state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* SEND MESSAGE
|
||||||
|
*******************************************************************************/
|
||||||
|
long SendMessage(int id, int msg) {
|
||||||
|
if(msg == BM_GETCHECK) {
|
||||||
|
ControlHandle hCntl = FindCntlHandle(id);
|
||||||
|
if(hCntl) {
|
||||||
|
return GetControlValue(hCntl) ? BST_CHECKED: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* INVALIDATE RECT
|
* INVALIDATE RECT
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -744,3 +822,17 @@ void ProcessPendingMessages() {
|
||||||
}
|
}
|
||||||
SystemTask();
|
SystemTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* SPLASH THE BITMAP
|
||||||
|
*******************************************************************************/
|
||||||
|
void SplashTheBitmap() {
|
||||||
|
GetDC(hIntroWnd);
|
||||||
|
Rect rect;
|
||||||
|
SetRect(&rect, 16, 18, 16+120, 18/*+258*/ +220);
|
||||||
|
if(tipIntroPic) {
|
||||||
|
DrawPicture(tipIntroPic, &rect);
|
||||||
|
}
|
||||||
|
DrawEdge(&rect, BDR_SUNKENOUTER, BF_RECT);
|
||||||
|
ReleaseDC(hIntroWnd);
|
||||||
|
}
|
|
@ -123,11 +123,36 @@ ErrorTypeList errorTypeList[] = {
|
||||||
0x0088020B, "Side Switch Error",
|
0x0088020B, "Side Switch Error",
|
||||||
0x00FFFFE6, "Buffer Too Big",
|
0x00FFFFE6, "Buffer Too Big",
|
||||||
|
|
||||||
|
/***** Mac SCSI Manager Errors *****/
|
||||||
|
0x00FFFF02, "SCSI comm err, timeout",
|
||||||
|
0x00FFFF03, "SCSI bus arb, timeout",
|
||||||
|
0x00FFFF05, "SCSI phase error",
|
||||||
|
0x00FFFF07, "SCSI Manager busy",
|
||||||
|
0x00FFFF08, "SCSI sequence error",
|
||||||
|
0x00FFFF09, "SCSI blind, timeout",
|
||||||
|
0x00FFFF0A, "SCSI compl, phase err",
|
||||||
|
/***********************************/
|
||||||
|
|
||||||
0xFFFFFFFF, "-- Unknown Error --",
|
0xFFFFFFFF, "-- Unknown Error --",
|
||||||
|
|
||||||
0, 0
|
0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/********** Main Window Controls Text ************/
|
||||||
|
|
||||||
|
const char *szIntroTitle = "Trouble in Paradise";
|
||||||
|
const char *szIntroSubTitle = "FREEWARE by Steve Gibson\r" \
|
||||||
|
"Gibson Research Corporation\r" \
|
||||||
|
"http://grc.com ( v 2.1b )\r" \
|
||||||
|
"http://github.com/marciot/mac-tip";
|
||||||
|
const char *szIntroText =
|
||||||
|
"A Macintosh port of \"TIP\" for Windows by Marcio Teixeira, made possible by a "
|
||||||
|
"generous code donation by Steve Gibson.\r\r"
|
||||||
|
"This freeware utility determines whether an Iomega Zip or Jaz drive is prone "
|
||||||
|
"to developing the dreaded \"Click of Death\" syndrome. Gibson's "
|
||||||
|
"research into the maintenance, repair and data recovery of Iomega's removable "
|
||||||
|
"media mass storage products led to this capability.";
|
||||||
|
|
||||||
/****************** Control Text *****************/
|
/****************** Control Text *****************/
|
||||||
|
|
||||||
const char *szBack = "< Back";
|
const char *szBack = "< Back";
|
||||||
|
@ -162,7 +187,33 @@ TextList TestGrayText[] = {
|
||||||
{155, 39, "Testing Progress"},
|
{155, 39, "Testing Progress"},
|
||||||
{129, 77, "Spare Sectors Consumed"},
|
{129, 77, "Spare Sectors Consumed"},
|
||||||
{61, 135, "Testing Location"},
|
{61, 135, "Testing Location"},
|
||||||
/*{219, 135, "Sound"},*/
|
{219, 135, "Sound"},
|
||||||
{297, 135, "Error Summary"},
|
{297, 135, "Error Summary"},
|
||||||
{0,0,0}
|
{0,0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------- Test Monitor Panel Definitions -------------------
|
||||||
|
|
||||||
|
#define SET_RECT(LEFT, TOP, RIGHT, BOTTOM) {TOP, LEFT, BOTTOM, RIGHT}
|
||||||
|
|
||||||
|
Rect CS_Stat = SET_RECT(114, 8, 242, 28);
|
||||||
|
Rect TP_Perc = SET_RECT( 12, 56, 409, 72);
|
||||||
|
Rect SS_Jaz = SET_RECT( 12, 94, 409, 126);
|
||||||
|
Rect SS_Sid0 = SET_RECT( 12, 94, 409, 110);
|
||||||
|
Rect TL_Sect = SET_RECT( 75, 154, 203, 170);
|
||||||
|
Rect ES_Read = SET_RECT(346, 154, 409, 170);
|
||||||
|
Rect SE_Rect = SET_RECT(222, 154, 255, 221);
|
||||||
|
|
||||||
|
BtnList tipBtns[] = {
|
||||||
|
{IDB_BACK, szBack, 157, 301, 80, 24},
|
||||||
|
{IDB_NEXT, szNext, 236, 301, 80, 24},
|
||||||
|
{IDB_QUIT, szQuit, 402, 301, 45, 24},
|
||||||
|
{IDB_BEEP, "", 252, 211, 22, 22, checkBoxProc},
|
||||||
|
// For Mac TIP only
|
||||||
|
{IDB_TEST, szPressToStart, 157, 301, 150, 24},
|
||||||
|
{IDB_EXPL, "Explain", 330, 301, 60, 24},
|
||||||
|
{IDB_OKAY, "Okay", 380, 301, 65, 24},
|
||||||
|
{IDB_READ, "Open in SimpleText...", 210, 301, 160, 24},
|
||||||
|
{0, 0, 0, 0, 0, 0}
|
||||||
|
};
|
|
@ -1,16 +1,19 @@
|
||||||
/************************************************************
|
/****************************************************************************
|
||||||
|
* Common Libraries (c) 1994 Marcio Teixeira *
|
||||||
pstring.c
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
AUTHOR: Marcio Luis Teixeira
|
* it under the terms of the GNU General Public License as published by *
|
||||||
CREATED: 9/17/94
|
* the Free Software Foundation, either version 3 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
LAST REVISION: 11/25/21
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
(c) 1994-1995 by Marcio Luis Teixeira.
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
All rights reserved.
|
* 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 "pstring.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
/************************************************************
|
/****************************************************************************
|
||||||
|
* Common Libraries (c) 1994 Marcio Teixeira *
|
||||||
pstring.h
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
AUTHOR: Marcio Luis Teixeira
|
* it under the terms of the GNU General Public License as published by *
|
||||||
CREATED: 9/17/94
|
* the Free Software Foundation, either version 3 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
LAST REVISION: 11/25/21
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
(c) 1994-1995 by Marcio Luis Teixeira.
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
All rights reserved.
|
* 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 );
|
short pstrlen( unsigned char *str );
|
||||||
void psetlen( unsigned char *str, short len );
|
void psetlen( unsigned char *str, short len );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user