; ViewDir 2.0/ size directory - Jim Butterfield. April 5/90. ; Exec library calls _LVOAllocMem EQU -$C6 _LVOFreeMem EQU -$D2 _LVOSetSignal EQU -$132 _LVOCloseLibrary EQU -$19E _LVOOpenLibrary EQU -$228 ; DOS library calls _LVOOpen EQU -$1E _LVOClose EQU -$24 _LVORead EQU -$2A _LVOWrite EQU -$30 _LVOOutput EQU -$3C _LVOLock EQU -$54 _LVOUnLock EQU -$5A _LVOExamine EQU -$66 _LVOExNext EQU -$6C _LVOCurrentDir EQU -$7E _LVOIoErr EQU -$84 ; ACCESS_READ equ -2 MODE_OLDFILE equ 1005 INFOSIZE equ 260 DATASIZE equ 100 ; FileInfoBlock items fib_FileName equ 8 fib_EntryType equ 120 fib_Size equ 124 fib_NumBlocks equ 128 ; IO Error Type NO_MORE_ENTRIES equ 232 ; ;-- Initial setup: ; offsets from A5 tSize equ -4 tCount equ -8 dosBase equ -12 argv equ -16 OutHandle equ -20 DataBlk equ -24 Blocker equ -25 ;byte KillInf equ -26 ;byte Look equ -27 ;byte FileErr equ -28 ;byte Level equ -30 ;word String equ -42 ;12 bytes link a5,#-44 ; common work area moveq #0,d1 move.l d1,FileErr(a5) ; four bytes trsp move.b d1,-1(a0,d0) ; c style string move.b -2(a0,d0),d1 cmp.b #$20,d1 bne.s lastCh subq.w #1,d0 bra.s trsp lastCh sub.b #$22,d1 ; kill trailing quote bne.s spdump move.b d1,-2(a0,d0) spdump move.b (a0)+,d0 cmp.b #$20,d0 beq.s spdump cmp.b #$22,d0 ; leading quote beq.s skipq cmp.b #$2d,d0 ;dash beq.s fgdump sub.b #'?',d0 beq.s hook bra.s spbak fgdump move.b (a0)+,d0 beq.s hook and.b #$5f,d0 cmp.b #$49,d0 ;-i bne.s NotI move.b d0,KillInf(a5) bra.s fgdump NotI cmp.b #$54,d0 bne.s NotT move.b d0,Look(a5) bra.s fgdump NotT cmp.b #$42,d0 ;-b bne.s spdump move.b d0,Blocker(a5) bra.s fgdump skipq addq.l #1,a0 spbak move.b -(a0),d0 move.l a0,argv(a5) ;** Level=0; tCount=0; hook moveq #0,d1 move.l d1,Level(a5) move.l d1,tCount(a5) ; set up dos, output, here movem.l a0/a1/d0/d1,-(A7) move.b #1,FileErr(a5) lea dosname(pc),a1 ; Name 'dos.library'. clr.l d0 ; Any version (0) move.l $4,a6 ; Using Exec library jsr _LVOOpenLibrary(a6) ; Open Dos library. move.l d0,dosBase(a5) ; Remember DosBase ptr. beq StartupQuit ; dos not opened move.l d0,a6 ; set Dos library jsr _LVOOutput(a6) ; get CLI outhandle, move.l d0,OutHandle(a5) ; & then remember it. movem.l (a7)+,a0/a1/d0/d1 tst.l d0 ; no file name? beq.s Prompt ;** GetDir(argv[1]); move.l $4,a6 ; this calls for Exec moveq #0,d1 ; any type of memory moveq #DATASIZE,d0 ; size of block needed jsr _LVOAllocMem(a6) ; go get it move.l dosBase(a5),a6 ; restore Dos Library move.l d0,DataBlk(a5) ; save the block address beq.s DosQuit ; quit if no memory move.l argv(a5),a0 ; file name bsr.s GetDir move.l $4,a6 ; set Exec library move.l DataBlk(a5),a1 ; memory block address moveq #DATASIZE,d0 ; size of block jsr _LVOFreeMem(a6) ; release this memory DosQuit move.l dosBase(a5),a6 ; set Dos Library ;** switch (FileErr) subq.b #1,FileErr(a5) bne.s Ncase1 ;** case 1: ;** printf("Out of Memory\n"); move.l OutHandle(a5),d1 ;file handle lea NoMemMsg(pc),a1 move.l a1,d2 ;outbuffer moveq #NoMemLen,d3 ;length jsr _LVOWrite(A6) ;** case 2: ;** printf("Can't find file.\n"); Ncase1 subq.b #1,FileErr(a5) bne.s Ncase2 move.l OutHandle(a5),d1 ;file handle lea NoFileMsg(pc),a1 move.l a1,d2 ;outbuffer moveq #NoFileLen,d3 ;length jsr _LVOWrite(A6) ;** case 3: ;** printf("^C\n"); Ncase2 subq.b #1,FileErr(a5) bne.s endSwitch move.l OutHandle(a5),d1 ;file handle lea CtrlCMsg(pc),a1 move.l a1,d2 moveq #CtrlCLen,d3 jsr _LVOWrite(A6) endSwitch bra.s LastGasp ;** } ;** } ;** else printf("FORMAT: ViewDir \n"); Prompt move.l OutHandle(a5),d1 lea PromptMsg(pc),a1 move.l a1,d2 moveq #PromptLen,d3 jsr _LVOWrite(A6) ;** } LastGasp: move.l dosBase(a5),a1 ; DosBase to a1; move.l $4,a6 ; then using Exec library, jsr _LVOCloseLibrary(a6) ; close Dos library. StartupQuit unlk a5 rts ; End of Program ;**void GetDir(char * Name) ;** { ;** unsigned long Size, Count, newLock, oldLock; ;** struct FileInfoBlock *fibb; ;** char *NameSave; ; offsets from A4 Size equ -4 Count equ -8 newLock equ -12 oldLock equ -16 fibb equ -20 NameSave equ -24 ;drawer (calling) name xName equ -28 ;name to be printed fType equ -32 ;dir or file GetDir link A4,#-32 move.l a0,xName(a4) move.l a0,NameSave(a4) ;** Size = 0; ;** Count =0; ;** Count = 0; moveq #0,d0 move.l d0,Size(a4) move.l d0,Count(a4) ;** FileErr =1; /* signal Alloc error */ move.b #1,FileErr(a5) ;** if ((fibb = AllocMem(INFOSIZE,0)) != 0) move.l $4,a6 ; this calls for Exec moveq #0,d1 ; any type of memory move.l #INFOSIZE,d0 ; size of block needed jsr _LVOAllocMem(a6) ; go get it move.l dosBase(a5),a6 ; restore Dos Library move.l d0,fibb(a4) ; save the block address beq GDExit ; quit if no memory ;** { ;** FileErr =2; /* signal file unreadable */ move.b #2,FileErr(a5) ;** if ((newLock = Lock(Name,ACCESS_READ)) != 0) move.l xName(a4),d1 moveq #ACCESS_READ,D2 ; get a read lock jsr _LVOLock(a6) move.l d0,newLock(a4) ; store the lock pointer beq DropMem ; couldn't get lock ;** { if ((Examine(newLock,fibb)) != 0) move.l d0,d1 ; lock move.l fibb(a4),d2 ; file info block address jsr _LVOExamine(a6) ; go for the data ; Assume Examine never fails. Go for the data. ;** { ;** FileErr =0; /* got file, normal error sequence */ move.b #0,FileErr(a5) ;** { ;** if (fibb->fib_EntryType < 0) move.l fibb(a4),a3 move.l fib_EntryType(a3),d0 move.l d0,fType(a4) bpl.s TypeDir2 ;** { ;** Size = fibb->fib_Size; ;** Blox = fibb->fib_NumBlocks; ;** Count = 1; ;** } /* file */ move.l NameSave(a4),a0 jsr FilBit bra NextItem ;** else TypeDir2: ;** { ;** oldLock = CurrentDir(newLock); move.l newLock(a4),d1 jsr _LVOCurrentDir(a6) move.l d0,oldLock(a4) ;** Level += 1; addq.w #1,Level(a5) DirLoop: ;** { ;** if ((ExNext(newLock,fibb)) == 0) move.l newLock(a4),d1 ; lock move.l fibb(a4),d2 ; file info block address jsr _LVOExNext(a6) ; go for the data tst.l d0 beq.s EndDir tst.b FileErr(a5) bne.s EndDir ;** if (fibb->fib_EntryType < 0) move.l fib_EntryType(a3),d0 bpl.s TypeDir3 lea fib_FileName(a3),a0 jsr FilBit bra.s Join3 ;** GetDir(fibb->fib_FileName); ;** Size += tSize; ;** Count += tCount; TypeDir3 lea fib_FileName(a3),a0 bsr GetDir Join3 move.l tSize(a5),d0 add.l d0,Size(a4) move.l tCount(a5),d0 add.l d0,Count(a4) ; collect stats? move.l fibb(a4),a3 bra.s DirLoop ;** Level -= 1; EndDir subq.w #1,Level(a5) ;** newLock = CurrentDir(oldLock); move.l oldLock(a4),d1 jsr _LVOCurrentDir(a6) move.l d0,newLock(a4) ;** } /* dir */ Rejoin2: ;** ??Count += Count; tst.b FileErr(a5) bne.s EndSplit1 move.l Size(a4),d7 ;** if (Level <1 0) move.w Level(a5),d0 beq.s Dir3 ; assuming a directory subq.w #1,d0 bne.s NextItem ;** { ;** else ;** printf(" DIR %3d",Count); Dir3 move.l OutHandle(a5),d1 lea DirMsg(pc),a1 move.l a1,d2 moveq #DirLen,d3 jsr _LVOWrite(A6) move.l Count(a4),d0 bsr MakeAscii move.l OutHandle(a5),d1 lea String+5(A5),a1 move.l a1,d2 moveq #5,d3 jsr _LVOWrite(A6) ;** printf(" %7d %4d %s\n",Size,Blox,NameSave); move.l NameSave(a4),a2 bsr PrintStuff ;** } ; look for file join here NextItem: move.l a6,d7 moveq #0,d0 move.l #$1000,d1 move.l $4,a6 jsr _LVOSetSignal(a6) move.l d7,a6 and.l #$1000,d0 beq.s EndSplit1 move.b #3,FileErr(a5) EndSplit1: ;** tSize = Size; ;** tCount = Count; move.l Size(a4),tSize(a5) move.l Count(a4),tCount(a5) ;** } /* Examine OK */ ;** UnLock(newLock); DropLock move.l dosBase(a5),a6 ; set Dos Library move.l newLock(a4),d1 ; take off the lock jsr _LVOUnLock(a6) ;** } /* Lock OK */ ;** FreeMem(fibb,INFOSIZE); DropMem: move.l $4,a6 ; set Exec library move.l fibb(a4),a1 ; memory block address move.l #INFOSIZE,d0 ; size of block jsr _LVOFreeMem(a6) ; release this memory move.l dosBase(a5),a6 ; set Dos Library ;** } /* Alloc OK */ GDExit unlk A4 FilEnd rts ;** } FilBit move.l a0,xName(a4) move.l fib_Size(a3),d7 tst.b Blocker(a5) beq.s noblox2 move.l fib_NumBlocks(a3),d7 noblox2 move.l d7,tSize(a5) moveq #1,d0 move.l d0,tCount(a5) ;** if (Level <1 0) move.w Level(a5),d0 beq.s pf ; assuming a file subq.w #1,d0 bne.s FilEnd ; Check .info status pf tst.b KillInf(a5) beq.s PeekFile move.l xName(a4),a2 TryCharx move.b (a2)+,d0 bne.s TryCharx lea -6(a2),a2 lea InfoLine(pc),a1 InfLp cmp.b (a1)+,(a2)+ beq.s InfLp tst.b -1(a2) beq.s FilEnd ; We're gonna print the file. Empty? Will we look at it? PeekFile lea EmptyMsg(pc),a2 tst.l d7 beq FlEmp tst.b Look(a5) bne DoNotLook ; Open the file in order to check details move.l xName(a4),d1 ; filename pointer move.l #MODE_OLDFILE,d2 ; get a read lock jsr _LVOOpen(a6) move.l d0,d6 ; store the file handle beq FlEmp ; couldn't get file ; Read DATASIZE bytes of the file, then close it move.l d6,d1 ;infile handle move.l DataBlk(a5),d2 ; input buffer address moveq #DATASIZE,d3 ; how many bytes jsr _LVORead(a6) ; so read it move.l d0,d5 ; actual bytes read move.l d6,d1 ; inhandle jsr _LVOClose(a6) ; close the file lea TextMsg(pc),a2 ; check for text characters only move.l DataBlk(a5),a0 moveq #0,d3 TxLp move.b 0(a0,d3),d0 cmp.b #9,d0 beq.s TryMore cmp.b #10,d0 beq.s TryMore cmp.b #$20,d0 blt.s NoText TryMore addq.w #1,d3 cmp.w d3,d5 bne.s TxLp bra FlEmp ; Not Text - try longword start NoText move.l (a0),d0 lea LdblMsg(pc),a2 cmp.l #$3F3,d0 beq.s FlEmp ; special IFF sequence cmp.l #'FORM',d0 bne.s WordStart lea String(a5),a2 move.l #'IFF:',(a2) move.l 8(a0),4(a2) bra.s FlEmp ; look for magic word start WordStart move.w (a0),d0 lea WBOMsg(pc),a2 cmp.w #$E310,d0 beq.s FlEmp lea FLisMsg(pc),a2 cmp.w #$f00,d0 beq.s FlEmp lea WBWMsg(pc),a2 cmp.w #$f34c,d0 beq.s FlEmp ; special Basic sequence and.w #$FE7F,d0 lea BasMsg(pc),a2 cmp.w #$F400,d0 beq.s FlEmp ; special longword-text test moveq #3,d1 lngtst move.b 0(a0,d1.w),d0 cmp.b #$30,d0 blt.s DoNotLook cmp.b #$7f,d0 bgt.s DoNotLook dbf d1,lngtst lea String(a5),a2 move.l #'....',(a2) move.l (a0),4(a2) bra.s FlEmp DoNotLook lea FileMsg(pc),a2 FlEmp move.l a2,d2 move.l OutHandle(a5),d1 moveq #FileLen,d3 jsr _LVOWrite(a6) move.l xName(a4),a2 ; PeekFile drops into PrintStuff ; ...or PS may be called directly... PrintStuff: move.l d7,d0 bsr.s MakeAscii move.l OutHandle(a5),d1 lea String(a5),a1 moveq #11,d3 tst.b Blocker(a5) beq.s noblox3 lea String+4(a5),a1 moveq #7,d3 noblox3 move.l a1,d2 jsr _LVOWrite(a6) move.w Level(a5),d0 bne.s Flush move.l OutHandle(a5),d1 lea SpaceMsg(pc),a1 move.l a1,d2 moveq #SpaceLen,d3 jsr _LVOWrite(A6) Flush move.l OutHandle(a5),d1 move.l a2,d2 moveq #0,d3 TryChara move.b 0(a2,d3),d0 beq.s FoundEnd addq.b #1,d3 bra.s TryChara FoundEnd jsr _LVOWrite(A6) move.l OutHandle(a5),d1 lea MsgNewLine(pc),a1 move.l a1,d2 moveq #NewLineLen,d3 jsr _LVOWrite(A6) PrEnd rts MakeAscii: moveq #$20,d1 lea String(a5),a1 moveq #11,d2 SpacedOut move.b d1,0(a1,d2) dbf d2,SpacedOut moveq #9,d2 DigLoop swap d0 moveq #0,d1 move.w d0,d1 beq.s Skipper divu #10,d1 Skipper move.w d1,d0 swap d0 move.w d0,d1 divu #10,d1 move.w d1,d0 swap d1 or.b #$30,d1 move.b d1,0(a1,d2) tst.l d0 dbeq d2,DigLoop rts InfoLine dc.b '.info.' MsgNewLine dc.b $0a NewLineLen equ *-MsgNewLine SpaceMsg dc.b $20 SpaceLen equ *-SpaceMsg DirMsg dc.b 'DIR' DirLen equ *-DirMsg PromptMsg dc.b 'ViewDir (by Jim Butterfield) V2.0',$0a dc.b 'FORMAT: ViewDir [-b -i -t] directory',$0a PromptLen equ *-PromptMsg TextMsg dc.b 'TextFile' LdblMsg dc.b 'Loadable' WBOMsg dc.b 'WBObject' WBWMsg dc.b 'WBWindow' BasMsg dc.b 'AmiBasic' FLisMsg dc.b 'FontList' FileMsg dc.b 'FILE ' FileLen equ *-FileMsg EmptyMsg dc.b 'Empty ',$0a EmptyLen equ *-EmptyMsg NoMemMsg dc.b 'Out of Memory',$0a NoMemLen equ *-NoMemMsg NoFileMsg dc.b 'Can t find file.',$0a NoFileLen equ *-NoFileMsg CtrlCMsg dc.b '^C',$0a CtrlCLen equ *-CtrlCMsg dosname dc.b 'dos.library',0 end