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