      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  LVOBltBitMap
 XREF  LVOInitRastPort
 XREF  LVOSetRast
 XREF  LVOSetAPen
 XREF  LVORectFill
 XREF  LVOClearScreen
 XREF  LVOMove
 XREF  LVODraw

                               ;routines in iffread2.o
 XREF  _test2                  ;Delay(parameter)
 XREF  _readfile               ;readfile(filename,bitmap,colourlist)

 XREF  _addscore
 XREF  _key
 
 XDEF  _main                   ;linker needed this as an external reference

 XDEF  _xpos
 XDEF  _ypos
 XDEF  _energy
 XDEF  _writedigit


  ;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)
  lea     rastport,a1
  jsr     LVOClearScreen(a6)
  jsr     remake                ;load the display
  move.l  #filename,d0          ;in this case piccy
  move.l  #BMfont,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)
  clr.l   d3
  clr.l   d2                    ;copy appropriate picture to screen
  lea     BMscene,a1            ;destination bit map
  move.l  #0,d0                 ;destination x coord  
  move.l  #96,d1               ;destination y coord
  move.l  #320,d4                ;width 
  move.l  #160,d5                ;height
  move.l  #$c0,d6               ;minterm
  move.l  #$ff,d7               ;mask
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMfont,a0            ;source bit map
  move.l  graphicsbase,a6
  jsr     LVOBltBitMap(a6)
  jsr     setup
loop:
   jsr    _key                 ;read keyboard
  jsr     _addscore            ;process result
  move.l  #1,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     update                ;update energy and time
  cmp.l     #216,_energy        ;test for end
  bne      loop
finish:
  move.l  oldview,a1           ;replace old view
  move.l  graphicsbase,a6 
  jsr     LVOLoadView(a6) 
  jsr     cleanup              ;release memory 
  jsr     closelibraries
  rts

setup:                         ;initialise enrgy 
   lea    rastport,a1
   move.l #4,d0
   move.l  graphicsbase,a6
   jsr    LVOSetAPen(a6)
   lea    rastport,a1
   move.l #216,d0
   move.l #84,d1
   move.l #309,d2
   move.l #103,d3
   jsr    LVORectFill(a6)
   move.l #16,xoffset             ;write texts on scoreboard
   move.l #310,_energy
   move.l #216,time
   move.l #0,count
   lea    number,a5
   move.l #9,_xpos
   move.l #11,_ypos
   jsr    _writetext
   lea    total,a5
   move.l #9,_xpos
   move.l #48,_ypos
   jsr    _writetext
   lea    health,a5
   move.l #9,_xpos
   move.l #84,_ypos
   jsr    _writetext
   lea    timetaken,a5
   move.l #9,_xpos
   move.l #120,_ypos
   jsr    _writetext
   move.l #24,xoffset
   rts

_writetext:               ;write a text string
   move.b  (a5)+,d0
   andi.l #255,d0
   beq    writeout
   move.l  d0,asc
   jsr    letter
   move.l xoffset,d0
   add.l  d0,_xpos
   bra    _writetext
writeout:
   rts

_writedigit:              ;write a string of digits
   move.b  (a5)+,d0
   andi.l #255,d0
   beq    writeout
   move.l  d0,asc
   jsr    digit
   move.l xoffset,d0
   add.l  d0,_xpos
   bra    _writedigit
   rts

update:                      ;update energy and time
   add.l #1,count
   move.l rate,d0
   cmp.l count,d0
   bne   updateout
   clr.l count
   sub.l #1,_energy
   add.l #1,time
   cmp.l #216,_energy
   beq   updateout
   lea    rastport,a1
   move.l #0,d0
   move.l  graphicsbase,a6
   jsr    LVOSetAPen(a6)
   lea    rastport,a1
   move.l _energy,d0
   move.l #84,d1
   jsr    LVOMove(a6)
   lea    rastport,a1
   move.l _energy,d0
   move.l #103,d1
   jsr    LVODraw(a6)
   lea    rastport,a1
   move.l #5,d0
   jsr    LVOSetAPen(a6)
   lea    rastport,a1
   move.l time,d0
   move.l #121,d1
   jsr    LVOMove(a6)
   lea    rastport,a1
   move.l time,d0
   move.l #141,d1
   jsr    LVODraw(a6)
updateout:
   rts   

letter:                  ;put letter on screen
  sub.l   #32,asc        ;calculate source coords
  move.l  asc,d0         ;from ascii value and source bitmap
  andi.l   #15,d0
  asl.l   #4,d0
  move.l  d0,xsrc
  move.l  asc,d0
  andi.l   #240,d0
  move.l  d0,ysrc
  move.l  _xpos,d2
  move.l  _ypos,d3
  lea     BMscene,a1            ;destination bit map
  move.l  xsrc,d0                 ;source x coord  
  move.l  ysrc,d1               ;source y coord
  move.l  #16,d4                ;width 
  move.l  #16,d5                ;height
  move.l  #$20,d6               ;minterm
  move.l  #$ff,d7               ;mask
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMfont,a0            ;source bit map
  move.l  graphicsbase,a6
  jsr     LVOBltBitMap(a6)
  move.l  _xpos,d2
  move.l  _ypos,d3
  lea     BMscene,a1            ;dest bit map
  move.l  xsrc,d0                 ;source x coord  
  move.l  ysrc,d1               ;source coord
  move.l  #16,d4                ;width 
  move.l  #16,d5                ;height
  move.l  #$60,d6               ;minterm
  move.l  #$ff,d7               ;colour
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMfont,a0            ;source bit map
  move.l  graphicsbase,a6
  jsr     LVOBltBitMap(a6)
  rts

digit:                       ;put digit on screen
  sub.l   #32,asc
  move.l  asc,d0
  andi.l   #15,d0
  asl.l   #4,d0
  move.l  d0,xsrc
  move.l  asc,d0
  andi.l   #240,d0
  move.l  d0,ysrc
  move.l  _xpos,d2
  move.l  _ypos,d3
  lea     BMscene,a1            ;destination bit map
  move.l  xsrc,d0                 ;src x coord  
  move.l  ysrc,d1               ;src y coord
  move.l  #16,d4                ;width 
  move.l  #16,d5                ;height
  move.l  #$c0,d6               ;minterm
  move.l  #$ff,d7               ;mask
  move.l  #0,a2                 ;buffer if source and destination overlap 
  lea     BMfont,a0            ;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)
  lea     BMfont,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 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     BMfont,a5           ;allocate rasters for 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      rastport,a1
  jsr      LVOInitRastPort(a6)
  move.l   #BMscene,rp_BitMap(a1)
  rts

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

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
  lea     BMfont,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
  rts

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


 CSECT  DATA,data
number:
 dc.b   'number',0
 ds.w   0
total:
 dc.b   'total score',0
 ds.w   0
health:
 dc.b   'energy left',0
 ds.w   0
timetaken:
 dc.b   'time taken',0
 ds.w   0
filename:
 dc.b  'fontpic',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
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
BMscene:
 ds.b  bm_SIZEOF
 ds.w  0
BMfont:
 ds.b  bm_SIZEOF
 ds.w  0
view:
 ds.b  v_SIZEOF
 ds.w  0
dosbase:
 ds.l 1
rastport:
 ds.b   rp_SIZEOF
 ds.w   0
_energy:
 ds.l   1
count:
 ds.l   1
time: 
 ds.l   1
rate:
 dc.l   40
_xpos:
 ds.l   1
_ypos:
 ds.l   1
asc:
 ds.l   1
xsrc:
 ds.l   1
ysrc:
 ds.l   1
xoffset:
 dc.l   16
 END

       
