*  flip.s
*  5 Apr 87
*
*  Written by Mike Berro of BCS Software
*  (818) 362-6031  CIS: [73267,3361]
*  Based on tilt.c by Leo L. Schwab
*  I hacked this together in 2 hours; C into assembly is no problem!
*  It is slow because of the need to flip individual bits left to right.
*    It'd be a LOT slower in C!  Is there a faster way to do the flip?
*  How about turning the display sideways?
*  You can insert your own effects in the effects subroutine.

   INCLUDE "exec/types.i"
   INCLUDE "exec/nodes.i"
   INCLUDE "exec/lists.i"
   INCLUDE "exec/ports.i"
   INCLUDE "exec/libraries.i"
   INCLUDE "exec/tasks.i"
   INCLUDE "intuition/intuition.i"
   INCLUDE "graphics/display.i"
   INCLUDE "graphics/gfxbase.i"

   XREF _AbsExecBase

   XREF _LVOOpenLibrary          ;intuition
   XREF _LVOCloseLibrary
   XREF _LVOOpenWindow
   XREF _LVOCloseWindow
   XREF _LVOOpenScreen
   XREF _LVOCloseScreen
   XREF _LVOScreenToFront
   XREF _LVOScreenToBack
   XREF _LVODisplayAlert

   XREF _LVOBltBitMap            ;graphics

   moveq.l  #101,d6              ;d6 is the error flag: 101=can't open Intui
   lea      IntuitionName,a1
   moveq.l  #0,d0
   movea.l  _AbsExecBase,a6
   jsr      _LVOOpenLibrary(a6)
   move.l   d0,IntuitionBase
   beq      all_done
   addq.l   #1,d6                ;102=can't open Graphics Library
   lea      GraphicsName,a1
   moveq.l  #0,d0
   movea.l  _AbsExecBase,a6
   jsr      _LVOOpenLibrary(a6)
   move.l   d0,GraphicsBase
   beq      all_done

   addq.l   #1,d6                ;103=can't open window
   lea      MyNewWindow,a0
   movea.l  IntuitionBase,a6
   jsr      _LVOOpenWindow(a6)
   move.l   d0,MyWindow
   beq      all_done

   addq.l   #1,d6                      ;104=can't open screen
   move.l   MyWindow,a0
   move.l   wd_WScreen(a0),a1          ;a1 points to WBench screen
   move.l   sc_RastPort+rp_BitMap(a1),wbm  ;points to Workbench BitMap structure
   lea      MyNewScreen,a0
   move.w   sc_LeftEdge(a1),ns_LeftEdge(a0)
   move.w   sc_TopEdge(a1),ns_TopEdge(a0)
   moveq.l  #0,d4
   move.w   sc_Width(a1),d4            ;save for BltBitMap
   move.w   d4,ns_Width(a0)
   moveq.l  #0,d5
   move.w   sc_Height(a1),d5           ;save for BltBitMap
   move.w   d5,ns_Height(a0)
   move.w   sc_ViewPort+vp_Modes(a1),ns_ViewModes(a0)
   jsr      _LVOOpenScreen(a6)
   move.l   d0,MyScreen
   beq      all_done

   move.l   d0,a0
   jsr      _LVOScreenToBack(a6)

   move.l   MyScreen,a1
   move.l   sc_RastPort+rp_BitMap(a1),a1  ;my BitMap
   move.l   a1,a2
   adda.l   #bm_Planes,a2
   move.l   (a2)+,Plane1            ;points to actual video memory
   move.l   (a2)+,Plane2
   move.l   wbm,a0                  ;WB's BitMap
   moveq.l  #0,d0                   ;faster than clr.l
   moveq.l  #0,d1
   moveq.l  #0,d2
   moveq.l  #0,d3
   move.l   #$c0,d6
   move.l   #$ff,d7
   move.l   #0,a2
   movea.l  GraphicsBase,a6
   jsr      _LVOBltBitMap(a6)       ;copy WB onto my custom screen

   movea.l  Plane1,a0
   bsr      do_flip              ;do the effect on plane1
   movea.l  Plane2,a0
   bsr      do_flip              ;and on plane 2

   movea.l  MyScreen,a0
   movea.l  IntuitionBase,a6
   jsr      _LVOScreenToFront(a6)      ;show it

   move.l  #800000,d0
lp_delay:
   subq.l   #1,d0
   bne.s    lp_delay

   move.l   #RECOVERY_ALERT,d0
   lea      message,a0
   moveq.l  #30,d1
   jsr      _LVODisplayAlert(a6)       ;pseudo-guru

   moveq.l  #0,d6                   ;no error

all_done:
   movea.l  IntuitionBase,a6
   tst.l    MyScreen
   beq.s    2$
   movea.l  MyScreen,a0
   jsr      _LVOCloseScreen(a6)
2$:
   tst.l    MyWindow
   beq.s    3$
   movea.l  MyWindow,a0
   jsr      _LVOCloseWindow(a6)
3$:
   move.l   _AbsExecBase,a6
   tst.l    GraphicsBase
   beq.s    4$
   move.l   GraphicsBase,a1
   jsr      _LVOCloseLibrary(a6)
4$:
   tst.l    IntuitionBase
   beq.s    5$
   move.l   IntuitionBase,a1
   jsr      _LVOCloseLibrary(a6)
5$:
   move.l   d6,d0
   rts

**************** Effects subroutine

do_flip:
   move.l   a0,a1
   add.l    #16000,a1
   move.l   #100,d0           ;# lines
lp_flip1:
   move.l   #20,d1            ;# long words per line
lp_flip2:
   move.l   (a0),d2
   bsr      sideflip
   move.l   -(a1),d2
   move.l   d5,(a1)
   bsr      sideflip
   move.l   d5,(a0)+
   subq.l   #1,d1
   bne.s    lp_flip2
   subq.l   #1,d0
   bne.s    lp_flip1
   rts

sideflip:
   moveq.l  #0,d5             ;clear the target
   moveq.l  #31,d3            ;source bit number index
   moveq.l  #0,d4             ;target "   "      "
lp_sideflip:
   btst.l   d3,d2
   beq.s    1$
   bset.l   d4,d5
1$:
   addq.l   #1,d4
   subq.l   #1,d3
   bpl.s    lp_sideflip
   rts

   SECTION fdata,DATA

IntuitionBase: dc.l  0
GraphicsBase:  dc.l  0

MyWindow:      dc.l  0
MyScreen:      dc.l  0
wbm:           dc.l  0
Plane1:        dc.l  0
Plane2:        dc.l  0

**************** Screen data

MyNewScreen:  dc.w 0,0,0,0   ;size filled in later
              dc.w 2      ;depth
              dc.b 0,1
              dc.w 0      ;viewmodes filled in later
              dc.w CUSTOMSCREEN
              dc.l 0
              dc.l 0      ;screen title
              dc.l 0,0

**************** Window data

MyFlags       EQU SMART_REFRESH!ACTIVATE!WINDOWDEPTH!WINDOWDRAG
MyNewWindow:  dc.w 0,30,100,10
              dc.b -1,-1
              dc.l 0
              dc.l MyFlags
              dc.l 0,0
              dc.l MyTitle
              dc.l 0,0
              dc.w 0,0,0,0
              dc.w WBENCHSCREEN

MyTitle:
   dc.b  'Flip',0
IntuitionName:
   dc.b  'intuition.library',0
GraphicsName:
   dc.b  'graphics.library',0
message:
   dc.b  1,34,22
   dc.b  'Flipped Out!',0

   END

