Hello All!
Here is code of Space Invaders game. It is x86 Assembly
Enjoy!
;;; $RCSfile: part0.asm,v $ $Revision: 1.8 $ $Date: 2005/03/09 15:31:55 $
BITS 16 ; outputin koko bitteinä
stacksize EQU 0200h ; pinon koko
videobase EQU 0a000h ; starting address of video memory
delay EQU 150 ; main loop viive
; some colors
black EQU 0
green EQU 00110000b
blue EQU 00001001b
red EQU 00000100b
white EQU 00001111b
grey EQU 00000111b
scrwidth EQU 320 ; screen width in pixels, in the graphics mode 320x200
Aluksenriviosoite EQU 150*scrwidth ; aluksen rivi
Aluksenleveys EQU 28
Aluksenkorkeus EQU 12
Tykinleveys EQU 5
Tykinkorkeus EQU 5
TykinPiirtoPisteeseen EQU ( -Aluksenkorkeus*scrwidth - Tykinkorkeus*scrwidth + Aluksenleveys/2 - Tykinleveys/2 )
; Invader constants
InvaderRows EQU 3
InvadersPerRow EQU 5
InvaderStartLoc EQU 13*scrwidth ; Location of the upperleftmost invader at the start of the game
InvaderDistance_x EQU 50 ; invaderien välinen matka, HUOM: oltava InvadersPerRow*InvaderDistance_x < 320
InvaderSpeed EQU 1
InvaderDistance_y EQU 12*scrwidth ; esim. 12 riviä
InvaderGoal EQU 107*scrwidth ; millä rivillä on invaderien maali
InvaderRiviMuutos EQU 3 ; montako rivia invader laskeutuu reunalla
InvaderType EQU 1 ; type of invader (0-2)
InvaderMatka EQU (scrwidth - (InvadersPerRow - 1)*InvaderDistance_x - 14) ; on matka, jonka invaderit kävelee yhdellä rivillä
;---------------------------------------------------------------------------------------------------
segment mystack stack ; pino sekmentti
resb stacksize ; varataan tila pinolle
stacktop:
;----------------------------------------------------------------------------------------------------
segment mydata data ;data segmentti
shiplocation dw (Aluksenriviosoite + scrwidth/2) ; vanhan kuvan paikka
newshiplocation dw (Aluksenriviosoite + scrwidth/2) ; uuden kuvan paikka
shotlocation dw 0 ; ammuksen paikka
fire dw 0 ; laukaustapahtuma (?)
laskuri dw 0 ; laskuri, joka laskee 16
laskuri2 dw 0 ; laskuri, joka laskee 110
pisteenpaikka dw 0 ; pisteenpaikka
mika_morko dw 0 ; mikä mörkö
osumat dw 0 ; osuma contteri
hyppy dw 0 ; hyppymuuttuja, jotta voidaan hypata pidemmalle koodissa
animationstep dw 0 ; muuttuja joka kertoo jalkojen heiluttamisen
invaderLocation dw InvaderStartLoc
InvaderStatus db green, green, green, green, green, blue, blue, blue, blue, blue, red, red, red, red, red
invaderDirection dw 1
Voitto DB ' Sina voitit! Press Esc to continue..$'
Havio DB 13,10,' Sina havisit! Press Esc to continue..',13,10,'$'
oldvideomode db 0 ; Varataan yksi tavu
pressesc dw 0 ; one word variable pressesc with value of 0
; HUOM ÄLÄ LAITA 0 NÄIHIN!!!!
oldintseg resw 1
oldintoff resw 1
;-----------------------------------------------------------------------------------------------------
segment mycode code ; Koodi segmentti
KeybInt:
push ds ; put the value of ds,ax to safety
push ax
mov ax,mydata ; Re-initialisation of
mov ds,ax ; the data segment
cli ; Disable other interrupts
; during this one
.getstatus:
in al, 64h
test al, 02h
loopnz .getstatus ; wait until the port is ready
in al,60h ; Get the scan code of
; the pressed/released key
; scan codes can be found in helppc
; interrupt services ->
; keyboard interrupt -> make codes
; here begins the actual key scanning
cmp al, 01h ; 1 is the scan code for ESC
jne .kbread ; if ESC was not pressed, continue
mov word [pressesc], 1
.kbread:
in al,61h ; Send acknowledgment without
or al,10000000b ; modifying the other bits.
out 61h,al ;
and al,01111111b ;
out 61h,al ;
mov al,20h ; Send End-of-Interrupt signal
out 20h,al ;
sti ; Enable interrupts again
pop ax
pop ds ; Regain the ds,ax from stack
iret ; Return from interrupt
; Mouse interrupt subroutine
MouseInt:
push cx
push ds
mov cx, mydata ; Re-initialization of the data segment
mov ds, cx ; (must be done in interrupt subroutines)
pop ds
pop cx
push di
add cx,Aluksenriviosoite ; Astetetaan aluksen paikka
mov word [newshiplocation],cx
; tarkistetaan onko "ammuttu"
cmp bx,1 ; jos on painettu, bx=1, tarkistetaan..
jne .hyppaayli ; jos ei oo painettu, hyppaa yli
mov word [fire] ,1h ; jos on painettu, fire = 1
mov di,[shotlocation] ; jos on ammuttu, pitää myös vanha ammus tuhota
mov byte [es:di],black
.hyppaayli
pop di
retf
;--------------------------------------------------------------------------------------------------
mikamorko:
push cx
push bx
push dx
push di
mov cx,(InvaderRows+2) ;loop countterin alustus, varmuuden vuoksi vähän isommaksi
mov dx,0
inc di ; korjaa bugin, jossa osuma tappoi viereisen olion
.loop
sub di,InvaderDistance_y
cmp di,[invaderLocation]
jb .poistumispaikka
add dx,InvadersPerRow
LOOP .loop
.poistumispaikka
mov cx,(InvaderDistance_y / scrwidth + 2)
.loop2
add di,scrwidth
cmp di,[invaderLocation]
ja .poistumispaikka2 ; pudottaudutaan samalle riville
LOOP .loop2
.poistumispaikka2
mov cx, (InvadersPerRow + 2) ;loop countterin alustus, varmuuden vuoksi vähän isommaksi
.loop3
sub di,InvaderDistance_x
cmp di,[invaderLocation]
jb .poistumispaikka3
inc dx
LOOP .loop3
.poistumispaikka3
mov [mika_morko],dx
pop di
pop dx
pop bx
pop cx
ret
moveshot: ; liikuttaa paukkua
push di
push bx
mov word di,[shotlocation]
; ensin mustaksi "vanha" ammus
mov byte [es:di],black
cmp word di,scrwidth ; tarkistetaan ollaanko yläreunassa
ja .hyppaayli ; jos ei, hypataan vain yli
mov word [shotlocation],0h ; jos ollaan, tuhotaan ammus
jmp .hyppaayli2
.hyppaayli
sub word di, scrwidth ; shotlocation yksi ylöspäin
sub word [shotlocation],scrwidth
; tarkistetaan seuraavan pikselin väri
mov bx,[es:di] ; Haetaan väri bx:ään
cmp bx,0 ; tarkistetaan onko nolla
je .hyppaayli1 ; jos oli niin laiteteean valkoiseksi
; jos ei niin tuhotaan invader
; selvitetään mihinkä mörköön osuttu
call mikamorko ; Huom! osumakoordinaatti on di:ssä
push bx
mov bx,InvaderStatus ; Kun tiedetään kehen on osuttu, pistetään kyseisen moron status=0
add bx,[mika_morko]
mov byte [bx],0h
pop bx
mov word [shotlocation],0h ; kun osutaan, tuhotaan myös paukku
inc word [osumat] ; kasvatetaan osumat laskuria
jmp .hyppaayli2
.hyppaayli1
mov byte [es:di], white
.hyppaayli2
pop bx
pop di
ret
fireshot: ; asettaa ammuksen lähtöpisteeseen
push ax
mov word ax,[shiplocation]
add ax, (Aluksenleveys/2 - Tykinkorkeus*scrwidth) ; mennään shiplocationista piippuun
mov word [shotlocation],ax
mov word [fire],0h ; nollaa fire
pop ax
ret
eraseship: ; poistaa vanhan avaruusaluksen
push ax ; ax työnnetään pinoon
push bx ; bx myös
push di
mov ax, (-Aluksenleveys)
mov word di,[shiplocation] ; avaruusaluksen sijainti asetetaan di-muistipaikkaan
mov bx, (-Aluksenkorkeus)
.Alusloop ; Alus loop
mov byte [es:di], black ; pikselin piirto
inc di ; mene seuraavaan pikseliin
inc ax ; incrementoi vaaka-loop-laskuria
cmp ax,0h
jne .Alusloop
add di,(scrwidth-Aluksenleveys) ; Menee seuraaval rivin alkuun
inc bx ; inkrementoi pysty-loopin laskuria
mov ax, (-Aluksenleveys)
cmp bx,0h ; jos bx=0, on kaikki rivit piirretty
jne .Alusloop
mov ax, (-Tykinleveys)
add di, TykinPiirtoPisteeseen ; Tykin piirtopiste
mov bx, (-Tykinkorkeus)
.Tykkiloop ; Tykki loop
mov byte [es:di], black ; toimii vastaavasti, muuta piirtaa pienemman nelion
inc di
inc ax
cmp ax,0h
jne .Tykkiloop
add di,(scrwidth-Tykinleveys) ; Menee seuraaval rivin alkuun
inc bx
mov ax, (-Tykinleveys)
cmp bx,0h
jne .Tykkiloop
pop di
pop bx
pop ax
ret
drawship: ; poistaa vanhan avaruusaluksen
push ax ; ax työnnetään pinoon
push bx ; bx myös
push di
mov ax,(-Aluksenleveys)
mov word di,[shiplocation] ; avaruusaluksen sijainti asetetaan di-muistipaikkaan
mov bx,(-Aluksenkorkeus)
.Alusloop ; Alus loop
mov byte [es:di], blue ; pikselin piirto
inc di ; mene seuraavaan pikseliin
inc ax ; incrementoi vaaka-loop-laskuria
cmp ax,0h
jne .Alusloop
add di,(scrwidth-Aluksenleveys) ; Menee seuraaval rivin alkuun
inc bx ; inkrementoi pysty-loopin laskuria
mov ax,(-Aluksenleveys)
cmp bx,0h ; jos bx=0, on kaikki rivit piirretty
jne .Alusloop
mov ax,(-Tykinleveys)
add di,TykinPiirtoPisteeseen ; Tykin piirtopiste
mov bx,(-Tykinkorkeus)
.Tykkiloop ; Tykki loop
mov byte [es:di], white ; toimii vastaavasti, muuta piirtaa pienemman nelion
inc di
inc ax
cmp ax,0h
jne .Tykkiloop
add di,(scrwidth-Tykinleveys) ; Menee seuraaval rivin alkuun
inc bx
mov ax,(-Tykinleveys)
cmp bx,0h
jne .Tykkiloop
pop di
pop bx
pop ax
ret
drawInvader:
pusha ; pistää kaikki rekisterit pinoon
CMP BX, 0
je .i1
jmp .i2
.i1
cmp CX, 0
je .invader11
jmp .invader12
.invader11:
add di, 5
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 318
mov cx, 4
.loop1:
mov byte [es:di], al
inc di
loop .loop1
add di, 315
mov cx, 6
.loop2:
mov byte [es:di], al
inc di
loop .loop2
add di, 313
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 313
mov cx, 8
.loop3:
mov byte [es:di], al
inc di
loop .loop3
add di, 314
mov byte [es:di], al
add di, 3
mov byte [es:di], al
add di, 316
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
add di, 314
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
add di, 3
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
jmp .end2
.invader12:
add di, 5
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 318
mov cx, 4
.loop4:
mov byte [es:di], al
inc di
loop .loop4
add di, 315
mov cx, 6
.loop5:
mov byte [es:di], al
inc di
loop .loop5
add di, 313
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 313
mov cx, 8
.loop6:
mov byte [es:di], al
inc di
loop .loop6
add di, 313
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
add di, 314
mov byte [es:di], al
add di, 7
mov byte [es:di], al
add di, 314
mov byte [es:di], al
add di, 5
mov byte [es:di], al
jmp .end2
.i2:
CMP BX, 1
je .i21
jmp .i3
.i21:
cmp CX, 0
je .invader21
jmp .invader22
.invader21:
add di, 3
mov byte [es:di], al
add di, 5
mov byte [es:di], al
add di, 313
mov byte [es:di], al
add di, 3
mov byte [es:di], al
add di, 3
mov byte [es:di], al
add di, 3
mov byte [es:di], al
add di, 311
mov byte [es:di], al
inc di
inc di
mov cx, 6
.loop7:
mov byte [es:di], al
inc di
loop .loop7
inc di
mov byte [es:di], al
add di, 311
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 311
mov cx, 10
.loop8:
mov byte [es:di], al
inc di
loop .loop8
add di, 311
mov cx, 8
.loop9:
mov byte [es:di], al
inc di
loop .loop9
add di, 313
mov byte [es:di], al
add di, 5
mov byte [es:di], al
add di, 314
mov byte [es:di], al
add di, 7
mov byte [es:di], al
jmp .end2
.invader22:
add di, 3
mov byte [es:di], al
add di, 5
mov byte [es:di], al
add di, 316
mov byte [es:di], al
add di, 3
mov byte [es:di], al
add di, 316
mov cx, 6
.loop10:
mov byte [es:di], al
inc di
loop .loop10
add di, 313
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 312
mov cx, 10
.loop11:
mov byte [es:di], al
inc di
loop .loop11
add di, 310
mov cx, 10
.loop12:
mov byte [es:di], al
inc di
loop .loop12
add di, 310
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
add di, 5
mov byte [es:di], al
inc di
inc di
mov byte [es:di], al
add di, 314
mov byte [es:di], al
add di, 3
mov byte [es:di], al
jmp .end2
.i3:
cmp CX, 0
je .invader31
jmp .invader32
.invader31:
add di, 4
mov cx, 4
.loop13:
mov byte [es:di], al
inc di
loop .loop13
add di, 313
mov cx, 10
.loop14:
mov byte [es:di], al
inc di
loop .loop14
add di, 309
mov cx, 12
.loop15:
mov byte [es:di], al
inc di
loop .loop15
add di, 308
mov cx, 3
.loop16:
mov byte [es:di], al
inc di
loop .loop16
add di, 2
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 3
mov cx, 3
.loop17:
mov byte [es:di], al
inc di
loop .loop17
add di, 308
mov cx, 12
.loop18:
mov byte [es:di], al
inc di
loop .loop18
add di, 311
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 3
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 314
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 2
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 2
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 311
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 9
mov byte [es:di], al
inc di
mov byte [es:di], al
jmp .end2
.invader32:
add di, 4
mov cx, 4
.loop19:
mov byte [es:di], al
inc di
loop .loop19
add di, 313
mov cx, 10
.loop20:
mov byte [es:di], al
inc di
loop .loop20
add di, 309
mov cx, 12
.loop21:
mov byte [es:di], al
inc di
loop .loop21
add di, 308
mov cx, 3
.loop22:
mov byte [es:di], al
inc di
loop .loop22
add di, 2
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 3
mov cx, 3
.loop23:
mov byte [es:di], al
inc di
loop .loop23
add di, 308
mov cx, 12
.loop24:
mov byte [es:di], al
inc di
loop .loop24
add di, 310
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 3
mov byte [es:di], al
inc di
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 312
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 3
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 3
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 312
mov byte [es:di], al
inc di
mov byte [es:di], al
add di, 5
mov byte [es:di], al
inc di
mov byte [es:di], al
jmp .end2
.end2:
popa
ret
eraseInvaders: ; alirutiini, joka pyyhkii invaderit
push ax
push cx
push bx ; laitetaan käytetyt rekisterit pinoon talteen
push dx
push di
mov dx,0 ; alustetaan dx=0, dx osoittaa nykyiseen olioon taulukossa
mov word di, [invaderLocation] ; di laitetaan invaderLocation, di kertoo mihin nykyinen olio piirretään
mov cx,InvaderRows ; alustetaan pystyloopin countteri, esim.3 riviä => cx=3
.pystyloop
push cx
mov cx, InvadersPerRow ; alustetaan riviloopin countteri
.riviloop
push cx ; pistetään loopcounter talteen
mov al,0 ; pyyhitään vanha invader pois, asetetaan musta väri
mov bx,InvaderType ; olion muotovakiot
mov cx,[animationstep] ; laitetaan cx:ään animaatiostep
call drawInvader ; jotta ei jää pikselijäämiä, pitää jostain syystä pyyhkiä kummatkin animaatiostepit
call animaatiostepinvaihto ; animaatiostepin vaihto
mov cx,[animationstep] ; laitetaan cx:ään animaatiostep
call animaatiostepinvaihto ; animaatiostepin vaihto takaisin siihen, mikä se on ollut ennen tätä alirutiinia
call drawInvader ; pyyhkiminen toisella animaatiostepilla
add di, InvaderDistance_x ; asetetaan di seuraavaan piirtokohtaan
inc dx ; käpistellään seuraavaa oliota
pop cx ; haetaan loopcountteri takaisin
LOOP .riviloop
add di, (InvaderDistance_y - InvadersPerRow*InvaderDistance_x) ; mennään seuraavalle riville
pop cx
LOOP .pystyloop
pop di
pop dx
pop bx
pop cx
pop ax
ret
drawInvaders: ; alirutiini, joka piirtää invaderit
push ax
push cx
push bx
push dx ; laitetaan käytetyt rekisterit pinoon talteen
push di
call animaatiostepinvaihto ; animation stepin vaihto uuteen
mov dx,0 ; alustetaan dx=0, dx osoittaa nykyiseen olioon taulukossa
mov word di, [invaderLocation] ; di laitetaan invaderLocation, di kertoo mihin nykyinen olio piirretään
mov cx,InvaderRows ; esim.3 riviä
.pystyloop
push cx
mov cx, InvadersPerRow ; esim. 5 per rivi
.riviloop
call animaatiostepinvaihto ; animation stepin vaihto vanhaan
push cx ; pistetään loopcounter talteen
mov al,0 ; pyyhitään vanha invader pois
mov bx, InvaderType ; olion tyypin alustus
mov cx, [animationstep] ; animation stepin alustus
sub di, [invaderDirection] ; di pitää vähentää, jolloin se osoittaa vanhaan invaderiin
call drawInvader ; nyt on vanhat invaderit pyyhitty mustalla värillä
call animaatiostepinvaihto ; animation stepin vaihto takaisin uuteen
add di, [invaderDirection] ; pyyhkimisen jälkeen piirretään invader 1 askel eteenpäin
; piirretään uusi invader uuteen paikkaan
mov cx, [animationstep] ; animation stepin alustus
push di ; laitetaan di pinoon, koska sitä tarvitaan seuraavilla 3:lla rivilla
mov word di, InvaderStatus ; asetetaan di, status-taulukon alkuun
add di,dx ; lisätään offset, jolloin päästään oikeaan olioon
mov byte al, [di] ; haetaan olion status al-paikkaan.
pop di ; haetaan di takaisin
call drawInvader ; piirtää uuden kuvan
add di, InvaderDistance_x ; asetetaan di seuraavaan piirtokohtaan
inc dx ; käpistellään seuraavaa oliota
pop cx ; haetaan loopcountteri takaisin
LOOP .riviloop
add di, (InvaderDistance_y - InvadersPerRow*InvaderDistance_x) ; mennään seuraavalle riville
pop cx
LOOP .pystyloop
pop di
pop dx
pop bx
pop cx
pop ax
ret
moveInvaders: ; liikuttaa invadereja
push bx
push di
inc word [laskuri2] ; kasvatetaan laskuria2, joka laskee kuinka monta askelta invader on kulkenut yhdellä rivillä
cmp word[laskuri2], InvaderMatka ; tarkistetaan, onko kävellyt yhden rivin matkan
jne .hyppaayli ; jos ei ole = InvaderMatka, suuntaa ei vaihdeta vaan hypataan yli
call eraseInvaders ; pyyhitään vanha pois tästä reunasta
add word [invaderLocation], (InvaderRiviMuutos*scrwidth) ; hypätään seuraavalle riville
neg word [invaderDirection] ; otetaan negaatio invaderlocationista
mov word [laskuri2],0 ; pitää nollata myös
jmp .hyppaayli2
.hyppaayli
mov word bx, [invaderDirection]
add word [invaderLocation],bx ; invaderlocation kasvatetaan 1:lla
call drawInvaders ; varsinainen piirtäminen
.hyppaayli2
pop di
pop bx
ret
Viive:
mov dx, delay
.pause1:
mov cx, 65535
.pause2:
dec cx
jne .pause2
dec dx
jne .pause1
ret
;piirrapiste: ; testausfunktio
; push di
; push cx
; mov cx,[mika_morko]
; mov di,[pisteenpaikka]
;.loop
; add di,8
; mov byte[es:di],red
;LOOP .loop
; pop cx
; pop di
;ret
animaatiostepinvaihto: ; vaihtaa eli invertoi animation stepin
cmp word [animationstep],0 ; päivitetään animation steppi
je .hyppaayli
mov word [animationstep],0
jmp .hyppaayli2
.hyppaayli
mov word [animationstep],1
.hyppaayli2
ret
;-----------------------------------------------------------------------------------------------------------------------
..start: ; pääohjelma alkaa tästä
mov ax, mydata ; asetetaan ds rekisteri oikeaan sekmentiiin
mov ds, ax
mov ax, mystack ; aettaa ss rekisterin oikeaan pino sekmenttiin
mov ss, ax
mov sp, stacktop ; pointteri osoittamaan stacktoppiiin
mov ah,35h ; Haetaan alkuperäinen keskeytysvektori
mov al, 9h ; ..näppäimistölle = 9
int 21h ; palauttaa es:bx, pointterin keskeytyshandleriin
mov [oldintseg],es ; segmenttiosoite tallennetaan => oldintseg
mov [oldintoff],bx ; offset tallennetaan => oldintoff
; asetetaan oma näppäimistön keskeytysvektori
mov dx, KeybInt ; keskeytysvektorin offset => dx-rekisteriin
mov ax, mycode ; keskeytysvektorin segmenttiosoite => ds-rekisteriin
mov ds, ax
mov ah, 25h ; aseteteaan keskeytysvektori...
mov al, 9h ; näppäimistölle
int 21h ; varsinainen operaatio, joka asettaa uuden keskeytysvektorin
mov ax, mydata ; operaatiossa tarvittiin ds-rekisteriä, palautetaan se takaisin data-segmanttiin
mov ds, ax
mov ah,0Fh ; Haetaan vanha resoluutio ja tallennetaan se
int 10h ; Tiedot ovat ah al ja bh rekistereissä
mov byte [oldvideomode],al ; vanha moodi tallennetaan paikkaan oldvideomode
; Asetetaan resoluutio 320*200*256
mov ah,00h ; Asetetaan resoluutio ...
mov al,13h ; 320x200
int 10h ; Varsinainen keskeytys
mov ax,00 ; Tutkitaan onko hiiri asennettu
int 33h ; varsinainen keskeytys
cmp ax,0000
jne .jump
mov word [hyppy],1 ; jos hiirtä ei ole asennettu, hypätään välihypyn kautta .dosexittiin
jmp .valihyppy
.jump
; Vaihdetaan hiiren keskeytys rutiin
mov ax,mycode ; segmentti osoite es:ää
mov es,ax
mov dx,MouseInt ; offset osoite dx:ään
mov ax,14h
mov cx,0003h ; keskeytysjos: 1.cursor position changed, 2.leftmouseclick
int 33h ; Varsinainen keskeytys
; asetetaan hiiren max ja min horisontaaliarvot
mov ax,7
mov bx,0 ; min=0
mov cx,(scrwidth-Aluksenleveys) ; max=320-aluksenleveys
int 33h ; varsinainen operaatio
; Videomuistialueen alustus
mov ax,videobase
mov es,ax
;------------------------------------------------------------------------------------------------------------------------
.mainloop ; Main-loop
call Viive ; viivästetään mainlooppia
call eraseship
mov ax,[newshiplocation]
mov [shiplocation],ax
call drawship
cmp word [fire],1 ; tarkistetaan, onko ammuttu
jne .hyppaayli1 ; jos ei, hyppaa yli
call fireshot ; jos on, kutsu fireshottia
.hyppaayli1
; ammuksen liikuttaminen
cmp word [shotlocation],0
je .hyppaayli20 ; ei liikuteta vaan hypataan yli
call moveshot ; jos slocation=1, kutsutaan moveshot
.valihyppy ; valihyppy: jos hiirtä ei asennettuna, hypätään tämän kautta .dosexit
cmp word [hyppy],1
je .dosexit
.hyppaayli20
inc word [laskuri] ; kasvaa mainin tahtiin
cmp word [laskuri], InvaderSpeed
jne .hyppaayli3
call moveInvaders
mov word [laskuri], 0
cmp word [invaderLocation],InvaderGoal
jb .hyppaayli4
mov dx,Havio
mov ah,9 ; DOS: print string
int 21h ; display the appropriate greeting
.loputonloop2
cmp word [pressesc],1
jne .loputonloop2
jmp .dosexit
.hyppaayli4
cmp word [osumat],(InvaderRows * InvadersPerRow )
jne .hyppaayli3
mov dx,Voitto
mov ah,9 ; DOS: print string
int 21h ; display the appropriate greeting
.loputonloop
cmp word [pressesc],1
jne .loputonloop
jmp .dosexit
.hyppaayli3
cmp word [pressesc],1 ; tutki, onko esc-nappia painettu
jne .mainloop ; jos ei ole painettu, palaa looppiin
.dosexit: ; Lopetusalirutiini
; Palautetaan resoluutio
mov ah,00h ; Asetetaan resoluutio ...
mov byte al,[oldvideomode] ; Vanhan videomoodin palautus
int 10h ; Varsinainen keskeytys
; palautetaan alkuperäinen näppäimistön keskeytysvektori
mov dx,[oldintoff] ; asetetaan alkuperaiset arvot dx ja ds rekistereihin
mov ax,[oldintseg]
mov ds,ax
mov ah,25h ; keskeytysvektorin asetus
mov al,9h ; ja nimenomaan näppäimistölle
int 21h ; varsinainen operaatio, joka palauttaa alkuperaiset arvot
mov al, 0 ; palautusarvo 0
mov ah, 4ch ; keskeytys 21.4c joka lopettaa ohjelman palautusarvolla
int 21h
.end