…is always light

Tag Archives: assembly

As far as I can remember, my old Quest of Love-project was something I made with Amiga mostly in the year 2004. It seems I started something related to the project in 2003.

First I was going to do the project fully in assembly, but later I decided to switch to C, when programming the actual game.

Below is a video of the experimental intro/demo, that tells a story in the scroll text in Finnish.

The demo that is coded in MC68040 assembly uses only system routines. Notice that in the scroll text the bitplanes jump separately.

For curiosity, I ran into some problems when coding the routine that clears the scroll text area. Because 68040 processor is a lot faster than Blitter, I have used CPU for clearing the area. In the fastest version I tried to use 68040’s move16 instruction, but I had some problems with it with Amiga’s CHIP memory.

I composed the musics with Amiga’s MED. The music routine is not included in the source below, because it’s linked to main code from object code. The routine is the one that comes with MED.

The music module is also converted to object code that is linked to the main code.

I really am not good at all at making graphics and the graphics in the demo are only at experimental level… Some of the graphics are in fact something that I made, when was about 16 years old… 🙂

When coding the demo, I hadn’t decided yet, that am I going to program the game in assembly or in C. This is why there is some code that was supposed to be used in the game, but is not used in the demo.

The comments and labels are partly in English and partly in Finnish in this old project…

Anyway, if you are interested in, how the demo was coded, see below:

 

               MACHINE  68040

               incdir   "Work:Assembler/include"

               include  "QuestOfLove.i"        ; Offsetit kirjastokutsuille, ym.
               include  "Intuition/intuition.i"
               include  "Libraries/iff.i"

; MED:in ProPlayer2.a:han liittyvÀt viittaukset

               xref  _startmusic
               xref  _endmusic
               xref  _modnum
               xref  _mymodule
               xref  _PlayModule
               xref  _StopPlayer

IDCMPf         set   VANILLAKEY

Liput          set   BORDERLESS!ACTIVATE!RMBTRAP

BITPLANE          equ   1024
DEMOFRAME         equ   16
FONTWIDTH         equ   10-4

MAP_WIDTH         equ   63
MAP_HEIGHT        equ   61

VISIBLE_BLOCKS_X  equ   13-1
VISIBLE_BLOCKS_Y  equ   11-1

RED_TILE          equ   8
LOW_WATER         equ   10
COL_TILE          equ   12
DEEP_WATER        equ   14

GHOST             equ   18
VIITTAMIES        equ   20
KORUNAINEN        equ   21
FOUNTAIN          equ   22
FOUNTAIN2         equ   23
      
TOWN              equ   49+48*63    ; (49,48) (origo = 0,0)

;------------------------------------------------------------------------------
; Ohjelma alkaa
;------------------------------------------------------------------------------

   section  Koodi,Code

               movem.l  d2-d7/a2-a6,-(sp)

               move.w   $dff006,rnd_more     ; Satunnaislukuja varten

; Avataan kirjastot

               lea      intuinimi,a1
               moveq    #0,d0
               LibCall  Exec,OpenLibrary
               move.l   d0,Intuibase

               lea      dosnimi,a1
               moveq    #0,d0
               LibCall  Exec,OpenLibrary
               move.l   d0,Dosbase

               LibCall  Dos,Output           ; Tulostusta varten
               move.l   d0,outfile           ;

               lea      GFXnimi,a1
               moveq    #0,d0
               LibCall  Exec,OpenLibrary
               move.l   d0,GFXbase

               lea      DiskFontnimi,a1
               moveq    #0,d0
               LibCall  Exec,OpenLibrary
               move.l   d0,DiskFontbase

               lea      IFFnimi,a1
               moveq    #16,d0               ; versio
               LibCall  Exec,OpenLibrary
               move.l   d0,IFFbase

; Avataan oma fontti

               lea      textattr,a0
               LibCall  DiskFont,OpenDiskFont
               move.l   d0,Font
               beq      CleanUp

; Avataan omistus-sourcescreen & window
; (LĂ€hde, mihin varsinaisesti ladataan omistuskuva)

               lea      OmistusNaytto,a0
               LibCall  Intui,OpenScreen
               move.l   d0,Om_Naytto
               beq      CleanUp

               move.l   Om_Naytto,a0            ; Otetaan nayton
               add.l    #44,a0                  ; viewport
               lea      colortable,a1           ; VĂ€rikartan alkuosoite
                                                ; (TÀssÀ vaiheessa pelkÀÀ
                                                ;  mustaa)
               moveq    #32,d0                  ; 32 vÀriÀ
               LibCall  GFX,LoadRGB4

               move.l   Om_Naytto,oms_addy
               lea      UusiIkkuna4,a0
               LibCall  Intui,OpenWindow
               move.l   d0,Om_Ikkuna
               beq      CleanUp

               move.l   Om_Ikkuna,a0            ; Otetaan ikkunan
               move.l   50(a0),Om_rastport      ; rastport

               lea      omistusfile,a0
               move.l   #IFFL_MODE_READ,d0
               LibCall  IFF,_LVOOpenIFF
               move.l   d0,iff
               cmp.l    #0,d0
               beq      clean

               move.l   iff,a1
               move.l   Om_Naytto,a0
               lea      sc_BitMap(a0),a0
               LibCall  IFF,_LVODecodePic

; Avataan oma screen, tÀmÀ on nÀkyvÀ screen

               lea      UusiNaytto,a0 
               LibCall  Intui,OpenScreen
               move.l   d0,MinunNaytto
               beq      CleanUp

; Avataan ikkuna yllÀ avatulle nÀytölle

               move.l   MinunNaytto,NaytonOsoite
               lea      UusiIkkuna,a0
               LibCall  Intui,OpenWindow
               move.l   d0,MinunIkkuna
               beq      CleanUp

               move.l   MinunIkkuna,a0          ; Otetaan ikkunan
               move.l   50(a0),rastport         ; rastport

               move.l   MinunNaytto,a0          ; Otetaan nayton
               add.l    #44,a0                  ; viewport
               move.l   a0,viewport

; Ladataan "kehysfile" (kuva Àsken avatulle nÀytölle)

               lea      kehysfile,a0
               move.l   #IFFL_MODE_READ,d0
               LibCall  IFF,_LVOOpenIFF
               move.l   d0,iff_kehysfile
               cmp.l    #0,d0
               beq      clean

               move.l   iff_kehysfile,a1
               lea      myBitMap1,a0
               LibCall  IFF,_LVODecodePic

; Ladataan block-file, vÀrikartta lopussa

               lea      blockfile,a0
               move.l   #IFFL_MODE_READ,d0
               LibCall  IFF,_LVOOpenIFF
               move.l   d0,iff_blockfile
               cmp.l    #0,d0
               beq      clean

               move.l   iff_blockfile,a1
               lea      blockBitMap,a0
               LibCall  IFF,_LVODecodePic

; Asetetaan vÀrit nÀytölle

               move.l   iff_blockfile,a1
               lea      colortable,a0
               LibCall  IFF,_LVOGetColorTab    ; Kutsun tulos: D0:ssa vÀrien mÀÀrÀ

               move.l   viewport,a0
;               move.l   #colortable,a1
               lea      colortable,a1
               moveq    #32,d0                 ; 32 vÀriÀ
               LibCall  GFX,LoadRGB4

; Asetetaan vÀrit nÀytölle

;               move.l   iff,a1
;               lea      colortable,a0
;               LibCall  IFF,_LVOGetColorTab    ; Kutsun tulos: D0:ssa vÀrien mÀÀrÀ
;               move.l   viewport,a0
;               lea      colortable,a1
;               moveq    #32,d0                 ; 32 vÀriÀ
;               LibCall  GFX,LoadRGB4

;               move.l   #blockdata+5120,a0      ; VÀrienkierrÀtyksessÀ kÀytetÀÀn
;               lea      colortable,a1           ; colortablea...
;               moveq    #32-1,d7
;initCTSil      move.w   (a0)+,(a1)+
;               dbf      d7,initCTSil

;               move.l   viewport,a0
;               lea      colortable,a1           ; VĂ€rikartan alkuosoite
;               moveq    #32,d0                  ; 32 vÀriÀ
;               LibCall  GFX,LoadRGB4

; Avataan "omistusikkuna" nÀytölle

               move.l   MinunNaytto,screenaddy
               lea      UusiIkkuna3,a0
               LibCall  Intui,OpenWindow
               move.l   d0,OmistusIkkuna
               beq      CleanUp

               move.l   OmistusIkkuna,a0
               move.l   50(a0),o_rastport       ; Omistusikkunan rastport

; Joitain alustuksia...

               moveq    #8-1,d7                 ; Kopioidaan vÀrienkierrÀtystÀ
               lea      colortable+32,a0        ; varten kierrÀtettÀvÀt vÀrit
               lea      copytable,a1            ; toiseen taulukkoon...
copycol        move.w   (a0)+,(a1)+
               dbf      d7,copycol

               move.b   #FONTWIDTH,Laskuri
               move.l   #13,FontColor
               move.l   #0,frameY

               move.l   viewport,a0             ; Muutetaan feidauskuvaa
               moveq    #2,d0                   ; varten yhden vÀrirekisterin
               moveq    #0,d1                   ; arvo mustaksi
               moveq    #0,d2
               moveq    #0,d3
               LibCall  GFX,SetRGB4

               jsr      _startmusic             ; Alun feidausmusiikit

               bsr      FadeIn                  ; Tulostetaan alkukuva
                                                ; pisteittÀin

               move.l   #50*12,d1
               LibCall  Dos,Delay

; TÀhÀn voisi laittaa mustan laatikon piirtÀmisen...
;
;               bsr      FadeOut                 ; PyyhitÀÀn alkukuva
                                                ; pisteittÀin

               move.l   viewport,a0             ; Asetetaan yllÀ muutettu
               moveq    #2,d0                   ; vÀri takaisin
               lea      colortable+4,a1         ; 4 = 2*2
               move.w   (a1),d1
               lsr.w    #8,d1                   ; Red
               and.l    #$f,d1
               move.w   (a1),d2
               lsr.w    #4,d2                   ; Green
               and.l    #$f,d2
               move.w   (a1),d3
               and.l    #$f,d3                  ; Blue
               LibCall  GFX,SetRGB4

               move.l   OmistusIkkuna,d0        ; Suljetaan omistusikkuna
               beq      CleanUp
               move.l   d0,a0
               LibCall  Intui,CloseWindow
               clr.l    OmistusIkkuna

; Kopiodaan myBitMap1:een ladattu kuva myBitMap2:een

               lea      myBitMap1,a0            ; LĂ€hde bitmap-structuren osoite
               moveq    #0,d0                   ; LÀhde: YlÀkulman x-koord.
               moveq    #0,d1                   ; LÀhde: YlÀkulman y-koord.
               lea      myBitMap2,a1            ; Kohde bitmap-structuren osoite
               moveq    #0,d2                   ; Kohde: x-koord.
               moveq    #0,d3                   ; Kohde: y-koord.
               move.l   #320,d4                 ; x-koko
               move.l   #256,d5                 ; y-koko
               move.l   #$c0,d6                 ; Minterm
               moveq    #$1f,d7                 ; 5 bittitasoa
               lea      Puskuri,a2              ; Puskuri
               LibCall  GFX,BltBitMap

               move.l   #Gamefield+8,gamefield  ; gamefield-osoittimeen
                                                ; kÀytettÀvÀ gamefield
               move.l   #Hahmot,hahmot          ;
               move.l   #monster_map,hahmo_map

               bsr      InitGhosts
               bsr      SwapBitMaps

               jsr      _StopPlayer
               move.w   #0,_modnum              ; Main-demon musiikki
               move.l   _mymodule,a0
               jsr      _PlayModule

;------------------------------------------------------------------------------
; PÀÀohjelma --------------------------------------------------------------
;------------------------------------------------------------------------------
MainProgram    tst.b    Quit
               bne      CleanUp

               move.l   viewport,a0
               LibCall  GFX,WaitBOVP

               addq.b   #1,Demoonko

               cmp.b    #1,DemoDone
               beq      MainLoppu

; TÀhÀn rutiinikutstut ...

               bsr      TextScroll
               bsr      DrawMap

               moveq    #0,d0
               move.b   Demoonko,d0
               divu.w   #3,d0
               swap     d0
               cmp.w    #0,d0
               bne      animframetst

; Aliohjelmat, jotka suoritetaan joka 3. frame

               bsr      HandlePlayer
               bsr      HandleCharacters
               bsr      SwapBitMaps          ; *
               bsr      ikkunanviestit
               bra      MainProgram

animframetst   moveq    #0,d0
               move.b   Demoonko,d0
               divu.w   #8,d0                ; Joka 8.frame on animaatioframe
               swap     d0
               cmp.w    #0,d0                ; Ovatko 16 alinta bittiÀ nollia?
               bne.s    ei_anim
               bsr      ColourCycling
ei_anim        
               cmp.b    #DEMOFRAME,Demoonko  ; Joka 16.frame kÀydÀÀn demossa
               bne      MainProgram          ; (tÀssÀ versiossa DEMOFRAMEn
               cmp.b    #1,DemoMode
               beq.s    demhon
               move.b   #0,Demoonko
               bra      MainProgram
demhon         bsr      HandleDemo           ;  oltava parillinen)
               move.b   #0,Demoonko
               bra      MainProgram

ikkunanviestit
               move.l   MinunIkkuna,a0       ; Ikkunan osoitin
               move.l   wd_UserPort(a0),a2   ; UserPort-osoitin
               moveq    #0,d1
               move.b   15(a2),d1            ; Signaalibitin numero
               moveq    #0,d0
               bset.l   d1,d0

Loop           move.l   a2,a0                ; UserPort-osoitin
               LibCall  Exec,GetMsg
               tst.l    d0
               bne.s    lueviesti
               rts
lueviesti      move.l   d0,a1                ; Viestin osoitin
               move.l   im_Class(a1),d2      ; Viestin luokka
               move.w   im_Code(a1),d3       ; Viestin koodi
               moveq    #0,d4
               moveq    #0,d5
               LibCall  Exec,ReplyMsg        ; Vastataan viestiin
WhatsHappening 
;               cmp.l    #MOUSEBUTTONS,d2     ; Viesti: Hiiren nappi?
;               bne.s    Next
;               move.b   #1,Quit
;               rts
Next1          cmp.l    #VANILLAKEY,d2       ; Viesti: NÀppÀin?
               bne      Next
               bsr      Nappis
Next           rts

;------------------------------------------------------------------------------
; NÀppisohjaus. Samaa koodia kÀytetÀÀn sellaisenaan myös
; demoliikkeen ohjaamiseen. Blocked-rutiini palauttaa D0:aan joko luvun 0 tai 1
; sen mukaan, voiko suuntaan liikkua (0 = voi liikkua, 1 = ei).
;------------------------------------------------------------------------------
Nappis
               lea      OmaHahmo,a1

               cmp.b    #27,d3                  ; Esc
               bne.s    nap
               move.b   #1,Quit
               rts

nap            cmp.b    #'e',d3                  ; e-nÀppÀin
               bne.s    spacebar

; Lasketaan pelaajan globaali paikka kartalla ja katsotaan, ollaanko
; kaupungin pÀÀllÀ. Tarvitsen nÀemmÀ kuitenkin jonkinlaisen "Kaupungissako"
; -muuttujan, jottei kÀy niin, ettÀ kaupungissa ollessa pelaajan painaessa
; e:tÀ, tullaan uudestaan kaupunkiin... Tarkistus tehdÀÀn vain e:tÀ
; painettaessa, joten pÀÀohjelmaan ei tule "turhaa" tarkistusta.
;
; Unohtamani syyn lisÀksi Blocked-rutiinia on uusittava tulevaisuudessa
; kaupunkien ja linnojen vuoksi (ellei sitten jokainen kaupunki ja linna ole
; samankokoisia kuin pÀÀkartta).

               tst.b    inTown                  ; Ollaanko jo kaupungissa?
               bne.s    notown

               move.l   (a1),d0                 ; MapX
               move.l   4(a1),d1                ; MapY
               addq.l   #6,d0                   ; x-keskitys
               addq.l   #5,d1                   ; y-keskitys
               move.l   8(a1),d4                ; ScreenX
               move.l   12(a1),d5               ; ScreenY
               asr.l    #4,d4
               asr.l    #4,d5
               add.l    d4,d0
               add.l    d5,d1
               mulu.w   #MAP_WIDTH,d1
               add.l    d1,d0                   ; D0:ssa on nyt paikka kartalla
               cmp.w    #TOWN,d0                ; Ollaanko kaupungissa?
               bne.s    notown
               move.l   #Townfield+8,gamefield
               move.l   #Ihmiset_Town,hahmot
               move.l   #TownHahmoMap,hahmo_map
               move.l   #25,(a1)                ; Asetetaan alkukoordinaatit
               move.l   #50,4(a1)               ; kaupungissa oleskelua varten
               move.l   #0,8(a1)                ; ScreenX
               move.l   #(16*3),12(a1)          ; ScreenY (pixeleinÀ)
               move.b   #1,inTown
notown         rts

spacebar       ;cmp.b    #64,d3                  ; VÀlilyönti?
               cmp.b    #' ',d3
               bne.s    ohjaus

               cmp.b    #0,DemoDone             ; Jos painettiin ja jos ollaan
               beq.s    demokehissa             ; "loppuhuipentumassa", niin
               move.b   #1,RestartAll           ; restartoidaan alkuun...
               rts

demokehissa    cmp.b    #1,DemoMode             ; Jos taas oltiin normaalissa
               beq.s    toggle                  ; karttaosuudessa, niin
               move.b   #1,DemoMode             ; toggletetaan DemoMoodia
               rts
toggle         move.b   #0,DemoMode
               rts

; Ylös pÀin

ohjaus
               cmp.b    #'8',d3
               bne.s    ne
               cmp.l    #0,4(a1)
               bne.s    mapUpko
               sub.l    #16,12(a1)
               bsr      Blocked
               beq.s    poUp
               add.l    #16,12(a1)
               rts
mapUpko        cmp.l    #0,12(a1)
               ble.s    mapUp
               sub.l    #16,12(a1)           ;
               bsr      Blocked
               beq.s    poUpko
               add.l    #16,12(a1)
poUpko         rts
mapUp          subq.l   #1,4(a1)
               bsr      Blocked
               beq.s    poUp
               addq.l   #1,4(a1)
poUp           rts

; Alas pÀin

ne             cmp.b    #'2',d3
               bne.s    ne2
               cmp.l    #MAP_HEIGHT-11,4(a1)
               bne.s    mapDownko
               add.l    #16,12(a1)
               bsr      Blocked
               beq.s    poDownko
               sub.l    #16,12(a1)
poDownko       rts
mapDownko      cmp.l    #0,12(a1)
               bge.s    mapDown
               add.l    #16,12(a1)
               bsr      Blocked
               beq.s    poDown
               sub.l    #16,12(a1)
               rts
mapDown        addq.l   #1,4(a1)
               bsr      Blocked
               beq.s    poDown
               subq.l   #1,4(a1)
poDown         rts

; Vasemmalle

ne2            cmp.b    #'4',d3
               bne.s    ne3
               cmp.l    #0,(a1)
               bne.s    mapLeftko
               sub.l    #16,8(a1)
               bsr      Blocked
               beq.s    poLeftko
               add.l    #16,8(a1)
poLeftko       rts
mapLeftko      cmp.l    #0,8(a1)
               ble.s    mapLeft
               sub.l    #16,8(a1)
               bsr      Blocked
               beq.s    poLeftko
               add.l    #16,8(a1)
               rts
mapLeft        subq.l   #1,(a1)
               bsr      Blocked
               beq.s    poLeft
               addq.l   #1,(a1)
poLeft         rts

; Oikealle

ne3            cmp.b    #'6',d3
               bne.s    ne4
               cmp.l    #MAP_WIDTH-13,(a1)
               bne.s    mapRightko
               add.l    #16,8(a1)
               bsr      Blocked
               beq.s    poRightko
               sub.l    #16,8(a1)
poRightko      rts             
mapRightko     cmp.l    #0,8(a1)
               bge.s    mapRight
               add.l    #16,8(a1)
               bsr      Blocked
               beq.s    poRightko
               rts
mapRight       addq.l   #1,(a1)
               bsr      Blocked
               beq.s    ne4
               subq.l   #1,(a1)
ne4            rts
;------------------------------------------------------------------------------
; Blocked -- tarkistaa voiko valittuun kulkusuuntaan mennÀ, palauttaa
; D0:ssa 0 jos voi; 1 jos ei. Olettaa rekisterit NĂ€ppis-aliohjelman mukaisiksi.
; Ks. Huomautus Nappis-rutiinissa...
;------------------------------------------------------------------------------
Blocked        move.l   gamefield,a2

               lea      OmaHahmo,a1
               move.l   (a1),d0              ; "Pelaajan" MapX
               move.l   4(a1),d1             ; "Pelaajan" MapY
               move.l   8(a1),d2             ; ScreenX
               move.l   12(a1),d3            ; ScreenY
               addq.l   #6,d0                ; Keskitys
               addq.l   #5,d1                ; Keskitys
               lsl.w    #1,d0
               lsl.w    #1,d1
               mulu.w   #MAP_WIDTH,d1
               asr.l    #3,d2                ; /16 * 2 ("LSL.W #1,DX valmiina")
               asr.l    #3,d3                ; /16 * 2 ("LSL.W #1,DY valmiina")
               move.l   d3,d4
               muls.w   #MAP_WIDTH,d3        ; ASR:n ja MULS:n voisi "yhdistÀÀ"
               add.l    d0,a2
               add.l    d1,a2
               add.l    d2,a2
               add.l    d3,a2

; Aluksi katsotaan, onko kÀvelty ulos kartalta

               tst.b    inTown
               beq.w    blockedko
               cmp.l    #-(6*2),d2                 ; "x1"
               bge.s    eks2
               bsr.w    backtomainmap
               rts
eks2           cmp.w    #6*2,d2
               ble.s    yy1
               bsr.w    backtomainmap
               rts
yy1            cmp.l    #-(5*2),d4
               bge.s    yy2
               bsr.w    backtomainmap
               rts
yy2            cmp.w    #5*2,d4
               ble.s    blockedko
               bsr.w    backtomainmap
               rts

blockedko      cmp.w    #RED_TILE,(a2)       ; Punainen tiili
               bne.s    nxt1
               moveq    #1,d0
               rts
nxt1           cmp.w    #LOW_WATER,(a2)      ; Matala vesi
               bne.s    nxt2
               moveq    #1,d0
               rts
nxt2           cmp.w    #COL_TILE,(a2)       ; VÀrikÀs seinÀ
               bne.s    nxt3
               moveq    #1,d0
               rts
nxt3           cmp.w    #DEEP_WATER,(a2)     ; SyvÀ vesi
               bne.s    nxtN1
               moveq    #1,d0
               rts
nxtN1          cmp.w    #FOUNTAIN,(a2)
               bne.s    nxtN2
               moveq    #1,d0
               rts
nxtN2          cmp.w    #FOUNTAIN2,(a2)
               bne.s    nxt4
               moveq    #1,d0
               rts

; Katsotaan, onko kÀvelty kartalla olevan hahmon pÀÀlle

nxt4           move.l   hahmo_map,a2
;              cmp.l    #0,a2                ; TÀssÀ versiossa hoidetaan varsin
;              beq      nxt6                 ; kömpelösti tsekkaus pelaajan
                                             ; törmÀÀmisestÀ eri hahmoihin...
                                             ; Tosin pienellÀ lisÀhiomisella
                                             ; kokonaisuudesta saa varsin
                                             ; nÀppÀrÀn.
                                             ; Voisi miettiÀ myös toisenlaista
                                             ; "tietorakennetta": monster_map
                                             ; pitÀisi sisÀllÀÀn myös monste-
                                             ; reiden koordinaatit...
               add.l    d0,a2
               add.l    d1,a2
               add.l    d2,a2
               add.l    d3,a2

               cmp.w    #17,(a2)             ; Nainen vihreÀllÀ hameella
               bne.s    nxt5
               bsr      LoppuHuipentuma
               bsr      SwapBitMaps
               moveq    #0,d0                ; Kone sekoaa, jos palautetaan
                                             ; luku  1
               rts

nxt5           cmp.w    #GHOST,(a2)
               bne      nxt7                 ; .s

               movem.l  d0-d2/a0,-(sp)
               move.l   #Hahmot+24,a0

; Lasketaan D0:aan pelaajan varsinainen x-koordinaatti kartalla, tulos D0:aan

               move.l   (a1),d0              ; Pelaajan MapX
               move.l   8(a1),d1             ; Pelaajan ScreenX
               asr.l    #4,d1
               add.l    d1,d0
               addq.l   #6,d0                ; "Keskitys"

; Lasketaan D1:een pelaajan varsinainen y-koordinaatti kartalla, tulos D1:een

               move.l   4(a1),d1             ; Pelaajan MapY
               move.l   12(a1),d2            ; Pelaajan ScreenY
               asr.l    #4,d2
               add.l    d2,d1
               addq.l   #5,d1                ; "Keskitys"

cmpX           cmp.l    #0,20(a0)
               bne.s    elossa
               add.l    #24,a0
               cmp.l    #-1,(a0)
               bne.s    cmpX
               moveq    #0,d0                ; Blockiin voi siirtyÀ
               movem.l  (sp)+,d0-d2/a0
               rts

elossa         move.l   (a0),d2              ; "cmpX"
               cmp.l    d0,d2                ; Onko PlyX == MonsterX ?
               beq.s    cmpY
               add.l    #24,a0               ; Seuraavan monsterin kohdalle
               cmp.l    #-1,(a0)             ; Loppuivatko monsterit?
               bne.s    cmpX
               movem.l  (sp)+,d0-d2/a0
               moveq    #0,d0                ; Blockiin voi siirtyÀ
               rts

cmpY           move.l   4(a0),d2
               cmp.l    d1,d2
               beq.s    eraseMonster
               add.l    #24,a0               ; Seuraavan monsterin kohdalle
               cmp.l    #-1,(a0)
               bne.s    cmpX
               movem.l  (sp)+,d0-d2/a0
               moveq    #0,d0                ; Blockiin voi siirtyÀ
               rts

eraseMonster   move.l   #0,20(a0)            ; Monsteri kuollut
               move.l   #12,20(a1)           ; Frame-counter sÀdekehÀlle
               movem.l  (sp)+,d0-d2/a0
nxt6           moveq    #0,d0                ; Palautetaan nolla, jos
                                             ; uuteen paikkaan voi mennÀ
               rts
nxt7           cmp.w    #VIITTAMIES,(a2)
               bne.s    nxt8
               moveq    #1,d0
               rts
nxt8           cmp.w    #KORUNAINEN,(a2)
               bne.s    nxt9
               moveq    #1,d0
               rts
nxt9           moveq    #0,d0
               rts

backtomainmap  move.l   #Gamefield+8,gamefield  ; Takaisin pÀÀkartalle
               move.l   #Hahmot,hahmot
               move.l   #monster_map,hahmo_map
               move.l   #49-6,(a1)              ; Koordinaatit kuntoon
               move.l   #48-5,4(a1)          ; pÀÀkartaa varten...
               move.l   #0,8(a1)             ;  ScreenX
               move.l   #0,12(a1)            ;  ScreenY
               move.b   #0,inTown
               moveq    #0,d0                ; "Loppumerkki" "parent-rutiinille"
               rts

;------------------------------------------------------------------------------
; PiirretÀÀn kartta (13*11 blockia)
;------------------------------------------------------------------------------
DrawMap        move.l   #MAP_WIDTH*2,d4   ; PelikentÀn leveys wordeina (*2)
               sub.l    #26,d4            ; VISIBLE_BLOCKS_X * 2

               lea      OmaHahmo,a2
               move.l   #7+41*40,d2       ; ((320-13*16)/2)/8 + 41*40

; Lasketaan karttadatan vasen ylÀkulma ("dynaaminen origo") pelaajan
; koordinaattien perusteella

               move.l   (a2),d0           ; Pelaajan MapX
               move.l   4(a2),d1          ; Pelaajan MapY
               lsl.w    #1,d0             ; x parilliseksi
;              lsl.w    #1,d1             ; y parilliseksi
               mulu.w   #MAP_WIDTH*2,d1   ; kerrotaan y*2 kartan leveydellÀ
               add.l    d1,d0
               move.l   gamefield,a3
               add.l    d0,a3             ; "Dynaaminen origo"

; Kartan tulostus jaettu 2:lle rasterikierrokselle...

               move.l   DrawBitMap,a2     ; Tulostus silmukan nopeuttamiseksi
                                          ; DrawBitMap a2:een...

               lea      blockBitMap,a6

               move.l   frameY,d5
               mulu.w   #2*MAP_WIDTH,d5   ; *2 = parilliseksi
               add.l    d5,a3
               move.l   frameY,d5
               mulu.w   #40*16,d5
               add.l    d5,d2             ; LisÀtÀÀn frameY-paikka "paikkaan"
               
               cmp.l    #3,frameY
               bge.s    lines4
               moveq    #3-1,d7
               bra.s    mapsil
lines4         moveq    #4-1,d7

mapsil         moveq    #VISIBLE_BLOCKS_X,d6
xsil

; Lasketaan paikka, mistÀ piirretÀÀn (D0)

               move.w   (a3)+,d0          ; Blockin "y-koordinaatti"
               lsl.w    #5,d0

; Kopioidaan blocki blockbitmapista...

               move.l   8(a6),a0          ; Source X
               add.l    d0,a0             ; Source
               move.l   8(a2),a1          ; Dest, BitPlane1
               add.l    d2,a1
               moveq    #16-1,d5          ; 16 pixeliÀ
bpl1sil        move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,bpl1sil

               move.l   12(a6),a0         ; X Source
               add.l    d0,a0             ; Source
               move.l   12(a2),a1         ; Dest, BitPlane2
               add.l    d2,a1
               moveq    #15,d5
bpl2sil        move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,bpl2sil

               move.l   16(a6),a0         ; Source
               add.l    d0,a0             ; Source
               move.l   16(a2),a1         ; Dest, BitPlane3
               add.l    d2,a1
               moveq    #15,d5
bpl3sil        move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,bpl3sil

               move.l   20(a6),a0         ; Source
               add.l    d0,a0             ; Source
               move.l   20(a2),a1         ; Dest, BitPlane4
               add.l    d2,a1
               moveq    #15,d5
bpl4sil        move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,bpl4sil

               move.l   24(a6),a0         ; Source
               add.l    d0,a0             ; Source
               move.l   24(a2),a1         ; Dest, BitPlane5
               add.l    d2,a1
               moveq    #15,d5
bpl5sil        move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,bpl5sil

               addq.l   #2,d2
               dbf      d6,xsil
               add.l    #40*16-(13*2),d2
               add.l    d4,a3
               dbf      d7,mapsil         ; "ysil"

               cmp.l    #3,frameY
               bge.s    kolomone
               addq.l   #3,frameY
               rts
kolomone       addq.l   #4,frameY
               cmp.l    #9,frameY
               blt.s    gouoon
               move.l   #0,frameY
gouoon         rts


; ------------------------------------------------------------------------------
; Joka 16. frame luetaan suunta demoliikettÀ varten
; ------------------------------------------------------------------------------
HandleDemo     moveq    #0,d3
               lea      Demoliike(pc),a0
               move.l   demomoveind,d0
               move.b   (a0,d0),d3
               bne.s    demojatkuu        ; Jos D0:ssa 0, niin pois demosta
               rts
demojatkuu     bsr      Nappis
               addq.l   #1,demomoveind
               rts

;------------------------------------------------------------------------------
; SwapBitMaps
;------------------------------------------------------------------------------
SwapBitMaps    tst.b    Kumpi
               beq.s    nholla
               move.b   #0,Kumpi
               move.l   viewport,a0
               move.l   vp_RasInfo(a0),a0
               lea      ri_BitMap(a0),a0
               move.l   #myBitMap1,(a0)
               move.l   #myBitMap2,DrawBitMap
               move.l   #myBitMap1,ShowBitMap
               move.l   viewport,a0
               LibCall  GFX,ScrollVPort
               rts
nholla         move.b   #1,Kumpi
               move.l   viewport,a0
               move.l   vp_RasInfo(a0),a0
               lea      ri_BitMap(a0),a0 
               move.l   #myBitMap2,(a0)
               move.l   #myBitMap1,DrawBitMap
               move.l   #myBitMap2,ShowBitMap
               move.l   viewport,a0
               LibCall  GFX,ScrollVPort
               rts

; -----------------------------------------------------------------------------
; A0:ssa tekstin alkuosoite
; -----------------------------------------------------------------------------
Print          move.l   a0,d2
etsi_0         tst.b    (a0)+
               bne.s    etsi_0
               subq.l   #1,a0
               sub.l    d2,a0
               move.l   a0,d3
               move.l   outfile,d1
               LibCall  Dos,Write
               rts


;-------------------------------------------------------------------------------
; Hoidellaan kartalla vaeltavat hahmot
;-------------------------------------------------------------------------------
HandleCharacters
               addq.b   #1,mm_delay

               move.l   hahmot,a3
;               lea      Hahmot,a3
hahmosil       cmp.l    #0,20(a3)         ; Jos hahmo ei ole elossa, niin
               beq      seuraava          ; mennÀÀn seuraavan kohdalle

               move.l   OmaHahmo,d0       ; Pelaajan MapX
               move.l   OmaHahmo+4,d1     ; Pelaajan MapY
               move.l   (a3),d2           ; Hahmon x-koordinaatti
               move.l   4(a3),d3          ; Hahmon y-koordinaatti

               cmp.b    #4,mm_delay       ; 3*4 framen viive
               bne.s    visible           ; Aina kuitenkin piirretÀÀn, jottei
                                          ; kartta peitÀ

               move.l   16(a3),d5         ; Liikkuvako?
               tst.l    d5                ; Onko hahmo liikkuva?
               bmi.s    visible           ; Ei, katsotaan onko nÀkyvissÀ
               bsr      MoveCharacter

visible        move.l   (a3),d2           ; Hahmon x-koordinaatti
               move.l   4(a3),d3          ; Hahmon y-koordinaatti
               move.l   OmaHahmo,d0       ; Pelaajan MapX
               move.l   OmaHahmo+4,d1     ; Pelaajan MapY
               sub.l    d0,d2
               cmp.l    #0,d2             ;
               blt.s    seuraava          ; Jos PelaajaX - HahmoX 0 !
               move.l   d0,(a0)+

               addq.l   #2,d2
               cmp.l    #10,d2            ; Jos rivi monstereita tÀynnÀ,
               ble.s    cont              ; niin aloitetaan seuraava kaksi
               moveq    #3,d2             ; blockia alempaa
               addq.l   #2,d3
cont           dbf      d7,bmsil
               move.l   #$ffffffff,(a0)   ; Loppumerkki monstereille

               movem.l  (sp)+,d0-d4
               
; TÀytetÀÀn taistelukenttÀ blockeista, so. piirretÀÀn kyseinen kenttÀ

FillField      moveq    #42,d3            ; BltBitMap: Kohteen y-koord.
               moveq    #11-1,d7          ; y: 11 blockia
fbfsil_y       moveq    #13-1,d6          ; x: 13 blockia
               moveq    #56,d2            ; BltBitMap: Kohteen x-koord.
fbfsil_x       moveq    #0,d0
               move.w   (a2)+,d0
               lsl.l    #4,d0             ; Blockin jÀrj.no. pixeleiksi (x)

               movem.l  d6-d7/a2,-(sp)

;               move.l   blockScreen,a0
;               lea      sc_BitMap(a0),a0  ; LĂ€hde bitmap-structuren osoite
               moveq    #0,d1             ; LÀhde: YlÀkulman y-koord.
               move.l   MinunNaytto,a1    ; Kohde bitmap-structuren
               lea      sc_BitMap(a1),a1  ; osoite
               move.l   #16,d4            ; x-koko
               move.l   #16,d5            ; y-koko
               move.l   #$c0,d6           ; Minterm
               move.l   #$1f,d7           ; 5 bittitasoa
               lea      Puskuri,a2        ; Puskuri
;               LibCall  GFX,BltBitMap
               
               movem.l  (sp)+,d6-d7/a2

               add.l    #16,d2
               dbf      d6,fbfsil_x
               add.l    #16,d3
               dbf      d7,fbfsil_y
               rts

;-------------------------------------------------------------------------------
; Blitataan taistelutilanteen monsteri
; - HUOM! Muista, ettÀ LibCall-makro kÀyttÀÀ A6:sta !
;-------------------------------------------------------------------------------
BlitBattleMonster
               movem.l  d0-d7/a0-a6,-(sp)

;               move.l   blockScreen,a0
;               lea      sc_BitMap(a0),a0  ; LĂ€hde bitmap-structuren osoite
               lsl.l    #4,d0             ; LÀhde: YlÀkulman x-koord.
               moveq    #0,d1             ; LÀhde: YlÀkulman y-koord.
               move.l   MinunNaytto,a1    ; Kohde bitmap-structuren
               lea      sc_BitMap(a1),a1  ; osoite
               lsl.l    #4,d2             ; Kohde: x-koord.
               lsl.l    #4,d3             ; Kohde: y-koord.
               add.l    #56,d2            ; KeskitetÀÀn koordinaatit
               add.l    #42,d3            ; karttanÀkymÀÀn
               move.l   #16,d4            ; x-koko
               move.l   #16,d5            ; y-koko
               move.l   #$c0,d6           ; Minterm
               moveq    #$1f,d7           ; 5 bittitasoa
               lea      Puskuri,a2        ; Puskuri
;               LibCall  GFX,BltBitMap

               movem.l  (sp)+,d0-d7/a0-a6
               rts

;-------------------------------------------------------------------------------
; Loppuhuipentuma!
;-------------------------------------------------------------------------------
LoppuHuipentuma
               move.l   a1,-(sp)
               movem.l  d0-d7/a0-a6,-(sp)
               jsr      _StopPlayer
               move.w   #1,_modnum
               move.l   _mymodule,a0
               jsr      _PlayModule
               movem.l  (sp)+,d0-d7/a0-a6

               move.l   #Lovefield+8,a3
               bsr      DrawField

               move.l   #16,d0
               lsl.w    #1,d0             ; Wordeiksi
               lsl.w    #4,d0             ; *16
                                          ; Muualla koodissa tÀmÀ on muodossa
                                          ; LSL.W #5,D0

               move.l   #1+7+41*40,d2     ; ((320-13*16)/2)/8 + 41*40
               add.l    #6*(16/8),d2
               add.l    #5*40*16,d2
               move.l   #boyMask(pc),a2
               bsr      DrawMonster


               move.l   #17,d0
               lsl.w    #1,d0             ; Wordeiksi
               lsl.w    #4,d0             ; *16
                                          ; Muualla koodissa tÀmÀ on muodossa
                                          ; LSL.W #5,D0

               move.l   #1+7+41*40,d2     ; ((320-13*16)/2)/8 + 41*40
               add.l    #5*(16/8),d2
               add.l    #5*40*16,d2
               move.l   #girlMask(pc),a2
               bsr      DrawMonster

               move.b   #1,DemoDone
               move.l   (sp)+,a1
               rts

;------------------------------------------------------------------------------
; Hoidellaan "pelaaja" ("oma hahmo").
; Pelaajan karttakoordinaatit tarkoittavat paikkaa kulloisenkin nÀkymÀn
; vasemassa ylÀkulmassa. Kuvaruudelle hahmo piirretÀÀn kuitenkin keskelle,
; jolloin hahmon aktuaalinen paikka kartalla on eri kuin nÀkymÀn vasenta
; ylÀkulmaa vastaava paikka kartalla.
;------------------------------------------------------------------------------
HandlePlayer
               lea      OmaHahmo,a0
               move.l   8(a0),d4          ; x-koordinaatti (screen)
               move.l   12(a0),d5         ; y-koordinaatti (screen)
;               move.l   16(a0),d0         ; Graafinen jÀrjestysnumero
;              lsl.l    #5,d0             ; 4 + 1

               move.l   20(a0),d6         ; SÀdekehÀ on/off
               beq.s    ei_kehaa

               subq.l   #1,20(a0)
               cmp.l    #0,20(a0)
               bgt.s    sadekehaon
               move.l   #0,20(a0)
               bra.s    ei_kehaa

sadekehaon     
               move.l   Om_Naytto,a0
               lea      sc_BitMap(a0),a0
               move.l   #159,d0
               moveq    #0,d1
               move.l   DrawBitMap,a1
               move.l   #56+5*16,d2
               add.l    d4,d2
               move.l   #41+4*16,d3
               add.l    d5,d3
               moveq    #48,d4
               moveq    #48,d5
               move.l   #$c0,d6           ; Minterm
               moveq    #31,d7
               LibCall  GFX,BltBitMap
               rts

ei_kehaa       move.l   #16*2*16,d0
               move.l   #4859,d2          ; ((320-13*16)/2)/8 + 41*40 +
                                          ; 6*(16/8) + (5*16)*40
               move.l   8(a0),d4          ; x-koordinaatti (screen)
               move.l   12(a0),d5         ; y-koordinaatti (screen)
               asr.l    #3,d4             ; screenX pixeleistÀ tavuiksi
               add.l    d4,d2
               muls     #40,d5
               add.l    d5,d2

               bsr      DrawBlock         ; D0 = lÀhde-osoitteeseen lisÀttÀvÀ
                                          ; paikka, D2 = kohde-osoitteeseen
                                          ; lisÀttÀvÀ paikka
               rts


;------------------------------------------------------------------------------
; Scrollaus
;------------------------------------------------------------------------------
TextScroll     
               cmp.b    #0,Laskuri
               bne      kopioi

; PyyhitÀÀn vanha kirjain pois. VÀristÀ johtuen 4:n bittitason
; kÀsittely riittÀÀ.

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   8(a0),a0          ; BitPlane1
               add.l    #124*40,a0
               moveq    #14-1,d7
csil1          move.w   #0,(a0)
               add.l    #40,a0
               dbf      d7,csil2

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   12(a0),a0         ; BitPlane2
               add.l    #124*40,a0
               moveq    #14-1,d7
csil2          move.w   #0,(a0)
               add.l    #40,a0
               dbf      d7,csil2

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   16(a0),a0         ; BitPlane3
               add.l    #124*40,a0
               moveq    #14-1,d7
csil3          move.w   #0,(a0)
               add.l    #40,a0
               dbf      d7,csil3

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   20(a0),a0         ; BitPlane4
               add.l    #124*40,a0
               moveq    #14-1,d7
csil4          move.w   #0,(a0)
               add.l    #40,a0
               dbf      d7,csil4

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   24(a0),a0         ; BitPlane5
               add.l    #124*40,a0
               moveq    #14-1,d7
csil5          move.w   #0,(a0)
               add.l    #40,a0
               dbf      d7,csil5

; Tulostetaan uusi kirjain

               move.l   Om_rastport,a1
               moveq    #13,d0               ; Fontin vÀri
               LibCall  GFX,SetAPen

               move.l   Om_rastport,a1     ; PiirtokynÀ scrollWindowin "origoon"
               moveq    #0,d0
               move.l   #33+100,d1        ; Huomaa fontin baseline
               LibCall  GFX,Move

               move.l   Om_rastport,a1
               lea      ScrolliTeksti(pc),a0
               move.l   TextInd,d0
               add.l    d0,a0
               cmp.b    #0,(a0)
               bne.s    notrestart
               rts                        ; Scrolleri ei tÀssÀ versiossa
                                          ; restartoidu
;               move.l   #0,TextInd
;               lea      ScrolliTeksti,a0
notrestart     moveq    #1,d0             ; Tulostetaan yksi kirjain
               LibCall  GFX,Text

               move.b   #FONTWIDTH,Laskuri
               addq.l   #1,TextInd
               move.l   #0,CopyInd

; Kopioidaan blockWindowista pala kirjainta scrollaavaan ikkunaan

kopioi         move.l   Om_rastport,a0
               move.l   CopyInd,d0        ; LĂ€hde x-koord
               move.l   #25+100,d1        ; LĂ€hde y-koord
               move.l   Om_rastport,a1
               move.l   #318,d2           ; Kohde x-koord
               move.l   #0+100,d3         ; Kohde y-koord
               moveq    #2,d4             ; x-koko
               moveq    #14,d5            ; y-koko
               move.l   #$c0,d6           ; Minterm
               LibCall  GFX,ClipBlit

; Scrollataan scrolli-ikkunalla

               move.l   Om_rastport,a1
               moveq    #2,d0             ; x-steppi
               moveq    #0,d1             ; y-steppi
               moveq    #0,d2             ; x1
               move.l   #100,d3           ; y1
               move.l   #319,d4           ; x2
               move.l   #112,d5           ; y2
               LibCall  GFX,ScrollRaster

               subq.b   #1,Laskuri
               addq.l   #2,CopyInd

; PyyhitÀÀn scrollitekstialue kokonaan (320*16)

               moveq    #0,d0
               moveq    #0,d1
               moveq    #0,d2
               moveq    #0,d3
               moveq    #0,d4
               moveq    #0,d5
               moveq    #0,d6

               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   8(a1),a1          ; BitPlane1
               add.l    #235*40,a1
               moveq    #22-1,d7          ; 616 tavua
cs1            movem.l  d0-d6,(a1)        ; 28 tavua
               add.l    #28,a1
               dbf      d7,cs1
               movem.l  d0-d5,(a1)        ; 24 tavua

               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   12(a1),a1          ; BitPlane2
               add.l    #235*40,a1
               moveq    #21,d7            ;
cs2            movem.l  d0-d6,(a1)
               add.l    #28,a1
               dbf      d7,cs2
               movem.l  d0-d5,(a1)        ; 24 tavua

               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   16(a1),a1          ; BitPlane3
               add.l    #235*40,a1
               moveq    #21,d7            ;
cs3            movem.l  d0-d6,(a1)
               add.l    #28,a1
               dbf      d7,cs3
               movem.l  d0-d5,(a1)        ; 24 tavua

               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   20(a1),a1          ; BitPlane4
               add.l    #235*40,a1
               moveq    #21,d7            ;
cs4            movem.l  d0-d6,(a1)
               add.l    #28,a1
               dbf      d7,cs4
               movem.l  d0-d5,(a1)        ; 24 tavua

               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   24(a1),a1          ; BitPlane5
               add.l    #235*40,a1
               moveq    #22-1,d7          ;
cs5            movem.l  d0-d6,(a1)
               add.l    #28,a1
               dbf      d7,cs5
               movem.l  d0-d5,(a1)        ; 24 tavua

; Kopsataan yksöispuskurointi-scrollin gfx DrawBitMappiin. Kopsaus hoidetaan
; omalla CPU-pohjaisella rutiinilla. PitÀÀ tarkistaa MOVE16-kÀskyn tapaa
; viitata muistiosoitteisiin; nÀyttÀÀ todella olevan jotain hÀssÀkkÀÀ
; CHIP-muistin kanssa...

;              lea      Pomppu,a2
;              add.l    pind,a2
;              move.l   (a2),d0
;              cmp.l    #1,d0
;              bne.s    nou
;              move.l   #-4,pind
;              moveq    #0,d0
;nou           addq.l   #4,pind

               lea      Pomppu2(pc),a2
               add.l    pind,a2
               move.l   (a2),d0
               cmp.l    #1,d0
               bne.s    nouh2
               move.l   #-4,pind
               moveq    #0,d0
nouh2          addq.l   #4,pind

               lea      Pomppu2(pc),a2
               add.l    pind2,a2
               move.l   (a2),d1
               cmp.l    #1,d1
               bne.s    nou2
               move.l   #-4,pind2
               moveq    #0,d1
nou2           addq.l   #4,pind2

; Kopioidaan scrolliscreeniltÀ scrollaus paikalleen pomppudatojen kera

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   8(a0),a0          ; BitPlane1
               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   8(a1),a1          ; BitPlane1
               add.l    #100*40,a0
               add.l    #237*40,a1
               add.l    d0,a1
               moveq    #120-1,d7         ; (30-1 = ((320/8) * 12) / 16 )
copysil1       move.l   (a0)+,(a1)+       ; (move16)
               dbf      d7,copysil1

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   12(a0),a0          ; BitPlane2
               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   12(a1),a1          ; BitPlane2
               add.l    #100*40,a0
               add.l    #237*40,a1
               moveq    #120-1,d7
copysil2       move.l   (a0)+,(a1)+
               dbf      d7,copysil2

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   16(a0),a0         ; BitPlane3
               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   16(a1),a1         ; BitPlane3
               add.l    #100*40,a0
               add.l    #237*40,a1
               add.l    d1,a1
               moveq    #120-1,d7         ; 30-1
copysil3       move.l   (a0)+,(a1)+
               dbf      d7,copysil3

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   20(a0),a0         ; BitPlane4
               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   20(a1),a1         ; BitPlane4
               add.l    #100*40,a0
               add.l    #237*40,a1
               add.l    d1,a1
               moveq    #120-1,d7         ; 30-1
copysil4       move.l   (a0)+,(a1)+
               dbf      d7,copysil4

               move.l   Om_Naytto,a0      ; LĂ€hde-screenin
               lea      sc_BitMap(a0),a0  ; bitmap-structuren osoite
               move.l   24(a0),a0         ; BitPlane5
               move.l   ShowBitMap,a1     ; Kohde-bitmap -structuuri
               move.l   24(a1),a1         ; BitPlane5
               add.l    #100*40,a0
               add.l    #237*40,a1
               add.l    d1,a1
               moveq    #120-1,d7         ; 30-1
copysil5       move.l   (a0)+,(a1)+
               dbf      d7,copysil5

               rts

;------------------------------------------------------------------------------
; PiirretÀÀn 16*16 monster; erona DrawBlock-rutiiniin se, ettÀ grafiikka
; "OR'itetaan" taustagrafiikan kanssa.
;------------------------------------------------------------------------------
DrawMonster    movem.l  d5-d7/a0/a3,-(sp)

               move.l   DrawBitMap,a3
               move.l   #blockplane1,a0
               add.l    d0,a0             ; Source
               move.l   8(a3),a1          ; Dest, BitPlane1
               add.l    d2,a1
               moveq    #15,d5            ; 16 pixeliÀ
dmbpl1sil      move.w   (a0)+,d6
               move.w   (a1),d7
               and.w    (a2)+,d7
               or.w     d6,d7
               move.w   d7,(a1)
               add.l    #40,a1
               dbf      d5,dmbpl1sil

               sub.l    #32,a2
               move.l   #blockplane2,a0
               add.l    d0,a0             ; Source
               move.l   12(a3),a1         ; Dest, BitPlane2
               add.l    d2,a1
               moveq    #15,d5
dmbpl2sil      move.w   (a0)+,d6
               move.w   (a1),d7
               and.w    (a2)+,d7
               or.w     d6,d7
               move.w   d7,(a1)
               add.l    #40,a1
               dbf      d5,dmbpl2sil

               sub.l    #32,a2
               move.l   #blockplane3,a0
               add.l    d0,a0             ; Source
               move.l   16(a3),a1         ; Dest, BitPlane3
               add.l    d2,a1
               moveq    #15,d5
dmbpl3sil      move.w   (a0)+,d6
               move.w   (a1),d7
               and.w    (a2)+,d7
               or.w     d6,d7
               move.w   d7,(a1)
               add.l    #40,a1
               dbf      d5,dmbpl3sil

               sub.l    #32,a2
               move.l   #blockplane4,a0
               add.l    d0,a0             ; Source
               move.l   20(a3),a1         ; Dest, BitPlane4
               add.l    d2,a1
               moveq    #15,d5
dmbpl4sil      move.w   (a0)+,d6
               move.w   (a1),d7
               and.w    (a2)+,d7
               or.w     d6,d7
               move.w   d7,(a1)
               add.l    #40,a1
               dbf      d5,dmbpl4sil

               sub.l    #32,a2
               move.l   #blockplane5,a0
               add.l    d0,a0             ; Source
               move.l   24(a3),a1         ; Dest, BitPlane5
               add.l    d2,a1
               moveq    #15,d5
dmbpl5sil      move.w   (a0)+,d6
               move.w   (a1),d7
               and.w    (a2)+,d7
               or.w     d6,d7
               move.w   d7,(a1)
               add.l    #40,a1
               dbf      d5,dmbpl5sil

               movem.l  (sp)+,d5-d7/a0/a3
               rts

;-------------------------------------------------------------------------------
; VÀrien kierrÀtykset (2 kpl)
; Idea: Ohjelman alussa kierrÀtettÀvÀt vÀrit on kopioitu omaan taulukkoonsa.
; KierrÀtysrutiinissa tÀstÀ taulukosta vÀriarvot kopioidaan varsinaiseen
; vÀritaulukkoon positioihin (k...k+4) siten, ettÀ ensimmÀinen kopioitava
; vÀri on kopiotaulukon vÀrinumero (jÀrj.numero), minkÀ ilmoittaa
; muuttuja "cind".
;-------------------------------------------------------------------------------
ColourCycling
               moveq    #0,d0
               move.l   #colortable+32,a0    ; 16. wordin kohdalle
               move.l   #copytable,a1

; KierrÀtetÀÀn vÀrit 16..19 (1. vÀri on numero 0)

               moveq    #4-1,d7
               move.b   cind,d0
ccsil          move.w   (a1,d0.b),(a0)+
               addq.l   #2,d0
               cmp.l    #8,d0
               blt.s    kunnossa
               moveq    #0,d0
kunnossa       dbf      d7,ccsil

; KierrÀtetÀÀn vÀrit 20..23 (1. vÀri on numero 0)

               move.l   #copytable+8,a1      ; 8 = 4*2
               moveq    #4-1,d7
               move.b   cind,d0
ccsil2         move.w   (a1,d0.b),(a0)+
               addq.l   #2,d0
               cmp.l    #8,d0
               blt.s    kunnossa2
               moveq    #0,d0
kunnossa2      dbf      d7,ccsil2

; cind-muuttujan (indikaattori vÀritaulukkoon) muuttaminen saa aikaan
; lopulta vÀrien kierrÀtyksen

               addq.b   #2,cind
               cmp.b    #8,cind
               blt.s    indok
               move.b   #0,cind

indok          move.l   viewport,a0
               lea      colortable,a1
               moveq    #32,d0
               LibCall  GFX,LoadRGB4

               rts

;------------------------------------------------------------------------------
; PiirretÀÀn kartta (13*11 blockia), A3 = osoite karttaan
;------------------------------------------------------------------------------
DrawField      movem.l  d0-d7,-(sp)

               moveq    #0,d0
               move.l   #7+41*40,d2       ; ((320-13*16)/2)/8 + 41*40
               moveq    #VISIBLE_BLOCKS_Y,d7
mapsildf       moveq    #VISIBLE_BLOCKS_X,d6
xsildf

; Lasketaan paikka, mistÀ piirretÀÀn (D0)

               move.w   (a3)+,d0          ; Blockin "y-koordinaatti"
               lsl.w    #5,d0             ; 4+1

; Kopioidaan blocki blockbitmapista...

               bsr      DrawBlock

               addq.l   #2,d2
               dbf      d6,xsildf
               add.l    #40*16-(13*2),d2
               dbf      d7,mapsildf       ; "ysil"

               movem.l  (sp)+,d0-d7
               rts

;------------------------------------------------------------------------------
; PiirretÀÀn 16*16 blocki
;------------------------------------------------------------------------------
DrawBlock      movem.l  d5/a0-a2,-(sp)

               move.l   DrawBitMap,a2
               move.l   #blockplane1,a0
               add.l    d0,a0             ; Source
               move.l   8(a2),a1          ; Dest, BitPlane1
               add.l    d2,a1
               moveq    #15,d5            ; 16 pixeliÀ
dbpl1sil       move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,dbpl1sil

               move.l   #blockplane2,a0
               add.l    d0,a0             ; Source
               move.l   12(a2),a1         ; Dest, BitPlane2
               add.l    d2,a1
               moveq    #15,d5
dbpl2sil       move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,dbpl2sil

               move.l   #blockplane3,a0
               add.l    d0,a0             ; Source
               move.l   16(a2),a1         ; Dest, BitPlane3
               add.l    d2,a1
               moveq    #15,d5
dbpl3sil       move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,dbpl3sil

               move.l   #blockplane4,a0
               add.l    d0,a0             ; Source
               move.l   20(a2),a1         ; Dest, BitPlane4
               add.l    d2,a1
               moveq    #15,d5
dbpl4sil       move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,dbpl4sil

               move.l   #blockplane5,a0
               add.l    d0,a0             ; Source
               move.l   24(a2),a1         ; Dest, BitPlane5
               add.l    d2,a1
               moveq    #15,d5
dbpl5sil       move.w   (a0)+,(a1)
               add.l    #40,a1
               dbf      d5,dbpl5sil

               movem.l  (sp)+,d5/a0-a2
               rts

;------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------
MainLoppu      move.b   #0,Demoonko
mloop          tst.b    Quit
               bne      CleanUp

;               move.l   viewport,a0      ; mloop-kokonaisuus vaikuttaa
;               LibCall  GFX,WaitBOVP     ; olevan liian nopea WaitBOVP:lle
               LibCall  GFX,WaitTOF

               bsr      TextScroll                                     

               addq.b   #1,Demoonko
               cmp.b    #8,Demoonko
               blt.s    mliv
               bsr      ColourCycling
               move.b   #0,Demoonko

mliv           bsr      ikkunanviestit

               cmp.b    #1,RestartAll
               bne.s    mloop

; Restartoidaan kaikki ...

               bsr      InitGhosts
               move.b   #0,DemoDone
               move.b   #1,DemoMode
               move.b   #0,RestartAll
               move.b   #0,Demoonko
               move.l   #0,demomoveind
               move.l   #0,TextInd
               move.l   #0,CopyInd
               move.l   #4*11,pind
               move.l   #0,pind2
               move.b   #0,cind
               move.b   #0,Laskuri
               move.l   #0,frameY
               move.b   #FONTWIDTH,Laskuri
               move.l   #13,FontColor

               lea      OmaHahmo,a0
               move.l   #0,(a0)+
               move.l   #0,(a0)+
               move.l   #-48,(a0)+
               move.l   #-48,(a0)+
               move.l   #16,(a0)+
               move.l   #0,(a0)+

               jsr      _StopPlayer
               move.w   #0,_modnum
               move.l   _mymodule,a0
               jsr      _PlayModule

               bra      MainProgram


;------------------------------------------------------------------------------
; Tulostetaan alkukuva pisteittÀin nÀkyviin.
; HUOM! NÀmÀ FadeIn ja FadeOut-rutiinit vaativat, ettÀ kuvassa ei ole
; pohjavÀrinÀ vÀriÀ 0!
;------------------------------------------------------------------------------
FadeIn         move.l   #2860-1,d7           ; 110*24 - 1 (pisteiden mÀÀrÀ)
               move.b   #0,points            ; 110*26

; Aluksi arvotaan tarvittaessa 20-1 kertaa piste; jos ei saada vapaata
; pistettÀ, niin siirrytÀÀn sellaiseen mekaanisesti.

rsil           moveq    #20,d6
readpixel      bsr      ArvoXjaY             ; Arvotaan x- ja y-koordinaatti
               move.l   o_rastport,a1
               move.l   x,d0
               move.l   y,d1
               LibCall  GFX,ReadPixel
               cmp.l    #0,d0                ; Jos arvotussa pisteessÀ ei ole
               beq.s    drawpix              ; pistettÀ, niin tulostetaan...
               dbf      d6,readpixel

; SiirrytÀÀn mekaanisesti vapaaseen pisteeseen.
; Jos rutiinin alussa kokonaispistemÀÀrÀ on laitettu liian suureksi, jÀÀdÀÀn
; ikuiseen silmukkaan...

readpixel2     move.l   o_rastport,a1
               move.l   x,d0
               move.l   y,d1
               LibCall  GFX,ReadPixel
               cmp.l    #0,d0                ; Jos arvotussa pisteessÀ ei ole
               beq.s    drawpix              ; pixeliÀ, niin tulostetaan...
                                             
               addq.l   #1,x
               cmp.l    #110,x
               bge.s    addy
               bra      readpixel2
addy           addq.l   #1,y
               move.l   #0,x
               cmp.l    #26,y
               bge.s    zeroy
               bra      readpixel2
zeroy          move.l   #0,y
               bra      readpixel2


drawpix        move.l   Om_rastport,a1
               move.l   x,d0
               move.l   y,d1  
               LibCall  GFX,ReadPixel        ; Laittaa D0:aan vÀrirekisterin
                                             ; jÀrjestysnumeron

               move.l   o_rastport,a1
               LibCall  GFX,SetAPen          

               addq.b   #1,points            ; Tulostetaan 10 pistettÀ
               cmp.b    #10,points           ; framessa
               bne.s    nowait
               move.b   #0,points
               LibCall  GFX,WaitTOF
nowait
               move.l   x,d0
               move.l   y,d1
               move.l   o_rastport,a1
               LibCall  GFX,WritePixel

               move.w   $dff006,rnd_more     ; Satunnaisuuden lisÀÀntymisen
                                             ; toivossa...
               dbf      d7,rsil
               rts

;------------------------------------------------------------------------------
; HÀvitetÀÀn alkukuva pisteittÀin
;------------------------------------------------------------------------------
FadeOut        move.l   #2640-1,d7           ; 110*24 - 1 (pisteiden mÀÀrÀ)
               move.b   #0,points

; Aluksi arvotaan tarvittaessa 20-1 kertaa piste; jos ei saada sopivaa
; pistettÀ (pisteessÀ oltava pixeli), niin siirrytÀÀn sellaiseen mekaanisesti

orsil          moveq    #20,d6
oreadpixel     bsr      ArvoXjaY             ; Arvotaan x- ja y-koordinaatti
               move.l   o_rastport,a1
               move.l   x,d0
               move.l   y,d1
               LibCall  GFX,ReadPixel
               cmp.l    #0,d0                ; Jos arvotussa pisteessÀ on
               bne.s    odrawpix             ; pixeli, niin pyyhitÀÀn se...
               dbf      d6,oreadpixel

; SiirrytÀÀn mekaanisesti sopivaan pisteeseen.
; Jos rutiinin alussa kokonaispistemÀÀrÀ on laitettu liian suureksi, jÀÀdÀÀn
; ikuiseen silmukkaan...

oreadpixel2    move.l   o_rastport,a1
               move.l   x,d0
               move.l   y,d1
               LibCall  GFX,ReadPixel
               cmp.l    #0,d0                ; Jos arvotussa pisteessÀ on
               bne.s    odrawpix             ; pixeli, niin pyyhitÀÀn...
                                             
               addq.l   #1,x
               cmp.l    #110,x
               bge.s    oaddy
               bra      oreadpixel2
oaddy          addq.l   #1,y
               move.l   #0,x
               cmp.l    #24,y
               bge.s    ozeroy
               bra      oreadpixel2
ozeroy         move.l   #0,y
               bra      oreadpixel2


odrawpix       move.l   o_rastport,a1
               moveq    #0,d0                ; TaustavÀri piirtovÀriksi
               LibCall  GFX,SetAPen          

               addq.b   #1,points            ; Tulostetaan 12 pistettÀ
               cmp.b    #12,points           ; framessa
               bne.s    onowait
               move.b   #0,points
               LibCall  GFX,WaitTOF
onowait
               move.l   x,d0
               move.l   y,d1
               move.l   o_rastport,a1
               LibCall  GFX,WritePixel

               move.w   $dff006,rnd_more     ; Satunnaisuuden lisÀÀntymisen
                                             ; toivossa...
               dbf      d7,orsil
               rts

;-------------------------------------------------------------------------------
; Arvotaan x- ja y-koord. FadeIn ja FadeOut-rutiineille.
; Satunnaisluku siis vÀleille x in [0,109] ja y in [0,23]
; VÀlin ylÀreunaan ei nÀemmÀ tahdo saada useinkaan suoraan arvoa, mistÀ syystÀ
; tÀssÀ arvotaan luku vÀleille [0,110] ja [0,24] sekÀ tarvittaessa vÀhennetÀÀn
; luku 1.
;-------------------------------------------------------------------------------
ArvoXjaY       move.b   $bfe601,d0           ; Arvotaan x
               fmove.w  d0,fp0

               move.w   $dff006,d0
               move.w   rnd_more,d2
               mulu.l   d2,d0
               move.w   d0,rnd_more
               fmove.w  d0,fp1

               fmul.l   fp0,fp1
               fsin.l   fp1
               fmul.l   #110,fp1              ; Satunnaisluvut vÀlillÀ 0-109
               fabs.l   fp1
               fmove.l  fp1,d0
               cmp.l    #110,d0              ; *
               bne.s    arvoy
               subq.l   #1,d0

arvoy          move.b   $bfe601,d1           ; Arvotaan y
               fmove.w  d1,fp0

               move.w   $dff006,d1
               move.w   rnd_more,d2
               mulu     d2,d1
               fmove.w  d1,fp1

               fmul.l   fp0,fp1
               fsin.l   fp1
               fmul.l   #24,fp1              ; Satunnaisluvut vÀlillÀ 0-23
               fabs.l   fp1
               fmove.l  fp1,d1
               cmp.l    #24,d1
               bne.s    savexy
               subq.l   #1,d1

savexy         and.l    #$0000ffff,d0        ; Vain 16-bittinen osa
               and.l    #$0000ffff,d1        ; koordinaatteja varten jÀljelle
               move.l   d0,x                 ; Talletetaan koordinaatit
               move.l   d1,y                 ; muistiosoitteisiin x ja y
               rts

;------------------------------------------------------------------------------
; RND(x)
; - YlÀraja luvulle on annettu rekisterissÀ D4, ohjelma arpoo kuitenkin
;   luvun vÀliltÀ [0,D4+1], ja tarvittaessa vÀhentÀÀ tuloksesta yhden
;------------------------------------------------------------------------------

Random         movem.l  d0-d2,-(sp)
               move.l   d4,d2
               addq.l   #1,d2
               fmovecr  #0,fp0               ; Pii
               fdiv.l   #180,fp0             ; 1 aste radiaaneina
               move.b   $bfe601,d0           ; Arvotaan x
               move.w   $dff006,d1
               mulu.l   d1,d0
               fmul.l   d0,fp0
               fsin.l   fp0
               fabs.l   fp0
               fmul.l   d2,fp0
               fmove.l  fp0,d0
               cmp.l    d4,d0                ; Jos "arvottu" luku on suurempi
               ble.s    arvoOK               ; (+1) kuin annettu ylÀraja, niin
               subq.l   #1,d0                ; vÀhennetÀÀn yksi

arvoOK         move.l   d0,rnd_number
               movem.l  (sp)+,d0-d2
               rts

;-------------------------------------------------------------------------------
; Arvotaan muutamalle mörölle koordinaatit
;-------------------------------------------------------------------------------
InitGhosts     moveq    #10-1,d7
               lea      tenghosts,a0
IGSil          moveq    #MAP_WIDTH-1,d4
               bsr      Random
               move.l   rnd_number,d0
               moveq    #MAP_HEIGHT-1,d4
               bsr      Random
               move.l   rnd_number,d1

; Katsotaan onko arvotussa paikassa blocki, minkÀ pÀÀlle ei saa mennÀ

               move.l   d0,d2                ; Työkopiot x:stÀ
               move.l   d1,d3                ; ja y:stÀ
               move.l   gamefield,a2
               lsl.w    #1,d2                ; Hahmon mapX parilliseksi
               lsl.w    #1,d3                ; Hahmon mapY parilliseksi
               mulu.w   #MAP_WIDTH,d3
               add.l    d3,d2
               add.l    d2,a2
               cmp.w    #RED_TILE,(a2)
               beq.s    IGSil
               cmp.w    #COL_TILE,(a2)
               beq.s    IGSil
               cmp.w    #LOW_WATER,(a2)
               beq.s    IGSil
               cmp.w    #DEEP_WATER,(a2)
               beq.s    IGSil

               move.l   #monster_map,a1
               add.l    d2,a1
               cmp.w    #0,(a1)
               bne.s    IGSil
               move.w   #GHOST,(a1)          ; Kirjataan mörkö monster_map'iin
               
               move.l   d0,(a0)+             ; Monsterin x
               move.l   d1,(a0)+             ; Monsterin y
               move.l   #GHOST,(a0)+         ; Blockin jÀrjestysnumero
               move.l   #GhostMask,(a0)+
               move.l   #0,(a0)+             ; Liikkuvako (0 = liikkuva)
               move.l   #1,(a0)+
               dbf      d7,IGSil

; Kirjoitetaan kuitenkin erilliset liikkumattomat hahmot monster_map'iin

               lea      Hahmot,a0
               move.l   #monster_map,a1
               move.l   (a0),d0
               move.l   4(a0),d1
               lsl.w    #1,d0                ; Hahmon mapX parilliseksi
               lsl.w    #1,d1                ; Hahmon mapY parilliseksi
               mulu.w   #MAP_WIDTH,d1
               add.l    d1,d0
               add.l    d0,a1
               move.l   8(a0),d2
               move.w   d2,(a1)              ; Kirjataan hahmon gfx-numero
                                             ; monster_map'iin

; Initioidaan "kaupungin" hahmokartta...

               lea      Ihmiset_Town,a0
itsil          lea      TownHahmoMap,a1
               cmp.l    #-1,(a0)
               beq.s    exitinit
               move.l   (a0)+,d0             ; Otetaan hahmon x-koord
               move.l   (a0)+,d1             ;         hahmon y-koord
               subq.l   #1,d0                ; HUOM!!!
               lsl.w    #1,d0
               lsl.w    #1,d1
               mulu.w   #MAP_WIDTH,d1
               add.l    d0,a1                ; MennÀÀn hahmon koordinaatteja
               add.l    d1,a1                ; vastaavaan paikkaan
               move.l   (a0)+,d2             ;         hahmon gfx-numero
               move.l   d2,(a1)              ; Kirjataan hahmo hahmokarttaan
               add.l    #12,a0               ; Seuraavan hahmon kohdalle
               bra.s    itsil
exitinit       rts

;-------------------------------------------------------------------------------
; Integer2ASCII_32bit, '020 + FPU version. Coded by Markus Ketola 4/2000.
; Uses CPU registers D0-D3,D7 & A2 and FPU register FP0.
;
; - Converts 32 bit unsigned integer given in D0 to ASCII, destination
;   address (where the digits are stored) is given in A2
;-------------------------------------------------------------------------------
Integer2ASCII_32bit
               movem.l  d0-d7/a0-a6,-(sp)

               lea      Number,a2            ; The digits will be stored here

               cmp.l    #0,d0                ; If the number to be converted is
               beq      justzero             ; 0 we skip the actual converting
                                             ; and write directly ASCII code of
                                             ; 0. Also, LOG10(0) is not defined;
                                             ; FLOG10 FP0 would crash the
                                             ; machine if FP0 = 0.

               fmove.x  #0,fp0
               fmove.l  d0,fp0               ; Number to be converted to FP0
               moveq    #0,d2
               moveq    #0,d3
               moveq    #0,d7

; Count the amount of digits; n = trunc(LOG10(number)) + 1

               flog10.l fp0                  ; LOG10
               fmove.l  fp0,d7               ; Minus 1 for loop below
                                             ; "internally included" :)

; Convert given 32 bit unsigned integer to its ASCII version

dloop          move.l   d0,d1                ; Working copy of D0

               fmove.l  d7,fp0
               ftentox.l   fp0               ; D = 10^(k-1)
               fmove.l  fp0,d3
goon                                         
               divs.l   d3,d1                ; Number / D ; reminder
                                             ; automatically disregarded
               divsl.l  #10,d2:d1            ; Divide by 10 once more;
                                             ; reminder goes to D2, which in
                                             ; fact holds the desired digit now.
               add.b    #'0',d2              ; Add ASCII code of 0 to the digit
               move.b   d2,(a2)+             ; and save the digit as ASCII...
               dbf      d7,dloop

; The actual Integer2ASCII routine ends here

               move.b   #10,(a2)             ; Line feed
               bra      printthenumber
justzero       move.b   #'0',(a2)+
               move.b   #10,(a2)

; Print the number
printthenumber lea      Number,a0
               bsr      Print                ; Print the number...

Clear_number   lea      Number,a0
               move.l   #14-1,d7
nollaa         clr.b    (a0)+
               dbf      d7,nollaa

               movem.l  (sp)+,d0-d7/a0-a6
               rts

;------------------------------------------------------------------------------
; Clean up -hommat
;------------------------------------------------------------------------------
CleanUp        jsr      _endmusic

clean          move.l   iff,d0
               beq.s    closekehys
               move.l   d0,a1
               LibCall  IFF,_LVOCloseIFF

closekehys     move.l   iff_kehysfile,d0
               beq.s    closeblock
               move.l   d0,a1
               LibCall  IFF,_LVOCloseIFF

closeblock     move.l   iff_blockfile,d0
               beq.s    suljeGFXbase
               move.l   d0,a1
               LibCall  IFF,_LVOCloseIFF

suljeGFXbase   move.l   GFXbase,d0
               beq.s    su2
               move.l   d0,a1
               LibCall  Exec,CloseLibrary
su2
               move.l   Om_Ikkuna,d0
               beq.s    sulje_1
               move.l   d0,a0
               LibCall  Intui,CloseWindow

sulje_1        move.l   Om_Naytto,d0
               beq.s    sulje_2
               move.l   d0,a0
               LibCall  Intui,CloseScreen

sulje_2        move.l   OmistusIkkuna,d0
               beq.s    sulje_IFFlib
               move.l   d0,a0
               LibCall  Intui,CloseWindow

sulje_IFFlib   move.l   IFFbase,d0
               beq.s    Loppu
               move.l   d0,a1
               LibCaLL  Exec,CloseLibrary

Loppu          move.l   MinunIkkuna,d0
               beq.s    Loppu1
               move.l   d0,a0
               LibCall  Intui,CloseWindow  

Loppu1         move.l   MinunNaytto,d0
               beq.s    Loppu2
               move.l   d0,a0
               LibCall  Intui,CloseScreen
 
Loppu2         move.l   Intuibase,d0
               beq.s    Loppu3
               move.l   d0,a1
               LibCall  Exec,CloseLibrary

Loppu3         move.l   Dosbase,d0
               beq.s    Loppu4
               move.l   d0,a1
               LibCall  Exec,CloseLibrary

Loppu4         move.l   DiskFontbase,d0
               beq.s    Loppu5
               move.l   d0,a1
               LibCall  Exec,CloseLibrary

Loppu5         move.l   Font,d0
               beq      Pois
               move.l   d0,a1
               LibCall  GFX,CloseFont

Pois           movem.l  (sp)+,d2-d7/a2-a6
               clr.l    d0
               rts

;------------------------------------------------------------------------------
; Vakioina pysyvÀÀ kamaa code-lohkon lopussa...
;------------------------------------------------------------------------------
Pomppu         dc.l  1*40,1*40,1*40,2*40,2*40,2*40
               dc.l  2*40,2*40,2*40,1*40,1*40,1*40
               dc.l  0,0,0,0,0,-1*40,-1*40,-1*40,0,0,0,0,0,1

Pomppu2        dc.l  0,0,0,-1*40,-1*40,-1*40,-2*40,-2*40,-2*40,-2*40,-1*40,-1*40,-1*40
               dc.l  0,0,0,1*40,1*40,1*40,2*40,2*40,2*40,2*40
               dc.l  2*40,2*40,2*40,2*40,1*40,1*40,1*40,0,0,0
               dc.l  -1*40,-1*40,-1*40,-2*40,-2*40,-2*40,-2*40,-1*40,-1*40,-1*40,-1*40
               dc.l  0,0,0,1

Gamefield      incbin   "Work:MyProjects/QoL/Gamefield/Map6.gamefield"
Battle_land    incbin   "Work:MyProjects/QoL/Gamefield/Battle_land.gamefield"
Battle_wood    incbin   "Work:MyProjects/QoL/Gamefield/Battle_wood.gamefield"
Battle_mount   incbin   "Work:MyProjects/QoL/Gamefield/Battle_mount.gamefield"
Lovefield      incbin   "Work:MyProjects/QoL/Gamefield/Lovefield.gamefield"
Townfield      incbin   "Work:MyProjects/QoL/Gamefield/Town.gamefield"

blockdata      incbin   "Work:MyProjects/QoL/BPLs/blocks8vert.bin"
GhostMask      incbin   "Work:MyProjects/QoL/BPLs/GhostMask_invert.bin"
boyMask        incbin   "Work:MyProjects/QoL/BPLs/boyMask_invert.bin"
girlMask       incbin   "Work:MyProjects/QoL/BPLs/girlMask_invert.bin"

; Merkit '2','4','6','8' tarkoittavat suuntia, muut merkit aiheuttavat viivettÀ,
; 0 on loppumerkki, mikÀ lopettaa demon, ja ukkoa voi ohjata nÀppikseltÀ.
Demoliike      dc.b  'ViiveViiveViiveViiveViiveViiveViive'
               dc.b  '2','2','2','4','2','2','Vii'
               dc.b  '2','6','2','6','2','2','4','2','Vii'
               dc.b  '2','4','2','6','2','2','2','6','6','Viive'
               dc.b  '8','6','6','6','8','Viive'
               dc.b  '8','8','8','8','4','8','8','6','6','Viiv'
               dc.b  '8','6','6','8','6','6','6','8','6','6','Viive'
               dc.b  '2','4','4','2','4','4','4','Vi','2','2','2','Vii'
               dc.b  '6','6','6','6','6','6','6','6','6','6','6','V','8'
               dc.b  'ViiveViiveViiveViiveViiveViiveViiveViiveViive'  ; "Joen ranta"
               dc.b  '2','4','4','4','4','4','4','4','4','4','4','4','2','2'
               dc.b  '2','2','2','2','2','2','Vi','4','4','2','4','4','4','4'
               dc.b  '4','8','4','4'
               dc.b  '2','V','6','6','2','V','4','V','2','6','6','6','6','2'
               dc.b  '8','6','6','6','6','6','6','6','6','6','6','6','2','6'
               dc.b  '2','6','2','2','2','6','6','6','8','8','6','6','8'
               dc.b  '6','8','8','6','8','8','6','6','6','6','6'
               dc.b  '8','8','6','8','8','8','8','8','ViiveViiveViive'
               dc.b  '6','6','6','6','6','6','2','6','6','6','6','6','6','6'
               dc.b  '6','Viive','2','2','2','2','2','6','6','6'
               dc.b  '2','2','6','ViiveViive','2','4','4','4','8','8','4','4'
               dc.b  'Vi','2','V','2','V','2','V','2','V','2','6','6','2','2'
               dc.b  '6','6','2','Vii','6','V','6','ViiveV','6','6','6','6','6','6'
               dc.b  0  ; Loppumerkki
               even

ScrolliTeksti  dc.b  "   Olipa kerran yksinÀinen poika. HÀn oli sisÀisesti "
               dc.b  "tyhjÀ ja vailla ystÀviÀ. HÀn harhaili pÀÀmÀÀrÀttömÀsti "
               dc.b  "ympÀri metsiÀ...                                         "
               dc.b  "                                                         "
               dc.b  "                                                         "
               dc.b  "                                                         "
               dc.b  "                    "
               dc.b  "Lopulta hÀn pysÀhtyi jÀrven rannalle...                  "
               dc.b  "        HÀn keksi, mitÀ hÀneltÀ puuttui, ja hÀn pÀÀtti et"
               dc.b  "siÀ sen...                                               "
               dc.b  "...         ...                                          "
               dc.b  " ...hÀn etsi...                            ...hÀn etsi..."
               dc.b  "                               ...                       "
               dc.b  " ...etsi...                                    ...etsi..."
               dc.b  "                                    ....................."
               dc.b  "                "
               dc.b  "...ja sitten...       HÀn alkoi tÀyttymÀÀn miellyttÀvÀstÀ"
               dc.b  " lÀmmöstÀ...                                ...ja.....   "
               dc.b  "          HĂ€n LÖYSI sen !!! "
               dc.b  "HÀn löysi Rakkauden !                                    "
               dc.b  "...ja he elivÀt onnellisina jne...                       "
               dc.b  "                                                         "
               dc.b  0

               even


;------------------------------------------------------------------------------
; Muuttujat
;------------------------------------------------------------------------------
   section  Muuttujat,DATA

DB

OmaHahmo       dc.l  0,0,-48,-48 ; MapX,MapY, ScreenX,ScreenY
               dc.l  16          ; gfx
               dc.l  0           ; Frame-counter sÀdekehÀlle

Hahmot         dc.l  58,28       ; Hahmon x- ja y-koordinaatit kartalla
               dc.l  17          ; JĂ€rjestysnumero blockdatassa
               dc.l  MaskOfZeros ; Maski
               dc.l  -1          ; Liikkuvako (-1 = ei, 0 = kyllÀ)
               dc.l  1           ; Elossako (1 = elossa, 0 = ei elossa)

               dc.l  8,10        ; MapX, MapY
               dc.l  18          ; gfx
               dc.l  GhostMask   ; Maski
               dc.l  0           ; Liikkuvako
               dc.l  1           ; Elossako (1 = elossa, 0 = ei elossa)

tenghosts      ds.l  6*10        ; Varataan tilaa vielÀ 10:lle mörölle

               dc.l  -1          ; Hahmojen loppumerkki


Ihmiset_Town   dc.l  31,47       ; x,y
               dc.l  20          ; Miespuolinen
               dc.l  MaskOfZeros
               dc.l  -1
               dc.l  1

               dc.l  9,9         ; x,y
               dc.l  21          ; Naispuolinen
               dc.l  MaskOfZeros
               dc.l  -1
               dc.l  1

               dc.l  29,15       ; x,y
               dc.l  21
               dc.l  MaskOfZeros
               dc.l  -1
               dc.l  1

               dc.l  7,15
               dc.l  20
               dc.l  MaskOfZeros
               dc.l  -1
               dc.l  1

               dc.l  38,7
               dc.l  20
               dc.l  MaskOfZeros
               dc.l  -1
               dc.l  1

               dc.l  51,52
               dc.l  21
               dc.l  MaskOfZeros
               dc.l  -1
               dc.l  1

               dc.l  -1          ; Loppumerkki!

; Varsinaisesti nÀkyvÀ nÀyttö

; Screen-struktuuri
UusiNaytto     dc.w  0           ; NÀytön vas. ylÀkulman x-koord.
               dc.w  0           ; NÀytön vas. ylÀkulman y-koord.
               dc.w  320         ; x-koko
               dc.w  256         ; y-koko
               dc.w  5           ; Syvyys (bittitasojen mÀÀrÀ)
               dc.b  0           ; Otsikkopalkin vÀri 1       
               dc.b  1           ; Otsikkopalkin vÀri 2
               dc.w  0           ; Moodi (TÀssÀ LO-RES) 
               dc.w  CUSTOMSCREEN!CUSTOMBITMAP  ; NÀytön tyyppi      
               dc.l  0           ; KÀytettÀvÀt fontit
               dc.l  Otsikko     ; NÀytön nimen osoitin
               dc.l  0           ; Osoitin gadgetteihin
               dc.l  myBitMap1   ; Osoitin kÀyttÀjÀn mÀÀrittelemÀÀn
                                 ; BitMap-structureen

; TÀmÀ on scrolli-ikkuna varsinaisesti nÀkyvÀllÀ alueella, mistÀ ikkunasta
; lisÀksi tarkkaillaan hiiren napin painalluksia.

UusiIkkuna     dc.w  0           ; NÀytön vas. ylÀkulman x-koord.
               dc.w  0           ; NÀytön vas. ylÀkulman y-koord.
               dc.w  320         ; x-koko
               dc.w  256         ; y-koko
               dc.b  0,1         ; Otsikkopalkkien vÀrit
               dc.l  IDCMPf      ; IDCMP-liput
               dc.l  Liput       ; liput
               dc.l  0           ; Osoitin to 1st gadget structure
               dc.l  0           ; Osoitin valintamerkkiin
               dc.l  0           ; Osoitin ikkunan nimeen
NaytonOsoite   dc.l  0           ; Osoitin nÀytön Screen-structureen
               dc.l  0           ; Osoitin omaan  BitMap-structureen
               dc.w  0,0,0,0     ; PienimmÀt sallitut koot
               dc.w  CUSTOMSCREEN ; Tyyppi

; TÀmÀ ikkuna on varsinaisesti nÀkyvÀllÀ screenillÀ, mihin ikkunaan
; tulostetaan pisteittÀin omistuskuva

UusiIkkuna3    dc.w  105         ; NÀytön vas. ylÀkulman x-koord.
               dc.w  80          ; NÀytön vas. ylÀkulman y-koord.
               dc.w  110         ; x-koko
               dc.w  50          ; y-koko
               dc.b  0,1         ; Otsikkopalkkien vÀrit
               dc.l  0           ; IDCMP-liput
               dc.l  BORDERLESS!RMBTRAP ; Liput
               dc.l  0           ; Osoitin to 1st gadget structure
               dc.l  0           ; Osoitin valintamerkkiin
               dc.l  0           ; Osoitin ikkunan nimeen
screenaddy     dc.l  0           ; Osoitin nÀytön Screen-structureen
omistusbm      dc.l  0           ; Osoitin omaan  BitMap-structureen
               dc.w  0,0,0,0     ; PienimmÀt sallitut koot
               dc.w  15          ; Tyyppi (tÀssÀ CUSTOM)

textattr       dc.l  FontinNimi
               dc.w  12
               dc.b  0
               dc.b  0

; Screen-struktuuri
OmistusNaytto  dc.w  0           ; NÀytön vas. ylÀkulman x-koord.
               dc.w  0           ; NÀytön vas. ylÀkulman y-koord.
               dc.w  320         ; x-koko
               dc.w  256         ; y-koko
               dc.w  5           ; Syvyys (bittitasojen mÀÀrÀ)
               dc.b  0           ; Otsikkopalkin vÀri 1       
               dc.b  1           ; Otsikkopalkin vÀri 2
               dc.w  0           ; Moodi (TÀssÀ LO-RES) 
               dc.w  CUSTOMSCREEN ; NÀytön tyyppi      
               dc.l  textattr    ; KÀytettÀvÀt fontit
               dc.l  0           ; NÀytön nimen osoitin
               dc.l  0           ; Gadgetit
               dc.l  0           ; Oma bitmap-struktuuri

; TÀmÀ on scrolli-ikkuna varsinaisesti nÀkyvÀllÀ alueella, mistÀ ikkunasta
; lisÀksi tarkkaillaan hiiren napin painalluksia.

UusiIkkuna4    dc.w  0           ; NÀytön vas. ylÀkulman x-koord.
               dc.w  0           ; NÀytön vas. ylÀkulman y-koord.
               dc.w  320         ; x-koko
               dc.w  256         ; y-koko
               dc.b  0,1         ; Otsikkopalkkien vÀrit
               dc.l  0           ; IDCMP-liput
               dc.l  BORDERLESS!RMBTRAP ; liput
               dc.l  0           ; Osoitin to 1st gadget structure
               dc.l  0           ; Osoitin valintamerkkiin
               dc.l  0           ; Osoitin ikkunan nimeen
oms_addy       dc.l  0           ; Osoitin nÀytön Screen-structureen
               dc.l  0           ; Osoitin omaan  BitMap-structureen
               dc.w  0,0,0,0     ; PienimmÀt sallitut koot
               dc.w  15          ; Tyyppi (tÀssÀ CUSTOM)

myBitMap1      dc.w  40,256      ; Leveys tavuina, korkeus pixeleinÀ
               dc.b  0,5         ; Liput, Syvyys
               dc.w  0           ; Pad
               dc.l  BitPlane1_1
               dc.l  BitPlane2_1
               dc.l  BitPlane3_1
               dc.l  BitPlane4_1
               dc.l  BitPlane5_1
               dc.l  0
               dc.l  0
               dc.l  0

myBitMap2      dc.w  40,256      ; Leveys tavuina, korkeus pixeleinÀ
               dc.b  0,5         ; Liput, Syvyys
               dc.w  0           ; Pad
               dc.l  BitPlane1_2
               dc.l  BitPlane2_2
               dc.l  BitPlane3_2
               dc.l  BitPlane4_2
               dc.l  BitPlane5_2
               dc.l  0
               dc.l  0
               dc.l  0

blockBitMap    dc.w  2,512       ; Leveys tavuina, korkeus pixeleinÀ
               dc.b  0,5         ; Liput, Syvyys
               dc.w  0           ; Pad
               dc.l  blockplane1
               dc.l  blockplane2
               dc.l  blockplane3
               dc.l  blockplane4
               dc.l  blockplane5
               dc.l  0
               dc.l  0
               dc.l  0

hahmo_map      dc.l  0
hahmot         dc.l  0
gamefield      dc.l  0
x              dc.l  0
y              dc.l  0
demomoveind    dc.l  0
iff            dc.l  0
iff_kehysfile  dc.l  0
iff_blockfile  dc.l  0
IFFbase        dc.l  0
MinunNaytto    dc.l  0
MinunIkkuna    dc.l  0
OmistusIkkuna  dc.l  0
o_rastport     dc.l  0
Om_Naytto      dc.l  0
Om_Ikkuna      dc.l  0
Om_rastport    dc.l  0
rastport       dc.l  0
viewport       dc.l  0
DrawBitMap     dc.l  0
ShowBitMap     dc.l  0
Intuibase      dc.l  0
Dosbase        dc.l  0
GFXbase        dc.l  0
DiskFontbase   dc.l  0
TextInd        dc.l  0
CopyInd        dc.l  0
FontColor      dc.l  0              ; Alustetaan ohjelmassa
Font           dc.l  0
outfile        dc.l  0
pind           dc.l  4*11
pind2          dc.l  0
frameY         dc.l  0
rnd_number     dc.l  0
rnd_more       dc.w  0
mm_delay       dc.b  0              ; Monster move delay
cind           dc.b  0              ; VÀrienkierrÀtysindikaattori
Laskuri        dc.b  0
BigBlit        dc.b  0
Demoonko       dc.b  0              ; Joka 16. frame demoon
DemoDone       dc.b  0              ; Ilmoittaa, onko demo suoritettu
points         dc.b  0
inTown         dc.b  0
Kumpi          dc.b  0
Quit           dc.b  0
DemoMode       dc.b  1
RestartAll     dc.b  0
Number         dc.b  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
               even

IFFnimi        dc.b  "iff.library",0
intuinimi      dc.b  "intuition.library",0
dosnimi        dc.b  "dos.library",0
GFXnimi        dc.b  "graphics.library",0
DiskFontnimi   dc.b  "diskfont.library",0
FontinNimi     dc.b  "diamond.font",0
Otsikko        dc.b  "",0
IkkunanNimi    dc.b  "",0
kehysfile      dc.b  "IFFs/Kehys5.iff",0
omistusfile    dc.b  "IFFs/Omistus4.iff",0
blockfile      dc.b  "IFFs/TestBlocks.iff",0
Tuloste        dc.b  0,0
Testi_txt      dc.b  "Testi",10,0
               even

   section  Puskurit,bss,chip

blockplane1    ds.b  1024
blockplane2    ds.b  1024
blockplane3    ds.b  1024
blockplane4    ds.b  1024
blockplane5    ds.b  1024
               
BitPlane1_2    ds.b  10240
BitPlane2_2    ds.b  10240
BitPlane3_2    ds.b  10240
BitPlane4_2    ds.b  10240
BitPlane5_2    ds.b  10240

BitPlane1_1    ds.b  10240
BitPlane2_1    ds.b  10240
BitPlane3_1    ds.b  10240
BitPlane4_1    ds.b  10240
BitPlane5_1    ds.b  10240

Puskuri        ds.b  40*5

MaskOfZeros    ds.b  32

   section  puskurit,bss

monster_map    ds.w  (MAP_WIDTH*MAP_HEIGHT)*2
TownHahmoMap   ds.w  (MAP_WIDTH*MAP_HEIGHT)*2

battle_monst   ds.l  (8*7)+1     ; TÀmÀ on taistelutilanteen monstereita
                                 ; varten. Rakenne:
                                 ; LONG x
                                 ; LONG y
                                 ; LONG HitPoints
                                 ; LONG ampuva? (0 tai 1, 1 = ampuva)
                                 ; LONG GFX
                                 ; LONG Maski
                                 ; LONG Rank
                                 ;
                                 ; YhteensÀ siis varataan 8 monsterille
                                 ; tilaa, lopuksi loppumerkille vielÀ LONG
colortable     ds.w  32
;colortable    incbin   "Work:Assembler/MJS/Rendez-vous/IFFs/colors.iff"
copytable      ds.w  8

;  section  ChipData,data,chip


              end

Advertisements

Here’s source code to my old experiment in Amiga game coding. The source I found, doesn’t seem to be exactly the same used in the code of the video showing below. There are more than one pieces of music in the unfinished game, but in the source there isn’t “incbin” for any Amiga music module.

The project started in 1992, when I was at high school (lukio), when I was experimenting in multiplexing Amiga’s hardware sprites. Much later I continued the project in order to see, if I could still do some Amiga coding in assembly.

The musics are not made by me, I used some nice music modules, I found from the Aminet.

There should be color stripes in the energy bar made with Copper, but for some reason the colors were lost in the emulation.

The source is a bit messy and labels and comments are partly in English and partly in Finnish.

As a reminder old Amigas have Motorola’s processors and the assembly is Motorola’s 68000 processor’s assembly code.

As you can see from the source, the ProTracker replay routine is not coded by me.

Some words about the vertical scrolling… This “game” 🙂 works on an A500 with only 512kb of CHIP memory, if my memory serves my right. The reason why this little project uses quite a lot of CHIP memory is because of the way the vertical scrolling is made: The game uses in fact three (3) screens in CHIP memory in total, two for double buffering and in addition there is one screen that only scrolls vertically. The latter is “ClearScreen”, it is used for clearing the drawing buffer from earlier bob (blitter object) movement (of course for sake of limited speed, the whole ClearScreen is not copied, but only the needed 16 x 16 pixel areas). As a reminder, the movement of sprites doesn’t need the clearing of earlier position, the sprites are drawn in a special way to the screen. Bobs (blitter objects) represent “normal” graphical objects, that require clearing of earlier position.

The smartest idea for fast (that is: takes only little raster time) vertical scrolling on an Amiga 500 I’ve ever seen, was on one book written in Finnish. In that idea if the area to be scrolled vertically is for example 320 x 256 pixels, again a lot of CHIP memory is used: For only scrolling the screen vertically 3 * (320 x 256) pixels area is used for scrolling and this area is used in a very smart manner in order to achieve vertical scrolling that takes on only few raster lines. Probably this idea also requires little extra CHIP memory for blitting new graphics to area… Over 20 years ago I implemented and tested this idea and this really is  a fast way to implement vertical scrolling on an Amiga!

The game isn’t any state of the art assembly code, just an experiment… See below:

        incdir  "ADCD_2.1:NDK/NDK_3.5/Include/include_i"

        include "exec/types.i"
        include "libraries/dosextens.i"
        include "graphics/gfxbase.i"
        include "exec/libraries.i"
        include "exec/execbase.i"
        include "Hardware/intbits.i"

;------------------------------------------------------------------------------
; Makroja
;------------------------------------------------------------------------------
WaitForBlitter  MACRO
W\@     btst    #14,$2(a5)
        bne.s   W\@
        ENDM

;------------------------------------------------------------------------------
; Vakioita
;------------------------------------------------------------------------------
Forbid         equ     -$0084
Permit         equ     -$008a
Disable        equ     -$0078
Enable         equ     -$007e
Write          equ     -$0030
Output         equ     -$003c
OpenLibrary    equ     -$0228
CloseLibrary   equ     -$019e

Execbase       equ      4

Screen_X_Size  equ     320
Screen_Y_Size  equ     256
Height_OBullet equ     8       ; Oman laakin korkeus
Frames         equ     3
OwnSpeed       equ     3       ; Oman aluksen nopeus
BSpeed         equ     4       ; Oman laakin nopeus
AmountBullets  equ     (Screen_Y_Size/(Height_OBullet*BSpeed))-1
AmountEBullets equ     10-1    ; Vihollisten laakien mÀÀrÀ
Dest           equ     (256+16+16)*4*32        ; Palikka sinne alapuolelle
max_bobs       equ     32
max_asteroids_on_screen equ 20

NOCHIPREV      equ 0

;------------------------------------------------------------------------------
; Startup-koodi
;------------------------------------------------------------------------------

        SECTION CODE,code

startup:
        movem.l d0/a0,-(sp)             ; Tallennetaan d0 ja a0
        move.l  4,a6                    ; SysBase
        move.l  #0,a1
        jsr     -$0126(a6)              ; Haetaan oma prosessi, FindTask()
        move.l  d0,a4
        move.l  d0,process
        tst.l   pr_CLI(a4)              ; CLI?
                                        ; tst.l $ac(a4)
        bne.s   check_aga               ; jos CLI niin check_aga
wb:
        lea     pr_MsgPort(a4),a0       ; Haetaan prosessin viestiportti
                                        ; lea $5c(a4),a0
        jsr     -$0180(a6)              ; Odotetaan viestiÀ, WaitPort()
        lea     pr_MsgPort(a4),a0
        jsr     -$0174(a6)              ; Haetaan viesti
                                        ; GetMsg()
        move.l  d0,wbenchmsg            ; tallennetaan ohjelman tarvetta
                                        ; varten
check_aga:                              ; TÀmÀ toimii OCS ja ECS koneissa,
        moveq   #0,d0                   ; joten AGA-checkiÀ ei tarvita...
        lea     gfxname,a1              
        jsr     -$0228(a6)              ; OpenLibrary()
        move.l  d0,gfxbase
        beq.w   reply_to_wb             ; jostain syystÀ ei saatu avattua
        move.l  d0,a4

        moveq   #0,d0
        lea     intuiname,a1
        jsr     -$0228(a6)
        move.l  d0,intuibase
        beq     Sulje

;        move.l  4,a6
;        jsr     -$0078(a6)              ; keskeytykset pois, Disable()
        cmp.w   #39,LIB_VERSION(a4)     ; onko ChipRevBits0 mÀÀritelty
                                        ; cmp.w #39,$14(a4)
        bne.s   no_chiprev

        move.b  gb_ChipRevBits0(a4),chiprev
                                        ; move.b $ec(a4),chiprev
        bra.s   check_proc
no_chiprev:
        move.b  #NOCHIPREV,chiprev      ; Ei pystyta hakemaan ChipRevBits:ia
check_proc:
        move.w  AttnFlags(a6),processor ; CPU ja FPU
                                        ; move.w $128(a6),processor
clear_view:
        move.l  gfxbase,a6
        move.l  gb_ActiView(a6),oldview ; nykyinen View talteen
                                        ; move.l $22(a6),oldview
        move.l  #0,a1                   ; NULL View tilalle
        jsr     -$00de(a6)              ; LoadView()
        jsr     -$010e(a6)     
        jsr     -$010e(a6)              ; WaitTOF()

        move.l  4,a6                    ; SysBase valmiiksi
        movem.l (sp)+,d0/a0             ; d0/a0 pois pinosta
        bsr.s   _start                  ; hypÀtÀÀn pÀÀohjelmaan
        move.l  d0,-(sp)                ; palautuskoodi turvaan
old_view:
        move.l  gfxbase,a0
        move.l  $26(a0),$dff080         ; Copperlistan palautus

        move.l  gfxbase,a6
        move.l  oldview,a1              ; vanha View
        jsr     -$00de(a6)              ; LoadView()
;        move.l  4,a6
;        jsr     -$007e(a6)              ; keskeytykset pÀÀlle, Enable() 
        move.l  intuibase,a6
        jsr     -$0186(a6)              ; RethinkDisplay()

        move.l  4,a6
        move.l  intuibase,a1
        jsr     -$019e(a6)              ; CloseLibrary()

Sulje   move.l  4,a6
        move.l  gfxbase,a1              ; suljetaan graphics.library
        jsr     -$019e(a6)              ; CloseLibrary()

        reply_to_wb:
        tst.l   wbenchmsg               ; onko workbench
        beq.s   exit                    ; jos ei niin exit
        jsr     -$0084(a6)              ; huomaa ettei tarvitse Permit()
                                        ; Forbid()
        move.l  wbenchmsg,a1
        jsr     -$017a(a6)              ; ReplyMsg()
exit:
        move.l  (sp)+,d0
        rts                             ; poistutaan ohjelmasta


_start

;------------------------------------------------------------------------------
; Itse ohjelma!
;------------------------------------------------------------------------------

        movem.l d2-d7/a2-a6,-(sp)

;         move.l  4,a6
;        lea     dosname,a1
;        moveq   #0,d0
;        jsr         OpenLibrary(a6)
;        move.l  d0,dosbase

;         move.l  dosbase,a6
;        jsr     Output(a6)           ; For printing...
;        move.l  d0,outfile           ;

        move.l  4,a6
        jsr     Forbid(a6)

        move.l  4,a6
        move.l  #((256+16)*2+16)*32*4,d0
        move.l  #65538,d1
        jsr     -$00c6(a6)
        move.l  d0,ClearScreen
        beq     Pois

        move.l  #((256+16)*2+16)*32*4,d0
        move.l  #65538,d1
        jsr     -$00c6(a6)
        move.l  d0,BitMap1
        beq     Vap1

        move.l  #((256+16)*2+16)*32*4,d0
        move.l  #65538,d1
        jsr     -$00c6(a6)
        move.l  d0,BitMap2
        beq     Vap2

        move.l  #32768,d0                       ; 256 x 256 pixeliÀ
        move.l  #65538,d1
        jsr     -$00c6(a6)
        move.l  d0,bitmap
        beq     Vap3
 
        lea     Gamefield,a6                ; LisÀtÀÀn blockien osoite valmiiksi
        lea     Coolfield,a4
        move.l  #5120-1,d7        
GBSil:  move.l  #Blocks,a1
        moveq   #0,d0
        move.w  (a6)+,d0
        lsl.l   #1,d0
;       add.l   d0,d0
        add.l   d0,a1
        move.l  a1,(a4)+
        dbf     d7,GBSil

        lea      Gamefield2,a6
        lea      Coolfield2,a4
        move.l   #5120-1,d7
GBSil2  move.l  #Blocks,a1
        moveq   #0,d0
        move.w  (a6)+,d0
        lsl.l   #1,d0
        add.l   d0,a1
        move.l  a1,(a4)+
        dbf      d7,GBSil2

        lea     Gamefield3,a6
        lea     Coolfield3,a4
        move.l  #5120-1,d7
GBSil3  move.l  #Blocks,a1
        moveq   #0,d0
        move.w  (a6)+,d0
        lsl.l   #1,d0
        add.l    d0,a1
        move.l  a1,(a4)+
        dbf     d7,GBSil3

      ;  move.l  4,a6
     ;   move.l  #0,d0
    ;    lea     gfxname,a1
   ;     jsr     -$228(a6)
  ;      move.l  d0,gfxbase
 ;       cmp.l   #0,d0
;        beq     CleanUp

;           bsr     mt_init
;           st          mt_Enable

;           move.l  #INTB_VERTB,d0
;           move.l  #Vert_str,a1    ; VBI -keskeytysstrukture
;           move.l  4,a6
;           jsr     -$00a8(a6)      ; AddIntServer

        move.l      #Laakit,LaakiPT

        move.l      #$dff000,a5
        move.l      #CopperLista,$080(a5)
        tst.w       $088(a5)

        move.w      #$87f0,$096(a5)
;       move.w  #$0400,$096(a5)
;       move.w  #$0020,$096(a5)
        move.l   #$ffffffff,$044(a5)
;         move.l  #$0,$044(a5)
        move.w  #$cce,$01a2(a5)
        move.w  #$789,$01a4(a5)
        move.w  #$446,$01a6(a5)
;         move.w  #$0fff,$01aa(a5)
;           move.w  #0,$106(a5) ; Spritet lo-res -tilaan (ECS default)
        and.w      #%1111111100111111,$106(a5)

        bsr     AlkuRoskat


JumpToAlkuScreen

        bra     AlkuScreen

JumpToAlustus

        bsr      Alustus                ; Nollataan "muuttujat"

        bsr     FillTheScreen
        bsr     SwapScreens

MainProgram
          cmp.b   #1,gameOver
          beq     GameOver

          cmp.b  #4,level
          beq    LoppuScreen

          bsr     SwapScreens
          bsr     Show
          bsr     Scroll
          bsr     ClearScore
          bsr     HandlePlayer
          bsr     Joystick
          bsr     PalautaExpTausta
          bsr     ReadAttackWaves
          bsr     CheckUnits
          bsr     CheckCoordBobs    ; Tsekataan koordinaattivalmiit enemyt
          bsr     CheckAsteroids
          bsr     CheckMonster
          bsr     HandleExplosions
          bsr     BlitScore
;           move.w  #$0f0,$180(a5)
          bsr     BlitNumbers
;           move.w  #$000f,$180(a5)
          bsr        HandleEnergySprite

          move.w  #$000,$180(a5)
          bsr     WaitForBeam
;         move.w  #$333,$180(a5)
;         move.w  #$779,$1a4(a5)

          bsr     RMB

          btst    #6,$bfe001
          bne.s   MainProgram

CleanUp     
            ;move.l  4,a6
        ;move.l  #0,d0
;        lea     gfxnimi,a1
;        jsr     -$228(a6)
;        move.l  d0,gfxbase
;        move.l  #0,d0
;        lea     intuinimi,a1
;        jsr     -$228(a6)
;        move.l  d0,intuibase
;        move.l  gfxbase,a0       
;        move.l  $26(a0),$dff080 
;        move.l  intuibase,a6      
;        jsr     -$186(a6)        
;        move.l  4,a6
;        move.l  intuibase,a1
;        jsr     -$19e(a6)
;        move.l  gfxbase,a1
;        jsr     -$19e(a6)

;         move.l  4,a6
;         move.l  dosbase,d0
;         beq.s   Vap3
;         move.l  d0,a1
;         jsr     CloseLibrary(a6)

;           bsr     mt_end

;           move.l  #INTB_VERTB,d0
;           lea     Vert_str,a1
;           move.l  4,a6
;           jsr     -$00ae(a6)          ; RemIntServer

          move.l  4,a6
          move.l  #32768,d0
          move.l  bitmap,a1
          jsr     -$00d2(a6)

Vap3:     move.l  4,a6
          move.l  #((256+16)*2+16)*32*4,d0
          move.l  BitMap2,a1
          jsr     -$00d2(a6)
Vap2:     move.l  4,a6
          move.l  #((256+16)*2+16)*32*4,d0
          move.l  BitMap1,a1
          jsr     -$00d2(a6)
Vap1:     move.l  4,a6
          move.l  #((256+16)*2+16)*32*4,d0
          move.l  ClearScreen,a1
          jsr     -$00d2(a6)

Pois      move.l  4,a6
          jsr     Permit(a6)
          movem.l (sp)+,d2-d7/a2-a6
          moveq   #0,d0
          rts

CheckUnits
          bsr       HandleUnit
          rts


CheckAsteroids
          cmp.b   #1,AsteroidsRunning
          bne.s   ExitCA

          cmp.b   #1,LastAsteroidFrames
          beq.s   LastFrames

          cmp.w   #0,Nr_of_asteroids
          ble.s   IsThereOnScreen
          bra.s   Mene
IsThereOnScreen
          cmp.b   #0,Asteroids_on_screen
          bne.s   Mene
          move.b  #1,LastAsteroidFrames
          rts  

Mene      bsr     PalautaAsteroidienTausta
          bsr     PutAsteroid
          bsr     MoveAsteroids
          bsr     AsteroidCollisions

ExitCA    rts
LastFrames
          bsr     PalautaAsteroidienTausta
          subq.b  #1,LastAsteroidFrames
Okay      move.b  #0,AsteroidsRunning
          rts


;-----------------------------------------------------------------------------
; KÀsitellÀÀn unit. Pointteri tietueeseen annetaan A1:ssÀ.
;-----------------------------------------------------------------------------
HandleUnit
           bsr      PalautaUnitinTausta
           bsr      PalautaUnitBulletinTausta
           move.l   UnitsVanhaSij,a6
           lea      Units,a1
           moveq        #5-1,d7

           WaitForBlitter
           move.w   #0000,$062(a5)  ; BLTBMOD
           move.w   #0028,$060(a5)  ; BLTCMOD 
           move.w   #0000,$064(a5)  ; BLTAMOD
           move.w   #0028,$066(a5)  ; BLTDMOD

HUSil      cmp.w    #0,(a1)         ; Onko liikkeellÀ?
           beq.s    NextUnit
           move.l   2(a1),d0        ; X
           move.l   6(a1),d1        ; Y
           move.l   28(a1),a2       ; Bob-data
           move.l   32(a1),a3       ; Mask-data

           bsr      BlitBob

           cmp.w    #1,46(a1)
           beq.s    liikutetaan
           cmp.w    #0,6(a1)
           bge.s    NextUnit
           addq.l    #1,6(a1)
           bra.s    NextUnit

liikutetaan
           addq.l   #1,6(a1)
           cmp.l    #256,6(a1)
           bge.s    RemoveUnit  
NextUnit
           add.l    #48,a1
           add.l    #10,a6
           dbf      d7,HUSil

           bra.s    HandleUnitBullet

RemoveUnit
           move.w   #0,(a1)
           add.l    #48,a1
           add.l    #10,a6
           dbf      d7,HUSil

; KÀsitellÀÀn unitin laaki

HandleUnitBullet
            moveq   #5-1,d7
            move.l  UnitsVBSij,a6

            lea     Units,a1
HUBSil      cmp.w   #1,10(a1)
            beq.s   BlitAndMoveUnitBullet

; Jos ei ole liikkeellÀ, niin katsotaan, onko unit kehissÀ; jos on, niin
; laitetaan laaki liikkeelle ehkÀ.

            cmp.l   #ExplodedUnit,28(a1)
            beq.s   Eilaakia
            cmp.w   #1,(a1)                 ; Onko unit kehissÀ?
            beq.s   Ampuukho
Eilaakia    add.l   #48,a1
            add.l   #10,a6
            dbf     d7,HUBSil

            bra.s   HandleUnitCollisions

Ampuukho
            move.w  $6(a5),d0               ; Jos ei ollut, niin arvotaan,
            add.w   Random,d0              ; laitetaanko liikkeelle
            and.l   #7,d0
            cmp.w   #7,d0
            beq.s   Ampuu

            add.l   #48,a1
            add.l   #10,a6
            dbf     d7,HUBSil

            bra.s       HandleUnitCollisions
         
Ampuu       move.l      2(a1),d0                ; Asetetaan laakille alkukoordinaatit
            move.l      6(a1),d1
            addq.l      #7,d0
            add.l       #16,d1
            lsl.l       #7,d0
            lsl.l       #7,d1
            move.l      d0,12(a1)               ; Talletetaan
            move.l      d1,16(a1)

            lsr.l       #7,d0
            lsr.l       #7,d1

            moveq       #0,d2                   ; TÀhdÀtyt laukauset uniteille
            moveq       #0,d3
            move.w      x,d2
            move.w      y,d3

            sub.l       d0,d2
            sub.l       d1,d3

            lsl.l       #7,d2                   ; "desimaaliluvuksi"
            lsl.l       #7,d3
            lsr.l       #6,d2
            lsr.l       #6,d3
            move.l      d2,20(a1)               ; AddX
            move.l      d3,24(a1)               ; AddY

            move.w      #1,10(a1)              ; Laaki liikkeellÀ -merkki

            add.l       #48,a1
            add.l       #10,a6 
            dbf         d7,HUBSil
            rts

            bra.s       HandleUnitCollisions

BlitAndMoveUnitBullet
            move.l      12(a1),d0       ; x
            move.l      16(a1),d1       ; y
            lsr.l       #7,d0               ; Kokonaisluvuksi
            lsr.l       #7,d1
            bsr         BlitBullet

            move.l      20(a1),d2       ; AddX
            move.l      24(a1),d3       ; AddY
            add.l       d2,12(a1)       ; Liikutetaan laakia
            add.l       d3,16(a1)

            move.l      12(a1),d0
            move.l      16(a1),d1
            lsr.l       #7,d0
            lsr.l       #7,d1

            cmp.w       #255-4,d0
            bgt.s       RemoveUnitBullet
            cmp.w       #4,d0
            ble.s       RemoveUnitBullet

            cmp.w       #256,d1
            bge.s       RemoveUnitBullet
            cmp.w       #4,d1
            ble.s       RemoveUnitBullet

            add.l       #48,a1
            add.l       #10,a6
            dbf         d7,HUBSil
            rts

            bra.s       HandleUnitCollisions

RemoveUnitBullet
            move.w      #0,10(a1)

            add.l       #48,a1
            add.l       #10,a6
            dbf         d7,HUBSil
            rts

; KÀsitellÀÀn unittien törmÀykset

HandleUnitCollisions
            lea         Units,a1
            moveq       #5-1,d6

HUCSil      cmp.w       #1,(a1)         ; Unit kehissÀ?
            beq.s       Proceed
            cmp.w       #1,10(a1)       ; Laaki kehissÀ?
            beq.s       Proceed

            add.l       #48,a1
            dbf         d6,HUCSil
            rts

Proceed
            move.l      2(a1),d0
            move.l      6(a1),d1
            move.l      12(a1),d4
            move.l      16(a1),d5
            asr.l       #7,d4
            asr.l       #7,d5
            bsr         UnitCollisions

            add.l       #48,a1
            dbf         d6,HUCSil
            rts
                
;-----------------------------------------------------------------------------
; Unit törmÀykset
; Idea: Verrataan pelaajan koordinaatteja unitiin ja sen bullettiin
;-----------------------------------------------------------------------------
UnitCollisions

; Vihollisien x,y on D0,D1:ssÀ

; Player to enemies

;         cmp.l   #ExplodedUnit,28(a1)      ; Jos unit on ammuttu, niin
;        beq.s   NoCollisionToEnemy         ; törmÀystÀ ei tsekata

;         moveq   #0,d2
;         moveq   #0,d3
;         move.w  x,d2
;         move.w  y,d3
; x-test
;         sub.w  d0,d2
;         cmp.w  #-15,d2
;         blt.s  NoCollisionToEnemy
;        cmp.w   #15,d2
;         bge.s  NoCollisionToEnemy
; y-test
;         sub.w   d1,d3
;         cmp.w   #-15,d3
;         blt.s   NoCollisionToEnemy
;         cmp.w   #15,d3
;         bge.s   NoCollisionToEnemy          
;         move.w     #$0f00,$01a4(a5)

NoCollisionToEnemy

; Player bullets to enemies
          cmp.l   #ExplodedUnit,28(a1)
          beq.s   PlayerToUnitBullet

          lea     Laakit,a0
          move.w  #AmountBullets,d7
OnkoLaakiLiikkeella
          cmp.w   #0,(a0)
          bne.s   LaakiLiikkeellÀ
          addq.l  #6,a0
          dbf     d7,OnkoLaakiLiikkeella
          bra.s   PlayerToUnitBullet    
LaakiLiikkeellÀ
          move.l  d0,d2
          move.l  d1,d3
          sub.w   2(a0),d2
          cmp.w   #-16,d2
          blt.s   NextBullet
          cmp.w   #4,d2
          bge.s   NextBullet
          sub.w   4(a0),d3
          cmp.w   #16,d3
          bge.s   NextBullet
          cmp.w   #-16,d3
          blt.s   NextBullet

          move.l  #ExplodedUnit,28(a1)
          move.l  #ExplodedUnitM,32(a1)
          move.w  #0,(a0)                   ; Laaki pois kehistÀ
;        subq.b  #1,OwnBulletsOnScreen

          addq.w  #5,Pisteet                ; Jos osuttu niin listÀÀn pelaajan
                                                ; pisteitÀ
          move.l  Exp_PT,a4             ; PiirretÀÀn rÀjÀhdys
          move.w  #1,(a4)
          move.w  d0,2(a4)
          move.w  d1,4(a4)
          move.w  #4,6(a4)
          add.l   #12,a4
          cmp.w   #-1,(a4)
          bne.s   Jatkuu
          move.l  #Explosions,Exp_PT
          bra.s   NextBullet
Jatkuu    move.l  a4,Exp_PT

NextBullet
          addq.l  #6,a0
          dbf       d7,OnkoLaakiLiikkeella

; Vihollisen laakin x,y on d4,d5
PlayerToUnitBullet
          moveq   #0,d2
          moveq   #0,d3
          move.w  x,d2
          move.w  y,d3
          sub.w   d2,d4
          cmp.w   #-3,d4
          blt.s   ExitUnitCollisions
          cmp.w   #14,d4
          bge.s   ExitUnitCollisions
          sub.w   d3,d5
          cmp.w   #-3,d5
          ble.s   ExitUnitCollisions
          cmp.w   #14,d5
          bge.s   ExitUnitCollisions
          move.w  #$0ff0,$01a4(a5)
;           move.b  #1,gameOver
          subq.b  #1,energia

ExitUnitCollisions
          rts

          
;-----------------------------------------------------------------------------
; Palautetaan unitin alta tausta
;-----------------------------------------------------------------------------
PalautaUnitinTausta
            move.l  UnitsVanhaSij,a6
            moveq   #5-1,d7

PalUniTau
            cmp.l   #0,(a6)
            beq.s   NextYksi

            WaitForBlitter
            move.w  #$9f0,$040(a5)  ; BLTCON0
            move.w  #$0000,$042(a5) ; BLTCON1
            move.w  #0028,$064(a5)  ; BLTAMOD
            move.w  #0028,$066(a5)  ; BLTDMOD
            move.l  (a6),$050(a5)   ; BLTAPTR
            move.l  4(a6),$054(a5)  ; BLTDPTR kohde
            move.w  8(a6),$058(a5)  ; BLTSIZE
            move.l  #0,(a6)
NextYksi    add.l   #10,a6
            dbf     d7,PalUniTau
            rts

PalautaUnitBulletinTausta:
            move.l  UnitsVBSij,a6
            moveq   #5-1,d7

PalUniBul
            cmp.l   #0,(a6)
            beq.s   NextUnitBullet

            WaitForBlitter
            move.w  #$9f0,$040(a5)  ; BLTCON0
            move.w  #$0000,$042(a5) ; BLTCON1
            move.w  #0028,$064(a5)  ; BLTAMOD
            move.w  #0028,$066(a5)  ; BLTDMOD
            move.l  (a6),$050(a5)   ; BLTAPTR
            move.l  4(a6),$054(a5)  ; BLTDPTR kohde
            move.w  8(a6),$058(a5)  ; BLTSIZE
            move.l  #0,(a6)
NextUnitBullet
            add.l   #10,a6
            dbf     d7,PalUniBul
            rts

;-----------------------------------------------------------------------------
; Blitataan unit-bob
;-----------------------------------------------------------------------------
BlitBob
        move.w  #4098,d6        ; BLTSIZE

        asl.l   #2,d1           ; Kerrotaan y-koord. 4:llÀ
        cmp.l   #256*4,d1
        bge.s   ExitBlitBob
        cmp.l   #-16*4,d1       ; -(Bobin korkeus)
        ble.s   ExitBlitBob

;        move.l  28(a1),a2
;        move.l  32(a1),a3
        cmp.l   #(255-16)*4,d1  ; Alalaita
        ble.s   NxtTest
        move.l  #256*4,d6       ; Screenin lainien mÀÀrÀ (eli korkeus)
        sub.l   d1,d6           ; Kuinka monta pixelia nÀkyvissÀ
        lsl.l   #6,d6           ; Lasketaan BLTSIZE
        addq.l  #2,d6           ; X lisÀtÀÀn suoraan tÀssÀ versiossa..  
        bra.s   Ready
NxtTest
        cmp.l   #0,d1           ; YlÀlaita (kÀsitellÀÀn negatiiviset
        bge.s   Ready             ; koordinaatit)
        moveq    #0,d6
        move.l  #16*4,d6        ; Bobin korkeus (siis y-pituus)
        add.l   d1,d6           ; Nyt d6:ssa bobin korkeus!
        lsl.l   #6,d6           ; Lasketaan BLTSIZE
        add.l   #2,d6           ; X lisÀtÀÀn suoraan tÀssÀ versiossa..  
        neg.l   d1              ; Lasketaan kohta, mistÀ bobbi-dataa
        lsl.l   #2,d1           ; aletaan blittaamaan
        add.l   d1,a2
        add.l   d1,a3
        moveq   #0,d1           ; Y-koordinaatti on tietysti nolla..
;------------------------------------------------------------------------------
;-- Lasketaan osoite
;------------------------------------------------------------------------------
Ready
        lsl.l   #5,d1
        move.b  d0,d2
        lsr.l   #3,d0
        add.l   d1,d0
        ext.l   d0
        add.l   ScrollOffset,d0 ; ScrollOffset
        and.l   #$000f,d2
        mulu    #$1000,d2
        move.l  DrawScreen,a4
        add.l   d0,a4
        move.l  ClearScreen,a0
        add.l   d0,a0   

        move.l  a0,(a6)         ; Vastaava paikka ClearScreenissÀ
        move.l  a4,4(a6)        ; Vanha Sijainti
        move.w  d6,8(a6)        ; Talletetaan BLTSIZE

;        WaitForBlitter
;        move.w  #0000,$062(a5)  ; BLTBMOD
;        move.w  #0028,$060(a5)  ; BLTCMOD 
;        move.w  #0000,$064(a5)  ; BLTAMOD
;        move.w  #0028,$066(a5)  ; BLTDMOD

        move.w  d2,$042(a5)     ; BLTCON1
        or.w   #$0fce,d2       ; ynnÀtÀÀn minterm+use shift valueen
        move.w  d2,$040(a5)     ; BLTCON0
        move.l  a4,$048(a5)     ; BLTCPTR kohde
        move.l  a2,$04c(a5)     ; BLTBPTR bob-data
        move.l  a3,$050(a5)     ; BLTAPTR mask
        move.l  a4,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE
ExitBlitBob
        rts

BlitBullet
        move.w  #1026,d6        ; BLTSIZE

        asl.l   #2,d1             ; Kerrotaan y-koord. 4:llÀ
        cmp.l   #256*4,d1
        bge.s   ExitBlitBullet
        cmp.l   #-4*4,d1       ; -(Bobin korkeus)
        ble.s   ExitBlitBullet

        move.l  #EnBulletBob,a2
        move.l  #EnBulletMask,a3
        cmp.l   #(255-4)*4,d1  ; Alalaita
        ble.s   NxTest
        move.l  #256*4,d6       ; Screenin lainien mÀÀrÀ (eli korkeus)
        sub.l   d1,d6           ; Kuinka monta pixelia nÀkyvissÀ
        lsl.l   #6,d6           ; Lasketaan BLTSIZE
        addq.l  #2,d6           ; X lisÀtÀÀn suoraan tÀssÀ versiossa..  
        bra.s   Ready
NxTest
        cmp.l   #0,d1           ; YlÀlaita (kÀsitellÀÀn negatiiviset
        bge.s   Readyjoo              ; koordinaatit)
        moveq   #0,d6
        move.l  #4*4,d6        ; Bobin korkeus (siis y-pituus)
        add.l   d1,d6           ; Nyt d6:ssa bobin korkeus!
        lsl.l   #6,d6           ; Lasketaan BLTSIZE
        add.l   #2,d6           ; X lisÀtÀÀn suoraan tÀssÀ versiossa..  
        neg.l   d1              ; Lasketaan kohta, mistÀ bobbi-dataa
        lsl.l   #2,d1           ; aletaan blittaamaan
        add.l   d1,a2
        add.l   d1,a3
        moveq   #0,d1           ; Y-koordinaatti on tietysti nolla..
;------------------------------------------------------------------------------
;-- Lasketaan osoite
;------------------------------------------------------------------------------
Readyjoo
        lsl.l   #5,d1
        move.b  d0,d2
        lsr.l   #3,d0
        add.l   d1,d0
        ext.l   d0
        add.l   ScrollOffset,d0 ; ScrollOffset
        and.l   #$000f,d2
        mulu    #$1000,d2
        move.l  DrawScreen,a4
        add.l   d0,a4
        move.l  ClearScreen,a0
        add.l   d0,a0   

        move.l  a0,(a6)         ; Vastaava paikka ClearScreenissÀ
        move.l  a4,4(a6)        ; Vanha Sijainti
        move.w  d6,8(a6)        ; Talletetaan BLTSIZE

        WaitForBlitter
        move.w  #0000,$062(a5)  ; BLTBMOD
        move.w  #0028,$060(a5)  ; BLTCMOD 
        move.w  #0000,$064(a5)  ; BLTAMOD
        move.w  #0028,$066(a5)  ; BLTDMOD

        move.w  d2,$042(a5)     ; BLTCON1
        or.w    #$0fce,d2       ; ynnÀtÀÀn minterm+use shift valueen
        move.w  d2,$040(a5)     ; BLTCON0
        move.l  a4,$048(a5)     ; BLTCPTR kohde
        move.l  a2,$04c(a5)     ; BLTBPTR bob-data
        move.l  a3,$050(a5)     ; BLTAPTR mask
        move.l  a4,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE
ExitBlitBullet
        rts

;------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------
ReadAttackWaves
          move.l  pt_toCoolF,d0

          moveq   #0,d1
          move.b  level,d1
          cmp.b   #2,d1
          beq     Level2

          cmp.b   #3,d1
          beq     Level3

; LEVEL 1

          cmp.l  #1280,d0
          beq.s  Kla
;         beq.s LM  ; HUOM!

          cmp.l   #2904,d0
          beq.s   Yep

          cmp.l   #6400,d0
          beq.s   AsteroiditKehiin

          cmp.l   #13480,d0
          beq.s   LM

          rts

Level2
          cmp.l  #1216,d0
          beq.s  putunits

          cmp.l  #2904,d0
          beq.s  putships

          cmp.l  #6400,d0
          beq.s  AsteroiditKehiin

          cmp.l #13408,d0
          beq.s  PutLoppuUnits

          cmp.l  #13440,d0
          beq    LM

          rts

Level3
          cmp.l  #320,d0
          beq.s  l3_aw1

          cmp.l  #6400,d0
          beq.s  AsteroiditKehiin

          cmp.l  #13480,d0
          beq    LM

          rts

; 3. hyökkÀysaalto

Yep       move.b  #1,CoordBobsRunning

          move.l  #Coords1,Coords

          move.l  #RengasBob,a3
          move.l  #RengasMask,a4
          move.b  #16,nr_of_bobs
          lea     PTRsAndONOFF,a0
          moveq   #0,d7
          move.b  nr_of_bobs,d7
          subq.l     #1,d7
          moveq   #0,d0
DefSil    move.l  d0,(a0)+        ; Pointteri koordinaatteihin
          move.w  #1,(a0)+        ; "Enemy kehissÀ" -merkki
          move.w  #1,(a0)+        ; KestÀvyys
          move.l  a3,(a0)+        ; Bob-data
          move.l  a4,(a0)+       ; Maski

          add.l   #32,d0          ; 
          dbf     d7,DefSil
          move.b  nr_of_bobs,AmEnemies
          rts


; 2. HyökkÀysaalto

Kla     
            lea     Units,a1
            move.w  #1,(a1)
            move.l  #96,2(a1)
            move.l  #-16,6(a1)

            move.l  #Unit,28(a1)
            move.l  #UnitMask,32(a1)
            move.l  #ExplodedUnit,36(a1)
            move.l  #ExplodedUnitM,40(a1)
            move.w  #1,46(a1)

            add.l   #48,a1

            move.w  #1,(a1)
            move.l  #112,2(a1)
            move.l  #-16,6(a1)

            move.l  #Unit,28(a1)
            move.l  #UnitMask,32(a1)
            move.l  #ExplodedUnit,36(a1)
            move.l  #ExplodedUnitM,40(a1)
            move.w  #1,46(a1)

            add.l   #48,a1

            move.w  #1,(a1)
            move.l  #128,2(a1)
            move.l  #-16,6(a1)

            move.l  #Unit,28(a1)
            move.l  #UnitMask,32(a1)
            move.l  #ExplodedUnit,36(a1)
            move.l  #ExplodedUnitM,40(a1)
            move.w  #1,46(a1)

            add.l   #48,a1

            move.w  #1,(a1)
            move.l  #144,2(a1)
            move.l  #-16,6(a1)

            move.l  #Unit,28(a1)
            move.l  #UnitMask,32(a1)
            move.l  #ExplodedUnit,36(a1)
            move.l  #ExplodedUnitM,40(a1)
            move.w  #1,46(a1)

            rts

; 3. HyökkÀysaalto

;Yea      move.b  #1,CoordBobsRunning
;
;        move.l  #Coords2,Coords
;
;         move.l     #UfoBob,a1
;         move.l     #UfoMask,a4
;         move.b  #16,nr_of_bobs
;       lea     PTRsAndONOFF,a0
;         moveq   #0,d7
;        move.b  nr_of_bobs,d7
;         subq.l  #1,d7
;         moveq   #0,d0
;DSil    move.l  d0,(a0)+               ; Pointteri koordinaatteihin
;         move.w  #1,(a0)+              ; KehissÀ
;         move.w  #3,(a0)+              ; KestÀvyys
;         move.l  a1,(a0)+              ; Bob-data
;       move.l  a4,(a0)+                ; Mask-data
;        add.l   #32,d0
;        dbf     d7,DSil
;        move.b  nr_of_bobs,AmEnemies

;         rts

; 4. HyökkÀysaalto

AsteroiditKehiin
        move.b  #1,AsteroidsRunning
        move.w  #164,Nr_of_asteroids
        rts

LM      move.b  #1,MonsterKehissa
        rts

; Level 2

PutLoppuUnits
            lea     Units,a1
            move.w  #1,(a1)
            move.l  #112,2(a1)
            move.l  #-16,6(a1)
            move.l  #Unit,28(a1)
            move.l  #UnitMask,32(a1)
            move.l  #ExplodedUnit,36(a1)
            move.l  #ExplodedUnitM,40(a1)
            move.w  #0,46(a1)

            add.l   #48,a1

            move.w  #1,(a1)
            move.l  #128,2(a1)
            move.l  #-16,6(a1)
            move.l  #Unit,28(a1)
            move.l  #UnitMask,32(a1)
            move.l  #ExplodedUnit,36(a1)
            move.l  #ExplodedUnitM,40(a1)
            move.w  #0,46(a1)

            rts

putunits
            lea     Units,a1
            move.w  #1,(a1)
            move.l  #112,2(a1)
            move.l  #-16,6(a1)
            move.l  #Unit,28(a1)
            move.l  #UnitMask,32(a1)
            move.l  #ExplodedUnit,36(a1)
            move.l  #ExplodedUnitM,40(a1)
            move.w  #1,46(a1)

            add.l   #48,a1

            move.w  #1,(a1)
            move.l  #128,2(a1)
            move.l  #-16,6(a1)
            move.l  #Unit,28(a1)
            move.l  #UnitMask,32(a1)
            move.l  #ExplodedUnit,36(a1)
            move.l  #ExplodedUnitM,40(a1)
            move.w  #1,46(a1)
            rts

putships
            move.b  #1,CoordBobsRunning

            move.l  #Coords2,Coords

            move.l  #ShipBob,a3
            move.l  #ShipMask,a4
            move.b  #16,nr_of_bobs
            lea     PTRsAndONOFF,a0
            moveq   #0,d7
            move.b  nr_of_bobs,d7
            subq.l  #1,d7
            moveq   #0,d0
initSil     move.l  d0,(a0)+          ; Pointteri koordinaatteihin
            move.w  #1,(a0)+        ; "Enemy kehissÀ" -merkki
            move.w  #3,(a0)+          ; KestÀvyys
            move.l  a3,(a0)+          ; Bob-data
            move.l  a4,(a0)+         ; Maski

            add.l   #32,d0          ; 
            dbf     d7,initSil
            move.b  nr_of_bobs,AmEnemies
            rts

l3_aw1
            move.b  #1,CoordBobsRunning

            move.l  #Coords3,Coords

            move.l  #WBob,a3
            move.l  #WMask,a4
            move.b  #16,nr_of_bobs
            lea     PTRsAndONOFF,a0
            moveq   #0,d7
            move.b  nr_of_bobs,d7
            subq.l   #1,d7
            moveq   #0,d0
init_l3_aw1
            move.l  d0,(a0)+          ; Pointteri koordinaatteihin
            move.w  #1,(a0)+        ; "Enemy kehissÀ" -merkki
            move.w  #3,(a0)+          ; KestÀvyys
            move.l  a3,(a0)+          ; Bob-data
            move.l  a4,(a0)+         ; Maski

            add.l   #32,d0          ; 
            dbf     d7,init_l3_aw1
            move.b  nr_of_bobs,AmEnemies
            rts

;------------------------------------------------------------------------------
; Katsotaan pitÀÀkö koordinaativalmiita bobbjea liikuttaa
;------------------------------------------------------------------------------
CheckCoordBobs
          cmp.b  #1,CoordBobsRunning
          beq.s  Yes
          rts
Yes       cmp.b  #0,AmEnemies
          beq.s  Ye
          bra.s  CCBR
Ye        cmp.b  #0,MovingEBullets
          beq.s  Chess
          
CCBR      bsr    PalautetaanTaustat
          bsr    HandleBob
          bsr    HandleEBullets
          bsr    Collisions
ExitCheck
          rts
Chess     cmp.b   #1,DoLastCoordBobFrames
          beq.s   Yeah
          move.b  #1,DoLastCoordBobFrames
          move.b  #1,LastCBFrames
Yeah      bsr     PalautetaanTaustat
          subq.b  #1,LastCBFrames
          cmp.b   #0,LastCBFrames
          beq.s   OliNolla
          rts
OliNolla
          move.b  #0,LastCBFrames
          move.b  #0,CoordBobsRunning
          move.b  #0,DoLastCoordBobFrames
          rts

;------------------------------------------------------------------------------
Collisions
; 1° Ovatko pelaajan laakit osuneet vihollisiin?
; Periaate: Otetaan laaki 1. Verrataan sitÀ kaikkiin enemyihin.
;           Otetaan laaki 2. Verrataan sitÀ kaikkiin enemyihin. JNE.
;------------------------------------------------------------------------------
;        move.w  #$0779,$01a4(a5)
        lea     Laakit,a0
        move.w  #AmountBullets,d7       ; Omien laakien mÀÀrÀ
CSil1:  lea     PTRsAndONOFF,a1
        moveq    #0,d6
        move.b  nr_of_bobs,d6        ; Vihollisten mÀÀrÀ -1
        subq.l  #1,d6

CSil2:  cmp.w   #0,(a0)
        bne.s   CSil3
        addq.l  #6,a0
        dbf     d7,CSil2
        bra.s   EnemiesToPlayer
CSil3:  cmp.w   #0,4(a1)        ; Katsotaan onko ko. enemy kehissÀ;
        beq.s   Nxt             ; ei -> seuraava enemy
        move.w  4(a0),d0        ; y-test ; Otetaan laakin (Ply) y-koord.
        move.l  Coords,a2       ; Pointteri enemyn
        add.l   (a1),a2         ; liikerataan!
        move.w  (a2),d2        ; Enemyn x-koord.
        move.w  2(a2),d1         ; Enemyn y-koord.
        sub.w   d1,d0
;       cmp.w   #0,d0
        blt.s   Nxt
        cmp.w   #8+8,d0
        bgt.s   Nxt
        move.w  2(a0),d0        ; x-test ; Laakin (Ply) x-koord.
        sub.w   d2,d0           ; Pelaajan x miinus enemyn x
        cmp.w   #-5,d0
        blt.s   Nxt
        cmp.w   #13,d0
        bgt.s   Nxt
        move.w  #0,(a0)         ; Laaki pois kehistÀ -merkki
;         subq.b  #1,OwnBulletsOnScreen
        subq.w  #1,6(a1)
        cmp.w   #0,6(a1)          ; Onko hajalla?
        bne.s   Nxt

        move.w  #0,4(a1)        ; Enemy pois kehistÀ -merkki
        subq.b  #1,AmEnemies
        addq.w  #5,Pisteet        ; LisÀtÀÀn pelaajan pisteitÀ
          
        move.l   Exp_PT,a4
        move.w   #1,(a4)
        move.w   (a2),2(a4)
        move.w   2(a2),4(a4)
        move.w   #4,6(a4)
        add.l    #12,a4
        cmp.w    #-1,(a4)
        bne.s     ptr_ok
        move.l   #Explosions,Exp_PT
;         move.w   #$fff,$dff180
        bra.s    Nxt
ptr_ok  move.l   a4,Exp_PT

Nxt     add.l   #16,a1          ; Seuraava enemy
        dbf     d6,CSil3
        addq.l  #6,a0           ; Seuraava laaki (Ply)
        dbf     d7,CSil1

;------------------------------------------------------------------------------
; 2° Onko joku vihulainen onnistunut krunssaamaan pelaajan aluksen?
; Periaate: Verrataan kaikkien vihollisten koordinaatteja pelaajan x,y:hyn
;------------------------------------------------------------------------------
EnemiesToPlayer
        moveq   #0,d7
        move.b  nr_of_bobs,d7       ; TÀssÀ oli bugi ennen!
        subq.l  #1,d7

        lea     PTRsAndONOFF,a0 ; Vihollisten pointterit koordinaatteihin
        move.w  x,d0            ; Pelaajan x ja
        move.w  y,d1            ; y
EToPly: cmp.w   #0,4(a0)        ; Jos vihulainen ei oo kehissÀ, niin next!
        beq.s   Nekst
        move.l  Coords,a1
        add.l   (a0),a1
        move.w  (a1)+,d2        ; Vihollisen x
        move.w  (a1),d3         ; Vihollisen y
        sub.w   d0,d2           ; VihX-PelX
        cmp.w   #-16,d2         ; Vasemmanpuoleinen raja
        blt.s   Nekst
        cmp.w   #13,d2          ; Oikeanpuolinen raja
        bgt.s   Nekst
        sub.w   d1,d3           ; VihY-PelY
        cmp.w   #-15,d3         ; YlÀraja
        blt.s   Nekst
        cmp.w   #14,d3          ; Alaraja
        bgt.s   Nekst
        move.w  #$0ff0,$01a4(a5) ; CRASH!!!!!!!!!!!!!!
;         move.b  #1,gameOver
        subq.b  #1,energia
    
;        bra.s   EBulletsToPlayer   ; ???
Nekst:  add.l   #16,a0
        dbf     d7,EToPly

;------------------------------------------------------------------------------
; 3° Onko vihulaisen laaki ehkÀ jopa osunut?
; Periaate: Verrataan kaikkien enemylaakien koordinaatteja pelaajan x,y:hyn
;------------------------------------------------------------------------------
; TÀhÀn tultaessa pelaajan x on D0:ssa ja y D1:ssÀ

EBulletsToPlayer
        move.w  #AmountEBullets,d7
        lea     EnemyLaakit,a0  ; Vihollisten laakien koordinaatit
BToPly  move.w  (a0)+,d2        ; Laakin x
        bmi.s   Seuraava        ; Jos x=-1, niin seuraava laaki!
        move.w  (a0)+,d3        ; Laakin y
        sub.w   d0,d2           ; LaakiX-PelaX
        cmp.w   #-3,d2          ; Vasemmanpuoleinen raja
        blt.s   Nekzt
        cmp.w   #14,d2        ; Oikeanpuolinen raja
        bgt.s   Nekzt
        sub.w   d1,d3           ; LaakiY-PelaY
        cmp.w   #-3,d3           ; YlÀraja
        blt.s   Nekzt
        cmp.w   #14,d3           ; Alaraja
        bgt.s   Nekzt
        move.w  #$0ff0,$01a4(a5) ; CRASH!!!!!!!!!!!!!!!!
;         move.b     #1,gameOver
        subq.b  #1,energia
        bra.s   Ex_BTP          ; (Future: Lives/Energy -1)
Nekzt   dbf     d7,BToPly
Ex_BTP  rts
Seuraava
        addq.l  #2,a0           ; Seuraava laaki
        dbf     d7,BToPly
        rts

;------------------------------------------------------------------------------
PalautetaanTaustat
;------------------------------------------------------------------------------
; Enemyiden alla olevat taustat

        move.l  VanhaSij,a2     ; ClearScreen,VanhaSij,BLTSIZE
        moveq   #0,d7
        move.b  nr_of_bobs,d7
        subq.l   #1,d7
        move.l  VanhaESij,a1    ; ClearScreen,VanhaESij
        move.w  #AmountEBullets,d6
        move.w  #1026,d0
        WaitForBlitter
        move.w  #$09f0,$040(a5) ; BLTCON0
        move.w  #$0000,$042(a5) ; BLTCON0
        move.w  #0028,$064(a5)  ; BLTAMOD
        move.w  #0028,$066(a5)  ; BLTDMOD
PalautaTausta
        cmp.l   #0,(a2)
        bne.s   NoSkip
        add.l   #4+4+2,a2
        dbf     d7,PalautaTausta
        bra.s   PalautaTausta2
NoSkip  WaitForBlitter
        move.l  (a2)+,$050(a5)  ; BLTAPTR
        move.l  (a2)+,$054(a5)  ; BLTDPTR kohde
        move.w  (a2)+,$058(a5)  ; BLTSIZE
        dbf     d7,PalautaTausta

; Vihollisten laakien alla olevat taustat
PalautaTausta2 
        cmp.l   #0,(a1)
        bne.s   NoSkip2
        addq.l  #4+4,a1
        dbf     d6,PalautaTausta2
        bra.s   ExitPal
NoSkip2 WaitForBlitter
        move.l  (a1)+,$050(a5)  ; BLTAPTR
        move.l  (a1)+,$054(a5)  ; BLTDPTR kohde
        move.w  d0,$058(a5)     ; BLTSIZE
        dbf     d6,PalautaTausta2
ExitPal move.w  $6(a5),Random   ; Avitetaan satunnaislukugeneraattoria
        rts

;------------------------------------------------------------------------------
; Palautetaan asteroidien alta tausta
;------------------------------------------------------------------------------
PalautaAsteroidienTausta
          moveq   #max_asteroids_on_screen-1,d7
;         lea       Asteroids,a0
          move.l  VanhaAstSij,a6

          WaitForBlitter
          move.w  #$09f0,$040(a5) ; BLTCON0
          move.w  #$0000,$042(a5) ; BLTCON0
          move.w  #0028,$064(a5)  ; BLTAMOD
          move.w  #0028,$066(a5)  ; BLTDMOD

PalAstTausta
          cmp.l   #0,(a6)          ; Onko liikkeellÀ?
          beq.s   SkipAst
          WaitForBlitter
          move.l  (a6)+,$050(a5) ; BLTAPTR
          move.l  (a6)+,$054(a5) ; BLTDPTR
          move.w  (a6)+,$058(a5) ; BLTSIZE
;         move.l  #0,-10(a6)
SkipAst
;         add.l   #10,a0                ; Oli 20
          dbf     d7,PalAstTausta

          rts

;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
HandlePlayer:
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Put the player's ship
        lea     SPR1,a1         ; Oma alus
        move.w  x,d0            ; x
        move.w  y,d1            ; y
        move.w  #15,d2          ; korkeus
        bsr     SpriteKondikseen

;------------------------------------------------------------------------------
; TÀssÀ liikutetaan ja pistetÀÀn kehiin omat spritelaakit.
; Laakimuuttujille tÀytyy
; siis varata kiinteÀsti muistia kuvaruudulle mahtuvien laakien mÀÀrÀ kertaa 3!
;------------------------------------------------------------------------------
        moveq   #AmountBullets,d7

        move.l  LaakiPT,a0
        lea     SPR0,a1         ; Laakisprite

BSil:   cmp.w   #0,(a0)         ; Onko laaki liikenteessÀ = kehiinkö?
        beq.s   NextB
        subq.w  #BSpeed,4(a0)   ; Laakin liikutus!
        move.w  2(a0),d0        ; Laakin x
        move.w  4(a0),d1        ; Laakin y
        cmp.w   #-8,d1
        bgt.s   Continue
        move.w  #0,(a0)         ; Laaki ei kehissÀ -merkki
;         subq.b  #1,OwnBulletsOnScreen
        bra.s   NextB
Continue:
        moveq   #8,d2           ; Laakispriten korkeus
        bsr     SpriteKondikseen
        add.l   #36,a1          ; Seuraava sprite

NextB:  addq.l  #6,a0
        cmp.w   #-1,(a0)
        bne.s   NoEi
        lea     Laakit,a0
NoEi:   dbf     d7,BSil
        move.l  #0,(a1)         ; Stop usage of LaakiSprite (SPR 0 tai 1)
Ex:     rts

;------------------------------------------------------------------------------
Joystick:
;------------------------------------------------------------------------------
        move.w  $c(a5),d6       ; Joikkis rekisteri

        btst    #1,d6           ; Ohjataanko oikealle?
        beq.s   jskip           ; Jos ei niin ...

        cmp.b   #1,phase
        beq.s   rdec1
        cmp.b   #2,phase
        beq.s   rdec2
        cmp.b   #3,phase
        beq.s   rdec3

        move.b   #1,phase
        move.b   #10,delay
rdec1   subq.b   #1,delay
        addq.w   #1,x
        cmp.b   #0,delay
        bne.s   ei1
        addq.b  #1,phase
        move.b  #5,delay
ei1     bra.s   ROnkoRajoissa

rdec2   subq.b  #1,delay
        addq.w  #2,x
        cmp.b   #0,delay
        bne.s   ei2
        addq.b  #1,phase
ei2     bra.s   ROnkoRajoissa

rdec3   addq.w  #3,x

ROnkoRajoissa

        cmp.w   #255-16,x
        ble.s   Nappi
        move.w  #255-16,x
        bra.s   EsiNappi

jskip:  btst    #9,d6           ; Ohjataanko vasemalle?
        beq.s   EsiNappi           ; Jos ei niin ...

        cmp.b   #1,phase
        beq.s   ldec1
        cmp.b   #2,phase
        beq.s   ldec2
        cmp.b   #3,phase
        beq.s   ldec3

        move.b  #1,phase
        move.b  #10,delay
ldec1   subq.b  #1,delay
        subq.w  #1,x
        cmp.b   #0,delay
        bne.s   ei3
        addq.b  #1,phase
        move.b  #5,delay
ei3     bra.s   LOnkoRajoissa

ldec2   subq.b  #1,delay
        subq.w  #2,x
        cmp.b   #0,delay
        bne.s   ei4
        addq.b  #1,phase
ei4     bra.s   LOnkoRajoissa

ldec3   subq.w  #3,x

LOnkoRajoissa

        cmp.w   #0,x
        bge.s   Nappi
        move.w  #0,x

EsiNappi
        move.b  #0,phase

Nappi   cmp.b   #0,Laskuri
        beq.s   Test
        subq.b  #1,Laskuri
        rts
Test:   btst    #7,$bfe001      ; Katsotaan painetaanko joikkiksen nappia ja
        bne.s   ExitJoystick    ; jos kyllÀ, niin laaki kehiin jos ei niin ei
        cmp.b   #1,NPohjassa
        bne.s   EiOo
Here:   rts
EiOo:   
;        cmp.b   #3,OwnBulletsOnScreen
;         beq.s   Here
;         addq.b  #1,OwnBulletsOnScreen
        move.b  #1,NPohjassa
        move.b  #Frames,Laskuri
        move.l  LaakiPT,a0
        move.w  x,d0            ; Laakille koordinaatit
        move.w  y,d1
        addq.w  #5,d0
        subq.w  #8,d1
        move.w  #1,(a0)         ; Laaki liikkellÀ merkki
        move.w  d0,2(a0)        ; Laakille alku-x
        move.w  d1,4(a0)        ; Laakille alky-y
        addq.l  #6,a0
        cmp.w   #-1,(a0)
        bne.s   Tedve
        lea     Laakit,a0
Tedve:  move.l  a0,LaakiPT
        rts
ExitJoystick
        cmp.b   #1,NPohjassa
        bne.s   Eij
        move.b  #0,NPohjassa
Eij:    rts

;------------------------------------------------------------------------------
; Sprite Kondikseen
; Usage: a1=sprite,d0=x,d1=y,d2=korkeus
; Kantsii ehkÀ kehitellÀ semmoinen sprite-macro, niin koodi lyhenee vÀhÀn
SpriteKondikseen 
X_kuntoon 
        and.b   #%10000000,3(a1)
        add.w   #32,d0
        add.w   #128,d0         ; Koodia kannattanee optimoida niin, ettÀ
        add.w   #44,d1          ; nÀmÀ on jo lisÀtty valmiiksi..
        add.w   d1,d2           ; VSTART+Korkeus=VSTOP

        ror.w   #1,d0           ; 8 ylintÀ x:n bittiÀ
        move.b  d0,1(a1)        ; HSTARTiin.
        btst    #15,d0          ; Katsotaan pitÀÀkö
        beq.s   Y_kuntoon       ; "the HSTART low bit"
        bset    #0,3(a1)        ; asettaa.
Y_kuntoon
        move.b  d1,(a1)         ; 8 alinta y:n bittiÀ VSTARTiin
        btst    #8,d1           ; Katsotaan pitÀÀkö
        beq.s   VSTOP_kuntoon   ; "the VSTART high bit"
        bset    #2,3(a1)        ; asettaa.
VSTOP_kuntoon 
        move.b  d2,2(a1)        ; 8 alinta vstop:in bittiÀ VSTOPpiin
        btst    #8,d2           ; Katsotaan pitÀÀkö
        beq.s   SprOut          ; "the VSTOP high bit"
        bset    #1,3(a1)        ; asettaa.
SprOut  rts

;------------------------------------------------------------------------------
; KÀsitellÀÀn energiasprite
;------------------------------------------------------------------------------
HandleEnergySprite
          moveq   #0,d2
          move.b  energia,d2            ; Korkeus
          cmp.b   #0,d2
          bgt.s   energiaa
          moveq   #0,d2
          move.b  #1,gameOver
energiaa
          moveq   #16,d3
          sub.l   d2,d3
          move.l  #235,d0
          moveq   #5,d1
          add.l   d3,d1
          move.l  #SPR2,a1
          bsr     SpriteKondikseen
          rts

;------------------------------------------------------------------------------
Scroll  cmp.b   #1,MonsterKehissa
        beq.s   GoOn

;        lea     Coolfield,a6
        move.l  coolfield,a6
        cmp.l   #5120*4,pt_toCoolF
        bne.s   Neij
        move.l  #0,pt_toCoolF

Neij    add.l   pt_toCoolF,a6
        bsr     DrawBlocks      ; PiirrettÀn 1 blocki kaikkiin (3) screeneihin
        sub.l   #32*4,ScrollOffset      ; Scrollataan 1 pixeli

        addq.b  #1,Frame
        cmp.b   #16,Frame
        bne.s   GoOn
        move.l  #0,Bl_paikka
        move.b  #0,Frame        
        cmp.b   #1,LameFrame
        bne.s   EiLameFrame
        move.b  #0,LameFrame
        move.l  #(256+16+16)*4*32,ScrollOffset
EiLameFrame
        sub.l   #16,LineN
        cmp.l   #-16,LineN
        bne.s   GoOn
        move.l  #0,Bl_paikka
        move.b  #1,LameFrame
        move.l  #256+16,LineN
GoOn    rts

;------------------------------------------------------------------------------
Show:   move.l  ShowScreen,d1
        add.l   ScrollOffset,d1
        move.w  d1,low1
        swap    d1
        move.w  d1,high1
        swap    d1
        add.l   #32,d1
        move.w  d1,low2
        swap    d1
        move.w  d1,high2
        swap    d1
        add.l   #32,d1
        move.w  d1,low3
        swap    d1
        move.w  d1,high3
        swap    d1
        add.l   #32,d1
        move.w  d1,low4
        swap    d1
        move.w  d1,high4
        rts

;------------------------------------------------------------------------------
DrawBlocks:     
        move.w  #4097,d6        ; BLTSIZE (16*(16*4))
        move.l  LineN,d1        ; Rivinumero, mihin blocki blitataan
        lsl.l   #7,d1           ; Kerrotaan 32*4:llÀ = screen's width * nr. bpls

        cmp.b   #1,LameFrame
        beq     Lame

; Kopsataan aluksi sama pala kahteen eri paikkaan ClearScreeniin

        move.l  ClearScreen,a2
        add.l   d1,a2           
        add.l   Bl_paikka,a2

        WaitForBlitter
        move.w  #$09f0,$040(a5) ; BLTCON0
        move.w  #$0000,$042(a5) ; BLTCON0
        move.w  #0038,$064(a5)  ; BLTAMOD
        move.w  #0030,$066(a5)  ; BLTDMOD
        
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE

        add.l   #Dest,a2        ; Dest-osoite
        WaitForBlitter
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE (16*(16*4))

; ..sitten BitMap1:een

        move.l  BitMap1,a2
        add.l   d1,a2           
        add.l   Bl_paikka,a2

        WaitForBlitter
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE

        add.l   #Dest,a2        ; Dest-osoite
        WaitForBlitter
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE (16*(16*4))

; ..sitten BitMap2:een

        move.l  BitMap2,a2
        add.l   d1,a2           
        add.l   Bl_paikka,a2

        WaitForBlitter
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE

        add.l   #Dest,a2        ; Dest-osoite
        WaitForBlitter
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE (16*(16*4))
        addq.l  #2,Bl_paikka
        addq.l  #4,pt_toCoolF
        rts

; Blitataan ensin ClearScreeniin

Lame:   move.l  ClearScreen,a2
        add.l   d1,a2           
        add.l   Bl_paikka,a2

        WaitForBlitter
        move.w  #$09f0,$040(a5) ; BLTCON0
        move.w  #$0000,$042(a5) ; BLTCON0
        move.w  #0038,$064(a5)  ; BLTAMOD
        move.w  #0030,$066(a5)  ; BLTDMOD

        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE (16*(16*4))

; Sitten BitMap1:een

        move.l  BitMap1,a2
        add.l   d1,a2           
        add.l   Bl_paikka,a2

        WaitForBlitter
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE (16*(16*4))

; Sitten BitMap2:een

        move.l  BitMap2,a2
        add.l   d1,a2           
        add.l   Bl_paikka,a2

        WaitForBlitter
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE (16*(16*4))
        addq.l  #2,Bl_paikka
        addq.l  #4,pt_toCoolF
        rts

;------------------------------------------------------------------------------
SwapScreens:
        cmp.b   #1,Kumpainen
        beq     LetItBeOneThen
        move.l  BitMap2,DrawScreen
        move.l  BitMap1,ShowScreen
;         cmp.b   #1,CoordBobsRunning
;         bne.s   Ej
        move.l  #VanhaSij1,VanhaSij
        move.l  #VanhaESij1,VanhaESij
;         lea     Asteroids,a0
;         move.l  #AstVanhaSij0,10(a0)
        cmp.b   #1,AsteroidsRunning
        bne.s   Eii
        move.l  #VanhaAstSij0,VanhaAstSij
Eii     
        move.l  #UnitsVanhaSij0,UnitsVanhaSij
        move.l  #UnitsVBSij0,UnitsVBSij

        move.l  #ExpVanhaSij0,VanhaExpSij

        move.l  #MonstVanhaSij0,MonsterVanhaSij
        move.l  #MonstBVanhaSij0,MonstBVanhaSij

        move.l  #MExp_VanhaSij0,MExp_vanhasij

        move.b  #1,Kumpainen
        rts

LetItBeOneThen:
        move.l  BitMap1,DrawScreen
        move.l  BitMap2,ShowScreen
;         lea     Asteroids,a0
;        move.l  #AstVanhaSij1,10(a0)
        cmp.b   #1,AsteroidsRunning
        bne.s   Eiii
        move.l  #VanhaAstSij1,VanhaAstSij
Eiii    move.l  #VanhaSij2,VanhaSij
        move.l  #VanhaESij2,VanhaESij

        move.l  #UnitsVanhaSij1,UnitsVanhaSij
        move.l  #UnitsVBSij1,UnitsVBSij

        move.l  #ExpVanhaSij1,VanhaExpSij

        move.l  #MonstVanhaSij1,MonsterVanhaSij
        move.l  #MonstBVanhaSij1,MonstBVanhaSij

        move.l  #MExp_VanhaSij1,MExp_vanhasij

        move.b  #0,Kumpainen
        rts

;------------------------------------------------------------------------------
; Tsekataan ovatko pelaajan laakit osuneet asteroideihin tai asteroidit pelaajaan
;------------------------------------------------------------------------------
AsteroidCollisions
; Ovatko pelaajan laakit osuneet asteroideihin
; Idea: Otetaan jÀrjestyksessÀ pelaajan laakeja ja verrataan niitÀ liikkeellÀ
; oleviin asteroideihin.

         moveq    #0,d4
         moveq    #0,d5
         move.w   x,d4                      ; Pelaajan X
         move.w   y,d5                      ; Pelaajan Y

         lea      Laakit,a0
         moveq    #AmountBullets,d7
LaakiKehissa
         cmp.w    #0,(a0)                  ; Onko laaki liikkeellÀ
         beq.s    NextLaaki           ; Jos ei ole, niin otetaan seuraava laaki
;       moveq    #0,d0
;       moveq    #0,d1
         move.w   2(a0),d0              ; Laakin X
         move.w   4(a0),d1              ; Laakin Y
         bra.s    CompareToAsteroids
NextLaaki
         addq.l   #6,a0
         dbf      d7,LaakiKehissa
         bra.s    PlayerToAsteroids

CompareToAsteroids
         moveq    #max_asteroids_on_screen-1,d6
         lea      Asteroids,a1
AstCollSil
         cmp.w    #0,(a1)                   ; Onko liikkeellÀ
        beq.s    NextAster           ; Jos ei ole niin seuraava asteroidi
;        moveq    #0,d2
;       moveq    #0,d3
         move.w   2(a1),d2              ; Asteroidin X
         move.w   4(a1),d3              ; Asteroidin Y
         sub.w    d0,d2                 ; AstX - PelX
         cmp.w    #-15,d2               ; -15
         blt.s    NextAster
         cmp.w    #2,d2             ; 2
         bgt.s    NextAster
         sub.w    d1,d3
         cmp.w    #-15,d3           ; -15
         blt.s    NextAster
         cmp.w    #16,d3            ; 16
         bgt.s    NextAster

         move.w   #0,(a0)                   ; Jos osuttu asteroidiin, niin laaki pois
;        subq.b   #1,OwnBulletsOnScreen

         subq.w   #1,8(a1)              ; VÀhennetÀÀn asteroidin kestÀvyyttÀ
         cmp.w    #0,8(a1)              ; Jos tuhoutunut, niin laitetaan
         bne.s    NextAster             ; pois kehistÀ ja lisÀtÀÀn
         move.w   #0,(a1)                   ; pelaajan pisteitÀ
         add.w    #10,Pisteet
         subq.b   #1,Asteroids_on_screen ; VÀhennetÀÀn ruudulla olevien
                                                    ; asteroidien mÀÀrÀÀ
         move.l   Exp_PT,a4
         move.w   #1,(a4)
         move.w   2(a1),2(a4)
         move.w   4(a1),4(a4)
         move.w   #4,6(a4)
         add.l    #12,a4
         move.l   a4,Exp_PT
         cmp.w    #-1,(a4)
         bne.s   NextAster
         move.l   #Explosions,Exp_PT

NextAster
         add.l    #10,a1
         dbf      d6,AstCollSil         ; Kun kaikki asteroidit on katsottu
         addq.l   #6,a0                 ; otetaan seuraava laaki
         dbf      d7,LaakiKehissa

; Katsotaan onko pelaaja törmÀnnyt asteroidiin

PlayerToAsteroids
         moveq   #max_asteroids_on_screen-1,d7
         lea     Asteroids,a1
AsterSil
         cmp.w   #0,(a1)                    ; Jos asteroidi ei ole liikkeellÀ, niin
         beq.s   NxtAster                   ; seuraava asteroidi
         moveq   #0,d2
         moveq   #0,d3
         move.w  2(a1),d2                  ; Asteroidin X
         move.w  4(a1),d3                   ; Asteroidin Y
         sub.w   d4,d2
         cmp.w   #-15,d2
         blt.s   NxtAster
         cmp.w   #13,d2
         bgt.s   NxtAster
         sub.w   d5,d3
         cmp.w   #-15,d3
         blt.s   NxtAster
         cmp.w   #14,d3
         bgt.s   NxtAster
         move.w  #$0ff0,$1a4(a5)
;        move.b #1,gameOver
         subq.b  #1,energia
NxtAster
         add.l   #10,a1
         dbf     d7,AsterSil
         rts

;------------------------------------------------------------------------------
; Laitetaan uusi asteroidi nÀytölle
;------------------------------------------------------------------------------
PutAsteroid
         cmp.w    #0,Nr_of_asteroids    ; Paljonko asteroideja jÀljellÀ
         ble.s    ExitPA              ; (yo. on kokonaismÀÀrÀ)

         cmp.b   #max_asteroids_on_screen,Asteroids_on_screen
         bge.s    ExitPA

         move.w   Random,d5
         lea      Asteroids,a0
         moveq    #max_asteroids_on_screen-1,d7
PASil    cmp.w    #0,Nr_of_asteroids    ; Onko kaikki asteroidit kÀytetty?
         ble.s    ExitPA

         cmp.b    #max_asteroids_on_screen,Asteroids_on_screen ; Onko ruudulla max mÀÀrÀ
         beq.s    ExitPA                  ; asteroideja

         cmp.w    #1,(a0)                   ; Onko jo kehissÀ?
         beq.s    NextAsteroid         ; Jos on niin seuraava asteroidi
         move.w   $6(a5),d0            ; Arvotaan uudelle asteroidille
         add.w    Random,d0            ; X-koordinaatti
         and.l    #255,d0
         cmp.w    #239,d0
         blt.s    Ookoo
         sub.l    #16,d0
Ookoo    move.w   d0,2(a0)
         move.w   #-16,4(a0)                ; Y-koordinaatti
         add.w    d5,d0                ; Arvotaan nopeus, D5:ssÀ random
         and.l    #3,d0
         cmp.l    #0,d0                ; Nolllaa ei kelpuuteta nopeudeksi
         bne.s    EiNolla
         moveq    #1,d0
EiNolla
         move.w   d0,6(a0)             ; Speed
         move.w   #9,8(a0)             ; KestÀvyys, asteroidit kestÀvÀt 3 laakia
         move.w   #1,(a0)                  ; Asteroidi kehissÀ merkki
         addq.b   #1,Asteroids_on_screen
         subq.w   #1,Nr_of_asteroids
NextAsteroid
         add.l    #10,a0
         dbf      d7,PASil

ExitPA rts
OutOfAsteroidField
         cmp.b    #0,Asteroids_on_screen
         beq.s    Out
         rts
Out      
         move.b   #1,LastAsteroidFrames
         rts

;------------------------------------------------------------------------------
; Liikutetaan ja piirretÀÀn asteroidit
;------------------------------------------------------------------------------
MoveAsteroids
 
         lea        Asteroids,a1
;        move.l   a1,a6
;       add.l    #10,a6
         move.l   VanhaAstSij,a6

         moveq    #max_asteroids_on_screen-1,d7

        move.l  ScrollOffset,d5
        WaitForBlitter
        move.w  #0000,$062(a5)  ; BLTBMOD
        move.w  #0028,$060(a5)  ; BLTCMOD 
        move.w  #0000,$064(a5)  ; BLTAMOD
        move.w  #0028,$066(a5)  ; BLTDMOD

AstSil  cmp.w    #0,(a1)              ; Onko liikkeellÀ? Jos ei ole, niin mennÀÀn
        beq.s    NextAst              ; seuraavan asteroidin kohdalle
        moveq    #0,d0
        moveq    #0,d1
        move.w   2(a1),d0         ; Asteroidin X
        move.w   4(a1),d1         ; Asteroidin Y
;        move.l   a1,a6           ; PutBob-rutiinia varten pointteri
;        add.l    #10,a6              ; kohdalleen
        move.l   #AsteroidBob,a2 ; A2:ssa bob-data
        move.l   #AsteroidMask,a3 ; A3:ssa mask-data
        bsr      PutBob
        add.l    #10,a6           ; HUOM !!!
        moveq    #0,d0
        move.w   6(a1),d0         ; Speed
        add.w    d0,4(a1)        ; Liikutetaan asteroidia
        cmp.w    #256+4,4(a1)         ; Onko poissa nÀkyvistÀ?
        blt.s    NextAst
        move.w   #0,(a1)              ; Jos on, niin pois kehistÀ merkki pÀÀlle
        subq.b   #1,Asteroids_on_screen
NextAst
        add.l    #10,a1
        dbf      d7,AstSil
        rts
Jooo    cmp.b    #0,Asteroids_on_screen
        beq.s    Out

;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
HandleBob:
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
        cmp.b   #0,AmEnemies      ; Jos ei ole yhtÀÀn enemyÀ kehissÀ, niin
        bne.s   SumLeft          ; poistutaan
        rts

SumLeft lea     PTRsAndONOFF,a1 ; Pointterit koordinaatteihin + ON/OFF merkki
        move.l  VanhaSij,a6
        moveq   #0,d7
        move.b  nr_of_bobs,d7
        subq.l   #1,d7

        move.l  ScrollOffset,d5
        WaitForBlitter
        move.w  #0000,$062(a5)  ; BLTBMOD
        move.w  #0028,$060(a5)  ; BLTCMOD 
        move.w  #0000,$064(a5)  ; BLTAMOD
        move.w  #0028,$066(a5)  ; BLTDMOD
;------------------------------------------------------------------------------
BobbyLoop:
;------------------------------------------------------------------------------
        cmp.w   #0,4(a1)        ; Jos "Pois pÀÀltÀ" -merkki on pÀÀllÀ,
        bne.s   Cont            ; mennÀÀn seuraavaan bobbiin
        add.l   #16,a1          ; Seuraava bob
        add.l   #4+4+2,a6       ; Seuraava vanhasijainti stuff
        dbf     d7,BobbyLoop
        rts
Cont:   move.l  Coords,a0       ; TÀÀllÀ on koordinaatit
        add.l   (a1),a0         ; Pointteri koordinaatteihin
        cmp.w   #999,(a0)       ; Jos A0:ssa on loppumerkki, niin
        bne.s   GoMan           ; pistetÀÀn "pois pÀÀltÀ"-merkki pÀÀlle
        move.w  #0,4(a1)
        add.l   #16,a1

;        subq.l  #4,(a1)+        ; Pointteri pois 999:n kohdalta
;        move.w  #0,(a1)+        ; "Pois pÀÀltÀ" -merkki pÀÀlle
;        move.l  #0,(a6)+
        addq.l  #4+2,a6
        subq.b  #1,AmEnemies
        dbf     d7,BobbyLoop
        rts

GoMan:  moveq    #0,d1
        addq.l  #4,(a1)         ; Pointteri seuraaviin koordinaatteihin
        move.w  (a0)+,d0        ; x
        move.w  (a0),d1         ; y
        move.l  8(a1),a2
        move.l  12(a1),a3

        bsr     PutBob

        add.l   #10,a6          ; HUOM !!!
        add.l   #16,a1          ; MennÀÀn seuraavan bobin tietojen kohdalle
        dbf     d7,BobbyLoop
        rts

;------------------------------------------------------------------------------
; Blitataan 16 x 16 pixelin bob.
; D5:ssÀ on oltava ScrollOffsett ja A6:ssa pointteri rakenteeseen, missÀ on
; LONG, LONG, WORD, mitkÀ tarkoittavat ClearScreen sijainti, vanha sijainti ja
; BLTSIZE. Modulorekisterit asetettava alussa.
;------------------------------------------------------------------------------

PutBob  move.w  #4098,d6        ; BLTSIZE

;------------------------------------------------------------------------------
        asl.w   #2,d1             ; 4 bittitasoa
        cmp.w   #256*4,d1
        bge.w   ExitPutBob

        cmp.w   #-16*4,d1       ; -(Bobin korkeus)
        ble.w   ExitPutBob

        cmp.w   #(255-16)*4,d1  ; Alalaita
        ble.s   NextTest
        move.w  #256*4,d6       ; Screenin lainien mÀÀrÀ (eli korkeus)
        sub.w   d1,d6           ; Kuinka monta pixelia nÀkyvissÀ
        lsl.l   #6,d6           ; Lasketaan BLTSIZE
        addq.w  #2,d6           ; X lisÀtÀÀn suoraan tÀssÀ versiossa..  
        bra.s   ReadyToBeBlitted
NextTest
        cmp.w   #0,d1           ; YlÀlaita (kÀsitellÀÀn negatiiviset
        bge.s   ReadyToBeBlitted ; koordinaatit)
        moveq   #0,d6
        move.w  #16*4,d6        ; Bobin korkeus (siis y-pituus)
        add.w   d1,d6           ; Nyt d6:ssa bobin korkeus!
        lsl.w   #6,d6           ; Lasketaan BLTSIZE
        add.w   #2,d6           ; X lisÀtÀÀn suoraan tÀssÀ versiossa..  
        neg.w   d1              ; Lasketaan kohta, mistÀ bobbi-dataa
GMan    lsl.w   #2,d1           ; aletaan blittaamaan
        add.l   d1,a2
        add.l   d1,a3
        moveq   #0,d1           ; Y-koordinaatti on tietysti nolla..
;------------------------------------------------------------------------------
;-- Lasketaan osoite
;------------------------------------------------------------------------------
ReadyToBeBlitted:
        lsl.w   #5,d1
        moveq   #0,d2
        move.b  d0,d2
        lsr.w   #3,d0
        add.w   d1,d0
        ext.l   d0
        add.l   d5,d0           ; ScrollOffset
        and.w   #$000f,d2
        mulu    #$1000,d2
        move.l  DrawScreen,a4
        add.l   d0,a4
        move.l  ClearScreen,a0
        add.l   d0,a0   
        move.l  a0,(a6)         ; Vastaava paikka ClearScreenissÀ
        move.l  a4,4(a6)        ; Vanha Sijainti
        move.w  d6,8(a6)        ; Talletetaan BLTSIZE

        WaitForBlitter
        move.w  d2,$042(a5)     ; BLTCON1
        or.w    #$0fce,d2       ; ynnÀtÀÀn minterm+use shift valueen
        move.w  d2,$040(a5)     ; BLTCON0
        move.l  a4,$048(a5)     ; BLTCPTR kohde
        move.l  a2,$04c(a5)     ; BLTBPTR bob-data
        move.l  a3,$050(a5)     ; BLTAPTR mask
        move.l  a4,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE
ExitPutBob
        rts


;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
HandleEBullets:
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
NewEBullets:
;------------------------------------------------------------------------------
        cmp.b   #AmountEBullets+1,MovingEBullets
        bge.s   MoveEBullets
        moveq   #0,d5
        move.w  #AmountEBullets,d7
        moveq    #0,d6
        move.b  nr_of_bobs,d6
        subq.l   #1,d6

        lea     PTRsAndONOFF,a0 ; Enemyiden koordinaatit ja ON/OFF
        lea     EnemyLaakit,a2  ; x,y
HEBSil: cmp.w   #0,4(a0)        ; Onko enmy kehissÀ? Jos ei, niin seuraava
        beq.s   NextE
Hee:    cmp.w   #-1,(a2)        ; Onko laaki jo liikkeellÀ? (-1=EI , >-1=ON)
        beq.s   Ok
        addq.l  #4,a2
        dbf     d7,Hee
        bra.s   MoveEBullets
Ok:     move.w  $6(a5),d0       ; Katsotaan "satunnaisluvun" perusteella
        add.w   Random,d0       ; pistetÀÀnkö sittenkÀÀn laakia kehiin
        and.w   #%0000000000000111,d0
        cmp.w   #7,d0
        bne.s   NextE
        move.l  Coords,a1
        move.l  (a0),d0         ; Kas nÀin se bugi-laaki eliminoidaan!!
        subq.l  #4,d0           ; ..nÀin..
        add.l   d0,a1           ; ..ja nÀin!!
;        move.w  (a1)+,(a2)+     ; Enemyn x laakin alku-x:ksi
;        move.w  (a1),(a2)+      ; Enemyn y laakin alku-y:ksi
        moveq   #0,d5             ; Jos y-koordinaatti 
	  subq.l   #1,d5

	  cmp.l   #-1,d5
      beq.s    dsil

;        add.l    d5,a2                 ; Nyt numerot alkavat oikeasta kohdasta
nolla     move.b      #0,(a2)+
      dbf         d5,nolla
      subq.l   #1,d7                    ; DBF-kÀskyn vuoksi

dsil  move.l   d0,d1              ; Working copy of D0

      moveq    #1,d3                ; MÀÀritetÀÀn 10 potensiin
      move.l   d7,d2                ; digitin jÀrjestysnumero - 1
potsil  subq.l   #1,d2              ;
      cmp.l    #-1,d2               ;
      ble.s    Jatka              ;
      mulu.w   #10,d3             ;
      bra.s    potsil             ;

Jatka   move.l   d3,d2              ; Jaetaan muutettava luku
      divu.w   d2,d1              ; yllÀ mÀÀritetyllÀ luvulla
      and.l    #$0000ffff,d1      ; Nollataan jakojÀÀnnös
      divu.w   #10,d1             ; Jaetaan vielÀ 10:llÀ
      swap     d1                 ; Otetaan jakojÀÀnnös ja nollataan
      and.l    #$0000ffff,d1      ; muu osa luvusta; jÀljellÀ on
                                    ; on haettu digit!
      move.b   d1,(a2)+           ; ja kirjoitetaan digit talteen
      dbf      d7,dsil

; Tulostetaan Number "muuttujassa" oleva numerosarja

Blit    lea     Number,a1
        moveq   #5-1,d7

        move.l  #192,d5             ; x-koordinaatti

        WaitForBlitter
        move.w  #0000,$062(a5)  ; BLTBMOD
        move.w  #0028,$060(a5)  ; BLTCMOD 
        move.w  #0000,$064(a5)  ; BLTAMOD
        move.w  #0028,$066(a5)  ; BLTDMOD

BNSil   lea      Numbers,a2
        lea     NumbersMask,a3

        moveq   #0,d4
        move.b  (a1)+,d4
        lsl.l   #7,d4
        add.l   d4,a2
        add.l   d4,a3
        move.l  d5,d0
        moveq   #13,d1              ; y-koordinaatti
        lsl.l   #2,d1               ; 4 bittitasoa
        bsr     BlitNumber

        add.l   #8,d5

        dbf     d7,BNSil
ExitBlitNumbers
        rts

;------------------------------------------------------------------------------
; Tulostetaan numero
;------------------------------------------------------------------------------
BlitNumber
;------------------------------------------------------------------------------
;-- Lasketaan osoite
;------------------------------------------------------------------------------
        lsl.l   #5,d1
        move.b  d0,d2
        lsr.l   #3,d0
        add.l   d1,d0
        ext.l   d0
        add.l   ScrollOffset,d0 ; ScrollOffset
        and.l   #$000f,d2
        mulu    #$1000,d2
        move.l  DrawScreen,a4
        add.l   d0,a4

        WaitForBlitter
        move.w  d2,$042(a5)     ; BLTCON1
        or.w    #$0fce,d2       ; ynnÀtÀÀn minterm+use shift valueen
        move.w  d2,$040(a5)     ; BLTCON0
        move.l  a4,$048(a5)     ; BLTCPTR kohde
        move.l  a2,$04c(a5)     ; BLTBPTR bob-data
        move.l  a3,$050(a5)     ; BLTAPTR mask
        move.l  a4,$054(a5)     ; BLTDPTR kohde
        move.w  #2050,$058(a5)  ; BLTSIZE

        rts

;------------------------------------------------------------------------------
; Palautetaan rÀjÀhdysten tausta
;------------------------------------------------------------------------------
PalautaExpTausta
        move.l  VanhaExpSij,a1
        moveq   #20-1,d7

        WaitForBlitter
        move.w  #$09f0,$040(a5) ; BLTCON0
        move.w  #$0000,$042(a5) ; BLTCON0
        move.w  #0028,$064(a5)  ; BLTAMOD
        move.w  #0028,$066(a5)  ; BLTDMOD
Pal
        cmp.l   #0,(a1)
        bne.s   Palauta
        add.l   #10,a1
        dbf     d7,Pal
          rts
Palauta WaitForBlitter
        move.l  (a1)+,$050(a5)  ; BLTAPTR
        move.l  (a1)+,$054(a5)  ; BLTDPTR kohde
        move.w  (a1)+,$058(a5)  ; BLTSIZE
        move.l  #0,-10(a1)
        dbf     d7,Pal
        rts

;------------------------------------------------------------------------------
; Hoidellaan rÀjÀhdykset
;------------------------------------------------------------------------------
HandleExplosions

        lea     Explosions,a1
        moveq   #20-1,d7
        move.l  ScrollOffset,d5
        move.l  VanhaExpSij,a6

        WaitForBlitter
        move.w  #0000,$062(a5)  ; BLTBMOD
        move.w  #0028,$060(a5)  ; BLTCMOD 
        move.w  #0000,$064(a5)  ; BLTAMOD
        move.w  #0028,$066(a5)  ; BLTDMOD

ExpSil  cmp.w   #0,(a1)             ; Onko kehissÀ
        beq.s    NextExp
        move.l  #Explosion,a2
        add.l   8(a1),a2
        move.l  #ExplosionMask,a3
        add.l   8(a1),a3
        moveq   #0,d0
        moveq   #0,d1
        move.w  2(a1),d0
        move.w  4(a1),d1
        cmp.b   #1,MonsterKehissa
        beq.s   blit
        addq.w  #1,4(a1)
        cmp.w   #256,4(a1)
        blt.s   blit
        move.w  #0,(a1)
        bra.s   NextExp
blit    bsr     PutBob

        cmp.w   #0,6(a1)            ; Onko viive nolla
        beq.s   NextExpFrame        ; Jos on, niin mennÀÀn seuraavaan frameen
        subq.w  #1,6(a1)            ; Jos ei ollut, niin vÀhennetÀÀn viivettÀ
        bra.s   NextExp

NextExpFrame
        add.l   #256,8(a1)          ; Seuraava frame
        move.w  #4,6(a1)            ; Laitetaan viive ennalleen
        cmp.l   #256*8,8(a1)        ; Ollaanko kÀyty kaikissa?
        bne.s   NextExp             ; Jos ei olla, niin mennÀÀn seuraavaan
        move.l  #0,8(a1)            ; Jos oltiin, niin nollataan framepointteri
        move.w  #0,(a1)             ; ja laitetaan pois kehistÀ-merkki

NextExp add.l   #12,a1
        add.l   #10,a6
        dbf     d7,ExpSil
exithe  rts

;------------------------------------------------------------------------------
; Katsotaan, onko monsteri liikkeellÀ
;------------------------------------------------------------------------------
CheckMonster
         cmp.b   #1,MonsterKehissa
         beq.s   HandleMonster
         rts

;------------------------------------------------------------------------------
; KÀsitellÀÀn monsteri
;------------------------------------------------------------------------------
HandleMonster
          lea     Monster,a1
          cmp.w   #32,2(a1)
          bge.s   LiikutaHorisontaalisesti
          addq.w  #1,2(a1)
          moveq   #0,d0
          moveq   #0,d1
          moveq   #0,d2
          move.w  (a1),d0
          move.w  2(a1),d1
          bsr     PyyhiMonster

          moveq   #0,d0
          moveq   #0,d1
          lea     Monster,a1
          move.w  (a1),d0
          move.w  2(a1),d1

          move.l  60(a1),a2          ; Bob-data
          move.l  64(a1),a3          ; Mask-data
          move.l  MonsterVanhaSij,a6

          bsr     BlitMonster
          bsr     CheckMColl
          rts

LiikutaHorisontaalisesti
          cmp.b   #1,Monster_destroyed
          beq.s   ME
          move.w  DX,d0
          add.w   d0,(a1)
          cmp.w   #96,(a1)
          bne.s   Tst
          neg.w   DX
Tst       cmp.w   #0,(a1)
          bne.s   Blittaa
          neg.w   DX
Blittaa
          bsr     PyyhiMonster
          moveq   #0,d0
          moveq   #0,d1

          bsr     AmpuukoMonster
          bsr     HandleMonsterBullet

          moveq   #0,d0
          moveq   #0,d1
          lea     Monster,a1
          move.w  (a1),d0
          move.w  2(a1),d1
          move.l  60(a1),a2
          move.l  64(a1),a3
          move.l  MonsterVanhaSij,a6

          bsr     BlitMonster

ME        lea        Monster_explosion,a0
;         cmp.w   #0,(a0)
;         beq.s   CheckMColl
          cmp.b   #0,Monster_destroyed
          beq.s   CheckMColl
          bsr     HandleMonstExplosion

CheckMColl
          lea     Monster,a1
          bsr     MCollisions
          rts

;------------------------------------------------------------------------------
; Hoidellaan hirviön rÀjÀhdys
;------------------------------------------------------------------------------
HandleMonstExplosion
          cmp.b   #3,MExpFinished                   ; Peli on pelattu, kun MExpFinished = 3
          beq.s   NextLevel

          cmp.b   #1,MExpFinished
          bne.s   jatkuu
          bsr        PM                             ; Huom!
          bsr     PyyhiMonstExplosion
          subq.b  #1,LastMExpFrames
          cmp.b   #0,LastMExpFrames
          bne.s   erteees
          move.b  #3,MExpFinished
          rts

jatkuu  ;bsr      PM
          bsr     PyyhiMonstExplosion
          bsr     PyyhiMonster
          bsr     HandleMonsterBullet
          move.l  #Monster,a1
          bsr     MCollisions
          move.l  #Monster_explosion,a0
          moveq   #0,d0
          moveq   #0,d1
          move.w  2(a0),d0
          move.w  4(a0),d1

          subq.w  #1,6(a0)              ; VÀhennetÀÀn viivettÀ yhdellÀ
          cmp.w   #0,6(a0)
          bgt.s   MonstExp
          add.l   #3840,8(a0)
          move.w  #4,6(a0)              ; Viive
          cmp.l   #3840*2,8(a0)
          bne.s   MonstExp
          addq.b  #1,kierros
          move.l  #0,8(a0)              ; MennÀÀn rÀjÀhdysframen alkuun
          cmp.b   #9,kierros
          bne.s  MonstExp

          move.b  #1,MExpFinished
          move.b  #3,LastMExpFrames ; 3
          move.l  #0,8(a0)
          rts

NextLevel
          addq.b  #1,level
          cmp.b   #3,level
          beq     putlevel3
          cmp.b   #4,level
          beq.s   erteees

          move.l  #Coolfield2,coolfield
          bsr     Alustus
          bsr     FillTheScreen
erteees rts
putlevel3
          move.l  #Coolfield3,coolfield
          bsr     Alustus
          bsr     FillTheScreen
          rts

MonstExp
          move.l  8(a0),d4
          move.l  #MonsterExplosionBob,a2
          add.l   d4,a2
          move.l  #MonsterExplosionMask,a3
          move.l  MExp_vanhasij,a6
          add.l   d4,a3
          bsr     BlitMonster

          rts

HandleMonsterBullet
          moveq   #3-1,d7
          lea     Monster,a1
          addq.l  #6,a1
          move.l  ScrollOffset,d5
          move.l  MonstBVanhaSij,a6

          WaitForBlitter
          move.w  #0000,$062(a5)  ; BLTBMOD
          move.w  #0028,$060(a5)  ; BLTCMOD 
          move.w  #0000,$064(a5)  ; BLTAMOD
          move.w  #0028,$066(a5)  ; BLTDMOD

HMBSil    cmp.w   #0,(a1)
          beq.s   NextMonsterBullet

          move.l  2(a1),d0              ; Bullet X
          move.l  6(a1),d1              ; Bullet Y
          lsr.l   #7,d0
          lsr.l   #7,d1

;         move.l  #MonsterBullet,a2
;         move.l  #MonsterBulMask,a3

          bsr     BlitBullet            ; Tulostetaan monsterin laaki

          move.l  10(a1),d0
          move.l  14(a1),d1
          add.l   d0,2(a1)          ; LisÀtÀÀn bulletin X:ÀÀn addX
          add.l   d1,6(a1)          ; Sama addY:lle

          move.l  2(a1),d0
          move.l  6(a1),d1
          asr.l   #7,d0
          asr.l   #7,d1

; Katsotaan pysyykö laaki rajoissa

          cmp.w   #256+4,d1
          blt.s   ookoo
          move.w  #0,(a1)
          bra.s   NextMonsterBullet
ookoo     cmp.w   #0,d0
          bge.s   AllRight
          move.w  #0,(a1)
          bra.s   NextMonsterBullet
AllRight
          cmp.w   #255-4,d0
          blt.s   NextMonsterBullet
          move.w  #0,(a1)

NextMonsterBullet

          add.l   #18,a1
          add.l   #10,a6

          dbf     d7,HMBSil
          rts


AmpuukoMonster
          cmp.b  #1,Monster_destroyed
          beq.s  xit
          moveq  #3-1,d7
          moveq  #0,d0
          moveq  #0,d1
          move.w (a1),d0
          move.w 2(a1),d1
          move.l d0,d4                  ; Monsterin X
          move.l d1,d5                  ; Monsterin Y

          addq.l #6,a1
AMPSil    cmp.w  #0,(a1)                ; Onko laaki vapaa?
          beq.s  Ampuuko                ; Jos on, niin arvotaan, ammutaanko
          add.l  #18,a1
          dbf    d7,AMPSil
xit       rts

Ampuuko   move.w $6(a5),d0
          add.w  Random,d0
          and.l  #7,d0
          cmp.w  #7,d0
          beq.s  MAmpuu
          add.l  #18,a1
          dbf    d7,AMPSil
          rts

MAmpuu  
          move.w #1,(a1)
          moveq  #0,d2
          moveq  #0,d3
          move.w x,d2                   ; Pelaajan X
          move.w y,d3                   ; Pelaajan Y

          move.l d4,d0                  ; Otetaan monsterin X ja Y
          move.l d5,d1                  ; tallesta

          add.l  #72,d0                 ; KeskitetÀÀn
          add.l  #48,d1

          sub.l  d0,d2                  ; Lasketaan X-etÀisyys
          sub.l  d1,d3                  ; Lasketaan Y-etÀisyys

          lsl.l  #7,d2
          lsl.l  #7,d3
          lsr.l  #6,d2
          lsr.l  #6,d3
          
          move.l d2,10(a1)              ; Talletetaan addX
          move.l d3,14(a1)              ; Talletetaan addY

          lsl.l  #7,d0
          lsl.l  #7,d1

          move.l d0,2(a1)               ; Talletetaan bullet X
          move.l d1,6(a1)               ; Talletataan bullet Y
          add.l  #18,a1
          dbf    d7,AMPSil        
ExitAmpuuko
          rts

MCollisions
; Ovatko pelaajan laakit osuneet monsteriin

          lea   Monster_explosion,a0    ; Jos monsteri rÀjÀhtÀnyt,
          cmp.w #1,(a0)                 ; niin ei tsekata törmÀyksiÀ
          beq.s OMLOP

          lea    Laakit,a0
          lea    Monster,a4
          moveq  #AmountBullets,d7

MCSil     cmp.w  #1,(a0)
          beq.s  OnkoOsunut
          addq.l #6,a0
          dbf    d7,MCSil
          bra.s  OMLOP
OnkoOsunut        
          move.w 2(a0),d0               ; Laakin X
          move.w 4(a0),d1               ; Laakin Y

          sub.w  (a1),d0

          cmp.w  #0,d0
          blt.s  Seur
          cmp.w  #144,d0                ; 192
          bge.s  Seur
          sub.w  2(a1),d1

          cmp.w  #48,d1             ; 64
          bgt.s  Seur
          cmp.w  #0,d1
          blt.s  Seur
;         move.w #$fff,$1a4(a5)
          move.w #0,(a0)
          subq.w #1,4(a4)               ; VÀhennetÀÀn monsterin kestÀvyyttÀ
          addq.w #5,Pisteet         ; LisÀtÀÀn pelaajan pisteitÀ
          cmp.w  #0,4(a4)               ; Onko tuhoutunut?
          bne.s Seur
          move.b #1,Monster_destroyed
          lea    Monster_explosion,a2
          move.w #1,(a2)
          move.w (a4),2(a2)
          move.w 2(a4),4(a2)
        
Seur      addq.l #6,a0
          dbf    d7,MCSil

; Onko monsterin laakit osuuneet pelaajaan

OMLOP    lea     Monster,a1
         moveq   #3-1,d7
         addq.l  #6,a1

OMLOPSil
         cmp.w   #0,(a1)                ; Onko laaki liikkeellÀ?
         beq.s   nextbullet

         moveq   #0,d0
         moveq   #0,d1  
         move.w  x,d0
         move.w  y,d1
         move.l  2(a1),d2               ; Monst bullet X
         move.l  6(a1),d3               ; Monst bullet Y
         asr.l   #7,d2
         asr.l   #7,d3

         sub.w   d0,d2

         cmp.w   #-3,d2
         blt.s   nextbullet
         cmp.w   #14,d2
         bge.s   nextbullet

         sub.w   d1,d3

         cmp.w   #-3,d3
         blt.s   nextbullet
         cmp.w   #14,d3
         blt.s   nextbullet  
         move.w  #$fff,$1a4(a5)
         subq.b #1,energia

nextbullet
         add.l   #18,a1
         dbf     d7,OMLOPSil

         rts

;------------------------------------------------------------------------------
; PiirretÀÀn monsteri
;------------------------------------------------------------------------------
BlitMonster
          move.l  #12298,d6
          asl.w   #2,d1             ; 4 bittitasoa
          cmp.w   #-4*48,d1
          ble.s   ExitBM
          
          cmp.w   #0,d1           ; YlÀlaita (kÀsitellÀÀn negatiiviset
          bge.s   Valmis             ; koordinaatit)
          moveq  #0,d6
          move.w  #4*48,d6        ; Bobin korkeus (siis y-pituus)
          add.w   d1,d6           ; Nyt d6:ssa bobin korkeus!
          lsl.w   #6,d6           ; Lasketaan BLTSIZE
          add.w   #10,d6          ; X lisÀtÀÀn suoraan tÀssÀ versiossa..  
          neg.w   d1              ; Lasketaan kohta, mistÀ bobbi-dataa
          mulu    #20,d1              ; aletaan blittaamaan.
          add.l   d1,a2
          add.l   d1,a3
          moveq   #0,d1           ; Y-koordinaatti on tietysti nolla..

Valmis  moveq    #0,d2

        lsl.l   #5,d1
        move.b  d0,d2
        lsr.l   #3,d0
        add.l   d1,d0
        ext.l   d0
        add.l   ScrollOffset,d0 ; ScrollOffset
        and.l   #$000f,d2
        mulu    #$1000,d2
        move.l  DrawScreen,a4
        add.l   d0,a4
        move.l  ClearScreen,a0
        add.l   d0,a0
        move.l  a0,(a6)+
        move.l  a4,(a6)+
        move.w  d6,(a6)+

        WaitForBlitter
        move.w  #0000,$062(a5)  ; BLTBMOD
        move.w  #0012,$060(a5)  ; BLTCMOD 
        move.w  #0000,$064(a5)  ; BLTAMOD
        move.w  #0012,$066(a5)  ; BLTDMOD

        move.w  d2,$042(a5)     ; BLTCON1
        or.w    #$0fce,d2       ; ynnÀtÀÀn minterm+use shift valueen
        move.w  d2,$040(a5)     ; BLTCON0
        move.l  a4,$048(a5)     ; BLTCPTR kohde
        move.l  a2,$04c(a5)     ; BLTBPTR bob-data
        move.l  a3,$050(a5)     ; BLTAPTR mask
        move.l  a4,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE
ExitBM
        rts

PyyhiMonstExplosion
        move.l  MExp_vanhasij,a6
        cmp.l   #0,(a6)
        beq.s   ExitPME

        WaitForBlitter
        move.w  #$9f0,$040(a5)  ; BLTCON0
        move.w  #$0000,$042(a5) ; BLTCON0
        move.w  #0012,$064(a5)  ; BLTAMOD
        move.w  #0012,$066(a5)  ; BLTDMOD

        move.l  (a6)+,$050(a5)  ; BLTAPTR
        move.l  (a6)+,$054(a5)  ; BLTDPTR kohde
        move.w  (a6)+,$058(a5)  ; BLTSIZE

ExitPME rts

PyyhiMonster
; PyyhitÀÀn ensin mahdollinen monsterin bullet
        move.l  MonstBVanhaSij,a4
        moveq   #3-1,d7

PML     cmp.l   #0,(a4)
        beq.s   NextMonstBullet

        WaitForBlitter
        move.w  #$9f0,$040(a5)  ; BLTCON0
        move.w  #0000,$042(a5)  ; BLTCON0
        move.w  #0028,$064(a5)  ; BLTAMOD
        move.w  #0028,$066(a5)  ; BLTDMOD
        move.l  (a4)+,$050(a5)  ; BLTAPTR
        move.l  (a4)+,$054(a5)  ; BLTDPTR
        move.w  (a4)+,$058(a5)  ; BLTSIZE
        dbf     d7,PML
        bra.s   PM
NextMonstBullet
        add.l   #10,a4
        dbf     d7,PML

PM      move.l  MonsterVanhaSij,a4
        cmp.l   #0,(a4)
        beq.s   ExitPM

        WaitForBlitter
        move.w  #$9f0,$040(a5)  ; BLTCON0
        move.w  #$000,$042(a5)  ; BLTCON0
        move.w  #0012,$064(a5)  ; BLTAMOD
        move.w  #0012,$066(a5)  ; BLTDMOD

        move.l  (a4)+,$050(a5)  ; BLTAPTR
        move.l  (a4)+,$054(a5)  ; BLTDPTR kohde
        move.w  (a4)+,$058(a5)  ; BLTSIZE
ExitPM  rts

;------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------
GameOver
            move.l      #Dummy,d0           ; Spritet pois pÀÀltÀ
            move.w      d0,s0_low
            swap        d0
            move.w      d0,s0_high

            move.w      d0,s1_low
            swap        d0
            move.w      d0,s1_high

            move.w      d0,s2_low
            swap        d0
            move.w      d0,s2_high

            move.b      #0,gameOver
            move.b      #0,letterstyped

            move.b   #1,level
            move.l   #Coolfield,coolfield
;           move.w   #0,Pisteet

            move.l   #0,$180(a5)

            bsr     pyyhi_bitmap

            move.l  bitmap,d1
            move.w  d1,low1
            swap     d1
            move.w   d1,high1
            swap     d1
            add.l    #32,d1
            move.w   d1,low2
            swap     d1
            move.w   d1,high2
            swap     d1
            add.l    #32,d1
            move.w   d1,low3
            swap     d1
            move.w   d1,high3
            swap     d1
            add.l    #32,d1
            move.w   d1,low4
            swap     d1
            move.w   d1,high4

            lea     gameover,a2
            move.l  bitmap,a1
            add.l    #14090,a1
            bsr     TulostaTeksti

            moveq    #5-1,d7
            lea      hiscoretable,a1
vertailu    move.w   4(a1),d1
            cmp.w    Pisteet,d1
            add.l    #6,a1
            blt.s    typeinname
            dbf     d7,vertailu

            bra.s    waitforjoybutton
typeinname

            move.l  bitmap,a1
            add.l   #1664,a1
            lea     usejoy,a2
            bsr     TulostaTeksti

            move.l  bitmap,a1
            add.l   #4864,a1
            lea     type,a2
            bsr     TulostaTeksti

            move.l   bitmap,a1
            add.l    #25738,a1
            move.b  #1,NPohjassa
            bsr     PrintLetter

gosil       bsr     JoystickForLetters
            bsr     WaitForBeam

            cmp.b   #3,letterstyped         
            beq.s   JumpToAlkuScreen

            btst    #6,$bfe001
            beq     CleanUp

            bra.s   gosil

;          bra.s    JumpToAlkuScreen

waitforjoybutton
            lea     pressjoy,a2
            move.l  bitmap,a1
            add.l   #29445,a1
            bsr     TulostaTeksti

loop        btst    #6,$bfe001
            beq     CleanUp

            bsr     WaitForBeam
            cmp.b   #1,NPohjassa
            bne.s   checkjoybutton
            move.b  #0,NPohjassa
            bra.s   loop

checkjoybutton
            btst    #7,$bfe001      ; Katsotaanko painetaanko joikkiksen nappia
            bne.s   loop
            move.b  #1,NPohjassa
            bra     JumpToAlkuScreen

;------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------
LoppuScreen
            move.l   #Dummy,d0
            move.w   d0,s0_low
            swap     d0
            move.w   d0,s0_high

            move.w   d0,s1_low
            swap     d0
            move.w   d0,s1_high

            move.w   d0,s2_low
            swap     d0
            move.w   d0,s2_high

            bsr      WaitForBeam
            bsr      pyyhi_bitmap

            move.l   bitmap,d1
            move.w   d1,low1
            swap     d1
            move.w   d1,high1
            swap     d1
            add.l    #32,d1
            move.w   d1,low2
            swap     d1
            move.w   d1,high2
            swap     d1
            add.l    #32,d1
            move.w   d1,low3
            swap     d1
            move.w   d1,high3
            swap     d1
            add.l    #32,d1
            move.w   d1,low4
            swap     d1
            move.w   d1,high4

            move.w  #0,$180(a5)

            lea     udidit,a2
            move.l  bitmap,a1
            add.l   #13060,a1
            bsr     TulostaTeksti

checkbut    btst    #6,$bfe001
            beq     CleanUp

            btst    #7,$bfe001      ; Katsotaanko painetaanko joikkiksen nappia
            bne.s   exitcbut
            cmp.b   #1,NPohjassa
            bne.s   eio
            bra.s   checkbut
eio         bra     GameOver
exitcbut    cmp.b   #1,NPohjassa
            bne.s   eiole
            move.b  #0,NPohjassa
eiole       bra.s   checkbut


;------------------------------------------------------------------------------
; Level-Screen. TÀmÀ tulostuu ennen alkavaa tasoa. TÀnne hypÀtÀÀn alustuksesta.
;------------------------------------------------------------------------------
LevelScreen
            move.l  #Dummy,d0
            move.w  d0,s0_low
            swap    d0
            move.w  d0,s0_high

            move.w  d0,s1_low
            swap    d0
            move.w  d0,s1_high

            move.w  d0,s2_low
            swap    d0
            move.w  d0,s2_high

            bsr     pyyhi_bitmap

            move.l  bitmap,d1
            move.w   d1,low1
            swap     d1
            move.w   d1,high1
            swap     d1
            add.l    #32,d1
            move.w   d1,low2
            swap     d1
            move.w   d1,high2
            swap     d1
            add.l    #32,d1
            move.w   d1,low3
            swap     d1
            move.w   d1,high3
            swap     d1
            add.l    #32,d1
            move.w   d1,low4
            swap     d1
            move.w   d1,high4

            moveq    #0,d0
            move.b   level,d0
            add.b    #'0',d0
    
            lea      LevelTXT,a2
            move.b   d0,7(a2)

            move.l   bitmap,a1
            add.l    #13067,a1
            bsr      TulostaTeksti

            move.l   #150,d7
Wait        bsr      WaitForBeam
            dbf      d7,Wait

            rts

;------------------------------------------------------------------------------
; Alkuscreen-rutiineita
;------------------------------------------------------------------------------
AlkuScreen

            move.w   #0,Pisteet

            bsr      pyyhi_bitmap

            move.l   bitmap,d1
            move.w   d1,low1
            swap     d1
            move.w   d1,high1
            swap     d1
            add.l    #32,d1
            move.w   d1,low2
            swap     d1
            move.w   d1,high2
            swap     d1
            add.l    #32,d1
            move.w   d1,low3
            swap     d1
            move.w   d1,high3
            swap     d1
            add.l    #32,d1
            move.w   d1,low4
            swap     d1
            move.w   d1,high4

            move.w   #$0,$180(a5)

            bsr      WaitForBeam

            lea      xwars,a2
            move.l   bitmap,a1
            add.l    #7,a1
            bsr      TulostaTeksti

            move.b   #1,small_font
            lea      press,a2
            move.l   bitmap,a1
            add.l    #30080,a1
            bsr      TulostaTeksti

            lea      leftmouse,a2
            move.l   bitmap,a1
            add.l    #31488,a1
            bsr      TulostaTeksti

            lea      codingby,a2
            move.l   bitmap,a1
            add.l    #2435,a1                    ; 19
            bsr      TulostaTeksti

            lea      musicby,a2
            move.l   bitmap,a1
            add.l    #3715,a1
            bsr      TulostaTeksti
            
            move.b   #0,small_font
            bsr      PrintHiScoreList

AlkuMP      btst     #6,$bfe001
            beq      CleanUp

            bsr      WaitForBeam
checkbutton
            btst     #7,$bfe001      ; Katsotaanko painetaanko joikkiksen nappia
            bne.s    exitcb
            cmp.b    #1,NPohjassa
            bne.s    eioo
            bra.s    AlkuMP
eioo        bra      JumpToAlustus
exitcb      cmp.b    #1,NPohjassa
            bne.s    eij
            move.b   #0,NPohjassa
eij         bra.s    AlkuMP

;------------------------------------------------------------------------------
; PyyhitÀÀn bitmap
;------------------------------------------------------------------------------
pyyhi_bitmap
            move.l   #4*2048-1,d7
            move.l   bitmap,a1
pyyhi       move.l   #0,(a1)+
            dbf      d7,pyyhi
            rts

;------------------------------------------------------------------------------
; Tulostetaan tekstiÀ kunnes törmÀtÀÀn nollaan
;------------------------------------------------------------------------------
TulostaTeksti
        lea         Fontti,a0

        moveq       #0,d0
        move.b      (a2)+,d0
        cmp.b       #0,d0
        beq.s       ExitPrintLetter
        sub.b       #'0',d0
        lsl.l       #6,d0
        add.l       d0,a0

        cmp.b       #1,small_font
        beq.s       printsmallletter

        moveq       #64-1,d7                    ; 64 - 1
lettersil
        move.b      (a0)+,(a1)
        add.l       #32,a1                  ; 16
        dbf         d7,lettersil
        addq.l      #1,a1
        sub.l       #2048,a1                    ; 1024
        bra.s       TulostaTeksti
    
ExitPrintLetter
        rts

printsmallletter
        move.l      #4*8-1,d7
smalllettersil
        move.b      (a0)+,(a1)
        addq.l      #1,a0
        add.l       #32,a1
        dbf         d7,smalllettersil
        sub.l       #1024,a1
        addq.l      #1,a1
        bra.s       TulostaTeksti

;------------------------------------------------------------------------------
; Tulostetaan yksi merkki fontista.
; A0:ssa osoitin fonttiin. A1:ssÀ osoitin kohteeseen. 
;------------------------------------------------------------------------------
PrintLetter
       lea          Fontti+17*64,a0
       add.l        pt_Font,a0

        moveq       #64-1,d7
letsil
        move.b      (a0)+,(a1)
        add.l       #32,a1                  ; 16
        dbf         d7,letsil
        sub.l       #2048,a1                    ; 1024

; Kirjoitetaan merkki myös merkki-bufferiin

merkkibufferiin

        lea         Nimi,a2
        moveq       #0,d0
        move.b      letterstyped,d0
        add.l       d0,a2
        move.b      currentchar,(a2)

        rts

;------------------------------------------------------------------------------
; Tulostetaan HiScore-lista
;------------------------------------------------------------------------------
PrintHiScoreList

        move.l      bitmap,a1
        add.l       #10250,a1

        lea         hiscoretable,a4
        moveq       #5-1,d6
hiscoresil
        move.l      (a4)+,a2
        bsr         TulostaTeksti
        moveq       #0,d0
        move.w      (a4)+,d0
        addq.l      #1,a1                   ; 1 vÀlilyönti nimien jÀlkeen
        lea         Luku,a2
        bsr         ConvertToASCII
        lea         Luku,a2
        bsr         TulostaTeksti
        sub.l       #9,a1
        add.l       #2176,a1                ; 1280
        dbf         d6,hiscoresil       
        rts

;------------------------------------------------------------------------------
JoystickForLetters
; A0:ssa on fontin osoite
;------------------------------------------------------------------------------
        move.w      $c(a5),d6       ; Joikkis rekisteri

          cmp.b     #0,viive
          beq.s     oikealle
          subq.b    #1,viive
          bra.s     JNappi
oikealle
        btst        #1,d6           ; Ohjataanko oikealle?
        beq.s       vasemmalle      ; Jos ei niin ...

        move.b      #10,viive
          
        add.l       #64,pt_Font
        addq.b      #1,currentchar
        cmp.b       #'[',currentchar
        blt.s       pri
        move.b      #'Z',currentchar
        sub.l       #64,pt_Font

pri     bsr         PrintLetter
        bra.s       JNappi

vasemmalle
        btst        #9,d6            ; Ohjataanko vasemalle?
        beq.s       JNappi           ; Jos ei niin ...

        move.b      #10,viive

        sub.l       #64,pt_Font
        subq.b      #1,currentchar
        cmp.b       #'@',currentchar
        bgt.s       prin
        move.b      #'A',currentchar
        add.l       #64,pt_Font

prin    bsr      PrintLetter

JNappi  cmp.b   #0,Laskuri
        beq.s   TestN
        subq.b  #1,Laskuri
        rts
TestN   btst    #7,$bfe001      ; Katsotaanko painetaanko joikkiksen nappia
        bne.s   ExtJoystick    ;
        cmp.b   #1,NPohjassa
        bne.s   EiO
        rts
EiO     move.b  #1,NPohjassa
        move.b  #Frames,Laskuri
        bsr      PrintLetter
        addq.l   #1,a1
        addq.b   #1,letterstyped
        cmp.b    #3,letterstyped    ; Nollas on ensimmÀinen kirjain
        bne.s    ei

        bsr      NewEntry
;         bsr        PrintHiScoreList
        rts

ExtJoystick
        cmp.b   #1,NPohjassa
        bne.s   ei
        move.b  #0,NPohjassa
ei      rts

NewEntry
        moveq    #5-1,d7
        lea     hiscoretable,a1
nesil   moveq   #0,d0
        move.w  4(a1),d0
        cmp.w   Pisteet,d0          ; Jos tietuessa oleva arvo on pienempi, on
        blt.s   yeah                    ; Pisteet suurempi...
        addq.l  #6,a1
        dbf     d7,nesil
        rts
yeah    lea     hiscoretable,a4
        subq.l  #1,d7
        cmp.l   #-1,d7              ; Jos kyseessÀ alimmainen, niin vain
        beq.s   JustPutNewEntry ; laitetaan entry...
        move.l  d7,d6
        mulu    #6,d6

; SiirretÀÀn listaa yhdellÀ pykÀlÀllÀ alaspÀin

;       moveq       #4-1,d7
;       add.l       d6,a4
        add.l   #3*6,a4
sil moveq    #4-1,d5
        move.l  (a4),a1
        move.l  6(a4),a2
        move.l  (a2),a2
csil    move.b   (a1)+,(a2)+
        dbf     d5,csil

        move.w  4(a4),10(a4)
        subq.l  #6,a4
        dbf     d7,sil
        addq.l  #6,a4

        move.l  a4,a1
        move.l  (a4),a4
        lea     Nimi,a3
        moveq   #4-1,d7
nimisil
        move.b  (a3)+,(a4)+
        dbf     d7,nimisil

        move.w  Pisteet,4(a1)
        rts

JustPutNewEntry
        add.l   #4*6,a4

        move.l  a4,a1
        move.l  (a4),a4
        lea     Nimi,a3
        moveq   #4-1,d7
anothernimisil
        move.b  (a3)+,(a4)+
        dbf     d7,anothernimisil
        move.w  Pisteet,4(a1)
        rts

;------------------------------------------------------------------------------
; Muutetaan kokonaisluku ASCII:ksi
;------------------------------------------------------------------------------
ConvertToASCII
; Muutettava luku D0:aan, tulos tulee A2:een.

      moveq    #0,d2

; Lasketaan digittien mÀÀrÀ
        move.l   d0,d1              ; Lasketaan digittien mÀÀrÀ
nrdigits
        addq.l   #1,d2
        divu.w   #10,d1
        and.l    #$0000ffff,d1
        cmp.w    #0,d1
        bgt.s    nrdigits
        move.l   d2,d7              ; Digittien mÀÀrÀ-1 D7:ÀÀn

        moveq    #5,d5                  ; Hoidellaan eteen tarpeellinen
        sub.l    d7,d5                  ; mÀÀrÀ nollia -->
        subq.l   #1,d5
        cmp.l    #0,d5
        blt.s    skipnolla
zerosil
        move.b    #'0',(a2)+
        dbf       d5,zerosil
;        add.l    d5,a2                 ; Nyt numerot alkavat oikeasta kohdasta

skipnolla

        subq.l   #1,d7                  ; DBF-kÀskyn vuoksi

digitsil
        move.l   d0,d1              ; Working copy of D0

        moveq    #1,d3                  ; MÀÀritetÀÀn 10 potensiin
        move.l   d7,d2                  ; digitin jÀrjestysnumero - 1
posil   subq.l   #1,d2              ;
        cmp.l    #-1,d2                 ;
        ble.s    Jaa                ;
        mulu.w   #10,d3             ;
        bra.s    posil              ;

Jaa     move.l   d3,d2              ; Jaetaan muutettava luku
        divu.w   d2,d1              ; yllÀ mÀÀritetyllÀ luvulla
        and.l    #$0000ffff,d1      ; Nollataan jakojÀÀnnös
        divu.w   #10,d1             ; Jaetaan vielÀ 10:llÀ
        swap     d1                 ; Otetaan jakojÀÀnnös ja nollataan
        and.l    #$0000ffff,d1      ; muu osa luvusta; jÀljellÀ on
        add.b    #'0',d1            ; on haettu digit!
        move.b   d1,(a2)+           ; ja kirjoitetaan digit talteen
        move.b   #0,(a2)
        dbf      d7,digitsil
        rts

;------------------------------------------------------------------------------
FillTheScreen:
; Fillataan 16*17 suuruinen alue blo(c)keisssa(16*16,what else?)
; (..ja tietysti kaikkissa (3) screeneissÀ!!)

        move.l  #(256+16)*4*32,d1
        move.l  BitMap1,a1
        move.l  BitMap2,a2
        move.l  ClearScreen,a3
        add.l   d1,a1
        add.l   d1,a2
        add.l   d1,a3
        move.l  coolfield,a6
;        lea     Coolfield,a6
        move.w  #16/16+(16*4*64),d6
        WaitForBlitter
        move.w  #$09f0,$040(a5) ; BLTCON0
        move.w  #$0000,$042(a5) ; BLTCON0
        move.w  #0038,$064(a5)  ; BLTAMOD
        move.w  #0030,$066(a5)  ; BLTDMOD

        moveq   #17-1,d7
YSil:   moveq   #16-1,d5
XSil:   WaitForBlitter
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a1,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE 16*(16*4)
        addq.l  #2,a1

        WaitForBlitter
        move.l  (a6),$050(a5)   ; BLTAPTR source
        move.l  a2,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE 16*(16*4)
        addq.l  #2,a2

        WaitForBlitter
        move.l  (a6)+,$050(a5)  ; BLTAPTR source
        move.l  a3,$054(a5)     ; BLTDPTR kohde
        move.w  d6,$058(a5)     ; BLTSIZE 16*(16*4)
        addq.l  #2,a3
        dbf     d5,XSil
        add.l   #(4*32*16)-32,a1
        add.l   #(4*32*16)-32,a2
        add.l   #(4*32*16)-32,a3
        dbf     d7,YSil
        rts

WaitForBeam 
        cmp.b   #$ff,$006(a5)
        bne.s   WaitForBeam
WFBeam 
        cmp.b   #$2c,$006(a5)
        bne.s   WFBeam
        rts

RMB     btst    #10,$016(a5)
        beq.s    changecol
        rts
changecol
         move.w  #$333,$180(a5)
         rts

;------------------------------------------------------------------------------
; Asetetaan tarvittavt alkuarvot, jotta uusi peli voi alkaa
;------------------------------------------------------------------------------
Alustus
        bsr     LevelScreen     ; Tulostetaan tason numero

        move.l  #(256+16+16)*4*32,ScrollOffset
;       move.w  #0,Pisteet
        move.l  #256,LineN      ; Blo(c)kin y-paikka
        move.l  #0,Bl_paikka   ; Blo(c)kin x-paikka
        move.l  #0,pt_toCoolF
        move.l  #0,pt_toClear
        move.b  #0,Frame            ; Scrollaukseen liittyvÀ
        move.b  #0,LameFrame
; 
        move.b   #16,energia

        lea     Explosions,a0
        lea     ExpVanhaSij0,a1
        lea     ExpVanhaSij1,a4

        moveq   #20-1,d7
Exps    move.w  #0,(a0)+        ; KehissÀ
        move.w  #0,(a0)+        ; x
        move.w  #0,(a0)+        ; y
        move.w  #4,(a0)+        ; viive
        move.l  #0,(a0)+        ; Pointteri grafiikkadataan

        move.l  #0,(a1)+        ; ClearScreen-osoite
        move.l  #0,(a1)+        ; VanhaSijainti-osoite
        move.w  #0,(a1)+        ; BLTSIZE

        move.l  #0,(a4)+
        move.l  #0,(a4)+
        move.w  #0,(a4)+

        dbf     d7,Exps     

        move.l  #0,Exp_PT
        move.l  #0,VanhaExpSij
        move.l  #Explosions,Exp_PT

;
        lea     MExp_VanhaSij0,a1
        lea     MExp_VanhaSij1,a4
        move.l  #0,(a1)+        ; ClearScreen-sijainti
        move.l  #0,(a1)+        ; VanhaSijainti
        move.w  #0,(a1)+        ; BLTSIZE

        move.l  #0,(a4)+        ; ClearScreen-sijainti
        move.l  #0,(a4)+        ; VanhaSijainti
        move.w  #0,(a4)+        ; BLTSIZE

        move.l  #0,MExp_vanhasij

        moveq   #3-1,d7
        lea     MonstBVanhaSij0,a0
        lea     MonstBVanhaSij1,a1

MBalustus
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.w  #0,(a0)+

        move.l  #0,(a1)+
        move.l  #0,(a1)+
        move.w  #0,(a1)+
        dbf     d7,MBalustus

; Coordbob-stuff

        lea     VanhaSij1,a0
        lea     VanhaSij2,a1
        lea     PTRsAndONOFF,a4
        moveq   #max_bobs-1,d7
CoordBobAlustus
        move.l  #0,(a0)+        ; ClearScreen
        move.l  #0,(a0)+        ; VanhaSijainti
        move.w  #0,(a0)+        ; BLTSIZE
        move.l  #0,(a1)+        ; ClearScreen
        move.l  #0,(a1)+        ; VanhaSijainti
        move.w  #0,(a1)+        ; BLTSIZE

        move.l  #0,(a4)+        ; Pointteri koordinaatteihin
        move.w  #0,(a4)+        ; ON/OFF
        move.w  #0,(a4)+        ; KestÀvyys
        move.l  #0,(a4)+        ; Pointteri bob-dataan
        move.l  #0,(a4)+        ; Pointteri mask-dataan
        dbf     d7,CoordBobAlustus

        move.b  #0,DoLastCoordBobFrames
        move.b  #0,CoordBobsRunning
        move.b  #0,nr_of_bobs
        move.b  #0,AmEnemies

        move.l  #0,VanhaSij

; Enemylaakit coordbobeille

        lea     VanhaESij1,a0
        lea     VanhaESij2,a1
        lea     EnemyLaakit,a2
        moveq   #AmountEBullets,d7

enbullet
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.l  #0,(a1)+
        move.l  #0,(a1)+

        move.w  #-1,(a2)+   ; x HUOM!!!
        move.w  #0,(a2)+        ; y
        
        dbf     d7,enbullet

; Omat laakit

        lea     Laakit,a0
        moveq   #AmountBullets,d7
omatlaakitalustus
        move.w  #0,(a0)+        ; KehissÀ
        move.w  #0,(a0)+        ; x
        move.w  #0,(a0)+        ; y
        dbf     d7,omatlaakitalustus

        move.l  #0,LaakiPT
        move.l   #Laakit,LaakiPT

; Unittien alkuarvot kuntoon

        lea     Units,a0
        lea     UnitsVanhaSij0,a1
        lea     UnitsVanhaSij1,a2
        lea     UnitsVBSij0,a3
        lea     UnitsVBSij1,a4
        moveq       #5-1,d7
UnitInit
        move.w  #0,(a0)+        ; LiikkeellÀ
        move.l  #0,(a0)+        ; UnitX
        move.l  #0,(a0)+        ; UnitY
        move.w  #0,(a0)+        ; Laaki liikkeellÀ
        move.l  #0,(a0)+        ; BulletX
        move.l  #0,(a0)+    ; BulletY
        move.l  #0,(a0)+        ; Bullet add X
        move.l  #0,(a0)+        ; Bullet add Y
        move.l  #0,(a0)+        ; UnitBob
        move.l  #0,(a0)+        ; UnitBobMask
        move.l  #0,(a0)+        ; ExplodedUnit
        move.l  #0,(a0)+        ; ExplodedUnitMask
        move.w  #0,(a0)+        ; KestÀvyys
        move.w  #0,(a0)+        ; Liikkuvako

        move.l  #0,(a1)+
        move.l  #0,(a1)+
        move.w  #0,(a1)+
        move.l  #0,(a2)+
        move.l  #0,(a2)+
        move.w  #0,(a2)+
        move.l  #0,(a3)+
        move.l  #0,(a3)+
        move.w  #0,(a3)+
        move.l  #0,(a4)+
        move.l  #0,(a4)+
        move.w  #0,(a4)+

        dbf     d7,UnitInit

; Asteroidien alkuarvot kuntoon

        lea     Asteroids,a0
        moveq       #28-1,d7
AsterInit
        move.w  #0,(a0)+        ; LiikkeellÀ merkki
        move.w  #0,(a0)+        ; X
        move.w  #0,(a0)+        ; Y
        move.w  #0,(a0)+        ; Speed
        move.w  #0,(a0)+        ; KestÀvyys
        dbf     d7,AsterInit
        moveq       #28-1,d7
        lea     VanhaAstSij0,a0
        lea     VanhaAstSij1,a1
AsterVSijInit
        move.l  #0,(a0)+        ; ClearScreen
        move.l  #0,(a0)+        ; VanhaSijainti
        move.w  #0,(a0)+        ; BLTSIZE
        move.l  #0,(a1)+
        move.l  #0,(a1)+
        move.w  #0,(a1)+
        dbf     d7,AsterVSijInit

        move.b  #0,Asteroids_on_screen
        move.b  #0,AsteroidsRunning
        move.b  #3,LastAsteroidFrames

; Monsterin alkuarvot kuntoon

        move.b  #0,MExpFinished
        move.b  #0,Monster_destroyed
        move.b  #0,MonsterKehissa

        lea     Monster,a0
        move.w  #32,(a0)+       ; X-koordinaatti
        move.w  #-64,(a0)+      ; Y
        move.w  #60,(a0)+       ; KestÀvyys
        move.w  #0,(a0)+            ; Laaki liikkeellÀ
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.w  #0,(a0)+
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.w  #0,(a0)+
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.l  #0,(a0)+
        move.l  #0,(a0)+

        cmp.b    #2,level
        beq.s    level2monsterbob

        cmp.b    #3,level
        beq.s    level3monsterbob

        move.l   #MonsterBob,(a0)+
        move.l   #MonsterMask,(a0)+
        bra.s    monsterjatkuu

level2monsterbob
        move.l   #Monster2Bob,(a0)+
        move.l   #MonsterMask,(a0)+
        bra.s    monsterjatkuu

level3monsterbob
        move.l  #Monster3Bob,(a0)+
        move.l  #MonsterMask,(a0)+

monsterjatkuu
        move.w  #1,DX

        lea     Monster_explosion,a0
        move.w  #0,(a0)+
        move.w  #0,(a0)+
        move.w  #0,(a0)+
        move.w  #4,(a0)+        ; Viive
        move.l  #0,(a0)+

        move.b  #0,kierros

; Taso 1 aloitustasoksi

;       move.b  #1,level
;       move.l   #Coolfield,coolfield

        move.l  #SPR0,d0
        move.w  d0,s0_low
        swap    d0
        move.w  d0,s0_high

        move.l  #SPR1,d0
        move.w  d0,s1_low
        swap    d0
        move.w  d0,s1_high

        move.l  #SPR2,d0
        move.w  d0,s2_low
        swap      d0
        move.w  d0,s2_high

;

        move.l  #0,pt_Font
        move.b  #'A',currentchar

        move.w  #128,x          ; Pelaajan koordinaatit
        move.w  #235,y

        rts


;------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------
AlkuRoskat:
        move.w  #5-1,d7         ; Spritejen mÀÀrÀ (mitkÀ "nollataan")
        move.l  #Dummy,d0       ; "Nollataan" kÀyttÀmÀttÀmÀt spritet
        lea     empty,a0
SprNl:  move.w  d0,2(a0)
        swap    d0
        move.w  d0,6(a0)
        addq.l  #8,a0
        dbf     d7,SprNl

;        lea     PTRsAndONOFF,a0 ; Lasketaan Enemyille koord. PTR:t
;         moveq   #0,d7
;        move.b  nr_of_bobs,d7
;         subq.l     #1,d7

;        move.l  #0,d0
;AlArv:  move.l  d0,(a0)+
;        move.w  #1,(a0)+        ; "Enemy kehissÀ" -merkki
;        add.l   #32,d0          ; 
;        dbf     d7,AlArv

        lea     EnemyLaakit,a0
        move.l  #AmountEBullets,d7
ELSil:  move.w  #-1,(a0)+
        move.w  #0,(a0)+
        dbf     d7,ELSil

        lea     Laakit,a0
        move.l  #AmountBullets,d7
SilL:   move.w  #0,(a0)+
        move.w  #0,(a0)+
        move.w  #0,(a0)+
        dbf     d7,SilL

        lea     VanhaESij1,a0
        move.l  #AmountEBullets,d7
VES1Sil move.l  #0,(a0)+
        move.l  #0,(a0)+
        dbf     d7,VES1Sil

        lea     VanhaESij2,a0
        move.l  #AmountEBullets,d7
VES2Sil move.l  #0,(a0)+
        move.l  #0,(a0)+
        dbf     d7,VES2Sil

;        lea     VanhaSij1,a0
;         moveq   #0,d7
;        move.b  nr_of_bobs,d7
;         subq.l     #1,d7
;ZIL:    move.l  #0,(a0)+
;        move.l  #0,(a0)+
;        move.w  #0,(a0)+
;        dbf     d7,ZIL

;        lea     VanhaSij2,a0
;         moveq  #0,d7
;        move.b  nr_of_bobs,d7
;         subq.l     #1,d7
;ZIL2:   move.l  #0,(a0)+
;        move.l  #0,(a0)+
;        move.w  #0,(a0)+
;        dbf     d7,ZIL2

        move.l  #SPR0,d0
        move.w  d0,s0_low
        swap    d0
        move.w  d0,s0_high

        move.l  #SPR1,d0
        move.w  d0,s1_low
        swap    d0
        move.w  d0,s1_high

        move.l  #SPR2,d0
        move.w   d0,s2_low
        swap    d0
        move.w  d0,s2_high

;        lea     Blocks+2560+2,a0               ; Blockien loppu + skip 1 vÀri
        move.l   #Blocks+2560+2,a0
;        lea     Colours+2,a1
        move.l   #Colours+2,a1
        moveq   #15-1,d7
CSil    move.w  (a0)+,(a1)                      ; Asetetaan vÀrit
        addq.l  #4,a1
        dbf     d7,CSil

;         lea        Monster,a0
;         move.w  #60,4(a0)         ; Monsterin kestÀvyys

        move.b  #1,level
        move.l  #Coolfield,coolfield
        rts

;------------------------------------------------------------------------------
; Musiikkikeskeytys
;------------------------------------------------------------------------------
Keskeytysrutiini
        bsr mt_music
        rts

;********************************************
;* ----- Protracker V1.1B Playroutine ----- *
;* Lars "Zap" Hamre/Amiga Freelancers 1991  *
;* Bekkeliveien 10, N-2010 STRØMMEN, Norway *
;********************************************

; CIA Version 1:
; Call SetCIAInt to install the interrupt server. Then call mt_init
; to initialize the song. Playback starts when the mt_enable flag
; is set to a nonzero value. To end the song and turn off all voices,
; call mt_end. At last, call ResetCIAInt to remove the interrupt.

; This playroutine is not very fast, optimized or well commented,
; but all the new commands in PT1.1 should work.
; If it's not good enough, you'll have to change it yourself.
; We'll try to write a faster routine soon...

; Changes from V1.0C playroutine:
; - ViBRAto depth changed to be compatible with Noisetracker 2.0.
;   You'll have to double all vib. depths on old PT modules.
; - Funk Repeat changed to Invert Loop.
; - Period set back earlier when stopping an effect.

; You can use this routine to play a module. Just remove the semicolons.
; Exit by pressing both mousebuttons.
;
;main   BSR.S   SetCIAInt
;   BSR mt_init
;   ST  mt_Enable
;   MOVE.L  4.W,A6
;   LEA DOSname(PC),A1
;   MOVEQ   #0,D0
;   JSR LVOOpenLiBRAry(A6)
;   TST.L   D0
;   BEQ.S   theend
;   MOVE.L  D0,A6
;wloop  MOVEQ   #10,D1
;   JSR LVODelay(A6)
;   BTST    #6,$BFE001
;   BNE.S   wloop
;   BTST    #2,$DFF016
;   BNE.S   wloop
;   MOVE.L  A6,A1
;   MOVE.L  4.W,A6
;   JSR LVOCloseLiBRAry(A6)
;theend BSR mt_end
;   BSR ResetCIAInt
;   RTS
;
;DOSname    dc.b "dos.liBRAry",0

;---- CIA Interrupt ----

AddICRVector    =   -6
RemICRVector    =  -12
LVOOpenResource = -498
LVOOpenLiBRAry  = -552
LVOCloseLiBRAry = -414
LVODelay    = -198

ciatalo = $400
ciatahi = $500
ciatblo = $600
ciatbhi = $700
ciacra  = $E00
ciacrb  = $F00

SetCIAInt
    MOVEQ   #2,D6
    LEA $BFD000,A5
    MOVE.B  #'b',CIAAname+3
SetCIALoop
    MOVEQ   #0,D0
    LEA CIAAname(PC),A1
    MOVE.L  4.W,A6
    JSR LVOOpenResource(A6)
    MOVE.L  D0,CIAAbase
    BEQ mt_Return

    LEA GfxName(PC),A1
    MOVEQ   #0,D0
    JSR LVOOpenLiBRAry(A6)
    TST.L   D0
    BEQ ResetCIAInt
    MOVE.L  D0,A1
    MOVE.W  206(A1),D0  ; DisplayFlags
    BTST    #2,D0       ; PAL?
    BEQ.S   WasNTSC
    MOVE.L  #1773447,D7 ; PAL
    BRA.S   sciask
WasNTSC MOVE.L  #1789773,D7 ; NTSC
sciask  MOVE.L  D7,TimerValue
    DIVU    #125,D7 ; Default to normal 50 Hz timer
    JSR CloseLiBRAry(A6)

    MOVE.L  CIAAbase(PC),A6
    CMP.W   #2,D6
    BEQ.S   TryTimerA
TryTimerB
    LEA MusicIntServer(PC),A1
    MOVEQ   #1,D0   ; Bit 1: Timer B
    JSR AddICRVector(A6)
    MOVE.L  #1,TimerFlag
    TST.L   D0
    BNE.S   CIAError
    MOVE.L  A5,CIAAaddr
    MOVE.B  D7,ciatblo(A5)
    LSR.W   #8,D7
    MOVE.B  D7,ciatbhi(A5)
    BSET    #0,ciacrb(A5)
    RTS

TryTimerA
    LEA MusicIntServer(PC),A1
    MOVEQ   #0,D0   ; Bit 0: Timer A
    JSR AddICRVector(A6)
    CLR.L   TimerFlag
    TST.L   D0
    BNE.S   CIAError
    MOVE.L  A5,CIAAaddr
    MOVE.B  D7,ciatalo(A5)
    LSR.W   #8,D7
    MOVE.B  D7,ciatahi(A5)
    BSET    #0,ciacra(A5)
    RTS

CIAError
    MOVE.B  #'a',CIAAname+3
    LEA $BFE001,A5
    SUBQ.W  #1,D6
    BNE SetCIALoop
    CLR.L   CIAAbase
    RTS

ResetCIAInt
    MOVE.L  CIAAbase(PC),D0
    BEQ mt_Return
    CLR.L   CIAAbase
    MOVE.L  D0,A6
    MOVE.L  CIAAaddr(PC),A5
    TST.L   TimerFlag
    BEQ.S   ResTimerA

    BCLR    #0,ciacrb(A5)
    MOVEQ   #1,D0
    BRA.S   RemInt

ResTimerA
    BCLR    #0,ciacra(A5)
    MOVEQ   #0,D0
RemInt  LEA MusicIntServer(PC),A1
    MOVEQ   #0,d0
    JSR RemICRVector(A6)
    RTS

;---- Tempo ----

SetTempo
    MOVE.L  CIAAbase(PC),D2
    BEQ mt_Return
    CMP.W   #32,D0
    BHS.S   setemsk
    MOVEQ   #32,D0
setemsk MOVE.W  D0,RealTempo
    MOVE.L  TimerValue(PC),D2
    DIVU    D0,D2
    MOVE.L  CIAAaddr(PC),A4
    MOVE.L  TimerFlag(PC),D0
    BEQ.S   SetTemA
    MOVE.B  D2,ciatblo(A4)
    LSR.W   #8,D2
    MOVE.B  D2,ciatbhi(A4)
    RTS

SetTemA MOVE.B  D2,ciatalo(A4)
    LSR.W   #8,D2
    MOVE.B  D2,ciatahi(A4)
    RTS

RealTempo   dc.w 125
CIAAaddr    dc.l 0
CIAAname    dc.b "ciaa.resource",0
CIAAbase    dc.l 0
TimerFlag   dc.l 0
TimerValue  dc.l 0
GfxName     dc.b "graphics.liBRAry",0,0

MusicIntServer
    dc.l 0,0
    dc.b 2,5 ; type, priority
    dc.l musintname
    dc.l 0,mt_music

musintname  dc.b "Protracker MusicInt",0

;---- Playroutine ----

n_note      EQU 0  ; W
n_cmd       EQU 2  ; W
n_cmdlo     EQU 3  ; B
n_start     EQU 4  ; L
n_length    EQU 8  ; W
n_loopstart EQU 10 ; L
n_replen    EQU 14 ; W
n_period    EQU 16 ; W
n_finetune  EQU 18 ; B
n_volume    EQU 19 ; B
n_dmabit    EQU 20 ; W
n_toneportdirec EQU 22 ; B
n_toneportspeed EQU 23 ; B
n_wantedperiod  EQU 24 ; W
n_viBRAtocmd    EQU 26 ; B
n_viBRAtopos    EQU 27 ; B
n_tremolocmd    EQU 28 ; B
n_tremolopos    EQU 29 ; B
n_wavecontrol   EQU 30 ; B
n_glissfunk EQU 31 ; B
n_sampleoffset  EQU 32 ; B
n_pattpos   EQU 33 ; B
n_loopcount EQU 34 ; B
n_funkoffset    EQU 35 ; B
n_wavestart EQU 36 ; L
n_reallength    EQU 40 ; W

mt_init ;LEA    mt_data,A0
    MOVE.L  A0,mt_SongDataPtr
    MOVE.L  A0,A1
    LEA 952(A1),A1
    MOVEQ   #127,D0
    MOVEQ   #0,D1
    MOVEQ   #0,D2
mtloop  MOVE.B  (A1)+,D1
    CMP.B   D2,D1
    BCS.S   mtloop2
    MOVE.L  D1,D2
mtloop2 DBRA    D0,mtloop
    ADDQ.B  #1,D2

    LEA mt_SampleStarts(PC),A1
    ASL.L   #8,D2
    ASL.L   #2,D2
    ADD.L   #1084,D2
    ADD.L   A0,D2
    MOVE.L  D2,A2
    MOVEQ   #30,D0
mtloop3 CLR.L   (A2)
    MOVE.L  A2,(A1)+
    MOVEQ   #0,D1
    MOVE.W  42(A0),D1
    ASL.L   #1,D1
    ADD.L   D1,A2
    ADD.L   #30,A0
    DBRA    D0,mtloop3

    OR.B    #2,$BFE001
    MOVE.B  #6,mt_speed
    CLR.B   mt_counter
    CLR.B   mt_SongPos
    CLR.W   mt_PatternPos
mt_end  SF  mt_Enable
    LEA $DFF000,A0
    CLR.W   $A8(A0)
    CLR.W   $B8(A0)
    CLR.W   $C8(A0)
    CLR.W   $D8(A0)
    MOVE.W  #$F,$DFF096
    RTS

mt_music
    MOVEM.L D0-D4/A0-A6,-(SP)
    TST.B   mt_Enable
    BEQ mt_exit
    ADDQ.B  #1,mt_counter
    MOVE.B  mt_counter(PC),D0
    CMP.B   mt_speed(PC),D0
    BLO.S   mt_NoNewNote
    CLR.B   mt_counter
    TST.B   mt_PattDelTime2
    BEQ.S   mt_GetNewNote
    BSR.S   mt_NoNewAllChannels
    BRA mt_dskip

mt_NoNewNote
    BSR.S   mt_NoNewAllChannels
    BRA mt_NoNewPosYet

mt_NoNewAllChannels
    LEA $DFF0A0,A5
    LEA mt_chan1temp(PC),A6
    BSR mt_CheckEfx
    LEA $DFF0B0,A5
    LEA mt_chan2temp(PC),A6
    BSR mt_CheckEfx
    LEA $DFF0C0,A5
    LEA mt_chan3temp(PC),A6
    BSR mt_CheckEfx
    LEA $DFF0D0,A5
    LEA mt_chan4temp(PC),A6
    BRA mt_CheckEfx

mt_GetNewNote
    MOVE.L  mt_SongDataPtr(PC),A0
    LEA 12(A0),A3
    LEA 952(A0),A2  ;pattpo
    LEA 1084(A0),A0 ;patterndata
    MOVEQ   #0,D0
    MOVEQ   #0,D1
    MOVE.B  mt_SongPos(PC),D0
    MOVE.B  (A2,D0.W),D1
    ASL.L   #8,D1
    ASL.L   #2,D1
    ADD.W   mt_PatternPos(PC),D1
    CLR.W   mt_DMACONtemp

    LEA $DFF0A0,A5
    LEA mt_chan1temp(PC),A6
    BSR.S   mt_PlayVoice
    LEA $DFF0B0,A5
    LEA mt_chan2temp(PC),A6
    BSR.S   mt_PlayVoice
    LEA $DFF0C0,A5
    LEA mt_chan3temp(PC),A6
    BSR.S   mt_PlayVoice
    LEA $DFF0D0,A5
    LEA mt_chan4temp(PC),A6
    BSR.S   mt_PlayVoice
    BRA mt_SetDMA

mt_PlayVoice
    TST.L   (A6)
    BNE.S   mt_plvskip
    BSR mt_PerNop
mt_plvskip
    MOVE.L  (A0,D1.L),(A6)
    ADDQ.L  #4,D1
    MOVEQ   #0,D2
    MOVE.B  n_cmd(A6),D2
    AND.B   #$F0,D2
    LSR.B   #4,D2
    MOVE.B  (A6),D0
    AND.B   #$F0,D0
    OR.B    D0,D2
    TST.B   D2
    BEQ mt_SetRegs
    MOVEQ   #0,D3
    LEA mt_SampleStarts(PC),A1
    MOVE    D2,D4
    SUBQ.L  #1,D2
    ASL.L   #2,D2
    MULU    #30,D4
    MOVE.L  (A1,D2.L),n_start(A6)
    MOVE.W  (A3,D4.L),n_length(A6)
    MOVE.W  (A3,D4.L),n_reallength(A6)
    MOVE.B  2(A3,D4.L),n_finetune(A6)
    MOVE.B  3(A3,D4.L),n_volume(A6)
    MOVE.W  4(A3,D4.L),D3 ; Get repeat
    TST.W   D3
    BEQ.S   mt_NoLoop
    MOVE.L  n_start(A6),D2  ; Get start
    ASL.W   #1,D3
    ADD.L   D3,D2       ; Add repeat
    MOVE.L  D2,n_loopstart(A6)
    MOVE.L  D2,n_wavestart(A6)
    MOVE.W  4(A3,D4.L),D0   ; Get repeat
    ADD.W   6(A3,D4.L),D0   ; Add replen
    MOVE.W  D0,n_length(A6)
    MOVE.W  6(A3,D4.L),n_replen(A6) ; Save replen
    MOVEQ   #0,D0
    MOVE.B  n_volume(A6),D0
    MOVE.W  D0,8(A5)    ; Set volume
    BRA.S   mt_SetRegs

mt_NoLoop
    MOVE.L  n_start(A6),D2
    ADD.L   D3,D2
    MOVE.L  D2,n_loopstart(A6)
    MOVE.L  D2,n_wavestart(A6)
    MOVE.W  6(A3,D4.L),n_replen(A6) ; Save replen
    MOVEQ   #0,D0
    MOVE.B  n_volume(A6),D0
    MOVE.W  D0,8(A5)    ; Set volume
mt_SetRegs
    MOVE.W  (A6),D0
    AND.W   #$0FFF,D0
    BEQ mt_CheckMoreEfx ; If no note
    MOVE.W  2(A6),D0
    AND.W   #$0FF0,D0
    CMP.W   #$0E50,D0
    BEQ.S   mt_DoSetFineTune
    MOVE.B  2(A6),D0
    AND.B   #$0F,D0
    CMP.B   #3,D0   ; TonePortamento
    BEQ.S   mt_ChkTonePorta
    CMP.B   #5,D0
    BEQ.S   mt_ChkTonePorta
    CMP.B   #9,D0   ; Sample Offset
    BNE.S   mt_SetPeriod
    BSR mt_CheckMoreEfx
    BRA.S   mt_SetPeriod

mt_DoSetFineTune
    BSR mt_SetFineTune
    BRA.S   mt_SetPeriod

mt_ChkTonePorta
    BSR mt_SetTonePorta
    BRA mt_CheckMoreEfx

mt_SetPeriod
    MOVEM.L D0-D1/A0-A1,-(SP)
    MOVE.W  (A6),D1
    AND.W   #$0FFF,D1
    LEA mt_PeriodTable(PC),A1
    MOVEQ   #0,D0
    MOVEQ   #35,D2
mt_ftuloop
    CMP.W   (A1,D0.W),D1
    BHS.S   mt_ftufound
    ADDQ.L  #2,D0
    DBRA    D2,mt_ftuloop
mt_ftufound
    MOVEQ   #0,D1
    MOVE.B  n_finetune(A6),D1
    MULU    #36*2,D1
    ADD.L   D1,A1
    MOVE.W  (A1,D0.W),n_period(A6)
    MOVEM.L (SP)+,D0-D1/A0-A1

    MOVE.W  2(A6),D0
    AND.W   #$0FF0,D0
    CMP.W   #$0ED0,D0 ; Notedelay
    BEQ mt_CheckMoreEfx

;   MOVE.W  n_dmabit(A6),$DFF096
    BTST    #2,n_wavecontrol(A6)
    BNE.S   mt_vibnoc
    CLR.B   n_viBRAtopos(A6)
mt_vibnoc
    BTST    #6,n_wavecontrol(A6)
    BNE.S   mt_trenoc
    CLR.B   n_tremolopos(A6)
mt_trenoc
    MOVE.L  n_start(A6),(A5)    ; Set start
    MOVE.W  n_length(A6),4(A5)  ; Set length
;   MOVE.W  n_period(A6),6(A5)  ; Set period
    MOVE.W  n_dmabit(A6),D0
    OR.W    D0,mt_DMACONtemp
    BRA mt_CheckMoreEfx

mt_SetDMA
    MOVE.W  mt_DMACONtemp(PC),D0
    BSR mt_PlaySamples      ; this does the magic
    LEA $DFF000,A5
    LEA mt_chan1temp(PC),A6
    MOVE.L  n_loopstart(A6),$A0(A5)
    MOVE.W  n_replen(A6),$A4(A5)
    LEA mt_chan2temp(PC),A6
    MOVE.L  n_loopstart(A6),$B0(A5)
    MOVE.W  n_replen(A6),$B4(A5)
    LEA mt_chan3temp(PC),A6
    MOVE.L  n_loopstart(A6),$C0(A5)
    MOVE.W  n_replen(A6),$C4(A5)
    LEA mt_chan4temp(PC),A6
    MOVE.L  n_loopstart(A6),$D0(A5)
    MOVE.W  n_replen(A6),$D4(A5)

mt_dskip
    ADD.W   #16,mt_PatternPos
    MOVE.B  mt_PattDelTime,D0
    BEQ.S   mt_dskc
    MOVE.B  D0,mt_PattDelTime2
    CLR.B   mt_PattDelTime
mt_dskc TST.B   mt_PattDelTime2
    BEQ.S   mt_dska
    SUBQ.B  #1,mt_PattDelTime2
    BEQ.S   mt_dska
    SUB.W   #16,mt_PatternPos
mt_dska TST.B   mt_PBreakFlag
    BEQ.S   mt_nnpysk
    SF  mt_PBreakFlag
    MOVEQ   #0,D0
    MOVE.B  mt_PBreakPos(PC),D0
    CLR.B   mt_PBreakPos
    LSL.W   #4,D0
    MOVE.W  D0,mt_PatternPos
mt_nnpysk
    CMP.W   #1024,mt_PatternPos
    BLO.S   mt_NoNewPosYet
mt_NextPosition 
    MOVEQ   #0,D0
    MOVE.B  mt_PBreakPos(PC),D0
    LSL.W   #4,D0
    MOVE.W  D0,mt_PatternPos
    CLR.B   mt_PBreakPos
    CLR.B   mt_PosJumpFlag
    ADDQ.B  #1,mt_SongPos
    AND.B   #$7F,mt_SongPos
    MOVE.B  mt_SongPos(PC),D1
    MOVE.L  mt_SongDataPtr(PC),A0
    CMP.B   950(A0),D1
    BLO.S   mt_NoNewPosYet
    CLR.B   mt_SongPos
mt_NoNewPosYet  
    TST.B   mt_PosJumpFlag
    BNE.S   mt_NextPosition
mt_exit MOVEM.L (SP)+,D0-D4/A0-A6
    RTS

;
; busywait-fixed by Delirium Softdesign.
;
; the old routine wasted about 2*10 rasterlines, this routine needs 2-8 lines
; (depending on the module). It was tested on an A500/A3000/A4000 and seems to
; play all modules ok. BTW, using this new technique it should be no problem
; to fix the busywait-loops of almost every other replay !
;
; known bugs:
;
;  sometimes when a module starts playing and the first note is played on
;  a channel, the routine needs ~100 rasterlines (in the mt_Wait2 loop).
;  perhaps this is a dma problem ?
;
; if you know how to fix these bugs please contact me:
; kunath@informatik.tu-muenchen.de (Peter Kunath)
;

mt_PlaySamples
    movem.l d0-d2/a5-a6,-(sp)
    lea $DFF000,a5
    move.w  d0,d2

    move.b  $06(a5),d0      ; wait until end of line
;   move.w  #$0ff,$180(a5)
mt_Wait1
    cmp.b   $06(a5),d0      ; the wait should be enough even on
    beq.s   mt_Wait1        ; an A4000 running DBLPAL screenmode
mt_MaxPer0
    btst    #0,d2
    beq.s   mt_MaxPer1
    move.w  #1,$A6(a5)      ; max. speed
mt_MaxPer1
    btst    #1,d2
    beq.s   mt_MaxPer2
    move.w  #1,$B6(a5)      ; max. speed
mt_MaxPer2
    btst    #2,d2
    beq.s   mt_MaxPer3
    move.w  #1,$C6(a5)      ; max. speed
mt_MaxPer3
    btst    #3,d2
    beq.s   mt_MaxPer4
    move.w  #1,$D6(a5)      ; max. speed
mt_MaxPer4
    move.w  $02(a5),d0      ; get active channels
    and.w   d2,d0
    move.w  d0,d1
    lsl.w   #7,d0
    move.w  d0,$9C(a5)      ; stop channels
    move.w  d1,$96(a5)
;   move.w  #$f00,$180(a5)
mt_Wait2
    move.w  $1E(a5),d1      ; wait until all channels are stopped
    and.w   d0,d1
    cmp.w   d0,d1
    bne.s   mt_Wait2

    move.w  $02(a5),d0      ; get active channels
    not.w   d0
    and.w   d2,d0
    move.w  d0,d1
    lsl.w   #7,d0
    move.w  d0,$9C(a5)
    or.w    #$8000,d1
    move.w  d1,$96(a5)      ; start channels
;   move.w  #$0f0,$180(a5)
mt_Wait3
    move.w  $1E(a5),d1      ; wait until all channels are running
    and.w   d0,d1
    cmp.w   d0,d1
    bne.s   mt_Wait3
    move.b  $06(a5),d0      ; wait until end of line
;   move.w  #$00f,$180(a5)
mt_Wait4
    cmp.b   $06(a5),d0      ; the wait should be enough even on
    beq.s   mt_Wait4        ; an A4000 running DBLPAL screenmode
mt_SetPer0
    btst    #0,d2
    beq.s   mt_SetPer1
    lea mt_chan1temp(pc),a6
    move.w  n_period(a6),$A6(a5)
mt_SetPer1
    btst    #1,d2
    beq.s   mt_SetPer2
    lea mt_chan2temp(pc),a6
    move.w  n_period(a6),$B6(a5)
mt_SetPer2
    btst    #2,d2
    beq.s   mt_SetPer3
    lea mt_chan3temp(pc),a6
    move.w  n_period(a6),$C6(a5)
mt_SetPer3
    btst    #3,d2
    beq.s   mt_SetPer4
    lea mt_chan4temp(pc),a6
    move.w  n_period(a6),$D6(a5)
mt_SetPer4
;   move.w  #$000,$180(a5)
    movem.l (sp)+,d0-d2/a5-a6
    rts

mt_CheckEfx
    BSR mt_UpdateFunk
    MOVE.W  n_cmd(A6),D0
    AND.W   #$0FFF,D0
    BEQ.S   mt_PerNop
    MOVE.B  n_cmd(A6),D0
    AND.B   #$0F,D0
    BEQ.S   mt_Arpeggio
    CMP.B   #1,D0
    BEQ mt_PortaUp
    CMP.B   #2,D0
    BEQ mt_PortaDown
    CMP.B   #3,D0
    BEQ mt_TonePortamento
    CMP.B   #4,D0
    BEQ mt_ViBRAto
    CMP.B   #5,D0
    BEQ mt_TonePlusVolSlide
    CMP.B   #6,D0
    BEQ mt_ViBRAtoPlusVolSlide
    CMP.B   #$E,D0
    BEQ mt_E_Commands
SetBack MOVE.W  n_period(A6),6(A5)
    CMP.B   #7,D0
    BEQ mt_Tremolo
    CMP.B   #$A,D0
    BEQ mt_VolumeSlide
mt_Return
    RTS

mt_PerNop
    MOVE.W  n_period(A6),6(A5)
    RTS

mt_Arpeggio
    MOVEQ   #0,D0
    MOVE.B  mt_counter(PC),D0
    DIVS    #3,D0
    SWAP    D0
    CMP.W   #0,D0
    BEQ.S   mt_Arpeggio2
    CMP.W   #2,D0
    BEQ.S   mt_Arpeggio1
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    LSR.B   #4,D0
    BRA.S   mt_Arpeggio3

mt_Arpeggio1
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #15,D0
    BRA.S   mt_Arpeggio3

mt_Arpeggio2
    MOVE.W  n_period(A6),D2
    BRA.S   mt_Arpeggio4

mt_Arpeggio3
    ASL.W   #1,D0
    MOVEQ   #0,D1
    MOVE.B  n_finetune(A6),D1
    MULU    #36*2,D1
    LEA mt_PeriodTable(PC),A0
    ADD.L   D1,A0
    MOVEQ   #0,D1
    MOVE.W  n_period(A6),D1
    MOVEQ   #35,D3
mt_arploop
    MOVE.W  (A0,D0.W),D2
    CMP.W   (A0),D1
    BHS.S   mt_Arpeggio4
    ADDQ.L  #2,A0
    DBRA    D3,mt_arploop
    RTS

mt_Arpeggio4
    MOVE.W  D2,6(A5)
    RTS

mt_FinePortaUp
    TST.B   mt_counter
    BNE.S   mt_Return
    MOVE.B  #$0F,mt_LowMask
mt_PortaUp
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   mt_LowMask(PC),D0
    MOVE.B  #$FF,mt_LowMask
    SUB.W   D0,n_period(A6)
    MOVE.W  n_period(A6),D0
    AND.W   #$0FFF,D0
    CMP.W   #113,D0
    BPL.S   mt_PortaUskip
    AND.W   #$F000,n_period(A6)
    OR.W    #113,n_period(A6)
mt_PortaUskip
    MOVE.W  n_period(A6),D0
    AND.W   #$0FFF,D0
    MOVE.W  D0,6(A5)
    RTS 
 
mt_FinePortaDown
    TST.B   mt_counter
    BNE mt_Return
    MOVE.B  #$0F,mt_LowMask
mt_PortaDown
    CLR.W   D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   mt_LowMask(PC),D0
    MOVE.B  #$FF,mt_LowMask
    ADD.W   D0,n_period(A6)
    MOVE.W  n_period(A6),D0
    AND.W   #$0FFF,D0
    CMP.W   #856,D0
    BMI.S   mt_PortaDskip
    AND.W   #$F000,n_period(A6)
    OR.W    #856,n_period(A6)
mt_PortaDskip
    MOVE.W  n_period(A6),D0
    AND.W   #$0FFF,D0
    MOVE.W  D0,6(A5)
    RTS

mt_SetTonePorta
    MOVE.L  A0,-(SP)
    MOVE.W  (A6),D2
    AND.W   #$0FFF,D2
    MOVEQ   #0,D0
    MOVE.B  n_finetune(A6),D0
    MULU    #36*2,D0
    LEA mt_PeriodTable(PC),A0
    ADD.L   D0,A0
    MOVEQ   #0,D0
mt_StpLoop
    CMP.W   (A0,D0.W),D2
    BHS.S   mt_StpFound
    ADDQ.W  #2,D0
    CMP.W   #36*2,D0
    BLO.S   mt_StpLoop
    MOVEQ   #35*2,D0
mt_StpFound
    MOVE.B  n_finetune(A6),D2
    AND.B   #8,D2
    BEQ.S   mt_StpGoss
    TST.W   D0
    BEQ.S   mt_StpGoss
    SUBQ.W  #2,D0
mt_StpGoss
    MOVE.W  (A0,D0.W),D2
    MOVE.L  (SP)+,A0
    MOVE.W  D2,n_wantedperiod(A6)
    MOVE.W  n_period(A6),D0
    CLR.B   n_toneportdirec(A6)
    CMP.W   D0,D2
    BEQ.S   mt_ClearTonePorta
    BGE mt_Return
    MOVE.B  #1,n_toneportdirec(A6)
    RTS

mt_ClearTonePorta
    CLR.W   n_wantedperiod(A6)
    RTS

mt_TonePortamento
    MOVE.B  n_cmdlo(A6),D0
    BEQ.S   mt_TonePortNoChange
    MOVE.B  D0,n_toneportspeed(A6)
    CLR.B   n_cmdlo(A6)
mt_TonePortNoChange
    TST.W   n_wantedperiod(A6)
    BEQ mt_Return
    MOVEQ   #0,D0
    MOVE.B  n_toneportspeed(A6),D0
    TST.B   n_toneportdirec(A6)
    BNE.S   mt_TonePortaUp
mt_TonePortaDown
    ADD.W   D0,n_period(A6)
    MOVE.W  n_wantedperiod(A6),D0
    CMP.W   n_period(A6),D0
    BGT.S   mt_TonePortaSetPer
    MOVE.W  n_wantedperiod(A6),n_period(A6)
    CLR.W   n_wantedperiod(A6)
    BRA.S   mt_TonePortaSetPer

mt_TonePortaUp
    SUB.W   D0,n_period(A6)
    MOVE.W  n_wantedperiod(A6),D0
    CMP.W   n_period(A6),D0
    BLT.S   mt_TonePortaSetPer
    MOVE.W  n_wantedperiod(A6),n_period(A6)
    CLR.W   n_wantedperiod(A6)

mt_TonePortaSetPer
    MOVE.W  n_period(A6),D2
    MOVE.B  n_glissfunk(A6),D0
    AND.B   #$0F,D0
    BEQ.S   mt_GlissSkip
    MOVEQ   #0,D0
    MOVE.B  n_finetune(A6),D0
    MULU    #36*2,D0
    LEA mt_PeriodTable(PC),A0
    ADD.L   D0,A0
    MOVEQ   #0,D0
mt_GlissLoop
    CMP.W   (A0,D0.W),D2
    BHS.S   mt_GlissFound
    ADDQ.W  #2,D0
    CMP.W   #36*2,D0
    BLO.S   mt_GlissLoop
    MOVEQ   #35*2,D0
mt_GlissFound
    MOVE.W  (A0,D0.W),D2
mt_GlissSkip
    MOVE.W  D2,6(A5) ; Set period
    RTS

mt_ViBRAto
    MOVE.B  n_cmdlo(A6),D0
    BEQ.S   mt_ViBRAto2
    MOVE.B  n_viBRAtocmd(A6),D2
    AND.B   #$0F,D0
    BEQ.S   mt_vibskip
    AND.B   #$F0,D2
    OR.B    D0,D2
mt_vibskip
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$F0,D0
    BEQ.S   mt_vibskip2
    AND.B   #$0F,D2
    OR.B    D0,D2
mt_vibskip2
    MOVE.B  D2,n_viBRAtocmd(A6)
mt_ViBRAto2
    MOVE.B  n_viBRAtopos(A6),D0
    LEA mt_ViBRAtoTable(PC),A4
    LSR.W   #2,D0
    AND.W   #$001F,D0
    MOVEQ   #0,D2
    MOVE.B  n_wavecontrol(A6),D2
    AND.B   #$03,D2
    BEQ.S   mt_vib_sine
    LSL.B   #3,D0
    CMP.B   #1,D2
    BEQ.S   mt_vib_rampdown
    MOVE.B  #255,D2
    BRA.S   mt_vib_set
mt_vib_rampdown
    TST.B   n_viBRAtopos(A6)
    BPL.S   mt_vib_rampdown2
    MOVE.B  #255,D2
    SUB.B   D0,D2
    BRA.S   mt_vib_set
mt_vib_rampdown2
    MOVE.B  D0,D2
    BRA.S   mt_vib_set
mt_vib_sine
    MOVE.B  (A4,D0.W),D2
mt_vib_set
    MOVE.B  n_viBRAtocmd(A6),D0
    AND.W   #15,D0
    MULU    D0,D2
    LSR.W   #7,D2
    MOVE.W  n_period(A6),D0
    TST.B   n_viBRAtopos(A6)
    BMI.S   mt_ViBRAtoNeg
    ADD.W   D2,D0
    BRA.S   mt_ViBRAto3
mt_ViBRAtoNeg
    SUB.W   D2,D0
mt_ViBRAto3
    MOVE.W  D0,6(A5)
    MOVE.B  n_viBRAtocmd(A6),D0
    LSR.W   #2,D0
    AND.W   #$003C,D0
    ADD.B   D0,n_viBRAtopos(A6)
    RTS

mt_TonePlusVolSlide
    BSR mt_TonePortNoChange
    BRA mt_VolumeSlide

mt_ViBRAtoPlusVolSlide
    BSR.S   mt_ViBRAto2
    BRA mt_VolumeSlide

mt_Tremolo
    MOVE.B  n_cmdlo(A6),D0
    BEQ.S   mt_Tremolo2
    MOVE.B  n_tremolocmd(A6),D2
    AND.B   #$0F,D0
    BEQ.S   mt_treskip
    AND.B   #$F0,D2
    OR.B    D0,D2
mt_treskip
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$F0,D0
    BEQ.S   mt_treskip2
    AND.B   #$0F,D2
    OR.B    D0,D2
mt_treskip2
    MOVE.B  D2,n_tremolocmd(A6)
mt_Tremolo2
    MOVE.B  n_tremolopos(A6),D0
    LEA mt_ViBRAtoTable(PC),A4
    LSR.W   #2,D0
    AND.W   #$001F,D0
    MOVEQ   #0,D2
    MOVE.B  n_wavecontrol(A6),D2
    LSR.B   #4,D2
    AND.B   #$03,D2
    BEQ.S   mt_tre_sine
    LSL.B   #3,D0
    CMP.B   #1,D2
    BEQ.S   mt_tre_rampdown
    MOVE.B  #255,D2
    BRA.S   mt_tre_set
mt_tre_rampdown
    TST.B   n_viBRAtopos(A6)
    BPL.S   mt_tre_rampdown2
    MOVE.B  #255,D2
    SUB.B   D0,D2
    BRA.S   mt_tre_set
mt_tre_rampdown2
    MOVE.B  D0,D2
    BRA.S   mt_tre_set
mt_tre_sine
    MOVE.B  (A4,D0.W),D2
mt_tre_set
    MOVE.B  n_tremolocmd(A6),D0
    AND.W   #15,D0
    MULU    D0,D2
    LSR.W   #6,D2
    MOVEQ   #0,D0
    MOVE.B  n_volume(A6),D0
    TST.B   n_tremolopos(A6)
    BMI.S   mt_TremoloNeg
    ADD.W   D2,D0
    BRA.S   mt_Tremolo3
mt_TremoloNeg
    SUB.W   D2,D0
mt_Tremolo3
    BPL.S   mt_TremoloSkip
    CLR.W   D0
mt_TremoloSkip
    CMP.W   #$40,D0
    BLS.S   mt_TremoloOk
    MOVE.W  #$40,D0
mt_TremoloOk
    MOVE.W  D0,8(A5)
    MOVE.B  n_tremolocmd(A6),D0
    LSR.W   #2,D0
    AND.W   #$003C,D0
    ADD.B   D0,n_tremolopos(A6)
    RTS

mt_SampleOffset
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    BEQ.S   mt_sononew
    MOVE.B  D0,n_sampleoffset(A6)
mt_sononew
    MOVE.B  n_sampleoffset(A6),D0
    LSL.W   #7,D0
    CMP.W   n_length(A6),D0
    BGE.S   mt_sofskip
    SUB.W   D0,n_length(A6)
    LSL.W   #1,D0
    ADD.L   D0,n_start(A6)
    RTS
mt_sofskip
    MOVE.W  #$0001,n_length(A6)
    RTS

mt_VolumeSlide
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    LSR.B   #4,D0
    TST.B   D0
    BEQ.S   mt_VolSlideDown
mt_VolSlideUp
    ADD.B   D0,n_volume(A6)
    CMP.B   #$40,n_volume(A6)
    BMI.S   mt_vsuskip
    MOVE.B  #$40,n_volume(A6)
mt_vsuskip
    MOVE.B  n_volume(A6),D0
    MOVE.W  D0,8(A5)
    RTS

mt_VolSlideDown
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
mt_VolSlideDown2
    SUB.B   D0,n_volume(A6)
    BPL.S   mt_vsdskip
    CLR.B   n_volume(A6)
mt_vsdskip
    MOVE.B  n_volume(A6),D0
    MOVE.W  D0,8(A5)
    RTS

mt_PositionJump
    MOVE.B  n_cmdlo(A6),D0
    SUBQ.B  #1,D0
    MOVE.B  D0,mt_SongPos
mt_pj2  CLR.B   mt_PBreakPos
    ST  mt_PosJumpFlag
    RTS

mt_VolumeChange
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    CMP.B   #$40,D0
    BLS.S   mt_VolumeOk
    MOVEQ   #$40,D0
mt_VolumeOk
    MOVE.B  D0,n_volume(A6)
    MOVE.W  D0,8(A5)
    RTS

mt_PatternBreak
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    MOVE.L  D0,D2
    LSR.B   #4,D0
    MULU    #10,D0
    AND.B   #$0F,D2
    ADD.B   D2,D0
    CMP.B   #63,D0
    BHI.S   mt_pj2
    MOVE.B  D0,mt_PBreakPos
    ST  mt_PosJumpFlag
    RTS

mt_SetSpeed
    MOVEQ   #0,D0
    MOVE.B  3(A6),D0
    BEQ mt_end
    CMP.B   #32,D0
    BHS SetTempo
    CLR.B   mt_counter
    MOVE.B  D0,mt_speed
    RTS

mt_CheckMoreEfx
    BSR mt_UpdateFunk
    MOVE.B  2(A6),D0
    AND.B   #$0F,D0
    CMP.B   #$9,D0
    BEQ mt_SampleOffset
    CMP.B   #$B,D0
    BEQ mt_PositionJump
    CMP.B   #$D,D0
    BEQ.S   mt_PatternBreak
    CMP.B   #$E,D0
    BEQ.S   mt_E_Commands
    CMP.B   #$F,D0
    BEQ.S   mt_SetSpeed
    CMP.B   #$C,D0
    BEQ mt_VolumeChange
    BRA mt_PerNop

mt_E_Commands
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$F0,D0
    LSR.B   #4,D0
    BEQ.S   mt_FilterOnOff
    CMP.B   #1,D0
    BEQ mt_FinePortaUp
    CMP.B   #2,D0
    BEQ mt_FinePortaDown
    CMP.B   #3,D0
    BEQ.S   mt_SetGlissControl
    CMP.B   #4,D0
    BEQ mt_SetViBRAtoControl
    CMP.B   #5,D0
    BEQ mt_SetFineTune
    CMP.B   #6,D0
    BEQ mt_JumpLoop
    CMP.B   #7,D0
    BEQ mt_SetTremoloControl
    CMP.B   #9,D0
    BEQ mt_RetrigNote
    CMP.B   #$A,D0
    BEQ mt_VolumeFineUp
    CMP.B   #$B,D0
    BEQ mt_VolumeFineDown
    CMP.B   #$C,D0
    BEQ mt_NoteCut
    CMP.B   #$D,D0
    BEQ mt_NoteDelay
    CMP.B   #$E,D0
    BEQ mt_PatternDelay
    CMP.B   #$F,D0
    BEQ mt_FunkIt
    RTS

mt_FilterOnOff
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #1,D0
    ASL.B   #1,D0
    AND.B   #$FD,$BFE001
    OR.B    D0,$BFE001
    RTS 

mt_SetGlissControl
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    AND.B   #$F0,n_glissfunk(A6)
    OR.B    D0,n_glissfunk(A6)
    RTS

mt_SetViBRAtoControl
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    AND.B   #$F0,n_wavecontrol(A6)
    OR.B    D0,n_wavecontrol(A6)
    RTS

mt_SetFineTune
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    MOVE.B  D0,n_finetune(A6)
    RTS

mt_JumpLoop
    TST.B   mt_counter
    BNE mt_Return
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    BEQ.S   mt_SetLoop
    TST.B   n_loopcount(A6)
    BEQ.S   mt_jumpcnt
    SUBQ.B  #1,n_loopcount(A6)
    BEQ mt_Return
mt_jmploop  MOVE.B  n_pattpos(A6),mt_PBreakPos
    ST  mt_PBreakFlag
    RTS

mt_jumpcnt
    MOVE.B  D0,n_loopcount(A6)
    BRA.S   mt_jmploop

mt_SetLoop
    MOVE.W  mt_PatternPos(PC),D0
    LSR.W   #4,D0
    MOVE.B  D0,n_pattpos(A6)
    RTS

mt_SetTremoloControl
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    LSL.B   #4,D0
    AND.B   #$0F,n_wavecontrol(A6)
    OR.B    D0,n_wavecontrol(A6)
    RTS

mt_RetrigNote
    MOVE.L  D1,-(SP)
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    BEQ.S   mt_rtnend
    MOVEQ   #0,D1
    MOVE.B  mt_counter(PC),D1
    BNE.S   mt_rtnskp
    MOVE.W  (A6),D1
    AND.W   #$0FFF,D1
    BNE.S   mt_rtnend
    MOVEQ   #0,D1
    MOVE.B  mt_counter(PC),D1
mt_rtnskp
    DIVU    D0,D1
    SWAP    D1
    TST.W   D1
    BNE.S   mt_rtnend
mt_DoRetrig
;   MOVE.W  n_dmabit(A6),$DFF096    ; Channel DMA off
    MOVE.L  n_start(A6),(A5)    ; Set sampledata pointer
    MOVE.W  n_length(A6),4(A5)  ; Set length
    MOVE.W  n_dmabit(A6),D0
    BSR mt_PlaySamples      ; this does the magic
    MOVE.L  n_loopstart(A6),(A5)
    MOVE.L  n_replen(A6),4(A5)
mt_rtnend
    MOVE.L  (SP)+,D1
    RTS

mt_VolumeFineUp
    TST.B   mt_counter
    BNE mt_Return
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$F,D0
    BRA mt_VolSlideUp

mt_VolumeFineDown
    TST.B   mt_counter
    BNE mt_Return
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    BRA mt_VolSlideDown2

mt_NoteCut
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    CMP.B   mt_counter(PC),D0
    BNE mt_Return
    CLR.B   n_volume(A6)
    MOVE.W  #0,8(A5)
    RTS

mt_NoteDelay
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    CMP.B   mt_counter,D0
    BNE mt_Return
    MOVE.W  (A6),D0
    BEQ mt_Return
    MOVE.L  D1,-(SP)
    BRA mt_DoRetrig

mt_PatternDelay
    TST.B   mt_counter
    BNE mt_Return
    MOVEQ   #0,D0
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    TST.B   mt_PattDelTime2
    BNE mt_Return
    ADDQ.B  #1,D0
    MOVE.B  D0,mt_PattDelTime
    RTS

mt_FunkIt
    TST.B   mt_counter
    BNE mt_Return
    MOVE.B  n_cmdlo(A6),D0
    AND.B   #$0F,D0
    LSL.B   #4,D0
    AND.B   #$0F,n_glissfunk(A6)
    OR.B    D0,n_glissfunk(A6)
    TST.B   D0
    BEQ mt_Return
mt_UpdateFunk
    MOVEM.L A0/D1,-(SP)
    MOVEQ   #0,D0
    MOVE.B  n_glissfunk(A6),D0
    LSR.B   #4,D0
    BEQ.S   mt_funkend
    LEA mt_FunkTable(PC),A0
    MOVE.B  (A0,D0.W),D0
    ADD.B   D0,n_funkoffset(A6)
    BTST    #7,n_funkoffset(A6)
    BEQ.S   mt_funkend
    CLR.B   n_funkoffset(A6)

    MOVE.L  n_loopstart(A6),D0
    MOVEQ   #0,D1
    MOVE.W  n_replen(A6),D1
    ADD.L   D1,D0
    ADD.L   D1,D0
    MOVE.L  n_wavestart(A6),A0
    ADDQ.L  #1,A0
    CMP.L   D0,A0
    BLO.S   mt_funkok
    MOVE.L  n_loopstart(A6),A0
mt_funkok
    MOVE.L  A0,n_wavestart(A6)
    MOVEQ   #-1,D0
    SUB.B   (A0),D0
    MOVE.B  D0,(A0)
mt_funkend
    MOVEM.L (SP)+,A0/D1
    RTS


mt_FunkTable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128

mt_ViBRAtoTable 
    dc.b   0, 24, 49, 74, 97,120,141,161
    dc.b 180,197,212,224,235,244,250,253
    dc.b 255,253,250,244,235,224,212,197
    dc.b 180,161,141,120, 97, 74, 49, 24

mt_PeriodTable
; Tuning 0, Normal
    dc.w    856,808,762,720,678,640,604,570,538,508,480,453
    dc.w    428,404,381,360,339,320,302,285,269,254,240,226
    dc.w    214,202,190,180,170,160,151,143,135,127,120,113
; Tuning 1
    dc.w    850,802,757,715,674,637,601,567,535,505,477,450
    dc.w    425,401,379,357,337,318,300,284,268,253,239,225
    dc.w    213,201,189,179,169,159,150,142,134,126,119,113
; Tuning 2
    dc.w    844,796,752,709,670,632,597,563,532,502,474,447
    dc.w    422,398,376,355,335,316,298,282,266,251,237,224
    dc.w    211,199,188,177,167,158,149,141,133,125,118,112
; Tuning 3
    dc.w    838,791,746,704,665,628,592,559,528,498,470,444
    dc.w    419,395,373,352,332,314,296,280,264,249,235,222
    dc.w    209,198,187,176,166,157,148,140,132,125,118,111
; Tuning 4
    dc.w    832,785,741,699,660,623,588,555,524,495,467,441
    dc.w    416,392,370,350,330,312,294,278,262,247,233,220
    dc.w    208,196,185,175,165,156,147,139,131,124,117,110
; Tuning 5
    dc.w    826,779,736,694,655,619,584,551,520,491,463,437
    dc.w    413,390,368,347,328,309,292,276,260,245,232,219
    dc.w    206,195,184,174,164,155,146,138,130,123,116,109
; Tuning 6
    dc.w    820,774,730,689,651,614,580,547,516,487,460,434
    dc.w    410,387,365,345,325,307,290,274,258,244,230,217
    dc.w    205,193,183,172,163,154,145,137,129,122,115,109
; Tuning 7
    dc.w    814,768,725,684,646,610,575,543,513,484,457,431
    dc.w    407,384,363,342,323,305,288,272,256,242,228,216
    dc.w    204,192,181,171,161,152,144,136,128,121,114,108
; Tuning -8
    dc.w    907,856,808,762,720,678,640,604,570,538,508,480
    dc.w    453,428,404,381,360,339,320,302,285,269,254,240
    dc.w    226,214,202,190,180,170,160,151,143,135,127,120
; Tuning -7
    dc.w    900,850,802,757,715,675,636,601,567,535,505,477
    dc.w    450,425,401,379,357,337,318,300,284,268,253,238
    dc.w    225,212,200,189,179,169,159,150,142,134,126,119
; Tuning -6
    dc.w    894,844,796,752,709,670,632,597,563,532,502,474
    dc.w    447,422,398,376,355,335,316,298,282,266,251,237
    dc.w    223,211,199,188,177,167,158,149,141,133,125,118
; Tuning -5
    dc.w    887,838,791,746,704,665,628,592,559,528,498,470
    dc.w    444,419,395,373,352,332,314,296,280,264,249,235
    dc.w    222,209,198,187,176,166,157,148,140,132,125,118
; Tuning -4
    dc.w    881,832,785,741,699,660,623,588,555,524,494,467
    dc.w    441,416,392,370,350,330,312,294,278,262,247,233
    dc.w    220,208,196,185,175,165,156,147,139,131,123,117
; Tuning -3
    dc.w    875,826,779,736,694,655,619,584,551,520,491,463
    dc.w    437,413,390,368,347,328,309,292,276,260,245,232
    dc.w    219,206,195,184,174,164,155,146,138,130,123,116
; Tuning -2
    dc.w    868,820,774,730,689,651,614,580,547,516,487,460
    dc.w    434,410,387,365,345,325,307,290,274,258,244,230
    dc.w    217,205,193,183,172,163,154,145,137,129,122,115
; Tuning -1
    dc.w    862,814,768,725,684,646,610,575,543,513,484,457
    dc.w    431,407,384,363,342,323,305,288,272,256,242,228
    dc.w    216,203,192,181,171,161,152,144,136,128,121,114

mt_chan1temp    dc.l    0,0,0,0,0,$00010000,0,  0,0,0,0
mt_chan2temp    dc.l    0,0,0,0,0,$00020000,0,  0,0,0,0
mt_chan3temp    dc.l    0,0,0,0,0,$00040000,0,  0,0,0,0
mt_chan4temp    dc.l    0,0,0,0,0,$00080000,0,  0,0,0,0

mt_SampleStarts dc.l    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        dc.l    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

mt_SongDataPtr  dc.l 0
mt_speed    dc.b 6
mt_counter  dc.b 0
mt_SongPos  dc.b 0
mt_PBreakPos    dc.b 0
mt_PosJumpFlag  dc.b 0
mt_PBreakFlag   dc.b 0
mt_LowMask  dc.b 0
mt_PattDelTime  dc.b 0
mt_PattDelTime2 dc.b 0
mt_Enable   dc.b 0
mt_PatternPos   dc.w 0
mt_DMACONtemp   dc.w 0

;------------------------------------------------------------------------------

;------------------------------------------------------------------------------

Gamefield       incbin  "Work:MyProjects/Game/GameFieldStuff/level1.gamefield"
Gamefield2      incbin  "Work:MyProjects/Game/GameFieldStuff/level2.gamefield"
Gamefield3      incbin  "Work:MyProjects/Game/GameFieldStuff/level3.gamefield"

Coords1         incbin  "Work:MyProjects/Game/Coords/Coords4"
Coords2         incbin  "Work:MyProjects/Game/Coords/3Coords2"
Coords3         incbin  "Work:MyProjects/Game/Coords/3Coords3"
                even

Fontti          incbin  "Work:MyProjects/Game/BPL/Font"

gfxname         dc.b    "graphics.liBRAry",0
intuiname       dc.b    "intuition.liBRAry",0
dosname         dc.b    "dos.liBRAry",0

vertname        dc.b    "Music interrupt",0

xwars           dc.b    "A?JOURNEY?TO?HOME",0
codingby        dc.b    "CODING?BY?MARKUS?KETOLA",0
musicby         dc.b    "MUSIC?BY?VARIOUS?PEOPLE",0
titlemusicby    dc.b    "TITLE?MUSIC?BY?CHIPPER",0
ingamemusicby   dc.b    "IN?GAME?MUSIC?BY?MERLIN?M",0
endmusicby      dc.b    "END?MUSIC?BY?HEATBEAT",0

press           dc.b    "PRESS?JOYSTICK?BUTTON?TO?PLAY",0
gameover        dc.b    "GAME?OVER",0
pressjoy        dc.b    "PRESS?JOYSTICK?BUTTON",0
udidit          dc.b    "YOU?DID?IT",0
leftmouse       dc.b    "PRESS?LEFT?MOUSEBUTTON?TO?EXIT",0
usejoy          dc.b    "USE?JOYSTICK?TO",0
type            dc.b    "TYPE?YOUR?INITIALS",0
                even

        section Muuttujat,DATA

intuibase       dc.l    0
gfxbase         dc.l    0
dosbase         dc.l    0
ptbase          dc.l    0

;------------------------------------------------------------------------------
; RÀjÀhdystietue
; WORD  KehissÀ 0/1
; WORD   x
; WORD   y
; WORD   viive
; LONG   Pointteri grafiikkadataan. TÀmÀ on pelkkÀ lisÀysarvo
Explosions       ds.b   12*20
                 dc.w   -1

; ExpVanhaSij0 rakenne
; LONG  ClearScreen-osoite
; LONG   Vanha sijainti -osoite
; WORD   BLITSIZE

ExpVanhaSij0     ds.b   10*20
ExpVanhaSij1     ds.b   10*20

;------------------------------------------------------------------------------
; Monsterin rÀjÀhdystietue
;------------------------------------------------------------------------------
; WORD KehissÀ 0/1
; WORD x
; WORD y
; WORD viive
; LONG Pointteri grafiikkadataan, pelkkÀ lisÀysarvo

Monster_explosion   ds.b    12

MExp_VanhaSij0      ds.b    10
MExp_VanhaSij1      ds.b    10

;------------------------------------------------------------------------------
; VanhaSijX:n rakenne: LONG,LONG,WORD
; 1.LONG: ClearScreen-addy, 2.LONG: Screen1/2-addy, WORD: BLTSIZE

VanhaSij1           ds.w    max_bobs+(4*max_bobs)
VanhaSij2           ds.w    max_bobs+(4*max_bobs)

;------------------------------------------------------------------------------
; Rakenne: LONG,WORD
; LONG: Pointteri Coordinaatteihin, WORD: ON/OFF (1=ON, 0=OFF)
; WORD kestÀvyys, LONG pointteri bob-dataan, LONG pointteri mask-dataan
; TÀssÀ versiossa kaikkien wordien pitÀÀ olla ykkösiÀ aluksi!

PTRsAndONOFF        ds.b    16*max_bobs

;------------------------------------------------------------------------------
; Rakenne: LONG,LONG: ClearScreen(osoite),Vanhasijainti(osoite)

VanhaESij1          ds.l    (AmountEBullets+1)*2
VanhaESij2          ds.l    (AmountEBullets+1)*2
;------------------------------------------------------------------------------
; Rakenne WORD,WORD=x,y. Jos x=-1,niin laaki ei ole liikenteessÀ (=vapaa)
; Aluksi kaikkien x:ien pitÀÀ olla -1!!

EnemyLaakit         ds.w    (AmountEBullets+1)*2

;------------------------------------------------------------------------------
; (0,0,0)=Laaki kehissÀ/ei kehissÀ,x,y)

Laakit              ds.w    (AmountBullets+1)*3
                    dc.w    -1

;------------------------------------------------------------------------------
; Monster-tietue
;
; WORD MX
; WORD MY
; WORD KestÀvyys
; WORD Laaki liikkeelÀ      
; LONG Bullet X             
; LONG Bullet Y             
; LONG AddX                     
; LONG AddY                     
; WORD Laaki liikkeellÀ     
; LONG Bullet X             
; LONG Bullet Y             
; LONG AddX                     
; LONG AddY                     
; WORD Laaki liikkeellÀ     
; LONG Bullet X             
; LONG Bullet Y             
; LONG AddX                     
; LONG AddY                     
; LONG BobData
; LONG MaskData

Monster ds.b    68

;------------------------------------------------------------------------------
; Unit rakenne.
; WORD LiikkellÀ 0/1        0
; LONG UnitX                2
; LONG UnitY                6
; WORD Laaki liikkeellÀ     10
; LONG Bullet X             12
; LONG Bullet Y             16
; LONG BulletAddX           20
; LONG BulletAddY           24
; LONG UnitBob              28
; LONG UnitBobMask          32
; LONG ExplodedUnit         36
; LONG ExplodedUnitMask     40
; WORD KestÀvyys            44
; WORD Liikkuvako           46 Jos 0, niin liikkuu vain 1.:set 16 pikseliÀ
;--------------------------
;                       48
Units           ds.b    48*5
UnitsVanhaSij0  ds.b    10*5
UnitsVanhaSij1  ds.b    10*5
UnitsVBSij0     ds.b    10*5
UnitsVBSij1     ds.b    10*5

; UnitLiikkeellÀ, unit x, unit y, laaki liikkeellÀ, bullet X, bullet Y,
; UnitClearScr, UnitVanhaSij, UnitBulletClearScr, UnitBulletVanhaSij,
; UnitBob, UnitMask
;


;------------------------------------------------------------------------------
; Asteroids-tietue: LiikkeellÀ-merkki, x,y,speed, KestÀvyys
;
; TÀssÀ laitetaan 28 asteroidia
;

Asteroids       ds.w    5*28
VanhaAstSij0    ds.w    28+(4*28)
VanhaAstSij1    ds.w    28+(4*28)

;------------------------------------------------------------------------------
; Monsterille vanhasijaintistuff
MonstVanhaSij0  ds.b    10
MonstVanhaSij1  ds.b    10
MonstBVanhaSij0 ds.b    30
MonstBVanhaSij1 ds.b    30

;------------------------------------------------------------------------------
ScrollOffset    dc.l    (256+16+16)*4*32
LaakiPT         dc.l    0       ; MissÀ kohtaa laakeja ollaan menossa

Exp_PT          dc.l    0           ;
VanhaExpSij     dc.l    0
MExp_vanhasij   dc.l    0

UnitsVanhaSij   dc.l    0
UnitsVBSij      dc.l    0

VanhaAstSij     dc.l    0
VanhaSij        dc.l    0       ; Vihollisten vanha sijainti
VanhaESij       dc.l    0       ; Vihollisten laakien vanha sijainti

MonsterVanhaSij dc.l    0
MonstBVanhaSij  dc.l    0

coolfield       dc.l    0

x               dc.w    128
y               dc.w    235
MX              dc.w    32
MY              dc.w    -64
DX              dc.w    1

Nr_of_asteroids dc.w    0

LineN           dc.l    256     ; Blo(c)kin y-paikka
Bl_paikka       dc.l    0       ; Blo(c)kin x-paikka
pt_toCoolF      dc.l    0       ; 2048
pt_toClear      dc.l    0
Coords          dc.l    0
BitMap1         dc.l    0
BitMap2         dc.l    0
ClearScreen     dc.l    0       ; PelkÀstÀÀn scrollaava alue 
ShowScreen      dc.l    0
DrawScreen      dc.l    0
AttackWavePointer dc.l  0
monster         dc.l   0

outfile         dc.l    0

Random          dc.w    0
Pisteet         dc.w    0

wbenchmsg       dc.l    0
oldview         dc.l    0
process         dc.l    0
processor       dc.w    0
chiprev         dc.b    0 

level           dc.b    1

LastCBFrames    dc.b    0
Kumpainen       dc.b    0
LameFrame       dc.b    0
Frame           dc.b    0
Laskuri         dc.b    0
NPohjassa       dc.b    0
AmEnemies       dc.b    0
MovingEBullets  dc.b    0       ; LiikkeellÀ olevien EnemyBullettien mÀÀrÀ
energia         dc.b    16

gameOver        dc.b    0

DoLastCoordBobFrames    dc.b 0
CoordBobsRunning        dc.b 0      ; Ovatko koordinaativalmiit bobit liikkeellÀ
nr_of_bobs              dc.b 0
Asteroids_on_screen     dc.b 0
AsteroidsRunning        dc.b 0
LastAsteroidFrames      dc.b 3
OwnBulletsOnScreen      dc.b 0
NrOfOwnBullets          dc.b 0
MonsterKehissa          dc.b 0
Monster_destroyed       dc.b 0
MExpFinished            dc.b 0
LastMExpFrames          dc.b 0

phase                   dc.b    0
delay                   dc.b    0
kierros                 dc.b    0

                        even

viive           dc.b  0
letterstyped    dc.b    0
currentchar     dc.b    'A'
small_font      dc.b    0
                    even
bitmap          dc.l    0
pt_Font         dc.l    0

hiscoretable
                    dc.l    Nimi1
                    dc.w    12345
                    dc.l    Nimi2
                    dc.w    2345
                    dc.l    Nimi3
                    dc.w    345
                    dc.l    Nimi4
                    dc.w    45
                    dc.l    Nimi5
                    dc.w    5

Nimi1               dc.b    "ABC",0
Nimi2               dc.b    "DEF",0
Nimi3               dc.b    "GHI",0
Nimi4               dc.b    "JKL",0
Nimi5               dc.b    "MNO",0

Nimi                dc.b    "   ",0,0,0,0,0,0,0,0,0
Luku                dc.b    0,0,0,0,0,0
LevelTXT            dc.b    "LEVEL?0",0,0

Number              dc.b     0,0,0,0,0
                even


; Vertical blanking -keskeytyksen strukture

Vert_str:       dc.l    0           ; KĂ€yttis asettaa
                dc.l    0           ;
                dc.b    2           ; Nodetyyppi=NT_INTERRUPT
                dc.b    0           ; Priotiteetti
                dc.l    vertname
                dc.l    0           ; Kesk.rut.lle tuleva tieto
                dc.l    Keskeytysrutiini ; Kesk. alkuosoite

        section ChipData,DATA,CHIP

Coolfield       ds.b    5120*4
                dc.l    999     ; Loppumerrki
Coolfield2       ds.b    5120*4
                    dc.l       999
Coolfield3       ds.b    5120*4
                     dc.l       999

Dummy           dc.l    0

;EsBob          incbin  "Work:MyProjects/Game/BPL/NewEs.bob"
;EsMask         incbin  "Work:MyProjects/Game/BPL/NewEs.mask"
RengasBob       incbin  "Work:MyProjects/Game/BPL/Rengas.bob"
RengasMask      incbin  "Work:MyProjects/Game/BPL/Rengas.mask"

;UfoBob         incbin  "Work:MyProjects/Game/BPL/Ufo.bob"
;UfoMask        incbin  "Work:MyProjects/Game/BPL/Ufo.mask"
ShipBob         incbin  "Work:MyProjects/Game/BPL/alus.bob"
ShipMask        incbin  "Work:MyProjects/Game/BPL/alus.mask"
WBob            incbin  "Work:MyProjects/Game/BPL/w.bob"
WMask           incbin  "Work:MyProjects/Game/BPL/w.mask"
;ThreeShipBob   incbin  "Work:MyProjects/Game/BPL/3-osainen_alus.bob"
;ThreeShipMask  incbin  "Work:MyProjects/Game/BPL/3-osainen_alus.mask"

Bob             incbin  "Work:MyProjects/Game/BPL/es.bob"
Mask            incbin  "Work:MyProjects/Game/BPL/es.mask"
;LBob           incbin  "Work:MyProjects/Game/BPL/OmaLaaki.mask"
EnBulletBob     incbin  "Work:MyProjects/Game/BPL/newEnemyBullet.bob"
EnBulletMask    incbin  "Work:MyProjects/Game/BPL/newEnemyBullet.mask"
Blocks          incbin  "Work:MyProjects/Game/BPL/4BPLBlocks"
Unit            incbin  "Work:MyProjects/Game/BPL/Unit.bob"
UnitMask        incbin  "Work:MyProjects/Game/BPL/Unit.mask"
ExplodedUnit    incbin  "Work:MyProjects/Game/BPL/ExplodedUnit.bob"
ExplodedUnitM   incbin  "Work:MyProjects/Game/BPL/ExplodedUnit.mask"
AsteroidBob     incbin  "Work:MyProjects/Game/BPL/NewAsteroid.bob"
AsteroidMask    incbin  "Work:MyProjects/Game/BPL/NewAsteroid.mask"
Explosion       incbin  "Work:MyProjects/Game/BPL/Explosion8Frames"
ExplosionMask   incbin  "Work:MyProjects/Game/BPL/Explosion8Frames.mask"
MonsterBob      incbin  "Work:MyProjects/Game/BPL/Monster_draft_smaller.bob"
MonsterMask     incbin  "Work:MyProjects/Game/BPL/Monster_draft_smaller.mask"
MonsterBullet   incbin  "Work:MyProjects/Game/BPL/Monster_bullet.bob"
MonsterBulMask  incbin  "Work:MyProjects/Game/BPL/Monster_bullet.mask"
MonsterExplosionBob incbin "Work:MyProjects/Game/BPL/Monster_explosion_smaller_2.bo"
MonsterExplosionMask incbin "Work:MyProjects/Game/BPL/Monster_explosion_smaller_2.ma"
Monster2Bob     incbin  "Work:MyProjects/Game/BPL/Monster2_draft_smaller.bob"
Monster3Bob     incbin  "Work:MyProjects/Game/BPL/Monster3_draft_smaller.bob"

Score           incbin  "Work:MyProjects/Game/BPL/NewScore"
ScoreMask       incbin  "Work:MyProjects/Game/BPL/NewScore.mask"

Numbers         incbin  "Work:MyProjects/Game/BPL/NewNumbers"
NumbersMask     incbin  "Work:MyProjects/Game/BPL/NewNumbers.mask"

    even

CopperLista
        dc.w    $00e0
high1   dc.w    $0000
        dc.w    $00e2
low1    dc.w    $0000
        dc.w    $00e4
high2   dc.w    $0000
        dc.w    $00e6
low2    dc.w    $0000
        dc.w    $00e8
high3   dc.w    $0000
        dc.w    $00ea
low3    dc.w    $0000
        dc.w    $00ec
high4   dc.w    $0000
        dc.w    $00ee
low4    dc.w    $0000
        dc.w    $0100,$4200
        dc.w    $0102,$0000
        dc.w    $0108,$0060
        dc.w    $010a,$0060
        dc.w    $0092,$0048
        dc.w    $0094,$00c0
        dc.w    $008e,$2c81
        dc.w    $0090,$2ca1

        dc.w    $0120
s0_high dc.w    $0000
        dc.w    $0122
s0_low: dc.w    $0000
        dc.w    $0124
s1_high dc.w    $0000
        dc.w    $0126
s1_low: dc.w    $0000
        dc.w    $0128
s2_high dc.w    $0000
        dc.w    $012a
s2_low  dc.w    $0000
empty   dc.w    $012c
        dc.w    $0000
        dc.w    $012e
        dc.w    $0000
        dc.w    $0130
        dc.w    $0000
        dc.w    $0132 
        dc.w    $0000
        dc.w    $0134
        dc.w    $0000
        dc.w    $0136
        dc.w    $0000
        dc.w    $0138
        dc.w    $0000
        dc.w    $013a
        dc.w    $0000
        dc.w    $013c,$0000
        dc.w    $013e,$0000

Colours
        dc.w    $0182,$0000
        dc.w    $0184,$0000
        dc.w    $0186,$0000
        dc.w    $0188,$0000
        dc.w    $018a,$0000
        dc.w    $018c,$0000
        dc.w    $018e,$0000
        dc.w    $0190,$0000
        dc.w    $0192,$0000
        dc.w    $0194,$0000
        dc.w    $0196,$0000
        dc.w    $0198,$0000
        dc.w    $019a,$0000
        dc.w    $019c,$0000
        dc.w    $019e,$0000

; Energiapalkin vÀrit

        dc.w    $3101,$ff00,$01aa,$0ff0
        dc.w    $3201,$ff00,$01aa,$0cf0
        dc.w    $3301,$ff00,$01aa,$09f0
        dc.w    $3401,$ff00,$01aa,$06f0
        dc.w    $3501,$ff00,$01aa,$03f0
        dc.w    $3601,$ff00,$01aa,$00f0
        dc.w    $3701,$ff00,$01aa,$00f3
        dc.w    $3801,$ff00,$01aa,$00f6
        dc.w    $3901,$ff00,$01aa,$00f9
        dc.w    $3a01,$ff00,$01aa,$00fc
        dc.w    $3b01,$ff00,$01aa,$00ff
        dc.w    $3c01,$ff00,$01aa,$00cf
        dc.w    $3d01,$ff00,$01aa,$009f
        dc.w    $3e01,$ff00,$01aa,$006f
        dc.w    $3f01,$ff00,$01aa,$003f
        dc.w    $4001,$ff00,$01aa,$000f

;           dc.w    $4101,$ff00,$01aa,$0fff

        dc.w    $ffff,$fffe


SPR2    dc.l    $00000000
        dc.l    $e0000000,$e0000000,$e0000000,$e0000000
        dc.l    $e0000000,$e0000000,$e0000000,$e0000000
        dc.l    $e0000000,$e0000000,$e0000000,$e0000000
        dc.l    $e0000000,$e0000000,$e0000000,$e0000000
        dc.l    $00000000

; Aluksi oma sprite-alus, sitten spritelaakit (30)
SPR1            dc.w    $0000,$0000,$0100,$0000,$4284,$0180,$A28A,$6186,$A44A,$63C6,$A44A,$63C6,$A92A,$66E6,$AAAA,$65E6,$B29A,$6DF6
                dc.w    $B45A,$6BF6,$B55A,$6BF6,$B55A,$6AF6,$B45A,$6BF6,$F7DE,$2872,$1010,$0FF0,$1FF0,$0010,$0000,$0000
                
SPR0            dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000

                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000

                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000
                dc.w    $0000,$0000,$2000,$0000,$5000,$3000,$5000,$3000,$5000,$3000,$8800,$7800,$8800,$7800,$8800,$7800,$7000,$7000

                dc.w    $0000,$0000

;mt_data        incbin  "ram:thinktwiceiii.mod"

       end