+ ld hl,GRAPH_MEM ;move from (hl) = top left
+ ld (hl),$00 ;first pixel will be copied all over the screen
+ ld de,GRAPH_MEM+1 ;(de) = next pixel, thus clearing whole screen
+ ld bc,896 ;loop 896 times = (128/8) * (64-8 for scorebar)
+ ldir ;all clear!
+
+ ld a,0 ;current frame/turn 0-255
+timer =$-1
+ and %11 ;a=0 once every 4 turns
+ jr z,movestarsdone ;don't move stars once every 4 frames
+ cal movestars1 ;move the stars on the FRONT layer
+ cal movestars2 ;move the distant stars
+movestarsdone:
+ ld a,(stars1) ;star positions (the missing byte...)
+ ld b,nrstars1 ;how many stars? now we know.
+ ld hl,starx1 ;points to the position of the stars
+ cal DisplayStars ;display front layer stars
+ ld a,(stars2) ;weren't you paying attention five lines ago?
+ ld b,nrstars2 ;that many?! whow!
+ ld hl,starx2 ;and there they are
+ cal DisplayStars ;use the same procedure to display back layer
+
+ ld a,(level_info) ;level info
+ and %00000110 ;isolate ground&ceiling
+ jr z,game_stuff ;both non-present
+ and %00000010 ;bit representing the presence of any ceiling
+ cal nz,Handle_ceiling ;scroll the ceiling (if any) +check4collision
+ cal Handle_ground ;scroll the ground and check if we're dead
+
+game_stuff:
+ cal Handle_Ship ;move you
+ ld a,(your_occ) ;are you 100% OK?
+ or a ;a=0??
+ jr nz,_gamestuff1 ;then don't check for movements/fires/...
+
+check_keys:
+ ld a,%10111111 ;function keys (MORE,EXIT,2ND,F1,F2,F3,F4,F5)
+ out (1),a ;ask for them
+ nop \ nop ;delay 8 clocks
+ in a,(1) ;get zem!
+
+check_exitkey:
+ bit 6,a ;test bit 6 = exit-key = EXIT
+ jp z,game_over ;<exit> pressed, so be it
+check_morekey: ;another unused label... poor compiler
+ bit 7,a ;test bit 7 = more-key = PAUSE
+ cal z,Pause ;yes, go to pause
+
+check_firekey:
+ bit 5,a ;test bit 5 = 2nd-key = FIRE
+ ld hl,check_selkey ;where to continue after executing Fire_bullet
+ psh hl ;push hl on stack (instead of cal Fire_bullet)
+ jp z,Fire_bullet ;fire smtn (bulletstorplasermultiples+stuff..)
+ pop hl ;no cal to Fire_bullet made, so pop stack
+ xor a ;no:
+ ld (just_fired),a ;reset just_fired
+
+check_selkey:
+ ld a,%01011111 ;look at first column of keys (ALPHA to STO)
+ out (1),a ;gimme
+ nop \ nop ;what's taking you so long
+ in a,(1) ;at last... our precious keyzzz...
+
+ bit 6,a ;'bout the GRAPH key...
+ cal z,Teacher ;you didn't _press_ it, did you?!?
+
+ rla ;test bit7 so we know f ALPHA has been pressed
+ cal nc,select ;yeppy, select the currently selected upgrade
+
+ cal Enemies_hit ;check for collision with enemies
+ cal inc_weapdamage
+
+_gamestuff1:
+ cal Handle_enemies ;move enemies
+
+ cal Handle_bullets ;move your bullets + check for hits
+ cal Enemy_bullets ;move enemy bullets
+ cal Handle_torp ;the same for your torpedo (assuming u have 1)
+
+ cal Level_event ;insert enemies
+ cal Display_Screen ;display all
+
+ ld b,1
+___:
+ halt ;delay
+ dnz ___
+ jp game_main_loop ;LOOP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+inc_weapdamage:
+ ld a,0
+weapincs =$-1
+ inc a
+ cp 97 ;max. 96 times (=96/16=6 increases)
+ ret nc ;return if already maxed
+ ld (weapincs),a ;save new incs
+
+ and %11110000 ;clear last 4 bits so no cf when rotating
+ ;btw: AND resets cf
+ rra ;rotate acting as shift (srl a) but just 1B
+ rra
+ rra
+ rra ;increase once just every 16 turns
+ ld b,a ;times to increase
+incthedamage:
+ add a,1 ;increase damage for one increase
+weapdaminc =$-1
+ dnz incthedamage ;a=total increase damage
+ ld b,1 ;minimal damage
+weapdamage =$-1
+ add a,b ;a=total damage
+ ld (curweapdamage),a ;safe the current damage
+ cal disp_charge
+ ret
+
+;--------------------------- ground -----------------------------------------
+
+Handle_ground:
+ ld a,(timer)
+ and %111 ;once every 8 frames
+ jr nz,Display_ground ;otherwise skip the scroll
+ ld bc,15 ;scroll all 16 bytes minus one (teh new byte)
+ ld hl,groundpos+1 ;from..
+ ld de,groundpos ;to (one byte to the left)
+ ldir ;LoaDIncreaseRepeat = scroll!
+
+ ld a,(groundinfo) ;what kind of ground
+ dec a ;type 1:
+ jr z,ground_tunnel ;tunnel effect
+ground_boring:
+ ld a,(groundpos) ;type 0
+ jr newground+1
+
+ground_tunnel:
+ ld a,(groundpos+14)
+ ld d,a
+ ld hl,spacespace
+ ld bc,$500 ;range=0..4
+ cal Random ;a=0..4
+ dec a ;a=-1..3
+ dec a ;a=-2..2
+ ld b,a
+ add a,(hl) ;add to spacesize (so +2..-2)
+ cp 10
+ jr c,newground ;>=0 then don't change
+ ld c,a
+ ld a,d
+ add a,b ;new position
+ or a
+ jr z,newground ;may not be 0 (=256)
+ cp -10
+ jr nc,newground ;and not be <0 (>246)
+diffground:
+ ld d,a
+ ld (hl),c
+newground:
+ ld a,d
+ ld (groundpos+15),a ;save new byte on the right
+
+Display_ground:
+ ld b,16 ;screen width
+ ld de,groundpos-1 ;height of current byte (previous actually)
+ psh de ;use later
+ ld hl,GRAPH_MEM+(56*16)-1 ;screen position
+ psh hl
+
+groundloopright:
+ ld c,b ;push b for groundloopup
+ pop hl \ inc hl ;get screen position and go one right
+ pop de \ inc de ;get height info and set to the next byte
+ psh de \ psh hl ;save these for the next time
+ ld a,(de) ;height of current byte
+ ld b,a ;save in b
+
+ ld de,16 ;to substract to go one line up
+ ld a,%11111111 ;bitmask black
+ or a
+groundloopup:
+ ld (hl),a ;display black byte
+ sbc hl,de ;go up (sbc must be used for 16-bit sub)
+ dnz groundloopup ;and loop >groundpos< times
+
+ ld b,c ;pop b used by groundloopup
+ dnz groundloopright ;loop right for entire screen (16x)
+ pop hl \ pop hl ;restore stack
+
+CheckGround: ;check for collision with the ground
+ ld a,(x)
+ srl a
+ srl a
+ srl a
+ inc a
+ ld l,a
+ ld h,0
+ ld de,groundpos
+ add hl,de
+ ld a,(y)
+ sub 57-7
+ neg
+ cp (hl)
+ ret nc
+ ld b,5
+ jp damage_you
+
+;--------------------------- ceiling ----------------------------------------
+
+Handle_ceiling:
+ ld a,(timer)
+ and %111 ;once every 8 frames
+ jr nz,Display_ceiling ;otherwise skip the scroll
+ ld bc,15 ;scroll all 15 bytes (16th is new position)
+ ld hl,ceilingpos+1 ;from..
+ ld de,ceilingpos ;to (one byte to the left)
+ ldir ;LoaDIncreaseRepeat = scroll!
+
+ ld a,(groundinfo) ;what kind of ceiling
+ dec a ;type 1:
+ jr z,ceiling_tunnel ;tunnel effect
+ceiling_boring:
+
+ceiling_tunnel:
+ ld a,(ceilingpos+14)
+ ld d,a ;d=new ceiling
+ ld hl,spacespace
+
+ ld bc,$201 ;range=1..3
+ cal Random ;a=1-3
+ dec a
+ jr z,newceiling ;1:same
+ dec a
+ jr z,ctunnelup ;2:up
+ctunneldown: ;3:down
+ ld a,(hl)
+ or a ;(spacespace)=0:
+ jr z,newceiling+2 ;keep same ceiling
+ inc (hl)
+ inc d
+ jr newceiling
+ctunnelup:
+ ld a,1
+ cp d ;if size=1 then don't
+ jr z,newceiling
+ dec d
+ dec (hl)
+newceiling:
+ ld a,d
+ ld (ceilingpos+15),a ;save the new byte
+
+Display_ceiling:
+ ld b,16 ;screen width
+ ld de,ceilingpos-1 ;height of current byte
+ psh de ;use later
+ ld hl,GRAPH_MEM-17 ;screen position
+ psh hl
+
+ceilingloopright:
+ ld c,b ;push b for groundloopup
+ pop hl \ inc hl ;get screen position and go one right
+ pop de \ inc de ;get height info and set to the next byte
+ psh de \ psh hl ;save these for the next time
+ ld a,(de) ;height of current byte
+ ld b,a ;save in b
+
+ ld de,16 ;to substract to go one line up
+ ld a,%11111111 ;bitmask black
+ or a
+ceilingloopdown:
+ ld (hl),a ;display black byte
+ add hl,de ;go down
+ dnz ceilingloopdown ;and loop >groundpos< times
+
+ ld b,c ;pop b used by groundloopup
+ dnz ceilingloopright ;loop right for entire screen (16x)
+ pop hl \ pop hl ;restore stack
+
+CheckCeiling: ;check for collision with the ground
+ ld a,(x) ;your x
+ srl a ;x/2
+ srl a ;x/4
+ srl a ;x/8 (current ceiling-byte)
+ inc a ;correction
+
+ ld l,a ;hl = a
+ ld h,0 ;"
+ ld de,ceilingpos ;first ceiling-byte
+ add hl,de ;current ceiling-byte
+ ld a,(y) ;your y-pos
+ inc a
+ cp (hl) ;compare with ceiling
+ ret nc ;carry if ceiling is above you
+ ld b,5
+ jp damage_you ;otherwise you don't wanna be in that ship
+
+;--------------------------- move stars -------------------------------------
+
+DisplayStars: ;inputs: hl=starx# a=stars# b=nrstars#
+ ld e,(hl)