** ** $Id: OpenIFF.S,v 22.3 92/06/03 23:44:19 chris Exp $ ** $Revision: 22.3 $ ** ** $Filename: OpenIFF.S $ ** $Author: chris $ ** $Date: 92/06/03 23:44:19 $ ** ** iff.library/IFFL_OpenIFF ** ** COPYRIGHT (C) 1987-1992 BY CHRISTIAN A. WEBER, BRUGGERWEG 2, ** CH-8037 ZUERICH, SWITZERLAND. ALL RIGHTS RESERVED. NO PART ** OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, OR TRANSMITTED ** IN ANY FORM OR BY ANY MEANS, WITHOUT THE PRIOR WRITTEN PER- ** MISSION OF THE AUTHOR. USE AT YOUR OWN RISK. ** DEBUG_DETAIL SET 0 XPK IDNT IFFL_OpenIFF SECTION text,CODE INCLUDE "IFFLib.i" IFD XPK INCLUDE "INCUSR:libraries/xpk.i" ENDC XREF SetError,ClearError XDEF OpenIFFFunc,OldOpenIFFFunc,OldNewOpenIFFFunc ******* iff.library/IFFL_OpenIFF ******************************************** * * NAME * IFFL_OpenIFF -- Open an IFF file for reading or writing * * SYNOPSIS * iff = IFFL_OpenIFF( filename, mode ) * D0 A0 D0 * * IFFL_HANDLE IFFL_OpenIFF( char *, ULONG ) * * FUNCTION * If mode == IFFL_MODE_READ: * This function opens a file on a disk and looks whether it's an IFF * file or not. If it is an IFF file, memory is allocated and the file * is read into memory. * * New for V22: * If xpkmaster.library is installed in your system, IFFL_OpenIFF() * will be able to read and decompress compressed IFF files, if they * use one of the xpk standard compression schemes. * * If mode == IFFL_MODE_WRITE: * Initializes an IFF file handle for writing. You may create chunks * with IFFL_PushChunk() and IFFL_PopChunk(), and you can write data * using the IFFL_WriteChunkBytes() routine. * * INPUTS * filename - Pointer to a null-terminated string * mode - IFFL_MODE_READ: Open file for reading * IFFL_MODE_WRITE: Open file for writing * * RESULT * iff - IFF handle. Making assumptions about the internal structure * of this handle is unwise, and may break in the future. * If this function fails, NULL will be returned, and you may * call IFFL_IFFError() to know the reason of the failure. * * SEE ALSO * IFFL_CloseIFF(), IFFL_PushChunk(), IFFL_PopChunk(), * IFFL_WriteChunkBytes(), IFFL_IFFError() * * BUGS * None known * ***************************************************************************** OpenIFFFunc: movem.l d2-d6/a2/a4-a6,-(SP) moveq.l #MEMF_ANY,d6 ; MemType: egal tst.l d0 ; IFFL_MODE_READ ? beq.b ReadMode ***************************************************************************** * Schreib-Modus movea.l a6,a5 ; A5 : IFFBase move.l a0,d5 ; D5 : Filename *** IFF-Handle allozieren moveq.l #ifffh_SIZEOF,d0 moveq.l #1,d1 swap d1 ; MEMF_CLEAR movea.l iffb_SysBase(a5),a6 JSRLIB AllocMem tst.l d0 bne.b 1$ moveq.l #IFFL_ERROR_NOMEM,d0 bra.b .Error ; Error ---> 1$: movea.l d0,a2 ; A2 : IFF-Handle move.l #IFFFH_MAGIC,ifffh_Magic(a2) *** File zum Schreiben öffnen move.l d5,d1 ; Name move.l #MODE_NEWFILE,d2 movea.l iffb_DOSBase(a5),a6 JSRLIB Open move.l d0,ifffh_File(a2) bne.b 2$ moveq.l #IFFL_ERROR_OPEN,d0 .Error: bsr SetError bra.b .End ; ---> Fertig 2$: *** Header ('FORM\0\0\0\0') schreiben move.l d0,d1 ; File lea IFFHeader(PC),a0 move.l a0,d2 moveq.l #8,d3 JSRLIB Write cmp.l d3,d0 beq.b 3$ moveq.l #IFFL_ERROR_WRITE,d0 bra.b .Error 3$: *** Alles OK, IFF-Handle zurückgeben bsr ClearError move.l a2,d0 ; IFF-Handle .End: bra OpenEnd ; ---> Fertig ******* iff.library/NewOpenIFF ********************************************** * * NAME * NewOpenIFF -- allocate memory for an IFF-file and read it * * SYNOPSIS * ifffile = NewOpenIFF( filename, memattr ) * D0 A0 D0 * * IFFFILE OpenIFF( char * ) * * FUNCTION * THIS FUNCTION IS OBSOLETE. USE IFFL_OpenIFF() INSTEAD. * * INPUTS * filename - Pointer to a null-terminated string * memattr - Memory requirements as used for Exec's AllocMem(), * such as MEMF_CHIP, MEMF_PUBLIC ... * (MEMF_CLEAR is not necessary) * * RESULT * ifffile - 'FileHandle', points to the beginning of the IFF file * ("FORM...."), Zero if unsuccessful. Call IFFError() to get * the reason of the failure. * * SEE ALSO * IFFL_OpenIFF(), IFFL_CloseIFF(), IFFL_IFFError() * * BUGS * None known * ***************************************************************************** OldNewOpenIFFFunc: movem.l d2-d6/a2/a4-a6,-(SP) move.l d0,d6 ; D6 : MemType bra.b ReadMode ******* iff.library/OpenIFF ************************************************* * * NAME * OpenIFF -- allocate memory for an IFF-file and read it * * SYNOPSIS * ifffile = OpenIFF( filename ) * D0 A0 * * IFFFILE OpenIFF( char * ) * * FUNCTION * THIS FUNCTION IS OBSOLETE. USE IFFL_OpenIFF() INSTEAD. * * INPUTS * filename - Pointer to a null-terminated string * * RESULT * ifffile - 'FileHandle', points to the beginning of the IFF file * ("FORM...."), 0 if unsuccessful. Call IFFError() to get the * reason of the failure. * * BUGS * None * * SEE ALSO * IFFL_OpenIFF(), IFFL_CloseIFF(), IFFL_IFFError() * ***************************************************************************** OldOpenIFFFunc: movem.l d2-d6/a2/a4-a6,-(SP) moveq.l #-1,d6 ; Kein MemType angegeben ;; bra.b ReadMode ***************************************************************************** * Lese-Modus ReadMode: movea.l a6,a5 ; A5 : IFFBase lea -12(SP),SP ; Arbeitsspeicher reservieren moveq.l #0,d5 ; Fehlernummer rücksetzen IFD XPK suba.l a4,a4 ; XpkBase ENDC *** File öffnen move.l a0,d1 ; Name move.l #MODE_OLDFILE,d2 ; accessmode movea.l iffb_DOSBase(a5),a6 JSRLIB Open move.l d0,d4 ; D4 := FileHandle bne.b 1$ moveq #IFFL_ERROR_OPEN,d5 bra .Error2 ; ---> 1$: *** Erste 12 Bytes lesen und wieder an den Anfang seeken move.l d4,d1 ; File move.l SP,d2 ; Adr moveq.l #12,d3 ; Len JSRLIB Read ; erste 3 Longwords lesen cmp.l d3,d0 bne .ReadError move.l d4,d1 ; File moveq #0,d2 ; Position moveq #OFFSET_BEGINNING,d3 JSRLIB Seek ; Zurück an den Fileanfang moveq.l #12,d3 ; Remember-Size + 'FORM....' *** testen ob 'FORM' steht im ersten LONG cmpi.l #'FORM',(SP) beq.b .IsIFF IFD XPK *** Es ist kein IFF. Testen ob's ein xpk-gepacktes IFF ist. lea XpkName(PC),a1 movea.l iffb_SysBase(a5),a6 JSRLIB OldOpenLibrary tst.l d0 ; xpk.library geöffnet ? beq.b .NotIFF ; nope ---> movea.l d0,a4 ; A4 : XpkBase PRINTF 10,<"Opened xpk.library"> lea -xf_SIZEOF(SP),SP ; Platz für FIB movea.l SP,a0 ; fib für XpkExamine() clr.l -(SP) ; TAG_DONE move.l d4,-(SP) ; Filehandle pea XPK_InFH ; TagItem movea.l SP,a1 ; Tags movea.l a4,a6 ; XpkBase jsr _LVOXpkExamine(a6) movem.l xf_Head+3*4(SP),d1-d3 ; Die 3 ersten LONGs lea xf_SIZEOF+3*4(SP),SP ; Stack aufräumen movem.l d1-d3,(SP) ; Die 3 ersten LONGs tst.l d0 bne.b .NotIFF ; XPKExamine() Error ---> PRINTF 10,<"Examine successful"> ;; move.l d4,d1 ; File ;; moveq #0,d2 ; Position ;; moveq #OFFSET_BEGINNING,d3 ;; movea.l iffb_DOSBase(a5),a6 ;; JSRLIB Seek ; Zurück an den Fileanfang moveq.l #(XPK_MARGIN+12)/4,d3 ; Remember-Size + 'FORM....' lsl.l #2,d3 ; Spart 2 Bytes :) cmpi.l #'FORM',(SP) ; Ist's jetzt ein IFF ? beq.b .IsIFF ; yup!! ENDC .NotIFF: moveq #IFFL_ERROR_NOTIFF,d5 bra.b .Error1 ; ---> .IsIFF: *** Testen ob Chip-Speicher erwünscht (bei 8SVX-Files) move.l d6,d1 ; Default-Requirements bpl.b 3$ ; sind gültig ---> moveq.l #MEMF_PUBLIC,d1 cmpi.l #'8SVX',8(SP) ; 8SVX-File ? bne.b 3$ ; nein ---> moveq.l #MEMF_CHIP|MEMF_PUBLIC,d1 ; sonst CHIP-Memory! 3$: *** Speicher für File reservieren add.l 4(SP),d3 ; D3 : Länge total move.l d3,d0 movea.l iffb_SysBase(a5),a6 JSRLIB AllocMem ; requirements von D1 movea.l d0,a2 ; A2 : IFFFile-Adresse tst.l d0 bne.b 4$ ; OK ---> moveq #IFFL_ERROR_NOMEM,d5 bra.b .Error1 ; ---> 4$: move.l d3,(a2)+ ; Länge eintragen (Remember) subq.l #4,d3 ; Remember-Size wieder wegzählen *** Je nachdem XPK-gepacktes File laden IFD XPK move.l a4,d0 ; XpkBase beq.b .NoXpkRead ; Kein Xpk-File ---> clr.l -(SP) ; TAG_DONE move.l d3,-(SP) ; Länge pea XPK_OutBufLen move.l a2,-(SP) ; OutBuf pea XPK_OutBuf move.l d4,-(SP) ; File pea XPK_InFH movea.l SP,a0 ; Tags movea.l a4,a6 ; XpkBase jsr _LVOXpkUnpack(a6) lea 7*4(SP),SP tst.l d0 ; OK ? bra.b .ReadCont ; ---> dort weitermachen :) .NoXpkRead: ENDC *** Nicht-XPK-gepacktes IFF-File laden move.l d4,d1 ; File move.l a2,d2 ; Adr movea.l iffb_DOSBase(a5),a6 JSRLIB Read ; D3 war schon Länge cmp.l d3,d0 ; Soviel gelesen ? .ReadCont: beq.b .ReadOK ; Yep ---> OK .ReadError: moveq #IFFL_ERROR_READ,d5 .ReadOK: .Error1: move.l d4,d1 ; File movea.l iffb_DOSBase(a5),a6 JSRLIB Close .Error2: *** Cleanup & quit IFD XPK move.l a4,d0 ; Xpk library offen ? beq.b .XpkNotOpen ; noe ---> movea.l a4,a1 ; XpkBase movea.l iffb_SysBase(a5),a6 JSRLIB CloseLibrary .XpkNotOpen: ENDC move.l d5,d0 ; Error ? beq.b 6$ ; nein ---> bsr SetError ; Löscht auch D0 bra.b .Ende 6$: bsr ClearError move.l a2,d0 ; Adresse als Return-Code .Ende: lea 12(SP),SP ; Lokalen Speicher freigeben OpenEnd: movem.l (SP)+,d2-d6/a2/a4-a6 rts IFFHeader: dc.b "FORM",0,0,0,0 IFD XPK XpkName: dc.b "xpkmaster.library",0 ENDC END