********************************************************************
*
*       Voxelspace_Calc
*
*       calculation routines for Voxelspace (68K version)
*
*       assemble with:
*       phxass Voxelspace_Calc.s to Voxelspace_Calc.o smallcode
*
*       link with smalldata and smallcode enabled
*
*       Note: this is extremely heavily optimized. Don't try to
*       understand everything (or anything? :). Documentation is
*       unsufficient.
*
*       © 1997 HAAGE&PARTNER Computer GmbH
*
********************************************************************


                include graphics/gfx.i
                include Voxelspace.i

;// XREF / XDEF
                xref    ChunkyBuffer
                xref    TempBuffer
                xref    HiddenBitmap
                xref    ViewCircle
                xref    ViewCirclePtr
                xref    ViewAngle
                xref    Perspective
                xref    HeightData
                xref    MapFile
                xref    ActualHeight
                xref    StartHeight
                xref    ViewDistance
                xref    MinRange
                xref    MaxRange
                xref    PixCount
                xref    Pix_Count
                xref    PixelCount
                xref    Ray_Count
                xref    Direction
                xref    RayCount
                xref    Angle
                xref    PosXDet
                xref    PosYDet
                xref    Pic_Mask2
                xref    ColumnCount
                xref    HRotActual
                xref    BitmapWidth
                xref    AreaHeight
                xref    DispHeight
                xref    SkyPos
                xref    SkyScroll
                xref    SkyBuffer
                xref    SkyData
                xref    SkyHeight
                xref    SkyWidth
                xref    SkyWidth2
                xref    DestOffset
                xref    ChunkyPtr

                xdef    Calculation_T
                xdef    Calculation_T_A
                xdef    Calculation2_T
                xdef    Calculation2_T_A
                xdef    Calculation4
                xdef    Calculation4_A

                xdef    ChunkyToPlanar
;;/


                section "Voxelspace_Calc",code

                mc68020

;// Calculation_T (calculates one voxelspace frame - column width 1)
******************************************************************************
*
*       Calculation_T
*
*       calculates one voxelspace frame with column width = 1
*       the results are written into the chunkybuffer
*       optimized for direct rendering into GfxRAM
*
******************************************************************************
Calculation_T
                movem.l d0-a6,-(sp)
                move.l  HeightData,a0           ;a0 -> place for online persp.
                move    StartHeight,d0
                sub     ActualHeight,d0         ;calc difference to standard
                muls    ViewDistance,d0         ;perspective
                muls    AreaHeight,d0           ;dh * z * AreaHeight
                moveq   #0,d5
                move    MinRange,d5
                moveq   #0,d1
                move.b  PixCount,d1
                lsl.l   d1,d5                   ;pix count * min. range
                moveq   #0,d3
                move    Pix_Count,d7
                subq    #1,d7
.calc
                move.l  d3,d4
                move    MaxRange,d2
                sub     MinRange,d2
                mulu    d2,d4
                add.l   d5,d4
                divu    Pix_Count,d4            ;calc actual x position
                move    d4,d6
                add     ViewDistance,d4         ;x + z
                ext.l   d4
                move.l  d0,d1
                divsl.l d4,d1                   ;dh * z / (x + z) * AreaHeight
                divs    DispHeight,d1           ;d1 / Dispheight
                move    d1,(a0)+                ;store value
                addq    #1,d3
                dbra    d7,.calc

                move.l  MapFile+FILE_ADDRESS,a2 ;a2 -> map
                move.l  ChunkyBuffer,a3         ;a3 -> chunky buffer
                move    AreaHeight,d0
                subq    #1,d0
                moveq   #0,d1
                move    BitmapWidth,d1
                move.l  d1,a6
                mulu    d1,d0
                add.l   d0,a3                   ;a3 -> last line in chunky buf.
                move.l  a3,ChunkyPtr
                move.l  TempBuffer,a3

                move.l  ViewCircle,a0
                move.l  ViewAngle,a5
                move    Direction,d0
                moveq   #0,d1
                move    Ray_Count,d1
                move    d1,d2
                subq    #1,d2
                mulu    Angle,d1
                divu    #360*2,d1               ;subtract half angle from dir.
                sub     d1,d0                   ;d0 = starting ray
                and     d2,d0                   ;wrap around
                ext.l   d0
                lsl.l   #4,d0
                ext.l   d2
                lsl.l   #4,d2

                moveq   #0,d4
                move    ActualHeight,d4         ;get actual height
                moveq   #0,d3
                move.b  SkyScroll,d3
                divu    d3,d4                   ;calc sky scroll value
                sub     SkyPos,d4               ;subtract offset
                neg     d4
                swap    d4
                move.l  a6,DestOffset
                move.l  SkyData,a1              ;a1 -> sky definition

                moveq   #9,d7
                move.l  PosXDet,d5
                lsl.l   d7,d5
                move.l  PosYDet,d6
                lsl.l   d7,d6

                move    ColumnCount,d7          ;number of columns
                subq    #1,d7
.loop
                movem.l d2/d3/d5/d6/a0/a3,-(sp)
                add.l   (a5)+,d0                ;jump to next ray
                and.l   d2,d0                   ;mask out
                add.l   d0,a0                   ;a0 -> new view circle
                add.l   (a0)+,d6
                add.l   (a0)+,d5
                move.l  (a0)+,d3
                move.l  (a0)+,d1
                movem.l d0/a0/a5,-(sp)
                move.l  d3,a0
                move.l  Perspective,a5          ;a5 -> perspective
                move.l  HeightData,a6           ;a1 -> online perspective
                moveq   #0,d3
                move    HRotActual,d3           ;hor. rotation value
                ext.l   d3
                asl.l   #8,d3
                moveq   #0,d0
                move    ColumnCount,d0
                lsr     #1,d0
                divsl.l d0,d3                   ;/ half column count
                move    d7,d4
                neg     d4
                add     d0,d4
                add     d4,d4
                subq    #1,d4
                move    d4,d2
                ext.l   d2
                muls.l  d2,d3                   ;* actual x value
                moveq   #17,d2
                asr.l   d2,d3
                move    d3,a4

                move    #0,d4                   ;old height
                swap    d7
                move    PixelCount,d7           ;number of pixels
                subq    #1,d7
.loop2
                move.l  d6,d2
                move.l  d5,d0
                lsr.l   #16-_PICSIZE,d2
                swap    d0
                and.l   #(((1<<_PICSIZE)-1)<<_PICSIZE),d2
                and.l   #(1<<_PICSIZE)-1,d0
                or.l    d0,d2
                moveq   #0,d3
                move.b  0(a2,d2.l*2),d3         ;read pixel height from map
                add.l   a0,d6
                add.l   d1,d5
                move    0(a5,d3.w*2),d0         ;calc perspective height
                lea     256(a5),a5              ;new tab for new distance
                sub     a4,d0                   ;subtract HRot offset
                add     (a6)+,d0                ;add online perspective value
                sub     d4,d0                   ;calc height difference
                ble.b   .loopend
                add     d0,d4                   ;calc new height
                move.b  1(a2,d2.l*2),d3         ;read pixel color from map
                subq    #1,d0                   ;now draw the vertical bar
.copy
                move.b  d3,(a3)
                addq.l  #4,a3
                dbra    d0,.copy
.loopend
                dbra    d7,.loop2
.colOK
                sub     AreaHeight,d4
                neg     d4                      ;area height - actual height
                move    d4,d0                   ;d0 = sky height to draw
                move    #-1,SKY_COUNT(a1)
                subq    #1,d0
                bmi.b   .jump                   ;no sky to draw -> jump
                swap    d4
                move    d4,d3                   ;get sky offset
                sub     a4,d3                   ;subtract hor. rotation value
                add     SkyHeight,d3
                sub     AreaHeight,d3           ;calc real sky offset
                muls    SkyWidth2,d3            ;mulitply by sky width
                move.l  d3,SKY_SOURCE(a1)       ;write sky offset
                move    d0,SKY_COUNT(a1)        ;write sky height
                swap    d4
.jump
                movem.l (sp)+,d0/a0/a5
                movem.l (sp)+,d2/d3/d5/d6/a0/a3
                addq.l  #1,a3                   ;next column
                lea     SKY_SIZE(a1),a1         ;next sky definition
                swap    d7

                move    d7,d4
                andi    #$3,d4
                bne.w   .loopend2
                movem.l d0/d2/d5-d7,-(sp)
                move.l  ChunkyPtr,a4
                addq.l  #4,ChunkyPtr
                subq.l  #4,a3
                move    AreaHeight,d4
                subq    #2,d4
                move    -4*SKY_SIZE+SKY_COUNT(a1),d2
                move    -3*SKY_SIZE+SKY_COUNT(a1),d5
                move    -2*SKY_SIZE+SKY_COUNT(a1),d1
                move    -SKY_SIZE+SKY_COUNT(a1),d3
                move.l  DestOffset,d0
                move    d3,d6
                cmp     d6,d1
                bge.b   .cmp1
                move    d1,d6
.cmp1
                cmp     d6,d5
                bge.b   .cmp2
                move    d5,d6
.cmp2
                cmp     d6,d2
                bge.b   .cmp3
                move    d2,d6
.cmp3
                sub     d4,d6
                neg     d6
                tst     d6
                bmi.b   .nodraw
.copycol
                move.l  (a3)+,(a4)
                sub.l   d0,a4
                dbra    d6,.copycol
.nodraw
                movem.l (sp)+,d0/d2/d5-d7
                move.l  TempBuffer,a3
.loopend2

                dbra    d7,.loop
                sub.l   a3,a3
                move.l  DestOffset,d5
                move    SkyWidth2,a3
                move.l  SkyBuffer,a1            ;a1 -> sky graphics
                move    Direction,d7            ;get direction
                mulu    SkyWidth2,d7
                divu    Ray_Count,d7            ;calc sky hor. position
                cmp     SkyWidth,d7             ;check for overflow
                blt.b   .cont
                sub     SkyWidth,d7
.cont
                add     d7,a1                   ;a1 -> sky start pos
                move.l  a1,d2
                move.l  SkyData,a0              ;a0 -> sky definition
                move.l  ChunkyBuffer,a2         ;a2 -> chunky buffer
                move.l  a2,d4
                move    ColumnCount,d7
                subq    #1,d7
.loop3
                move.l  SKY_SOURCE(a0),d0       ;get sky source offset
                move.l  d2,a1
                move.l  d4,a2
                add.l   d0,a1                   ;a1 -> sky start pos
                cmp     #3,d7
                blt.w   .normal
                cmp.l   SKY_SOURCE+SKY_SIZE(a0),d0 ;next offset equal?
                bne.w   .normal                 ;no -> normal draw
                cmp.l   SKY_SOURCE+2*SKY_SIZE(a0),d0 ;next offset equal?
                bne.w   .normal                 ;no -> normal draw
                cmp.l   SKY_SOURCE+3*SKY_SIZE(a0),d0 ;next offset equal?
                bne.w   .normal                 ;no -> normal draw
                subq    #3,d7
                movem.l d0/d2/d4/d7,-(sp)
                move    SKY_COUNT(a0),d6
                move    SKY_COUNT+SKY_SIZE(a0),d3
                move    SKY_COUNT+2*SKY_SIZE(a0),d1
                move    SKY_COUNT+3*SKY_SIZE(a0),d0
                move    d6,d2
                cmp     d2,d3
                bge.b   .scmp1
                move    d3,d2
.scmp1
                cmp     d2,d1
                bge.b   .scmp2
                move    d1,d2
.scmp2
                cmp     d2,d0
                bge.b   .scmp3
                move    d0,d2
.scmp3
                tst     d2
                bmi.b   .ssingle1
                sub     d2,d6
                sub     d2,d3
                sub     d2,d1
                sub     d2,d0
                subq    #1,d6
                subq    #1,d3
                subq    #1,d1
                subq    #1,d0
.drawsky4
                move.l  (a1),(a2)               ;draw 4 columns at once
                add.l   d5,a2
                add.l   a3,a1
                dbra    d2,.drawsky4
.ssingle1
                tst     d6
                bmi.b   .ssingle2
                move.l  a1,d4
                move.l  a2,d7
.ssloop1
                move.b  (a1),(a2)
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.ssloop1
                move.l  d4,a1
                move.l  d7,a2
.ssingle2
                tst     d3
                bmi.b   .ssingle3
                move.l  a1,d4
                move.l  a2,d7
.ssloop2
                move.b  1(a1),1(a2)
                add.l   d5,a2
                add.l   a3,a1
                dbra    d3,.ssloop2
                move.l  d4,a1
                move.l  d7,a2
.ssingle3
                tst     d1
                bmi.b   .ssingle4
                move.l  a1,d4
                move.l  a2,d7
.ssloop3
                move.b  2(a1),2(a2)
                add.l   d5,a2
                add.l   a3,a1
                dbra    d1,.ssloop3
                move.l  d4,a1
                move.l  d7,a2
.ssingle4
                tst     d0
                bmi.b   .ssingle5
                move.l  a1,d4
                move.l  a2,d7
.ssloop4
                move.b  3(a1),3(a2)
                add.l   d5,a2
                add.l   a3,a1
                dbra    d0,.ssloop4
                move.l  d4,a1
                move.l  d7,a2
.ssingle5
                movem.l (sp)+,d0/d2/d4/d7
                addq.l  #4,d2                   ;increase by 4 columns
                addq.l  #4,d4
                lea     SKY_SIZE*4(a0),a0
                dbra    d7,.loop3
                bra.b   .end
.normal
                move    SKY_COUNT(a0),d6        ;get sky height
                bmi.b   .next
.drawsky
                move.b  (a1),(a2)               ;draw one sky column
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky
.next
                addq.l  #1,d2                   ;next column
                addq.l  #1,d4
                lea     SKY_SIZE(a0),a0
                dbra    d7,.loop3
.end
                movem.l (sp)+,d0-a6
                rts
;;/
;// Calculation_T_A (calculates one voxelspace frame - column width 1)
******************************************************************************
*
*       Calculation_T_A
*
*       calculates one voxelspace frame with column width = 1
*       the results are written into the chunkybuffer
*       optimized for direct rendering into GfxRAM
*       approximation routine
*
******************************************************************************
Calculation_T_A
                movem.l d0-a6,-(sp)
                move.l  HeightData,a0           ;a0 -> place for online persp.
                move    StartHeight,d0
                sub     ActualHeight,d0         ;calc difference to standard
                muls    ViewDistance,d0         ;perspective
                muls    AreaHeight,d0           ;dh * z * AreaHeight
                moveq   #0,d5
                move    MinRange,d5
                moveq   #0,d1
                move.b  PixCount,d1
                lsl.l   d1,d5                   ;pix count * min. range
                moveq   #0,d3
                move    Pix_Count,d7
                subq    #1,d7
.calc
                move.l  d3,d4
                move    MaxRange,d2
                sub     MinRange,d2
                mulu    d2,d4
                add.l   d5,d4
                divu    Pix_Count,d4            ;calc actual x position
                move    d4,d6
                add     ViewDistance,d4         ;x + z
                ext.l   d4
                move.l  d0,d1
                divsl.l d4,d1                   ;dh * z / (x + z) * AreaHeight
                divs    DispHeight,d1           ;d1 / Dispheight
                move    d1,(a0)+                ;store value
                addq    #1,d3
                dbra    d7,.calc

                move.l  MapFile+FILE_ADDRESS,a2 ;a2 -> map
                move.l  ChunkyBuffer,a3         ;a3 -> chunky buffer
                move    AreaHeight,d0
                subq    #1,d0
                moveq   #0,d1
                move    BitmapWidth,d1
                move.l  d1,a6
                mulu    d1,d0
                add.l   d0,a3                   ;a3 -> last line in chunky buf.
                move.l  a3,ChunkyPtr
                move.l  TempBuffer,a3

                move.l  ViewCircle,a0
                move.l  ViewAngle,a5
                move    Direction,d0
                moveq   #0,d1
                move    Ray_Count,d1
                move    d1,d2
                subq    #1,d2
                mulu    Angle,d1
                divu    #360*2,d1               ;subtract half angle from dir.
                sub     d1,d0                   ;d0 = starting ray
                and     d2,d0                   ;wrap around
                ext.l   d0
                lsl.l   #4,d0
                ext.l   d2
                lsl.l   #4,d2

                moveq   #0,d4
                move    ActualHeight,d4         ;get actual height
                moveq   #0,d3
                move.b  SkyScroll,d3
                divu    d3,d4                   ;calc sky scroll value
                sub     SkyPos,d4               ;subtract offset
                neg     d4
                swap    d4
                move.l  a6,DestOffset
                move.l  SkyData,a1              ;a1 -> sky definition

                moveq   #9,d7
                move.l  PosXDet,d5
                lsl.l   d7,d5
                move.l  PosYDet,d6
                lsl.l   d7,d6

                move    ColumnCount,d7          ;number of columns
                subq    #1,d7
.loop
                movem.l d2/d3/d5/d6/a0/a3,-(sp)
                add.l   (a5)+,d0                ;jump to next ray
                and.l   d2,d0                   ;mask out
                add.l   d0,a0                   ;a0 -> new view circle
                add.l   (a0)+,d6
                add.l   (a0)+,d5
                move.l  (a0)+,d3
                move.l  (a0)+,d1
                movem.l d0/a0/a5,-(sp)
                move.l  d3,a0
                move.l  Perspective,a5          ;a5 -> perspective
                move.l  HeightData,a6           ;a1 -> online perspective
                moveq   #0,d3
                move    HRotActual,d3           ;hor. rotation value
                ext.l   d3
                asl.l   #8,d3
                moveq   #0,d0
                move    ColumnCount,d0
                lsr     #1,d0
                divsl.l d0,d3                   ;/ half column count
                move    d7,d4
                neg     d4
                add     d0,d4
                add     d4,d4
                subq    #1,d4
                move    d4,d2
                ext.l   d2
                muls.l  d2,d3                   ;* actual x value
                moveq   #17,d2
                asr.l   d2,d3
                move    d3,a4

                move    #0,d4                   ;old height
                swap    d7
                move    PixelCount,d7           ;number of pixels
                subq    #1,d7
.loop2
                move.l  d6,d2
                move.l  d5,d0
                lsr.l   #16-_PICSIZE,d2
                swap    d0
                and.l   #(((1<<_PICSIZE)-1)<<_PICSIZE),d2
                and.l   #(1<<_PICSIZE)-1,d0
                or.l    d0,d2
                moveq   #0,d3
                move.b  0(a2,d2.l*2),d3         ;read pixel height from map
                add.l   a0,d6
                add.l   d1,d5
                move    0(a5,d3.w*2),d0         ;calc perspective height
                lea     256(a5),a5              ;new tab for new distance
                sub     a4,d0                   ;subtract HRot offset
                add     (a6)+,d0                ;add online perspective value
                sub     d4,d0                   ;calc height difference
                ble.b   .loopend
                add     d0,d4                   ;calc new height
                move.b  1(a2,d2.l*2),d3         ;read pixel color from map
                subq    #1,d0                   ;now draw the vertical bar
.copy
                move.b  d3,(a3)
                addq.l  #4,a3
                dbra    d0,.copy
                dbra    d7,.loop2
                bra.b   .colOK
.approx
                subq    #1,d7
                bmi.b   .colOK
                lea     256(a5),a5
                addq.l  #2,a6
                add.l   a0,d6
                add.l   d1,d5
                dbra    d7,.loop2
                bra.b   .colOK
.loopend
                blt.b   .approx
                dbra    d7,.loop2
.colOK
                sub     AreaHeight,d4
                neg     d4                      ;area height - actual height
                move    d4,d0                   ;d0 = sky height to draw
                move    #-1,SKY_COUNT(a1)
                subq    #1,d0
                bmi.b   .jump                   ;no sky to draw -> jump
                swap    d4
                move    d4,d3                   ;get sky offset
                sub     a4,d3                   ;subtract hor. rotation value
                add     SkyHeight,d3
                sub     AreaHeight,d3           ;calc real sky offset
                muls    SkyWidth2,d3            ;mulitply by sky width
                move.l  d3,SKY_SOURCE(a1)       ;write sky offset
                move    d0,SKY_COUNT(a1)        ;write sky height
                swap    d4
.jump
                movem.l (sp)+,d0/a0/a5
                movem.l (sp)+,d2/d3/d5/d6/a0/a3
                addq.l  #1,a3                   ;next column
                lea     SKY_SIZE(a1),a1         ;next sky definition
                swap    d7

                move    d7,d4
                andi    #$3,d4
                bne.w   .loopend2
                movem.l d0/d2/d5-d7,-(sp)
                move.l  ChunkyPtr,a4
                addq.l  #4,ChunkyPtr
                subq.l  #4,a3
                move    AreaHeight,d4
                subq    #2,d4
                move    -4*SKY_SIZE+SKY_COUNT(a1),d2
                move    -3*SKY_SIZE+SKY_COUNT(a1),d5
                move    -2*SKY_SIZE+SKY_COUNT(a1),d1
                move    -SKY_SIZE+SKY_COUNT(a1),d3
                move.l  DestOffset,d0
                move    d3,d6
                cmp     d6,d1
                bge.b   .cmp1
                move    d1,d6
.cmp1
                cmp     d6,d5
                bge.b   .cmp2
                move    d5,d6
.cmp2
                cmp     d6,d2
                bge.b   .cmp3
                move    d2,d6
.cmp3
                sub     d4,d6
                neg     d6
                tst     d6
                bmi.b   .nodraw
.copycol
                move.l  (a3)+,(a4)
                sub.l   d0,a4
                dbra    d6,.copycol
.nodraw
                movem.l (sp)+,d0/d2/d5-d7
                move.l  TempBuffer,a3
.loopend2
                dbra    d7,.loop
                sub.l   a3,a3
                move.l  DestOffset,d5
                move    SkyWidth2,a3
                move.l  SkyBuffer,a1            ;a1 -> sky graphics
                move    Direction,d7            ;get direction
                mulu    SkyWidth2,d7
                divu    Ray_Count,d7            ;calc sky hor. position
                cmp     SkyWidth,d7             ;check for overflow
                blt.b   .cont
                sub     SkyWidth,d7
.cont
                add     d7,a1                   ;a1 -> sky start pos
                move.l  a1,d2
                move.l  SkyData,a0              ;a0 -> sky definition
                move.l  ChunkyBuffer,a2         ;a2 -> chunky buffer
                move.l  a2,d4
                move    ColumnCount,d7
                subq    #1,d7
.loop3
                move.l  SKY_SOURCE(a0),d0       ;get sky source offset
                move.l  d2,a1
                move.l  d4,a2
                add.l   d0,a1                   ;a1 -> sky start pos
                cmp     #3,d7
                blt.w   .normal
                cmp.l   SKY_SOURCE+SKY_SIZE(a0),d0 ;next offset equal?
                bne.w   .normal                 ;no -> normal draw
                cmp.l   SKY_SOURCE+2*SKY_SIZE(a0),d0 ;next offset equal?
                bne.w   .normal                 ;no -> normal draw
                cmp.l   SKY_SOURCE+3*SKY_SIZE(a0),d0 ;next offset equal?
                bne.w   .normal                 ;no -> normal draw
                subq    #3,d7
                movem.l d0/d2/d4/d7,-(sp)
                move    SKY_COUNT(a0),d6
                move    SKY_COUNT+SKY_SIZE(a0),d3
                move    SKY_COUNT+2*SKY_SIZE(a0),d1
                move    SKY_COUNT+3*SKY_SIZE(a0),d0
                move    d6,d2
                cmp     d2,d3
                bge.b   .scmp1
                move    d3,d2
.scmp1
                cmp     d2,d1
                bge.b   .scmp2
                move    d1,d2
.scmp2
                cmp     d2,d0
                bge.b   .scmp3
                move    d0,d2
.scmp3
                tst     d2
                bmi.b   .ssingle1
                sub     d2,d6
                sub     d2,d3
                sub     d2,d1
                sub     d2,d0
                subq    #1,d6
                subq    #1,d3
                subq    #1,d1
                subq    #1,d0
.drawsky4
                move.l  (a1),(a2)               ;draw 4 columns at once
                add.l   d5,a2
                add.l   a3,a1
                dbra    d2,.drawsky4
.ssingle1
                tst     d6
                bmi.b   .ssingle2
                move.l  a1,d4
                move.l  a2,d7
.ssloop1
                move.b  (a1),(a2)
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.ssloop1
                move.l  d4,a1
                move.l  d7,a2
.ssingle2
                tst     d3
                bmi.b   .ssingle3
                move.l  a1,d4
                move.l  a2,d7
.ssloop2
                move.b  1(a1),1(a2)
                add.l   d5,a2
                add.l   a3,a1
                dbra    d3,.ssloop2
                move.l  d4,a1
                move.l  d7,a2
.ssingle3
                tst     d1
                bmi.b   .ssingle4
                move.l  a1,d4
                move.l  a2,d7
.ssloop3
                move.b  2(a1),2(a2)
                add.l   d5,a2
                add.l   a3,a1
                dbra    d1,.ssloop3
                move.l  d4,a1
                move.l  d7,a2
.ssingle4
                tst     d0
                bmi.b   .ssingle5
                move.l  a1,d4
                move.l  a2,d7
.ssloop4
                move.b  3(a1),3(a2)
                add.l   d5,a2
                add.l   a3,a1
                dbra    d0,.ssloop4
                move.l  d4,a1
                move.l  d7,a2
.ssingle5
                movem.l (sp)+,d0/d2/d4/d7
                addq.l  #4,d2                   ;increase by 4 columns
                addq.l  #4,d4
                lea     SKY_SIZE*4(a0),a0
                dbra    d7,.loop3
                bra.b   .end
.normal
                move    SKY_COUNT(a0),d6        ;get sky height
                bmi.b   .next
.drawsky
                move.b  (a1),(a2)               ;draw one sky column
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky
.next
                addq.l  #1,d2                   ;next column
                addq.l  #1,d4
                lea     SKY_SIZE(a0),a0
                dbra    d7,.loop3
.end
                movem.l (sp)+,d0-a6
                rts
;;/
;// Calculation2_T (calculates one voxelspace frame - column width 2)
******************************************************************************
*
*       Calculation2_T
*
*       calculates one voxelspace frame with column width = 2
*       the results are written into the chunkybuffer
*       optimized for direct rendering into GfxRAM
*
******************************************************************************
Calculation2_T
                movem.l d0-a6,-(sp)
                move.l  HeightData,a0           ;a0 -> place for online persp.
                move    StartHeight,d0
                sub     ActualHeight,d0         ;calc difference to standard
                muls    ViewDistance,d0         ;perspective
                muls    AreaHeight,d0           ;dh * z * AreaHeight
                moveq   #0,d5
                move    MinRange,d5
                moveq   #0,d1
                move.b  PixCount,d1
                lsl.l   d1,d5                   ;pix count * min. range
                moveq   #0,d3
                move    Pix_Count,d7
                subq    #1,d7
.calc
                move.l  d3,d4
                move    MaxRange,d2
                sub     MinRange,d2
                mulu    d2,d4
                add.l   d5,d4
                divu    Pix_Count,d4            ;calc actual x position
                move    d4,d6
                add     ViewDistance,d4         ;x + z
                ext.l   d4
                move.l  d0,d1
                divsl.l d4,d1                   ;dh * z / (x + z) * AreaHeight
                divs    DispHeight,d1           ;d1 / Dispheight
                move    d1,(a0)+                ;store value
                addq    #1,d3
                dbra    d7,.calc

                move.l  MapFile+FILE_ADDRESS,a2 ;a2 -> map
                move.l  ChunkyBuffer,a3         ;a3 -> chunky buffer
                move    AreaHeight,d0
                subq    #1,d0
                moveq   #0,d1
                move    BitmapWidth,d1
                move.l  d1,a6
                mulu    d1,d0
                add.l   d0,a3                   ;a3 -> last line in chunky buf.
                move.l  a3,ChunkyPtr
                move.l  TempBuffer,a3

                move.l  ViewCircle,a0
                move.l  ViewAngle,a5
                move    Direction,d0
                moveq   #0,d1
                move    Ray_Count,d1
                move    d1,d2
                subq    #1,d2
                mulu    Angle,d1
                divu    #360*2,d1               ;subtract half angle from dir.
                sub     d1,d0                   ;d0 = starting ray
                and     d2,d0                   ;wrap around
                ext.l   d0
                lsl.l   #4,d0
                ext.l   d2
                lsl.l   #4,d2

                moveq   #0,d4
                move    ActualHeight,d4         ;get actual height
                moveq   #0,d3
                move.b  SkyScroll,d3
                divu    d3,d4                   ;calc sky scroll value
                sub     SkyPos,d4               ;subtract offset
                neg     d4
                swap    d4
                move.l  a6,DestOffset
                move.l  SkyData,a1              ;a1 -> sky definition

                moveq   #9,d7
                move.l  PosXDet,d5
                lsl.l   d7,d5
                move.l  PosYDet,d6
                lsl.l   d7,d6

                move    ColumnCount,d7          ;number of columns
                subq    #1,d7
.loop
                movem.l d2/d3/d5/d6/a0/a3,-(sp)
                add.l   (a5)+,d0                ;jump to next ray
                and.l   d2,d0                   ;mask out
                add.l   d0,a0                   ;a0 -> new view circle
                add.l   (a0)+,d6
                add.l   (a0)+,d5
                move.l  (a0)+,d3
                move.l  (a0)+,d1
                movem.l d0/a0/a5,-(sp)
                move.l  d3,a0
                move.l  Perspective,a5          ;a5 -> perspective
                move.l  HeightData,a6           ;a1 -> online perspective
                moveq   #0,d3
                move    HRotActual,d3           ;hor. rotation value
                ext.l   d3
                asl.l   #8,d3
                moveq   #0,d0
                move    ColumnCount,d0
                lsr     #1,d0
                divsl.l d0,d3                   ;/ half column count
                move    d7,d4
                neg     d4
                add     d0,d4
                add     d4,d4
                subq    #1,d4
                move    d4,d2
                ext.l   d2
                muls.l  d2,d3                   ;* actual x value
                moveq   #17,d2
                asr.l   d2,d3
                move    d3,a4

                move    #0,d4                   ;old height
                swap    d7
                move    PixelCount,d7           ;number of pixels
                subq    #1,d7
.loop2
                move.l  d6,d2
                move.l  d5,d0
                lsr.l   #16-_PICSIZE,d2
                swap    d0
                and.l   #(((1<<_PICSIZE)-1)<<_PICSIZE),d2
                and.l   #(1<<_PICSIZE)-1,d0
                or.l    d0,d2
                moveq   #0,d3
                move.b  0(a2,d2.l*2),d3         ;read pixel height from map
                add.l   a0,d6
                add.l   d1,d5
                move    0(a5,d3.w*2),d0         ;calc perspective height
                lea     256(a5),a5              ;new tab for new distance
                sub     a4,d0                   ;subtract HRot offset
                add     (a6)+,d0                ;add online perspective value
                sub     d4,d0                   ;calc height difference
                ble.b   .loopend
                add     d0,d4                   ;calc new height
                move.b  1(a2,d2.l*2),d3         ;read pixel color from map
                subq    #1,d0                   ;now draw the vertical bar
                move.b  d3,d2
                lsl     #8,d3
                move.b  d2,d3
.copy
                move    d3,(a3)
                addq.l  #4,a3
                dbra    d0,.copy
.loopend
                dbra    d7,.loop2
.colOK
                sub     AreaHeight,d4
                neg     d4                      ;area height - actual height
                move    d4,d0                   ;d0 = sky height to draw
                move    #-1,SKY_COUNT(a1)
                subq    #1,d0
                bmi.b   .jump                   ;no sky to draw -> jump
                swap    d4
                move    d4,d3                   ;get sky offset
                sub     a4,d3                   ;subtract hor. rotation value
                add     SkyHeight,d3
                sub     AreaHeight,d3           ;calc real sky offset
                muls    SkyWidth2,d3            ;mulitply by sky width
                move.l  d3,SKY_SOURCE(a1)       ;write sky offset
                move    d0,SKY_COUNT(a1)        ;write sky height
                swap    d4
.jump
                movem.l (sp)+,d0/a0/a5
                movem.l (sp)+,d2/d3/d5/d6/a0/a3
                addq.l  #2,a3                   ;next column
                lea     SKY_SIZE(a1),a1         ;next sky definition
                swap    d7

                btst    #0,d7
                bne.w   .loopend2
                move.l  d0,-(sp)
                move.l  ChunkyPtr,a4
                addq.l  #4,ChunkyPtr
                subq.l  #4,a3
                move    AreaHeight,d4
                subq    #2,d4
                move    -2*SKY_SIZE+SKY_COUNT(a1),d1
                move    -SKY_SIZE+SKY_COUNT(a1),d3
                move.l  DestOffset,d0
                cmp     d3,d1
                ble.b   .noexg1
                exg     d1,d3
.noexg1
                sub     d4,d1
                neg     d1
                tst     d1
                bmi.b   .nodraw
.copycol
                move.l  (a3)+,(a4)
                sub.l   d0,a4
                dbra    d1,.copycol
.nodraw
                move.l  TempBuffer,a3
                move.l  (sp)+,d0
.loopend2
                dbra    d7,.loop
                sub.l   a3,a3
                move.l  DestOffset,d5
                move    SkyWidth2,a3
                move.l  SkyBuffer,a1            ;a1 -> sky graphics
                move    Direction,d7            ;get direction
                mulu    SkyWidth2,d7
                divu    Ray_Count,d7            ;calc sky hor. position
                cmp     SkyWidth,d7             ;check for overflow
                blt.b   .cont
                sub     SkyWidth,d7
.cont
                add     d7,a1                   ;a1 -> sky start pos
                move.l  a1,d2
                move.l  SkyData,a0              ;a0 -> sky definition
                move.l  ChunkyBuffer,a2         ;a2 -> chunky buffer
                move.l  a2,d4
                move    ColumnCount,d7
                subq    #1,d7
.loop3
                move.l  SKY_SOURCE(a0),d0       ;get sky source offset
                move.l  d2,a1
                move.l  d4,a2
                add.l   d0,a1                   ;a1 -> sky start pos
                tst     d7                      ;if last turn
                beq.b   .normal                 ;then normal draw
                cmp.l   SKY_SOURCE+SKY_SIZE(a0),d0 ;next offset equal?
                bne.b   .normal                 ;no -> normal draw
                move    SKY_COUNT(a0),d6        ;sky height > 0 ?
                bmi.b   .next                   ;no -> no draw
                move    SKY_COUNT+SKY_SIZE(a0),d3 ;next sky height > 0?
                bmi.b   .next                   ;no -> no draw
                subq    #1,d7                   ;draw optimized
                moveq   #2,d0
                cmp     d3,d6                   ;compare sky heights
                ble.b   .noexg                  ;of both columns
                exg     d3,d6                   ;change if necessary
                moveq   #0,d0
.noexg
                move    d6,d1
.drawsky2
                move.l  (a1),(a2)               ;draw 2 columns at once
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky2
                sub     d1,d3                   ;subtract heights
                subq    #1,d3
                bmi.b   .next2                  ;equal -> done
                add.l   d0,a1
                add.l   d0,a2
.drawsky3
                move    (a1),(a2)               ;now draw the longer one
                add.l   d5,a2
                add.l   a3,a1
                dbra    d3,.drawsky3
.next2
                addq.l  #4,d2                   ;increase by 2 columns
                addq.l  #4,d4
                lea     SKY_SIZE*2(a0),a0
                dbra    d7,.loop3
                bra.b   .end
.normal
                move    SKY_COUNT(a0),d6        ;get sky height
                bmi.b   .next
.drawsky
                move    (a1),(a2)               ;draw one sky column
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky
.next
                addq.l  #2,d2                   ;next column
                addq.l  #2,d4
                lea     SKY_SIZE(a0),a0
                dbra    d7,.loop3
.end
                movem.l (sp)+,d0-a6
                rts
;;/
;// Calculation2_T_A (calculates one voxelspace frame - column width 2)
******************************************************************************
*
*       Calculation2_T_A
*
*       calculates one voxelspace frame with column width = 2
*       the results are written into the chunkybuffer
*       optimized for direct rendering into GfxRAM
*       approximation routine
*
******************************************************************************
Calculation2_T_A
                movem.l d0-a6,-(sp)
                move.l  HeightData,a0           ;a0 -> place for online persp.
                move    StartHeight,d0
                sub     ActualHeight,d0         ;calc difference to standard
                muls    ViewDistance,d0         ;perspective
                muls    AreaHeight,d0           ;dh * z * AreaHeight
                moveq   #0,d5
                move    MinRange,d5
                moveq   #0,d1
                move.b  PixCount,d1
                lsl.l   d1,d5                   ;pix count * min. range
                moveq   #0,d3
                move    Pix_Count,d7
                subq    #1,d7
.calc
                move.l  d3,d4
                move    MaxRange,d2
                sub     MinRange,d2
                mulu    d2,d4
                add.l   d5,d4
                divu    Pix_Count,d4            ;calc actual x position
                move    d4,d6
                add     ViewDistance,d4         ;x + z
                ext.l   d4
                move.l  d0,d1
                divsl.l d4,d1                   ;dh * z / (x + z) * AreaHeight
                divs    DispHeight,d1           ;d1 / Dispheight
                move    d1,(a0)+                ;store value
                addq    #1,d3
                dbra    d7,.calc

                move.l  MapFile+FILE_ADDRESS,a2 ;a2 -> map
                move.l  ChunkyBuffer,a3         ;a3 -> chunky buffer
                move    AreaHeight,d0
                subq    #1,d0
                moveq   #0,d1
                move    BitmapWidth,d1
                move.l  d1,a6
                mulu    d1,d0
                add.l   d0,a3                   ;a3 -> last line in chunky buf.
                move.l  a3,ChunkyPtr
                move.l  TempBuffer,a3

                move.l  ViewCircle,a0
                move.l  ViewAngle,a5
                move    Direction,d0
                moveq   #0,d1
                move    Ray_Count,d1
                move    d1,d2
                subq    #1,d2
                mulu    Angle,d1
                divu    #360*2,d1               ;subtract half angle from dir.
                sub     d1,d0                   ;d0 = starting ray
                and     d2,d0                   ;wrap around
                ext.l   d0
                lsl.l   #4,d0
                ext.l   d2
                lsl.l   #4,d2

                moveq   #0,d4
                move    ActualHeight,d4         ;get actual height
                moveq   #0,d3
                move.b  SkyScroll,d3
                divu    d3,d4                   ;calc sky scroll value
                sub     SkyPos,d4               ;subtract offset
                neg     d4
                swap    d4
                move.l  a6,DestOffset
                move.l  SkyData,a1              ;a1 -> sky definition

                moveq   #9,d7
                move.l  PosXDet,d5
                lsl.l   d7,d5
                move.l  PosYDet,d6
                lsl.l   d7,d6

                move    ColumnCount,d7          ;number of columns
                subq    #1,d7
.loop
                movem.l d2/d3/d5/d6/a0/a3,-(sp)
                add.l   (a5)+,d0                ;jump to next ray
                and.l   d2,d0                   ;mask out
                add.l   d0,a0                   ;a0 -> new view circle
                add.l   (a0)+,d6
                add.l   (a0)+,d5
                move.l  (a0)+,d3
                move.l  (a0)+,d1
                movem.l d0/a0/a5,-(sp)
                move.l  d3,a0
                move.l  Perspective,a5          ;a5 -> perspective
                move.l  HeightData,a6           ;a1 -> online perspective
                moveq   #0,d3
                move    HRotActual,d3           ;hor. rotation value
                ext.l   d3
                asl.l   #8,d3
                moveq   #0,d0
                move    ColumnCount,d0
                lsr     #1,d0
                divsl.l d0,d3                   ;/ half column count
                move    d7,d4
                neg     d4
                add     d0,d4
                add     d4,d4
                subq    #1,d4
                move    d4,d2
                ext.l   d2
                muls.l  d2,d3                   ;* actual x value
                moveq   #17,d2
                asr.l   d2,d3
                move    d3,a4
                move    #0,d4                   ;old height
                swap    d7
                move    PixelCount,d7           ;number of pixels
                subq    #1,d7
.loop2
                move.l  d6,d2
                move.l  d5,d0
                lsr.l   #16-_PICSIZE,d2
                swap    d0
                and.l   #(((1<<_PICSIZE)-1)<<_PICSIZE),d2
                and.l   #(1<<_PICSIZE)-1,d0
                or.l    d0,d2
                moveq   #0,d3
                move.b  0(a2,d2.l*2),d3         ;read pixel height from map
                add.l   a0,d6
                add.l   d1,d5
                move    0(a5,d3.w*2),d0         ;calc perspective height
                lea     256(a5),a5              ;new tab for new distance
                sub     a4,d0                   ;subtract HRot offset
                add     (a6)+,d0                ;add online perspective value
                sub     d4,d0                   ;calc height difference
                ble.b   .loopend
                add     d0,d4                   ;calc new height
                move.b  1(a2,d2.l*2),d3         ;read pixel color from map
                subq    #1,d0                   ;now draw the vertical bar
                move.b  d3,d2
                lsl     #8,d3
                move.b  d2,d3
.copy
                move    d3,(a3)
                addq.l  #4,a3
                dbra    d0,.copy
                dbra    d7,.loop2
                bra.b   .colOK
.approx
                subq    #1,d7
                bmi.b   .colOK
                lea     256(a5),a5
                addq.l  #2,a6
                add.l   a0,d6
                add.l   d1,d5
                dbra    d7,.loop2
                bra.b   .colOK
.loopend
                blt.b   .approx
                dbra    d7,.loop2
.colOK
                sub     AreaHeight,d4
                neg     d4                      ;area height - actual height
                move    d4,d0                   ;d0 = sky height to draw
                move    #-1,SKY_COUNT(a1)
                subq    #1,d0
                bmi.b   .jump                   ;no sky to draw -> jump
                swap    d4
                move    d4,d3                   ;get sky offset
                sub     a4,d3                   ;subtract hor. rotation value
                add     SkyHeight,d3
                sub     AreaHeight,d3           ;calc real sky offset
                muls    SkyWidth2,d3            ;mulitply by sky width
                move.l  d3,SKY_SOURCE(a1)       ;write sky offset
                move    d0,SKY_COUNT(a1)        ;write sky height
                swap    d4
.jump
                movem.l (sp)+,d0/a0/a5
                movem.l (sp)+,d2/d3/d5/d6/a0/a3
                addq.l  #2,a3                   ;next column
                lea     SKY_SIZE(a1),a1         ;next sky definition
                swap    d7

                btst    #0,d7
                bne.w   .loopend2
                move.l  d0,-(sp)
                move.l  ChunkyPtr,a4
                addq.l  #4,ChunkyPtr
                subq.l  #4,a3
                move    AreaHeight,d4
                subq    #2,d4
                move    -2*SKY_SIZE+SKY_COUNT(a1),d1
                move    -SKY_SIZE+SKY_COUNT(a1),d3
                move.l  DestOffset,d0
                cmp     d3,d1
                ble.b   .noexg1
                exg     d1,d3
.noexg1
                sub     d4,d1
                neg     d1
                tst     d1
                bmi.b   .nodraw
.copycol
                move.l  (a3)+,(a4)
                sub.l   d0,a4
                dbra    d1,.copycol
.nodraw
                move.l  TempBuffer,a3
                move.l  (sp)+,d0
.loopend2
                dbra    d7,.loop
                sub.l   a3,a3
                move.l  DestOffset,d5
                move    SkyWidth2,a3
                move.l  SkyBuffer,a1            ;a1 -> sky graphics
                move    Direction,d7            ;get direction
                mulu    SkyWidth2,d7
                divu    Ray_Count,d7            ;calc sky hor. position
                cmp     SkyWidth,d7             ;check for overflow
                blt.b   .cont
                sub     SkyWidth,d7
.cont
                add     d7,a1                   ;a1 -> sky start pos
                move.l  a1,d2
                move.l  SkyData,a0              ;a0 -> sky definition
                move.l  ChunkyBuffer,a2         ;a2 -> chunky buffer
                move.l  a2,d4
                move    ColumnCount,d7
                subq    #1,d7
.loop3
                move.l  SKY_SOURCE(a0),d0       ;get sky source offset
                move.l  d2,a1
                move.l  d4,a2
                add.l   d0,a1                   ;a1 -> sky start pos
                tst     d7                      ;if last turn
                beq.b   .normal                 ;then normal draw
                cmp.l   SKY_SOURCE+SKY_SIZE(a0),d0 ;next offset equal?
                bne.b   .normal                 ;no -> normal draw
                move    SKY_COUNT(a0),d6        ;sky height > 0 ?
                bmi.b   .next                   ;no -> no draw
                move    SKY_COUNT+SKY_SIZE(a0),d3 ;next sky height > 0?
                bmi.b   .next                   ;no -> no draw
                subq    #1,d7                   ;draw optimized
                moveq   #2,d0
                cmp     d3,d6                   ;compare sky heights
                ble.b   .noexg                  ;of both columns
                exg     d3,d6                   ;change if necessary
                moveq   #0,d0
.noexg
                move    d6,d1
.drawsky2
                move.l  (a1),(a2)               ;draw 2 columns at once
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky2
                sub     d1,d3                   ;subtract heights
                subq    #1,d3
                bmi.b   .next2                  ;equal -> done
                add.l   d0,a1
                add.l   d0,a2
.drawsky3
                move    (a1),(a2)               ;now draw the longer one
                add.l   d5,a2
                add.l   a3,a1
                dbra    d3,.drawsky3
.next2
                addq.l  #4,d2                   ;increase by 2 columns
                addq.l  #4,d4
                lea     SKY_SIZE*2(a0),a0
                dbra    d7,.loop3
                bra.b   .end
.normal
                move    SKY_COUNT(a0),d6        ;get sky height
                bmi.b   .next
.drawsky
                move    (a1),(a2)               ;draw one sky column
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky
.next
                addq.l  #2,d2                   ;next column
                addq.l  #2,d4
                lea     SKY_SIZE(a0),a0
                dbra    d7,.loop3
.end
                movem.l (sp)+,d0-a6
                rts
;;/
;// Calculation4 (calculates one voxelspace frame - column width 4)
******************************************************************************
*
*       Calculation4
*
*       calculates one voxelspace frame with column width = 4
*       the results are written into the chunkybuffer
*
******************************************************************************
Calculation4
                movem.l d0-a6,-(sp)
                move.l  HeightData,a0           ;a0 -> place for online persp.
                move    StartHeight,d0
                sub     ActualHeight,d0         ;calc difference to standard
                muls    ViewDistance,d0         ;perspective
                muls    AreaHeight,d0           ;dh * z * AreaHeight
                moveq   #0,d5
                move    MinRange,d5
                moveq   #0,d1
                move.b  PixCount,d1
                lsl.l   d1,d5                   ;pix count * min. range
                moveq   #0,d3
                move    Pix_Count,d7
                subq    #1,d7
.calc
                move.l  d3,d4
                move    MaxRange,d2
                sub     MinRange,d2
                mulu    d2,d4
                add.l   d5,d4
                divu    Pix_Count,d4            ;calc actual x position
                move    d4,d6
                add     ViewDistance,d4         ;x + z
                ext.l   d4
                move.l  d0,d1
                divsl.l d4,d1                   ;dh * z / (x + z) * AreaHeight
                divs    DispHeight,d1           ;d1 / Dispheight
                move    d1,(a0)+                ;store value
                addq    #1,d3
                dbra    d7,.calc
                move.l  MapFile+FILE_ADDRESS,a2 ;a2 -> map
                move.l  ChunkyBuffer,a3         ;a3 -> chunky buffer
                move    AreaHeight,d0
                subq    #1,d0
                moveq   #0,d1
                move    BitmapWidth,d1
                move.l  d1,a6
                mulu    d1,d0
                add.l   d0,a3                   ;a3 -> last line in chunky buf.

                move.l  ViewCircle,a0
                move.l  ViewAngle,a5
                move    Direction,d0
                moveq   #0,d1
                move    Ray_Count,d1
                move    d1,d2
                subq    #1,d2
                mulu    Angle,d1
                divu    #360*2,d1               ;subtract half angle from dir.
                sub     d1,d0                   ;d0 = starting ray
                and     d2,d0                   ;wrap around
                ext.l   d0
                lsl.l   #4,d0
                ext.l   d2
                lsl.l   #4,d2

                moveq   #0,d4
                move    ActualHeight,d4         ;get actual height
                moveq   #0,d3
                move.b  SkyScroll,d3
                divu    d3,d4                   ;calc sky scroll value
                sub     SkyPos,d4               ;subtract offset
                neg     d4
                swap    d4
                move.l  a6,DestOffset
                move.l  SkyData,a1              ;a1 -> sky definition

                moveq   #9,d7
                move.l  PosXDet,d5
                lsl.l   d7,d5
                move.l  PosYDet,d6
                lsl.l   d7,d6

                move    ColumnCount,d7          ;number of columns
                subq    #1,d7
.loop
                movem.l d2/d3/d5/d6/a0/a3,-(sp)
                add.l   (a5)+,d0                ;jump to next ray
                and.l   d2,d0                   ;mask out
                add.l   d0,a0                   ;a0 -> new view circle
                add.l   (a0)+,d6
                add.l   (a0)+,d5
                move.l  (a0)+,d3
                move.l  (a0)+,d1
                movem.l d0/a0/a5,-(sp)
                move.l  d3,a0
                move.l  Perspective,a5          ;a5 -> perspective
                move.l  HeightData,a6           ;a1 -> online perspective
                moveq   #0,d3
                move    HRotActual,d3           ;hor. rotation value
                ext.l   d3
                asl.l   #8,d3
                moveq   #0,d0
                move    ColumnCount,d0
                lsr     #1,d0
                divsl.l d0,d3                   ;/ half column count
                move    d7,d4
                neg     d4
                add     d0,d4
                add     d4,d4
                subq    #1,d4
                move    d4,d2
                ext.l   d2
                muls.l  d2,d3                   ;* actual x value
                moveq   #17,d2
                asr.l   d2,d3
                move    d3,a4

                move    #0,d4                   ;old height
                swap    d7
                move    PixelCount,d7           ;number of pixels
                subq    #1,d7
.loop2
                move.l  d6,d2
                move.l  d5,d0
                lsr.l   #16-_PICSIZE,d2
                swap    d0
                and.l   #(((1<<_PICSIZE)-1)<<_PICSIZE),d2
                and.l   #(1<<_PICSIZE)-1,d0
                or.l    d0,d2
                moveq   #0,d3
                move.b  0(a2,d2.l*2),d3         ;read pixel height from map
                add.l   a0,d6
                add.l   d1,d5
                move    0(a5,d3.w*2),d0         ;calc perspective height
                lea     256(a5),a5              ;new tab for new distance
                sub     a4,d0                   ;subtract HRot offset
                add     (a6)+,d0                ;add online perspective value
                sub     d4,d0                   ;calc height difference
                ble.b   .loopend
                add     d0,d4                   ;calc new height
                move.b  1(a2,d2.l*2),d3         ;read pixel color from map
                cmp     AreaHeight,d4
                bge.b   .cut
                subq    #1,d0                   ;now draw the vertical bar
                move.b  d3,d2
                lsl     #8,d3
                move.b  d2,d3
                lsl.l   #8,d3
                move.b  d2,d3
                lsl.l   #8,d3
                move.b  d2,d3
                move.l  DestOffset,d2
.copy
                move.l  d3,(a3)
                sub.l   d2,a3                   ;subtract one line
                dbra    d0,.copy
.loopend
                dbra    d7,.loop2
                bra.b   .colOK
.cut
                sub     AreaHeight,d4
                sub     d4,d0                   ;correct bar height to draw
                beq.b   .zero
                subq    #1,d0
                move.b  d3,d2
                lsl     #8,d3
                move.b  d2,d3
                lsl.l   #8,d3
                move.b  d2,d3
                lsl.l   #8,d3
                move.b  d2,d3
                move.l  DestOffset,d2
.copy2
                move.l  d3,(a3)
                sub.l   d2,a3
                dbra    d0,.copy2
.zero
                move    #-1,SKY_COUNT(a1)       ;no sky
                bra.b   .jump                   ;column done
.colOK
                sub     AreaHeight,d4
                neg     d4                      ;area height - actual height
                move    d4,d0                   ;d0 = sky height to draw
                move    #-1,SKY_COUNT(a1)
                subq    #1,d0
                bmi.b   .jump                   ;no sky to draw -> jump
                swap    d4
                move    d4,d3                   ;get sky offset
                sub     a4,d3                   ;subtract hor. rotation value
                add     SkyHeight,d3
                sub     AreaHeight,d3           ;calc real sky offset
                muls    SkyWidth2,d3            ;mulitply by sky width
                move.l  d3,SKY_SOURCE(a1)       ;write sky offset
                move    d0,SKY_COUNT(a1)        ;write sky height
                swap    d4
.jump
                movem.l (sp)+,d0/a0/a5
                movem.l (sp)+,d2/d3/d5/d6/a0/a3
                addq.l  #4,a3                   ;next column
                lea     SKY_SIZE(a1),a1         ;next sky definition
                swap    d7
                dbra    d7,.loop
                sub.l   a3,a3
                move.l  DestOffset,d5
                move    SkyWidth2,a3
                move.l  SkyBuffer,a1            ;a1 -> sky graphics
                move    Direction,d7            ;get direction
                mulu    SkyWidth2,d7
                divu    Ray_Count,d7            ;calc sky hor. position
                cmp     SkyWidth,d7             ;check for overflow
                blt.b   .cont
                sub     SkyWidth,d7
.cont
                add     d7,a1                   ;a1 -> sky start pos
                move.l  a1,d2
                move.l  SkyData,a0              ;a0 -> sky definition
                move.l  ChunkyBuffer,a2         ;a2 -> chunky buffer
                move.l  a2,d4
                move    ColumnCount,d7
                subq    #1,d7
.loop3
                move.l  SKY_SOURCE(a0),d0       ;get sky source offset
                move.l  d2,a1
                move.l  d4,a2
                add.l   d0,a1                   ;a1 -> sky start pos
                tst     d7                      ;if last turn
                beq.b   .normal                 ;then normal draw
                cmp.l   SKY_SOURCE+SKY_SIZE(a0),d0 ;next offset equal?
                bne.b   .normal                 ;no -> normal draw
                move    SKY_COUNT(a0),d6        ;sky height > 0 ?
                bmi.b   .next                   ;no -> no draw
                move    SKY_COUNT+SKY_SIZE(a0),d3 ;next sky height > 0?
                bmi.b   .next                   ;no -> no draw
                subq    #1,d7                   ;draw optimized
                moveq   #4,d0
                cmp     d3,d6                   ;compare sky heights
                ble.b   .noexg                  ;of both columns
                exg     d3,d6                   ;change if necessary
                moveq   #0,d0
.noexg
                move    d6,d1
.drawsky2
                move.l  (a1),(a2)               ;draw 2 columns at once
                move.l  4(a1),4(a2)             ;draw 2 columns at once
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky2
                sub     d1,d3                   ;subtract heights
                subq    #1,d3
                bmi.b   .next2                  ;equal -> done
                add.l   d0,a1
                add.l   d0,a2
.drawsky3
                move.l  (a1),(a2)               ;now draw the longer one
                add.l   d5,a2
                add.l   a3,a1
                dbra    d3,.drawsky3
.next2
                addq.l  #8,d2                   ;increase by 2 columns
                addq.l  #8,d4
                lea     SKY_SIZE*2(a0),a0
                dbra    d7,.loop3
                bra.b   .end
.normal
                move    SKY_COUNT(a0),d6        ;get sky height
                bmi.b   .next
.drawsky
                move.l  (a1),(a2)               ;draw one sky column
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky
.next
                addq.l  #4,d2                   ;next column
                addq.l  #4,d4
                lea     SKY_SIZE(a0),a0
                dbra    d7,.loop3
.end
                movem.l (sp)+,d0-a6
                rts
;;/
;// Calculation4_A (calculates one voxelspace frame - column width 4)
******************************************************************************
*
*       Calculation4_A
*
*       calculates one voxelspace frame with column width = 4
*       the results are written into the chunkybuffer
*       approximation routine
*
******************************************************************************
Calculation4_A
                movem.l d0-a6,-(sp)
                move.l  HeightData,a0           ;a0 -> place for online persp.
                move    StartHeight,d0
                sub     ActualHeight,d0         ;calc difference to standard
                muls    ViewDistance,d0         ;perspective
                muls    AreaHeight,d0           ;dh * z * AreaHeight
                moveq   #0,d5
                move    MinRange,d5
                moveq   #0,d1
                move.b  PixCount,d1
                lsl.l   d1,d5                   ;pix count * min. range
                moveq   #0,d3
                move    Pix_Count,d7
                subq    #1,d7
.calc
                move.l  d3,d4
                move    MaxRange,d2
                sub     MinRange,d2
                mulu    d2,d4
                add.l   d5,d4
                divu    Pix_Count,d4            ;calc actual x position
                move    d4,d6
                add     ViewDistance,d4         ;x + z
                ext.l   d4
                move.l  d0,d1
                divsl.l d4,d1                   ;dh * z / (x + z) * AreaHeight
                divs    DispHeight,d1           ;d1 / Dispheight
                move    d1,(a0)+                ;store value
                addq    #1,d3
                dbra    d7,.calc
                move.l  MapFile+FILE_ADDRESS,a2 ;a2 -> map
                move.l  ChunkyBuffer,a3         ;a3 -> chunky buffer
                move    AreaHeight,d0
                subq    #1,d0
                moveq   #0,d1
                move    BitmapWidth,d1
                move.l  d1,a6
                mulu    d1,d0
                add.l   d0,a3                   ;a3 -> last line in chunky buf.

                move.l  ViewCircle,a0
                move.l  ViewAngle,a5
                move    Direction,d0
                moveq   #0,d1
                move    Ray_Count,d1
                move    d1,d2
                subq    #1,d2
                mulu    Angle,d1
                divu    #360*2,d1               ;subtract half angle from dir.
                sub     d1,d0                   ;d0 = starting ray
                and     d2,d0                   ;wrap around
                ext.l   d0
                lsl.l   #4,d0
                ext.l   d2
                lsl.l   #4,d2

                moveq   #0,d4
                move    ActualHeight,d4         ;get actual height
                moveq   #0,d3
                move.b  SkyScroll,d3
                divu    d3,d4                   ;calc sky scroll value
                sub     SkyPos,d4               ;subtract offset
                neg     d4
                swap    d4
                move.l  a6,DestOffset
                move.l  SkyData,a1              ;a1 -> sky definition

                moveq   #9,d7
                move.l  PosXDet,d5
                lsl.l   d7,d5
                move.l  PosYDet,d6
                lsl.l   d7,d6

                move    ColumnCount,d7          ;number of columns
                subq    #1,d7
.loop
                movem.l d2/d3/d5/d6/a0/a3,-(sp)
                add.l   (a5)+,d0                ;jump to next ray
                and.l   d2,d0                   ;mask out
                add.l   d0,a0                   ;a0 -> new view circle
                add.l   (a0)+,d6
                add.l   (a0)+,d5
                move.l  (a0)+,d3
                move.l  (a0)+,d1
                movem.l d0/a0/a5,-(sp)
                move.l  d3,a0
                move.l  Perspective,a5          ;a5 -> perspective
                move.l  HeightData,a6           ;a1 -> online perspective
                moveq   #0,d3
                move    HRotActual,d3           ;hor. rotation value
                ext.l   d3
                asl.l   #8,d3
                moveq   #0,d0
                move    ColumnCount,d0
                lsr     #1,d0
                divsl.l d0,d3                   ;/ half column count
                move    d7,d4
                neg     d4
                add     d0,d4
                add     d4,d4
                subq    #1,d4
                move    d4,d2
                ext.l   d2
                muls.l  d2,d3                   ;* actual x value
                moveq   #17,d2
                asr.l   d2,d3
                move    d3,a4

                move    #0,d4                   ;old height
                swap    d7
                move    PixelCount,d7           ;number of pixels
                subq    #1,d7
.loop2
                move.l  d6,d2
                move.l  d5,d0
                lsr.l   #16-_PICSIZE,d2
                swap    d0
                and.l   #(((1<<_PICSIZE)-1)<<_PICSIZE),d2
                and.l   #(1<<_PICSIZE)-1,d0
                or.l    d0,d2
                moveq   #0,d3
                move.b  0(a2,d2.l*2),d3         ;read pixel height from map
                add.l   a0,d6
                add.l   d1,d5
                move    0(a5,d3.w*2),d0         ;calc perspective height
                lea     256(a5),a5              ;new tab for new distance
                sub     a4,d0                   ;subtract HRot offset
                add     (a6)+,d0                ;add online perspective value
                sub     d4,d0                   ;calc height difference
                ble.b   .loopend
                add     d0,d4                   ;calc new height
                move.b  1(a2,d2.l*2),d3         ;read pixel color from map
                cmp     AreaHeight,d4
                bge.b   .cut
                subq    #1,d0                   ;now draw the vertical bar
                move.b  d3,d2
                lsl     #8,d3
                move.b  d2,d3
                lsl.l   #8,d3
                move.b  d2,d3
                lsl.l   #8,d3
                move.b  d2,d3
                move.l  DestOffset,d2
.copy
                move.l  d3,(a3)
                sub.l   d2,a3                   ;subtract one line
                dbra    d0,.copy
                dbra    d7,.loop2
                bra.b   .colOK
.approx
                subq    #1,d7
                bmi.b   .colOK
                lea     256(a5),a5
                addq.l  #2,a6
                add.l   a0,d6
                add.l   d1,d5
                dbra    d7,.loop2
                bra.b   .colOK
.loopend
                blt.b   .approx
                dbra    d7,.loop2
                bra.b   .colOK
.cut
                sub     AreaHeight,d4
                sub     d4,d0                   ;correct bar height to draw
                beq.b   .zero
                subq    #1,d0
                move.b  d3,d2
                lsl     #8,d3
                move.b  d2,d3
                lsl.l   #8,d3
                move.b  d2,d3
                lsl.l   #8,d3
                move.b  d2,d3
                move.l  DestOffset,d2
.copy2
                move.l  d3,(a3)
                sub.l   d2,a3
                dbra    d0,.copy2
.zero
                move    #-1,SKY_COUNT(a1)       ;no sky
                bra.b   .jump                   ;column done
.colOK
                sub     AreaHeight,d4
                neg     d4                      ;area height - actual height
                move    d4,d0                   ;d0 = sky height to draw
                move    #-1,SKY_COUNT(a1)
                subq    #1,d0
                bmi.b   .jump                   ;no sky to draw -> jump
                swap    d4
                move    d4,d3                   ;get sky offset
                sub     a4,d3                   ;subtract hor. rotation value
                add     SkyHeight,d3
                sub     AreaHeight,d3           ;calc real sky offset
                muls    SkyWidth2,d3            ;mulitply by sky width
                move.l  d3,SKY_SOURCE(a1)       ;write sky offset
                move    d0,SKY_COUNT(a1)        ;write sky height
                swap    d4
.jump
                movem.l (sp)+,d0/a0/a5
                movem.l (sp)+,d2/d3/d5/d6/a0/a3
                addq.l  #4,a3                   ;next column
                lea     SKY_SIZE(a1),a1         ;next sky definition
                swap    d7
                dbra    d7,.loop
                sub.l   a3,a3
                move.l  DestOffset,d5
                move    SkyWidth2,a3
                move.l  SkyBuffer,a1            ;a1 -> sky graphics
                move    Direction,d7            ;get direction
                mulu    SkyWidth2,d7
                divu    Ray_Count,d7            ;calc sky hor. position
                cmp     SkyWidth,d7             ;check for overflow
                blt.b   .cont
                sub     SkyWidth,d7
.cont
                add     d7,a1                   ;a1 -> sky start pos
                move.l  a1,d2
                move.l  SkyData,a0              ;a0 -> sky definition
                move.l  ChunkyBuffer,a2         ;a2 -> chunky buffer
                move.l  a2,d4
                move    ColumnCount,d7
                subq    #1,d7
.loop3
                move.l  SKY_SOURCE(a0),d0       ;get sky source offset
                move.l  d2,a1
                move.l  d4,a2
                add.l   d0,a1                   ;a1 -> sky start pos
                tst     d7                      ;if last turn
                beq.b   .normal                 ;then normal draw
                cmp.l   SKY_SOURCE+SKY_SIZE(a0),d0 ;next offset equal?
                bne.b   .normal                 ;no -> normal draw
                move    SKY_COUNT(a0),d6        ;sky height > 0 ?
                bmi.b   .next                   ;no -> no draw
                move    SKY_COUNT+SKY_SIZE(a0),d3 ;next sky height > 0?
                bmi.b   .next                   ;no -> no draw
                subq    #1,d7                   ;draw optimized
                moveq   #4,d0
                cmp     d3,d6                   ;compare sky heights
                ble.b   .noexg                  ;of both columns
                exg     d3,d6                   ;change if necessary
                moveq   #0,d0
.noexg
                move    d6,d1
.drawsky2
                move.l  (a1),(a2)               ;draw 2 columns at once
                move.l  4(a1),4(a2)             ;draw 2 columns at once
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky2
                sub     d1,d3                   ;subtract heights
                subq    #1,d3
                bmi.b   .next2                  ;equal -> done
                add.l   d0,a1
                add.l   d0,a2
.drawsky3
                move.l  (a1),(a2)               ;now draw the longer one
                add.l   d5,a2
                add.l   a3,a1
                dbra    d3,.drawsky3
.next2
                addq.l  #8,d2                   ;increase by 2 columns
                addq.l  #8,d4
                lea     SKY_SIZE*2(a0),a0
                dbra    d7,.loop3
                bra.b   .end
.normal
                move    SKY_COUNT(a0),d6        ;get sky height
                bmi.b   .next
.drawsky
                move.l  (a1),(a2)               ;draw one sky column
                add.l   d5,a2
                add.l   a3,a1
                dbra    d6,.drawsky
.next
                addq.l  #4,d2                   ;next column
                addq.l  #4,d4
                lea     SKY_SIZE(a0),a0
                dbra    d7,.loop3
.end
                movem.l (sp)+,d0-a6
                rts
;;/
;// ChunkyToPlanar (converts chunky data to bitplane data)

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

******************************************************************************
*
*       ChunkyToPlanar
*
*       converts chunky data into bitplane data (using Bitmap Structure)
*       works ONLY with a depth of 8!
*       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)
*
******************************************************************************
ChunkyToPlanar
                movem.l d0-a6,-(sp)
                sub.w   #40,sp          ; space for temporary variables

                move.l  #256*40,d2
                move.l  ChunkyBuffer,a0
                move.l  HiddenBitmap,a1
                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
                move    AreaHeight,d2
                mulu    #320,d2
                add.l   d2,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
;;/


