Files
Shawn Quick dfcaae62dd Add qlink, the disk tools, and a bootable ProDOS 8 image.
Move the assembler to src/qasm. qlink links OMF 1.0 and 2.0 from a script. makeBin flattens a load file, qomf dumps OMF, and qpro builds ProDOS volumes. APW and MPW assemble through the ORCA front end. Relocatable modules emit OMF objects. Listings stay off unless -l is set.

make boot assembles the GS/OS 6.0.1 ProDOS 8 kernel and BASIC.SYSTEM into an 800K volume. BASIC.SYSTEM accepts ls and pfx, and its splash reports PRODOS BASIC 2.0, copyright 1983-2026. IIGS.601.SRC is the source and the BASIC.SYSTEM oracle that image is built from.
2026-10-16 14:41:55 -07:00

1 line
17 KiB
OpenEdge ABL

{ Copyright 1990-1993 Apple Computer, Inc. All Rights Reserved }
{ 26-Jan-93 SS -- switched to newer call GetCtlValueByID}
UNIT FindFileDA;
INTERFACE
USES
Types, GSOS, QuickDraw, IntMath, Events, Controls, Windows, Menus,
Desk, LineEdit, ProDOS, Lists, Resources, Memory, Locator, MiscTool,
Loader;
{$Z+} {So 'C' routines know about these names}
const
MyDATitle = ' Find File 1.1 ';
MaxFilesToFind = 200; { matches MaxEntries constant in ProcessLevel.asm }
type
MyListRec = Record
MemString:ptr;
MemFlag:Integer;
MemFullName:Handle;
memType:Integer;
memAux:Longint;
memEOF:Longint;
end;
MyListHand = ^MyListPtr;
MyListPtr = ^MyListarray;
MyListArray= Array[0..100] of MyListRec;
Str255Ptr=^str255;
Str255Hndl=^Str255Ptr;
convtype = packed array [1..31] of char;
convptr = ^convtype;
ConvHndl = ^ConvPtr;
VAR
IdleWind : GrafPortPtr; { do not remove }
initType, { do not remove }
Stk_Size, { do not remove }
quitflag, { do not remove }
menuID, { do not remove }
itemID, { do not remove }
actionCode : Integer; { do not remove }
eventP : EventRecordPtr; { do not remove }
InvisibleFlag: boolean; { true if invisible files should be found }
tempRect :Rect;
MyList : MyListHand;
messageStr :str255;
tempString : str255; { used by ProcessLevel.asm }
currentDirPath:str255; { used by ProcessLevel.asm }
MyDirEntry : DirEntryRec;
MyOpenRec : OpenRec;
MyCLose : FileIORec;
MyListCnt : Integer;
ListCtrl : CtlRecHndl;
MyID : Integer;
MatchType : Integer;
MatchStr : str32;
CurrentVol: str32;
VolPopUp,tempBar : MenuBarRecHndl;
StackHandle : Longint;
StackLevel : Integer;
EntryCount : Integer;
PascalStack: Integer;
Running:Integer; { Flag that tells us if we are currently running }
Stopping : Integer; {Flag that tells us that we should stop and why}
IdleCount : Integer;
AsmToolErr : Integer;
PathListHidden : Boolean;
tempNamePtr : Record
stat:integer;
length:integer;
theName:packed array [1..40] of char;
end;
screenMode : Integer;
PROCEDURE ReallyOpen; { do not remove }
PROCEDURE ReallyInit; { do not remove }
PROCEDURE ReallyClose; { do not remove }
PROCEDURE ReallyAction; { do not remove }
Procedure SetMessage(theString:str255);
IMPLEMENTATION
{$Z-} { hide the rest }
{ place variables & constants here that need to be known between calls }
TYPE
integerPtr = ^integer;
MyTaskRec= RECORD wmWhat : Integer;
wmMessage : Longint;
wmWhen : Longint;
wmWhere : Point;
wmModifiers : Integer;
wmTaskData : Longint; { TaskMaster return value. }
wmTaskMask : Longint; { TaskMaster feature mask. }
wmLastClickTick : Longint;
wmClickCount : Integer;
wmTaskData2 : Longint;
wmTaskData3 : Longint;
wmTaskData4 : Longint;
wmLastClickPt : Point;
wmBuffer : array[0..4] of Integer;
END;
VAR
windParams : ParamList;
emptyString : String[1];
titleStr: String[32];
AppResFork : Integer;
theDATask : MyTaskRec;
PROCEDURE BeginDA; EXTERNAL;
PROCEDURE AddVolumeMenu; EXTERNAL;
PROCEDURE CallNotifyProc; EXTERNAL;
PROCEDURE CallDelNotifyProc; EXTERNAL;
Function MakeCurPath:Boolean; EXTERNAL;
PROCEDURE TestSetKT; EXTERNAL;
PROCEDURE ServiceDiskSwitch; EXTERNAL;
PROCEDURE PollDevices; External;
PROCEDURE GetUpTextFromLE(theLEHandle:LERecHndl; var theStr:str32); External;
PROCEDURE MyMemberDraw; External;
PROCEDURE SetAboutMessage; External;
Function ffRequestProc(code: integer; inP, outP: univ longint): integer; External;
Procedure InstallMyRequestProc; External;
Procedure CreatePathList(thePath:ptr); External;
procedure MakeSureExtraToolsAreHere; external;
Procedure Debug; INLINE $0000 ;
Procedure DebugStr(theStr:str255); INLINE $A2,$FF09,$22,$E10000;
{ Function GetCtlValueByID(theWindow:WindowPtr; theID:longint) : integer; INLINE $A2,$3D10,$22,$E10000; }
Procedure SetControls(running:Boolean);
var RunButton,
StopButton,
LineEditCtl,
DiskPopUp,
MatchPopUp: CtlRecHndl;
begin
RunButton := GetCtlHandleFromID(IdleWind,1001);
StopButton := GetCtlHandleFromID(IdleWind,1002);
LineEditCtl := GetCtlHandleFromID(IdleWind,$3f0);
DiskPopUp := GetCtlHandleFromID(IdleWind,1);
MatchPopUp := GetCtlHandleFromID(IdleWind,$3EE);
If Running then begin
HideControl(RunButton);
ShowControl(StopButton);
HiliteControl($FF,LineEditCtl);
HiliteControl($FF,DiskPopUp);
HiliteControl($FF,MatchPopUp);
end
else
begin
HideControl(StopButton);
ShowControl(RunButton);
HiliteControl(0,LineEditCtl);
HiliteControl(0,DiskPopUp);
HiliteControl(0,MatchPopUp);
end;
end;
{ ------------------------------------------------------------------------------------}
{ This procedure is called when the desk accessory is selected from the }
{ Apple menu. It will only be called once. Any re-selection of the DA's }
{ menu item will be filtered out before reaching this routine. }
PROCEDURE ReallyOpen;
VAR
oldRgn,
tmpRgn : RegionHndl;
myPoint : Ptr;
temp,errtemp:Integer;
fileOpen,Abort:Boolean;
prefsParms : SysPrefsRecGS;
oldPrefs : Integer;
BEGIN
emptyString := '';
MyID:=MMStartup;
ResourceStartup(MyID);
fileOpen:=false;
PathListHidden:=true;
Abort:=false;
{ save current SysPrefs and set them up to automatically display mount dialog }
prefsParms.pCount := 1;
GetSysPrefsGS(prefsParms);
oldPrefs := prefsParms.preferences;
prefsParms.preferences := $8000; { show 'dem dialogs! }
SetSysPrefsGS(prefsParms);
{GAB}
Repeat
temp := OpenResourceFile(1,NIL,GSString255Ptr(LGetPathname2(MyID,1)));
If _ToolErr=0 then FileOpen:=true
else
begin
If _ToolErr=volNotFound then
Abort := true {User must have selected "Cancel" in volume mount dialog}
else
Begin
errTemp:=TLMountVolume(30,30,'Error occured while opening',
'Find File', 'Try Again', 'Cancel');
If errTemp=2 then Abort:=true;
end
end;
until fileOpen or Abort;
{ reset SysPrefs to original value }
prefsParms.preferences := oldPrefs;
SetSysPrefsGS(prefsParms);
{GAB}
If Abort then
begin
idleWind:=NIL;
ResourceShutDown;
exit(ReallyOpen);
end;
MakeSureExtraToolsAreHere;
titleStr:=MyDATitle;
MessageStr:='';
if BAnd(GetMasterSCB,$0080) = 0 then { determine what screen mode we're in }
screenMode := 320
else
screenMode := 640;
IdleWind := NewWindow2(@titleStr,0,NIL,NIL,$0002,ref(screenMode),$800E);
SetControls(false);
if _toolErr <> 0 THEN SysFailMgr(_toolErr,emptyString);
SetSysWindow(IdleWind);
quitflag := 0; { set to 1 by action routine if its time to quit }
ListCtrl := GetCtlHandleFromID(IdleWind,longint(1009 + screenMode));
MyList := MyListHand(NewHandle(20*MaxFilesToFind,MyID,$8000,NIL));
AddVolumeMenu;
CallNotifyProc;
MyListCnt := 0;
MatchType := 1;
END; {ReallyOpen}
{ ------------------------------------------------------------------------------------}
{ This procedure is called when DeskStartUp or DeskShutDown is called }
{ It is normally not used but is used here so that the header for the }
{ desk accessory can be built from Pascal }
PROCEDURE ReallyInit;
TYPE
DAHeader = RECORD
openPtr : LongInt; { pointer to open routine (do not change) }
closePtr : LongInt; { pointer to close routine (do not change) }
actionPtr : LongInt; { pointer to action routine (do not change) }
initPtr : LongInt; { pointer to init routine (do not change) }
period : Integer; { How often the DA is to get a run call - set in make file }
eventMask : Integer; { Discribes what events DA responds to - set in make file }
menuLine : packed ARRAY [0..20] of char;
END;
DAHeaderPtr = ^DAHEADER;
VAR
customHeader : DAHeaderPtr;
BEGIN
IF initType <> 0 THEN
BEGIN { DeskStartUp call being made }
customHeader := DAHeaderPtr(@BeginDA);
{ change the following if you want more or less stack }
Stk_Size := 2048; { live with applications }
END
ELSE
BEGIN { DeskShutDown call being made - this is not close desk accessory}
InstallMyRequestProc;
END;
END;
{ ------------------------------------------------------------------------------------}
{ This procedure is called when the desk accessory is about to close. }
PROCEDURE ReallyClose;
BEGIN
DisposeAll(MyID+$0700);
DisposeAll(MyID+$0600);
DisposeAll(MyID+$0900);
DisposeAll(MyID+$0300); { added 9-Apr-92 DAL -- get rid of list items! }
DisposeHandle(Handle(MyList));
StackHandle := 0;
Running := 0;
myListCnt:=0;
CallDelNotifyProc; { remove the disk switch routine from GS/OS notif. queue }
CloseWindow(IdleWind);
ResourceShutDown;
Stopping := 1;
END; { ReallyClose }
{ ------------------------------------------------------------------------------------}
{ This procedure handles any events or periodic run requests which are passed }
{ to the desk accessory. }
Procedure ShowMessage;
var
PathList: CtlRecHndl;
tempPort: GrafPortPtr;
tempRgn: RegionHndl;
myRect: Rect;
begin
PathList := GetCtlHandleFromID(IdleWind,1015 + screenMode);
PathListHidden := true;
{ Set the clip rect here to avoid mucking up the list above?? }
tempPort := GetPort;
SetPort(IdleWind);
tempRgn := NewRgn;
GetClip(tempRgn);
SetRect(myRect,0,100,1000,1000); { don't mess up anything above top of list }
ClipRect(myRect);
HideControl(PathList);
SetClip(tempRgn);
DisposeRgn(tempRgn);
SetPort(tempPort);
end;
Procedure ShowPathList;
var
PathList:CtlRecHndl;
begin
PathList:=getCtlHandleFromID(IdleWind,1015 + screenMode);
ShowControl(PathList);
PathListHidden:=false;
end;
procedure UpdateMessageBox;
var
tempPort: GrafPortPtr;
begin
if PathListHidden then
begin
tempPort := GetPort;
SetPort(IdleWind);
SetRect(tempRect,4,105,318,145);
LETextBox2(ptr(ord4(@MessageStr)+1),length(MessageStr),tempRect,0);
SetPort(tempPort);
end;
end;
Procedure SetMessage(theString:str255);
var
savePort : GrafPortPtr;
begin
savePort := GetPort;
SetPort(IdleWind);
ShowMessage;
MessageStr := theString;
SetPort(savePort);
UpdateMessageBox;
end;
{
This routine should be called at the start of every search to dump the current list and
all its contents, as well as called for shutdown...
}
Procedure DumpList;
begin
DisposeAll(MyID+$0700);
myListCnt := 0;
NewList2(NIL,1,ref(MyList),1,myListCnt,listCtrl);
BeginUpdate(IdleWind); { make sure the old list disappears }
DrawControls(IdleWind);
EndUpdate(IdleWind);
end;
Function ProcessLevel(Flag:Integer):Integer; External;
{
This procedure should be called before any routine starts/ends to determine if
the state of the buttons needs to be changed.
}
Procedure Idler;
var
i,j:Integer;
MyLERecord:LERecHndl;
RunButton:CtlRecHndl;
StopButton:CtlRecHndl;
theState:Byte;
begin
MyLERecord := LERecHndl(GetCtlTitle(GetCtlHandleFromID(IdleWind,1008)));
RunButton := GetCtlHandleFromID(IdleWind,1001);
StopButton := GetCtlHandleFromID(IdleWind,1002);
If Running<>0 then
begin
idleCount:=0;
end
else
begin
IdleCount := IdleCount + 1;
PollDevices;
ServiceDiskSwitch;
theState:=RunButton^^.ctlHilite;
i := LEGetTextLen(MyLERecord);
If (theState=noHilite) and (i=0) then
HiliteControl(inactiveHilite,RunButton);
If (theState=inactiveHilite) and (i<>0) then
HiliteControl(noHilite,RunButton);
end;
end;
Procedure StartSearch(doInvisibles: boolean);
var
i, j: Integer;
MyLERecord: LERecHndl;
begin
{ First set up MatchType and MatchStr }
MyLERecord:=LERecHndl(GetCtlTitle(GetCtlHandleFromID(IdleWind,1008)));
GetUpTextFromLE(MyLERecord,MatchStr); {Get the user inputed file choice..}
If Length(MatchStr)=0 then Exit(StartSearch);
SetControls(true);
StackHandle := 0;
stackLevel := 0;
{*** changed to new call 26-Jan-93 SS}
{ i := GetCtlValue(GetCtlHandleFromID(IdleWind,1006)); }
i := GetCtlValueByID(IdleWind,1006);
{*** end 26-Jan-93}
MatchType := i-1600;
DumpList;
SetMessage('Searching...');
{ get the proper prefix to use... }
If not MakeCurPath then ; { What is this?? --DAL }
Stopping := 0; {Set the stopping flag to zero....}
InvisibleFlag := doInvisibles;
Running := processLevel(0); {Start the recursion}
end;
Procedure DisplayItem;
const
theLeftEdge=190;
theTopEdge=62;
var
MyHand:Str255Hndl;
theItem:Integer;
tempPort:grafportPtr;
begin
tempport := GetPort;
SetPort(IdleWind);
theItem:=NextMember2(0,ListCtrl); {Get the member to display}
If theItem=0 then
begin
SetABoutMessage;
Exit(DisplayItem);
end;
MyHand:=Str255Hndl(MyList^^[theItem-1].MemFullName);
CreatePathList(Ptr(MyHand^));
ShowPathList;
SetPort(tempPort);
end;
Procedure Continue(Chunkiness: integer);
var
MyHand:Str255Hndl;
theItem:Integer;
tempPort:grafportPtr;
tempLong:Longint;
StartTick: longint;
dummyEvent: EventRecord;
begin
if running<>0 then begin
StartTick := GetTick;
while ((GetTick-StartTick) < Chunkiness) and (Running<>0) and
not EventAvail(mDownMask+keyDownMask+autoKeyMask,dummyEvent) do
begin
running := processlevel(0);
end;
end else
begin
if StackHandle<>0 then
begin
tempport := GetPort;
SetPort(IdleWind);
DisposeHandle(Handle(StackHandle));
tempLong:=Longint(GetCtlTitle(ListCtrl)); {Get the ctlData field}
if (tempLong<MaxFilesToFind) and (MessageStr='Searching...') then
SetMessage('No files found.');
theItem := NextMember2(0,ListCtrl); { Get the member to display }
If MessageStr='Searching...' then SetMessage('Done searching.');
SetPort(tempPort);
SysBeep2($4005); { operation complete, bonk, defer }
SetControls(false);
end;
StackHandle := 0;
End;
if (Running=0) and (Stopping<0) then
Begin
SetControls(False);
SetMessage('Too many items found. Try searching for something more specific.');
SysBeep2($400C); { operation failed, bonk, defer }
Stopping := 1;
End;
end;
Procedure StopSearch;
begin
SetControls(false);
Stopping := 1;
SetMessage('Search stopped.');
end;
Procedure HandleControl(theID: longint; modifiers: integer);
var
temp: Integer;
begin
temp:=theID; {make it a integer};
case temp of
1001: StartSearch(band(modifiers,optionKey)<>0);
1002: StopSearch;
{ 1003: ; }
{ 1004: ; }
{ 1005: ; }
{ 1006: ; } { Matches popup displayed... }
{ 1007: ; }
{ 1008: ; }
1009 + 320,
1009 + 640: DisplayItem;
{ 1010: ; }
{ 1011: ; }
{ 1012: ; }
{ 1013: ; }
{ 1014: ; }
{ 1015: ; }
end;
end;
PROCEDURE ReallyAction;
CONST
XSpan = 145;
YSpan = 168;
VAR
savePort : GrafPortPtr;
newX,
newY : integer;
code :Integer;
theRect : Rect;
BEGIN
theDATask.wmWhat:=EventP^.wmWhat;
theDATask.wmMessage:=EventP^.wmMessage;
theDATask.wmWhen:=EventP^.wmWhen;
theDATask.wmWhere:=EventP^.wmWhere;
theDATask.wmModifiers:=EventP^.wmModifiers;
theDATask.wmTaskData:=0;
theDATask.wmTaskMask:=$1FFFFF;
CASE ActionCode of
runAction:
BEGIN { a periodic call is being made }
savePort := GetPort;
SetPort(IdleWind);
LEIdle(LERecHndl(GetCtlTitle(GetCtlHandleFromID(IdleWind,$3F0))));
continue(15); {call the idle routine}
Idler;
SetPort(savePort);
END;
cursorAction: { like Run, but don't call Idler! }
BEGIN
savePort := GetPort;
SetPort(IdleWind);
continue(50); {call the idle routine}
SetPort(savePort);
END;
eventAction:
BEGIN { an event has been passed to the DA }
CASE EventP^.what OF
updateEvt:
BEGIN
BeginUpdate(IdleWind);
DrawControls(IdleWind);
PenNormal;
UpdateMessageBox;
EndUpdate(IdleWind);
Idler;
END;
keyDownEvt,
autoKeyEvt:
Begin
code:= band($00FF,theDATask.wmMessage);
if (code=13) and (Running=0) then
StartSearch(band(theDATask.wmModifiers,optionKey)<>0)
else
begin
if (code=10) or (code=11) then theDATask.wmWhat := 0; { up/down arrows }
if (running=0) and (code=27) {esc} then theDATask.wmMessage := 24; { Clear }
if (code=46) { period } and (band(theDATask.wmModifiers,$0100)<>0) then
theDATask.wmMessage := 27; { command-period --> esc }
code:=TaskMasterDA($FFFF,@theDATask);
if code = wInControl then HandleControl(theDATask.wmTaskData4,theDATask.wmModifiers);
Idler;
end;
End;
mouseDownEvt,
mouseUpEvt,
ActivateEvt:
BEGIN
code:=TaskMasterDA($FFFF,@theDATask);
if code = wInControl then HandleControl(theDATask.wmTaskData4, theDATask.wmModifiers);
Idler;
END;
END; { CASE }
END;
END; { CASE }
END;
END. { of Unit }