home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / code_examples / pfiler / pfiler.asm < prev    next >
Assembly Source File  |  1990-10-29  |  36KB  |  1,129 lines

  1. ;    OPT O+
  2. ;    OPT O1+        ;Tells when a branch could be optimised to short
  3. ;    OPT i+        ;Tells when '#' is probably missing
  4.  
  5.     incdir    "INCLUDE:"
  6.     include "exec/memory.i"
  7.     include "exec/exec_lib.i"
  8.     include "graphics/rastport.i"
  9.     include "graphics/graphics_lib.i"
  10.     include "intuition/intuition.i"
  11.     include "intuition/intuition_lib.i"
  12.     include "libraries/dos.i"
  13.     include "libraries/dosextens.i"
  14.     include "libraries/dos_lib.i"
  15.     incdir    "DF0:PFiler/"
  16.     include "PFiler.i"
  17.  
  18. * A few macro's
  19. LoadBase    MACRO
  20.         IFNC        '\1','ExecBase'
  21.         movea.l        FD_\1(A5),A6
  22.         ENDC
  23.         IFC        '\1','ExecBase'
  24.         movea.l        4.W,A6
  25.         ENDC
  26.         ENDM
  27. CallLib        MACRO
  28.         jsr        _LVO\1(A6)
  29.         ENDM
  30. Call        MACRO
  31.         bsr        \1
  32.         ENDM
  33. PushS        MACRO
  34.         move.l        \1,-(SP)
  35.         ENDM
  36. PopS        MACRO
  37.         move.l        (SP)+,\1
  38.         ENDM
  39. Push        MACRO
  40.         movem.l        \1,-(SP)
  41.         ENDM
  42. Pop        MACRO
  43.         movem.l        (SP)+,\1
  44.         ENDM
  45. GADGET        MACRO
  46.         dc.l        \1
  47.         dc.w        \2,\3,\4,\5,\6,\7,\8
  48.         ENDM
  49. GADGET2        MACRO
  50.         dc.l        \1,\2,\3,\4,\5
  51.         dc.w        \6
  52.         dc.l        \7
  53.         ENDM
  54. BORDER        MACRO
  55.         dc.w        \1,\2
  56.         dc.b        \3,\4,\5,\6
  57.         dc.l        \7,\8
  58.         ENDM
  59. IMAGE        MACRO
  60.         dc.w        \1,\2,\3,\4,\5
  61.         dc.l        \6
  62.         dc.b        \7,\8
  63.         dc.l        \9
  64.         ENDM
  65. INTUITEXT    MACRO
  66.         dc.b        \1,\2,\3,0
  67.         dc.w        \4,\5
  68.         dc.l        TxtAttr,\6,\7
  69.         ENDM
  70.  
  71. * These are MY definitions.
  72.  
  73. BUTCOLOR    =3
  74. STRCOLOR    =3
  75. PROPCOLOR    =3
  76. FILECOLOR    =1
  77. DIRCOLOR    =3
  78. DEVCOLOR    =2
  79.  
  80.                 ;The possible Node-Types
  81. DIRTYPE        =-1        ;Node contains the name of a directory        ('c','libs','med-res' etc.)
  82. DEVTYPE        =-2        ;Node contains the name of a device        ('DF1:','DH0:' etc.)
  83. VOLTYPE        =-3        ;Node contains the name of a volume        ('CLIDisk:','AmigaLibDisk294:' etc.)
  84. ASNTYPE        =-4        ;Node contains the name of a logical device    ('LIBS:','S:','FONTS:' etc.)
  85.                 ;A Node containing the name of file is
  86.                 ;characterized by having a type >=0 (the size actually)
  87.  
  88.                 ;Flags indicating what has to be done
  89. NEWDIR        =0        ;Start scanning a new directory and the Device-List
  90. REFSTR        =1        ;Refresh string-gadgets
  91. ACTFSG        =2        ;Activate the file-string-gadget
  92. GETDEVS        =3        ;Get names from Device-List instead of from disk
  93. NOTDEVS        =4        ;Don't show devices until the user clicks RMB
  94. LETSWAIT    =5        ;Be nice and wait for next message
  95. DONTPOS        =6        ;Just a trick to help saving a few bytes
  96. KEEPTOP        =7        ;Keep the display steady for a while no matter what arrives in the list
  97.  
  98. Select1ID    =0        ;Gadget ID's
  99. Select2ID    =1
  100. Select3ID    =2
  101. Select4ID    =3
  102. Select5ID    =4
  103. Select6ID    =5
  104. Select7ID    =6
  105. ParentID    =7
  106. UpID        =8
  107. DownID        =9
  108. SlideID        =10
  109. PathID        =11
  110. PosID        =12
  111. NegID        =13
  112.  
  113.                 ;STRUCTURE EntryNode    (Variable size)
  114. EntryNext    =0        ;APTR EntryNext        This is a single-linked list
  115. EntryType    =4        ;WORD EntryType
  116. EntrySize    =8        ;LONG EntrySize
  117. EntryName    =10        ;APTR EntryName
  118. EntrySIZEOF    =10        ;Size of EntryNode    (Except for the string)
  119.  
  120.                 ;STRUCTURE FileSelectData
  121. FD_DosBase    =0        ;APTR FD_DosBase
  122. FD_GfxBase    =4        ;APTR FD_GfxBase
  123. FD_IntBase    =8        ;APTR FD_IntBase
  124. FD_Window    =12        ;APTR FD_Window
  125. FD_Rp        =16        ;APTR FD_Rp        ;Rastport
  126. FD_Up        =20        ;APTR FD_Up        ;UserPort (for messages)
  127. FD_FIB        =24        ;APTR FD_FIB        ;FileInfoBlock
  128. FD_Lock        =28        ;APTR FD_Lock        ;Lock)
  129. FD_SlideHeight    =32        ;WORD FD_SlideHeight    ;Height of slide-knob
  130. FD_SlideVPos    =34        ;WORD FD_SlideVPos    ;Vertical position of slide-knob
  131. FD_Class    =36        ;WORD FD_Class        ;\
  132. FD_Code        =40        ;WORD FD_Code        ; \
  133. FD_IAddress    =42        ;WORD FD_IAddress    ;  > Copied from last IntuiMessage 
  134. FD_Seconds    =46        ;LONG FD_Seconds    ; /
  135. FD_Micros    =50        ;LONG FD_Micros        ;/
  136. FD_OSeconds    =54        ;LONG FD_OSeconds    ;\
  137. FD_OMicros    =58        ;LONG FD_OMicros    ; > Used to check for double-clicks
  138. FD_LastSelect    =62        ;LONG FD_LastSelect    ;/
  139. FD_TxtBuf    =66        ;APTR FD_TxtBuf
  140. FD_DisplayList    =70        ;APTR FD_DisplayList
  141. FD_SIZEOF    =76    ;(74)    ;Size of FileSelectBlock ((FD_SIZEOF mod 4) MUST be 0) 
  142.  
  143. DisplayCols    =32        ;Length of TxtBuffer
  144. DisplayRows    =7        ;Lines on display
  145.  
  146. InternalMem    =FD_SIZEOF+fib_SIZEOF+4*DisplayRows+DisplayCols+10
  147.  
  148.     SECTION SELECT,CODE
  149.  
  150. FReq        EQUR        A4
  151. FData        EQUR        A5
  152. *----------------------------------------------------
  153. * Frees the memory for every node in FR_List
  154. * Doesn't destroy  registers
  155. *----------------------------------------------------
  156.     XDEF    _FreeFileSelect
  157. _FreeFileSelect    Push        D0-D7/A0-A6
  158.         movea.l        4*15+4(SP),FReq        ;FSRequest always in A4
  159.         LoadBase    ExecBase
  160.         lea        FR_List(FReq),A1
  161.         move.l        EntryNext(A1),D2    ;Save first node in list for later
  162.         clr.l        EntryNext(A1)
  163. FreeLoop    tst.l        D2            ;Any node ?
  164.         beq.S        DoneFreeList
  165.         movea.l        D2,A1
  166.         move.l        EntryNext(A1),D2    ;Save next node in list for later
  167.         move.w        EntrySize(A1),D0
  168.         ext.l        D0
  169.         CallLib        FreeMem            ;Free this node
  170.         bra.S        FreeLoop
  171. DoneFreeList    Pop        D0-D7/A0-A6
  172.         rts
  173.  
  174. *----------------------------------------------------
  175. *FILESELECT
  176. *Register usage:
  177. *    A4: Used for base-relative access to user-supplied FileSelectRequest-structure (Never changed)
  178. *    A5: Used for base-relative access to internally used/allocated data (Never changed)
  179. *    A6: Only used for base-relative library-calls (Changes all the time)
  180. *    All internally called sub-routines (referenced by the macro CALL)
  181. *    preserves all registers (except A6), apart from some
  182. *    (MyStrLen, ExNextD), which returns something in D0
  183. *    Sort does not preserve registers at all
  184. *    FileSelect itself returns an error-code in D0
  185. *----------------------------------------------------
  186.     XDEF    _FileSelect
  187. * Here we enter the FileSelect
  188. _FileSelect    Push        D1-D7/A0-A6
  189.         movea.l        4*14+4(SP),FReq        ;FSRequest always in A4
  190.         move.l        FR_PosTxt(FReq),D0    ;User-defined PosTxt ?
  191.         bne.S        SetPosTxt
  192.         lea        TxtPositiv(PC),A0    ;Set default PosTxt
  193.         move.l        A0,D0
  194. SetPosTxt    lea        ITxtPos(PC),A0
  195.         move.l        D0,it_IText(A0)        ;Put PosTxt into IntuiText
  196.         move.l        FR_NegTxt(FReq),D0    ;User-defined NegTxt ?
  197.         bne.S        SetNegTxt
  198.         lea        TxtNegativ(PC),A0    ;Set default NegTxt
  199.         move.l        A0,D0
  200. SetNegTxt    lea        ITxtNeg(PC),A0
  201.         move.l        D0,it_IText(A0)        ;Put NegTxt into IntuiText
  202.         LoadBase    ExecBase
  203.         move.l        #InternalMem,D0
  204.         move.l        #MEMF_PUBLIC!MEMF_CLEAR,D1
  205.         CallLib        AllocMem        ;Allocate local data block + FileInfoBlock
  206.         movea.l        D0,FData        ;Internal datablock always in A5
  207.         moveq        #FSENoMem,D7 
  208.         tst.l        D0
  209.         beq        Exit
  210.         lea        FD_SIZEOF(FData),A0    ;fib MUST be longword-aligned
  211.         move.l        A0,FD_FIB(FData)    ;Use part of allocated memory as FileInfoBlock
  212.         lea        fib_SIZEOF(A0),A0
  213.         move.l        A0,FD_DisplayList(FData)
  214.         lea        4*DisplayRows(A0),A0
  215.         move.l        A0,FD_TxtBuf(FData)
  216.         lea        PathInfo(PC),A0        ;Put user-PathBuffer into StringInfo
  217.         move.w        FR_PathChars(FReq),si_MaxChars(A0)
  218.         move.l        FR_PathBuf(FReq),si_Buffer(A0)
  219.         lea        FileInfo(PC),A0        ;Put user-FileBuffer into StringInfo
  220.         move.w        FR_FileChars(FReq),si_MaxChars(A0)
  221.         move.l        FR_FileBuf(FReq),si_Buffer(A0)
  222.         moveq        #FSENoLib,D7
  223.         lea        DosName(PC),A1
  224.         CallLib        OldOpenLibrary        ;Open dos
  225.         move.l        D0,FD_DosBase(FData)
  226.         lea        GfxName(PC),A1
  227.         CallLib        OldOpenLibrary        ;Open graphics
  228.         move.l        D0,FD_GfxBase(FData)
  229.         lea        IntuiName(PC),A1
  230.         CallLib        OldOpenLibrary        ;Open Intuition
  231.         move.l        D0,FD_IntBase(FData)
  232.         lea        FileNW(PC),A0
  233.         movem.w        FR_LeftEdge(FReq),D0-D1
  234.         movem.w        D0-D1,nw_LeftEdge(A0)    ;Put coordinates into NewWindow-structure
  235.         moveq        #WBENCHSCREEN,D0
  236.         move.l        FR_Screen(FReq),nw_Screen(A0)    ;Put screen-ptr or 0 into NewWindow-structure    
  237.         beq.S        SetScreenType
  238.         moveq        #CUSTOMSCREEN,D0
  239. SetScreenType    move.w        D0,nw_Type(A0)        ;Put CUSTOMSCREEN or WBENCHSCREEN into NewWindow-structure
  240.         LoadBase    IntBase
  241.         CallLib        OpenWindow        ;Open the Window
  242.         moveq        #FSENoWin,D7
  243.         move.l        D0,FD_Window(FData)
  244.         beq.S        Exit
  245.         movea.l        D0,A1
  246.         move.l        wd_RPort(A1),FD_Rp(FData)    ;Get RastPort
  247.         move.l        wd_UserPort(A1),FD_Up(FData)    ;Get UserPort
  248.         lea        TxtAttr(PC),A0
  249.         LoadBase    GfxBase
  250.         CallLib        OpenFont        ;Open Topaz-80
  251.         movea.l        D0,A0
  252.         movea.l        FD_Rp(FData),A1
  253.         CallLib        SetFont            ;Use Topaz-80
  254.         bra.S        Main            ;Lets begin
  255. * Here we exits, D7 contains return-code
  256. Exit        btst        #LETSWAIT,FR_ToDo(FReq)    ;The completion of the list was interrupted ?
  257.         bne.S        FreeLock
  258.         move.l        FReq,-(SP)
  259.         Call        _FreeFileSelect        ;Free old list
  260.         addq.l        #4,SP
  261. FreeLock    Call        RemoveLock        ;UnLock if not already done
  262. FreeWindow    LoadBase    IntBase
  263.         move.l        FD_Window(FData),D0
  264.         beq.S        FreeInt
  265.         movea.l        D0,A0
  266.         movem.w        wd_LeftEdge(A0),D0-D1
  267.         movem.w        D0-D1,FR_LeftEdge(FReq)    ;Store window-position in FileSelectRequest structure
  268.         CallLib        CloseWindow        ;Close window if it was open
  269. FreeInt        LoadBase    ExecBase
  270.         move.l        FD_IntBase(FData),D0
  271.         beq.S        FreeGfx
  272.         movea.l        D0,A1
  273.         CallLib        CloseLibrary        ;Close intuition if it was open
  274. FreeGfx        move.l        FD_GfxBase(FData),D0
  275.         beq.S        FreeDos
  276.         movea.l        D0,A1
  277.         CallLib        CloseLibrary        ;Close graphics if it was open
  278. FreeDos        move.l        FD_DosBase(FData),D0
  279.         beq.S        FreeFSMem
  280.         movea.l        D0,A1
  281.         CallLib        CloseLibrary        ;Close dos if it was open
  282. FreeFSMem    move.l        FData,D0
  283.         beq.S        AllDone
  284.         movea.l        D0,A1
  285.         move.l        #InternalMem,D0
  286.         CallLib        FreeMem            ;Free allocated memory
  287. AllDone        move.l        D7,D0            ;Set return-code
  288.         Pop        D1-D7/A0-A6
  289.         rts                    ;Return to the caller
  290.  
  291. * Here we really begin    
  292. Main        ori.b        #(1<<REFSTR)!(1<<ACTFSG)!(1<<LETSWAIT),FR_ToDo(FReq)
  293.         tst.l        FR_List(FReq)        ;Called with a list ?. If so, use it
  294.         bne        RefreshDisplay        ;If not, lets start all over
  295.         move.b        #(1<<REFSTR)!(1<<ACTFSG)!(1<<NEWDIR),FR_ToDo(FReq)
  296. * This is the start of the event-loop
  297. * See what happened since last time
  298. GetNextMsg    LoadBase    IntBase
  299. CheckRefresh    bclr        #REFSTR,FR_ToDo(FReq)    ;Clear RefreshBit
  300.         beq.S        CheckActivate        ;Refresh String-Gadgets if it was set
  301.         lea        PathGad(PC),A0
  302.         movea.l        FD_Window(FData),A1
  303.         suba.l        A2,A2
  304.         moveq        #2,D0
  305.         CallLib        RefreshGList        ;Refresh String-Gadgets
  306. CheckActivate    bclr        #ACTFSG,FR_ToDo(FReq)    ;Clear activatebit
  307.         beq.S        CheckNewDir        ;Activate FileString-Gadget if it was set
  308.         lea        FileGad(PC),A0
  309.         movea.l        FD_Window(FData),A1
  310.         suba.l        A2,A2
  311.         CallLib        ActivateGadget        ;Activate FileString-Gadget
  312. CheckNewDir    bclr        #NEWDIR,FR_ToDo(FReq)    ;Clear NewDirBit
  313.         bne.S        DoNewPath        ;Get new directory if it was set
  314.         LoadBase    ExecBase
  315.         btst        #LETSWAIT,FR_ToDo(FReq)    ;Are we busy ?
  316.         beq.S        NotWaiting
  317.         movea.l        FD_Up(FData),A0
  318.         CallLib        WaitPort        ;We aren't busy, so we wait
  319. NotWaiting    movea.l        FD_Up(FData),A0
  320.         CallLib        GetMsg            ;Get a message
  321.         tst.l        D0
  322.         beq.S        DoneWithMessage        ;Did we get a message
  323. DoMessage    movea.l        D0,A1            ;Yes, put message address to A1 and reply
  324.         move.l        im_Class(A1),FD_Class(FData)
  325.         move.w        im_Code(A1),FD_Code(FData)
  326.         move.l        im_IAddress(A1),FD_IAddress(FData)
  327.         move.l        im_Seconds(A1),FD_Seconds(FData)
  328.         move.l        im_Micros(A1),FD_Micros(FData)
  329.         CallLib        ReplyMsg        ;Reply the message
  330.         move.l        FD_Class(FData),D0
  331.         moveq        #MOUSEBUTTONS,D1
  332.         cmp.l        D1,D0
  333.         beq        DoButtons
  334.         moveq        #GADGETUP,D1
  335.         cmp.l        D1,D0
  336.         beq        DoGadgets
  337.         cmpi.l        #INTUITICKS,D0        ;It is time to see if we should scroll
  338.         beq        CheckScroll
  339. DoneWithMessage    btst        #LETSWAIT,FR_ToDo(FReq)
  340.         beq.S        GetNextFile        ;If we are busy then get next file/dir/Device, else goto sleep
  341.  
  342. * Start scanning a new directory and the Device-List
  343. DoNewPath    bset        #NOTDEVS,FR_ToDo(FReq)    ;Lets get Devices first
  344.         bclr        #KEEPTOP,FR_ToDo(FReq)
  345.         Call        ResetKnob
  346.         Call        ClearDisplay
  347.         move.l        FReq,-(SP)
  348.         Call        _FreeFileSelect        ;Free old list
  349.         addq.l        #4,SP
  350.         Call        RemoveLock        ;Free old lock
  351.         moveq        #FR_ToDo-FR_TopView-1,D1
  352. ResetLoop    clr.b        FR_TopView(FReq,D1.W)    ;Clear FR_TopView and counters
  353.         dbf        D1,ResetLoop
  354.         lea        SelectTxt(PC),A1
  355.         tst.l        FR_TitleTxt(FReq)    ;Has the user supplied us with a title ?
  356.         beq.S        SetWTitle
  357.         movea.l        FR_TitleTxt(FReq),A1
  358. SetWTitle    movea.l        FD_Window(FData),A0
  359.         suba.l        A2,A2
  360.         LoadBase    IntBase
  361.         CallLib        SetWindowTitles        ;Set window-title (User-supplied or default)
  362. GetDevs        bset        #GETDEVS,FR_ToDo(FReq)    ;Lets get Devices first
  363.         Call        LockD            ;Lock DeviceList
  364.         bra.S        SignalDontWait
  365. GetFiles    LoadBase    DosBase            ;When that is done, we can get Files/Dirs
  366.         move.l        FR_PathBuf(FReq),D1
  367.         moveq        #ACCESS_READ,D2
  368.         CallLib        Lock            ;Lock new directory
  369.         move.l        D0,FD_Lock(FData)
  370.         beq        DirError
  371.         move.l        D0,D1
  372.         move.l        FD_FIB(FData),D2
  373.         CallLib        Examine            ;Examine new directory
  374.         tst.l        D0
  375.         beq        DirError
  376. SignalDontWait    bclr        #LETSWAIT,FR_ToDo(FReq)    ;We are busy, Can't wait
  377.  
  378. * Read next entry from directory or Device-list
  379. GetNextFile    btst        #GETDEVS,FR_ToDo(FReq)
  380.         beq.S        GettingFiles
  381. GettingDevs    Call        ExNextD            ;Try to get next device
  382.         bra.S        DidWeGetOne
  383. GettingFiles    LoadBase    DosBase
  384.         move.l        FD_Lock(FData),D1    ;Try to get next file
  385.         move.l        FD_FIB(FData),D2
  386.         CallLib        ExNext
  387. DidWeGetOne    tst.l        D0
  388.         beq        NoMore            ;Success, found something
  389.         movea.l        FD_FIB(FData),A3
  390.         lea        fib_FileName(A3),A0
  391.         Call        MyStrLen
  392.         tst.l        D0
  393.         beq        GetNextMsg        ;Could it happen ?
  394.         btst        #GETDEVS,FR_ToDo(FReq)    ;Is it a device ?
  395.         beq.S        SpecFDs
  396. SpecDevs    move.l        fib_DirEntryType(A3),D1
  397.         bne.S        SpecDevs2
  398.         btst        #FSB_NODRIVE,FR_Flags+1(FReq)
  399.         bra.S        Trick            ;This doesn't destroy cc
  400. SpecDevs2    subq.l        #1,D1
  401.         bne.S        SpecDevs3
  402.         btst        #FSB_NOASSIGN,FR_Flags+1(FReq)
  403.         bra.S        Trick
  404. SpecDevs3    btst        #FSB_NOVOL,FR_Flags+1(FReq)
  405.         bra.S        Trick
  406. SpecFDs        tst.l        fib_DirEntryType(A3)    ;Is it a directory ?
  407.         bmi.S        SpecFiles
  408. SpecDirs    btst        #FSB_NODIR,FR_Flags+1(FReq)
  409. Trick        bne        GetNextMsg
  410.         bra.S        DoneSpec
  411. SpecFiles    btst        #FSB_NOFILE,FR_Flags+1(FReq)
  412.         bne        GetNextMsg
  413.         btst        #FSB_NOINFO,FR_Flags+1(FReq)
  414.         beq.S        DoneSpec
  415.         cmpi.w        #5,D0            ;Too short
  416.         blt.S        DoneSpec
  417.         lea        fib_FileName(A3),A0
  418.         lea        -5(A0,D0.W),A0
  419.         lea        InfoTxt(PC),A1
  420.         moveq        #4,D1
  421. InfoLoop    cmpm.b        (A1)+,(A0)+
  422.         bne.S        DoneSpec
  423.         dbf        D1,InfoLoop
  424.         bra        GetNextMsg
  425. DoneSpec    addi.w        #EntrySIZEOF+1,D0    ;Make room for null character
  426.         move.l        D0,D6
  427.         move.l        #MEMF_PUBLIC!MEMF_CLEAR,D1
  428.         LoadBase    ExecBase
  429.         CallLib        AllocMem        ;AllocMem(EntryBaseSize+MyStrLen(Name)+1,MEM_CLEAR)
  430.         movea.l        D0,A0
  431.         tst.l        D0
  432.         beq        MemError
  433.         move.w        D6,EntrySize(A0)    ;Store size of allocated blok in the block itself
  434.         btst        #GETDEVS,FR_ToDo(FReq)    ;Is it a device ?
  435.         beq.S        IsItDirType
  436.         addq.w        #1,FR_Devs(FReq)    ;One more device
  437.         moveq        #DEVTYPE,D0        ;The next few lines is here just for sorting reasons
  438.         move.l        fib_DirEntryType(A3),D1
  439.         beq.S        OneMoreOfThese        ;DLT_DEVICE
  440.         moveq        #ASNTYPE,D0
  441.         subq.l        #1,D1
  442.         beq.S        OneMoreOfThese        ;DLT_DIRECTORY
  443.         moveq        #VOLTYPE,D0    
  444.         bra.S        OneMoreOfThese        ;DLT_VOLUME
  445. IsItDirType    tst.l        fib_DirEntryType(A3)    ;Is it a directory ?
  446.         bmi.S        IsItFileType
  447.         addq.w        #1,FR_Dirs(FReq)    ;One more directory
  448.         moveq        #DIRTYPE,D0
  449.         bra.S        OneMoreOfThese
  450. IsItFileType    addq.w        #1,FR_Files(FReq)    ;One more file
  451.         move.l        fib_Size(A3),D0        ;Store size instead of type
  452. OneMoreOfThese    move.l        D0,EntryType(A0)    ;D0=Type/Size
  453.         move.w        FR_Files(FReq),D0
  454.         add.w        FR_Dirs(FReq),D0
  455.         btst        #NOTDEVS,FR_ToDo(FReq)
  456.         bne.S        DontCountDevs
  457.         add.w        FR_Devs(FReq),D0
  458. DontCountDevs    move.w        D0,FR_Count(FReq)
  459.         lea        fib_FileName(A3),A1
  460.         lea        EntryName(A0),A2
  461. StoreNameLoop    move.b        (A1)+,(A2)+        ;Copy name from FIB to EntryNode
  462.         bne.S        StoreNameLoop
  463.         move.w        SlideInfo+pi_VertPot(PC),FD_SlideVPos(FData)    ;Necessary, otherwise the user couldn't drag the slider
  464.         Call        SortFiles        ;while a directory is being scanned
  465.         move.w        FR_Count(FReq),D0
  466.         beq        GetNextMsg        ;Only devices so far ?
  467.         sub.w        FR_TopCount(FReq),D0
  468.         subq.w        #DisplayRows,D0
  469.         bgt.S        AdjustKnob        ;Full display ?
  470. Here        move.w        FR_TopCount(FReq),D0
  471.         bra        SeeThem
  472. AdjustKnob    Call        SetKnobHeight        ;Display is full
  473.         Call        SetKnobPos
  474.         Call        SetKnob            ;slider while the directory/device-List is being scanned
  475.         bra        GetNextMsg
  476. MemError    lea        MemErrorTxt(PC),A1    ;Could not get memory for a node
  477.         bra.S        ShowError
  478. DirError    lea        DirErrorTxt(PC),A1    ;Could not Lock/Examine a directory
  479. ShowError    LoadBase    IntBase
  480.         movea.l        FD_Window(FData),A0
  481.         suba.l        A2,A2
  482.         CallLib        SetWindowTitles
  483. NoMore        Call        RemoveLock        ;Let's unlock
  484.         bclr        #GETDEVS,FR_ToDo(FReq)
  485.         bne        GetFiles        ;Were we getting Devices ?
  486. WasFileLock    bset        #LETSWAIT,FR_ToDo(FReq)    ;We are done getting Files/Dirs. We can wait now
  487.         move.w        FR_Count(FReq),D0
  488.         beq.S        Here
  489.         subq.w        #DisplayRows,D0
  490.         bgt.S        Here
  491.         clr.w        FR_TopCount(FReq)
  492.         move.l        FR_List(FReq),FR_TopView(FReq)
  493.         bra.S        Here
  494.  
  495. * Have just recieved a MOUSEBUTTONS-message
  496. DoButtons    bset        #ACTFSG,FR_ToDo(FReq)    ;Always activate FileString-gadget
  497.         cmpi.w        #MENUDOWN,FD_Code(FData);Pressed the Menu-button
  498.         bne        GetNextMsg
  499.         Call        ClearDisplay
  500.         moveq        #0,D0
  501.         bclr        #NOTDEVS,FR_ToDo(FReq)    ;yes
  502.         beq.S        DontAddDevs
  503.         move.w        FR_Devs(FReq),D1
  504.         add.w        D1,FR_Count(FReq)    ;Now devices can be shown
  505.         bra.S        SeeDevs
  506. DontAddDevs    movea.l        FR_TopView(FReq),A0
  507.         moveq        #DIRTYPE,D1
  508.         cmp.l        EntryType(A0),D1
  509.         bgt.S        SeeFiles
  510.         bne.S        SeeDirs
  511.         bra.S        SeeDevs
  512. SeeFiles    tst.w        FR_Files(FReq)
  513.         bne.S        SeeThese
  514. SeeDirs        tst.w        FR_Dirs(FReq)
  515.         bne.S        SeeTrick
  516. SeeDevs        tst.w        FR_Devs(FReq)
  517.         beq.S        SeeFiles
  518.         add.w        FR_Dirs(FReq),D0
  519. SeeTrick    add.w        FR_Files(FReq),D0
  520. SeeThese    bset        #KEEPTOP,FR_ToDo(FReq)
  521.         bra        SeeThem            ;Look at files
  522.  
  523. * Have just recieved a GADGETUP-message
  524. DoGadgets    bset        #ACTFSG,FR_ToDo(FReq)    ;Always activate FileString-gadget
  525.         movea.l        FD_IAddress(FData),A1
  526.         move.w        gg_GadgetID(A1),D0
  527.         lsl.w        #1,D0
  528.         move.w        GJ(PC,D0.W),D0
  529.         jmp        GJ(PC,D0.W)
  530. GJ        dc.w        DoSelect-GJ        ;Gadget indirect jumptable
  531.         dc.w        DoSelect-GJ
  532.         dc.w        DoSelect-GJ
  533.         dc.w        DoSelect-GJ
  534.         dc.w        DoSelect-GJ
  535.         dc.w        DoSelect-GJ
  536.         dc.w        DoSelect-GJ
  537.         dc.w        DoParent-GJ
  538.         dc.w        GetNextMsg-GJ        ;Up   arrow
  539.         dc.w        GetNextMsg-GJ        ;Down arrow
  540.         dc.w        SlideScroll-GJ        ;Clicked in Slide-gadget box beside the knob
  541.         dc.w        DoPathStr-GJ
  542.         dc.w        DoPosExit-GJ
  543.         dc.w        DoNegExit-GJ
  544.  
  545. * You clicked on one of the 7 gadgets on the display
  546. DoSelect    movea.l        FD_IAddress(FData),A1
  547.         move.w        gg_GadgetID(A1),D0
  548.         lsl.l        #2,D0
  549.         movea.l        FD_DisplayList(FData),A2
  550.         move.l        0(A2,D0.W),D0
  551.         beq.S        DoneSelect
  552.         movea.l        D0,A2            ;A2=EntryNode
  553.         tst.l        EntryType(A2)        ;Test type
  554.         bmi.S        NewDir
  555. NewFile        cmpa.l        FD_LastSelect(FData),A2    ;Same as last time ?
  556.         bne.S        NoDouble
  557.         LoadBase    IntBase            ;Same as last time. Check time between clicks
  558.         movem.l        FD_OSeconds(FData),D0-D1;Time of previous select
  559.         movem.l        FD_Seconds(FData),D2-D3    ;Time of this select
  560.         CallLib        DoubleClick
  561.         tst.l        D0
  562.         bne        DoPosExit        ;Double-clicked on a file. Let's exit
  563. NoDouble    move.l        A2,FD_LastSelect(FData)    ;New last select
  564.         movem.l        FD_Seconds(FData),D0-D1
  565.         movem.l        D0-D1,FD_OSeconds(FData);Store time this select
  566.         movea.l        FR_FileBuf(FReq),A0
  567.         move.w        FR_FileChars(FReq),D1
  568.         ext.l        D1
  569.         add.l        A0,D1            ;This is the end of the FileBuffer
  570.         bra.S        CopyFile
  571. NewDir        bset        #NEWDIR,FR_ToDo(FReq)
  572.         movea.l        FR_PathBuf(FReq),A0
  573.         move.w        FR_PathChars(FReq),D1
  574.         subq.w        #1,D1            ;Need room for '/' in the end
  575.         ext.l        D1
  576.         add.l        A0,D1            ;This is the end of the PathBuffer
  577.         cmpi.l        #DEVTYPE,EntryType(A2)
  578.         ble.S        CopyFile        ;Clicked on something ending with a ':' ?
  579.         Call        TackOn            ;Clicked on a directory
  580. CopyFile    lea        EntryName(A2),A1
  581.         subq.l        #1,D1
  582. FileCopyLoop    cmpa.l        D1,A0
  583.         beq.S        BufOverflow
  584.         move.b        (A1)+,(A0)+        ;Copy name to String-Gadget
  585.         bne.S        FileCopyLoop
  586. BufOverflow    clr.b        (A0)            ;Just in case we overflowed
  587.         bset        #REFSTR,FR_ToDo(FReq)
  588. DoneSelect    bra        GetNextMsg
  589.  
  590. * The slide-knob is currently selected and you moved the mouse, or
  591. * you clicked in the prop-gadget box beside the knob
  592. SlideScroll    move.w        SlideInfo+pi_VertPot(PC),FD_SlideVPos(FData)
  593.         moveq        #0,D0
  594.         move.w        FR_Count(FReq),D2
  595.         subq.w        #DisplayRows,D2        ;TopCount must not be greater than Count-DisplayRows
  596.         ble.S        NoNewTop        ;If less than DisplayRows files then TopIt
  597.         move.l        #MAXPOT,D1
  598.         divu        D2,D1            ;65535/(Count-DisplayRows)
  599.         move.w        FD_SlideVPos(FData),D0
  600.         divu        D1,D0            ;D0=Slide.vertpot/(65535/(Count-DisplayRows))
  601.         cmp.w        FR_TopCount(FReq),D0    ;Last line will cause a crash if Count-DisplayRows>65535
  602.         beq.S        DoneScroll        ;Don't scroll if knob hasn't moved enough
  603.         cmp.w        D2,D0            ;If TopCount>D2 then
  604.         ble.S        NoNewTop
  605.         move.w        D2,D0            ;TopCount=D2
  606. NoNewTop    bset        #DONTPOS,FR_ToDo(FReq)
  607.         bclr        #KEEPTOP,FR_ToDo(FReq)
  608.         bra.S        SeeThem
  609.  
  610. * Have just recieved a INTUITICK-message, and are now going to examine
  611. * whether the arrow-gadget are currently selected
  612. CheckScroll    btst        #7,SlideGad+gg_Flags+1(PC)    ;SlideGad Selected ?
  613.         bne.S        SlideScroll
  614.         btst        #7,UpGad+gg_Flags+1(PC)        ;UpGad Selected ?
  615.         bne.S        ScrollOneUp
  616.         btst        #7,DownGad+gg_Flags+1(PC)    ;DownGad Selected ?
  617.         beq.S        DoneScroll
  618. * The down-arrow is currently selected
  619. ScrollOneDown    move.w        FR_TopCount(FReq),D0
  620.         move.w        FR_Count(FReq),D1
  621.         subq.w        #DisplayRows,D1
  622.         cmp.w        D0,D1            ;If TopCount+DisplayRows>Count then dont scroll
  623.         ble.S        DoneScroll
  624.         addq.w        #1,D0
  625.         bra.S        SeeThem
  626. * The up-arrow is currently selected
  627. ScrollOneUp    move.w        FR_TopCount(FReq),D0
  628.         beq.S        DoneScroll        ;If TopCount=0 then dont scroll
  629.         subq.w        #1,D0
  630.  
  631. * D0=count of node to display on top of the display
  632. * Finds node and fills the display
  633. SeeThem        move.w        D0,FR_TopCount(FReq)    ;Show the list from the 'D0'th node
  634. FindEntry    lea        FR_List(FReq),A0
  635.         movea.l        EntryNext(A0),A0
  636. EntryLoop    subq.w        #1,D0
  637.         bmi.S        DoneFindEntry
  638.         movea.l        EntryNext(A0),A0
  639.         bra.S        EntryLoop
  640. DoneFindEntry    move.l        A0,FR_TopView(FReq)
  641. RefreshDisplay    Call        WriteDisplay
  642.         bclr        #DONTPOS,FR_ToDo(FReq)
  643.         bne.S        DoneScroll        ;If called from SlideScroll then
  644.         Call        SetKnobHeight        ;don't do any of these
  645.         Call        SetKnobPos        ;because intuition
  646.         Call        SetKnob            ;has already done it
  647. DoneScroll    bra        GetNextMsg
  648.  
  649. * You clicked the 'Parent' button
  650. DoParent    ori.b        #(1<<REFSTR)!(1<<NEWDIR),FR_ToDo(FReq)
  651.         movea.l        FR_PathBuf(FReq),A0
  652.         Call        MyStrLen        ;Returns length excluding the null
  653.         subq.w        #1,D0            ;Skip the last character
  654.         beq.S        DoneParent2        ;One more than besides the null ?
  655.         bmi.S        DoneParent3        ;Only the null was present ?
  656. CutOffLoop    subq.w        #1,D0
  657.         bmi.S        DoneParent1
  658.         move.b        0(A0,D0.W),D1
  659.         cmpi.b        #'/',D1
  660.         beq.S        DoneParent2        ;If '/' then clear this byte
  661.         cmpi.b        #':',D1
  662.         bne.S        CutOffLoop        ;If ':' then clear next byte
  663. DoneParent1    addq.w        #1,D0
  664. DoneParent2    clr.b        0(A0,D0.W)
  665. DoneParent3    bra        GetNextMsg
  666.  
  667. * You pressed return while the path-string-gadget was active
  668. DoPathStr    bset        #NEWDIR,FR_ToDo(FReq)
  669.         bra        GetNextMsg
  670.  
  671. * You clicked the 'Ok' button, or
  672. * you pressed return while the file-string-gadget was active, or
  673. * you double-clicked on a filename
  674. DoPosExit    movea.l        FR_PathBuf(FReq),A0
  675.         Call        TackOn            ;Append a '/'
  676.         bra.S        DoExit
  677. * You clicked the 'Cancel' button
  678. DoNegExit    moveq        #FSENeg,D7
  679. DoExit        bra        Exit
  680.  
  681. * ----------------------- Misc sub-routines ----------------------------
  682. * A0=String, returns i D0.L the length of string excluding the null character
  683. * Destroys D0
  684. MyStrLen    PushS        A0
  685.         moveq        #-1,D0
  686. MyStrLenLoop    addq.l        #1,D0
  687.         tst.b        (A0)+
  688.         bne.S        MyStrLenLoop
  689.         PopS        A0
  690.         rts
  691.  
  692. * A0=Buffer to extend with a '/' if the buffer is non-empty, and
  693. * if it doesn't already end with a '/' or a ':'
  694. * Destroys A0 which on return points to NULL-byte after ':' or '/'
  695. TackOn        PushS        D0
  696.         Call        MyStrLen
  697.         tst.w        D0
  698.         adda.w        D0,A0            ;End of the path-string
  699.         beq.S        EndTackOn
  700.         cmpi.b        #':',-1(A0)        ;If path ends on anything else than
  701.         beq.S        EndTackOn        ;a ':'
  702.         moveq        #'/',D0
  703.         cmp.b        -1(A0),D0        ;or a '/'
  704.         beq.S        EndTackOn
  705.         move.b        D0,(A0)+        ;then add a '/'
  706. EndTackOn    clr.b        (A0)            ;and a NULL
  707.         PopS        D0
  708.         rts
  709.  
  710. * Sets the Slide-Knob vertical size according to FR_Count
  711. * Doesn't destroys registers
  712. SetKnobHeight    Push        D0-D2
  713.         move.l        #MAXBODY,D0
  714.         move.w        FR_Count(FReq),D1
  715.         moveq        #DisplayRows,D2        ;Count<=DisplayRows means full-sized knob
  716.         cmp.w        D2,D1
  717.         ble.S        DoneSH
  718.         divu        D1,D0            ;D0=65535/Count*DisplayRows
  719.         mulu        D2,D0
  720. DoneSH        move.w        D0,FD_SlideHeight(FData)
  721.         Pop        D0-D2
  722.         rts
  723. * Sets the Slide-Knob vertical position according to FR_TopCount
  724. * Doesn't destroys registers
  725. SetKnobPos    Push        D0-D1
  726.         moveq        #0,D0
  727.         move.w        FR_Count(FReq),D1
  728.         subq.w        #DisplayRows,D1
  729.         ble.S        SetKnobToTop        ;Count<=DisplayRows means top-placed knob
  730.         move.w        FR_TopCount(FReq),D0
  731.         swap        D0
  732.         divu        D1,D0            ;(D0*65535)/(Count-DisplayRows)
  733.         bvc.S        SetKnobToTop
  734.         moveq        #-1,D0            ;move.l #MAXPOS,D0
  735. SetKnobToTop    move.w        D0,FD_SlideVPos(FData)
  736.         Pop        D0-D1
  737.         rts
  738. * Makes the Slide-Knob fill the entire Prop-Gadget
  739. * Doesn't destroys registers
  740. ResetKnob    clr.w        FD_SlideVPos(FData)    ;Knob to the top
  741.         move.w        #-1,FD_SlideHeight(FData);Full size
  742. * Updates/refreshes the Prop-Gadget
  743. * Doesn't destroys registers
  744. SetKnob        Push        D0-D5/A0-A2
  745.         lea        SlideGad(PC),A0
  746.         movea.l        FD_Window(FData),A1
  747.         suba.l        A2,A2
  748.         moveq        #AUTOKNOB!FREEVERT!PROPBORDERLESS,D0
  749.         moveq        #0,D1
  750.         move.w        FD_SlideVPos(FData),D2
  751.         moveq        #-1,D3            ;move.w #$FFFF,D3 (HorizBody)
  752.         move.w        FD_SlideHeight(FData),D4
  753.         moveq        #1,D5
  754.         LoadBase    IntBase
  755.         CallLib        NewModifyProp
  756.         Pop        D0-D5/A0-A2
  757.         rts
  758.  
  759. * Fills the display with color 0
  760. * Doesn't destroys registers
  761. ClearDisplay    Push        D0-D3/A0-A1
  762.         LoadBase    GfxBase            ;Clear display
  763.         moveq        #0,D0
  764.         movea.l        FD_Rp(FData),A1
  765.         CallLib        SetAPen
  766.         moveq        #6,D0
  767.         moveq        #12,D1
  768.         move.w        #6+DisplayCols*8,D2
  769.         moveq        #81,D3
  770.         movea.l        FD_Rp(FData),A1
  771.         CallLib        RectFill
  772.         moveq        #1,D0
  773.         movea.l        FD_Rp(FData),A1
  774.         CallLib        SetAPen
  775.         Pop        D0-D3/A0-A1        ;Fall through
  776. * Clears then DisplayList-array
  777. * Doesn't destroys registers
  778. ClearDisplayArr    Push        D0/A0
  779.         movea.l        FD_DisplayList(FData),A0
  780.         moveq        #DisplayRows-1,D0
  781. ClearArrLoop    clr.l        (A0)+
  782.         dbf        D0,ClearArrLoop
  783.         Pop        D0/A0
  784.         rts
  785.  
  786. * Fills the display with filenames plus size/type
  787. * Stores the address of the nodes containing the displayed filenames in DisplayRows
  788. * This routine could be made faster (but its fast enough for now)
  789. * Doesn't destroys registers
  790. WriteDisplay    Push        D0-D4/A0-A3
  791.         Call        ClearDisplayArr
  792.         LoadBase    GfxBase
  793.         move.w        FR_TopCount(FReq),D4
  794.         movea.l        FR_TopView(FReq),A3
  795.         movea.l        FD_DisplayList(FData),A2
  796.         moveq        #19,D3
  797. WriteLoop    cmp.l        #0,A3            ;This double-condition is necessary in order
  798.         beq        DoneWriting        ;to keep the devices from being shown
  799.         cmp.w        FR_Count(FReq),D4    ;because FR_TopCount doesn't correspond to
  800.         bge        DoneWriting        ;FR_TopView while the list is being build
  801.         move.l        A3,(A2)+        ;Save address of EntryNode
  802.         movea.l        FD_TxtBuf(FData),A0
  803.         move.l        EntryType(A3),D0    ;D0=Type or Size
  804.         bge.S        CopyName
  805. InsertType    addq.w        #1,D0            ;Find correct text to insert
  806.         mulu        #-5,D0
  807.         lea        TxtDirs(PC),A1
  808.         adda.w        D0,A1            ;One more directory,device,volume or 'assign'
  809.         movea.l        FD_TxtBuf(FData),A0
  810.         moveq        #4,D0
  811. InsertTypeLoop    move.b        (A1)+,(A0)+        ;Insert '(Dir)','<Dev>','<Vol>' or '<Asn>'
  812.         dbf        D0,InsertTypeLoop
  813.         move.b        #' ',(A0)+
  814. CopyName    lea        EntryName(A3),A1
  815. NameCopyLoop    move.b        (A1)+,(A0)+        ;Copy name to Txtbuffer
  816.         bne.S        NameCopyLoop
  817.         subq.l        #1,A0
  818.         move.l        A0,D0
  819.         sub.l        FD_TxtBuf(FData),D0
  820.         moveq        #DisplayCols-1,D1
  821.         sub.w        D0,D1
  822.         moveq        #' ',D0
  823. BuffClearLoop    move.b        D0,(A0)+        ;Clear rest of Txtbuffer
  824.         dbf        D1,BuffClearLoop
  825.         move.l        EntryType(A3),D0    ;D0=Type or Size
  826.         cmpi.l        #DIRTYPE,D0
  827.         blt.S        TxtInDevColor
  828.         beq.S        TxtInDirColor
  829.         btst        #FSB_NOFILESIZE,FR_Flags+1(FReq)
  830.         bne.S        TxtInFileColor        ;This doesn't destroy cc
  831. InsertSize    move.b        #'0',-1(A0)        ;This has to be done If D0=0 
  832. ConvertLoop    tst.l        D0            ;A0=end of Txtbuffer
  833.         ble.S        TxtInFileColor
  834.         divu        #10,D0
  835.         swap        D0
  836.         addi.b        #'0',D0
  837.         move.b        D0,-(A0)
  838.         clr.w        D0
  839.         swap        D0
  840.         bra.S        ConvertLoop
  841. TxtInFileColor    moveq        #FILECOLOR,D0
  842.         bra.S        WriteLine
  843. TxtInDirColor    moveq        #DIRCOLOR,D0
  844.         bra.S        WriteLine
  845. TxtInDevColor    moveq        #DEVCOLOR,D0
  846. WriteLine    movea.l        FD_Rp(FData),A1
  847.         cmp.b        rp_FgPen(A1),D0
  848.         beq.S        DontSetColor
  849.         CallLib        SetAPen            ;Shouldn't do this everytime
  850. DontSetColor    moveq        #6,D0
  851.         move.w        D3,D1
  852.         movea.l        FD_Rp(FData),A1
  853.         CallLib        Move
  854.         moveq        #DisplayCols,D0
  855.         movea.l        FD_TxtBuf(FData),A0
  856.         movea.l        FD_Rp(FData),A1
  857.         move.b        #%00000011,rp_Mask(A1)    ;Only write in bitplanes 0 and 1
  858.         CallLib        Text
  859.         addq.w        #1,D4
  860.         movea.l        EntryNext(A3),A3
  861.         addi.w        #10,D3            ;Add 10 to vertical Write-position
  862.         cmpi.w        #19+(DisplayRows-1)*10,D3
  863.         ble        WriteLoop
  864. DoneWriting    Pop        D0-D4/A0-A3
  865.         rts
  866.  
  867. * A0=Node to insert in list
  868. * Sorts according to EntryType and EntryName
  869. * Destroys D0-D4,A0-A3
  870. SortFiles    lea        EntryName(A0),A2
  871.         movea.l        FD_TxtBuf(FData),A3
  872. UpperCaseLoop    move.b        (A2)+,D0        ;Convert name to uppercase
  873.         beq.S        DoneUpperCase
  874.         cmpi.b        #'a',D0
  875.         blt.S        StoreUpperCase
  876.         cmpi.b        #'z',D0
  877.         bgt.S        StoreUpperCase
  878.         subi.b        #32,D0
  879. StoreUpperCase    move.b        D0,(A3)+
  880.         bra.S        UpperCaseLoop
  881. DoneUpperCase    move.l        EntryType(A0),D0
  882.         bmi.S        TypeOk
  883.         moveq        #1,D0            ;Type 1 is File
  884. TypeOk        lea        FR_List(FReq),A1
  885.         move.l        FR_TopView(FReq),D4
  886. SortLoop    cmp.l        A1,D4
  887.         bne.S        LowerThan
  888.         moveq        #0,D4
  889. LowerThan    move.l        A1,D3            ;D3 always entry to insert after
  890.         tst.l        EntryNext(A1)
  891.         beq.S        Insert            ;End of list ?
  892.         movea.l        EntryNext(A1),A1    ;We go further down
  893.         move.l        EntryType(A1),D2
  894.         bmi.S        TypeOk2
  895.         moveq        #1,D2            ;Type 1 is File
  896. TypeOk2        cmp.l        D2,D0
  897.         blt.S        SortLoop
  898.         bgt.S        Insert
  899. CmpStr        movea.l        FD_TxtBuf(FData),A2    ;Name to insert
  900.         lea        EntryName(A1),A3    ;Name to compare to
  901. CmpLoop        move.b        (A3)+,D1
  902.         beq.S        SortLoop
  903.         cmpi.b        #'a',D1
  904.         blt.S        Compare
  905.         cmpi.b        #'z',D1
  906.         bgt.S        Compare
  907.         subi.b        #32,D1
  908. Compare        cmp.b        (A2)+,D1        ;Compare in uppercase
  909.         beq.S        CmpLoop
  910.         blt.S        SortLoop        ;If name to insert>name in list then continue
  911. Insert        movea.l        D3,A1
  912.         move.l        EntryNext(A1),EntryNext(A0)    ;A0 is entry to insert
  913.         move.l        A0,EntryNext(A1)
  914.         tst.w        D4
  915.         beq.S        DoneSort
  916.         btst        #KEEPTOP,FR_ToDo(FReq)
  917.         beq.S        DoneSort
  918.         addq.w        #1,FR_TopCount(FReq)    ;Inserted the new entry before TopView        
  919. DoneSort    rts
  920.  
  921. * UnLocks, whether FD_Lock is on a file or on the Device-list
  922. * Doesn't destroy  registers
  923. RemoveLock    Push        D0-D1/A0-A1
  924.         move.l        FD_Lock(FData),D1
  925.         beq.S        DoneRemoveLock
  926.         btst        #GETDEVS,FR_ToDo(FReq)
  927.         beq.S        RemoveFileLock
  928. RemoveDevLock    Call        UnLockD            ;Unlock Device-List
  929.         bra.S        DoneRemoveLock
  930. RemoveFileLock    LoadBase    DosBase
  931.         CallLib        UnLock
  932. DoneRemoveLock    clr.l        FD_Lock(FData)
  933.         Pop        D0-D1/A0-A1
  934.         rts
  935.  
  936. * The next three sub-routines fakes a Lock/UnLock/ExNext (Not Examine) on the Device-List
  937. * LockD disables multitasking to make sure the Device-List is not changed while doing ExNextD's
  938. * UnLockD enables multitasking again
  939.  
  940. * Stores the Device-List in FD_Lock 
  941. * Doesn't destroys registers
  942. LockD        Push        D0-D1/A0-A1
  943.         LoadBase    ExecBase
  944.         CallLib        Forbid
  945.         movea.l        FD_DosBase(FData),A0
  946.         movea.l        dl_Root(A0),A0        ;dl_Root
  947.         movea.l        rn_Info(A0),A0        ;dl_Root->rn_Info
  948.         adda.l        A0,A0
  949.         adda.l        A0,A0
  950.         movea.l        di_DevInfo(A0),A0    ;Dosbase->dl_Root->rn_Info->di_DevInfo
  951.         adda.l        A0,A0
  952.         adda.l        A0,A0
  953.         move.l        A0,FD_Lock(FData)
  954.         Pop        D0-D1/A0-A1
  955.         rts
  956.  
  957. * Clears FD_Lock
  958. * Doesn't destroys registers
  959. UnLockD        Push        D0-D1/A0-A1
  960.         LoadBase    ExecBase
  961.         CallLib        Permit
  962.         clr.l        FD_Lock(FData)
  963.         Pop        D0-D1/A0-A1
  964.         rts
  965.  
  966. * Fills the FileInfoBlock FD_FIB with name and type
  967. * Returns 0 in D0 if no more entries on the Device-List and 1 otherwise
  968. * Destroys D0
  969. ExNextD        Push        D1-D2/A0-A3
  970. FindNextDev    movea.l        FD_FIB(FData),A2    ;A2=FIB
  971.         movea.l        FD_Lock(FData),A3    ;A3=(struct DeviceList *)Lock
  972.         moveq        #0,D0            ;Return code
  973.         tst.l        FD_Lock(FData)        ;while not end of list
  974.         beq.S        EndOfList
  975.         move.l        dl_Next(A3),D0
  976.         asl.l        #2,D0
  977.         move.l        D0,FD_Lock(FData)
  978.         move.l        dl_Type(A3),D1
  979.         moveq        #DLT_VOLUME,D0
  980.         cmp.l        D0,D1
  981.         beq.S        GetTheDevice
  982.         moveq        #DLT_DIRECTORY,D0
  983.         cmp.l        D0,D1
  984.         beq.S        GetTheDevice
  985.         moveq        #DLT_DEVICE,D0
  986.         cmp.l        D0,D1
  987.         bne.S        FindNextDev
  988.         tst.l        dl_Task(A3)        ;if(dn->dn_Task == 0 then skip it
  989.         beq.S        FindNextDev
  990. GetTheDevice    movea.l        dl_Name(A3),A1        ;A1=(BPTR)list->dl_Name
  991.         adda.l        A1,A1
  992.         adda.l        A1,A1
  993.         move.b        (A1)+,D0        ;D0=Length of string, A0=string
  994.         ext.w        D0
  995.         moveq        #32,D2
  996.         cmp.w        D2,D0            ;if(D0 > 32)
  997.         ble.S        NameLengthIsOk
  998.         move.w        D2,D0            ;D0 = 32;
  999. NameLengthIsOk    lea        fib_FileName(A2),A0    ;A0=fib->fib_FileName
  1000.         subq.w        #1,D0
  1001. CopyLoop    move.b        (A1)+,(A0)+
  1002.         dbf        D0,CopyLoop
  1003.         move.b        #':',(A0)+        ;Append a ':'
  1004.         clr.b        (A0)+            ;and a NULL
  1005.         move.l        dl_Type(A3),fib_DirEntryType(A2)    ;fib->fib_DirEntryType=list->dl_type
  1006.         moveq        #1,D0            ;return 1;
  1007. EndOfList    Pop        D1-D2/A0-A3
  1008.         rts                    ;return 1 or return 0
  1009.  
  1010. DosName        dc.b        'dos.library',0
  1011. GfxName        dc.b        'graphics.library',0
  1012. IntuiName    dc.b        'intuition.library',0
  1013.         EVEN
  1014.  
  1015. FileNW        dc.w        111,58,299,126
  1016.         dc.b        0,1
  1017.         dc.l        MOUSEBUTTONS!GADGETUP!INTUITICKS,ACTIVATE!RMBTRAP!WINDOWDRAG,GadgetList,0,0,0,0
  1018.         dc.w        0,0,0,0,0
  1019.  
  1020. BWIDTH        =74
  1021. BHEIGHT        =11
  1022. ButBorder    BORDER        -2,-1,BUTCOLOR,0,RP_JAM2,17,ButVectors,0
  1023. ButVectors    dc.w        2,0,BWIDTH+1,0,BWIDTH+3,2,BWIDTH+3,BHEIGHT-1,BWIDTH+1,BHEIGHT+1,2,BHEIGHT+1,0,BHEIGHT-1,0,2,2,0
  1024.         dc.w        1,0,-1,2,-1,BHEIGHT-1,1,BHEIGHT+1,BWIDTH+2,BHEIGHT+1,BWIDTH+4,BHEIGHT-1,BWIDTH+4,2,BWIDTH+2,0
  1025. SWIDTH        =215
  1026. SHEIGHT        =10
  1027. StrBorder    BORDER        -4,-2,STRCOLOR,0,RP_JAM2,17,SVectors,0
  1028. SVectors    dc.w        2,0,SWIDTH+1,0,SWIDTH+3,2,SWIDTH+3,SHEIGHT-1,SWIDTH+1,SHEIGHT+1,2,SHEIGHT+1,0,SHEIGHT-1,0,2,2,0
  1029.         dc.w        1,0,-1,2,-1,SHEIGHT-1,1,SHEIGHT+1,SWIDTH+2,SHEIGHT+1,SWIDTH+4,SHEIGHT-1,SWIDTH+4,2,SWIDTH+2,0
  1030. PWIDTH        =18
  1031. PHEIGHT        =70
  1032. P2HEIGHT    =92
  1033. SlideBorder    BORDER        -2,-82,PROPCOLOR,0,RP_JAM2,17,PVectors,0
  1034. PVectors    dc.w        2,0,PWIDTH+1,0,PWIDTH+3,2,PWIDTH+3,P2HEIGHT-1,PWIDTH+1,P2HEIGHT+1,2,P2HEIGHT+1,0,P2HEIGHT-1,0,2,2,0
  1035.         dc.w        1,0,-1,2,-1,P2HEIGHT-1,1,P2HEIGHT+1,PWIDTH+2,P2HEIGHT+1,PWIDTH+4,P2HEIGHT-1,PWIDTH+4,2,PWIDTH+2,0
  1036.  
  1037. ITxtParent    INTUITEXT    1,0,RP_JAM2,13,2,TxtParent,0
  1038. ITxtPath    INTUITEXT    1,0,RP_JAM2,-41,0,TxtPath,0
  1039. ITxtFile    INTUITEXT    1,0,RP_JAM2,-41,0,TxtFile,0
  1040. ITxtPos        INTUITEXT    1,0,RP_JAM2,5,2,TxtPositiv,0
  1041. ITxtNeg        INTUITEXT    1,0,RP_JAM2,5,2,TxtNegativ,0
  1042.  
  1043. TxtAttr        dc.l        FontName
  1044.         dc.w        TOPAZ_EIGHTY
  1045.         dc.b        FS_NORMAL,FPB_ROMFONT
  1046.  
  1047. FontName    dc.b        'topaz.font',0
  1048. MemErrorTxt    dc.b        'Out of memory',0
  1049. DirErrorTxt    dc.b        'Directory error',0
  1050. SelectTxt    dc.b        'Select a file',0
  1051. InfoTxt        dc.b        '.info'
  1052. TxtDirs        dc.b        '(dir)'            ;\
  1053. TxtDevs        dc.b        '<dev>'            ; \The order and length of these strings is important to 'WriteDisplay'
  1054. TxtVols        dc.b        '<vol>'            ; /
  1055. TxtAsns        dc.b        '<asn>'            ;/
  1056. TxtParent    dc.b        'Parent',0
  1057. TxtPath        dc.b        'Path',0
  1058. TxtFile        dc.b        'File',0
  1059. TxtNegativ    dc.b        ' Cancel',0
  1060. TxtPositiv    dc.b        '   Ok',0
  1061.         EVEN
  1062.  
  1063. SlideImage    IMAGE        0,0,0,0,0,0,0,0,0
  1064. ArrowsImage    IMAGE        1,0,16,22,1,ArrowsData,%00000001,%00000000,0
  1065.  
  1066. PathInfo    ds.b        36
  1067. FileInfo    ds.b        36
  1068. SlideInfo    dc.w        AUTOKNOB!FREEVERT!PROPBORDERLESS,0,0,0,8700,0,0,0,0,0,0
  1069.  
  1070. GadgetList
  1071. Select1Gad    GADGET        Select2Gad,4,12,DisplayCols*8+3,10,GADGHCOMP,RELVERIFY,BOOLGADGET
  1072.         GADGET2        0,0,0,0,0,Select1ID,0
  1073. Select2Gad    GADGET        Select3Gad,4,22,DisplayCols*8+3,10,GADGHCOMP,RELVERIFY,BOOLGADGET
  1074.         GADGET2        0,0,0,0,0,Select2ID,0
  1075. Select3Gad    GADGET        Select4Gad,4,32,DisplayCols*8+3,10,GADGHCOMP,RELVERIFY,BOOLGADGET
  1076.         GADGET2        0,0,0,0,0,Select3ID,0
  1077. Select4Gad    GADGET        Select5Gad,4,42,DisplayCols*8+3,10,GADGHCOMP,RELVERIFY,BOOLGADGET
  1078.         GADGET2        0,0,0,0,0,Select4ID,0
  1079. Select5Gad    GADGET        Select6Gad,4,52,DisplayCols*8+3,10,GADGHCOMP,RELVERIFY,BOOLGADGET
  1080.         GADGET2        0,0,0,0,0,Select5ID,0
  1081. Select6Gad    GADGET        Select7Gad,4,62,DisplayCols*8+3,10,GADGHCOMP,RELVERIFY,BOOLGADGET
  1082.         GADGET2        0,0,0,0,0,Select6ID,0
  1083. Select7Gad    GADGET        ParentGad,4,72,DisplayCols*8+3,10,GADGHCOMP,RELVERIFY,BOOLGADGET
  1084.         GADGET2        0,0,0,0,0,Select7ID,0
  1085. ParentGad    GADGET        UpGad,112,110,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
  1086.         GADGET2        ButBorder,0,ITxtParent,0,0,ParentID,0
  1087. UpGad        GADGET        DownGad,271,83,18,12,GADGHCOMP!GADGIMAGE,RELVERIFY,BOOLGADGET
  1088.         GADGET2        ArrowsImage,0,0,0,0,UpID,0
  1089. DownGad        GADGET        SlideGad,271,94,18,12,GADGHCOMP,RELVERIFY,BOOLGADGET
  1090.         GADGET2        SlideBorder,0,0,0,0,DownID,0
  1091. SlideGad    GADGET        PathGad,271,13,PWIDTH,PHEIGHT,GADGHCOMP,RELVERIFY,PROPGADGET
  1092.         GADGET2        SlideImage,0,0,0,SlideInfo,SlideID,0
  1093. PathGad        GADGET        FileGad,48,85,SWIDTH,SHEIGHT,GADGHCOMP,RELVERIFY,STRGADGET
  1094.         GADGET2        StrBorder,0,ITxtPath,0,PathInfo,PathID,0
  1095. FileGad        GADGET        PosGad,48,96,SWIDTH,SHEIGHT,GADGHCOMP,RELVERIFY,STRGADGET
  1096.         GADGET2        StrBorder,0,ITxtFile,0,FileInfo,PosID,0
  1097. PosGad        GADGET        NegGad,10,110,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
  1098.         GADGET2        ButBorder,0,ITxtPos,0,0,PosID,0
  1099. NegGad        GADGET        0,215,110,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
  1100.         GADGET2        ButBorder,0,ITxtNeg,0,0,NegID,0
  1101.         EVEN
  1102.  
  1103.     SECTION IMAGEDATA,DATA_C        ;Image-data has to be in CHIP-RAM
  1104. ArrowsData    dc.w        %0000000110000000
  1105.         dc.w        %0000001111000000
  1106.         dc.w        %0000011001100000
  1107.         dc.w        %0000110000110000
  1108.         dc.w        %0001100000011000
  1109.         dc.w        %0011000000001100
  1110.         dc.w        %0110000000000110
  1111.         dc.w        %1100000000000011
  1112.         dc.w        %1100000000000011
  1113.         dc.w        %0110000000000110
  1114.         dc.w        %0011000000001100
  1115.         dc.w        %0011111111111100
  1116.         dc.w        %0110000000000110
  1117.         dc.w        %1100000000000011
  1118.         dc.w        %1100000000000011
  1119.         dc.w        %0110000000000110
  1120.         dc.w        %0011000000001100
  1121.         dc.w        %0001100000011000
  1122.         dc.w        %0000110000110000
  1123.         dc.w        %0000011001100000
  1124.         dc.w        %0000001111000000
  1125.         dc.w        %0000000110000000
  1126.         END
  1127.  
  1128.  
  1129.