upto 4 simultaneous multiples
[nemesis.git] / nemesis.z80
1 ;----------------------------------------------------------------------------
2 ;---------------------- NEMESIS ---------------------------------------------
3 ;----------------------------------------------------------------------------
4
5 ;by SHIAR | shiar0@hotmail.com | icq#43840958 | www.shiar.org
6
7 ;Description           : cool arcade-shoot-em-up-game
8 ;Other games by author : Worm
9 ;This source should only be used for learning practises, do not
10 ;alter it, and certainly do not distribute an altered version!!
11
12 ;&&& marks uncertainties or things to optimize
13
14 ;---------------------- nemesis.z80 start -----------------------------------
15
16 #include        "asm86.h"
17 #include        "ti86asm.inc"   ;standard ti86 romcalls
18 #include        "ti86abs.inc"   ;used to save hiscores and so
19
20         .org _asm_exec_ram
21
22 #define           cal   call    ;just to make it harder for you to understand
23 #define           psh   push    ; ^:D
24 #define           dnz   djnz    ;Dec&Jump while NonZero becomes Do w.Non-Zero
25
26 dispbuffer      = $81FA ;= $C9FA                ;virtual screen
27 ;VIDEO_MEM      = $FC00         ;tha big scareen
28 TEXT_MEM        = _textShadow   ;text buffer; C0F9-C1A0 (167/$A7 bytes)
29
30 _clrWindow      = $4a86         ;_clrLCD and _clrScrn
31 _ex_ahl_bde     = $45f3         ;exchange values between AHL and BDE
32 _shracc         = $4383         ;like _shlacc but just the opposite :P
33 _dispahl        = $4a33         ;display value in ahl <100000 (cheap TI)
34 _asapvar        = $d6fc         ;our own variable name (likely "nemesis")
35
36 storepos        = _asm_exec_ram+7000            ;120 OF 165
37 storepos2       = _asm_exec_ram+7200            ;141 OF 167 9000 BYTES
38
39 ;---------------------- in-game vars ----------------------------------------
40
41 just_fired      = storepos              ; +0    ;counts how long a blast lasts
42 menuitem        = storepos              ; +0    ;used to store menu location
43 hiscorepos      = storepos              ; +0    ;entering hiscore name
44                                         ;       ;--------YOU
45 x               = storepos+1            ; +1    ;your ship's position
46 y               = x+1                   ; +2    ;your y-pos
47 firex           = y+1                   ; +3    ;(1 byte)
48 firey           = firex+1               ; +4    ;(1 byte)
49                                         ;       ;--------LEVEL
50 eventleft       = storepos+5            ; +5    ;nr. of enemies still to come
51 nextevent       = eventleft+1           ; +6    ;time to next event
52 level_enemy     = nextevent+1           ; +7    ;enemy type
53 level_info      = level_enemy+1         ; +8    ;info (see below)
54 level_move      = level_info+1          ; +9    ;=
55                                         ;       ;--------OBJECTS
56 spacespace      = storepos+19           ;+19
57 groundinfo      = spacespace+1          ;+20
58 groundpos       = groundinfo+1          ;+21    $10
59 ceilingpos      = groundpos+16          ;+37    $10
60                                         ;       ;--------STARS
61 stars1          = ceilingpos+16         ;+53
62 stars2          = stars1+1              ;+54
63 nrstars1        = 7
64 starx1          = storepos+55           ;+55
65 nrstars2        = 7
66 starx2          = starx1+(nrstars1*2)   ;+69
67                                         ;       ;--------MULTIPLES
68 your_prevpos    = starx2+(nrstars2*2)   ;+87    ;save previous positions (32d)
69 mm              = 4
70
71 ;^-----------------------------------<1 ;-120=$78
72
73 enemies         = storepos2             ;  +0   ;info about each enemy
74 enemysize       = 9                             ;infobytes per enemy
75 nrenemies       = 16                            ;max. nr of enemies
76
77 ybullets        = enemies+(nrenemies*enemysize) ;60 bytes = 20(state,damg,x,y)
78 nrybuls         = 64                    ; +80\
79 ebullets        = ybullets+(nrybuls*4)  ;+110   ;30 bytes = 10(state,x,y)
80 nrebuls         = 16
81 lvlenemies      = ebullets+(nrebuls*3)
82
83 ;^-----------------------------------<2 ;-141=$8D
84 ;level_info:
85 ;       [0000:damage 0:diagfire 0:ground 0:ceiling 0:-]
86 ;enemies:
87 ;       [HP64] [000000:HP left 00:(00=no enemy 01=exploding 10=normal 11=moving)]
88 ;       [ship type or explosion frame] [x] [y] [movetype] [movecounter] [firecounter] [firefreq]
89
90 ;---------------------- introduction ----------------------------------------
91
92          nop                    ;hello yas/ase/rascall/whathever
93          jp init                ;here's the program, but first: a description
94         .dw $0001               ;description type 2 (description + YASicon)
95         .dw Title               ;pointer to description (all shells)
96         .dw Icon                ;pointer to YAS icon
97
98 Title:  .db "Nemesis v0.98 by SHIAR",0
99
100 Icon:   .db 8,1                 ;icon for YAS: width = 1byte; height = 9bytes
101         .db %11100000           ; ███
102         .db %01111000           ;  ████
103         .db %00111110           ;   █████
104         .db %01111001           ;  ████  █
105         .db %00111110           ;   █████
106         .db %01111000           ;  ████
107         .db %11100000           ; ███             ;recommend 80x50 screen mode
108         .DB 0   ;clear stupid YAS-line
109
110 ;---------------------- init ------------------------------------------------
111
112 int_handler:                    ;new interrupt proc
113         ex  af,af'              ;just af only (no need for exx)
114         in  a,($03)             ;read bit 3 port 3
115         bit 3,a                 ;is ON key pressed?
116         jp  z,$0039             ;no: np, return
117         res 0,a                 ;yes: then we have a problem (freeze), so...
118         out ($03),a             ;...mask the ON key interrupts!
119         jp  $0039               ;all done, return
120 int_end:
121
122 init:   cal BUSY_OFF            ;turns the run-indicator off, obviously
123         cal _clrScrn            ;clean the screen
124         xor a                   ;ld a,0
125         res 2,(iy+13)           ;don't scroll the screen
126         cal _flushallmenus      ;remove TI menus
127
128 FixKeys:                        ;fixes some key problems like left+down bug
129         im  1
130         ld  a,$D4
131         ld  bc,$0100
132         ld  h,a
133         ld  l,c                 ;ld hl,$D400
134         ld  d,a
135         ld  e,b                 ;ld de,$D401
136         dec a                   ;ld a,$D3
137         ld  (hl),a
138         ldir
139         ld  hl,int_handler      ;new interrupt handler
140         ld  d,a
141         ld  e,a                 ;ld de,$D3D3
142         ld  bc,int_end-int_handler
143         ldir
144         inc a                   ;ld a,$D4
145         ld  i,a
146         im  2
147
148 ;---------------------- main menu -------------------------------------------
149
150 LogoPut:
151         xor a                   ;white bitmask (a=0)
152         ld  hl,logo_nemesis     ;from...
153         ld  de,VIDEO_MEM+16     ;...to one line from top
154         ld  b,e                 ;ld b,16: one line
155 AboveLogo:
156         ld  (de),a              ;clear/n byte
157         inc de                  ;next
158         dnz AboveLogo           ;repeat for the first line
159         ld  bc,16*19            ;logo size
160         ldir                    ;display one line of logo
161
162         ld  hl,16*$33+VIDEO_MEM ;$33 rows down
163         ld  b,16*7              ;draw black 7 lines
164         ld  a,%11111111         ;horizontal line mask
165 underline:
166         ld  (hl),a              ;draw one piece of the divider-line
167         inc hl                  ;move right (8 pixels = 1 byte)
168         dnz underline           ;repeat
169
170         ld  hl,_txt_email       ;at the very bottom of tha screen
171         ld  (_penCol),hl
172         ld  hl,txt_email        ;hey, my e-mail address so SEND ME SOMETHING!!
173         cal _vputs              ;VERY important, so display in small font ?:}
174
175         set 3,(iy+5)            ;set white on black
176         ld  de,_txt_about       ;near the bottom of the screen
177         ld  (_penCol),de        ;hl=txt_email++=txt_about
178         cal _vputs              ;display version + me
179         res 3,(iy+5)            ;return to default black on white
180
181 dispmenu:
182         ld  de,$0304
183         ld  (_curRow),de
184         ld  hl,txt_menu1
185         cal _puts
186         ld  de,$0305
187         ld  (_curRow),de
188         ld  hl,txt_menu2
189         cal _puts
190
191         xor a
192         ld  (menuitem),a
193
194 menuloop:
195         ld  a,(menuitem)
196         ld  h,$01
197         add a,4
198         ld  l,a
199
200         ld  a,5
201         ld  (_curRow),hl
202         cal _putc
203
204         ld  a,(menuitem)
205         ld  h,$01
206         sub 5
207         neg
208         ld  l,a
209
210         ld  a,32
211         ld  (_curRow),hl
212         cal _putc
213
214         halt \ halt
215
216         cal GET_KEY             ;wait for keypress
217         cp  K_UP
218         jr  z,menuchange
219         cp  K_DOWN
220         jr  z,menuchange
221         cp  K_EXIT
222         jr  z,menuexit
223         cp  K_F1
224         cal z,do_invert
225         cp  K_SECOND
226         jr  z,start_tha_freakin_game
227         cp  K_ENTER
228         jr  nz,menuloop
229 start_tha_freakin_game:
230
231         ld  a,(menuitem)
232         dec a
233         cal nz,New_game         ;NEW GAME
234         jp  samelevel           ;CONTINUE: game_main_loop
235
236 menuexit:
237         ld  hl,0
238         ld  (your_score),hl
239         jp  game_over
240
241 menuchange:
242         ld  a,(menuitem)
243         xor 1
244         ld  (menuitem),a
245         jr  menuloop
246
247 do_invert:                      ;invert screen (b<>w); destr:b
248         psh hl
249         ld  b,a                 ;psh a
250         ld  hl,_invert
251         ld  a,$98
252         xor (hl)                ;$2F (cpl) <-> $B7 (or a)
253         ld  (hl),a
254         ld  a,b                 ;pop a
255         pop hl
256         ret
257
258 ;----------------------------------------------------------------------------
259 ;---------------------- game loop -------------------------------------------
260 ;----------------------------------------------------------------------------
261
262 game_main_loop:                 ;REPEATS FROM HERE EVERY FRAME
263         ld  hl,timer            ;update time
264         inc (hl)                ;increase by 1
265         ld  a,(hl)
266         and %11111
267         ld  hl,1                ;once every 32 frames, increase score by 1
268         cal z,scoreInc          ;do it
269
270 Clear_screen:
271         ld  hl,dispbuffer       ;move from (hl) = top left
272         ld  (hl),$00            ;first pixel will be copied all over the screen
273         ld  de,dispbuffer+1     ;(de) = next pixel, thus clearing whole screen
274         ld  bc,896              ;loop 896 times = (128/8) * (64-8 for scorebar)
275         ldir                    ;all clear!
276
277         ld  a,0                 ;current frame/turn 0-255
278 timer =$-1
279         and %11                 ;a=0 once every 4 turns
280         jr  z,movestarsdone     ;don't move stars once every 4 frames
281         cal movestars1          ;move the stars on the FRONT layer
282         cal movestars2          ;move the distant stars
283 movestarsdone:
284         ld  a,(stars1)          ;star positions (the missing byte...)
285         ld  b,nrstars1          ;how many stars? now we know.
286         ld  hl,starx1           ;points to the position of the stars
287         cal DisplayStars        ;display front layer stars
288         ld  a,(stars2)          ;weren't you paying attention five lines ago?
289         ld  b,nrstars2          ;that many?! whow!
290         ld  hl,starx2           ;and there they are
291         cal DisplayStars        ;use the same procedure to display back layer
292
293         ld  a,(level_info)      ;level info
294         and %00000110           ;isolate ground&ceiling
295         jr  z,game_stuff        ;both non-present
296         and %00000010           ;bit representing the presence of any ceiling
297         cal nz,Handle_ceiling   ;scroll the ceiling (if any) +check4collision
298         cal Handle_ground       ;scroll the ground and check if we're dead
299
300 game_stuff:
301         cal Handle_Ship         ;move you
302         ld  a,(your_occ)        ;are you 100% OK?
303         or  a                   ;a=0??
304         jr  nz,_gamestuff1      ;then don't check for movements/fires/...
305
306 check_keys:
307         ld  a,%10111111         ;function keys (MORE,EXIT,2ND,F1,F2,F3,F4,F5)
308         out (1),a               ;ask for them
309         nop \ nop               ;delay 8 clocks
310         in  a,(1)               ;gettem!
311
312 check_exitkey:
313         bit 6,a                 ;test bit 6 = exit-key = EXIT
314         jp  z,game_over         ;<exit> pressed, so be it
315 check_morekey:                  ;another unused label... poor compiler
316         bit 7,a                 ;test bit 7 = more-key = PAUSE
317         cal z,Pause             ;yes, go to pause
318
319 check_firekey:
320         bit 5,a                 ;test bit 5 = 2nd-key = FIRE
321         ld  hl,check_selkey     ;where to continue after executing Fire_bullet
322         psh hl                  ;push hl on stack (instead of cal Fire_bullet)
323         jp  z,Fire_bullet       ;fire smtn (bulletstaillasermultiples+stuff..)
324         pop hl                  ;no cal to Fire_bullet made, so pop stack
325         xor a                   ;no:
326         ld  (just_fired),a      ;reset just_fired
327
328 check_selkey:
329         ld  a,%01011111         ;look at first column of keys (ALPHA to STO)
330         out (1),a               ;gimme
331         nop \ nop               ;what's taking you so long
332         in  a,(1)               ;at last... our precious keyzzz...
333
334         bit 6,a                 ;'bout the GRAPH key...
335         cal z,Teacher           ;you didn't _press_ it, did you?!?
336
337         rla                     ;test bit7 so we know f ALPHA has been pressed
338         cal nc,select           ;yeppy, select the currently selected upgrade
339
340         cal Enemies_hit         ;check for collision with enemies
341         cal inc_weapdamage
342
343 _gamestuff1:
344         cal Handle_enemies      ;move enemies
345
346         cal Handle_bullets      ;move your bullets + check for hits
347         cal Enemy_bullets       ;move enemy bullets
348
349         cal Level_event         ;insert enemies
350         cal Display_Screen      ;display all
351
352  ld  b,1
353 ___:
354         halt                    ;delay
355  dnz ___
356         jp  game_main_loop      ;LOOP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
357
358 inc_weapdamage:
359         ld  a,0
360 weapincs =$-1
361         inc a
362         cp  97                  ;max. 96 times (=96/16=6 increases)
363         ret nc                  ;return if already maxed
364         ld  (weapincs),a        ;save new incs
365
366         and %11110000           ;clear last 4 bits so no cf when rotating
367                                 ;btw: AND resets cf
368         rra                     ;rotate acting as shift (srl a) but just 1B
369         rra
370         rra
371         rra                     ;increase once just every 16 turns
372         ld  b,a                 ;times to increase
373 incthedamage:
374         add  a,1                ;increase damage for one increase
375 weapdaminc =$-1
376         dnz incthedamage        ;a=total increase damage
377         ld  b,1                 ;minimal damage
378 weapdamage =$-1
379         add a,b                 ;a=total damage
380         ld  (curweapdamage),a   ;safe the current damage
381         cal disp_charge
382         ret
383
384 ;--------------------------- ground -----------------------------------------
385
386 Handle_ground:
387         ld  a,(timer)
388         and %111                ;once every 8 frames
389         jr  nz,Display_ground   ;otherwise skip the scroll
390         ld  bc,15               ;scroll all 16 bytes minus one (teh new byte)
391         ld  hl,groundpos+1      ;from..
392         ld  de,groundpos        ;to (one byte to the left)
393         ldir                    ;LoaDIncreaseRepeat = scroll!
394
395         ld  a,(groundinfo)      ;what kind of ground
396         dec a                   ;type 1:
397         jr  z,ground_tunnel     ;tunnel effect
398 ground_boring:
399         ld  a,(groundpos)       ;type 0
400         jr  newground+1
401
402 ground_tunnel:
403         ld  a,(groundpos+14)
404         ld  d,a
405         ld  hl,spacespace
406         ld  bc,$500             ;range=0..4
407         cal Random              ;a=0..4
408         dec a                   ;a=-1..3
409         dec a                   ;a=-2..2
410         ld  b,a
411         add a,(hl)              ;add to spacesize (so +2..-2)
412         cp  10
413         jr  c,newground         ;>=0 then don't change
414         ld  c,a
415         ld  a,d
416         add a,b                 ;new position
417         or  a
418         jr  z,newground         ;may not be 0 (=256)
419         cp  -10
420         jr  nc,newground        ;and not be <0 (>246)
421 diffground:
422         ld  d,a
423         ld  (hl),c
424 newground:
425         ld  a,d
426         ld  (groundpos+15),a    ;save new byte on the right
427
428 Display_ground:
429         ld  b,16                ;screen width
430         ld  de,groundpos-1      ;height of current byte (previous actually)
431         psh de                  ;use later
432         ld  hl,dispbuffer+(56*16)-1 ;screen position
433         psh hl
434
435 groundloopright:
436         ld  c,b                 ;push b for groundloopup
437         pop hl \ inc hl         ;get screen position and go one right
438         pop de \ inc de         ;get height info and set to the next byte
439         psh de \ psh hl         ;save these for the next time
440         ld  a,(de)              ;height of current byte
441         ld  b,a                 ;save in b
442
443         ld  de,16               ;to substract to go one line up
444         ld  a,%11111111         ;bitmask black
445         or  a
446 groundloopup:
447         ld  (hl),a              ;display black byte
448         sbc hl,de               ;go up (sbc must be used for 16-bit sub)
449         dnz groundloopup        ;and loop >groundpos< times
450
451         ld  b,c                 ;pop b used by groundloopup
452         dnz groundloopright     ;loop right for entire screen (16x)
453         pop hl \ pop hl         ;restore stack
454
455 CheckGround:                    ;check for collision with the ground
456         ld  a,(x)
457         srl a
458         srl a
459         srl a
460         inc a
461         ld  l,a
462         ld  h,0
463         ld  de,groundpos
464         add hl,de
465         ld  a,(y)
466         sub 57-7
467         neg
468         cp  (hl)
469         ret nc
470         ld  b,5
471         jp  damage_you
472
473 ;--------------------------- ceiling ----------------------------------------
474
475 Handle_ceiling:
476         ld  a,(timer)
477         and %111                ;once every 8 frames
478         jr  nz,Display_ceiling  ;otherwise skip the scroll
479         ld  bc,15               ;scroll all 15 bytes (16th is new position)
480         ld  hl,ceilingpos+1     ;from..
481         ld  de,ceilingpos       ;to (one byte to the left)
482         ldir                    ;LoaDIncreaseRepeat = scroll!
483
484         ld  a,(groundinfo)      ;what kind of ceiling
485         dec a                   ;type 1:
486         jr  z,ceiling_tunnel    ;tunnel effect
487 ceiling_boring:
488
489 ceiling_tunnel:
490         ld  a,(ceilingpos+14)
491         ld  d,a                 ;d=new ceiling
492         ld  hl,spacespace
493
494         ld  bc,$201             ;range=1..3
495         cal Random              ;a=1-3
496         dec a
497         jr  z,newceiling        ;1:same
498         dec a
499         jr  z,ctunnelup         ;2:up
500 ctunneldown:                    ;3:down
501         ld  a,(hl)
502         or  a                   ;(spacespace)=0:
503         jr  z,newceiling+2      ;keep same ceiling
504         inc (hl)
505         inc d
506         jr  newceiling
507 ctunnelup:
508         ld  a,1
509         cp  d                   ;if size=1 then don't
510         jr  z,newceiling
511         dec d
512         dec (hl)
513 newceiling:
514         ld  a,d
515         ld  (ceilingpos+15),a   ;save the new byte
516
517 Display_ceiling:
518         ld  b,16                ;screen width
519         ld  de,ceilingpos-1     ;height of current byte
520         psh de                  ;use later
521         ld  hl,dispbuffer-17    ;screen position
522         psh hl
523
524 ceilingloopright:
525         ld  c,b                 ;push b for groundloopup
526         pop hl \ inc hl         ;get screen position and go one right
527         pop de \ inc de         ;get height info and set to the next byte
528         psh de \ psh hl         ;save these for the next time
529         ld  a,(de)              ;height of current byte
530         ld  b,a                 ;save in b
531
532         ld  de,16               ;to substract to go one line up
533         ld  a,%11111111         ;bitmask black
534         or  a
535 ceilingloopdown:
536         ld  (hl),a              ;display black byte
537         add hl,de               ;go down
538         dnz ceilingloopdown     ;and loop >groundpos< times
539
540         ld  b,c                 ;pop b used by groundloopup
541         dnz ceilingloopright    ;loop right for entire screen (16x)
542         pop hl \ pop hl         ;restore stack
543
544 CheckCeiling:                   ;check for collision with the ground
545         ld  a,(x)               ;your x
546         srl a                   ;x/2
547         srl a                   ;x/4
548         srl a                   ;x/8 (current ceiling-byte)
549         inc a                   ;correction
550
551         ld  l,a                 ;hl = a
552         ld  h,0                 ;"
553         ld  de,ceilingpos       ;first ceiling-byte
554         add hl,de               ;current ceiling-byte
555         ld  a,(y)               ;your y-pos
556         inc a
557         cp  (hl)                ;compare with ceiling
558         ret nc                  ;carry if ceiling is above you
559         ld  b,5
560         jp  damage_you          ;otherwise you don't wanna be in that ship
561
562 ;--------------------------- move stars -------------------------------------
563
564 DisplayStars:                   ;inputs: hl=starx# a=stars# b=nrstars#
565         ld  e,(hl)
566         inc hl
567         ld  d,(hl)
568         ld  (de),a
569         inc hl
570         dnz DisplayStars
571         ret                     ;let's comment this: returns
572
573 movestars2:
574         ld  ix,starx2
575         ld  a,(stars2)
576         rlca
577         ld  (stars2),a
578         ret nc
579         ld  b,nrstars2
580         jr  movestars_loop
581
582 movestars1:
583         ld  ix,starx1
584         ld  a,(timer)
585         rra
586         ld  a,(stars1)
587         ret c
588         rlca
589         ld  (stars1),a
590         ret nc
591         ld  b,nrstars1
592
593 movestars_loop:
594         ld  h,(ix+1)
595         ld  l,(ix)
596         dec hl
597
598         ld  a,l
599         and %00001111
600         cp  9                   ;(GRAPH_MEM&%00001111)-- = $C9FAand15-1 = $A-1
601         jr  nz,newstarok
602         cal RandomY
603
604 newstarok:
605         ld  (ix),l
606         ld  (ix+1),h
607         inc ix \ inc ix
608         dnz movestars_loop
609         ret                     ;for stupid people, here's another comment...
610
611 ;--------------------------- pause ------------------------------------------
612
613 Pause:
614         psh af
615         ld  hl,$0200            ;top left
616         ld  (_curRow),hl
617         ld  hl,txt_pressenter   ;"Enter to continue"
618         cal _puts               ;display message
619 pause:
620         cal _getkey             ;enter low-power mode and wait for key
621         cp  kEnter              ;keypressed = enter?
622         jr  nz,pause            ;no, wait some more
623         pop af
624         ret                     ;continue
625
626 ;--------------------------- teacher ----------------------------------------
627
628 Teacher:
629         ld  (iy+12),5           ;enable flashing cursor
630         cal _clrWindow          ;top left
631         ld  hl,txt_teacher
632         cal _puts               ;display message
633         cal releasekeys
634
635 teacherloop:
636         cal _getkey             ;enter low-power mode and wait for key
637         cp  kEnter              ;enter pressed?
638         jr  z,teacherans
639         cp  kGrMenu             ;keypressed = graph?
640         jr  nz,teacherloop      ;no, wait some more
641
642         ld  (iy+12),0           ;disable cursor
643         cal releasekeys
644         jp  disp_icons          ;+ret
645
646 teacherans:
647         ld  a,' '
648         cal _putc
649
650         ld  hl,$0701
651         ld  (_curRow),hl
652         ld  hl,txt_teacherans
653         cal _puts
654         jr  teacherloop
655
656
657 ;--------------------------- exit -------------------------------------------
658
659 quit:   im  1                   ;release keyfix procedure
660         set 2,(iy+13)           ;set back screen scrolling
661         xor a
662         ld (_asapvar+1),a       ;next Asm( run will reload the program
663         ld  hl,dispbuffer       ;graph-screen location
664         ld  de,dispbuffer+1
665         ld  (hl),a
666         ld  bc,1024-1           ;do it 1024 times = entire screen
667         ldir
668         jp  _clrWindow          ;as _clrLCD but also clears TEXT_MEM (like the
669                                 ;_clrScrn) AND also executes _homeup and ret
670
671 ;--------------------------- display ----------------------------------------
672
673 Display_Screen:
674         ld  hl,dispbuffer       ;from buffer (top left)
675         ld  de,VIDEO_MEM        ;to real screen (top left)
676         ld  c,56                ;display height = 64 bytes (minus 8 for bar)
677 displayloop:
678         ld  b,16                ;display width = 16 bytes (16*8bits=256pixels)
679 displaytloop:
680         ld  a,(hl)              ;copy byte from (hl)
681 _invert:                        ;SMC: cpl <-> or a
682         cpl                     ;xor $ff: invert byte (white<=>black)
683         ld  (de),a              ;to (de)
684         inc hl \ inc de         ;next byte
685         dnz displaytloop        ;16x hl >> de
686         dec c                   ;next line
687         jr  nz,displayloop      ;loop 56x
688
689         ld  hl,time2invert
690         ld  a,(hl)
691         or  a                   ;(time2invert)=0:
692         jr  z,noinvert          ; do nothing
693         dec a                   ;otherwise decrease
694         cal z,do_invert         ;if it became 0 then invert
695         ld  (hl),a              ;save new value
696 noinvert:
697
698         ld  hl,$396b            ;Display Score
699         ld  (_penCol),hl        ;bottom right of screen
700         ld  hl,(your_score)
701
702 _D_HL_DECI:                     ;------- display 5-digit value -------
703         ld  de,savestr+4        ;savenr saves number string
704         ld  b,5                 ;five digits
705 ldhld:  cal UNPACK_HL           ;one digit of hl
706         add a,'0'               ;make number
707         ld  (de),a              ;save into savenr
708         dec de                  ;point to next digit
709         dnz ldhld               ;repeat for all digits
710
711         ld  hl,savestr          ;we (the program) saved the value righthere
712         jp  _vputs              ;the only thing left to do is to display it
713
714 savestr:                        ;@here the score will be stored
715         .db "00000",0           ;don't worry, it's just temporary
716
717 ;------------------------- handle ship --------------------------------------
718
719 Handle_Ship:
720         ld  a,(your_occ)        ;are
721         or  a                   ;you
722         jr  z,ok                ;ok?
723
724         inc a                   ;no! next (explosion)frame
725         ld  (your_occ),a        ;save
726
727         cp  64+1                ;last explosion frame? (1-16=1st;49-64=4th)
728         jp  c,exploding_you     ;not yet: display explosion
729         cp  64+16               ;delay finished?
730         jp  z,You_die           ;yes = game over
731         ret                     ;don't display anything
732
733 ;----move----
734 ok:                             ;we are
735         ld  a,%01111110         ;get arrow keys
736         out (1),a               ;it's cold outside
737         ld  hl,y                ;instead of nop\nop do something usefull
738         in  a,(1)               ;come back in
739
740         ld  b,a                 ;psh a (keys)
741         xor -1                  ;inverted a: 0 if arrow-key has been pressed
742         ld  a,(your_multiples)          ;(btw: CPL doesn't set any flags)
743         res 7,a                 ;reset move bit (no flags changed)
744         jr  z,adv_ok            ;if so, leave the multiples where they are
745         set 7,a                 ;set move bit
746 adv_ok: ld  (your_multiples),a
747
748         ld  a,(timer)           ;framecounter
749         and %1                  ;switches 0<>1 each frame
750         inc a                   ;a = 1 or 2 (1.5 avg)
751         ld  c,a                 ;c = your_speed
752
753         ld  a,b                 ;pop a (keys)
754         rra                     ;rotate right (put last bit in c)
755         ld  b,a                 ;we need a later
756
757         jr  c,no_down
758         ld  a,(hl)
759         add a,c
760         cp  50                  ;56-6 = bottom of screen
761         jr  nc,no_down
762         ld  (hl),a
763 no_down:
764         dec hl
765         rr  b                   ;because we now use b, it's rr instead of rra
766         jr  c,no_left
767         ld  a,(hl)
768         sub c                   ;<dec a> doesn't affect c-flag
769         jr  c,no_left           ;-1 = left side
770         ld  (hl),a
771 no_left:
772         rr  b
773         jr  c,no_right
774         ld  a,(hl)
775         add a,c
776         cp  122                 ;128-6 = right side
777         jr  nc,no_right
778         ld  (hl),a
779 no_right:
780         ld  d,(hl)              ;d=x
781         inc hl
782         rr  b
783         jr  c,no_up
784         ld  a,(hl)
785         sub c                   ;<dec a> doesn't affect carry-flag
786         jr  c,no_up             ;-1 = top of screen
787         ld  (hl),a              ;save new y
788
789 no_up:  ld  e,(hl)              ;e=y
790         ld  ix,spr_ship01       ;normal ship sprite
791 your_shipspr =$-2
792         ld  hl,your_inv         ;invulnerable?
793         ld  a,(hl)              ;load time in a
794         or  a                   ;is it 0?
795         jr  z,disp_ship         ;yes so ship = normal (display \ continue)
796
797         ld  a,(timer)           ;load frame nr.
798         and %00000111           ;a=0 once every four frames
799         jr  nz,not_time         ;a<>0 = not time to update counter
800         dec (hl)                ;decrease inv-time left
801 not_time:
802         and %00000100           ;a switches 0<->1 every 2 frames
803         jr  z,disp_ship         ;show normal ship
804 inv_flicker:
805         ld  bc,spr_ship01i-spr_ship01
806         add ix,bc               ;display invulnerable ship
807 disp_ship:
808         cal safeputsprite       ;display your ship; save de
809
810 ;----multiples----
811
812 handle_multiples:
813         ld  a,(your_multiples)  ;do you have multiples
814         ld  b,a                 ;save a for 2nd check
815         and %111                ;no? (last two bits = nr of multiples)
816         ret z                   ;then don't handle them either
817         bit 7,b                 ;move the multiples??? (=move bit set?)
818         jr  z,mult_adv          ;nope, just let them (saves (y)in y, (x)in x)
819
820         psh de                  ;current position = needed later
821         ld  hl,mm*14+1+your_prevpos     ;previous positions
822         ld  de,mm*14+3+your_prevpos     ;move all positions one back
823         ld  bc,mm*14+2
824         lddr                    ;change 0-57 -> 2-59 (if mm=4 that is)
825         inc hl                  ;your_prevpos+0
826         pop de
827         ld  (hl),d              ;x-pos
828         inc hl                  ;=current position
829         ld  (hl),e              ;y-pos
830
831 mult_adv:
832         ld  hl,your_prevpos+16  ;first pos.
833 disp_multiples:
834         psh af
835         psh hl
836         ld  d,(hl)              ;load coords
837         inc hl
838         ld  e,(hl)
839         ld  ix,spr_multiple     ;sprite
840         cal putsprite           ;display
841         pop hl
842         ld  de,14
843         add hl,de               ;next multiple
844         pop af                  ;counter
845         dec a
846         ret z                   ;return if all done
847         jr  disp_multiples      ;loop
848
849 ;----explode----
850
851 exploding_you:
852         srl a                   ;half the framerate
853         srl a                   ;half that framerate
854         srl a                   ;and half again that framerate
855         ld  hl,x-1
856         ld  ix,spr_yexplosion   ;base sprite
857
858 explosion_stuff:                ;in:a=frame*2+(0 to 1); (hl)=xpos-- ix=sprite
859         and %11111110
860         add a,a
861         add a,a                 ;frame*8
862         ld  c,a
863         ld  b,0                 ;bc=a
864         add ix,bc               ;go to correct sprite (each spr. is 8 bytes)
865         inc hl
866         ld  d,(hl)              ;load xpos
867         inc hl
868         ld  e,(hl)              ;and y
869         jp  putsprite           ;and display it too
870
871 ;----hit----
872
873 damage_you:                     ;damages you B points
874         ld  a,(your_inv)        ;shield left?
875         or  a
876         jr  z,dothadamage       ;no shield
877         srl b                   ;shield: half the damage
878 dothadamage:
879         ld  hl,time2invert
880         xor a                   ;a=0
881         cp  (hl)                ;no already inverted?
882         cal z,do_invert         ;then invert screen
883         ld  a,2
884         ld  (hl),a              ;change back 2 frames from now
885
886         ld  hl,your_armor       ;armor left
887         ld  a,(hl)              ;load hp in A
888         sub b                   ;decrease hp by B
889         jp  m,no_armor          ;<0hp left so explode
890         ld  (hl),a              ;no, so save decreased hp
891         jp  disp_armor          ;and display new value
892 no_armor:
893         ld  a,%01               ;occ %xxxxxx01 = explode
894         ld  (your_occ),a        ;too bad, you're dead meat
895         ret
896
897 ;------------------------- place multiples ----------------------------------
898
899 Place_multiples:
900         ld  hl,your_prevpos     ;place all previous positions
901         ld  b,mm*7+2            ;all saved positions of them (14 per multiple)
902 place_multiples:
903         ld  (hl),e              ;set prev-x to d
904         inc hl                  ;next
905         ld  (hl),d              ;set prev-y to e
906         inc hl                  ;next
907         dnz place_multiples     ;repeat
908         ret
909
910 ;------------------------- select upgrade -----------------------------------
911
912 inc_armor:
913         ld  a,(your_armor)      ;load current armor
914         cp  25-6                ;may not become >=25
915         jr  c,doincarmor        ;ok then just add 6
916         ld  a,24-6              ;set to maximum (6 will be added below)
917 doincarmor:
918         add a,6                 ;add 6 to armor
919         ld  (your_armor),a      ;change armor
920         ret
921
922 select:
923         ld  hl,your_pickup      ;select pickups
924         ld  a,(hl)              ;load pickups taken so far
925         dec a                   ;is it 1?
926         ret m                   ;return if it's 0 (no pickups)
927         jr  nz,select2          ;no, carry on
928 select1:
929         ld  (hl),a              ;reset pickups
930         cal inc_armor
931         jp  disp_icons          ;display and return
932 select2:
933         dec a                   ;is it 2?
934         jr  nz,select3          ;no, carry on
935         ld  (hl),a              ;reset pickups
936         inc a                   ;a=1
937         ld  (your_tail),a       ;ready tail beam
938         jp  disp_icons          ;display 'n return
939 select3:
940         dec a                   ;is it 3?
941         jr  nz,select4          ;no, carry on
942         ld  (hl),a              ;reset pickups
943         ld  hl,your_weapon
944         ld  a,(hl)
945         inc a
946         cp  maxweapon
947         jp  nc,disp_icons       ;weapon maxed out
948         ld  (hl),a              ;set new weapon
949         cal loadweapon          ;load it (damage and stuff)
950         jp  disp_icons          ;display n return
951 select4:
952         dec a                   ;is it 4?
953         jr  nz,select5          ;no, carry on again
954         ld  (hl),a              ;reset pickups
955         ld  hl,your_weapon
956         ld  a,(hl)
957         cp  maxweapon           ;upgrade from bullet
958         jr  nc,upgradelaser     ;nope, just upgrade
959         ld  a,maxweapon-1       ;yes, set laser #1
960 upgradelaser:
961         inc a                   ;next laser
962         cp  maxlaser
963         jp  nc,disp_icons       ;laser maxed out
964         ld  (hl),a
965         cal loadweapon
966         jp  disp_icons          ;display + return
967 select5:
968         dec a                   ;is it 5?
969         jr  nz,select6          ;no, carry on once more
970         ld  (hl),a              ;reset pickups
971         ld  hl,your_multiples
972         ld  a,(hl)              ;multiples you already got
973         inc a                   ;one more
974         cp  mm+1
975         jr  nc,enoughmultiples  ;maxed out
976         ld  (hl),a
977 enoughmultiples:
978         ld  de,(x)
979         dec a                   ;if this is your first multiple then...
980         cal z,Place_multiples   ;reset multiples positions
981         jp  disp_icons          ;display, return
982 select6:
983         ld  (hl),0              ;reset pickups
984         jp  disp_icons          ;display/return
985
986 ;------------------------- fire bullet --------------------------------------
987
988 fire_multiples:
989         ld  hl,(your_prevpos+16);then, fire from multiple position
990         psh af
991         dec h                   ;one up (-2 height: keeps weapons centered)
992         cal fireany             ;fire from multiple position
993         pop af                  ;number of multiples
994         dec a                   ;one just displayed
995         ret z                   ;return if none left
996         ld  hl,(your_prevpos+30)
997         psh af
998         dec h
999         cal fireany
1000         pop af
1001         dec a
1002         ret z
1003         ld  hl,(your_prevpos+44)
1004         psh af
1005         dec h
1006         cal fireany
1007         pop af
1008         dec a
1009         ret z
1010         ld  hl,(your_prevpos+58)
1011         psh af
1012         dec h
1013         cal fireany
1014         pop af
1015         dec a
1016         ret
1017
1018 Fire_bullet:
1019         ld  hl,just_fired
1020         ld  a,(hl)              ;just_fired
1021         cp  5                   ;already pressed?
1022         ret z                   ;return when already pressed (=5)
1023
1024         inc (hl)                ;otherwise increase counter (0 to 4 >> 1 to 5)
1025         ld  a,(your_weapon)     ;if you have bullets.....
1026         cp  maxweapon
1027         jr  nc,fireOK           ;>weapons = laser
1028         ld  (hl),5              ;.....then can't fire next turn (go to 5 imm.)
1029
1030 fireOK:
1031         ld  a,(your_multiples)  ;any multiples?
1032         and %111                ;nr. of multiples
1033         cal nz,fire_multiples   ;if >0 then fire them too
1034         ld  hl,(x)              ;fire from ship position (x)
1035 fireany:                        ;HL=(x,y)
1036         ld  (firex),hl          ;set position to fire from
1037         ld  a,(your_weapon)
1038         ld  ix,weapondata+2-(256*3)
1039         add a,a                 ;weap*2
1040         add a,a                 ;    *4
1041         add a,a                 ;    *8
1042         ld  c,a
1043         ld  b,3                 ;go to current weapon (bc=a), b=3 :P
1044         add ix,bc
1045
1046 fire_weapon:                    ;b=3
1047         psh bc                  ;save counter
1048         ld  a,(ix)              ;load this weapon
1049         cp  %11100000           ;%11110000=laser
1050         cal z,fire_laser        ;fire laser (will set a=0 when done)
1051         or  a                   ;<>0=bullet
1052         cal nz,fire_ybullet
1053         inc ix
1054         inc ix
1055         pop bc                  ;weapon counter (do 3 weapons)
1056         dnz fire_weapon
1057
1058 fire_tail:
1059         ld  hl,your_tail
1060         ld  a,(hl)
1061         dec a
1062         ret nz
1063         ld  a,(ix-2)            ;last weapon fired
1064         cp  %11100000           ;issit laser
1065         ret z                   ;then return
1066         xor %11111              ;smart way of going left instead of right :P
1067         jr  fire_ybullet        ;fire tail bullet and return
1068
1069 ;-----fire LASER-----
1070
1071 fire_laser:
1072         ld  b,0                 ;overflow counter
1073         ld  hl,firex
1074         ld  d,(hl)              ;d = your x-pos
1075         inc hl
1076
1077         ld  a,(hl)              ;base y-coord (firey)
1078         add a,(ix+1)            ;at specified offset (most likely the middle)
1079         ld  e,a                 ;save laser-y in e
1080         psh de                  ;save unmodified (x,y)
1081         add a,a                 ;y*2
1082         add a,a                 ;y*4
1083         add a,a                 ;y*8
1084         rl  b                   ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
1085         add a,a                 ;y*16 (width of screen)
1086         rl  b                   ;b=b*2+overflow (if y>64 then bc=bc+512)
1087         inc a                   ;8 pixels to right (a=even so no overflow)
1088
1089         srl d                   ;X/2
1090         srl d                   ;X/4
1091         srl d                   ;X/8
1092         add a,d                 ;a = (Y*16+X/8) mod 256 (c set on overflow)
1093
1094         jr  nc,_nolc            ;jump if no carry = no overflow = a<=255
1095         inc b                   ;a>255 so increase bc by 256
1096 _nolc:  ld  c,a                 ;c = (Y*16+X/8) mod 256
1097         ld  hl,dispbuffer       ;save-location
1098         add hl,bc               ;bc = Y*16+X/8: hl=screen address
1099         ld  a,15                ;128/8=16=screen width ** minus one (inc a ^^)
1100         sub d                   ;minus x-start (d=X/8)
1101         ld  b,a
1102 drawlaser:
1103         ld  (hl),%11111111
1104         inc hl                  ;Go to next byte
1105         dnz drawlaser
1106 handle_laser:
1107         pop de                  ;de=(firex): x-pos unmodified
1108
1109 check_laserhits:                ;de = (x,y)
1110         psh ix
1111         ld  b,nrenemies         ;check all enemies
1112         ld  hl,enemies+1        ;enemy#1+occ/hp00
1113 laserhits:                      ;hits with normal enemies
1114         psh hl
1115         ld  a,(hl)              ;occ+hp00
1116         and %00000010           ;normal/moving occ.=%1x
1117         jr  z,nolashit          ;no hit when enemy_occ <> 2/3
1118         inc hl                  ;enemy type
1119         ld  a,(hl)
1120         or  a                   ;enemy #0 = pickup
1121         jr  z,nolashit          ;yes: don't destroy
1122
1123         cal find_sprite         ;ix=sprite to enemy (hl)
1124         inc hl
1125         ld  a,(hl)              ;check x
1126         sub d
1127         jp  m,nolashit          ;no hit when enemy is left of you
1128         inc hl
1129         ld  a,(hl)              ;check y
1130         sub e
1131         jr  z,enemy_lashit      ;a-e=0 = laser on top line of enemy = hit
1132         jr  nc,nolashit         ;a-e>0 = enemy above laser = no hit
1133         dec a                   ;minus one
1134         add a,(ix+1)            ;add enemy height (according to sprite @ix)
1135         jp  m,nolashit          ;a-e>0 = hit
1136 enemy_lashit:
1137         ld  a,(curweapdamage)   ;damage
1138         cal enemy_hit           ;hl=enemy+y
1139 nolashit:
1140         pop hl                  ;enemy+1
1141         ld  a,b                 ;psh bc
1142         ld  bc,enemysize
1143         add hl,bc               ;go to next enemy
1144         ld  b,a                 ;pop bc
1145         dnz laserhits           ;check all enemies
1146         xor a                   ;a=0 otherwise weird things might happen :P
1147         ld  (weapincs),a        ;reset damage
1148         pop ix
1149         ret
1150
1151 ;-----fire BULLETs-----
1152
1153 fire_ybullet:           ;fire bullet type=C dam=(curweapdamage) at (firex/y)
1154         ld  c,a                 ;save bulletType in c
1155         ld  hl,ybullets         ;check for unused bullet
1156         ld  de,4
1157         ld  b,nrybuls
1158 find_ybullet:
1159         ld  a,(hl)
1160         or  a
1161         jr  z,found_ybullet     ;0 = no bullet here
1162         add hl,de
1163         dnz find_ybullet        ;look next bullet
1164         ret                     ;none found, return don't fire
1165
1166 found_ybullet:
1167         ld  (hl),c              ;use the bullet and set correct bullet-type
1168         inc hl                  ;@damage
1169         ld  (hl),1              ;set bullet damage
1170 curweapdamage =$-1
1171         ld  a,(firex)           ;your x-pos
1172         add a,5                 ;place bullet in front of you
1173         inc hl                  ;go to bullet-x
1174         ld  (hl),a              ;set x
1175
1176         ld  a,(firey)           ;your y-pos
1177         add a,(ix+1)            ;place bullet at the middle of your ship
1178         inc hl                  ;go to bullet-y
1179         ld  (hl),a              ;set y
1180
1181         xor a
1182         ld  (weapincs),a        ;reset damage
1183         ret
1184
1185 ;------------------------ handle bullets ------------------------------------
1186
1187 bullet_left:
1188         ld  c,a                 ;c=type
1189         and %11111              ;pixels to move
1190         add a,(hl)              ;a = X + (hl) to the right
1191         sub 16                  ;and 16 to the left (so -16..+15)
1192         jr  c,remove_bullet     ;remove if x<0
1193         cp  128
1194         jr  nc,remove_bullet    ;or x>=128
1195         ld  (hl),a              ;save new pos.
1196         ld  d,a                 ;d = X
1197
1198         inc hl                  ;@y-pos
1199         ld  a,c
1200         cal _shracc             ;%11110000->1111
1201         srl a                   ;%1110->111
1202         dec a
1203         jr  z,bullet_noymove    ;1=straight forward
1204         dec a
1205         jr  z,bullet_up         ;2=up
1206         dec a
1207         jr  z,bullet_halfup     ;3=1/2up
1208         dec a
1209         jr  z,bullet_down       ;4=down
1210
1211 bullet_halfdown:                ;5=1/2down
1212         ld  a,(timer)
1213         and 1
1214         jr  z,bullet_noymove
1215 bullet_down:
1216         ld  a,(hl)
1217         inc a
1218         cp  55
1219         jr  z,bullet_noymove
1220         ld  (hl),a
1221 bullet_halfup:
1222         ld  a,(timer)
1223         and 1
1224         jr  z,bullet_noymove
1225 bullet_up:
1226         ld  a,(hl)
1227         dec a
1228         jr  z,bullet_noymove
1229         ld  (hl),a
1230 bullet_noymove:
1231         ld  e,(hl)              ;e = Y
1232         ret
1233
1234 remove_bullet:
1235         pop hl                  ;cal bullet_left
1236         pop hl                  ;enemy+type
1237         ld  (hl),0              ;dump this bullet!
1238         jr  next_ybullet+1      ;+1:skip pop hl at next_ybullet
1239
1240 Handle_bullets:
1241         ld  hl,ybullets
1242         ld  b,nrybuls
1243 scan_bullets:
1244         psh bc                  ;bullet counter
1245         psh hl                  ;save enemy+type
1246         ld  (temp1),hl          ;needed for check_bullethits
1247         ld  a,(hl)              ;@bulletType
1248         inc hl                  ;@damage
1249         inc hl                  ;@x
1250
1251         or  a
1252         jp  z,next_ybullet      ;bulletType=0 >> no bullet
1253         cal bullet_left         ;move bullet left
1254
1255 display_bullet:
1256         psh de                  ;save de =position
1257         dec hl                  ;@x
1258         dec hl                  ;@damage
1259         ld  a,(hl)              ;bullet damage=size
1260         ld  hl,bullettable      ;pointer to first bullet
1261         srl a
1262         srl a                   ;per 4
1263         ld  d,0
1264         ld  e,a                 ;->16bit (de=a)
1265         add hl,de               ;point to correct bullet offset
1266         ld  a,(hl)              ;load bullet offset
1267         ld  e,a                 ;convert to 16bit (d=0)
1268         ld  ix,spr_bullet01     ;first sprite
1269         add ix,de               ;add offset (go to correct sprite)
1270         pop de                  ;saved position
1271
1272         ld  a,(ix)              ;bullet x-size
1273         ld  (bulletxsize),a     ;used at check_bullethits
1274         ld  a,(ix+1)            ;bullet y-size...
1275         ld  (bulletysize),a     ;...too
1276
1277         cal safeputsprite       ;display bullet; DE used for check_bullethits
1278
1279         cal check_bullethits
1280
1281 next_ybullet:
1282         pop hl                  ;restore enemy+type
1283         inc hl
1284         inc hl
1285         inc hl
1286         inc hl                  ;skip type,dam,x,y: next enemy+type
1287         pop bc                  ;b=counter
1288         dnz scan_bullets        ;next bullet (loop)
1289         ret
1290
1291 ;--------------------------- check bullethits -------------------------------
1292
1293 check_bullethits:               ;INPUT: de=X,Y; (temp1)=bullet
1294         ld  b,nrenemies
1295         ld  hl,enemies+1
1296
1297 hit_enemies:                    ;Hits with normal enemies
1298         psh bc                  ;enemy counter
1299         psh hl
1300
1301         ld  a,(hl)
1302         and %00000010
1303         jr  z,nohit             ;no hit when enemy_occ <> 2/3
1304
1305         inc hl                  ;enemy type
1306         ld  a,(hl)
1307         or  a                   ;enemy #0 = pickup
1308         jr  z,nohit             ;yes: don't destroy
1309
1310         cal find_sprite         ;set ix to the sprite of this enemy
1311
1312         inc hl                  ;@x
1313         ld  a,(hl)              ;check x
1314         sub d                   ;minus bullet x-position
1315         ld  b,a                 ;psh a
1316         sub 5                   ;minus bullet x-size
1317 bulletxsize =$-1
1318         jp  p,nohit             ;miss
1319         ld  a,b                 ;pop a
1320         add a,(ix)              ;add enemy width
1321         jp  m,nohit             ;miss
1322
1323         inc hl                  ;@y
1324         ld  a,(hl)              ;check y
1325         sub e                   ;minus bullet y-position
1326         ld  b,a                 ;psh a
1327         sub 3                   ;substract bullet height
1328 bulletysize =$-1
1329         jp  p,nohit             ;nope, missed it
1330         ld  a,b                 ;pop a
1331         add a,(ix+1)            ;add enemy height
1332         dec a                   ;minus one
1333         jp  m,nohit             ;missed after all
1334
1335                                 ;---bullet hits enemy (auch-time!)---
1336         psh hl
1337         ld  hl,0                ;@bulletType
1338 temp1 =$-2
1339         ld  (hl),0              ;remove bullet
1340         inc hl                  ;@damage
1341         ld  a,(hl)              ;set damage
1342         pop hl                  ;enemy+y
1343         cal enemy_hit
1344 nohit:
1345         pop hl
1346         ld  bc,enemysize
1347         add hl,bc
1348         pop bc
1349         dnz hit_enemies         ;check next enemy
1350         ret
1351
1352 enemy_hit:                      ;*in:a=damage;hl=enemy+y
1353         add a,a                 ;a=damage to inflict
1354         add a,a                 ;first 2 bits used for occ.
1355         ld  b,a
1356
1357         dec hl                  ;@x
1358         dec hl                  ;@type
1359         dec hl                  ;@hp00 (occ)
1360         ld  a,(hl)              ;load hp00
1361         sub b                   ;decrease HP (if <0xx then c is set)
1362         ld  (hl),a              ;save (no flag-changes)
1363         dec hl                  ;@hp64; no change in c
1364         ld  a,(hl)              ;load; no c-change
1365         sbc a,0                 ;if cf then decrease a
1366         ld  (hl),a              ;save back the new value
1367         ret nc                  ;if a>=0 then return, otherwise explode
1368
1369         inc hl                  ;goto occ again
1370         ld  (hl),%01            ;set to explode
1371         ld  a,(pickuptimer)     ;counts enemies destroyed
1372         dec a                   ;enough destroyed for a pickup?
1373         jr  nz,pickupdone       ;otherwise just explode
1374         ld  (hl),%110           ;change it into a pickup (with 2 HP)
1375         ld  a,18                ;reset enemies counter (18 hits = next)
1376 pickupdone:
1377         ld  (pickuptimer),a     ;save new enemiescounter value
1378         inc hl
1379         ld  (hl),$00            ;explosionFrame 0
1380
1381         ld  hl,1                ;increase score by one
1382         jp  scoreInc            ;+ret
1383
1384 ;--------------------------- level events -----------------------------------
1385
1386 Level_event:
1387         ld  hl,nextevent        ;time to next event     <ld  a,(nextevent)
1388         dec (hl)                ;decrease counter       <dec a
1389         ld  a,(hl)              ;look at counter        <ld  (nextevent),a
1390         or  a                   ;has it reached zero?
1391         ret nz                  ;nope: get outta here!
1392
1393         ld  bc,0                ;enemy frequency (lvl)
1394 eventtime =$-2
1395         cal Random
1396         ld  (nextevent),a       ;set time to next event
1397         ld  hl,eventleft
1398         dec (hl)                ;update enemy-counter
1399
1400         ld  a,(hl)              ;look at counter
1401         or  a                   ;has it reached 0?
1402         jp  z,Next_level        ;yes: level finished
1403         dec a                   ;has it reached 1?
1404         jr  z,standby_event     ;yes: wait until no enemies present/left
1405         dec a                   ;has it reached 2?
1406         jr  z,place_boss        ;yep: place the BigBossTM!
1407         dec a                   ;has it reached 3?
1408         jr  nz,do_event         ;nope: >3 = place an enemy
1409         inc hl                  ;nextevent located behind eventleft
1410         ld  (hl),123            ;set delay
1411         ret                     ;don't place any more enemies
1412
1413 standby_event:
1414         ld  b,nrenemies
1415         ld  hl,enemies+1-enemysize
1416         ld  de,enemysize
1417 chk_enemyleft:
1418         add hl,de
1419         ld  a,(hl)
1420         or  a                   ;0 = no enemy present
1421         jr  nz,enemyleft
1422         dnz chk_enemyleft
1423         ret
1424 enemyleft:
1425         ld  hl,eventleft
1426         inc (hl)
1427         ret
1428
1429
1430 place_boss:
1431         ld  a,1
1432         ld  (nrlvlenemies),a    ;just one enemy: the BOSS
1433         ld  hl,(levelp)         ;the leveldata (including the boss)
1434         dec hl                  ;points to leveldata\boss\enemynr
1435         ld  a,(hl)              ;load it
1436         ld  (lvlenemies),a      ;set new enemy (boss)
1437
1438 do_event:
1439         ld  hl,enemies+1-enemysize
1440         ld  bc,enemysize
1441         xor a                   ;a=0
1442 chk_noenemy:
1443         add hl,bc
1444         cp  (hl)                ;(hl) = 0 ??
1445         jr  nz,chk_noenemy      ;jump if enemy present (non-0)
1446         ex  de,hl               ;de=hl=usable enemy
1447
1448 place_enemy:                    ;de = enemy+1
1449         ld  bc,0                ;0..nrlvlenemies
1450 nrlvlenemies =$-1               ;=nr of enemies minus 1
1451         cal Random              ;random enemy b..b+c = 0..nrenemies-1
1452         ld  b,0
1453         ld  c,a                 ;bc=a
1454         ld  hl,lvlenemies
1455         add hl,bc               ;go to a random enemy
1456         ld  a,(hl)              ;load enemy nr of this mysterious random enemy
1457         cal findenemyspecs      ;hl = enemy #a specs
1458
1459         dec de                  ;goto hp64 (before occ)
1460         ldi                     ;set hp64
1461         ldi                     ;set hitpoints+occ of enemy class
1462         ld  a,(hl)              ;save sprite-offset/2 (ldi decs bc so in a)
1463         ldi                     ;set sprite
1464         ldi                     ;set x-position
1465
1466         ld  c,a                 ;c=sprite
1467         ld  a,(hl)              ;load placeInfo
1468         inc hl
1469         dec a                   ;is it 1?
1470         jr  z,random_enemy      ;yes: create random value <51 in a
1471         dec a                   ;is it 2?
1472         jr  z,lure_enemy        ;yes: create a 100% luring enemy
1473                                 ;otherwise?
1474 halflure_enemy:                 ;yes (of course it is): pick one (50% lure)
1475         ld  a,(timer)           ;look at frame-number
1476         and %00000001           ;make random if odd frame nr.
1477         jr  nz,random_enemy     ;1st possibility: random enemy
1478 lure_enemy:                     ;2nd possibility: luring enemy
1479         ld  a,(y)               ;place at same y-pos as YOUR ship
1480         jr  ypos_OK
1481 random_enemy:
1482         ld  b,0                 ;bc = enemy sprite offset / 2
1483         ld  ix,spr_enemy00      ;first enemy sprite
1484         add ix,bc               ;add offset for current enemy
1485         add ix,bc               ;twice (offset stored as offset/2)
1486         ld  a,64-8              ;=57=screen height (8 is scorebar)
1487         sub (ix+1)              ;minus sprite height=bottom
1488         ld  c,b                 ;range=0 to...
1489         ld  b,a                 ;...57-y
1490         cal Random              ;random value on screen
1491 ypos_OK:                        ;random value successfully created
1492         ld  (de),a              ;save y-position
1493         inc de                  ;@movecounter
1494         ldi                     ;set move-type
1495         ld  a,1                 ;movecounter = 1
1496         ld  (de),a              ;set
1497         inc de                  ;@firecounter
1498         ldi                     ;set time-to-1st-fire
1499         ldi                     ;set firefreq
1500         ret                     ;return
1501
1502 ;--------------------------- enemy fires ------------------------------------
1503
1504 Enemy_fires:                    ;de = x,y
1505         dec d
1506         dec d                   ;d = x-2
1507         inc e                   ;e = y+1
1508
1509         ld  b,nrebuls
1510         ld  hl,ebullets
1511 find_ebullet:
1512         ld  a,(hl)
1513         or  a
1514         jr  z,found_ebullet     ;0 = not used
1515         inc hl \ inc hl \ inc hl
1516         dnz find_ebullet        ;look next bullet
1517         ret
1518
1519 found_ebullet:
1520         ld  b,%1100
1521         ld  a,(level_info)
1522         and %00001000
1523         jr  z,bulletok
1524
1525         ld  a,(y)
1526         sub e
1527         add a,10
1528         jp  p,bulletnotup
1529         ld  b,%1011             ;yourY-bulY = negative (=bullet below you)
1530         add a,10
1531         jp  p,bulletnotup
1532         ld  b,%1001             ;yourY-bulY = even more negative (going up)
1533
1534 bulletnotup:
1535         sub 20
1536         jp  m,bulletok
1537         ld  b,%1010             ;bullet going down
1538         sub 10
1539         jp  m,bulletok          ;even more going down
1540         ld  b,%1000
1541
1542 bulletok:
1543         ld  a,(level_info)
1544         and %11110000
1545         or  b
1546         ld  (hl),a              ;set bullet direction
1547         inc hl
1548         ld  (hl),d              ;set x-pos
1549         inc hl
1550         ld  (hl),e              ;set y-pos
1551         ret
1552
1553 ;----------------------------- enemy bullets --------------------------------
1554
1555 Enemy_bullets:
1556         ld  hl,ebullets
1557         ld  b,nrebuls
1558 handle_bullet:
1559         psh bc
1560         psh hl
1561         ld  a,(hl)              ;load bulletType in a
1562         and %1111               ;select direction-bits
1563         jr  nz,enemy_bullet     ;non-0: handle bullet
1564 next_bullet:
1565         pop hl                  ;do not move the <pop hl>
1566         pop bc
1567         inc hl \ inc hl \ inc hl
1568         dnz handle_bullet
1569         ret
1570
1571 enemy_bullet:
1572         ld  b,a                 ;save type&%1111
1573         inc hl                  ;bullet x
1574         ld  a,(hl)              ;check if it has reached the left side of scrn
1575         bit 7,a                 ;x<0?
1576         jr  nz,remove_ebullet   ;yes, remove bullet
1577         dec (hl)                ;move one left
1578         dec (hl)                ;and another one
1579         ld  d,(hl)              ;d=x
1580         inc hl                  ;@y
1581
1582         ld  a,b                 ;restore type
1583         cp  %1100               ;is it a normal bullet? (cp = faster than bit)
1584         jr  z,ebullet_common    ;type %1100: normal bullet
1585         and %111                ;isolate important bits
1586         jr  z,ebullet_down      ;type %1000: moving down
1587         dec a
1588         jr  z,ebullet_up        ;type %1001: moving up
1589         ld  b,a
1590
1591         ld  a,(timer)
1592         rra
1593         jr  c,ebullet_common
1594
1595         ld  a,b
1596         dec a
1597         jr  z,ebullet_down      ;type %1010: moving down 50%
1598                                 ;type %1011: moving up 50%
1599 ebullet_up:
1600         ld  a,(hl)
1601         dec a
1602         jp  m,ebullet_common
1603         ld  (hl),a
1604         jr  ebullet_common
1605
1606 ebullet_down:
1607         ld  a,(hl)
1608         inc a
1609         cp  55
1610         jr  z,ebullet_common
1611         ld  (hl),a
1612
1613 ebullet_common:
1614         ld  e,(hl)              ;e=y
1615         ld  ix,spr_bullete1     ;display enemy bullet
1616         cal putsprite
1617
1618 ebullet_hits:
1619         ld  a,(your_occ)
1620         or  a
1621         jr  nz,next_bullet      ;0 = you're normal
1622
1623         pop hl
1624         psh hl
1625         inc hl                  ;check x
1626         ld  a,(x)
1627         sub (hl)
1628         add a,6
1629         jp  m,next_bullet
1630         cp  9
1631         jr  nc,next_bullet
1632
1633         inc hl                  ;check y
1634         ld  a,(y)
1635         sub (hl)
1636         add a,6
1637         jp  m,next_bullet
1638         cp  9
1639         jr  nc,next_bullet
1640
1641         pop hl                  ;points to bullettype again
1642         psh hl                  ;and save it again (ivm call to damage_you)
1643         ld  a,(hl)              ;load bullettype
1644         cal _shracc             ;isolate damage-bits (%1111???? -> %00001111)
1645         ld  b,a                 ;set damage-amount
1646         cal damage_you          ;HIT!!
1647 remove_ebullet:
1648         pop hl                  ;hl could be destroyed by damage_you
1649         ld  (hl),0              ;bullet > unused
1650         jr  next_bullet+1       ;next bullet (SKIP THE <POP HL> = one byte)
1651
1652 ;--------------------------- handle enemies ---------------------------------
1653
1654 Handle_enemies:
1655         ld  hl,enemies+1
1656         ld  b,nrenemies         ;handle all enemies
1657
1658 handle_enemy:
1659         psh bc
1660         psh hl
1661
1662         ld  a,(hl)
1663         and %00000011
1664         jr  z,next_enemy        ;occ "no enemy" 0
1665         dec a
1666         jr  z,exploding_enemy   ;occ "exploding" 1
1667
1668 normal_enemy:
1669         inc hl
1670         ld  c,(hl)              ;c = enemy type = de
1671         cal find_sprite
1672
1673         inc hl
1674         ld  d,(hl)              ;x
1675         inc hl
1676         ld  e,(hl)              ;y
1677
1678         inc hl                  ;@movetype
1679         cal moving_enemy
1680         dec hl
1681
1682         ld  a,e                 ;new y value
1683         cp  57
1684         jr  c,enemyonscreenY    ;=on screen
1685         cp  -20                 ;moved off at top
1686         ld  e,0                 ;reset to top
1687         jr  nc,enemyonscreenY
1688         ld  e,57                ;otherwise reset to bottom
1689 enemyonscreenY:
1690         ld  (hl),e              ;store new y
1691         dec hl                  ;@x
1692
1693         ld  a,d                 ;new x value
1694         cp  128                 ;x<128
1695         jr  c,enemyonscreenX    ;=on screen
1696         cp  -7                  ;x<=-8
1697         jr  c,remove_enemy      ;=off screen
1698 enemyonscreenX:
1699         ld  (hl),d              ;store new x
1700         ld  a,c                 ;a = enemy type
1701         or  a                   ;type 0? (pickup)
1702         jr  nz,check_enemyfire  ;no, a normal enemy; let em fire
1703         ld  a,(timer)           ;load time
1704         and %1                  ;move left once every 2 turns
1705         jr  z,firing_done       ;don't move now
1706         inc d                   ;increase x-position (don't move this turn)
1707         inc (hl)                ;and save it
1708         jr  firing_done         ;continue
1709
1710 check_enemyfire:
1711         inc hl                  ;@y
1712         inc hl                  ;@movetype
1713         inc hl                  ;@movecount
1714         inc hl                  ;@firecount
1715         dec (hl)                ;decrease counter till next blast
1716         ld  a,(hl)              ;&&&doesn't seem efficient to me
1717         or  a                   ;has it reached zero?
1718         jr  nz,firing_done      ;finished if not
1719
1720         inc hl                  ;@firefreq
1721         ld  a,(hl)
1722         dec hl
1723         ld  (hl),a              ;reset counter for next blast
1724         psh de                  ;save registers for firing-use
1725         cal Enemy_fires         ;fires bullet
1726         pop de                  ;restore (destroyed by Enemy_fires)
1727 firing_done:
1728         cal putwidesprite       ;display sprite @ix
1729
1730 next_enemy:
1731         pop hl
1732         ld  bc,enemysize
1733         add hl,bc
1734         pop bc
1735         dnz handle_enemy
1736         ret
1737
1738 remove_enemy:
1739         pop hl
1740         ld  (hl),$0000          ;bye bye enemy
1741         jr  next_enemy+1        ;continue AFTER pop hl (already done)
1742
1743 exploding_enemy:
1744         inc hl
1745         ld  a,(hl)
1746         cp  16
1747         jr  z,remove_enemy      ;remove when at last frame
1748         inc a
1749         ld  (hl),a              ;next frame
1750         dec a                   ;1-16 -> 0-15
1751         ld  ix,spr_explosion    ;base sprite
1752         cal explosion_stuff     ;display explosion
1753         jr  next_enemy
1754
1755 ;--------------------------- moving enemies ---------------------------------
1756
1757 moving_enemy:
1758         ld  a,(hl)              ;how does this enemy move?
1759         bit 7,a                 ;direction indicator
1760         jr  nz,moveright
1761 moveleft:
1762         dec d
1763         jr  moveXdone
1764 moveright:
1765         inc d
1766 moveXdone:
1767         res 7,a                 ;01111111=movetype:
1768         and a
1769         ret z                   ;0 = don't move
1770         dec a
1771         jr  z,movetype_updown   ;1 = 0 >< up / down
1772         dec a
1773         jr  z,movetype_vslow    ;2 = .75 >>
1774         dec a
1775         jr  z,movetype_slow     ;3 = .5 >>
1776         dec a
1777         jr  z,movetype_fast     ;4 = .5 <<
1778         dec a
1779         jr  z,movetype_vfast    ;5 = 1 <<
1780         dec a
1781         jr  z,movetype_smart    ;6
1782         dec a
1783         jr  z,movetype_lure     ;7 = 1 >> move y towards you
1784         dec a
1785         jr  z,movetype_slowlure ;8 = 1 >> lure 1/2 speed
1786         dec a
1787 ;       jr  z,movetype_stoplure ;9 = 1 >> slowlure; stop at x=99
1788 ;       dec a
1789 ;       jr  z,movetype_fulllure ;10 = x+y towards you 1/2 speed
1790
1791 movetype_fulllure:
1792         ld  a,(timer)
1793         and 1
1794         ret z
1795         cal movetype_lure
1796         ld  a,(x)
1797         cp  d
1798         ret c                   ;move left (already did)
1799 lure_right:
1800         inc d                   ;already moved left, so move right
1801 moverightonce:
1802         inc d                   ;twice (=+1)
1803         ret
1804
1805 movetype_slowlure:
1806         ld  a,(timer)
1807         and 1                   ;half the time
1808         jr  z,moverightonce     ;dont move at all (compensate move left +ret)
1809 movetype_lure:
1810         ld  a,104
1811         cp  d
1812         jr  c,dothelurethingy
1813         inc d                   ;x<106: full stop
1814 dothelurethingy:
1815         ld  a,(y)
1816         cp  e
1817         ret z                   ;don't move if equal
1818         jr  c,lure_up           ;below you then move up
1819 lure_down:                      ;above then move down
1820         inc e
1821         ret
1822 lure_up:
1823         dec e
1824         ret
1825
1826 movetype_smart:
1827         inc hl                  ;hl =@ <move>
1828         ld  a,(timer)
1829         and %1111               ;     |
1830         ld  a,(hl)              ;&&& \|/
1831         jr  nz,smartupdate
1832         inc a
1833 smartupdate:
1834         ld  (hl),a
1835
1836         or  a                   ;reset carry flag
1837         dec hl                  ;reset hl to <y>
1838         and %11111100
1839         jr  z,movetype_fast
1840
1841 movetype_slow:
1842         ld  a,(timer)
1843         and %1
1844         ret z
1845 movetype_vslow:
1846         ld  a,(timer)
1847         and %11
1848         ret z
1849         inc d
1850         ret
1851
1852 movetype_fast:
1853         ld  a,(timer)
1854         and %1
1855         ret z
1856 movetype_vfast:
1857         dec d                   ;move left
1858         ret nz                  ;finished
1859         pop hl                  ;restore stack (no ret used)
1860         jp  remove_enemy        ;remove this enemy (off screen)
1861
1862 movetype_updown:
1863         inc hl                  ;@ <move>
1864         ld  a,(hl)
1865         dec a
1866         jr  nz,move_updated
1867         add a,128
1868 move_updated:
1869         ld  (hl),a
1870
1871         or  a                   ;reset carry flag
1872         dec hl                  ;@ <y>
1873         and %00100000
1874         ld  a,(hl);&&&ld a,e    ;load current y-position
1875         jr  z,movedown
1876
1877 moveup: dec a                   ;decrease y-pos (=move up)
1878         ret m                   ;don't move off the screen (y<0)
1879         dec e                   ;save new y-pos
1880         ret                     ;finish
1881 movedown:
1882         inc a                   ;increase y-pos
1883         cp  55                  ;compare with bottom
1884         ret nc                  ;return if it has passed that line (>40)
1885         inc e                   ;otherwise save new position
1886         ret                     ;and return
1887
1888 ;--------------------------- check collision --------------------------------
1889
1890 Enemies_hit:
1891         ld  hl,(x)              ;e = X, d = Y
1892         ld  de,$0707            ;add 7 to both d and e
1893         add hl,de
1894         ld  d,h
1895         ld  e,l                 ;e = X+7, d = Y+7
1896
1897         ld  hl,enemies+1
1898         ld  b,nrenemies         ;check all 20 enemies
1899 check_collision:
1900         psh hl
1901         ld  a,(hl)
1902         and %00000010
1903         jr  z,check_next        ;2 or 3 = ok
1904         inc hl
1905
1906 collide_enemy:                  ;&&& include in Handle_enemy proc
1907         cal find_sprite
1908
1909         inc hl
1910         ld  a,(hl)              ;check x match
1911         sub e                   ;enemy position minus yours minus 7
1912         jp  p,check_next
1913         add a,6
1914         add a,(ix)              ;enemy width
1915         jp  m,check_next
1916
1917         inc hl
1918         ld  a,(hl)              ;check y match
1919         sub d                   ;same as with x-check
1920         jp  p,check_next
1921         add a,6
1922         add a,(ix+1)            ;enemy height
1923         jp  m,check_next
1924         dec hl
1925         dec hl
1926
1927 take_pickup:
1928         psh hl                  ;we need hl
1929         ld  hl,2                ;increase score by 2
1930         cal scoreInc
1931         pop hl                  ;we're done
1932
1933         ld  a,(hl)              ;load enemy type
1934         or  a
1935         jr  nz,collide          ;enemy when <>0
1936
1937         psh hl
1938         ld  hl,your_pickup      ;your pickups
1939         ld  a,(hl)              ;current
1940         inc a                   ;go to next
1941         cp  6                   ;pickups >=6
1942         jr  c,not_maxpickup
1943         ld  a,1                 ;yes: reset to pickup 1
1944 not_maxpickup:
1945         ld  (hl),a              ;save new
1946         cal disp_icons          ;display altered pickupicons
1947         pop hl
1948
1949         dec hl                  ;to enemy occ
1950         xor a                   ;set to 0 = gone
1951         ld  (hl),a              ;remove
1952         jr  check_next          ;all done, next..
1953
1954 destroy_enemy:
1955         ld  (hl),%01            ;set to explode
1956         inc hl
1957         ld  (hl),0              ;explosionFrame 0
1958         jr  collide_done
1959
1960 collide:
1961         dec hl
1962         ld  a,(hl)
1963         and %11111100
1964         jr  z,destroy_enemy
1965         ld  a,(hl)
1966         sub collidedamage
1967         ld  (hl),a
1968 collide_done:
1969         ld  b,collidedamage     ;damage
1970         cal damage_you
1971
1972 check_next:
1973         pop hl
1974         ld  a,b                 ;psh bc
1975         ld  bc,enemysize
1976         add hl,bc
1977         ld  b,a                 ;pop bc
1978         dnz check_collision
1979         ret
1980
1981 ;--------------------------- story ------------------------------------------
1982
1983 storyPage:
1984         psh hl
1985         cal _clrLCD
1986         pop hl
1987 storyLine:
1988         inc hl
1989         ld  e,(hl)
1990         inc hl
1991         ld  d,(hl)
1992         ld  (_penCol),de
1993         inc hl
1994         cal _vputs
1995
1996         ld  a,(hl)
1997         dec a
1998         jr  z,storyLine
1999
2000         psh hl
2001         ld  hl,VIDEO_MEM        ;copy text
2002         ld  de,dispbuffer       ;to GRAPH_MEM
2003         ld  bc,1024             ;entire screen
2004         ldir
2005         cal _clrLCD
2006         pop hl
2007
2008         inc hl
2009         ld  a,(hl)
2010         inc hl
2011         ld  b,(hl)
2012         psh hl
2013         cal DoSFX
2014         cal _getkey
2015         pop hl
2016         ret
2017
2018 dostory:
2019         cal storyPage                   ;do some story
2020         inc hl                          ;look at next hl
2021         ld  a,(hl)                      ;load in a
2022         dec hl                          ;restory hl
2023         inc a                           ;set z-flag if a = $ff
2024         jr  nz,dostory                  ;otherwise loop
2025
2026         ld  bc,2+1                      ;story ends
2027         add hl,bc                       ;set hl to beginning of the level
2028         ld  (levelp),hl                 ;set the level-pointer
2029         ret                             ;and return
2030
2031 ;--------------------------- SFX --------------------------------------------
2032
2033 DoSFX:                          ;in:a=beginLine;b=nrOfLines
2034         ld  (curline),a
2035 SFXframe:
2036         psh bc
2037
2038         ld  a,0                 ;get line number
2039 curline =$-1
2040         inc a                   ;go to the next line
2041         ld  (curline),a         ;update
2042
2043         ld  l,a
2044         ld  h,0                 ;hl=a
2045         add hl,hl
2046         add hl,hl
2047         add hl,hl
2048         add hl,hl               ;*16 (a pixels down=a*16)
2049
2050         ld  b,h                 ;save hl for later
2051         ld  c,l
2052
2053         ld  de,VIDEO_MEM        ;where to put sfx
2054         add hl,de               ;go to ymin
2055         ex  de,hl               ;put into de again
2056
2057         ld  hl,dispbuffer
2058         add hl,bc               ;hl->logo
2059
2060         sub 64                  ;a=a-64
2061         neg                     ;a=64-a (lines from bottom)
2062
2063 ;       ld  c,a                 ;c=a=(curline)
2064 ;       ld  a,64
2065 ;       sub c                   ;lines from bottom
2066
2067 SFXdisp:                        ;display this frame on screen
2068         ld  bc,16               ;one line (=16 bytes, you'd know by now)
2069         ldir                    ;display (copy actually)
2070         ld  bc,-16              ;go up one line (not on screen)
2071         add hl,bc               ;so the same line will be displayed
2072         dec a                   ;counter
2073         jr  nz,SFXdisp          ;repeat until whole screen is displayed
2074
2075         ld  b,8
2076 SFXdelay:
2077         halt                    ;delay
2078         dnz SFXdelay            ;8x
2079
2080         pop bc                  ;counter
2081         dnz SFXframe
2082         ret
2083
2084 ;--------------------------- show icon --------------------------------------
2085
2086 drawline:
2087         ld  (hl),a              ;draw one piece of the divider-line
2088         inc hl                  ;move right (8 pixels = 1 byte)
2089         dnz drawline            ;repeat (16bytes * 8pixels =128= screen width)
2090         ret
2091
2092 disp_icons:
2093  psh bc \ psh de \ psh hl \ psh ix ;&&&
2094
2095         ld  hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
2096         ld  (PutWhere),hl       ;place icons at bottom of normal screen
2097         ld  b,16                ;draw 16x (screen width)
2098         ld  a,%11111111         ;horizontal line mask
2099         cal drawline            ;draw divider-line
2100
2101         ld  b,16*7              ;draw 16x (screen width) 7x (height)
2102         xor a                   ;blank line mask
2103         cal drawline            ;clear scorebar
2104
2105 disp_lives:
2106         ld  de,5                ;(0,5)
2107         ld  a,(your_lives)      ;nr of lives
2108         or  a
2109         jr  z,displivesdone     ;no lives
2110         ld  b,a
2111 displivesloop:
2112         psh bc
2113         ld  ix,spr_lship
2114         cal safeputsprite       ;put li'l ship
2115         ld  a,lshipsize+1
2116         add a,d
2117         ld  d,a                 ;x=x+5
2118         pop bc
2119         dnz displivesloop       ;one ship per life
2120 displivesdone:
2121
2122         ld  ix,spr_icon01       ;armorIcon
2123         ld  de,$1901            ;icon #1
2124         cal putwidesprite       ;display icon
2125         cal disp_armor          ;display bar
2126
2127         ld  ix,spr_icon00
2128         ld  a,(your_weapon)     ;ur weapon
2129         cp  maxweapon           ;laser?
2130         psh af                  ;(your_weapon)
2131         jr  nc,no_tail          ;if laser (nc) then tail ain't fired
2132         ld  a,(your_tail)
2133         or  a
2134         jr  z,no_tail
2135         ld  ix,spr_icon02       ;tailbeamIcon
2136 no_tail:
2137         ld  de,$2901            ;icon #2
2138         cal putwidesprite       ;display
2139
2140         ld  ix,spr_icon00
2141         pop af                  ;a=(your_weapon); cf=bullets
2142         psh af
2143         jr  nc,no_bullets       ;=laser
2144         ld  hl,$3945            ;position to display bullet-type digit
2145         pop af                  ;digit=(your_weapon)
2146         psh af
2147         inc a                   ;1 = weapon #1 (=0)
2148         ld  (_penCol),hl        ;set location
2149         add a,'0'               ;make digit
2150         cal _vputmap            ;display char
2151         ld  ix,spr_icon03       ;bulletIcon
2152 no_bullets:
2153         ld  de,$3901            ;icon #3
2154         cal putwidesprite       ;display icon
2155
2156         ld  ix,spr_icon00       ;emptyIcon
2157         pop af                  ;ld a,(your_weapon)
2158         ld  b,a
2159         jr  c,no_laser          ;popped carry
2160         ld  hl,$3955            ;position to display bullet-type digit
2161         ld  (_penCol),hl        ;set location
2162         ld  a,b                 ;(your_weapon)  ;load = faster than push
2163         sub maxweapon-1         ;1 = laser #1 (=maxweapon)
2164         add a,'0'               ;make digit
2165         cal _vputmap            ;display char
2166         ld  ix,spr_icon04       ;laserIcon
2167 no_laser:
2168         ld  de,$4901            ;icon #4
2169         cal putwidesprite
2170
2171         ld  ix,spr_icon00       ;emptyIcon
2172         ld  a,(your_multiples)
2173         and %111
2174         jr  z,no_multiples
2175         ld  ix,spr_icon05
2176 no_multiples:
2177         ld  de,$5901            ;icon #5
2178         cal putwidesprite
2179
2180         ld  ix,spr_dividerline
2181         ld  de,$6901
2182         cal putwidesprite
2183
2184         ld  a,(your_pickup)     ;pickups taken
2185         add a,a                 ;picks*2 (sets z-flag)
2186         jr  z,iconsdone         ;return if no pickups
2187         add a,a                 ;picks*4
2188         add a,a                 ;picks*8
2189         add a,a                 ;picks*$10
2190         add a,$09               ;add 0ah
2191         ld  d,a                 ;y-pos = picks * $10 + $0a (19,29,39,49,59)
2192         ld  e,$01               ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
2193
2194         ld  ix,spr_icon
2195         cal putwidesprite
2196 iconsdone:
2197         ld  hl,dispbuffer       ;normal game-screen
2198         ld  (PutWhere),hl       ;set sprite-position to normal screen
2199
2200  pop ix \ pop hl \ pop de \ pop bc
2201         ret
2202
2203 disp_armor:
2204         ld  de,16               ;line size
2205         ld  hl,(57*16)+VIDEO_MEM+3
2206         ld  b,3
2207 armorbarclr:
2208         dec hl
2209         ld  (hl),0
2210         add hl,de
2211         ld  (hl),0
2212         sbc hl,de
2213         dnz armorbarclr
2214
2215         ld  a,(your_armor)      ;load your armor (<25)
2216         ld  c,a                 ;psh a
2217         srl a                   ;/2
2218         srl a                   ;/4
2219         srl a                   ;/8: don't display last 3 bits of a (later)
2220         jr  z,noarmorbar        ;if a=0 then it would loop 256x so skip it
2221         ld  b,a                 ;loop b=a times
2222 armorbar:                       ;starting at ($39*16)+VIDEO_MEM
2223         ld  (hl),%11111111      ;draw a piece of the bar
2224         add hl,de               ;one down (resets carry)
2225         ld  (hl),%11111111      ;same piece
2226         sbc hl,de               ;up again
2227         inc hl                  ;next position
2228         dnz armorbar            ;loop it b times
2229
2230 noarmorbar:
2231         ld  a,c                 ;pop a
2232         and %111                ;display last bits of armor
2233         ret z                   ;if armor=0 then bit = %00000000 (don't disp)
2234         ld  b,a                 ;into B
2235         xor a                   ;bit = %00000000
2236 armorbarbit:
2237         scf                     ;set carry flag
2238         rra                     ;rotates A right and sets bit 7 (c-flag)
2239         dnz armorbarbit         ;repeat B times (so if B=6 then a=%11111100)
2240 armorbarready:                  ;               (an if B=3 then a=%11100000)
2241         ld  (hl),a              ;draw this last byte
2242         add hl,de
2243         ld  (hl),a              ;and just below
2244         ret
2245
2246 disp_charge:
2247         ld  hl,(59*16)+VIDEO_MEM+3
2248         ld  b,3
2249 chargebarclr:
2250         dec hl
2251         ld  (hl),0
2252         dnz chargebarclr
2253
2254         ld  a,(weapincs)        ;load bar size (0-80)
2255         srl a                   ;half the size (0-40)
2256         srl a                   ;again half that size (0-20 pixels)
2257         ld  c,a                 ;psh a
2258         srl a                   ;/2
2259         srl a                   ;/4
2260         srl a                   ;/8: don't display last 3 bits of a (later)
2261         jr  z,nochargebar       ;if a=0 then it would loop 256x so skip it
2262         ld  b,a                 ;loop b=a times
2263 chargebar:                      ;starting at ($39*16)+VIDEO_MEM
2264         ld  (hl),%11111111      ;draw a piece of the bar
2265         inc hl                  ;next position
2266         dnz chargebar           ;loop it b times
2267 nochargebar:
2268         ld  a,c                 ;pop a
2269         and %111                ;display last bits of chargebar
2270         ret z                   ;if armor=0 then bit = %00000000 (don't disp)
2271         ld  b,a                 ;into B
2272         xor a                   ;bit = %00000000
2273 chargebarbit:
2274         scf                     ;set carry flag
2275         rra                     ;rotates A right and sets bit 7 (c-flag)
2276         dnz chargebarbit        ;repeat B times (so if B=6 then a=%11111100)
2277 chargebarready:                 ;               (an if B=3 then a=%11100000)
2278         ld  (hl),a              ;draw this last byte
2279         ret
2280
2281 ;--------------------------- proc -------------------------------------------
2282
2283 Random:                         ;a=c<random<b+c; destr:none
2284         psh hl
2285         ld  hl,rancount         ;amount to increase with (0-255)
2286 randomloop:
2287         inc (hl)                ;change for next time
2288         ld  a,r                 ;value $0-7F (can be _anything_ so watch out!)
2289         add a,0                 ;add to last random value
2290 ranseed =$-1                    ;SMC :P
2291         add a,(hl)              ;add the changing increase value
2292                         ;(this is because R can be anything;
2293                         ; ie always be even so freeze when a must be 1<=a<=1)
2294         ld  (ranseed),a         ;save for next time
2295         cp  b                   ;a>=b
2296         jr  nc,randomloop       ;then add again
2297         add a,c                 ;a<b; a=a+c
2298         pop hl
2299         ret
2300 rancount: .db 0
2301
2302 RandomY:                        ;HL = random Y 0..50 right side ((1..51)*16-1)
2303         psh bc
2304         ld  bc,50*256+1         ;range=1..51
2305         cal Random              ;a = 1..51
2306         ld  h,0
2307         ld  l,a                 ;hl = 1..51
2308         add hl,hl
2309         add hl,hl
2310         add hl,hl
2311         add hl,hl               ;hl = 1..51 * 16 (left side at random y)
2312         dec hl                  ;hl = 0..50 * 16 (" at right side of screen)
2313         ld  de,dispbuffer
2314         add hl,de               ;position on screen
2315         pop bc
2316         ret
2317
2318 scoreInc:
2319         psh bc
2320         ld  bc,(your_score)
2321         add hl,bc
2322         ld  (your_score),hl
2323         pop bc
2324         ret
2325
2326 find_sprite:                    ;in:hl=enemy+type | out:ix=sprite to enemy
2327         psh de
2328         psh hl
2329         ld  e,(hl)              ;e = enemy offset/2
2330         ld  d,0                 ;de = e
2331         ld  ix,spr_enemy00      ;first enemy sprite
2332         add ix,de               ;add offset for current enemy
2333         add ix,de               ;twice (offset stored as offset/2)
2334         pop hl
2335         pop de
2336         ret
2337
2338 BLACKLCD:
2339         ld  hl,VIDEO_MEM        ;screen location (top left)
2340         ld  de,VIDEO_MEM+1
2341         ld  (hl),%11111111
2342         ld  bc,1024-1           ;do it 1024 times = entire screen
2343         ldir
2344         set 3,(iy+5)            ;set white on black
2345         ret
2346
2347 releasekeys:
2348         halt
2349         ld  a,%10000000         ;all key-masks
2350         out (1),a
2351         in  a,(1)
2352         inc a                   ;cp %11111111 (no keys pressed)
2353         jr  nz,releasekeys      ;keep waitin
2354         cal GET_KEY             ;clear buffer
2355         ret
2356
2357 findenemyspecs:                 ;enemy #a specs in (hl); in:b=0; out:ac=?
2358         ld  hl,enemyspecs-8     ;enemy "0" specs (1 before enemy #1)
2359         add a,a                 ;a=type*2
2360         add a,a                 ;a=type*4
2361         add a,a                 ;a=type*8
2362         ld  c,a                 ;b=0; c=bc=type*8
2363         add hl,bc               ;hl = enemy specs
2364         ret
2365
2366 ;--------------------------- game over / new game / death -------------------
2367 chartable:
2368         .db 0,".<>!",0,0,0,0  ;down,L,R,up
2369         .db 0,"xtoje0",0      ;enter..clear
2370         .db " wsnid9",0       ;(-)..custom
2371         .db "zvrmhc8",0       ;dot..del
2372         .db "yuqlgb7#"        ;0..xvar
2373         .db $D9,"-pkfa6'"     ;on..alpha
2374         .db "54321*",0,$D0    ;F5..more
2375
2376 save_hi:
2377         ld  hl,_asapvar         ;find own variable
2378         rst 20h                 ;cal _ABS_MOV10TOOP1
2379         rst 10h                 ;cal _FINDSYM
2380
2381         xor a
2382         ld  hl,4+storehi_start-_asm_exec_ram
2383         add hl,de               ;hl=pointer to data in original prog
2384         adc a,b
2385         cal _SET_ABS_DEST_ADDR
2386         xor a
2387         ld  hl,storehi_start
2388         cal _SET_ABS_SRC_ADDR
2389         ld  hl,storehi_end-storehi_start
2390         cal _SET_MM_NUM_BYTES
2391         cal _mm_ldir            ;save done (cal \ ret)
2392         jp  _RAM_PAGE_1
2393
2394 save_lvl:
2395         ld  hl,_asapvar         ;find own variable
2396         rst 20h                 ;cal _ABS_MOV10TOOP1
2397         rst 10h                 ;cal _FINDSYM
2398
2399         xor a
2400         ld  hl,4+storesave_start-_asm_exec_ram
2401         add hl,de               ;hl=pointer to data in original prog
2402         adc a,b
2403         cal _SET_ABS_DEST_ADDR
2404         xor a
2405         ld  hl,storesave_start
2406         cal _SET_ABS_SRC_ADDR
2407         ld  hl,storesave_end-storesave_start
2408         cal _SET_MM_NUM_BYTES
2409         cal _mm_ldir            ;save done (cal \ ret)
2410         jp  _RAM_PAGE_1
2411
2412 game_over:                      ;stack=+0
2413         cal BLACKLCD            ;clear screen
2414         ld  hl,$0603
2415         ld  (_curRow),hl        ;center
2416         ld  hl,txt_gameover
2417         cal _puts               ;display "GAME OVER"
2418         cal releasekeys         ;wait for all keys to be released
2419
2420         ld  hl,$0007
2421         ld  (_curRow),hl
2422
2423         ld  de,(your_score)
2424         ld  hl,(hiscore)
2425         cal CP_HL_DE
2426         jr  nc,no_hiscore
2427         ld  (hiscore),de
2428
2429 ask_hiname:
2430         ld  ix,hiname
2431         ld  a,9
2432         ld  (hiscorepos),a
2433 enter_name_loop:
2434         ld  a,'_'
2435         cal _putc
2436         ld  hl,_curCol
2437         dec (hl)
2438 nokeypressed:
2439         halt \ halt
2440         cal GET_KEY
2441         or  a
2442         jr  z,nokeypressed
2443
2444         cp  K_DEL
2445         jr  z,backup
2446         cp  K_ENTER
2447         jr  z,nomore
2448         cp  K_EXIT
2449         jr  z,nomore
2450
2451         ld  hl,hiscorepos
2452         ld  b,(hl)
2453         dec b
2454         jr  z,nokeypressed
2455         ld  (hl),b
2456
2457         ld  hl,chartable
2458         ld  e,a
2459         ld  d,0
2460         add hl,de
2461         ld  a,(hl)
2462         or  a
2463         jr  z,nokeypressed
2464
2465         ld  (ix),a
2466         cal _putc
2467         inc ix
2468         cal releasekeys
2469         jr  enter_name_loop
2470
2471 backup:
2472         ld  hl,hiscorepos
2473         ld  a,(hl)
2474         cp  9
2475         jr  nc,nokeypressed
2476         inc (hl)
2477
2478         dec ix
2479         ld  (ix),' '
2480         ld  a,32
2481         cal _putc
2482         ld  hl,_curCol
2483         dec (hl)
2484         dec (hl)
2485         jr  enter_name_loop
2486
2487 nomore:
2488         ld  a,' '
2489         cal _putc
2490         ld  (ix),0
2491         cal save_hi
2492         jr  hiscoredone
2493
2494 no_hiscore:
2495         ld  hl,hiname
2496         cal _puts
2497
2498 hiscoredone:
2499         xor a                   ;clear a (Ahl will be displayed)
2500         ld  hl,$1006            ;bottom-1 right
2501         ld  (_curRow),hl        ;set
2502         ld  hl,(your_score)     ;your score
2503         cal _dispahl            ;display it (a=0)
2504
2505         ld  hl,$314b            ;bottom-1 right before score ^^
2506         ld  (_penCol),hl        ;set
2507         ld  hl,txt_score        ;"Score"
2508         cal _vputs              ;display (small)
2509
2510         ld  hl,$1007            ;bottom right
2511         ld  (_curRow),hl        ;set
2512         ld  hl,(hiscore)        ;hi-score
2513         cal _dispahl            ;display
2514         ld  hl,$3946            ;bottom right before hiscore ^^
2515         ld  (_penCol),hl        ;set
2516         ld  hl,txt_hiscore      ;"Hiscore"
2517         cal _vputs              ;display (small)
2518         res 3,(iy+5)
2519
2520         ld  b,16
2521         ld  de,16
2522         ld  hl,VIDEO_MEM+(49*16)-1
2523 restore_line:
2524         set 1,(hl)
2525         add hl,de
2526         dnz restore_line
2527
2528         cal _getkey             ;wait for keypress
2529         jp  quit                ;restore some things and return to TI-OS/shell
2530
2531 invship:                        ;procedure used in New_game
2532         psh af
2533         inc b
2534         ld  de,$C0
2535         ld  hl,VIDEO_MEM+$30-$C0;begin pos
2536 invshipinit:
2537         add hl,de
2538         dnz invshipinit
2539         ld  b,$B0               ;12 lines down
2540 invshiploop:
2541         ld  a,(hl)
2542         cpl                     ;invert byte
2543         ld  (hl),a
2544         inc hl
2545         dnz invshiploop         ;loop
2546         pop af
2547         ret
2548
2549 New_game:                       ;stack must be +1 (so change the jp in cal :)
2550         cal _clrLCD
2551         ld  hl,VIDEO_MEM
2552         ld  (PutWhere),hl       ;will be reset after displaying iconbar
2553         ld  ix,spr_ship01       ;first ship: sprite
2554         ld  de,$0105            ;position
2555         ld  b,4                 ;number of ships to display
2556 dispshipsloop:
2557         psh bc                  ;counter
2558         psh de                  ;position
2559         cal putwidesprite       ;display
2560         pop de
2561         ld  bc,spr_ship01i-spr_ship01+2
2562         add ix,bc               ;go to next ship
2563         ld  a,12                ;below the previous one
2564         add a,e
2565         ld  e,a
2566         pop bc
2567         dnz dispshipsloop       ;loop
2568
2569         ld  b,0                 ;menu pos.
2570 selectship:
2571         psh bc
2572         cal invship
2573 selectshiploop:
2574         halt
2575         cal GET_KEY
2576         or  a
2577         jr  z,selectshiploop
2578         pop bc
2579         psh bc
2580         cal invship
2581         pop bc
2582         cp  K_SECOND
2583         jr  z,startthenewgame
2584         cp  K_ENTER
2585         jr  z,startthenewgame
2586         cp  K_DOWN
2587         jr  nz,selnotdown
2588         inc b
2589 selnotdown:
2590         cp  K_UP
2591         jr  nz,selnotup
2592         dec b
2593 selnotup:
2594         ld  a,b
2595         and %11
2596         ld  b,a
2597         jr  selectship
2598
2599 startthenewgame:
2600         ld  hl,spr_ship01-(spr_ship02-spr_ship01)
2601         ld  de,spr_ship02-spr_ship01
2602         inc b                   ;your ship #0-3++
2603 searchyourship:
2604         add hl,de               ;next ship
2605         dnz searchyourship
2606         ld  (your_ship),hl
2607         xor a                   ;ld a,0
2608         ld  (your_score),a      ;reset score
2609         ld  (your_score+1),a    ;reset score (0)
2610         ld  (your_tail),a       ;no tail beam
2611         ld  (your_weapon),a     ;no laser
2612         ld  (your_pickup),a     ;reset pickups
2613         ld  (your_multiples),a  ;no multiples
2614         inc a                   ;ld a,1
2615         ld  (level),a           ;reset level nr (#1)
2616         ld  hl,level00          ;set level pointer to level#1
2617         ld  (levelp),hl         ;reset level pointer
2618         ld  a,4
2619         ld  (your_lives),a      ;3 lives (4 will be decreased @ You_die)
2620         ld  (pickuptimer),a     ;next pickup after 4 enemies destroyed
2621
2622 You_die:                        ;stack must be +1
2623         pop hl                  ;restore stack
2624         ld  a,12
2625         ld  (your_armor),a      ;12 HPs/shields
2626         ld  a,(your_lives)      ;load lives left
2627         dec a                   ;decrease lives
2628         ld  (your_lives),a      ;if lives=0ffh GO
2629         inc a                   ;if -1 then zf set now
2630         jp  z,game_over         ;and game's over
2631         jr  samelevel
2632
2633 ;--------------------------- next level -------------------------------------
2634
2635 Next_level:                     ;stack must be +1
2636         pop hl
2637
2638         cal inc_armor           ;increase armor
2639         ld  hl,level            ;level number
2640         ld  a,(hl)
2641         inc a
2642         ld  (hl),a
2643
2644         add a,a
2645         add a,a
2646         ld  h,0                 ;increase score....
2647         ld  l,a                 ;by level number * 4
2648         ld  bc,20
2649         add hl,bc               ;plus 20
2650         cal scoreInc            ;update score
2651
2652         ld  hl,(levelp)         ;level pointer
2653         ld  b,0                 ;advance one level
2654         ld  c,(hl)
2655         add hl,bc               ;passed the enemies
2656         ld  c,1+7+32+3
2657         add hl,bc               ;update to point to next level
2658         ld  (levelp),hl         ;save
2659
2660 samelevel:
2661         ld  hl,(your_ship)
2662         ld  (your_shipspr),hl
2663
2664         ld  a,80
2665         ld  (nextevent),a       ;time to first enemy appearance
2666
2667         ld  hl,(levelp)         ;level pointer
2668         xor a
2669         cp  (hl)
2670         cal z,dostory
2671
2672         ld  a,(hl)              ;number of (different) enemies in this level
2673         inc hl
2674         ld  c,a
2675         ld  (nrlvlenemies),a    ;set nr of enemies-1
2676         ld  b,0                 ;bc=c so we can use ldir
2677         ld  de,lvlenemies       ;table of enemies
2678         ldir                    ;load enemies to table
2679         ld  a,(hl)              ;load new appearance-time
2680         ld  (eventtime),a
2681         inc hl
2682         ld  a,(hl)
2683         ld  (eventtime+1),a     ;set
2684         inc hl
2685         ld  a,(hl)              ;load nr of enemies in this level
2686         ld  (eventleft),a       ;set nr of events left
2687         inc hl
2688         ld  a,(hl)
2689         ld  (level_info),a      ;
2690         inc hl
2691         ld  a,(hl)              ;movement of enemies in this level
2692         ld  (level_move),a      ;do it
2693
2694         inc hl
2695         ld  de,spacespace
2696         ld  c,17+17+2           ;b=0
2697         ldir
2698
2699         ld  ix,starx1
2700         ld  b,nrstars1
2701         cal placestars
2702         ld  ix,starx2
2703         ld  b,nrstars2
2704         cal placestars
2705
2706         xor a
2707         ld  (timer),a           ;reset time
2708         ld  hl,your_occ         ;hl = your_occ
2709         ld  (hl),a              ;reset your ship (not exploding)
2710         inc hl                  ;hl = your_inv
2711         ld  (hl),25             ;set 25*4=100 frames invulnerable
2712         ld  de,$1800
2713         ld  (x),de              ;begin position (x,y)
2714         cal Place_multiples     ;place all multiple-positions at that (0,24)
2715
2716         cal loadweapon          ;load (your_weapon)
2717
2718         ld  hl,enemies          ;remove all enemies and bullets
2719         ld  (hl),0              ;clear first byte
2720         ld  de,enemies+1        ;copy this to the next byte
2721         ld  bc,(nrenemies*enemysize)+(nrybuls*4)+(nrebuls*3)-1
2722         ldir                    ;clear enemies + bullets (y/e)
2723
2724 ;--------------------------- setup game -------------------------------------
2725
2726 game_setup:
2727         cal BLACKLCD            ;white on black
2728         ld  hl,txt_level
2729         ld  de,$0703
2730         ld  (_curRow),de        ;center
2731         cal _puts               ;display "LEVEL "
2732
2733         ld  a,(level)           ;current level
2734         ld  l,a
2735         ld  h,0                 ;in hl
2736         cal UNPACK_HL           ;create first digit
2737         add a,'0'               ;0-9
2738         ld  b,a                 ;into b
2739         cal UNPACK_HL           ;second digit
2740         add a,'0'               ;0-9
2741         cal _putc               ;display second digit
2742         ld  a,b
2743         cal _putmap             ;display first digit
2744
2745         ld  hl,txt_lives        ;bar text: "Lx0"...
2746         ld  de,$0904
2747         ld  (_curRow),de        ;display lives left below level nr
2748         cal _puts
2749         ld  a,(your_lives)      ;lives left
2750         add a,'0'               ;make value 0='0'
2751         cal _putc
2752
2753         cal releasekeys         ;wait for user to release all keys
2754         ld  hl,txt_savekey      ;"Press [F1] to save"
2755         ld  de,$3A46            ;bottom-right
2756         ld  (_penCol),de
2757         cal _vputs
2758
2759         res 3,(iy+5)            ;set white on black
2760         cal _getkey             ;wait for keypress
2761         cp  kF1
2762         cal z,save_lvl
2763
2764         cal _clrLCD             ;clear screen
2765         cal disp_icons          ;display bottom icons +ret
2766         jp  game_main_loop
2767
2768 placestars:
2769         cal RandomY             ;a = random y-pos 1..bottom
2770         ld  a,b                 ;a =  b = star nr. = 1..7
2771         add a,a                 ;a = 2b = 2..14
2772         ld  d,0
2773         ld  e,a                 ;de = a = 2-14
2774         or  a
2775         sbc hl,de               ;substract from random y => random pos anywhere
2776
2777         ld  (ix),l              ;save x-pos (l)
2778         ld  (ix+1),h            ;save y-pos (h)
2779         inc ix \ inc ix         ;next star
2780         dnz placestars          ;repeat for all stars
2781         ret
2782
2783 loadweapon:
2784         ld  a,(your_weapon)
2785         add a,a                 ;weap*2
2786         add a,a                 ;    *4
2787         add a,a                 ;    *8
2788         ld  c,a
2789         ld  b,0
2790         ld  hl,weapondata
2791         add hl,bc
2792         ld  a,(hl)
2793         ld  (weapdamage),a      ;damage of bullets
2794         inc hl
2795         ld  a,(hl)
2796         ld  (weapdaminc),a      ;damage increase
2797         ret
2798
2799 ;----------------------------------------------------------------------------
2800 ;--------------------------- putsprite --------------------------------------
2801 ;----------------------------------------------------------------------------
2802 ;in:  de=(x,y); ix=sprite
2803 ;out: ix=behind sprite; hl:a=right below sprite; b=0; d=width; ce=?
2804
2805 putsprite:
2806         ld  c,(ix)              ;save width
2807 _putsprite:                     ;putsprite with custom width
2808         ld  a,d                 ;a=X
2809         bit 7,d                 ;check sign bit of X
2810         jr  z,CSpositive        ;X>=0
2811
2812         neg                     ;a=|X|
2813         cp  (ix)                ;off screen?
2814         ret nc                  ;X<=-width: don't draw at all
2815         ld  b,a                 ;b=|X|mod 8=1..7=bits to draw
2816         ld  a,%11111111         ;all bits set (draw everything)
2817 CSclipleft:
2818         srl a                   ;remove first bit in a for each b
2819         dnz CSclipleft          ;b=1: a=%01111111
2820                                 ;b=2: a=%00111111
2821                                 ;b=3: a=%00011111
2822                                 ;b=4: a=%00001111
2823                                 ;b=5: a=%00000111
2824                                 ;b=6: a=%00000011
2825                                 ;b=7: a=%00000001
2826         res 7,d                 ;X+128 (right side of screen)
2827         dec e                   ;Y--
2828         jr  CSdisplay           ;done clipping
2829
2830 CSpositive:
2831         sub 129-8               ;minus (screen width - byte width)
2832         ld  b,a
2833         ld  a,%11111111         ;clipmask
2834         jr  c,CSdisplay         ;x+width<128 then entire sprite is on screen
2835         inc b                   ;b = number of pixels off screen
2836 CSclipright:
2837         add a,a                 ;remove last bit in a for each b
2838         dnz CSclipright         ;b=1: a=%11111110
2839                                 ;b=2: a=%11111100
2840                                 ;b=3: a=%11111000
2841                                 ;b=4: a=%11110000
2842                                 ;b=5: a=%11100000
2843                                 ;b=6: a=%11000000
2844                                 ;b=7: a=%10000000
2845                                 ;b>7: a=%00000000 = off screen
2846
2847 CSdisplay:                      ;display the sprite ix at (d,e) masked
2848         ld  (CSclipmask),a      ;set mask
2849         cal findpixel           ;convert de to screen location hl:a
2850         ld  (CSbitmask),a
2851
2852         ld  d,c                 ;width
2853         ld  b,(ix+1)            ;height
2854 CSyloop:
2855         psh bc                  ;save rows to go
2856         psh hl                  ;screen
2857         ld  b,d                 ;width
2858         ld  a,(ix+2)            ;load image line
2859         and 255                 ;mask
2860 CSclipmask =$-1
2861         ld  c,a                 ;c=image
2862         inc ix                  ;next
2863 CSbitmask =$+1
2864         ld  a,1                 ;saved bitmask
2865 CSxloop:
2866         sla c                   ;test leftmost pixel
2867         jr  nc,CSnodraw         ;don't draw if it's 0
2868         ld  e,a                 ;psh af: save bitmask
2869         or  (hl)
2870         ld  (hl),a              ;OR pixel with screen
2871         ld  a,e                 ;pop af
2872 CSnodraw:
2873         rrca                    ;next bit
2874         jr  nc,CSbitdrawn       ;carry set if bit "jumped"
2875         inc hl                  ;next byte
2876 CSbitdrawn:
2877         dnz CSxloop
2878         pop hl                  ;screen at x-offset=0
2879         ld  bc,16
2880         add hl,bc               ;next line
2881         pop bc                  ;rows counter
2882         dnz CSyloop
2883 CSdone: ret
2884
2885 ;--------------------------- putbigsprite -----------------------------------
2886
2887 putwidesprite:
2888 ;destr: abcdehl+ix (ix=behind sprite; hl:a=right below sprite; b=0; d=width)
2889         ld  a,(ix)              ;width
2890         cp  9
2891         jr  c,putsprite         ;width<=8: just draw the sprite
2892
2893         ld  a,(ix)
2894         sub 8                   ;width>8
2895         psh af
2896         ld  c,8
2897         psh de
2898         cal _putsprite          ;otherwise draw one column (8 pixels wide)
2899         pop de
2900         inc ix                  ;no x-size to load
2901         ld  a,8                 ;next
2902         add a,d                 ;8 pixels right
2903         ld  d,a
2904         pop bc                  ;then draw the remaining pixels (c=width-8)
2905         ld  c,b
2906         jr  _putsprite
2907
2908 safeputsprite:                  ;cal putsprite with de intact
2909         psh de
2910         cal putsprite
2911         pop de
2912         ret
2913
2914 ;------------------------------- findpixel ----------------------------------
2915 ;based upon CLEM's fp | 131 cycles | 28 bytes | in:(d,e); out:hla; destr:de
2916
2917 findpixel:
2918         ld  a,e                 ;a=e=Y
2919         add a,a
2920         add a,a                 ;add a,a is 7 cycles faster than add hl,hl
2921         ld  h,0                 ;switch to hl now (Y<64)
2922         ld  l,a                 ;hl=4*Y
2923         ld  a,d                 ;a=d=X
2924         rra                     ;RRA: carry flag must be reset!
2925         add hl,hl               ;that's what the adds are for :P
2926         rra
2927         add hl,hl               ;hl=16*Y
2928         rra                     ;a=X/8
2929         or  l
2930         ld  l,a                 ;hl=hl+a
2931         ld  a,d
2932         and 7                   ;a=X\8
2933         cpl
2934         rlca
2935         rlca
2936         rlca
2937         ld (FPbit),a
2938         xor a
2939 FPbit =$+1
2940         set 0,a
2941         ld  de,dispbuffer       ;screen base position (where x+y=0)
2942 PutWhere =$-2
2943         add hl,de
2944         ret
2945
2946 ;----------------------------------------------------------------------------
2947 ;------------------------------- sprites ------------------------------------
2948 ;----------------------------------------------------------------------------
2949
2950 spr_ship01:
2951         .db 7,7         ;ship alpha class
2952         .db %11000000   ;██
2953         .db %11110000   ;████
2954         .db %01111110   ; ██████
2955         .db %11101000   ;███ █
2956         .db %01111110   ; ██████
2957         .db %11110000   ;████
2958         .db %11000000   ;██
2959 spr_ship01i:
2960         .db 8,7
2961         .db %11000010   ;██    █
2962         .db %11110001   ;████   █
2963         .db %01111111   ; ███████
2964         .db %11101001   ;███ █  █
2965         .db %01111111   ; ███████
2966         .db %11110001   ;████   █
2967         .db %11000010   ;██    █
2968
2969 spr_ship02:
2970         .db 7,7         ;ship beta class
2971         .db %11100000   ;███
2972         .db %11111000   ;█████
2973         .db %01111100   ; █████
2974         .db %01110010   ; ███  █
2975         .db %01111100   ; █████
2976         .db %11111000   ;█████
2977         .db %11100000   ;███
2978 spr_ship02i:
2979         .db 8,7
2980         .db %11100010   ;███   █
2981         .db %11111001   ;█████  █
2982         .db %01111101   ; █████ █
2983         .db %01110011   ; ███  ██
2984         .db %01111101   ; █████ █
2985         .db %11111001   ;█████  █
2986         .db %11100010   ;███   █
2987
2988 spr_ship03:
2989         .db 7,7         ;ship gamma class
2990         .db %11111000   ;█████
2991         .db %01100000   ; ██
2992         .db %11111100   ;██████
2993         .db %11100110   ;███  ██
2994         .db %11111100   ;██████
2995         .db %01100000   ; ██
2996         .db %11111000   ;█████
2997 spr_ship03i:
2998         .db 8,7
2999         .db %11111010   ;█████ █
3000         .db %01100001   ; ██    █
3001         .db %11111101   ;██████ █
3002         .db %11100111   ;███  ███
3003         .db %11111101   ;██████ █
3004         .db %01100001   ; ██    █
3005         .db %11111010   ;█████ █
3006
3007 spr_ship04:
3008         .db 7,7         ;ship delta class
3009         .db %11000000   ; ██
3010         .db %11110000   ; ████
3011         .db %11111100   ; ██████
3012         .db %01100010   ;  ██   █
3013         .db %11111100   ; ██████
3014         .db %11110000   ; ████
3015         .db %11000000   ; ██
3016 spr_ship04i:
3017         .db 8,7
3018         .db %11000010   ; ██    █
3019         .db %11110001   ; ████   █
3020         .db %11111101   ; ██████ █
3021         .db %01100011   ;  ██   ██
3022         .db %11111101   ; ██████ █
3023         .db %11110001   ; ████   █
3024         .db %11000010   ; ██    █
3025
3026 spr_multiple:
3027         .db 6,5         ;multiples
3028         .db %01111000   ;  ████
3029         .db %11001100   ; ██  ██
3030         .db %10000100   ; █    █
3031         .db %11001100   ; ██  ██
3032         .db %01111000   ;  ████
3033
3034 ;-------------------------------- explosions --------------------------------
3035
3036 spr_explosion:
3037         .db 8,6         ;1
3038         .db %00000000
3039         .db %00011100   ;    ███
3040         .db %00111110   ;   █████
3041         .db %01010110   ;  █ █ ██
3042         .db %00111000   ;   ███
3043         .db %00000000
3044
3045         .db 8,6         ;2
3046         .db %00110000   ;   ██
3047         .db %01001110   ;  █ ▒███
3048         .db %10111110   ; █ █████
3049         .db %01001111   ;  █ ▒████
3050         .db %00111000   ;   ███
3051         .db %00011010   ;    ██ █
3052
3053         .db 8,6         ;3
3054         .db %10110000   ; █ ██
3055         .db %01001110   ;  █  ███
3056         .db %10110101   ; █ ██▒█▒█
3057         .db %01000101   ;  █  ▒█▒█
3058         .db %00111110   ;   █████
3059         .db %01011010   ;  █ ██ █
3060
3061         .db 8,6         ;4
3062         .db %00101010   ; ▒ █▒█ █
3063         .db %01000110   ;  █  ▒██
3064         .db %10110101   ; █ ██ █ █
3065         .db %01100110   ;  ██  ██▒
3066         .db %00111100   ;   ████▒
3067         .db %01011001   ;  █ ██ ▒█
3068
3069         .db 8,6         ;5
3070         .db %01000000   ;  █▒ ▒ ▒
3071         .db %00100101   ;  ▒█  █▒█
3072         .db %00010100   ; ▒ ▒█ █ ▒
3073         .db %01000100   ;  █▒  █
3074         .db %00010010   ;   ▒█▒▒█
3075         .db %10011010   ; █▒ ██ █▒
3076
3077         .db 8,6         ;6
3078         .db %01000100   ;  █   █
3079         .db %00100000   ;   ▒█ ▒ ▒
3080         .db %00000001   ;    ▒ ▒ █
3081         .db %01000100   ;  █   █
3082         .db %00100010   ;   █▒  █
3083         .db %01001000   ; ▒█ ▒█ ▒
3084
3085         .db 8,6         ;7
3086         .db %00001000   ;  ▒  █▒
3087         .db %11000010   ; ██ ▒  █
3088         .db %00000000   ;        ▒
3089         .db %00100000   ;  ▒█  ▒
3090         .db %00000001   ;   ▒   ▒█
3091         .db %00110000   ;  ▒██▒
3092
3093         .db 8,6         ;8
3094         .db %00000100   ;     ▒█
3095         .db %00000000   ; ▒▒    ▒
3096         .db %01000000   ;  █
3097         .db %00000000   ;   ▒
3098         .db %00000010   ;       █▒
3099         .db %00100100   ;   █▒ █
3100
3101 spr_yexplosion:
3102         .db 8,5         ;1
3103         .db %00000000
3104         .db %00101100   ;  █ ██
3105         .db %00011110   ;   ████
3106         .db %00110100   ;  ██ █
3107         .db %00011000   ;   ██
3108         .db %00000000
3109
3110         .db 8,5         ;2
3111         .db %00111000   ;  ███
3112         .db %01011100   ; █ ███
3113         .db %10010111   ;█  █ ███
3114         .db %01000110   ; █   ██
3115         .db %00111000   ;  ███
3116         .db %00000000
3117
3118         .db 8,6         ;3
3119         .db %00111100   ;   ████
3120         .db %01001111   ; █  ████
3121         .db %10100011   ;█ █   ██
3122         .db %11000110   ;██   ██
3123         .db %01110101   ; ███ █ █
3124         .db %00111000   ;  ███
3125
3126         .db 8,6         ;4
3127         .db %00110110   ;  ██ ██
3128         .db %00000101   ;     █ █
3129         .db %11000001   ;██     █
3130         .db %01100001   ; ██    █
3131         .db %11000010   ;██    █
3132         .db %01010001   ; █ █   █
3133
3134 ;--------------------------------- bullets ----------------------------------
3135
3136 spr_bullet01:
3137         .db 2,1
3138         .db %11000000   ;▒██
3139 spr_bullet02:
3140         .db 4,1
3141         .db %11110000   ;▒████
3142 spr_bullet03:
3143         .db 2,2
3144         .db %11000000   ;▒██
3145         .db %11000000   ;▒██
3146 spr_bullet04:
3147         .db 3,2
3148         .db %11100000   ;▒███
3149         .db %11100000   ;▒███
3150 spr_bullet05:
3151         .db 4,3
3152         .db %01100000   ; ▒██
3153         .db %11110000   ;▒████
3154         .db %01100000   ; ▒██
3155 spr_bullet06:
3156         .db 5,3
3157         .db %00110000   ;  ▒██
3158         .db %11111000   ;▒█████
3159         .db %00110000   ;  ▒██
3160 spr_bullet07:
3161         .db 5,3
3162         .db %01110000   ; ▒███
3163         .db %11111000   ;▒█████
3164         .db %01110000   ; ▒███
3165 spr_bullet08:
3166         .db 5,3
3167         .db %11110000   ;▒████
3168         .db %11111000   ;▒█████
3169         .db %11110000   ;▒████
3170 spr_bullet09:
3171         .db 5,4
3172         .db %00010000   ;   ▒█
3173         .db %10111000   ;▒█▒███
3174         .db %01111000   ; ▒████
3175         .db %00010000   ;   ▒█
3176 spr_bullet10:
3177         .db 6,4
3178         .db %00111000   ;  ▒███
3179         .db %01111100   ; ▒█████
3180         .db %11111100   ;▒██████
3181         .db %00110000   ;  ▒██
3182 spr_bullet11:
3183         .db 7,5
3184         .db %00011000   ;   ▒██
3185         .db %11111100   ;▒██████
3186         .db %00111110   ;  ▒█████
3187         .db %01111100   ; ▒█████
3188         .db %00011000   ;   ▒██
3189 spr_bullet12:
3190         .db 7,6
3191         .db %00110000   ;  ▒██
3192         .db %11111100   ;▒██████
3193         .db %00111110   ;  ▒█████
3194         .db %01111110   ; ▒██████
3195         .db %11111100   ;▒██████
3196         .db %00111000   ;  ▒███
3197 spr_bullet13:
3198         .db 8,8
3199         .db %00111100   ;  ▒████
3200         .db %11111110   ;▒███████
3201         .db %01111111   ; ▒███████
3202         .db %00011111   ;   ▒█████
3203         .db %01111111   ; ▒███████
3204         .db %11111110   ;▒███████
3205         .db %00111100   ;  ▒████
3206 spr_bullett1:
3207         .db 4,3         ;▒▒▒
3208         .db %11100000   ;▒███
3209         .db %11110000   ; ████
3210         .db %01110000   ;  ███
3211
3212 spr_bullete1:
3213         .db 4,3         ;enemy bullets
3214         .db %01100000   ; ██▒
3215         .db %11110000   ;████▒
3216         .db %01100000   ; ██▒
3217
3218 bullettable:
3219         .db (spr_bullet01-spr_bullet01) ;0
3220         .db (spr_bullet02-spr_bullet01) ;4
3221         .db (spr_bullet03-spr_bullet01) ;8
3222         .db (spr_bullet04-spr_bullet01) ;12
3223         .db (spr_bullet05-spr_bullet01) ;16
3224         .db (spr_bullet06-spr_bullet01) ;20
3225         .db (spr_bullet07-spr_bullet01) ;24
3226         .db (spr_bullet08-spr_bullet01) ;28
3227         .db (spr_bullet09-spr_bullet01) ;32
3228         .db (spr_bullet10-spr_bullet01) ;36
3229         .db (spr_bullet11-spr_bullet01) ;40
3230         .db (spr_bullet12-spr_bullet01) ;44
3231         .db (spr_bullet13-spr_bullet01) ;48
3232         .db (spr_bullet13-spr_bullet01) ;52
3233         .db (spr_bullet13-spr_bullet01) ;56
3234         .db (spr_bullet13-spr_bullet01) ;60
3235
3236 ;format:[min.damage] [dam.inc] [000:direction 00000:speed] [offset]
3237 ;damage = min.damage + dam.inc*incs (0<=incs<=6)
3238 ;speed in pixels/frame (>=%10010=forward; <=%01110=backwards)
3239 ;direction: 0=straight forward; 1=up; 2=1/2up; 3=down; 4=1/2down
3240
3241 maxnrweapons = 8+1
3242 weapondata:
3243         .db 1,1,%00000000,0,%00000000,0,%00010010,3     ;1 single fire
3244         .db 4,1,%00000000,0,%00000000,0,%00010011,3     ;2 fast single
3245         .db 1,1,%00000000,0,%00010010,0,%00010010,6     ;3 double
3246         .db 1,1,%01110010,2,%10010010,2,%00110010,2     ;4 triple
3247         .db 3,2,%01110011,2,%10010011,2,%00110011,2     ;5
3248         .db 5,3,%01110011,2,%10010100,2,%00110011,2     ;6
3249         .db 7,4,%01110100,2,%10010100,2,%00110100,2     ;7
3250         .db 12,5,%01110110,2,%10010110,2,%00110110,2    ;8
3251 maxweapon = 8
3252         .db 1,1,%00000000,0,%00000000,0,%11100000,3     ;1 single laser
3253         .db 1,1,%00000000,0,%11100000,0,%11100000,6     ;2 double laser
3254         .db 1,1,%11100000,0,%11100000,6,%11100000,3     ;3 triple laser
3255 maxlaser = 11
3256
3257 collidedamage = 4
3258
3259 ;------------------------------------ bar -----------------------------------
3260
3261 spr_lship:
3262         .db 5,3                 ;li'l ship indicating lives left
3263         .db %11100000           ;███
3264         .db %01111000           ; ████
3265         .db %11100000           ;███
3266 lshipsize = 5                   ;space between two ship icons
3267
3268 spr_icon:
3269         .db 16,7        ;selected.......:.......:
3270         .db %11111111           ;████████████████
3271         .db %11000000           ;██             █
3272         .db %11000000           ;██             █
3273         .db %11000000           ;██             █
3274         .db %11000000           ;██             █
3275         .db %11000000           ;██             █
3276         .db %11111111           ;████████████████
3277         .db 7
3278         .db %11111111
3279         .db %00000001
3280         .db %00000001
3281         .db %00000001
3282         .db %00000001
3283         .db %00000001
3284         .db %11111111
3285 spr_icon00:
3286         .db 16,7        ;unused  .......:.......:
3287         .db %10101010           ;█ █ █ █ █ █ █ █
3288         .db %11010101           ;██ █ █ █ █ █ █ █
3289         .db %10101010           ;█ █ █ █ █ █ █ █
3290         .db %11010101           ;██ █ █ █ █ █ █ █
3291         .db %10101010           ;█ █ █ █ █ █ █ █
3292         .db %11010101           ;██ █ █ █ █ █ █ █
3293         .db %10101010           ;█ █ █ █ █ █ █ █
3294         .db 7
3295         .db %10101010
3296         .db %01010101
3297         .db %10101010
3298         .db %01010101
3299         .db %10101010
3300         .db %01010101
3301         .db %10101010
3302 spr_icon01:
3303         .db 16,7        ;armor  ;.......:.......:
3304         .db %10000111           ;█    ███████    ▒
3305         .db %10011000           ;█  ██       ██  ▒
3306         .db %10110011           ;█ ██  ████   ██ ▒
3307         .db %10110000           ;█ ██    ████ ██ ▒
3308         .db %10110011           ;█ ██  ████   ██ ▒
3309         .db %10011000           ;█  ██       ██  ▒
3310         .db %10000111           ;█    ███████    ▒
3311         .db 7
3312         .db %11110000
3313         .db %00001100
3314         .db %11000110
3315         .db %11100110
3316         .db %11000110
3317         .db %00001100
3318         .db %11110000
3319 spr_icon02:
3320         .db 16,7        ;tailbeam.......:.......:
3321         .db %10000000           ;█               ▒
3322         .db %10000011           ;█     ██        ▒
3323         .db %10000001           ;█      ███      ▒
3324         .db %10111011           ;█ ███ ██████  ██▒
3325         .db %10000001           ;█      ███      ▒
3326         .db %10000011           ;█     ██        ▒
3327         .db %10000000           ;█               ▒
3328         .db 7
3329         .db %00000000
3330         .db %00000000
3331         .db %11000000
3332         .db %11110011
3333         .db %11000000
3334         .db %00000000
3335         .db %00000000
3336 spr_icon02b:
3337         .db 16,7        ;torpedo .......:.......:
3338         .db %10111000           ;█ ███      █ █ █▒
3339         .db %10011100           ;█  ███     █ █ █▒
3340         .db %10111000           ;█ ███    █  █ █ ▒
3341         .db %10000000           ;█       ███ █ █ ▒
3342         .db %11100001           ;███    ████  █ █▒
3343         .db %10011000           ;█  ██   ████ █ █▒
3344         .db %11100110           ;███  ██   ██  █ ▒
3345         .db 7
3346         .db %00010101
3347         .db %00010101
3348         .db %01001010
3349         .db %11101010
3350         .db %11100101
3351         .db %11110101
3352         .db %00110010
3353 spr_icon03:
3354         .db 16,7        ;bullets .......:.......:
3355         .db %10000000           ;█       ██      ▒
3356         .db %10000011           ;█     █████ ▒▒▒ ▒
3357         .db %10011000           ;█  ██   ██  ▒▒▒ ▒
3358         .db %11111100           ;██████      ▒▒▒ ▒
3359         .db %10011000           ;█  ██   ██  ▒▒▒ ▒
3360         .db %10000011           ;█     █████ ▒▒▒ ▒
3361         .db %10000000           ;█       ██      ▒
3362         .db 7
3363         .db %11000000
3364         .db %11100000
3365         .db %11000000
3366         .db %00000000
3367         .db %11000000
3368         .db %11100000
3369         .db %11000000
3370 spr_icon04:
3371         .db 16,7        ;laser   .......:.......:
3372         .db %10000000           ;█               ▒
3373         .db %10001010           ;█   █ █     ▒▒▒ ▒
3374         .db %11101100           ;███ ██      ▒▒▒ ▒
3375         .db %11110111           ;████ ███████▒▒▒█▒
3376         .db %11101100           ;███ ██      ▒▒▒ ▒
3377         .db %10001010           ;█   █ █     ▒▒▒ ▒
3378         .db %10000000           ;█               ▒
3379         .db 7
3380         .db %00000000
3381         .db %00000000
3382         .db %00000000
3383         .db %11111111
3384         .db %00000000
3385         .db %00000000
3386         .db %00000000
3387 spr_icon05:
3388         .db 16,7        ;multiple.......:.......:
3389         .db %10000011           ;█     ███       ▒
3390         .db %10000001           ;█      ████  ██ ▒
3391         .db %10000001           ;█      ████     ▒
3392         .db %10000011           ;█     ███       ▒
3393         .db %10011000           ;█  ██           ▒
3394         .db %10111100           ;█ ████  ██    ██▒
3395         .db %10011000           ;█  ██           ▒
3396         .db 7
3397         .db %10000000
3398         .db %11100110
3399         .db %11100000
3400         .db %10000000
3401         .db %00000000
3402         .db %11000011
3403         .db %00000000
3404 spr_dividerline:
3405         .db 8,7
3406         .db 128,128,128,128,128,128,128 ;128 = %10000000
3407
3408 ;---------------------------- texts -----------------------------------------
3409
3410 txt_email:      .db "www.shiar.org ",127 ;title screen
3411                 .db " shiar0@hotmail.com",0
3412 _txt_email = $3A01 ;$3A1E=just email
3413 txt_about:      .db "v0.98.79 ",127," by Shiar",0 ;right behind txt_email
3414 _txt_about = $3321
3415 txt_menu1:      .db "NEW GAME",0
3416 txt_menu2:      .db "CONTINUE",0
3417
3418 txt_level:      .db "LEVEL ",0 ;new level screen
3419 txt_lives:      .db   "Lx0",0
3420 txt_savekey:    .db "Press [F1] to save",0
3421
3422 txt_gameover:   .db "GAME OVER!",0 ;game over screen
3423 txt_score:      .db "Score",0
3424 txt_hiscore:    .db "Hiscore",0
3425
3426 txt_pressenter: .db "Enter to continue",0 ;pause
3427 txt_teacher:    .db "(2",Lpi,"*.98)/sin 13",0 ;teacher
3428 txt_teacherans: .db Lneg,"14.6549373495",0
3429
3430 ;---------------------------- save data -------------------------------------
3431
3432 storehi_start:
3433 hiscore         .dw 0                   ;default hiscore
3434 hiname          .db "shiar.98",0        ;   "       "    name
3435 storehi_end:
3436
3437 storesave_start:                        ;--SAVED GAME--                 defs:
3438 level           .db  1                  ;level number                   1
3439 levelp          .dw level01             ;pointer to level data          l01
3440 pickuptimer     .db  4                  ;counts when to place a pickup  4
3441 your_ship       .dw spr_ship01          ;your sprite                    sprs1
3442 your_score      .dw  0                  ;current score                  0
3443 your_pickup     .db  3                  ;pickups already picked up      0
3444 your_occ        .db  0                  ;0=normal 1..16=exploding       0
3445 your_inv        .db  0                  ;invincibility left             0
3446 your_armor      .db 12                  ;HP left                        12
3447 your_lives      .db  3                  ;lives left                     3
3448 your_weapon     .db  0                  ;current weapon upgrade         0
3449 your_multiples  .db  0                  ;multiples present              0
3450 your_tail       .db  0                  ;tail beam present              0
3451 storesave_end:
3452
3453 time2invert:    .db 0                   ;time until b<>w switch (0 at startup)
3454
3455 ;------------------------------ levels data ---------------------------------
3456
3457 ;format:boss: [moveType] [enemyType]
3458 ;       @level: [nr.dif.enemies]x [enemy nr]
3459 ;       [min. enemy frequency] [enemy frequency max.inc] [next lvl]
3460 ;       [level_info: 0000:damage 0:diagfire 0:ground 0:ceiling 0:?]
3461 ;       [level_move] [tunnel size] [groundtype]
3462 ;       [16_ground] [16_ceiling] [stars1] [stars2]
3463 ;efrequency must be odd if halfluring!
3464
3465 level00:
3466         .db 0                           ;story identifier
3467         .db $21,$1d,"Cosmic year 6716"          ,0,0,$1d,$06
3468         .db $1b,$1d,"STORYLINE COMING SOON"     ,0,0,$1d,$06
3469         .db $09,$19,"STORYLINE COMING SOON"     ,0,1
3470         .db $2e,$21,"**** NEMESIS 86"           ,0,1
3471         .db $52,$36,"by Shiar"                  ,0,0,$19,$23
3472         .db $ff                         ;story end
3473
3474         .db 20 ;boss for level01
3475 level01:                        ;intro-like, just a few enemies to begin with
3476         .db 2,6,8
3477         .db 26,70,20,%00010000,0,0,0
3478         .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3479         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3480         .db 1,1
3481
3482         .db 21
3483 level02:                        ;first wave of enemies; easeey
3484         .db 3,6,7,8
3485         .db 20,60,60,%00100000,0,0,0
3486         .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3487         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3488         .db 1,1
3489
3490         .db 22
3491 level03:                        ;some more enemies
3492         .db 4,7,8,9,10
3493         .db 17,40,75,%00110000,0,0,0
3494         .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3495         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3496         .db 1,1
3497
3498         .db 0,0 ;storyline ID
3499         .db 1,1,"Long-Range scanners are ",
3500         .db     "showing",0,1
3501         .db 1,8,"lots of enemy vessels on ",
3502         .db     "an intercept",0,1
3503         .db 1,15,"course.",0,1
3504         .db 1,24,"I'm changing course to a",
3505         .db     " nearby ",0,1
3506         .db 1,31,"asteroid belt and try to",0,1
3507         .db 1,38,"lose them inthere.",0,0
3508         .db 1,38+5,$FF
3509
3510         .db 23
3511 level04:                        ;light asteroid belt
3512         .db 3,1,2,4
3513         .db 12,24,80,%00111000
3514         .db 2,0,0
3515         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1     ;16
3516         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3517         .db 1,1
3518
3519         .db 24
3520 level05:                        ;inside asteroid belt
3521         .db 5,1,2,3,4,5
3522         .db 6,10,180,%01011000
3523         .db 2,0,0
3524         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1     ;16
3525         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3526         .db 1,1
3527
3528         .db 25
3529 level02a:
3530         .db 3,4,5,6
3531         .db 30,1,40,%01000000
3532         .db 0,0,0
3533         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1     ;16
3534         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3535         .db 1,1
3536
3537         .db 0
3538
3539         .db 0
3540         .db $01,01,"And the storyline conti",
3541                 .db "nues.....",0,1
3542         .db $01,09,"You decide to fly close",
3543                 .db " to the",0,1
3544         .db $01,15,"surface of a nearby pl",
3545                 .db "anet =)",0,0,1,20
3546         .db $FF
3547
3548         .db 26
3549 level03b:
3550         .db 1,$02
3551         .db $13,40,$4b,%00100100,0,-5,1
3552         .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3553         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3554         .db 1,1
3555
3556         .db 0
3557
3558         .db 0
3559         .db $01,01,"Blablabla...",0,1
3560         .db $01,34,"this storyline sux",0,0,1,39
3561         .db $FF
3562
3563         .db 27
3564 level03a:
3565         .db 1,$03
3566         .db $2d,$3f,%00010110,0,-9,1
3567         .db 3,2,4,3,2,2,1,1,1,1 ,1,1,21,17,18,20
3568         .db 1,1,1,1,1,1,1,3,6,12,9,1,21,19,18,18
3569         .db -1,-1 ;=%11111111=line
3570
3571         .db $07,$08
3572 level04b:
3573         .db 1,$04
3574         .db $11,$41,%00100001,0,0,0
3575         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3576         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3577         .db 1,1
3578         .db $07,$09
3579 level05a:
3580         .db 1,$05
3581         .db $11,$45,%00100101,%10,-7,1
3582         .db 14,12,11,9,10,7,7,5,4,3,4,4,2,3,1,2
3583         .db 1, 1, 1, 1,1, 1,1,1,1,1,1,1,1,1,1,1
3584         .db 1,1
3585         .db $07,$08
3586 level06c:
3587         .db 1,$06
3588         .db $19,$3a,%00100111,0,-4,1
3589         .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
3590         .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
3591         .db 1,1
3592
3593         .db $07,$09
3594 level07:
3595         .db 1,$07
3596         .db $09,$ff,%00100001,0,0,0
3597         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3598         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3599         .db 1,1
3600
3601 ;------------------------------ enemies -------------------------------------
3602
3603 ;format: [HP64] [000000:HP 00:occ] [sprite] [xpos] [appearance(ypos)]
3604 ;        [movetype] [time2fire] [firefreq]
3605 ;appearances: 1=random; 2=lure; 3=halflure
3606 ;case movetype:
3607 ;  1=updown; 2=1/4x; 3=1/2x; 4=1.5x; 5=2x; 6=smart; 7=y-lure;
3608 ;  8=y-lure 1/2x; 9=8 stop at x=99; 10=x+y-lure 1/2x
3609 enemyspecs:
3610 ;1-5=asteroids
3611         .db 0,%00100110,(spr_enemyA1-spr_enemy00)/2,128,1,0,0,0
3612         .db 0,%00111110,(spr_enemyA2-spr_enemy00)/2,128,1,0,0,0
3613         .db 0,%01011010,(spr_enemyA3-spr_enemy00)/2,128,1,4,0,0
3614         .db 1,%00001010,(spr_enemyA4-spr_enemy00)/2,128,1,3,0,0
3615         .db 0,%00111110,(spr_enemyA4-spr_enemy00)/2,128,1,5,0,0
3616 ;6-10=basic enemies
3617         .db 0,%00010010,(spr_enemyE1-spr_enemy00)/2,128,1,0,10,0 ;weak
3618         .db 0,%00110010,(spr_enemyE4-spr_enemy00)/2,128,1,3,6,50 ;slow
3619         .db 0,%00100110,(spr_enemyE2-spr_enemy00)/2,128,1,0,1,0
3620         .db 0,%00101110,(spr_enemyE3-spr_enemy00)/2,128,3,0,19,39
3621         .db 0,%00101010,(spr_enemyE5-spr_enemy00)/2,128,3,4,1,0 ;fast
3622 ;11=jumping bug (up/down)
3623         .db 0,%00001111,(spr_enemyN3-spr_enemy00)/2,128,2,1,87,5
3624
3625         .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;12
3626         .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;13
3627         .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;14
3628         .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;15
3629         .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;16
3630         .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;17
3631         .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;18
3632         .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;19
3633 ;20-22=first bosses
3634         .db 1,%00101011,(spr_boss0_1-spr_enemy00)/2,127,1,8,20,12       ;20
3635         .db 1,%00110011,(spr_boss0_1-spr_enemy00)/2,127,1,8,15,10       ;21
3636         .db 1,%01001011,(spr_boss0_2-spr_enemy00)/2,127,3,9,10,9        ;22
3637 ;23-24=asteroid bosses
3638         .db 2,%00001011,(spr_boss0_3-spr_enemy00)/2,127,1,10,36,14
3639         .db 2,%00110011,(spr_boss0_3-spr_enemy00)/2,127,2,10,28,12
3640 ;25-26=big bosses
3641         .db 2,%00000111,(spr_boss0_4-spr_enemy00)/2,127,3,7,18,7        ;25=bigboss1
3642         .db 2,%01001011,(spr_boss0_5-spr_enemy00)/2,127,3,7,18,7        ;26=bigboss2
3643
3644 spr_enemy00:
3645         .db 16,8                        ;pickup
3646         .db %11111111                   ; ████████████
3647         .db %10000110                   ; █    ██    █
3648         .db %10000110                   ; █    ██    █
3649         .db %10111111                   ; █ ████████ █
3650         .db %10111111                   ; █ ████████ █
3651         .db %10000110                   ; █    ██    █
3652         .db %10000110                   ; █    ██    █
3653         .db %11111111                   ; ████████████
3654         .db 8
3655         .db %11110000
3656         .db %00010000
3657         .db %00010000
3658         .db %11010000
3659         .db %11010000
3660         .db %00010000
3661         .db %00010000
3662         .db %11110000
3663         .db 0
3664
3665 spr_enemyA1:
3666         .db 7,6                         ;asteroid one
3667         .db %00011000                   ;   ██
3668         .db %01101100                   ; ██ ██
3669         .db %10011110                   ;█  ████
3670         .db %11111010                   ;█████ █
3671         .db %10111100                   ;█ ████
3672         .db %01110000                   ; ███
3673 spr_enemyA2:
3674         .db 8,7                         ;asteroid two
3675         .db %00111100                   ;  ████
3676         .db %01011010                   ; █ ██ █
3677         .db %01101101                   ; ██ ██ █
3678         .db %11111101                   ;██████ █
3679         .db %11111111                   ;████████
3680         .db %10110110                   ;█ ██ ██
3681         .db %01100000                   ; ██
3682         .db 0
3683 spr_enemyA3:
3684         .db 8,8                         ;asteroid three
3685         .db %00011110                   ;   ████
3686         .db %01110011                   ; ███  ██
3687         .db %01111101                   ; █████ █
3688         .db %10110111                   ;█ ██ ███
3689         .db %11111110                   ;███████
3690         .db %11111101                   ;██████ █
3691         .db %01010111                   ; █ █ ███
3692         .db %00001110                   ;    ███
3693 spr_enemyA4:
3694         .db 7,6                         ;asteroid four
3695         .db %01111000                   ; ████
3696         .db %10110110                   ;█ ██ ██
3697         .db %11111101                   ;██████ █
3698         .db %01111011                   ; ████ ██
3699         .db %01001110                   ; █  ███
3700         .db %00110000                   ;  ██
3701
3702 spr_enemyE1:
3703         .db 6,7                         ;weak
3704         .db %00111100                   ;  ████
3705         .db %01000100                   ; █   █
3706         .db %10111000                   ;█ ███
3707         .db %11100000                   ;███
3708         .db %10111000                   ;█ ███
3709         .db %01000100                   ; █   █
3710         .db %00111100                   ;  ████
3711         .db 0
3712 spr_enemyE2:
3713         .db 6,6                         ;weak
3714         .db %00111100                   ;  ████
3715         .db %01010000                   ; █ █
3716         .db %10100000                   ;█ █
3717         .db %10100000                   ;█ █
3718         .db %01010000                   ; █ █
3719         .db %00111100                   ;  ████
3720 spr_enemyE3:
3721         .db 6,6                         ;normal solid (Galaxian enemy)
3722         .db %00111100                   ;  ████
3723         .db %01110000                   ; ███
3724         .db %11110000                   ;████
3725         .db %11110000                   ;████
3726         .db %01110000                   ; ███
3727         .db %00111100                   ;  ████
3728 spr_enemyE4:
3729         .db 6,7
3730         .db %00011100                   ;   ███
3731         .db %01101000                   ; ██ █
3732         .db %10011000                   ;█  ██
3733         .db %01110000                   ; ███
3734         .db %10011000                   ;█  ██
3735         .db %01101000                   ; ██ █
3736         .db %00011100                   ;   ███
3737         .db 0
3738 spr_enemyE5:
3739         .db 6,6                         ;speedy
3740         .db %00011100                   ;   ███
3741         .db %01111000                   ; ████
3742         .db %11100000                   ;███
3743         .db %11100000                   ;███
3744         .db %01111000                   ; ████
3745         .db %00011100                   ;   ███
3746
3747 spr_enemyG1:
3748         .db 8,6                         ;G-Type
3749         .db %00111111                   ;   █████
3750         .db %01001000                   ; █  █
3751         .db %10110100                   ;█ ██ █
3752         .db %10110100                   ;█ ██ █
3753         .db %01001000                   ; █  █
3754         .db %00111111                   ;   █████
3755 spr_enemyG2:
3756         .db 8,6                         ;smaller nacelles
3757         .db %00000111                   ;     ███
3758         .db %01101100                   ; ██ ██
3759         .db %10110100                   ;█ ██ █
3760         .db %10110100                   ;█ ██ █
3761         .db %01101100                   ; ██ ██
3762         .db %00000111                   ;     ███
3763 spr_enemyG3:
3764         .db 8,6                         ;shuttle
3765         .db %00001111                   ;    ████
3766         .db %01111100                   ; █████
3767         .db %10011100                   ;█  ███
3768         .db %10011100                   ;█  ███
3769         .db %01111100                   ; █████
3770         .db %00001111                   ;    ████
3771 spr_enemyG4:
3772         .db 8,6                         ;G-Type solid
3773         .db %00111111                   ;   █████
3774         .db %01111000                   ; ████
3775         .db %11111100                   ;██████
3776         .db %11111100                   ;██████
3777         .db %01111000                   ; ████
3778         .db %00111111                   ;   █████
3779 spr_enemyG5:
3780         .db 6,6                         ;G lost his head; large window ;)
3781         .db %01111100                   ; █████
3782         .db %10110000                   ;█ ██
3783         .db %10111000                   ;█ ███
3784         .db %10111000                   ;█ ███
3785         .db %10110000                   ;█ ██
3786         .db %01111100                   ; █████
3787 spr_enemyG6:
3788         .db 7,6                         ;small G-type
3789         .db %00011110                   ;   ████
3790         .db %01111000                   ; ████
3791         .db %11110000                   ;████
3792         .db %11110000                   ;████
3793         .db %01111000                   ; ████
3794         .db %00011110                   ;   ████
3795
3796 spr_enemyS1:
3797         .db 6,6                         ;solid
3798         .db %00111000                   ;   ███
3799         .db %01111100                   ;  █████
3800         .db %11111000                   ; █████
3801         .db %11111000                   ; █████
3802         .db %01111100                   ;  █████
3803         .db %00111000                   ;   ███
3804 spr_enemyS2:
3805         .db 7,6                         ;some attack vessel
3806         .db %00011100                   ;    ███
3807         .db %01110010                   ;  ███  █
3808         .db %10101100                   ; █ █ ██
3809         .db %10101100                   ; █ █ ██
3810         .db %01110010                   ;  ███  █
3811         .db %00011100                   ;    ███
3812 spr_enemyS3:
3813         .db 7,6                         ;interceptor
3814         .db %00011110                   ;    ████
3815         .db %01111110                   ;  ██████
3816         .db %11111100                   ; ██████
3817         .db %11111100                   ; ██████
3818         .db %01111110                   ;  ██████
3819         .db %00011110                   ;    ████
3820 spr_enemyS4:
3821         .db 8,6                         ;cheap intercept
3822         .db %00011011                   ;    ██ ██
3823         .db %01110110                   ;  ███ ██
3824         .db %10111100                   ; █ ████
3825         .db %10111100                   ; █ ████
3826         .db %01110110                   ;  ███ ██
3827         .db %00011011                   ;    ██ ██
3828
3829 spr_enemyN1:
3830         .db 8,7                         ;some cool Nemesis-MSX enemy
3831         .db %00111110                   ;  █████
3832         .db %11110001                   ;████   █
3833         .db %00001110                   ;    ███
3834         .db %00010101                   ;   █ █ █
3835         .db %00001110                   ;    ███
3836         .db %11110001                   ;████   █
3837         .db %00111110                   ;  █████
3838         .db 0
3839 spr_enemyN2:
3840         .db 8,7                         ;
3841         .db %00111110                   ;  █████
3842         .db %00011101                   ;   ███ █
3843         .db %11111111                   ;████ ███
3844         .db %01110110                   ; ██ ███
3845         .db %11111111                   ;████ ███
3846         .db %00011101                   ;   ███ █
3847         .db %00111110                   ;  █████
3848         .db 0
3849 spr_enemyN3:
3850         .db 8,7                         ;Nem3MSX jumper lvl#3
3851         .db %10111110                   ;█ █████
3852         .db %01011101                   ; █ ███ █
3853         .db %01111110                   ; ██████
3854         .db %00010100                   ;   █ █
3855         .db %01111110                   ; ██████
3856         .db %01011101                   ; █ ███ █
3857         .db %10111110                   ;█ █████
3858         .db 0
3859
3860 spr_boss0_1:
3861         .db 16,10               ;boss type one..:.......:
3862         .db %00000001                   ;       ██████ ██
3863         .db %00001110                   ;    ███   █ ███
3864         .db %00110010                   ;  ██  █ ████
3865         .db %01001101                   ; █  ██ ██
3866         .db %11101011                   ;███ █ ██ █
3867         .db %11101011                   ;███ █ ██ █
3868         .db %01001101                   ; █  ██ ██
3869         .db %00110010                   ;  ██  █ ████
3870         .db %00001110                   ;    ███   █ ███
3871         .db %00000001                   ;       ██████ ██
3872         .db 10
3873         .db %11111011
3874         .db %00101110
3875         .db %11110000
3876         .db %10000000
3877         .db %01000000
3878         .db %01000000
3879         .db %10000000
3880         .db %11110000
3881         .db %00101110
3882         .db %11111011
3883         .db 0
3884 spr_boss0_2:
3885         .db 16,10               ;boss type two..:.......:
3886         .db %11111110                   ;███████
3887         .db %00000011                   ;      ███   ████
3888         .db %00110101                   ;  ██ █ ████    █
3889         .db %01111010                   ; ████ █ █  █ ██
3890         .db %10001101                   ;█   ██ █ ██ ██
3891         .db %10001101                   ;█   ██ █ ██ ██
3892         .db %01111010                   ; ████ █ █  █ ██
3893         .db %00110101                   ;  ██ █ ████    █
3894         .db %00000011                   ;      ███   ████
3895         .db %11111110                   ;███████
3896         .db 9
3897         .db %00000000
3898         .db %10001111
3899         .db %11100001
3900         .db %10010110
3901         .db %01101100
3902         .db %01101100
3903         .db %10010110
3904         .db %11100001
3905         .db %10001111
3906 spr_boss0_3:
3907         .db 16,11                       ;bigasteroid one
3908         .db %00011110                   ;   ████
3909         .db %01110011                   ; ███  ███
3910         .db %01111111                   ; ███████ █
3911         .db %01111111                   ; █████████
3912         .db %11111110                   ;███████ ███
3913         .db %11111111                   ;███████████
3914         .db %11111111                   ;████████████
3915         .db %10111110                   ;█ █████ ████
3916         .db %01011111                   ; █ ███████
3917         .db %00110111                   ;  ██ ███
3918         .db %00001110                   ;    ███
3919         .db 9
3920         .db %00000000
3921         .db %10000000
3922         .db %01000000
3923         .db %11000000
3924         .db %11100000
3925         .db %11100000
3926         .db %11110000
3927         .db %11110000
3928         .db %11000000
3929         .db 0
3930 spr_boss0_4:
3931         .db 16,18                       ;bigboss one    :
3932         .db %00000000                   ;         █ █
3933         .db %00000111                   ;     ███ ███
3934         .db %00000011                   ;      ████ █
3935         .db %00000001                   ;       ██ ██
3936         .db %00000011                   ;      ███ ██
3937         .db %00000000                   ;        █████
3938         .db %00010111                   ;   █ ██████████
3939         .db %00111111                   ;  ██████ ██ ██
3940         .db %11111000                   ;█████   ██ █ ███
3941         .db %00001111                   ;    █████ ██ █ █
3942         .db %11111000                   ;█████   ██ █ ███
3943         .db %00111111                   ;  ██████ ██ ██
3944         .db %00010111                   ;   █ ██████████
3945         .db %00000000                   ;        █████
3946         .db %00000011                   ;      ███ ██
3947         .db %00000001                   ;       ██ ██
3948         .db %00000011                   ;      ████ █
3949         .db %00000111                   ;     ███ ███
3950         .db 19                          ;         █ █
3951         .db %01010000                   ;modelled after a Nemesis][MSX boss
3952         .db %01110000
3953         .db %11010000
3954         .db %10110000
3955         .db %10110000
3956         .db %11111000
3957         .db %11111110
3958         .db %01101100
3959         .db %11010111
3960         .db %10110101
3961         .db %11010111
3962         .db %01101100
3963         .db %11111110
3964         .db %11111000
3965         .db %10110000
3966         .db %10110000
3967         .db %11010000
3968         .db %01110000
3969         .db %01010000
3970 spr_boss0_5:
3971         .db 16,15                       ;bigboss two    :
3972         .db %00001111                   ;    █████
3973         .db %00111110                   ;  █████ █████
3974         .db %01111101                   ; █████ █ ███████
3975         .db %00000011                   ;      ██
3976         .db %00000100                   ;     █  █
3977         .db %00000011                   ;      █████
3978         .db %00011110                   ;   ████ ██ ████
3979         .db %11110011                   ;████  ██ █ █
3980         .db %00011110                   ;   ████ ██ ████
3981         .db %00000011                   ;      █████
3982         .db %00000100                   ;     █  █
3983         .db %00000011                   ;      ██
3984         .db %01111101                   ; █████ █ ███████
3985         .db %00111110                   ;  █████ █████
3986         .db %00001111                   ;    █████
3987         .db 15                          ;modelled after a Nemesis][MSX boss
3988         .db %10000000
3989         .db %11111000
3990         .db %01111111
3991         .db %00000000
3992         .db %10000000
3993         .db %11100000
3994         .db %11011110
3995         .db %01010000
3996         .db %11011110
3997         .db %11100000
3998         .db %10000000
3999         .db %00000000
4000         .db %01111111
4001         .db %11111000
4002         .db %10000000
4003         .db 0
4004
4005 ;----------------------------------------------------------------------------
4006 ;----------------------------- logo ------------------------------------------
4007 ;----------------------------------------------------------------------------
4008
4009 logo_nemesis:
4010 .db %11111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00001011,%11111111,%11111111,%11111111,%11111110
4011 .db %01111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00011011,%11111111,%11111111,%11111111,%11111100
4012 .db %00111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00111011,%11111111,%11111111,%11111111,%11111000
4013 .db %00011111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%01111011,%11111111,%11111111,%11111111,%11110000
4014 .db %00000000,%00000000,%00000001,%00011110,%00010000,%00000000,%10000001,%00011110,%00010000,%000000001,%00000000,%00001000,%01000000,%00000000,%00000000,%00000000
4015 .db %00000000,%00000000,%00000011,%00011110,%00110000,%00000001,%10000011,%00011110,%00110000,%000000011,%00000000,%00011000,%11000000,%00000000,%00000000,%00000000
4016 .db %00000000,%00000000,%00000111,%00011110,%01110000,%00000011,%10000111,%00011110,%01110000,%000000111,%00000000,%00111001,%11000000,%00000000,%00000000,%00000000
4017 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4018 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4019 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4020 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4021 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4022 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4023 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4024 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4025 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000111,%11010001
4026 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00011011
4027 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010101
4028 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010001
4029
4030 ;----------------------------- end ------------------------------------------
4031
4032         .end
4033 .end
4034
4035
4036 ;----------------------------------------------------------------------------
4037 ;----------------------------------------------------------------------------
4038 ;----------------------------------------------------------------------------
4039
4040 ; 0.98.77 -- 7.VII.00 -- size 6707
4041 ;
4042 ;       # bullets do damage in all levels
4043 ;       * more armor at armor-upgrade and extra armor at end of a level
4044 ;       - internal levels again (no need 4 external, safer/smaller)
4045 ;       # some registers not correctly pushed/popped
4046 ;       * several optimizations (init.procs some bytes smaller)
4047 ;       # enemies hit with hitpoints left disappeared (one pop too much...)
4048 ;       + bullets "charge up" (more damage) when not firing
4049 ;       - removed contrast changes
4050 ;       + more powerful bullets have different sprites (larger=more damage)
4051 ;       # multiples appear at your position (begin level/just selected)
4052 ;       # when invulnerable multiples acted weird
4053 ;       # no more error at activation after APD off after running Nemesis
4054 ;       # saves correctly if own name ain't "nemesis" + some bytes smaller
4055 ;       # screen wasn't always entirely cleared after quit
4056 ;       * waits until all keys have been released after death
4057 ;       + different bullets sizes will miss if they're too small
4058 ;       + at level start "press F1 to save"-text will be displayed
4059 ;       * w3.shiar.org displayed at title screen, black bar behind version nr
4060 ;       # score to 0 when exit pressed at main menu
4061 ;       # no residual story-text in first frame of game
4062 ;       # game doesn't continue again after death (stack messed up)
4063 ;       # game over when lives<0 (didn't work in v0.96+)
4064 ;       * using some self-modifiing code (so it's smaller)
4065 ;       # new random procedure: stars don't appear on one line anymore
4066 ;       * weapons appear centered at multiples
4067 ;       * laser properties can be changed (damage, charge)
4068 ;       + weapon can be combination of bullets/lasers (max. of 3 per weapon)
4069 ;       * bullet-icon is removed when laser is selected
4070 ;       * enemy sprite table integrated in enemy specs (-1 byte/enemy)
4071 ;       + random enemy is chosen from any number of enemies per level
4072 ;       * time to first enemy fire defined per enemy, not per level
4073 ;       + CLIPPED sprites!! no more in/out popping enemies! wow...
4074 ;       * bullets/enemies removed when _entirely_ off screen
4075 ;       # enemies would sometimes be hit by bullets going right below them
4076 ;       # size of the second bullet was too big (invisible hit)
4077 ;       * the frequency an enemy fires bullets is defined per enemy
4078 ;       + wide clipped sprites implemented (width 1-16 pixels)
4079 ;       # bosses first move left until x=100, otherwise they'd be off-screen
4080 ;       * at status bar left below ships are displayed for lives left
4081 ;       * armor bar is two pixels high (better visible)
4082 ;       # bullet overflow fixed again (>63 bullets fired)
4083 ;       # correct weapon loaded when continuing a saved game
4084 ;       # game freezed when generating a random value <=1
4085 ;       * you explode in a different way than the enemies
4086 ;       + screen inverts for a brief time when you are hit!
4087 ;       # stats-bar was messed up when ya got 0 lives left
4088 ;       * two new (big) bosses modeled after a common MSX Nemesis2-boss
4089 ;       * score increased once every 32 frames (instead of every 256)
4090 ;       # ground fixed for new random routine (smaller routine; incs -2 to 2)
4091 ;       + laser will upgrade as well when you reselect it
4092 ;       * 2nd can be used in main menu (wow!)
4093 ;       # altered variable storage space because of Nemesis grew beyond 6kb
4094 ;       # fixed armor bar display when at maximum
4095 ;       + a few new enemies (asteroids) and remade 1st 4 levels; new pickup
4096 ;       - torpedo since it was kinda useless
4097 ;       + second icon now selects TAIL BEAM: bullet going backwards
4098 ;       # armor increase at the end of a level doesn't overflow armorbar
4099 ;       + you can choose your own ship out of four vessel after NEW GAME!
4100 ;       + enemies can appear at any x-position and move both left and right
4101 ;       + move patterns given per enemy, not per level
4102 ;       * new (faster) enemy-move system; 10 basic moves (x2 left+right)
4103 ;       # enemies can _never_ move above or below visible screen
4104 ;       * "randomY"-enemies are placed entirely on screen (height calced)
4105 ;       # the major TI-OS crash bug WAS afterall caused by sprites drawn
4106 ;          (partially) outside screen memory. temporarily fixed by setting
4107 ;          virtual screen buffer to $8200 (enough mem there)
4108 ;       + upto 29 cool enemy sprites and redone first five levels
4109 ;       * improved enemy-move routine; smooth luring, five speeds+backwards
4110 ;       # after pause weapon will not be fired
4111 ;       # teacher key fixed (waits for GRAPH to be release before&after)
4112 ;
4113 ; 0.99.79 -- 9.VII.00 -- size 6747
4114 ;
4115 ;       + you can have upto FOUR multiples! (~20 pixels apart)
4116 ;
4117 ;        + added        - removed       * changed       # bug fixed
4118
4119 ;bullet handling: (255/enemy)+419+putsprite cycles per bullet