      INCLUDE "EXEC/TYPES.I"

      INCLUDE "GRAPHICS/GFXBASE.I"
      INCLUDE "GRAPHICS/GFX.I"
      INCLUDE "GRAPHICS/VIEW.I"
      INCLUDE "GRAPHICS/RASTPORT.I"

 XREF  AbsExecBase             ;library references
 XREF  LVOCloseLibrary
 XREF  LVOOpenLibrary
 XREF  LVOInitView
 XREF  LVOLoadView
 XREF  LVOInitBitMap
 XREF  LVOFreeRaster
 XREF  LVOFreeColorMap
 XREF  LVOFreeVPortCopLists
 XREF  LVOAllocRaster
 XREF  LVOMakeVPort
 XREF  LVOMrgCop
 XREF  LVOInitVPort
 XREF  LVOGetColorMap
 XREF  LVOWaitTOF
 XREF  LVOLoadRGB4
 XREF  LVOExit
 XREF  LVOInitRastPort
 XREF  LVOSetAPen
 XREF  LVORectFill
 XREF  LVOBltBitMap


                               ;routines from stix.o 
 XREF  _xmove                  ;x movement flag, stick 1
 XREF  _ymove                  ;y movement flag, stick 1 
 XREF  _xmove2                 ;x movement flag, stick 2 
 XREF  _ymove2                 ;y movement flag, stick 2
 XREF  _fire                   ;fire button flag, stick 1
 XREF  _fire2                  ;fire button flag, stick 2  
 XREF  _playsig                ;read joystick routine
  

                               ;routines in iffread2.o
 XREF  _test2                  ;Delay(parameter)
 XREF  _readfile               ;readfile(filename,bitmap,colourlist)
 
 XDEF  _main                   ;linker needed this as an external reference


  ;I used the -u underscore option when linking from an assembled object
  ;module to a C module.         I also found that 
  ; the program would not run if I used the a4 register at all!
  ;even if I preserved it at the beginning and restored it at the end.
  ;I used the Lattice Assembler, the DevPak syntax may be different

 CSECT  text,code
 _main:
  jsr     openlibraries         ;for graphics library
  move.l  graphicsbase,a6
  move.l  gb_ActiView(a6),d0
  movem.l d0,oldview            ;save old view address
  jsr     init                  ;initialise view
  lea     viewport,a0           ;load colours to clear the screen
  lea     colourlist,a1
  move.l  #16,d0              
  move.l  graphicsbase,a6     
  jsr     LVOLoadRGB4(a6)
  jsr     remake                ;load the display
  move.l  #filename,d0          ;in this case piccy
  move.l  #BMpix,d1             ;initialised bitmap
  move.l  #colourlist,d2        ;list for colours
  movem.l d0-d2,-(sp)
  jsr     _readfile             ;read the iff file using C module iffread2
  movem.l (sp)+,d0-d2
  lea     viewport,a0           ;load colours from colourlist
  lea     colourlist,a1
  move.l  #16,d0   
  move.l  graphicsbase,a6     
  jsr     LVOLoadRGB4(a6)
  jsr     stripes               ;put striped background in place 
  clr.l   xpos                  ;initialise coordinates 
  clr.l   ypos
  clr.l   sourcexpos
  clr.l   sourceypos 
  clr.l   oldscenexpos
  clr.l   oldsceneypos
  clr.l   oldbufferxpos
  clr.l   oldbufferypos
  clr.l   sourcexoffset
  clr.l   sourcexstart
  jsr     scenetostore 
  jsr     buffertostore
loop:
  move.l  #5,d0                ;put delay time on the stack                  
  movem.l d0,-(sp)             ;call delay from C module 
  jsr     _test2
  movem.l (sp)+,d0             ;tidy the stack

  jsr     _playsig             ;call joystick routine from other Assembler
                               ;module
  clr.l   d1
  clr.l   d0
  add.l   _xmove,d0
  add.l   _xmove2,d0
  tst.l   d0                   ;test for x movement
  beq     vertical
  blt     left
  move.l  #160,sourcexstart    ;teddy looking to the right
  move.l  #0,sourceypos
  cmp.l   #286,xpos            ;make sure he is still on the screen
  beq     out
  add.l   #2,xpos
  bra     out
left:
  move.l  #160,sourcexstart    ;teddy looking to the left
  move.l  #37,sourceypos
  cmp.l   #0,xpos              ;make sure he is still on the screen
  beq     out
  sub.l   #2,xpos                
  bra     out
vertical:
  add.l   _ymove,d1              
  add.l   _ymove2,d1            
  tst.l   d1                    ;test for y movement
  beq     out
  blt     up                    ;teddy going down
  move.l  #0,sourcexstart
  move.l  #0,sourceypos
  cmp.l   #216,ypos             ;make sure he is still on the screen
  beq     out 
  add.l   #2,ypos               
  bra     out 
up:
  clr.l   d1
  move.l  #0,sourcexstart      ;teddy climbing up 
  move.l  #37,sourceypos
  cmp.l   #0,ypos              ;make sure he is still on the screen
  beq     out
  sub.l   #2,ypos               
out:                           ;take the next movement picture
  add.l   #32,sourcexoffset    ;in the series
  cmp.l   #160,sourcexoffset   ;to dive the source offset
  blt     offsetnonzero
  move.l  #32,sourcexoffset
offsetnonzero:
  move.l  sourcexoffset,d1     ;calculate the source x position
  add.l   sourcexstart,d1
  move.l  d1,sourcexpos
  add.l   #1,count             ;check for odd or even cycle
  move.l  count,d0
  and.l   #1,d0
  beq     drawinbuffer         ;update the picture in the screen
  jsr     storetoscene         ;copy background in store to old space
  jsr     scenetostore         ;copy new space background to store  
  move.l  xpos,oldscenexpos    ;update old screen positions  
  move.l  ypos,oldsceneypos
  lea     BMscene,a1
  jsr     maskon               ;copy appropriate mask to screen
  lea     BMscene,a1 
  jsr     picon                ;copy appropriate picture to screen
  lea     viewport,a5          ;remake the display, showing screen bitmap
  move.l  #riscene,d0
  move.l  d0,vp_RasInfo(a5)
  jsr     remake
  bra     testforfire
drawinbuffer:                   ;updatethe picture in the buffer 
  jsr     storetobuffer        ;copy background in buffer to old space  
  jsr     buffertostore        ;copy new space background to store
  move.l  xpos,oldbufferxpos   ;update old buffer positions
  move.l  ypos,oldbufferypos
  lea     BMbuffer,a1
  jsr     maskon               ;copy appropriate mask to buffer
  lea     BMbuffer,a1
  jsr     picon                ;copy appropriate picture to buffer    
  lea     viewport,a5
  move.l  #ribuffer,d0          ;remake the display, showing the buffer bitmap
  move.l  d0,vp_RasInfo(a5)
  jsr     remake

testforfire:
  tst.l   _fire2               ;test for a fire button pressed
  bne     finish
  tst.l   _fire
  beq     loop
finish:
  move.l  oldview,a1           ;replace old view
  move.l  graphicsbase,a6 
  jsr     LVOLoadView(a6) 
  jsr     cleanup              ;release memory 
  jsr     closelibraries
  rts

maskon:
  move.l  xpos,d2               ;destination x coord
  move.l  ypos,d3               ;destination y coord
  move.l  sourcexpos,d0         ;source x coord  
  move.l  sourceypos,d1         ;source y coord
  add.l   #74,d1                ;y offset for mask position
  move.l  #32,d4                ;width 
  move.l  #37,d5                ;height
  move.l  #$20,d6               ;minterm
  move.l  #$ff,d7               ;mask
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMpix,a0              ;source bit map
  move.l  graphicsbase,a6
  jsr     LVOBltBitMap(a6)
  rts

picon:
  move.l  xpos,d2               ;destination x coord 
  move.l  ypos,d3               ;destination y coord
  move.l  sourcexpos,d0         ;source x coord  
  move.l  sourceypos,d1         ;source y coord
  move.l  #32,d4                ;width 
  move.l  #37,d5                ;height
  move.l  #$60,d6               ;minterm
  move.l  #$ff,d7               ;mask
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMpix,a0              ;source bit map
  move.l  graphicsbase,a6
  jsr     LVOBltBitMap(a6)
  rts
storetoscene:
  move.l  oldscenexpos,d2       ;destination x position
  move.l  oldsceneypos,d3       ;destination y position
  lea     BMscene,a1            ;destination bit map
  move.l  #0,d0                 ;source x coord  
  move.l  #168,d1               ;source y coord
  move.l  #32,d4                ;width 
  move.l  #37,d5                ;height
  move.l  #$c0,d6               ;minterm
  move.l  #$ff,d7               ;mask
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMpix,a0              ;source bit map
  move.l  graphicsbase,a6
  jsr     LVOBltBitMap(a6)
  rts
scenetostore:
  move.l  xpos,d0
  move.l  ypos,d1
  lea     BMscene,a0            ;destination bit map
  move.l  #0,d2                 ;source x coord  
  move.l  #168,d3                 ;source y coord
  move.l  #32,d4                ;width 
  move.l  #37,d5                ;height
  move.l  #$c0,d6               ;minterm
  move.l  #$ff,d7               ;mask
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMpix,a1              ;source bit map
  move.l  graphicsbase,a6
  jsr     LVOBltBitMap(a6)
  rts
storetobuffer:
  move.l  oldbufferxpos,d2
  move.l  oldbufferypos,d3
  lea     BMbuffer,a1           ;destination bit map
  move.l  #32,d0                 ;source x coord  
  move.l  #168,d1                 ;source y coord
  move.l  #32,d4                ;width 
  move.l  #37,d5                ;height
  move.l  #$c0,d6               ;minterm
  move.l  #$ff,d7               ;mask
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMpix,a0              ;source bit map
  move.l  graphicsbase,a6
  jsr     LVOBltBitMap(a6)
  rts
buffertostore:
  move.l  xpos,d0               ;source x position 
  move.l  ypos,d1               ;source y position
  lea     BMbuffer,a0           ;destination bit map
  move.l  #32,d2                ;source x coord  
  move.l  #168,d3               ;source y coord
  move.l  #32,d4                ;width 
  move.l  #37,d5                ;height
  move.l  #$c0,d6               ;minterm
  move.l  #$ff,d7               ;mask
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMpix,a1              ;source bit map
  move.l  graphicsbase,a6
  jsr     LVOBltBitMap(a6)
  rts

remake:                        ;remakes the display
  move.l  graphicsbase,a6      ;the display could be made any which way
  lea     view,a0              ;you want
  lea     viewport,a1
  jsr     LVOMakeVPort(a6)
  lea     view,a1
  jsr     LVOMrgCop(a6)
  jsr     LVOWaitTOF(a6)
  lea     view,a1
  jsr     LVOLoadView(a6)
  rts
  
init:                          ;if you are not using graphics primitives
  move.l  graphicsbase,a6      ;all you need do here is set up a bitmap 
  lea     view,a1              ;structure, poking the values in directly
  jsr     LVOInitView(a6)
  lea     viewport,a0
  jsr     LVOInitVPort(a6)     ;initialises viewport(NTSC) viewport
  lea     view,a5
  move.l  #viewport,d0
  move.l  d0,v_ViewPort(a5)
  lea     BMscene,a0           ;bitmap 
  move.b  #4,d0                ;playfield 1 320x256 fixed
  move.w  #320,d1
  move.w  #256,d2
  jsr     LVOInitBitMap(a6)
  move.l  #BMscene,d0
  lea     riscene,a5           ;rasinfo
  move.l  d0,ri_BitMap(a5)
  move.w  #0,ri_RxOffset(a5)
  move.w  #0,ri_RyOffset(a5)
  move.l  #0,ri_Next(a5)
  lea     viewport,a5          ;viewport parameters
  move.w  #320,vp_DWidth(a5)
  move.w  #256,vp_DHeight(a5)
  move.w  #0,vp_DyOffset(a5)   ;centred
  move.w  #-2,vp_DxOffset(a5)
  move.l  #riscene,d0
  move.l  d0,vp_RasInfo(a5)
  move.w  #0,vp_Modes(a5)
  move.l  #16,d0               ;put in colour map
  jsr     LVOGetColorMap(a6)
  lea     viewport,a5
  move.l  d0,vp_ColorMap(a5)
  movem.l d0,colourmap
  lea     BMscene,a5           ;allocate rasters for screen bitmap
  move.l  #3,d5
  lea     bm_Planes(a5),a3
nextplane:
  move.l  #320,d0
  move.l  #256,d1
  jsr     LVOAllocRaster(a6)
  tst.l   d0
  beq     notworthstarting
  move.l  d0,(a3)+
  dbra    d5,nextplane
  lea     BMbuffer,a0          ;bitmap 
  move.b  #4,d0                ;playfield 1 320x256 fixed
  move.w  #320,d1
  move.w  #256,d2
  jsr     LVOInitBitMap(a6)
  move.l  #BMbuffer,d0
  lea     ribuffer,a5           ;rasinfo
  move.l  d0,ri_BitMap(a5)
  move.w  #0,ri_RxOffset(a5)
  move.w  #0,ri_RyOffset(a5)
  move.l  #0,ri_Next(a5)
  lea     BMbuffer,a5           ;allocate rasters for buffer bitmap
  move.l  #3,d5
  lea     bm_Planes(a5),a3
nextplane2:
  move.l  #320,d0
  move.l  #256,d1
  jsr     LVOAllocRaster(a6)
  tst.l   d0
  beq     notworthstarting
  move.l  d0,(a3)+
  dbra    d5,nextplane2
  lea     BMpix,a0           ;bitmap 
  move.b  #4,d0              ;playfield 1 320x256 fixed
  move.w  #320,d1
  move.w  #256,d2
  jsr     LVOInitBitMap(a6)
  move.l  #BMpix,d0
  lea     ripix,a5           ;rasinfo
  move.l  d0,ri_BitMap(a5)
  move.w  #0,ri_RxOffset(a5)
  move.w  #0,ri_RyOffset(a5)
  move.l  #0,ri_Next(a5)
  lea     BMpix,a5           ;allocate rasters for source bitmap
  move.l  #3,d5
  lea     bm_Planes(a5),a3
nextplane3:
  move.l  #320,d0
  move.l  #256,d1
  jsr     LVOAllocRaster(a6)
  tst.l   d0
  beq     notworthstarting
  move.l  d0,(a3)+
  dbra    d5,nextplane3
  rts

notworthstarting:              ;graceful exit if necessary
  move.l  #1,d0
  move.l  #dosbase,a6
  jsr     LVOExit(a6)
  rts


stripes:                      ;draw a striped background into 
 lea      rastport,a1         ;screen rastport
 jsr      LVOInitRastPort(a6)
 move.l   #BMscene,rp_BitMap(a1)
 clr.l    d4
 clr.l    d1
 clr.l    d5
 move.l   #5,d2
 move.l   #255,d3
rstripe:
 movem.l  d0-d7/a0-a6,-(sp)
 move.l   d5,d0
 andi.l   #3,d0
 add.l    #4,d0
 jsr      LVOSetAPen(a6)
 movem.l  (sp)+,d0-d7/a0-a6
 move.l   d4,d0
 movem.l  d0-d7/a0-a6,-(sp)
 jsr      LVORectFill(a6)   ;fill a vertical stripe
 movem.l  (sp)+,d0-d7/a0-a6
 add.l    #4,d2
 add.l    #4,d4
 add.l    #1,d5
 cmp.l    #80,d5
 bne      rstripe
 move.l   #0,d0                 ;copy it to the buffer
 move.l   #0,d1
 lea      BMscene,a0            ;destination bit map
 move.l   #0,d2                 ;source x coord  
 move.l   #0,d3                 ;source y coord
 move.l   #320,d4               ;width 
 move.l   #256,d5               ;height
 move.l   #$c0,d6               ;minterm
 move.l   #$ff,d7               ;mask
 move.l   #0,a2                 ;buffer if source and destination overlap 
 lea      BMbuffer,a1           ;source bit map
 move.l   graphicsbase,a6
 jsr      LVOBltBitMap(a6)
 openlibraries:               
  move.l  AbsExecBase,a6
  move.l  #dosname,a1
  clr.l   d0
  jsr     LVOOpenLibrary(a6)
  movem.l d0,dosbase
  tst.l   d0
  beq     notworthstarting
  move.l  #graphicsname,a1
  clr.l   d0
  jsr     LVOOpenLibrary(a6)
  movem.l d0,graphicsbase
  tst.l   d0
  beq     notworthstarting
  rts

cleanup:
  move.l  graphicsbase,a6
  lea     viewport,a0
  jsr     LVOFreeVPortCopLists(a6)
  move.l  colourmap,a0
  jsr     LVOFreeColorMap(a6)
  lea     BMscene,a5
  move.l  #3,d5
  lea     bm_Planes(a5),a3
cleanrast:
  move.l  (a3)+,a0
  move.l  #320,d0
  move.l  #256,d1
  jsr     LVOFreeRaster(a6)
  add.l   #4,a0
  dbra    d5,cleanrast
  lea     BMbuffer,a5
  move.l  #3,d5
  lea     bm_Planes(a5),a3
cleanrast2:
  move.l  (a3)+,a0
  move.l  #320,d0
  move.l  #256,d1
  jsr     LVOFreeRaster(a6)
  add.l   #4,a0
  dbra    d5,cleanrast2
  lea     BMpix,a5
  move.l  #3,d5
  lea     bm_Planes(a5),a3
cleanrast3:
  move.l  (a3)+,a0
  move.l  #320,d0
  move.l  #256,d1
  jsr     LVOFreeRaster(a6)
  add.l   #4,a0
  dbra    d5,cleanrast3
  rts

closelibraries:              
  move.l  AbsExecBase,a6
  move.l  graphicsbase,a1
  jsr     LVOCloseLibrary(a6)
  move.l  dosbase,a1
  jsr     LVOCloseLibrary(a6)
  rts


 CSECT  data
filename:
 dc.b  'piccy',0
 ds.w    0
dosname:
 dc.b  'dos.library',0
 ds.w   0
graphicsname:
 dc.b  'graphics.library',0
 ds.w   0
riscene:                        
 dc.l 0
 dc.l BMscene
 ds.w 2
ribuffer:                        
 dc.l 0
 dc.l BMscene
 ds.w 2
ripix:                        
 dc.l 0
 dc.l BMscene
 ds.w 2
viewport:      
 ds.b vp_SIZEOF
 ds.w 0
graphicsbase:                      
 ds.l    1
oldview:
 ds.l    1
colourmap:
 ds.l    1
colourlist:
 ds.l 32
colourlist2:
 ds.l 32
BMbuffer:
 ds.b  bm_SIZEOF
 ds.w  0
BMpix:
 ds.b  bm_SIZEOF
 ds.w  0
BMscene:
 ds.b  bm_SIZEOF
 ds.w  0
view:
 ds.b  v_SIZEOF
 ds.w  0
rastport:
 ds.b   rp_SIZEOF
 ds.w   0
dosbase:
 ds.l 1
count:
 ds.l 1
xpos:
 ds.l 1
ypos:
 ds.l 1
oldscenexpos:
 ds.l 1
oldsceneypos:
 ds.l 1
oldbufferxpos:
 ds.l 1
oldbufferypos:
 ds.l 1
sourcexpos
 ds.l 1
sourceypos
 ds.l 1
sourcexoffset:
 ds.l 1 
sourcexstart:
 ds.l 1
 END

       
