home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d358
/
scaniff.lha
/
ScanIFF
/
ScanIFF.asm
< prev
next >
Wrap
Assembly Source File
|
1990-06-12
|
10KB
|
254 lines
;
; IFFscan - IFF file scanner - Jim Butterfield. January 12/90.
; Exec library calls
_LVOOpenLibrary EQU -$228
_LVOCloseLibrary EQU -$19E
_LVOSetSignal EQU -$132
; DOS library calls
_LVOSeek EQU -$42
_LVOOutput EQU -$3C
_LVOWrite EQU -$30
_LVORead EQU -$2A
_LVOClose EQU -$24
_LVOOpen EQU -$1E
;
BufSize EQU 10
;-- Initial setup:
Startup move.l a0,a4 ; Remember ptr to argument line. cf MOVEA
move.b #0,-$1(a0,d0.W) ; binary zero at end
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,a6 ; Remember DosBase ptr.
tst.l d0 ; Check for error (d0=0 means
beq.s StartupQuit ; dos not opened)
bsr.s DOSinit
move.l a6,a1 ;-Specify Dos library in a1;
move.l $4,a6 ; then using Exec library,
jsr _LVOCloseLibrary(a6) ; close Dos library.
StartupQuit rts ; End of Program
;
;-- Get CLI outhandle:
DOSinit jsr _LVOOutput(a6) ; get CLI outhandle,
move.l d0,d7 ; & then remember it.
;
; -- Skin leading spaces:
skipspc move.l a4,d1 ; filename start
cmp.b #$20,(a4)+ ; space?
beq.s skipspc
move.l #1005,d2 ; MODE_OLDFILE (for reading)
jsr _LVOOpen(a6)
move.l d0,d6 ; file inhandle
beq.s FileNot ; no good, quit
link a5,#-$1C
bsr.s ScanFile ; the main job
unlk a5
move.l d6,d1 ; use the handle..
jsr _LVOClose(a6) ; to close the file
DOSquit rts ; exit program.
FileNot move.l d7,d1 ; handle
lea FNF.MSG(pc),a0
move.l a0,d2
moveq #FNFlen,d3
jmp _LVOWrite(a6)
;
; DOS is open and we have our in/out handles.
; Global stack definitions
FileP EQU -$4
DosBase EQU -$8
Type EQU -$C
Abort EQU -$10
String EQU -$1C ; 12 byte work area
; Look for 'FORM' or other drawer types
ScanFile: move.l a6,DosBase(a5)
moveq #1,d4 ; start at Level 1
moveq #0,d0
move.l d0,Abort(a5) ; Ctrl-C trap
move.l d0,FileP(a5) ; file position=start
bsr ReadType
tst.l d5 ; is it a drawer?
bne.s GotDrawer ; yes, exit
; First four characters are not valid type. Give up.
move.l d7,d1 ;output handle
lea NotIFF.MSG(pc),a0 ;message to
move.l a0,d2 ; buffer
moveq #NotIFFlen,d3 ;length
jsr _LVOWrite(a6)
bra.s SFexit
;
GotDrawer bsr.s DoBlock ; recursive analysis job
tst.l Abort(a5)
beq.s SFexit
move.l d7,d1 ;output handle
lea CtrlCMess(pc),a0 ;message to
move.l a0,d2 ; buffer
moveq #3,d3 ;length
jsr _LVOWrite(a6)
SFexit rts ; job complete
; D4=Recursion level D5=Drawer Flag
; D6=Inhandle (file) D7=Outhandle (screen)
; A4=Local Stack Frame
; A5=Global Stack Frame A6=DosLibrary
;
BSize EQU -4
CSize EQU -8
FileF EQU -12
XType EQU -$10
DoBlock link a4,#-$10 ; local variables
; read Size of this block
move.l d6,d1 ; input file handle
lea BSize(a4),a2 ; input buff (stack) address
move.l a2,d2 ; .. to D2 for read
moveq #4,d3 ; read 4 characters
add.l d3,FileP(a5) ; record file position
jsr _LVORead(a6) ; read 'em
move.l (a2),d0 ; take raw size
addq.l #1,d0 ; round up to even value
and.b #$fe,d0
move.l d0,CSize(a4) ; store rounded value
move.l FileP(a5),d1 ; start point this chunk
add.l d1,d0 ; log end point this chunk
move.l d0,FileF(a4)
tst.w d5 ; a drawer?
beq.s NotDraw1
; read subType of the drawer
move.l d6,d1 ; input file handle
lea XType(a4),a0 ; input buff (stack) address
move.l a0,d2 ; .. to D2 for read
moveq #4,d3 ; read 4 characters
add.l d3,FileP(a5) ; record file position
jsr _LVORead(a6) ; read 'em
; print <indent> drawer Type <space> subType <newline>
bsr ShowType
move.l d7,d1 ;output handle
lea Spaces(PC),a0 ;message to
move.l a0,d2 ; buffer
moveq #1,d3 ;length=1 space
jsr _LVOWrite(a6)
move.l d7,d1 ;output handle
lea XType(a4),a0 ;message to
move.l a0,d2 ; buffer
moveq #4,d3 ;length
jsr _LVOWrite(a6)
move.l d7,d1 ;output handle
lea NewLine(PC),a0 ;message to
move.l a0,d2 ; buffer
moveq #1,d3 ;length=1 char
jsr _LVOWrite(a6)
; Scan through size of drawer. First, Check CTL-C
NotDraw1 move.l 4,a6 ; set Exec libr
moveq #0,d0
move.l #$1000,d1
jsr _LVOSetSignal(a6) ;test CTRL-C
move.l DosBase(a5),a6 ;restore DOS libr
and.l #$1000,d0
or.l d0,Abort(a5)
tst.l Abort(a5)
bne.s EndSect
move.l FileP(a5),d0
cmp.l FileF(a4),d0
bcc.s EndSect
tst.w d5 ; a drawer?
beq.s NotDraw2
; Analyze drawer for sub elements - get Type!
bsr.s ReadType
; recurse .. look inside outer drawer
addq #1,d4
bsr DoBlock
subq #1,d4
moveq #1,d5 ; restore old drawer type!
bra.s NotDraw1
; found a non-drawer .. report it and position
; print <indent> Type <newline>
NotDraw2 bsr.s ShowType
move.l d7,d1 ;output handle
lea NewLine(PC),a0 ;message to
move.l a0,d2 ; buffer
moveq #1,d3 ;length=1 char
jsr _LVOWrite(a6)
; now position to FileP(a5)+CSize(a4)
move.l d6,d1 ;input handle
move.l FileF(a4),d2 ;new position
move.l d2,FileP(a5) ; synchronize
moveq #-1,d3 ;offset from start.file
jsr _LVOSeek(a6)
bra.s NotDraw1
EndSect unlk a4
rts
; read Type and identify if drawer
ReadType move.l d6,d1 ; input file handle
lea Type(a5),a2 ; input buff (stack) address
move.l a2,d2 ; .. to D2 for read
moveq #4,d3 ; read 4 characters
add.l d3,FileP(a5) ; record file position
jsr _LVORead(a6) ; read 'em
; Look for 'FORM' or other drawer types
moveq #1,d5 ; drawer?
moveq #0,d0 ; zero table count
lea Ttab,a0 ; start of table
move.l (a2),d1
RTloop cmp.l 0(a0,d0.w),d1 ; is it drawer?
beq.s DrawerGot ; yes, exit
addq.w #4,d0 ; try next type
cmp.w #Ttlen,d0 ; any more?
bne.s RTloop ; yes, try it
moveq #0,d5 ; not a drawer
DrawerGot rts
; print <indent> Type..
ShowType move.l d7,d1 ;output handle
lea Spaces(PC),a0 ;message to
move.l a0,d2 ; buffer
move.l d4,d3 ; (Level) number of spaces
jsr _LVOWrite(a6)
move.l d7,d1 ;output handle
lea Type(a5),a0 ;message to
move.l a0,d2 ; buffer
moveq #4,d3 ;length
jsr _LVOWrite(a6)
move.l BSize(a4),d0 ; size of block
; MakeAscii
lea String(a5),a1 ; Address of string
moveq #11,d2 ; size of string
DigLoop swap d0 ; hi/lo swap
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.w)
tst.l d0
dbeq d2,DigLoop
lea 0(a1,d2.w),a0
move.b #$20,-(a0)
move.l d7,d1 ; outhandle
moveq #13,d3 ; max string size
sub.b d2,d3 ; less unused
move.l a0,d2 ; num string address
; d2 string position, d3 length
jsr _LVOWrite(a6)
rts
Ttab dc.b 'FORM'
dc.b 'CAT '
dc.b 'LIST'
dc.b 'PROP'
Ttlen EQU *-Ttab
FNF.MSG dc.b 'File not found.',$a
FNFlen EQU *-FNF.MSG
NotIFF.MSG dc.b 'Not an IFF file!',$a
NotIFFlen EQU *-NotIFF.MSG
Spaces dc.b ' '
dosname dc.b 'dos.library',0
CtrlCMess dc.b '^C'
NewLine dc.b $0a
end