; Convert DEEP-IFF nach PPM
; Gerd Wieczorek, 16.12.95


buflen          equ     1024

dosbase         equ     0               ; long
rdarg           equ     4+dosbase
arg_file        equ     4+rdarg
breite          equ     4+arg_file
hoehe           equ     4+breite
buffer1         equ     4+hoehe
buffer2         equ     buflen+buffer1
gesamt          equ     buflen+buffer2

        nolist
        machine 68000
        INCDIR  "ass:/INCLUDE"
        INCLUDE "lvo/exec.i"
        INCLUDE "lvo/dos.i"
        INCLUDE "dos/dos.i"
        list

r_memptr    equr    a5
r_buf1ptr   equr    a4
r_chunk     equr    a3
r_retval    equr    d7
r_fh1       equr    d6
r_fh2       equr    d5

CALL    macro
        jsr     _LVO\1(a6)
        endm

start
        move.l  4.w,a6
        move.l  #gesamt,d0
        moveq   #1,d1
        swap    d1              ; MEMF_CLEAR
        CALL    AllocVec
        tst.l   d0
        bne.s   mem_ok
        moveq   #30,d0
        rts
mem_ok
        move.l  d0,r_memptr     ; Pointer auf reserviertes RAM
        moveq   #25,r_retval    ; RetVal setzen
        lea     dosname(pc),a1
        moveq   #37,d0
        CALL    OpenLibrary
        move.l  d0,(r_memptr)   ; dosbase
        bne.s   dos_ok
        bra     free_mem
dos_ok
        move.l  d0,a6
        moveq   #20,r_retval
        lea     buffer1(r_memptr),r_buf1ptr ; globale Konstanten
        lea     chunks(pc),r_chunk
arg
        lea     argstring(pc),a0
        move.l  a0,d1           ; Argument-Schablone nach d1
        lea     arg_file(r_memptr),a0
        move.l  a0,d2           ; Argument-Struct nach d2
        moveq   #0,d3
        CALL    ReadArgs
        move.l  d0,rdarg(r_memptr)
        bne.s   arg_ok

        CALL    IoErr           ; Fehler bei ReadArgs
        move.l  d0,d1
        moveq   #0,d2
        CALL    PrintFault
        bra.s   close_dos
arg_ok
        moveq   #10,r_retval
        move.l  arg_file(r_memptr),d1
        move.l  #MODE_OLDFILE,d2
        CALL    Open
        move.l  d0,r_fh1
        beq.s   free_arg

        move.l  r_fh1,d1
        move.l  r_buf1ptr,d2
        moveq   #12,d3          ; 12 Byte Header
        CALL    Read
        tst.l   d0              ; überhaupt gelesen ?
        beq.s   close_file

        move.l  (r_chunk)+,d0   ; "FORM"
        cmp.l   (r_buf1ptr),d0
        bne.s   close_file
        move.l  (r_chunk)+,d0   ; "DEEP"
        cmp.l   8(r_buf1ptr),d0
        bne.s   close_file

        move.l  (r_chunk)+,d4   ; "DGBL"
        bsr.s   SeekChunk
        beq.s   close_file

        move.l  r_fh1,d1
        move.l  r_buf1ptr,d2
        move.l  4(r_buf1ptr),d3 ; Länge DGBL-Chunk
        CALL    Read
        tst.l   d0
        beq.s   close_file

        move.w  (r_buf1ptr),breite+2(r_memptr)  ; Word -> LW
        move.w  2(r_buf1ptr),hoehe+2(r_memptr)  ; Word -> LW

        move.l  (r_chunk)+,d4   ; "DBOD"
        bsr.s   SeekChunk
        beq.s   close_file

        CALL    Output          ; StdOut holen
        move.l  d0,r_fh2
        beq.s   close_file

        bsr.s   Header          ; PNM-Header schreiben
        beq.s   close_file
        bsr.s   Deep2pnm        ; eigentliche Wandlung

        moveq   #0,r_retval     ; alles ok
close_file
        move.l  r_fh1,d1
        CALL    Close
free_arg
        move.l  rdarg(r_memptr),d1
        CALL    FreeArgs
close_dos
        move.l  a6,a1           ; dosbase
        move.l  4.w,a6
        CALL    CloseLibrary
free_mem
        move.l  r_memptr,a1
        CALL    FreeVec
ende
        move.l  r_retval,d0
        rts

SeekChunk
        move.l  r_fh1,d1
        move.l  r_buf1ptr,d2
        moveq   #8,d3
        CALL    Read
        tst.l   d0
        beq.s   end_seek

        move.l  d4,d0
        cmp.l   (r_buf1ptr),d0
        beq.s   end_seek

        move.l  r_fh1,d1
        move.l  4(r_buf1ptr),d2
        moveq   #OFFSET_CURRENT,d3
        CALL    Seek
        bra.s   SeekChunk
end_seek
        tst.l   d0              ; CC setzen: 0 = Fehler bei Read, sonst ok
        rts

Deep2pnm
        move.l  r_fh1,d1
        move.l  r_buf1ptr,d2
        move.l  #buflen,d3      ; Buffer voll lesen
        CALL    Read
        tst.l   d0
        beq.s   conv_end

        move.l  r_buf1ptr,a0
        lea     buffer2(r_memptr),a1
        move.l  a1,d2           ; für Write merken
        lsr.l   #2,d0           ; Anzahl Langworte
        move.l  d0,d3           ; merken
        subq.l  #1,d0
copyloop
        move.b  (a0)+,(a1)+     ; je 3 von 4 Byte kopieren
        move.b  (a0)+,(a1)+
        move.b  (a0)+,(a1)+
        addq.l  #1,a0
        dbra    d0,copyloop

        move.l  r_fh2,d1
        mulu    #3,d3           ; 3 Byte je Langwort schreiben
        CALL    Write
        bne.s   Deep2pnm
conv_end
        rts

Header
        move.l  4.w,a6
        lea     fmtstring(pc),a0
        lea     breite(r_memptr),a1
        lea     PutChProc(pc),a2
        move.l  r_buf1ptr,a3
        CALL    RawDoFmt
        move.l  r_fh2,d1
        move.l  r_buf1ptr,d2
        move.l  count(pc),d3
        move.l  (r_memptr),a6   ; dosbase
        CALL    Write
        rts
PutChProc
        move.b  d0,(a3)+
        lea     count(pc),a0
        addq.l  #1,(a0)
        rts

count           dc.l    -1      ; für Write wegen abschließender 0
chunks          dc.b    "FORM"
                dc.b    "DEEP"
                dc.b    "DGBL"
                dc.b    "DBOD"
dosname         dc.b    "dos.library",0
argstring       dc.b    "DEEPFILE/A",0
fmtstring       dc.b    "P6",10,"%ld %ld",10,"255",10,0
        end
