diff --git a/mac-cpp-source/Iomega Tester.rsrc.bin b/mac-cpp-source/Iomega Tester.rsrc.bin index efc02d6..cef6a5b 100644 Binary files a/mac-cpp-source/Iomega Tester.rsrc.bin and b/mac-cpp-source/Iomega Tester.rsrc.bin differ diff --git a/mac-cpp-source/macos/mac_vol.cpp b/mac-cpp-source/macos/mac_vol.cpp index 9d1cf56..07231bb 100644 --- a/mac-cpp-source/macos/mac_vol.cpp +++ b/mac-cpp-source/macos/mac_vol.cpp @@ -83,3 +83,22 @@ void mac_unmount(int id) { default: printf("Failed %d\n", err); } } + +void mac_eject(int id) { + HParamBlockRec paramBlock; + paramBlock.volumeParam.ioCompletion = 0; + paramBlock.volumeParam.ioNamePtr = 0; + paramBlock.volumeParam.ioVRefNum = 0; + paramBlock.volumeParam.ioVolIndex = id; + OSErr err = PBHGetVInfo(¶mBlock, false); + if (err == nsvErr) { + printf("No such volume\n"); + return; + } + err = Eject(0, paramBlock.volumeParam.ioVRefNum); + switch (err) { + case noErr: printf("Okay\n"); break; + case fBsyErr: printf("One or more files are open\n"); break; + default: printf("Failed %d\n", err); + } +} \ No newline at end of file diff --git a/mac-cpp-source/macos/mac_vol.h b/mac-cpp-source/macos/mac_vol.h index 7d971f8..95b5436 100644 --- a/mac-cpp-source/macos/mac_vol.h +++ b/mac-cpp-source/macos/mac_vol.h @@ -1,4 +1,5 @@ void mac_list_volumes(); void mac_unmount(int id); +void mac_eject(int id); OSErr mac_get_drive_volumes(int driveNum, Str255 str); OSErr mac_unmount_drive(int driveNum); diff --git a/mac-cpp-source/scsi/command_line.cpp b/mac-cpp-source/scsi/command_line.cpp new file mode 100644 index 0000000..bf5bf33 --- /dev/null +++ b/mac-cpp-source/scsi/command_line.cpp @@ -0,0 +1,165 @@ +#include +#include +#include +#include +#include + +#include "command_line.h" +#include "mac_vol.h" +#include "mac_scsi.h" +#include "iomega_cmds.h" + +bool process_command(); +void printn( unsigned char *c, int n ); +void print_help(); +void scan_bus(); +void dev_info( int id ); +void show_spares( int id ); + +void command_line_event_loop() { + for(int i = 0; i < 20; i++) printf("\n"); + print_help(); + + do { + EventRecord event; + if (WaitNextEvent(everyEvent, &event, GetCaretTime(), NULL)) + SIOUXHandleOneEvent(&event); + + } while (process_command()); + + printf( "Returning to TIP...\n" ); +} + +bool process_command() { + short int arg_val = 0; + char cmd[80]; + printf( "\nCmd> " ); + gets( cmd ); + printf("\n"); + + char *arg_str = strchr(cmd, ' '); + while(*arg_str == ' ') arg_str++; + if(arg_str) arg_val = atoi(arg_str); + + switch( tolower(cmd[0]) ) { + case 'h': print_help(); break; + case 'l': scan_bus(); break; + case 's': iomega_spin_up_cartridge(arg_val); break; + case 'r': scsi_reset(); break; + case 'e': mac_eject(arg_val); break; + case 'i': dev_info(arg_val); break; + case 'v': mac_list_volumes(); break; + case 'u': mac_unmount(arg_val); break; + case 'q': return false; + default: printf("Unknown command, type 'h' for help\n"); + } + return true; +} + +void print_help() { + printf( + "\nGeneral commands:\n" + " help : print this help\n" + " quit : exit the command line\n" + + "\nMacintosh commands:\n" + " volumes : list Mac volumes\n" + " unmount [n] : unmount a volume\n" + " eject [n] : eject a volume\n" + + "\nGeneral SCSI operations:\n" + " reset : reset the SCSI bus\n" + " list : list devices on the SCSI bus\n" + " info [n] : display SCSI inquiry\n" + + "\nIomega device operations on SCSI device:\n" + " spin [n] : spin up a cartridge\n" + ); +} + +void scan_bus() { + short err, id; + scsi_inq_reply reply; + + for( id=0; id<8; id++ ) { + err = scsi_inquiry( id, 0, &reply); + if( err != 0 ) { + printf( " %hd: (Not installed)\n", id ); + } else { + printf( " %hd: ", id ); + printn( reply.vend, 8 ); + printf( ", " ); + printn( reply.prod, 16 ); + printf( ", " ); + printn( reply.rvsn, 4 ); + putchar( '\n' ); + } + } +} + +void dev_info( int id ) { + short err, lun; + scsi_inq_reply reply; + + for( lun = 0; lun < 8; lun++ ) { + err = scsi_inquiry( id, lun, &reply); + if( err ) { + printf( "Device not installed\n" ); + return; + } + + printf( " LUN %hd: ", lun ); + switch( (reply.inf1 & 0xE0) >> 5 ) { + case 0x00: printf( "supported and connected\n" ); break; + case 0x01: printf( "not connected\n" ); continue; + case 0x03: printf( "not supported\n" ); continue; + } + + printf( " Device class (%02X): ", reply.inf1 & 0x1F ); + switch( reply.inf1 & 0x1F ) { + case 0x00: printf( "Disk drive\n" ); break; + case 0x01: printf( "Tape drive\n" ); break; + case 0x02: printf( "Printer\n" ); break; + case 0x03: printf( "Processor device\n" ); break; + case 0x04: printf( "WORM drive\n" ); break; + case 0x05: printf( "CD-ROM drive\n" ); break; + case 0x06: printf( "Scanner\n" ); break; + case 0x07: printf( "Optical disk\n" ); break; + case 0x08: printf( "Media changer\n" ); break; + case 0x09: printf( "Communication device\n" ); break; + case 0x1F: printf( "Unknown device\n" ); break; + default: printf( "Reserved\n" ); + } + + printf( " ANSI version (%02X): ", reply.vers & 0x07 ); + switch( reply.vers & 0x07 ) { + case 0x00: printf( "SCSI-1\n" ); break; + case 0x01: printf( "SCSI-1 w/ CCS\n" ); break; + case 0x02: printf( "SCSI-2\n" ); break; + default: printf( "???\n" ); + } + printf( " ISO version (%02X)\n", reply.vers & 0xC0 >> 6 ); + printf( " ECMA version (%02X)\n", reply.vers & 0x78 >> 3 ); + + printf( " Flags: " ); + if( reply.flg1 & 0x80 ) printf( "rmb " ); + if( reply.flg2 & 0x80 ) printf( "rel " ); + if( reply.flg2 & 0x40 ) printf( "w32 " ); + if( reply.flg2 & 0x20 ) printf( "w16 " ); + if( reply.flg2 & 0x10 ) printf( "syn " ); + if( reply.flg2 & 0x08 ) printf( "lnk " ); + if( reply.flg2 & 0x04 ) printf( "??? " ); + if( reply.flg2 & 0x02 ) printf( "que " ); + if( reply.flg2 & 0x01 ) printf( "sfR " ); + if( reply.inf2 & 0x80 ) printf( "aen " ); + if( reply.inf2 & 0x40 ) printf( "tio " ); + printf( "\n" ); + } +} + +void printn( unsigned char *c, int n ) { + while( n-- ) { + putchar( isprint(*c) ? *c : '.' ); + c++; + } +} \ No newline at end of file diff --git a/mac-cpp-source/scsi/command_line.h b/mac-cpp-source/scsi/command_line.h new file mode 100644 index 0000000..3f23c63 --- /dev/null +++ b/mac-cpp-source/scsi/command_line.h @@ -0,0 +1 @@ +void command_line_event_loop(); \ No newline at end of file diff --git a/mac-cpp-source/tip/tip_main.cpp b/mac-cpp-source/tip/tip_main.cpp index 355fe20..8376ebd 100644 --- a/mac-cpp-source/tip/tip_main.cpp +++ b/mac-cpp-source/tip/tip_main.cpp @@ -13,6 +13,7 @@ #include "mac_vol.h" #include "text_box.h" #include "tip.h" +#include "command_line.h" enum TipPage { kTestingPage, @@ -24,12 +25,16 @@ static bool allowColor; static bool inited = false; static bool timerEnabled = false; static WindowPtr tipWindow; +static MenuHandle tipMenu; static TBHandle richText; static const char *textFileName; void NewTipWindow(); void DisposeTipWindow(); +void AddTipMenus(); +void RunCommandLine(); void DoEvent(EventRecord &event, RgnHandle *cursorRgn); +void DoMenuEvent(EventRecord &event); void DoUpdate(WindowPtr window); void DoMouseDown(EventRecord &event); void DoMouseMove(EventRecord &event, RgnHandle *cursorRegion); @@ -44,6 +49,8 @@ void OpenExplanationInSimpleText(); const Point mainWndOrigin = SET_POINT(0, 40); void run_tip() { + AddTipMenus(); + RgnHandle cursorRgn = NewRgn(); NewTipWindow(); @@ -136,6 +143,24 @@ void NewTipWindow() { SetPage(kTestingPage); } +void AddTipMenus() { + tipMenu = GetMenu(128); + InsertMenu(tipMenu, 0); + DrawMenuBar(); +} + +void RunCommandLine() { + HideWindow(tipWindow); + DisableItem(tipMenu, 0); + DrawMenuBar(); + command_line_event_loop(); + EnableItem(tipMenu, 0); + DrawMenuBar(); + ShowWindow(tipWindow); + SelectWindow(tipWindow); + InitCursor(); +} + void DisposeTipWindow() { TBDispose(richText); DisposeWindow(tipWindow); @@ -178,9 +203,39 @@ void DoEvent(EventRecord &event, RgnHandle *cursorRgn) { case diskEvt: DoDiskEvent(event); break; case osEvt: DoMouseMove(event, cursorRgn); break; } + } else { // Trap unhandled SIOUX menu events + DoMenuEvent(event); } } +void DoMenuEvent(EventRecord &event) { + // SIOUX will handle the menu event, but we can check after the fact + // to see whether the user selected one of our menus + + WindowPtr thisWindow; + if(event.what == mouseDown && FindWindow(event.where, &thisWindow) == inMenuBar) { + long int choice = MenuChoice(); + int menuId = HiWord(choice); + int itemId = LoWord(choice); + switch(menuId) { + case 32000: // Apple menu + SysBeep(10); + break; + case 32001: // File menu + if (itemId == 9) { + WndProc(WM_COMMAND, IDB_QUIT); + } + break; + case 32002: // Edit menu + case 128: // TIP menu + switch(itemId) { + case 1: HiliteMenu(0); RunCommandLine(); break; + } + } + } + HiliteMenu(0); +} + void DoUpdate(WindowPtr window) { BeginUpdate(window); SetPort(window);