;***********************************************
; Blitter-"Benchmark"
; written by Peter Simons
; (C) by MAXON-Computer GmbH
;***********************************************

;**************** Makros, Labels ***************

;-------------------------- Switches -----------
                BASEREG A3,DATAS

;-------------------------- Exec ---------------
_LVOAllocMem            equ     -198
_LVOFreeMem             equ     -210
_LVOFindName            equ     -276
_LVOOldOpenLibrary      equ     -408
_LVOCloseLibrary        equ     -414

MEMF_PUBLIC     equ     1<<0
MEMF_CLEAR      equ     1<<16

;-------------------------- DOS ----------------
_LVOOpen        equ     -30
_LVOClose       equ     -36
_LVORead        equ     -42
_LVOWrite       equ     -48
_LVOOutput      equ     -60
_LVOLock        equ     -84
_LVOUnLock      equ     -90
_LVOExamine     equ     -102

MODE_OLDFILE    equ     1005
MODE_NEWFILE    equ     1006
ACCESS_READ     equ     -2

fib_SIZEOF      equ     260
fib_Size        equ     124

;-------------------------- Macros -------------
CALLSYS         MACRO
                jsr     _LVO\1(a6)
                ENDM

CALLEXEC        MACRO
                move.l  4.W,a6
                jsr     _LVO\1(a6)
                ENDM

CALLDOS         MACRO
                move.l  _DOSBase(PC),a6
                jsr     _LVO\1(a6)
                ENDM

amove           MACRO
                lea     \1(PC),a0
                move.l  a0,\2
                ENDM


;******************* Programm ******************

                        SECTION "CODE",CODE

START           lea     DATAS(PC),a3

                move.l  a0,_FileName
                move.l  d0,d5

                lea     dosname(PC),a1
                CALLEXEC OldOpenLibrary
                move.l  d0,_DOSBase
                beq.w   Ende

                CALLDOS Output
                move.l  d0,_OutputHandle

                move.l  d0,d1
                amove   StartUp_MSG,d2
                move.l  #StartUp_MSG_len,d3
                CALLSYS Write

                subq.l  #1,d5
                beq.w   NoParamError

                move.l  _FileName(PC),a5
                add.l   d5,a5
                clr.b   (a5)

                bsr.w   FileLength
                move.l  d0,IFFLength
                beq.w   NoFileError

                move.l  #MEMF_PUBLIC!MEMF_CLEAR,d1
                CALLEXEC AllocMem
                move.l  d0,_Buffer
                beq.w   NoMemoryError

                move.l  _FileName(PC),d1
                move.l  #MODE_OLDFILE,d2
                CALLDOS Open
                move.l  d0,_SourceHandle

                move.b  #'.',(a5)+  ; ".RAW" an
                move.b  #'R',(a5)+  ; den Namen
                move.b  #'A',(a5)+  ; anhängen
                move.b  #'W',(a5)+
                move.b  #0,(a5)+

                move.l  _FileName(PC),d1
                move.l  #MODE_NEWFILE,d2
                CALLSYS Open
                move.l  d0,_DestinationHandle
                beq.w   NoDestFileError

                bsr.s   LoadIFF ; Lädt ein IFF-
                tst.l   d0      ; bild in einen
                beq.w   NoILBMError ;Puffer

                move.l  _DestinationHandle(PC),d1
                move.l  _PicBuffer(PC),d2
                move.l  PicLength(PC),d3
                CALLDOS Write

;--------------- Exit gracefully ---------------

FreePicBuffer   move.l  _PicBuffer(PC),a1
                move.l  PicLength(PC),d0
                CALLEXEC FreeMem

CloseDestFile   move.l  _DestinationHandle(PC),d1
                CALLDOS Close

CloseSourceFile move.l  _SourceHandle(PC),d1
                CALLDOS Close

FreeIFFBuffer   move.l  _Buffer(PC),a1
                move.l  IFFLength(PC),d0
                CALLEXEC FreeMem

CloseDosLib     move.l  _DOSBase(PC),a1
                CALLEXEC CloseLibrary

Ende            rts

;************** Unterprogramme *****************

LoadIFF:
                move.l  _SourceHandle(PC),d1
                move.l  _Buffer(PC),d2
                move.l  IFFLength(PC),d3
                CALLDOS Read

                move.l  _Buffer(PC),a5
                cmp.l   #'ILBM',8(a5)
                bne.w   .Error

                move.l  #'BMHD',d0
                bsr.w   FindChunk

                move.w  4(a5),d0        ; Width
                move.w  6(a5),d1        ; Height
                move.b  12(a5),d2       ; Planes
                and.l   #$0000000F,d2
                lsr.w   #3,d0
                mulu    d1,d0
                mulu    d2,d0
                move.l  d0,PicLength
                move.l  #MEMF_PUBLIC!MEMF_CLEAR,d1
                CALLEXEC AllocMem
                move.l  d0,_PicBuffer
                bne.s   .NoError

                addq.w  #4,a7      ; BSR löschen
                beq.w   NoPicBufferError

.NoError        tst.b   14(a5)
                beq.s   .NoCompression

;------------ Lade-Routine Kompaktiert ---------

                move.l  _Buffer(PC),a5
                move.l  #'BODY',d0
                bsr.s   FindChunk

                move.l  _PicBuffer(PC),a1

                move.l  (a5)+,d1
                move.l  a5,a4
                add.l   d1,a4

.c_loop         moveq   #0,d0
                move.b  (a5)+,d0
                bmi.s   .unpack
.c_loop2        move.b  (a5)+,(a1)+
                dbra    d0,.c_loop2
                bra.s   .next

.unpack         neg.b   d0
.c_loop3        move.b  (a5),(a1)+
                dbra    d0,.c_loop3
                addq.w  #1,a5

.next           cmp.l   a5,a4
                bne.s   .c_loop
                moveq   #-1,d0   ; kein Fehler
                rts              ; aufgetreten

;---------- Lade-Routine Unkompaktiert ---------

.NoCompression  move.l  _Buffer(PC),a5
                move.l  #'BODY',d0
                bsr.s   FindChunk

                move.l  _PicBuffer(PC),a1
                move.l  (a5)+,d0
                subq.l  #1,d0
.nc_loop3       move.b  (a5)+,(a1)+
                dbra    d0,.nc_loop3
                rts

.Error          moveq   #0,d0
                rts

FindChunk:          ; der Chunk muß in D0 stehen
                swap    d0
.loop           cmp.w   (a5)+,d0
                bne.s   .loop
                swap    d0
                cmp.w   (a5),d0
                bne.s   FindChunk
                addq.w  #2,a5
                rts

FileLength:         ; Diese Unterroutine gibt in
                    ; D0 die Länge des Files zu-
                    ; rück, auf das _Filename
                    ; zeigt

                move.l  _FileName(PC),d1
                moveq   #ACCESS_READ,d2
                CALLDOS Lock
                move.l  d0,d5
                beq.s   .Error

                move.l  d0,d1
                amove   FileInfo,d2
                CALLSYS Examine
                tst.l   d0
                beq.s   .Error

                move.l  d5,d1
                CALLSYS UnLock

                lea     FileInfo(PC),a0
                move.l  fib_Size(a0),d0
                rts

.Error          moveq   #0,d0
                rts

;-------------------- Fehler -------------------

NoFileError     move.l  _OutputHandle(PC),d1
                amove   NoFile_MSG,d2
                move.l  #NoFile_MSG_len,d3
                CALLDOS Write
                bra.w   CloseDosLib

NoParamError:
                move.l  _OutputHandle(PC),d1
                amove   NoParamError_MSG,d2
                move.l  #NoParamError_MSG_len,d3
                CALLDOS Write
                bra.w   CloseDosLib

NoMemoryError   move.l  _OutputHandle(PC),d1
                amove   NoMemory_MSG,d2
                move.l  #NoMemory_MSG_len,d3
                CALLDOS Write
                bra.w   CloseDosLib

NoDestFileError move.l  _OutputHandle(PC),d1
                amove   NoDestFile_MSG,d2
                move.l  #NoDestFile_MSG_len,d3
                CALLDOS Write
                bra.w   CloseSourceFile

NoILBMError     move.l  _OutputHandle(PC),d1
                amove   NoILBM_MSG,d2
                move.l  #NoILBM_MSG_len,d3
                CALLDOS Write
                bra.w   CloseDestFile

NoPicBufferError:
                move.l  _OutputHandle(PC),d1
                amove   NoMemory_MSG,d2
                move.l  #NoMemory_MSG_len,d3
                CALLDOS Write
                bra.w   CloseDestFile

;****************** Daten **********************

DATAS:

_DOSBase        ds.l    1
_FileName       ds.l    1
_SourceHandle   ds.l    1
_DestinationHandle ds.l 1
_OutputHandle   ds.l    1
_Buffer         ds.l    1
_PicBuffer      ds.l    1

IFFLength       ds.l    1
PicLength       ds.l    1

                CNOP    0,4
FileInfo        ds.b    fib_SIZEOF

dosname         dc.b    "dos.library",0
                EVEN

StartUp_MSG     dc.b 10,$9b,"1;33",$6d,"Picture"
                dc.b "Splitter V1.0",$9b,$6d,10
                dc.b "all coding was done by"
                dc.b " Peter Simons",10
                dc.b "Releasing date: 26/SEP/91"
                dc.b 10,10
StartUp_MSG_len equ     (*-StartUp_MSG)

NoFile_MSG      dc.b "FATAL ERROR: Can't find "
                dc.b "sourcefile ...",10,10
NoFile_MSG_len  equ     (*-NoFile_MSG)

NoParamError_MSG dc.b "Usage: PSplit "
                 dc.b "<SourceFile>",10,10
NoParamError_MSG_len equ (*-NoParamError_MSG)

NoMemory_MSG    dc.b "FATAL ERROR: Can't "
                dc.b "allocte Working Buffer "
                dc.b "...",10,10
NoMemory_MSG_len equ (*-NoMemory_MSG)

NoDestFile_MSG  dc.b "FATAL ERROR: Can't open "
                dc.b "destinationfile ...",10,10
NoDestFile_MSG_len equ (*-NoDestFile_MSG)

NoILBM_MSG      dc.b "FATAL ERROR: Sourcefile "
                dc.b "is no IFF-ILBM-file ..."
                dc.b 10,10
NoILBM_MSG_len  equ     (*-NoILBM_MSG)

                END
