WBStartup
NoCli

; CLEARSCREEN version. Additional code by Paul West.

; Non-clearscreen results:

; 040/25 results:

; 320x200 @42fps DoublePAL or 44fps PAL
; 320x256 @31fps DoublePAL or 34fps PAL
; 320x240 @33.7fps DoublePAL or 36.5fps PAL

#c2pBPLX=320
#c2pBPLY=256
#c2pBPLSIZE=(#c2pBPLX*#c2pBPLY)/8

#scrwidth=#c2pBPLX
#scrheight=#c2pBPLY
#screensize=#scrwidth*#scrheight

#clearscreento=$00000000

; 060 friendly version
;       modulo  max res fscreen compu
; c2p1x1_8_c5     no  320x256?  no  030

Statement c2pGenericInit{A.l,B.l}

  ;A.l=d0=Width.w
  ;B.l=d1=Height.w

; d0.w  chunkyx [chunky-pixels]
; d1.w  chunkyy [chunky-pixels]
; d3.w  scroffsy [screen-pixels]

  MOVEQ.l #0,d3 ; Y offset

c2p1x1_8_c5_init
  LEA c2p_data(pc),a0
  ANDI.l  #$ffff,d0
  MULU.w  d0,d3
  LSR.l #3,d3
  MOVE.l  d3,c2p_scroffs-c2p_data(a0)
  MULU.w  d0,d1
  MOVE.l  d1,c2p_pixels-c2p_data(a0)
AsmExit
End Statement

Statement c2pGeneric{A.l,B.l}

  MOVE.l  d0,a0 ; Chunky
  MOVE.l  d1,a1 ; Planar

; a0  c2pscreen
; a1  bitplanes

c2p1x1_8_c5
  MOVEM.l a3-a6,-(a7)

  LEA c2p_data(pc),a2

  MOVE.l  #$33333333,d5
  MOVE.l  #$55555555,a6

  ADD.w #c2pBPLSIZE,a1
  ADD.l c2p_scroffs-c2p_data(a2),a1

  MOVE.l  c2p_pixels-c2p_data(a2),a2
  ADD.l a0,a2
  CMP.l a0,a2
  BEQ _none

  MOVEM.l a0-a1,-(a7)

  MOVE.l  (a0),d0
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d2
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d1
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d3
  MOVE.l  #clearscreento,(a0)+

  MOVE.l  #$0f0f0f0f,d4   ; Merge 4x1, part 1
  AND.l d4,d0
  AND.l d4,d1
  AND.l d4,d2
  AND.l d4,d3
  LSL.l #4,d0
  LSL.l #4,d1
  OR.l  d2,d0
  OR.l  d3,d1

  MOVE.l  (a0),d2
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d6
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d3
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d7
  MOVE.l  #clearscreento,(a0)+

  AND.l d4,d2     ; Merge 4x1, part 2
  AND.l d4,d6
  AND.l d4,d3
  AND.l d4,d7
  LSL.l #4,d2
  LSL.l #4,d3
  OR.l  d6,d2
  OR.l  d7,d3

  MOVE.w  d2,d6     ; Swap 16x2
  MOVE.w  d3,d7
  MOVE.w  d0,d2
  MOVE.w  d1,d3
  SWAP  d2
  SWAP  d3
  MOVE.w  d2,d0
  MOVE.w  d3,d1
  MOVE.w  d6,d2
  MOVE.w  d7,d3

  MOVE.l  d2,d6     ; Swap 2x2
  MOVE.l  d3,d7
  LSR.l #2,d6
  LSR.l #2,d7
  EOR.l d0,d6
  EOR.l d1,d7
  AND.l d5,d6
  AND.l d5,d7
  EOR.l d6,d0
  EOR.l d7,d1
  LSL.l #2,d6
  LSL.l #2,d7
  EOR.l d6,d2
  EOR.l d7,d3

  MOVE.l  #$00ff00ff,d4
  MOVE.l  d1,d6     ; Swap 8x1
  MOVE.l  d3,d7
  LSR.l #8,d6
  LSR.l #8,d7
  EOR.l d0,d6
  EOR.l d2,d7
  BRA _start1
_x1
  MOVE.l  (a0),d0
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d2
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d1
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d3
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  d7,-c2pBPLSIZE(a1)

  MOVE.l  #$0f0f0f0f,d4   ; Merge 4x1, part 1
  AND.l d4,d0
  AND.l d4,d1
  AND.l d4,d2
  AND.l d4,d3
  LSL.l #4,d0
  LSL.l #4,d1
  OR.l  d2,d0
  OR.l  d3,d1

  MOVE.l  (a0),d2
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d6
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d3
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d7
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  a3,c2pBPLSIZE(a1)

  AND.l d4,d2     ; Merge 4x1, part 2
  AND.l d4,d6
  AND.l d4,d3
  AND.l d4,d7
  LSL.l #4,d2
  LSL.l #4,d3
  OR.l  d6,d2
  OR.l  d7,d3

  MOVE.w  d2,d6     ; Swap 16x2
  MOVE.w  d3,d7
  MOVE.w  d0,d2
  MOVE.w  d1,d3
  SWAP  d2
  SWAP  d3
  MOVE.w  d2,d0
  MOVE.w  d3,d1
  MOVE.w  d6,d2
  MOVE.w  d7,d3
  MOVE.l  a4,c2pBPLSIZE*2(a1)

  MOVE.l  d2,d6     ; Swap 2x2
  MOVE.l  d3,d7
  LSR.l #2,d6
  LSR.l #2,d7
  EOR.l d0,d6
  EOR.l d1,d7
  AND.l d5,d6
  AND.l d5,d7
  EOR.l d6,d0
  EOR.l d7,d1
  LSL.l #2,d6
  LSL.l #2,d7
  EOR.l d6,d2
  EOR.l d7,d3

  MOVE.l  #$00ff00ff,d4
  MOVE.l  d1,d6     ; Swap 8x1
  MOVE.l  d3,d7
  LSR.l #8,d6
  LSR.l #8,d7
  EOR.l d0,d6
  EOR.l d2,d7
  MOVE.l  a5,(a1)+
_start1
  AND.l d4,d6
  AND.l d4,d7
  EOR.l d6,d0
  EOR.l d7,d2
  LSL.l #8,d6
  LSL.l #8,d7
  EOR.l d6,d1
  EOR.l d7,d3

  MOVE.l  a6,d4
  MOVE.l  d1,d6     ; Swap 1x1
  MOVE.l  d3,d7
  LSR.l #1,d6
  LSR.l #1,d7
  EOR.l d0,d6
  EOR.l d2,d7
  AND.l d4,d6
  AND.l d4,d7
  EOR.l d6,d0
  EOR.l d7,d2
  ADD.l d6,d6
  ADD.l d7,d7
  EOR.l d1,d6
  EOR.l d3,d7

  MOVE.l  d0,a4
  MOVE.l  d2,a5
  MOVE.l  d6,a3

  CMPA.l  a0,a2
  BNE _x1
  MOVE.l  d7,-c2pBPLSIZE(a1)
  MOVE.l  a3,c2pBPLSIZE(a1)
  MOVE.l  a4,c2pBPLSIZE*2(a1)
  MOVE.l  a5,(a1)+

  MOVEM.l (a7)+,a0-a1
  ADD.l #c2pBPLSIZE*4,a1

  MOVE.l  (a0),d0
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d2
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d1
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d3
  MOVE.l  #clearscreento,(a0)+

  MOVE.l  #$f0f0f0f0,d4   ; Merge 4x1, part 1
  AND.l d4,d0
  AND.l d4,d1
  AND.l d4,d2
  AND.l d4,d3
  LSR.l #4,d2
  LSR.l #4,d3
  OR.l  d2,d0
  OR.l  d3,d1

  MOVE.l  (a0),d2
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d6
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d3
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d7
  MOVE.l  #clearscreento,(a0)+

  AND.l d4,d2     ; Merge 4x1, part 2
  AND.l d4,d6
  AND.l d4,d3
  AND.l d4,d7
  LSR.l #4,d6
  LSR.l #4,d7
  OR.l  d6,d2
  OR.l  d7,d3

  MOVE.w  d2,d6     ; Swap 16x2
  MOVE.w  d3,d7
  MOVE.w  d0,d2
  MOVE.w  d1,d3
  SWAP  d2
  SWAP  d3
  MOVE.w  d2,d0
  MOVE.w  d3,d1
  MOVE.w  d6,d2
  MOVE.w  d7,d3

  MOVE.l  d2,d6     ; Swap 2x2
  MOVE.l  d3,d7
  LSR.l #2,d6
  LSR.l #2,d7
  EOR.l d0,d6
  EOR.l d1,d7
  AND.l d5,d6
  AND.l d5,d7
  EOR.l d6,d0
  EOR.l d7,d1
  LSL.l #2,d6
  LSL.l #2,d7
  EOR.l d6,d2
  EOR.l d7,d3

  MOVE.l  #$00ff00ff,d4
  MOVE.l  d1,d6     ; Swap 8x1
  MOVE.l  d3,d7
  LSR.l #8,d6
  LSR.l #8,d7
  EOR.l d0,d6
  EOR.l d2,d7
  BRA _start2
_x2
  MOVE.l  (a0),d0
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d2
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d1
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d3
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  d7,-c2pBPLSIZE(a1)

  MOVE.l  #$f0f0f0f0,d4   ; Merge 4x1, part 1
  AND.l d4,d0
  AND.l d4,d1
  AND.l d4,d2
  AND.l d4,d3
  LSR.l #4,d2
  LSR.l #4,d3
  OR.l  d2,d0
  OR.l  d3,d1

  MOVE.l  (a0),d2
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d6
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d3
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  (a0),d7
  MOVE.l  #clearscreento,(a0)+
  MOVE.l  a3,c2pBPLSIZE(a1)

  AND.l d4,d2     ; Merge 4x1, part 2
  AND.l d4,d6
  AND.l d4,d3
  AND.l d4,d7
  LSR.l #4,d6
  LSR.l #4,d7
  OR.l  d6,d2
  OR.l  d7,d3

  MOVE.w  d2,d6     ; Swap 16x2
  MOVE.w  d3,d7
  MOVE.w  d0,d2
  MOVE.w  d1,d3
  SWAP  d2
  SWAP  d3
  MOVE.w  d2,d0
  MOVE.w  d3,d1
  MOVE.w  d6,d2
  MOVE.w  d7,d3
  MOVE.l  a4,c2pBPLSIZE*2(a1)

  MOVE.l  d2,d6     ; Swap 2x2
  MOVE.l  d3,d7
  LSR.l #2,d6
  LSR.l #2,d7
  EOR.l d0,d6
  EOR.l d1,d7
  AND.l d5,d6
  AND.l d5,d7
  EOR.l d6,d0
  EOR.l d7,d1
  LSL.l #2,d6
  LSL.l #2,d7
  EOR.l d6,d2
  EOR.l d7,d3

  MOVE.l  #$00ff00ff,d4
  MOVE.l  d1,d6     ; Swap 8x1
  MOVE.l  d3,d7
  LSR.l #8,d6
  LSR.l #8,d7
  EOR.l d0,d6
  EOR.l d2,d7
  MOVE.l  a5,(a1)+
_start2
  AND.l d4,d6
  AND.l d4,d7
  EOR.l d6,d0
  EOR.l d7,d2
  LSL.l #8,d6
  LSL.l #8,d7
  EOR.l d6,d1
  EOR.l d7,d3

  MOVE.l  a6,d4
  MOVE.l  d1,d6     ; Swap 1x1
  MOVE.l  d3,d7
  LSR.l #1,d6
  LSR.l #1,d7
  EOR.l d0,d6
  EOR.l d2,d7
  AND.l d4,d6
  AND.l d4,d7
  EOR.l d6,d0
  EOR.l d7,d2
  ADD.l d6,d6
  ADD.l d7,d7
  EOR.l d1,d6
  EOR.l d3,d7

  MOVE.l  d0,a4
  MOVE.l  d2,a5
  MOVE.l  d6,a3

  CMPA.l  a0,a2
  BNE _x2
  MOVE.l  d7,-c2pBPLSIZE(a1)
  MOVE.l  a3,c2pBPLSIZE(a1)
  MOVE.l  a4,c2pBPLSIZE*2(a1)
  MOVE.l  a5,(a1)+

_none
  MOVEM.l (a7)+,a3-a6
  AsmExit

  Even4
c2p_data
c2p_screen: Dc.l 0
c2p_scroffs: Dc.l 0
c2p_scroffs2: Dc.l 0
c2p_c2pBPLSIZE: Dc.l 0
c2p_pixels: Dc.l 0
  Ds.l  16
End Statement



.blitzprogram
; Setup
InitBank 0,(#scrwidth*#scrheight)+1000,2|65536 ; Chipram planar buffer
CludgeBitMap 0,#scrwidth,#scrheight,8,Bank(0)
InitPalette 0,256
For c=0 To 255
  AGAPalRGB 0,c,Rnd(c),Rnd(c),Rnd(c)
Next c
AGAPalRGB 0,0,0,0,0
Screen 0,0,0,#scrwidth,#scrheight,8,0,"c2p test",0,0,0
Use Palette 0
VWait 50
baseaddress1.l=AllocMem(#scrwidth*#scrheight,$10000) ; Fastram chunky buffer

; Put something into the chunky buffer so we can see it working
GetReg a0,baseaddress1
MOVE.l  #0,d0
MOVE.l  #screensize-1,d1
cloop
  MOVE.b  d0,(a0)+
  ADDQ.l  #1,d0
  SUBQ.l  #1,d1
  TST.l   d1
  BLT     done
  BRA     cloop
done

; Do the c2p test
c2pGenericInit{#scrwidth,#scrheight}
VWait 20
Forbid_
VWait
ResetTimer
For time=1 To 800
  c2pGeneric{baseaddress1,Bank(0)} ; Convert chunky to planar
Next time
t=Ticks
VWait 2 : Permit_
VWait 20
FindScreen 0
Window 0,0,11,640,100,0,"Test results for c2p",0,0
WindowOutput 0
NPrint "Routine performed @ ",50/(t/800),"fps - ",t," ticks"
NPrint " "
NPrint "Press mousebutton..."
Free Screen 0
MouseWait
Free Window 0
End

