
                incdir  include:
                incdir  lvo:
                incdir  powerasm:source/powerpc_lib/warprace/

                include powerpc/powerpc.i
                include warprace.i

                include exec/memory.i
                include graphics/gfx.i

                include exec_lib.i
                include graphics_lib.i

                xref    _LinkerDB
                xref    C2P_PPC

                xdef    bitmap
                xdef    ChunkyBuffer

VERSION         =       1
REVISION        =       0
REVISIONCOUNT   =       1

merge           macro
                move.l  \2,\4
                move.l  #\5,\3
                and.l   \3,\2
                and.l   \1,\3
                eor.l   \3,\1
                eor.l   \2,\4
                ifeq    \6-1
                add.l   \3,\3
                else
                lsl.l   #\6,\3
                endc
                lsr.l   #\6,\4
                or.l    \3,\2
                or.l    \4,\1
                endm




                section "",code

                mc68020

start
                movem.l d1-a6,-(sp)
                lea     _LinkerDB,a4
                cmp.l   #WR_ID,d0
                beq.b   .go
                movem.l (sp)+,d1-a6
                moveq   #0,d0
                rts
.go
                lea     ErrParams,a3
                move.l  a0,a2
                move.l  $4.w,_SysBase
                lea     graf_name,a1
                move.l  a1,(a3)
                moveq   #0,d0
                move.l  d0,4(a3)
                lea     LibErr,a5
                CALLEXEC        OpenLibrary
                move.l  d0,_GfxBase
                beq.b   .error
                move.l  #320*256,d0
                move.l  d0,(a3)
                move.l  #MEMF_PUBLIC,d1
                lea     MemErr,a5
                CALLEXEC        AllocVec
                move.l  d0,ChunkyBuffer
                beq.b   .error
                lea     ChipErr,a5
                bsr     SetupBitmaps
                tst.l   d0
                beq.b   .error
                move.l  WRI_POWERPCBASE(a2),_PowerPCBase
                tst     WRI_68K(a2)
                bne     .notPPC
                move.l  a2,a0
                RUNPOWERPC      C2P_PPC
                bra.w   .done
.notPPC
                move.l  WRI_STARTTIMER_68K(a2),a1
                jsr     (a1)
                moveq   #50-1,d7
.loop
                move.l  ChunkyBuffer,a0
                lea     bitmap,a1
                bsr     ChunkyToPlanar
                dbra    d7,.loop
                move.l  WRI_STOPTIMER_68K(a2),a1
                jsr     (a1)
                divu.l  #50,d0
.done
                move.l  d0,Result
                divul.l #1000,d1:d0
                move.l  d0,ResultParams
                move.l  d1,ResultParams+4
                move.l  #STATUS_SUCCESS,Status
                bra.b   .end
.error
                move.l  #STATUS_ERROR,Status
                move.l  a5,ErrStr
.end
                move.l  ChunkyBuffer,d0
                beq.b   .nofree
                move.l  d0,a1
                CALLEXEC        FreeVec
.nofree
                bsr     FreeBitmaps
                move.l  _GfxBase,d0
                beq.b   .nograf
                move.l  d0,a1
                CALLEXEC        CloseLibrary
.nograf
                move.l  #WRO,d0
                movem.l (sp)+,d1-a6
                rts

******************************************************************************
*
*       d0 = SetupBitmaps
*
*       prepares one bitmap
*
*       Out:
*       d0 = error code
*
*       error codes:    -1 = success
*                        0 = not enough memory
******************************************************************************
SetupBitmaps
                movem.l d1/d5-a2,-(sp)
                lea     bitmap,a0
                move.l  a0,ActualBitmap
.loop
                move.l  a0,a2
                lea     bm_Planes(a2),a2        ;a2 -> planeptrs
                moveq   #8,d0
                move.l  #320,d1
                move.l  #256,d2
                CALLGRAF        InitBitMap      ;init bitmap structures
                move.l  #320,d0
                move.l  #256*8,d1
                CALLGRAF        AllocRaster     ;allocate bitmap memory
                tst.l   d0
                beq.b   .error
                move.l  d0,a0
                move.l  #(256*8*320/8/4),d5
.clear
                clr.l   (a0)+                   ;clear one plane
                subq.l  #1,d5
                bne.b   .clear
                moveq   #8-1,d6
.loop2
                move.l  d0,(a2)+                ;and insert into bitmap struct
                add.l   #320/8*256,d0
                dbra    d6,.loop2
                moveq   #-1,d0
                bra.b   .end
.error
                moveq   #0,d0
.end
                movem.l (sp)+,d1/d5-a2
                rts

******************************************************************************
*
*       FreeBitmaps
*
*       frees all the memory allocated by 'AllocRaster'
*
******************************************************************************
FreeBitmaps
                movem.l d0/d1/d6-a2,-(sp)
                lea     bitmap,a0
.loop
                move.l  a0,a2
                lea     bm_Planes(a2),a2
                moveq   #8-1,d6
.loop2
                move.l  (a2)+,d0                ;read planeptr
                beq.b   .next
                move.l  d0,a0
                move.l  #320,d0
                move.l  #256,d1
                CALLGRAF        FreeRaster      ;free the bitmap memory
.next
                dbra    d6,.loop2
                movem.l (sp)+,d0/d1/d6-a2
                rts

******************************************************************************
*
*       ChunkyToPlanar (a0,a1)
*
*       converts chunky data into bitplane data (using Bitmap Structure)
*       works ONLY with a depth of 8 and resolution 320*256.
*       the 8 bitplanes MUST have been allocated in ONE piece!!
*
*       original algorithm by James McCoull (I found the source somewhere
*       on the AMINET CD's)
*
*       In: a0 -> Chunkybuffer
*           a1 -> Bitmap structure
*
******************************************************************************
ChunkyToPlanar
                movem.l d0-a6,-(sp)
                sub.w   #40,sp          ; space for temporary variables

                move.l  #256*40,d2
                move.l  bm_Planes(a1),a1

; a0 = chunky buffer
; a1 = output area
; d2 = plsiz
                ext.l   d2
                movea.l d2,a3           ; a3 = plsiz
                move.l  a0,a4
                add.l   #320*256,a4     ; a4 -> end of chunky data


first_case
                move.l  (0,a0),d1
                move.l  (4,a0),d3
                move.l  (8,a0),d0
                move.l  (12,a0),d2
                move.l  (2,a0),d4
                move.l  (10,a0),d5
                move.l  (6,a0),d6
                move.l  (14,a0),d7

                move.w  (16,a0),d1
                move.w  (24,a0),d0
                move.w  (20,a0),d3
                move.w  (28,a0),d2
                move.w  (18,a0),d4
                move.w  (26,a0),d5
                move.w  (22,a0),d6
                move.w  (30,a0),d7

                adda.w  #32,a0

                move.l  d6,a5
                move.l  d7,a6

                merge   d1,d0,d6,d7,$00ff00ff,8
                merge   d3,d2,d6,d7,$00ff00ff,8

                merge   d1,d3,d6,d7,$0f0f0f0f,4
                merge   d0,d2,d6,d7,$0f0f0f0f,4

                exg     d1,a5
                exg     d0,a6

                merge   d4,d5,d6,d7,$00ff00ff,8
                merge   d1,d0,d6,d7,$00ff00ff,8

                merge   d4,d1,d6,d7,$0f0f0f0f,4
                merge   d5,d0,d6,d7,$0f0f0f0f,4

                merge   d3,d1,d6,d7,$33333333,2
                merge   d2,d0,d6,d7,$33333333,2

                merge   d3,d2,d6,d7,$55555555,1
                merge   d1,d0,d6,d7,$55555555,1

                move.l  d0,(0*4,sp)             ;plane0
                move.l  d1,(1*4,sp)             ;plane1
                move.l  d2,(2*4,sp)             ;plane2
                move.l  d3,(3*4,sp)             ;plane3

                move.l  a5,d3
                move.l  a6,d2

                merge   d3,d4,d6,d7,$33333333,2
                merge   d2,d5,d6,d7,$33333333,2

                merge   d3,d2,d6,d7,$55555555,1
                merge   d4,d5,d6,d7,$55555555,1

                move.l  d5,(4*4,sp)             ;plane4
                move.l  d4,(5*4,sp)             ;plane5

                move.l  d2,(6*4,sp)             ;plane6
                move.l  d3,(7*4,sp)             ;plane7

                move.l  a1,(32,sp)              ; save output address
                addq.l  #4,a1                   ; skip 32 pixels on output

                cmpa.l  a0,a4
                beq.w   final_case



main_case
                move.l  a1,(36,sp)      ; save current output address
                move.l  (32,sp),a1      ; a1 = previous output address

                move.l  (0,a0),d1
                move.l  (4,a0),d3
                move.l  (8,a0),d0
                move.l  (12,a0),d2
                move.l  (2,a0),d4
                move.l  (10,a0),d5
                move.l  (6,a0),d6
                move.l  (14,a0),d7

                move.w  (16,a0),d1
                move.w  (24,a0),d0
                move.w  (20,a0),d3
                move.w  (28,a0),d2
                move.w  (18,a0),d4
                move.w  (26,a0),d5
                move.w  (22,a0),d6
                move.w  (30,a0),d7

                adda.w  #32,a0

                move.l  d6,a5
                move.l  d7,a6

                move.l  (0*4,sp),(a1)           ;plane0
                adda.l  a3,a1                   ;a1+=plsiz

                merge   d1,d0,d6,d7,$00ff00ff,8
                merge   d3,d2,d6,d7,$00ff00ff,8

                move.l  (1*4,sp),(a1)           ;plane1
                adda.l  a3,a1                   ;a1+=plsiz

                merge   d1,d3,d6,d7,$0f0f0f0f,4
                merge   d0,d2,d6,d7,$0f0f0f0f,4

                exg     d1,a5
                exg     d0,a6

                move.l  (2*4,sp),(a1)           ;plane2
                adda.l  a3,a1                   ;a1+=plsiz

                merge   d4,d5,d6,d7,$00ff00ff,8
                merge   d1,d0,d6,d7,$00ff00ff,8

                move.l  (3*4,sp),(a1)           ;plane3
                adda.l  a3,a1                   ;a1+=plsiz

                merge   d4,d1,d6,d7,$0f0f0f0f,4
                merge   d5,d0,d6,d7,$0f0f0f0f,4

                move.l  (4*4,sp),(a1)           ;plane4
                adda.l  a3,a1                   ;a1+=plsiz

                merge   d3,d1,d6,d7,$33333333,2
                merge   d2,d0,d6,d7,$33333333,2

                move.l  (5*4,sp),(a1)           ;plane5
                adda.l  a3,a1                   ;a1+=plsiz

                merge   d3,d2,d6,d7,$55555555,1
                merge   d1,d0,d6,d7,$55555555,1

                move.l  d0,(0*4,sp)             ;plane0 (movem.l is slower!)
                move.l  d1,(1*4,sp)             ;plane1
                move.l  d2,(2*4,sp)             ;plane2
                move.l  d3,(3*4,sp)             ;plane3

                move.l  a5,d3
                move.l  a6,d2

                move.l  (6*4,sp),(a1)           ;plane6
                adda.l  a3,a1                   ;a1+=plsiz

                merge   d3,d4,d6,d7,$33333333,2
                merge   d2,d5,d6,d7,$33333333,2

                move.l  (7*4,sp),(a1)           ;plane7
                adda.l  a3,a1                   ;a1+=plsiz

                merge   d3,d2,d6,d7,$55555555,1
                merge   d4,d5,d6,d7,$55555555,1

                move.l  d5,(4*4,sp)             ;plane4
                move.l  d4,(5*4,sp)             ;plane5

                move.l  d2,(6*4,sp)             ;plane6
                move.l  d3,(7*4,sp)             ;plane7

                movea.l (36,sp),a1      ; restore current output address
                move.l  a1,(32,sp)      ; save output address
                addq.l  #4,a1

                cmpa.l  a0,a4
                bne.w   main_case


final_case
                move.l  (32,sp),a1      ; a1 = previous output address

                move.l  (0*4,sp),(a1)           ;plane0
                adda.l  a3,a1                   ;a1+=plsiz
                move.l  (1*4,sp),(a1)           ;plane1
                adda.l  a3,a1                   ;a1+=plsiz
                move.l  (2*4,sp),(a1)           ;plane2
                adda.l  a3,a1                   ;a1+=plsiz
                move.l  (3*4,sp),(a1)           ;plane3
                adda.l  a3,a1                   ;a1+=plsiz
                move.l  (4*4,sp),(a1)           ;plane4
                adda.l  a3,a1                   ;a1+=plsiz
                move.l  (5*4,sp),(a1)           ;plane5
                adda.l  a3,a1                   ;a1+=plsiz
                move.l  (6*4,sp),(a1)           ;plane6
                adda.l  a3,a1                   ;a1+=plsiz
                move.l  (7*4,sp),(a1)           ;plane7

exit
                add.w   #40,sp
                movem.l (sp)+,d0-a6
                rts



                section "",data

graf_name       GRAFNAME
                cnop    0,4

WRO
                dc.l    ModName
                dc.l    Short
                dc.l    Description
                dc.l    Author
                dc.l    VERSION
                dc.l    REVISION
                dc.l    REVISIONCOUNT
                dc.l    0
Result
                dc.l    0
                dc.l    RES_MICROSECS
                dc.l    ResultString
                dc.l    ResultParams
Status
                dc.l    0
ErrStr
                dc.l    0
                dc.l    ErrParams
                dc.l    0

ModName         dc.b    "C2P",0
Short           dc.b    "ChunkyToPlanar converter (320*256*8)",0
Description     dc.b    "This program measures the time for a ChunkyToPlanar-\n"
                dc.b    "conversion to complete. The dimensions are 320*256*8.",0
Author          dc.b    "Sam Jordan (original C2P algorithm by James Mc Coull)",0
ResultString    dc.b    "Elapsed time: %ld.%03ld ms",0

LibErr          dc.b    "Failed to open %s V%ld",0
MemErr          dc.b    "Failed to allocate %ld bytes or memory",0
ChipErr         dc.b    "Failed to allocate 320*256 bytes of CHIP memory",0

                section "",bss

_SysBase        ds.l    1
_GfxBase        ds.l    1
_PowerPCBase    ds.l    1
ActualBitmap    ds.l    1
ChunkyBuffer    ds.l    1
ResultParams    ds.l    2
ErrParams       ds.l    2
bitmap          ds.b    bm_SIZEOF
