version 0.94 (major beta): stars, ground, more enemy abilities, menu
[nemesis.git] / nemesis.z80
1 ;------------------------------------------------------------------------------
2 ;---------------------- NEMESIS -----------------------------------------------
3 ;------------------------------------------------------------------------------
4
5 ;       >>> NEMESIS <<<         Version 0.94 BETA       by SHIAR
6 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7 ;  SHIAR  ***  shiar0@hotmail.com  ***  ICQ#43840958  ***  come.to/shiar
8 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 ; DESCRIPTION:                 Fast+cool arcade-game based on the old MSX-game
10 ; CALC:                                                             TI-86 only
11 ; FILES:                                               86P (3624)  Z80 (62443)
12 ; BETA:                   I hope to release the full game around december 1999
13 ; ABOUT:        This source should only be used for learning practises, do not
14 ;               alter it, and certainly do not distribute an altered version!!
15 ;                               &&& marks uncertainties or things to optimize
16
17 ;---------------------- nemesis.z80 start -------------------------------------
18
19         .include "asm86.h"
20         .include "ti86asm.inc"
21         .include "ti86abs.inc"
22
23         .org _asm_exec_ram
24
25 #define           cal   call    ;just to make it harder for you to understand
26 #define           psh   push    ; ^:D
27
28 _dispahl        = $4A33
29
30 TEXT_MEM        = $C0F9 ;-$C1A0 ;_textShadow    ;167 bytes ($A7)
31 DELC_LEN        = $C012 ;-$C076 ;_undelBufLen   ;100 bytes ($64)
32
33 ;---------------------- in-game vars ------------------------------------------
34
35 just_fired      = TEXT_MEM      ;$C0F9          ;counts how long a blast lasts
36 curline         = TEXT_MEM      ;$C0F9          ;used to display SFX
37 menuitem        = TEXT_MEM      ;$C0F9
38 temp1           = TEXT_MEM+1    ;$C0FA-C0FB     ;(2 bytes)
39 RanPos          = TEXT_MEM+3    ;$C0FC          ;used for making random values
40 timer           = TEXT_MEM+4    ;$C0FD          ;frame counter
41
42 x               = TEXT_MEM+5    ;$C0FE          ;your ship's position
43 y               = x+1           ;$C0FF          ;your y-pos
44 firex           = TEXT_MEM+7    ;$C100          ;(1 byte)
45 firey           = firex+1       ;$C101          ;(1 byte)
46 mx              = TEXT_MEM+9    ;$C102          ;position of multiple#1
47 my              = mx+1          ;$C103          ;multiple y-pos
48
49 bossx           = $8001
50 bossy           = bossx+1
51 bossmy          = bossy+1
52
53 level_enemy     = TEXT_MEM+11   ;$C104          ;enemy type
54 eventtime       = TEXT_MEM+12   ;$C105          ;enemy frequency
55 eventleft       = TEXT_MEM+13   ;$C106          ;nr. of enemies still to come
56 nextevent       = TEXT_MEM+14   ;$C107          ;time to next event
57 pickuptimer     = TEXT_MEM+15   ;$C108          ;counts when to place a pickup
58 level_occ       = TEXT_MEM+16   ;$C109
59 level_move      = $8010
60 level_fire      = $8011
61
62 spacespace      = $8012
63 groundinfo      = spacespace+1  ;$8013
64 groundpos       = groundinfo+1  ;$8014  $10
65 ceilingpos      = groundpos+16  ;$8023  $10
66 stars1          = ceilingpos+16 ;$8033
67 stars2          = stars1+1      ;$8034
68
69 nrybullets      = 20
70 ybullets        = TEXT_MEM+17   ;$C10A          ;60 bytes = 20(state,x,y)
71 nrebullets      = 10
72 ebullets        = ybullets+(nrybullets*3)       ;30 bytes = 10(state,x,y)
73
74 your_locpos     = ebullets+(nrebullets*3)       ;position in your_prevpos table
75 your_prevpos    = your_locpos+1                 ;saves previous positions (32d)
76
77 nrstars1        = 7
78 starx1          = your_prevpos+32               ;ends at C192
79 nrstars2        = 7
80 starx2          = starx1+(nrstars1*2)           ;ends at C1A0
81
82 nrenemies       = 10
83 enemies         = DELC_LEN+1
84 add2enemy       = nrenemies*4
85 enemiesxtra     = enemies+add2enemy
86
87 ;enemies:
88 ;       %111111 (HP left) 11 (00=no enemy 01=exploding 10=normal 11=moving)
89 ;       %11111111 (ship type or explosion frame)  %11111111 (x) %11111111 (y)
90 ;enemiesxtra:
91 ;       $11 (move) $11 (fire) $11 (bullettype)
92
93 ;---------------------- introduction ------------------------------------------
94
95          nop                    ;hello yas/ase/rascall/whathever
96          jp init                ;here's the program, but first: a description
97         .dw $0001               ;description type 2 (description + YASicon)
98         .dw Title               ;pointer to description (all shells)
99         .dw Icon                ;pointer to YAS icon
100
101 Title:  .db "Nemesis v0.94 by Shiar",0
102
103 Icon:   .db 8,1                 ;icon for YAS: width = 1byte; height = 9bytes
104         .db %11100000           ; ███
105         .db %01111000           ;  ████
106         .db %00111110           ;   █████
107         .db %01111001           ;  ████  █
108         .db %00111110           ;   █████
109         .db %01111000           ;  ████
110         .db %11100000           ; ███             ;recommend 80x50 screen mode
111         .DB 0   ;clear stupid YAS-line
112
113 ;---------------------- init --------------------------------------------------
114
115 init:
116         cal BUSY_OFF            ;turns the run-indicator off, obviously
117         cal CLEARLCD            ;clean the screen
118         xor a                   ;<ld a,0>: reset:
119         ld  (iy+13),a           ;>system vars
120         ld  (DELC_LEN),a        ;>buffer so we can use the space to store vars
121
122         ld  a,(CONTRAST)        ;load current contrast level
123         cp  $1f                 ;if already at maximum...
124         jr  z,skipdarken        ;...then skip level increase
125         inc a                   ;otherwise increase contrast level
126 skipdarken:
127         out (2),a               ;set it
128
129 ;---------------------- main menu ---------------------------------------------
130
131 LogoPut:
132         xor a                   ;white bitmask (a=0)
133         ld  b,16                ;one line
134         ld  hl,logo_nemesis     ;from...
135         ld  de,VIDEO_MEM+16     ;...to one line from top
136 AboveLogo:
137         ld  (de),a              ;clear/n byte
138         inc de                  ;next
139         djnz AboveLogo          ;repeat for the first line
140
141         ld  bc,16*19            ;logo size
142         ldir                    ;display one line of logo
143
144 ;       ld  hl,GRAPH_MEM        ;cleared line
145 ;       ld  bc,16               ;size=one line
146 ;       ldir                    ;also clear one line below the logo
147
148 ;       ld  a,-1                ;first line is -1+1=0
149 ;       ld  b,21                ;with first 21 lines:
150 ;       cal DoSFX               ;do special effect &&&skip
151
152         ld  hl,VIDEO_MEM+(16*$39)+4     ;$39 rows down, 4 cols right (4*8=$20)
153         ld  b,8                 ;draw 8x one byte = 8*8 = 64 pixels wide
154         ld  a,%11111111         ;horizontal line mask
155 underline:
156         ld  (hl),a              ;draw one piece of the divider-line
157         inc hl                  ;move right (8 pixels = 1 byte)
158         djnz underline          ;repeat
159
160         set 3,(iy+5)            ;set white on black
161         ld  hl,$3320            ;near the bottom of the screen
162         ld  (_penCol),hl
163         ld  hl,txt_about        ;display version and author (yes, that's me!)
164         cal _vputs              ;useful procedure if you want to display somtn
165         res 3,(iy+5)            ;return to default black on white
166
167         ld  hl,$3a1e            ;below previous stuff
168         ld  (_penCol),hl
169         ld  hl,txt_email        ;hey, my e-mail address so SEND ME SOMETHING!!
170         cal _vputs              ;VERY important, so display in small font ?:}
171
172 dispmenu:
173         ld  de,$0304
174         ld  (_curRow),de
175         ld  hl,txt_menu1
176         cal _puts
177         ld  de,$0305
178         ld  (_curRow),de
179         ld  hl,txt_menu2
180         cal _puts
181
182         xor a
183         ld  (menuitem),a
184
185 menuloop:
186         ld  a,(menuitem)
187         ld  h,$01
188         add a,4
189         ld  l,a
190
191         ld  a,5
192         ld  (_curRow),hl
193         cal _putc
194
195         ld  a,(menuitem)
196         ld  h,$01
197         sub 5
198         neg
199         ld  l,a
200
201         ld  a,32
202         ld  (_curRow),hl
203         cal _putc
204
205         halt \ halt \ halt \ halt
206
207         cal GET_KEY             ;wait for keypress
208         cp  K_UP
209         jr  z,menuchange
210         cp  K_DOWN
211         jr  z,menuchange
212         cp  K_EXIT
213         jp  z,game_over_nopop
214         cp  K_ENTER
215         jr  nz,menuloop
216
217         ld  a,(menuitem)
218         dec a
219         cal z,Story
220         cal New_game            ;prepare level
221         jr  game_main_loop
222
223 menuchange:
224         ld  a,(menuitem)
225         xor 1
226         ld  (menuitem),a
227         jr  menuloop
228
229 ;------------------------------------------------------------------------------
230 ;---------------------- game loop ---------------------------------------------
231 ;------------------------------------------------------------------------------
232
233 game_main_loop:                 ;REPEATS FROM HERE EVERY FRAME
234         ld  hl,timer            ;update time
235         inc (hl)                ;increase by 1
236         ld  b,(hl)              ;new time, save for rand# upd. (no flag change)
237         jr  nz,updaterandom     ;continue when new time <> 0
238         ld  hl,1                ;once every 256 frames, increase score by 1
239         cal scoreInc            ;do it
240
241 updaterandom:
242         ld  hl,RanPos           ;random counter
243         ld  a,r
244         add a,(hl)              ;random value
245         add a,b                 ;even more random by adding timer
246 ;.db    $80+7                   ;<add a,r>
247         ld  (hl),a              ;save even more random value back
248
249 Clear_screen:
250         ld  hl,GRAPH_MEM        ;move from (hl) = top left
251         ld  (hl),$00            ;first pixel will be copied all over the screen
252         ld  de,GRAPH_MEM+1      ;(de) = next pixel, thus clearing whole screen
253         ld  bc,896              ;loop 896 times = (128/8) * (64-8 for scorebar)
254         ldir                    ;clear!
255
256         ld  a,(timer)
257         and %11
258         jr  z,movestarsdone
259
260         cal movestars1          ;move the stars on the FRONT layer
261         cal movestars2          ;move the distant stars far, far away
262
263 movestarsdone:
264         ld  a,(stars1)          ;star positions (the missing byte...)
265         ld  b,nrstars1          ;how many stars? now we know.
266         ld  hl,starx1           ;points to the position of the stars
267         cal DisplayStars        ;display front layer stars
268
269         ld  a,(stars2)          ;weren't you paying attention five lines ago?
270         ld  b,nrstars2          ;that many?! whow!
271         ld  hl,starx2           ;and there they are
272         cal DisplayStars        ;use the same procedure to display back layer
273
274         ld  a,(level_move)      ;level info
275         and %01100000           ;isolate ground&ceiling
276         jr  z,game_stuff        ;both non-present
277         and %00100000           ;bit representing the presence of any ceiling
278         cal nz,Handle_ceiling   ;scroll the ceiling (if any)
279         cal Handle_ground       ;scroll the ground
280
281 game_stuff:
282         ld  a,(your_occ)        ;are you 100% OK?
283         or  a                   ;a=0??
284         jr  nz,_gamestuff1      ;then don't check for movements/fires/...
285
286         ld  a,(level_move)      ;the same level info
287         and %01100000           ;isolate ground&ceiling again
288         jr  z,check_keys        ;no ceiling nor ground
289         and %00100000           ;this bit will tell us if there is a ceiling
290         cal nz,CheckCeiling     ;if there is, check it
291         cal CheckGround         ;check for collision with the ground
292
293 check_keys:
294         ld  a,%00111111         ;function keys (MORE,EXIT,2ND,F1,F2,F3,F4,F5)
295         out (1),a               ;ask for them
296         nop \ nop               ;delay 8 clocks
297         in  a,(1)               ;get zem!
298
299 check_exitkey:                  ;why give it a label? i dunno, i'm just crazy
300         bit 6,a                 ;test bit 6 = exit-key = EXIT
301         jp  z,game_over_nopop   ;<exit> pressed, so be it
302 check_morekey:                  ;again, another unused label... poor compiler
303         bit 7,a                 ;test bit 7 = more-key = PAUSE
304         cal z,Pause             ;yes, go to pause
305
306 check_firekey:
307         bit 5,a                 ;test bit 5 = 2nd-key = FIRE
308         ld  hl,check_selkey     ;where to continue after executing Fire_bullet
309         psh hl                  ;push hl on stack (instead of cal Fire_bullet)
310         jp  z,Fire_bullet       ;fire smtn (bulletstorplasermultiples+stuff..)
311         pop hl                  ;no cal to Fire_bullet made, so pop stack
312         ld  hl,just_fired       ;no:
313         ld  (hl),0              ;reset just_fired
314
315 check_selkey:
316         ld  a,%01011111         ;look at first column of keys (ALPHA to STO)
317         out (1),a               ;gimme gimme
318         nop \ nop               ;what's taking you so long
319         in  a,(1)               ;at last... our precious keyzzz...
320                                 ;old: <bit 7,a \ cal z,select> now see this:
321         rla                     ;test bit7 so we know f ALPHA has been pressed
322         cal nc,select           ;yeppy, select the currently selected upgrade
323
324         cal Enemies_hit         ;check for collision with enemies
325
326 _gamestuff1:
327         cal Handle_Ship         ;move you
328         cal Handle_bullets      ;move your bullets
329         cal Handle_torp         ;move your torpedo
330
331         cal Handle_enemies      ;move enemies
332         cal Enemy_bullets       ;move enemy bullets
333
334 ;       ld   a,(level_occ)
335 ;       or   a
336 ;       jr   nz,bosslevel       ;levelocc<>0 so no
337
338         cal Level_event         ;insert enemies
339         jr   _gamestuff2
340 bosslevel:
341         cal Handle_boss
342 _gamestuff2:
343         cal Display_Screen      ;display all
344         halt                    ;delay
345
346         jp   game_main_loop     ;LOOP
347
348 ;--------------------------- ground -------------------------------------------
349
350 Handle_ground:
351         ld  a,(timer)
352         and %111                ;once every 8 frames
353         jr  nz,Display_ground   ;otherwise skip the scroll
354         ld  bc,15               ;scroll all 16 bytes minus one (teh new byte)
355         ld  hl,groundpos+1      ;from..
356         ld  de,groundpos        ;to (one byte to the left)
357 ;       ld  a,(de)              ;load byte on left (will be lost after scroll)
358         ldir                    ;LoaDIncreaseRepeat = scroll!
359
360         ld  a,(groundinfo)      ;what kind of ground
361         dec a                   ;type 1:
362         jr  z,ground_tunnel     ;tunnel effect
363         jr  ground_boring
364
365 ground_tunnel:
366  ld  a,(groundpos+14)
367  ld  (groundpos+15),a
368  ld  hl,spacespace
369
370  ld  a,(RanPos)
371  ld  b,a
372  bit 1,a
373  jr  z,ground_previous
374  bit 2,a
375  jr  z,gtunneldown
376 gtunnelup:
377  ld  a,(hl)
378  or  a
379  jr  z,ground_previous          ;a>=0 (a=0 actually, because a<0 = a>0)
380  inc (hl)
381  ld  a,(groundpos+15)
382  inc a
383  jr  newground
384 gtunneldown:
385  ld  a,(groundpos+15)
386  dec a
387  jr  z,ground_previous
388  dec (hl)
389  jr  newground
390
391 ground_previous:
392         ld  a,(groundpos+14)    ;type 1
393         jr  newground
394 ground_boring:
395         ld  a,(groundpos)       ;type 0
396 newground:
397         ld  (groundpos+15),a    ;save new byte on the right
398         ld  a,(hl)
399         cp  -25
400         jr  nc,Display_ground
401         ld  a,b
402         and %1
403         ld  b,0
404         jr  nz,gtunnelup
405
406 Display_ground:
407         ld  b,16                ;screen width
408         ld  de,groundpos-1      ;height of current byte (previous actually)
409         psh de                  ;use later
410         ld  hl,GRAPH_MEM+(56*16)-1 ;screen position
411         psh hl
412
413 groundloopright:
414         ld  c,b                 ;push b for groundloopup
415         pop hl \ inc hl         ;get screen position and go one right
416         pop de \ inc de         ;get height info and set to the next byte
417         psh de \ psh hl         ;save these for the next time
418         ld  a,(de)              ;height of current byte
419         ld  b,a                 ;save in b
420
421         ld  de,16               ;to substract to go one line up
422         ld  a,%11111111         ;bitmask black
423         or  a
424 groundloopup:
425         ld  (hl),a              ;display black byte
426         sbc hl,de               ;go up (sbc must be used for 16-bit sub)
427         djnz groundloopup       ;and loop >groundpos< times
428
429         ld  b,c                 ;pop b used by groundloopup
430         djnz groundloopright    ;loop right for entire screen (16x)
431         pop hl \ pop hl         ;restore stack
432         ret
433
434 CheckGround:                    ;check for collision with the ground
435         ld  a,(x)
436         srl a
437         srl a
438         srl a
439         inc a
440         ld  l,a
441         ld  h,0
442         ld  de,groundpos
443         add hl,de
444         ld  a,(y)
445         sub 57-7
446         neg
447         cp  (hl)
448         ret nc
449         jp  damage_you
450
451 ;--------------------------- ceiling ------------------------------------------
452
453 Handle_ceiling:
454         ld  a,(timer)
455         and %111                ;once every 8 frames
456         jr  nz,Display_ceiling  ;otherwise skip the scroll
457         ld  bc,15               ;scroll all 15 bytes (16th is new position)
458         ld  hl,ceilingpos+1     ;from..
459         ld  de,ceilingpos       ;to (one byte to the left)
460         ld  a,(de)              ;load byte on left (will be lost after scroll)
461         ldir                    ;LoaDIncreaseRepeat = scroll!
462
463         ld  a,(groundinfo)      ;what kind of ceiling
464         dec a                   ;type 1:
465         jr  z,ceiling_tunnel    ;tunnel effect
466         jr  ceiling_boring
467
468 ceiling_tunnel:
469  ld  a,(ceilingpos+14)
470  ld  (ceilingpos+15),a
471  ld  hl,spacespace
472
473  ld  a,(RanPos)
474  ld  b,a
475  bit 4,a
476  jr  z,ceiling_previous
477  bit 5,a
478  jr  z,ctunnelup
479 ctunneldown:
480  ld  a,(hl)
481  or  a
482  jr  z,ceiling_previous
483  inc (hl)
484  ld  a,(ceilingpos+15)
485  inc a
486  jr  newceiling
487 ctunnelup:
488  ld  a,(ceilingpos+15)
489  dec a
490  jr  z,ceiling_previous
491  dec (hl)
492  jr  newceiling
493
494 ceiling_previous:
495         ld  a,(ceilingpos+14)   ;type 1
496         jr  newceiling
497 ceiling_boring:
498         ld  a,(ceilingpos)      ;type 0
499 newceiling:
500         ld  (ceilingpos+15),a   ;save the new byte
501         ld  a,(hl)
502         cp  -25
503         jr  nc,Display_ceiling
504         ld  a,b
505         and %1
506         ld  b,0
507         jr  nz,ctunneldown
508
509 Display_ceiling:
510         ld  b,16                ;screen width
511         ld  de,ceilingpos-1     ;height of current byte
512         psh de                  ;use later
513         ld  hl,GRAPH_MEM-17     ;screen position
514         psh hl
515
516 ceilingloopright:
517         ld  c,b                 ;push b for groundloopup
518         pop hl \ inc hl         ;get screen position and go one right
519         pop de \ inc de         ;get height info and set to the next byte
520         psh de \ psh hl         ;save these for the next time
521         ld  a,(de)              ;height of current byte
522         ld  b,a                 ;save in b
523
524         ld  de,16               ;to substract to go one line up
525         ld  a,%11111111         ;bitmask black
526         or  a
527 ceilingloopdown:
528         ld  (hl),a              ;display black byte
529         add hl,de               ;go down
530         djnz ceilingloopdown    ;and loop >groundpos< times
531
532         ld  b,c                 ;pop b used by groundloopup
533         djnz ceilingloopright   ;loop right for entire screen (16x)
534         pop hl \ pop hl         ;restore stack
535         ret
536
537 CheckCeiling:                   ;check for collision with the ground
538         ld  a,(x)               ;your x
539         srl a                   ;x/2
540         srl a                   ;x/4
541         srl a                   ;x/8 (current ceiling-byte)
542  inc a
543         ld  l,a                 ;hl = a
544         ld  h,0                 ;"
545         ld  de,ceilingpos       ;first ceiling-byte
546         add hl,de               ;current ceiling-byte
547         ld  a,(y)               ;your y-pos
548         inc a
549         cp  (hl)                ;compare with ceiling
550         ret nc                  ;carry if ceiling is above you
551         jp  damage_you          ;otherwise you don't wanna be in that ship
552
553 ;--------------------------- move stars ---------------------------------------
554
555 DisplayStars:                   ;inputs: hl=starx# a=stars# b=nrstars#
556         ld  e,(hl)
557         inc hl
558         ld  d,(hl)
559         ld  (de),a
560         inc hl
561         djnz DisplayStars
562         ret                     ;let's comment this: returns
563
564 movestars2:
565         ld  ix,starx2
566         ld  a,(stars2)
567         rlca
568         ld  (stars2),a
569         ret nc
570         ld  b,nrstars2
571         jr  movestars_loop
572
573 movestars1:
574         ld  ix,starx1
575         ld  a,(timer)
576         rra
577         ld  a,(stars1)
578         ret c
579         rlca
580         ld  (stars1),a
581         ret nc
582         ld  b,nrstars1
583
584 movestars_loop:
585         ld  h,(ix+1)
586         ld  l,(ix)
587         dec hl
588
589         ld  a,l
590         and %00001111
591         cp  9                   ;(GRAPH_MEM&%00001111)-- = $C9FAand15-1 = $A-1
592         jr  nz,newstarok
593         ld  de,16
594         add hl,de
595
596 newstarok:
597         ld  (ix),l
598         ld  (ix+1),h
599         inc ix \ inc ix
600         djnz movestars_loop
601         ret                     ;for stupid people, here's another comment...
602
603 ;--------------------------- pause --------------------------------------------
604
605 Pause:
606         ld  hl,$0200            ;top left
607         ld  (_curRow),hl
608         ld  hl,txt_pressenter   ;"Enter to continue"
609         cal _puts               ;display message
610 pause:
611         cal _getkey             ;enter low-power mode and wait for key
612         cp  kEnter              ;keypressed = enter?
613         jr  nz,pause            ;no, wait some more
614         ret                     ;continue
615
616 ;--------------------------- exit ---------------------------------------------
617
618 quit:
619         cal CLEARLCD            ;clears screen
620         cal _homeup             ;set cursor to top-left
621         ld  a,(CONTRAST)        ;load original contrast level
622         out (2),a               ;and set it back
623         ld  (iy+13),6           ;restore system-flags
624         ret                     ;quit Nemesis :(
625
626 ;--------------------------- display ------------------------------------------
627
628 Display_Screen:
629         ld  hl,GRAPH_MEM        ;from storage (top left)
630         ld  de,VIDEO_MEM        ;to screen (top left)
631         ld  c,56                ;display height = 64 bytes (minus 8 for bar)
632 displayloop:
633         ld  b,16                ;display width = 16 bytes (16*8bits=256pixels)
634 displaytloop:
635         ld  a,(hl)              ;copy byte from (hl)
636 ;       xor $ff                 ;   }   ;invert byte (white<=>black) &&&&
637         ld  (de),a              ;to (de)
638         inc hl \ inc de         ;next byte
639         djnz displaytloop       ;16x hl >> de
640         dec c                   ;next line
641         jr  nz,displayloop      ;loop 64x
642
643         ld  hl,$396b            ;Display Score
644         ld  (_penCol),hl        ;bottom right of screen
645         ld  hl,(score)
646
647 _D_HL_DECI:                     ;------- display 5-digit value -------
648         ld  de,savestr+4        ;savenr saves number string
649         ld  b,5                 ;five digits
650 ldhld:  cal UNPACK_HL           ;one digit of hl
651         add a,'0'               ;make number
652         ld  (de),a              ;save into savenr
653         dec de                  ;point to next digit
654         djnz ldhld              ;repeat for all digits
655
656         ld  hl,savestr          ;we (the program) saved the value righthere
657         cal _vputs              ;the only thing left to do is to display it
658         ret                     ;and we're done again
659
660 savestr:                        ;@here the score will be stored
661         .db "00000",0           ;don't worry, it's just temporary
662
663 ;------------------------- handle ship ----------------------------------------
664
665 Handle_Ship:
666         ld  a,(your_occ)        ;are
667         or  a                   ;you
668         jr  z,ok                ;ok?
669
670         inc a                   ;no! next (explosion)frame
671         ld  (your_occ),a        ;save
672
673         cp  34                  ;last explosion frame?
674         jp  c,exploding_you     ;not yet: display explosion
675         cp  40                  ;delay finished?
676         jp  z,You_die           ;yes = game over
677         ret                     ;don't display anything
678
679 ok:                             ;we are
680         ld  a,%01111110         ;get arrow keys
681         out (1),a               ;it's cold outside
682         ld  hl,y                ;instead of nop\nop do something usefull
683         in  a,(1)               ;come back in
684
685         ld  b,a                 ;psh a (keys)
686         xor %11111111           ;inverted a = 0 if arrow-key has been pressed
687         ld  a,(your_multiples)
688         jr  z,no_adv            ;if so, leave the multiples where they are
689         or  %100                ;set move bit
690         jr  adv_ok
691 no_adv: and %11111011           ;reset move bit
692
693 adv_ok: ld  (your_multiples),a
694         ld  a,b                 ;pop a (keys)
695
696         rra                     ;rotate right (put last bit in c)
697         ld  b,a                 ;we need a later
698
699         jr  c,no_down
700         ld  a,(hl)
701         cp  49                  ;55-6 = bottom of screen
702         jr  z,no_down
703         inc a
704         ld  (hl),a
705 no_down:
706         dec hl
707         rr  b                   ;because we now use b, it's rr instead of rra
708         jr  c,no_left
709         ld  a,(hl)
710         sub 1                   ;<dec a> doesn't affect c-flag
711         jr  c,no_left           ;-1 = left side
712         ld  (hl),a
713 no_left:
714         rr  b   
715         jr  c,no_right
716         ld  a,(hl)
717         cp  121                 ;127-6 = right side
718         jr  z,no_right
719         inc a
720         ld  (hl),a
721 no_right:
722         ld  d,(hl)
723         inc hl
724         rr  b
725         jr  c,no_up
726         ld  a,(hl)
727         sub 1                   ;<dec a> doesn't affect carry-flag
728         jr  c,no_up             ;-1 = top of screen
729         ld  (hl),a              ;save new y
730
731 no_up:  ld  e,(hl)
732         ld  ix,spr_ship01       ;ship sprite
733         ld  hl,your_inv         ;invulnerable?
734         ld  a,(hl)              ;load time in a
735         or  a                   ;is it 0?
736         jr  z,handle_multiples  ;yes so ship = normal (display \ continue)
737
738         ld  b,a                 ;save inv-time
739         ld  a,(timer)           ;load frame nr.
740         and %00000011           ;a=0 once every four frames
741         jr  nz,not_time         ;a<>0 = not time to update counter
742         dec (hl)                ;decrease inv-time left
743 not_time:
744         and %00000010           ;a switches 0<->1 every 2 frames
745         jr  z,no_flicker        ;don't show normal sprite anyway
746         ld  a,b                 ;pop inv-time
747         and %11110000           ;inv-time <16 ticks left?
748         jr  z,handle_multiples  ;yes: display normal sprite and continue
749
750 no_flicker:
751         ld  ix,spr_ship01i      ;display inv-ship (ld ix is faster than add ix)
752
753 handle_multiples:
754         cal putsprite           ;display your ship
755
756         ld  a,(your_multiples)  ;do you have multiples
757         ld  b,a                 ;save a for 2nd check
758         and %11                 ;no? (last two bits = nr of multiples)
759         ret z                   ;then don't handle them either
760
761         ld  hl,y
762         ld  a,b                 ;restore a (your_multiples)
763         and %100                ;move the multiples???
764         jr  z,mult_adv          ;nope, just let them (saves (y) in y, (x) in x)
765
766         ld  hl,your_locpos      ;location to save this position
767         ld  a,(hl)              ;load a
768         inc a                   ;a=a+1
769         and %00001111           ;if a>15 then a=a-16
770         ld  (hl),a              ;save new a
771         add a,a                 ;a=a*2
772         ld  c,a                 ;bc=2a
773         ld  b,0
774
775         ld  hl,your_prevpos     ;previous positions
776         add hl,bc               ;16 turns ago
777         ld  d,(hl)              ;old x-pos
778         inc hl                  ;and
779         ld  e,(hl)              ;old y-pos
780         ld  (mx),de             ;save multiple position in (mx)
781
782         ld  a,(y)               ;load new y-pos
783         ld  (hl),a              ;save it for 16 turns in the future
784         dec hl                  ;and
785         ld  a,(x)               ;load new x-pos
786         ld  (hl),a              ;save that too
787
788 mult_adv:
789  ld de,(mx)
790         ld  ix,spr_multiple     ;sprite of the multiple
791         jp  putsprite           ;display it + <ret>
792
793 exploding_you:
794         srl a                   ;half the framerate
795         dec a                   ;first frame is 1>inc>srl>dec = 0
796         ld  hl,x-1
797
798 explosion_stuff:
799         rra
800         add a,a
801         add a,a
802         add a,a
803         ld  c,a
804         ld  b,0
805         ld  ix,spr_explosion
806         add ix,bc
807         inc hl
808         ld  d,(hl)
809         inc hl
810         ld  e,(hl)
811         jp  putsprite
812
813 damage_you:
814         ld  a,(your_inv)        ;invulnerability left?
815         or  a
816         ret nz                  ;return if inv>0
817         ld  hl,your_armor       ;armor left
818         ld  a,(hl)              ;check
819         dec a                   ;is it 0?
820         jp  m,no_armor          ;yes, 0hp left so explode
821         ld  (hl),a              ;no, so save decreased hp
822         cal disp_armor          ;and display new value
823         ret                     ;and return
824 no_armor:
825         ld  a,%01               ;occ %xxxxxx01 = explode
826         ld  (your_occ),a        ;set to explode
827         ret
828
829 ;------------------------- place multiples ------------------------------------
830
831 Place_multiples:
832         ld  (mx),de             ;set last multiple-position
833         ld  hl,your_prevpos     ;place all previous positions
834         ld  b,16                ;all 16 of them
835 place_multiples:
836         ld  (hl),d              ;set prev-x to d
837         inc hl                  ;next
838         ld  (hl),e              ;set prev-y to e
839         inc hl                  ;next
840         djnz place_multiples    ;repeat
841         ret
842
843 ;------------------------- select upgrade -------------------------------------
844
845 select:
846         ld  hl,your_pickup      ;select pickups
847         ld  a,(hl)              ;load pickups taken so far
848         dec a                   ;is it 1?
849         jr  nz,select2          ;no, carry on
850         ld  (hl),a              ;reset pickups (a=0)
851         ld  hl,your_armor       ;change armor
852         inc (hl)                ;increase HPs by one
853         jp  disp_icons          ;display and return
854 select2:
855         dec a                   ;is it 2?
856         jr  nz,select3          ;no, carry on
857         ld  (hl),a              ;reset pickups
858         inc a                   ;a=1
859         ld  (torp_occ),a        ;ready torpedoes
860         jp  disp_icons          ;display 'n return
861 select3:
862         dec a                   ;is it 3?
863         jr  nz,select4          ;no, carry on
864         ld  (hl),a              ;reset pickups
865         jp  disp_icons          ;display n return
866 select4:
867         dec a                   ;is it 4?
868         jr  nz,select5          ;no, carry on again
869         ld  (hl),a              ;reset pickups
870         inc a                   ;a=1
871         ld  (your_laser),a      ;ready laser
872         jp  disp_icons          ;display + return
873 select5:
874         dec a                   ;is it 5?
875         jr  nz,select6          ;no, carry on once more
876         ld  (hl),a              ;reset pickups
877         inc a
878         ld  (your_multiples),a
879         ld  de,(x)
880         cal Place_multiples
881         jp  disp_icons          ;display, return
882 select6:
883         ld  (hl),0              ;reset pickups
884         jp  disp_icons          ;display/return
885
886 ;------------------------- fire bullet ----------------------------------------
887
888 Fire_bullet:
889         ld  hl,RanPos           ;random
890         inc (hl)                ;update random counter
891
892         ld  hl,just_fired
893         ld  a,(hl)              ;just_fired
894         cp  5                   ;already pressed?
895         ret z                   ;return when already pressed (=5)
896         inc (hl)                ;otherwise increase counter (0 to 4 >> 1 to 5)
897         ld  a,(your_laser)      ;if you have bullets.....
898         or  a                   ;(0=no laser)
899         jr  nz,fireOK
900         ld  (hl),5              ;.....then can't fire next turn (go to 5 imm.)
901
902 fireOK:
903         ld  hl,(x)              ;yes: first fire from ship position (x)
904         ld  (firex),hl          ;set firepos
905         ld  a,(your_multiples)  ;any multiples?
906         and %11                 ;nope?
907         jr  z,fireany           ;then just fire somethin'
908         cal fireany             ;and blast
909         ld  hl,(my)             ;then, fire from multiple position (mx)
910         ld  a,(mx)              ;<ex h,l>
911         ld  h,a                 ; ^^^^^^
912         ld  (firex),hl          ;set firepos
913                                 ;blast again and <ret>
914 fireany:
915         ld  a,(your_laser)      ;do you have laser?
916         dec a                   ;1=yes
917         jr  nz,fire_ybullet     ;no, just fire a bullet
918
919 fire_laser:                     ;yes, fire that laser instead
920         ld  a,(firex)           ;a = your x-pos
921         ld  d,a
922
923         ld  hl,GRAPH_MEM        ;save-location
924         ld  a,(firey)           ;y-coord
925         add a,3                 ;at middle of your ship (y+3)
926         ld  e,a                 ;save laser-y in e
927         add a,a                 ;y*2
928         add a,a                 ;y*4
929         add a,a                 ;y*8
930         rl  b                   ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
931         add a,a                 ;y*16 (width of screen)
932         rl  b                   ;b=b*2+overflow (if y>64 then bc=bc+512)
933         inc a                   ;8 pixels to right (a=even so no overflow)
934
935         srl d                   ;X/2
936         srl d                   ;X/4
937         srl d                   ;X/8
938         add a,d                 ;a = (Y*16+X/8) mod 256 (c set on overflow)
939         jr  nc,_nolc            ;jump if no carry = no overflow = a<=255
940         inc b                   ;a>255 so increase bc by 256
941 _nolc:  ld  c,a                 ;c = (Y*16+X/8) mod 256
942         add hl,bc               ;bc = Y*16+X/8
943           
944         ld  a,15                ;128/8=16=screen width ** minus one (inc a ^^)
945         sub d                   ;minus x-start (d=X/8)
946         ld  b,a
947 drawlaser:
948         ld  (hl),%11111111
949         inc hl                  ;Go to next byte
950         djnz drawlaser
951
952 handle_laser:
953         ld  a,(firex)
954         ld  d,a                 ;d was divided, so reload the laser-x
955
956 check_laserhits:                ;de = (x,y)
957         ld  ix,nolashit
958         ld  b,nrenemies
959         ld  hl,enemies
960
961 laserhits:                      ;Hits with normal enemies
962         psh hl
963
964         ld  a,(hl)
965         and %00000010
966         jr  z,nolashit          ;no hit when enemy_occ <> 2/3
967
968         inc hl                  ;enemy type
969         ld  a,(hl)
970         or  a                   ;enemy #0 = pickup
971         jr  z,nolashit          ;yes: don't destroy
972
973         inc hl
974         ld  a,(hl)              ;check x
975         sub d
976         jp  m,nolashit          ;no hit when enemy is left of you
977
978         inc hl
979         ld  a,(hl)              ;check y
980         sub e
981         jp  z,enemy_hit         ;a-e=0 = laser on top line of enemy = hit
982         jr  nc,nolashit         ;a-e>0 = enemy above laser = no hit
983         add a,5                 ;add enemy height
984         jp  p,enemy_hit         ;a-e>0 = hit
985
986 nolashit:
987         pop hl
988         inc hl                  ;go to next enemy
989         inc hl
990         inc hl
991         inc hl
992         djnz laserhits          ;check all enemies
993
994         ld  a,d                 ;<ex d,e>
995         ld  d,e
996         ld  e,a
997         jr  fire_torp           ;fire torpedoes as well
998
999 fire_ybullet:
1000         ld  hl,ybullets
1001         ld  de,3
1002         ld  b,nrybullets
1003 find_ybullet:
1004         ld  a,(hl)
1005         or  a
1006         jr  z,found_ybullet     ;0 = no bullet here
1007         add hl,de
1008         djnz find_ybullet       ;look next bullet
1009         ret
1010
1011 found_ybullet:
1012         ld  (hl),1              ;use bullet
1013         ld  a,(firex)           ;your x-pos
1014         add a,5                 ;place bullet in front of you
1015         inc hl                  ;go to bullet-x
1016         ld  (hl),a              ;set x
1017         ld  e,a                 ;save torp-x in e
1018
1019         ld  a,(firey)           ;your y-pos
1020         add a,2                 ;place bullet at the middle of your ship
1021         inc hl                  ;go to bullet-y
1022         ld  (hl),a              ;set y
1023         add a,3                 ;place torpedo at bottom of ship
1024         ld  d,a                 ;save torp-y in d
1025
1026 fire_torp:
1027         ld  hl,torp_occ         ;torpedo...
1028         ld  a,(hl)              ;load torpInfo
1029         dec a                   ;do you have (unused) torpedoes?
1030         ret nz                  ;nope (a must be 1)
1031         ld  (hl),2              ;yes; use torpedo
1032         ld  (torp_pos),de       ;save torpedo position (in de)
1033         ret
1034
1035 ;------------------------ handle bullets --------------------------------------
1036
1037 remove_bullet:
1038         dec hl
1039         ld  (hl),0              ;dump this bullet!
1040         ret
1041
1042 Handle_bullets:
1043         ld  hl,ybullets
1044         ld  b,nrybullets
1045 scan_bullets:
1046         psh bc
1047         psh hl
1048         ld  (temp1),hl
1049         ld  a,(hl)
1050         inc hl
1051         dec a                   ;type 1?
1052         cal z,bullet_2left      ;yes: 2left
1053         pop hl
1054         pop bc
1055         ld  de,3
1056         add hl,de               ;3 x <inc hl>
1057         djnz scan_bullets       ;next bullet (loop)
1058         ret
1059
1060 bullet_2left:
1061         ld  a,(hl)              ;d = X
1062         cp  122                 ;off screen? (x>128-5)
1063         jr  nc,remove_bullet
1064         add a,2                 ;move 2 2 the right
1065         ld  (hl),a              ;save new pos.
1066         ld  d,a
1067
1068         inc hl                  ;to y-pos
1069         ld  e,(hl)              ;e = Y
1070
1071         ld  ix,spr_bullet01
1072         psh de
1073         cal putsprite           ;display bullet
1074         pop de
1075
1076 check_bullethits:               ;INPUT: de=X,Y
1077         ld  b,nrenemies
1078         ld  hl,enemies
1079         ld  ix,nohit
1080
1081 hit_enemies:                    ;Hits with normal enemies
1082         psh hl
1083
1084         ld  a,(hl)
1085         and %00000010
1086         jr  z,nohit             ;no hit when enemy_occ <> 2/3
1087
1088         inc hl                  ;enemy type
1089         ld  a,(hl)
1090         or  a                   ;enemy #0 = pickup
1091         jr  z,nohit             ;yes: don't destroy
1092
1093         inc hl
1094         ld  a,(hl)              ;check x
1095         sub d
1096         add a,5
1097         jp  m,nohit
1098         cp  8
1099         jr  nc,nohit
1100
1101         inc hl
1102         ld  a,(hl)              ;check y
1103         sub e
1104         add a,5
1105         jp  m,nohit
1106         cp  10
1107         jr  nc,nohit
1108
1109         psh hl
1110         ld  hl,(temp1)
1111         ld  (hl),$00            ;remove bullet
1112         pop hl
1113
1114 enemy_hit:
1115         dec hl
1116         dec hl
1117         dec hl
1118         ld  a,(hl)              ;occ
1119         ld  c,a                 ;psh occ
1120         and %11111100           ;occ/4 = HP left        ;<srl a\srl a
1121         jr  nz,hpleft           ;not zero -> jump
1122         ld  (hl),%01            ;set to explode
1123
1124         ld  a,(pickuptimer)     ;counts enemies destroyed
1125         dec a                   ;enough destroyed for a pickup?
1126         jr  nz,pickupdone       ;otherwise just explode
1127         ld  (hl),%00000110      ;change it into a pickup (with 2 HP)
1128         ld  a,18                ;reset enemies counter (18 hits = next)
1129 pickupdone:
1130         ld  (pickuptimer),a     ;save new enemiescounter value
1131         inc hl
1132         ld  (hl),$00            ;explosionFrame 0
1133
1134         ld  hl,1                ;increase score by one
1135         cal scoreInc
1136         jp  (ix)
1137
1138 hpleft:
1139         ld  a,c                 ;pop occ
1140         sub %00000100           ;decrease HP by one
1141         ld  (hl),a              ;save
1142         jp  (ix)
1143
1144 nohit:
1145         pop hl
1146         inc hl
1147         inc hl
1148         inc hl
1149         inc hl
1150         djnz hit_enemies        ;check next enemy
1151         ret
1152
1153 ;--------------------------- handle torpedo -----------------------------------
1154
1155 Handle_torp:
1156         ld  a,(torp_occ)
1157         sub 2
1158         ret m                   ;return if occ=0/1
1159
1160         ld  hl,torp_pos         ;x-position
1161         ld  a,(hl)              ;load in a
1162         inc a                   ;move right
1163         cp  125                 ;right edge reached
1164         jr  nc,remove_torp      ;remove if x>125
1165         ld  (hl),a              ;save new x
1166         ld  d,a
1167
1168         inc hl                  ;y-position
1169         ld  a,(hl)
1170         inc a                   ;move down
1171         cp  56                  ;bottom reached
1172         jr  nc,remove_torp      ;remove if y>40
1173         ld  (hl),a              ;save new y
1174         ld  e,a
1175
1176         ld  ix,spr_bullett1
1177         psh de
1178         cal putsprite           ;display torpedo
1179         pop de
1180         jp  check_bullethits    ;check for hits with enemies
1181
1182 remove_torp:
1183         ld  a,1
1184         ld  (torp_occ),a
1185         ret
1186
1187 ;--------------------------- level events -------------------------------------
1188
1189 Level_event:
1190         ld  hl,nextevent        ;time to next event     <ld  a,(nextevent)
1191         dec (hl)                ;decrease counter       <dec a
1192         ld  a,(hl)              ;look at counter        <ld  (nextevent),a
1193         or  a                   ;has it reached zero?
1194         ret nz                  ;nope: get outta here!
1195
1196         ld  a,(eventtime)       ;enemy frequency (lvl)
1197         ld  (nextevent),a       ;set time to next event
1198         ld  hl,eventleft
1199         dec (hl)                ;update enemy-counter
1200
1201         ld  a,(hl)              ;look at counter
1202         or  a                   ;has it reached 0?
1203         jp  z,Next_level        ;yes: level finished
1204         dec a                   ;has it reached 1?
1205         jr  nz,do_event         ;nope: wait for enemies to leave
1206         inc hl                  ;nextevent located behind eventleft
1207         ld  (hl),123            ;set delay
1208         ret                     ;don't place any more enemies
1209
1210 do_event:
1211         ld  de,enemies-4
1212 chk_noenemy:
1213         inc de
1214         inc de
1215         inc de
1216         inc de
1217         ld  a,(de)
1218         or  a                   ;0 = no enemy present
1219         jr  nz,chk_noenemy
1220
1221 place_enemy:
1222         ld  a,(level_enemy)     ;enemy type to place (lvl)
1223         ld  hl,enemy00          ;enemy 1 specs
1224         add a,a                 ;a=type*2
1225         add a,a                 ;a=type*4
1226         ld  c,a                 ;c=type
1227         ld  b,0                 ;bc = enemy nr.
1228         add hl,bc               ;hl = enemy specs
1229         ld  a,(hl)              ;load hitpoints+occ of this enemy class
1230         ld  (de),a              ;occ
1231
1232         inc hl                  ;next enemyInfo byte
1233         inc de                  ;next byte of current enemy
1234         ld  a,(hl)              ;load movement+type of this enemy class
1235         ld  (de),a              ;enemy type
1236
1237         inc de                  ;set x-pos
1238         ld  a,122               ;appear at right edge of screen (128-6)
1239         ld  (de),a              ;= x-position
1240
1241         inc de                  ;set y-pos
1242         inc hl                  ;where to place??
1243         ld  a,(hl)              ;load placeInfo
1244         dec a                   ;is it 1?
1245         jr  z,random_enemy      ;yes: create random value <51 in a
1246         dec a                   ;is it 2?
1247         jr  z,lure_enemy        ;yes: create a 100% luring enemy
1248                                 ;otherwise?
1249 halflure_enemy:                 ;yes (of course it is): pick one (50% lure)
1250         ld  a,(timer)           ;look at frame-number
1251         and %00000001           ;make random if odd frame nr.
1252         jr  nz,random_enemy     ;1st possibility: random enemy
1253 lure_enemy:                     ;2nd possibility: luring enemy
1254         ld  a,(y)               ;place at same y-pos as YOUR ship
1255         jr  ypos_OK
1256
1257 random_enemy:
1258         cal Random              ;make a (in a) random value 0-255
1259         cp  51                  ;y may not be more than 51
1260         jr  c,ypos_OK           ;OK if a<51
1261         and %00111111           ;a = 0..63
1262         sub 13                  ;a = -13..50
1263         jr  c,random_enemy      ;not OK if a<0
1264
1265 ypos_OK:                        ;random value successfully created
1266         ld  (de),a              ;save y-position
1267
1268         ld  hl,add2enemy-3      ;offset to xtra enemy info
1269         add hl,de               ;hl points to <xtra info: move>
1270         ld  (hl),1              ;set move-counter to 1
1271         inc hl                  ;hl to <xtra info: fire>
1272
1273         ld  a,(level_move)
1274         and %00010000
1275         jr  z,ffiredelayed
1276         ld  a,1                 ;set time-to-fire to 1 frame (fires directly)
1277         jr  ffireOK
1278 ffiredelayed:
1279         ld  a,(level_fire)      ;set "ttf" to normal nr of frames
1280 ffireOK:
1281         ld  (hl),a
1282         inc hl                  ;hl to <xtra info: bullettype>
1283         ld  (hl),1              ;type 1
1284         inc hl                  ;hl to <xtra info: bullettype>
1285         ld  a,(RanPos)
1286         and %01111111
1287         ld  (hl),a              ;type 1
1288         ret                     ;return
1289
1290 Random:
1291         ld  a,(RanPos)          ;a handy random-var.
1292         ld  hl,x                ;add your x-coord for randomness
1293         adc a,(hl)
1294         ld  hl,y                ;add your y-coord for randomness
1295         adc a,(hl)
1296         ld  (RanPos),a          ;save altered random-var
1297         ret                     ;RanPos also in #a
1298
1299 ;--------------------------- enemy fires --------------------------------------
1300
1301 Enemy_fires:                    ;de = x,y
1302         dec d
1303         dec d                   ;d = x-2
1304         inc e                   ;e = y+1
1305
1306         ld  b,nrebullets
1307         ld  hl,ebullets
1308 find_ebullet:
1309         ld  a,(hl)
1310         or  a
1311         jr  z,found_ebullet     ;0 = not used
1312         inc hl \ inc hl \ inc hl
1313         djnz find_ebullet       ;look next bullet
1314         ret
1315
1316 found_ebullet:
1317         ld  b,%1100
1318         ld  a,(level_move)
1319         and %10000000
1320         jr  z,bulletok
1321
1322         ld  a,(y)
1323         sub e
1324         add a,10
1325         jp  p,bulletnotup
1326         ld  b,%1011             ;yourY-bulY = negative (=bullet below you)
1327         add a,10
1328         jp  p,bulletnotup
1329         ld  b,%1001             ;yourY-bulY = even more negative (going up)
1330
1331 bulletnotup:
1332         sub 20
1333         jp  m,bulletok
1334         ld  b,%1010             ;bullet going down
1335         sub 10
1336         jp  m,bulletok          ;even more going down
1337         ld  b,%1000
1338
1339 bulletok:
1340 ;       ld  a,c                 ;load bullet type
1341 ;       add a,a                 ;type*2                 %..Btype.
1342 ;       add a,a                 ;type*4                 %.Btype..
1343 ;       add a,a                 ;type*8                 %Btype...
1344                                 ;add bullet direction   %BtypeDir
1345         ld  (hl),b              ;set bullet direction
1346         inc hl
1347         ld  (hl),d              ;set x-pos
1348         inc hl
1349         ld  (hl),e              ;set y-pos
1350         ret
1351
1352 ;----------------------------- enemy bullets ----------------------------------
1353
1354 Enemy_bullets:
1355         ld  hl,ebullets
1356         ld  b,nrebullets
1357 handle_bullet:
1358         psh bc
1359         psh hl
1360         ld  a,(hl)              ;load bulletType in a
1361         or  a                   ;is it 0?
1362         jr  nz,enemy_bullet     ;no: handle bullet
1363 next_bullet:
1364         pop hl                  ;do not move the <pop hl>
1365         pop bc
1366         inc hl \ inc hl \ inc hl
1367         djnz handle_bullet
1368         ret
1369
1370 enemy_bullet:
1371         ld  b,a                 ;save type
1372         inc hl                  ;bullet x
1373         ld  a,(hl)              ;check if it has reached the left side of scrn
1374         and %11111110           ;it is <2 (0 or 1)?
1375         jr  z,remove_ebullet    ;yes, remove bullet
1376         dec (hl)                ;move one left
1377         dec (hl)                ;and another one
1378         ld  d,(hl)              ;d=x
1379         inc hl                  ;@y
1380
1381         ld  a,b                 ;restore type
1382         cp %1100                ;&&& use <bit ?,a>
1383         jr  z,ebullet_common    ;type %1100: normal bullet
1384         and %111
1385         jr  z,ebullet_down      ;type %1000: moving down
1386         dec a
1387         jr  z,ebullet_up        ;type %1001: moving up
1388         ld  b,a
1389
1390         ld  a,(timer)
1391         rra
1392         jr  c,ebullet_common
1393
1394         ld  a,b
1395         dec a
1396         jr  z,ebullet_down      ;type %1010: moving down 50%
1397                                 ;type %1011: moving up 50%
1398 ebullet_up:
1399         ld  a,(hl)
1400         dec a
1401         jp  m,ebullet_common
1402         ld  (hl),a
1403         jr  ebullet_common
1404
1405 ebullet_down:
1406         ld  a,(hl)
1407         inc a
1408         cp  55
1409         jr  z,ebullet_common
1410         ld  (hl),a
1411
1412 ebullet_common:
1413         ld  e,(hl)              ;e=y
1414         ld  ix,spr_bullete1     ;display enemy bullet
1415         cal putsprite
1416
1417 ebullet_hits:
1418         ld  a,(your_occ)
1419         or  a
1420         jr  nz,next_bullet      ;0 = you're normal
1421
1422         pop hl
1423         psh hl
1424         inc hl                  ;check x
1425         ld  a,(x)
1426         sub (hl)
1427         add a,6
1428         jp  m,next_bullet
1429         cp  9
1430         jr  nc,next_bullet
1431
1432         inc hl                  ;check y
1433         ld  a,(y)
1434         sub (hl)
1435         add a,6
1436         jp  m,next_bullet
1437         cp  9
1438         jr  nc,next_bullet
1439
1440         cal damage_you          ;HIT!!
1441 remove_ebullet:
1442         pop hl                  ;hl could be destroyed by damage_you
1443         ld  (hl),0              ;bullet > unused
1444         jr  next_bullet+1       ;next bullet (SKIP THE <POP HL> = one byte)
1445
1446 ;--------------------------- handle enemies -----------------------------------
1447
1448 Handle_enemies:
1449         ld  hl,enemies
1450         ld  b,nrenemies         ;handle all enemies
1451
1452 handle_enemy:
1453         psh bc
1454         psh hl
1455
1456         ld  a,(hl)
1457         and %00000011
1458         jr  z,next_enemy        ;occ "no enemy" 0
1459         dec a
1460         jr  z,exploding_enemy   ;occ "exploding" 1
1461         ld  b,a                 ;b=2 if moving, otherwise b=1
1462
1463 normal_enemy:                   ;occ "normal" 2 or "moving" 3
1464         inc hl
1465         psh hl
1466
1467         ld  e,(hl)              ;e = enemy type
1468         ld  c,e                 ;c = e
1469         ld  d,0                 ;de = e
1470         ld  hl,sprites          ;hl = @sprites offset-table
1471         add hl,de               ;points to offset of current enemy offset
1472         ld  e,(hl)              ;de = @enemy offset
1473
1474         ld  ix,spr_enemy00      ;first enemy sprite
1475         add ix,de               ;add offset for current enemy
1476         pop hl
1477
1478         inc hl
1479         ld  a,(hl)              ;x
1480         dec a                   ;move left
1481         jr  c,remove_enemy      ;off screen
1482         jr  z,remove_enemy      ;"
1483         ld  d,a
1484
1485         inc hl
1486         ld  e,(hl)              ;y
1487         ld  a,b                 ;moving state was stored in b earlier
1488         dec a                   ;is it 1?
1489         cal nz,moving_enemy     ;2 = moving enemy
1490
1491         dec hl                  ;@x
1492         ld  (hl),d              ;store new x
1493         ld  a,c                 ;a = enemy type
1494         or  a                   ;type 0? (pickup)
1495         jr  nz,check_enemyfire  ;no, a normal enemy; let em fire
1496         ld  a,(timer)           ;load time
1497         and %1                  ;move left once every 2 turns
1498         jr  z,firing_done       ;don't move now
1499         inc d                   ;increase x-position (don't move this turn)
1500         inc (hl)                ;and save it
1501         jr  firing_done         ;continue
1502
1503 check_enemyfire:
1504         ld  bc,add2enemy+1-2    ;offset of <xtra enemy info: fire>
1505         add hl,bc               ;go there (@hl)
1506         dec (hl)                ;decrease counter till next blast
1507         ld  a,(hl)              ;load new counter
1508         or  a                   ;has it reached zero?
1509         jr  nz,firing_done      ;finished if not
1510
1511         ld  a,(level_fire)      ;re-set counter for next blast
1512         ld  (hl),a              ;save time to fire
1513         inc hl                  ;next byte = bullettype
1514         ld  c,(hl)              ;c = bullet type
1515         psh de                  ;save registers for firing-use
1516         cal Enemy_fires         ;fires bullet
1517         pop de                  ;restore (destroyed by Enemy_fires)
1518 firing_done:
1519         cal putsprite           ;display sprite @ix
1520
1521 next_enemy:
1522         pop hl
1523         ld  bc,$0004
1524         add hl,bc
1525         pop bc
1526         djnz handle_enemy
1527         ret
1528
1529 remove_enemy:
1530         pop hl
1531         ld  (hl),$0000          ;bye bye enemy
1532         psh hl
1533         jr  next_enemy
1534
1535 exploding_enemy:
1536         inc hl
1537         psh hl
1538         ld  a,(hl)
1539         cal explosion_stuff     ;display explosion
1540         pop hl
1541
1542         ld  a,(hl)
1543         cp  15
1544         jr  z,remove_enemy      ;remove when at last frame
1545         inc a
1546         ld  (hl),a              ;next frame
1547         jr  next_enemy
1548
1549 ;--------------------------- moving enemies -----------------------------------
1550
1551 moving_enemy:
1552         ld  a,(level_move)
1553         and %1111
1554         jr  z,movetype_updown
1555         dec a
1556         jr  z,movetype_vslow
1557         dec a
1558         jr  z,movetype_fast
1559         dec a
1560         jr  z,movetype_vfast
1561
1562 movetype_smart:
1563         ld  bc,add2enemy
1564         add hl,bc
1565
1566         ld  a,(timer)
1567         and %1111
1568         ld  a,(hl)
1569         jr  nz,smartupdate
1570         inc a
1571 smartupdate:
1572         ld  (hl),a
1573
1574         or  a                   ;reset carry flag
1575         sbc hl,bc
1576         and %11111100
1577         jr  z,movetype_fast
1578
1579 movetype_vslow:
1580         ld  a,(timer)
1581         and %11
1582         ret z
1583         inc d
1584         ret
1585
1586 movetype_fast:
1587         ld  a,(timer)
1588         and %1
1589         ret z
1590 movetype_vfast:
1591         dec d                   ;move left
1592         ret nz                  ;finished
1593         pop hl                  ;restore stack (no ret used)
1594         jr  remove_enemy        ;remove this enemy (off screen)
1595
1596 movetype_updown:
1597         ld  bc,add2enemy
1598         add hl,bc
1599
1600         ld  a,(hl)
1601         dec a
1602         jr  nz,move_updated
1603         add a,128
1604 move_updated:
1605         ld  (hl),a
1606
1607         or  a                   ;reset carry flag
1608         sbc hl,bc
1609         and %00100000
1610         ld  a,(hl)              ;load current y-position
1611         jr  z,movedown
1612
1613 moveup: dec a                   ;decrease y-pos (=move up)
1614         ret m                   ;don't move off the screen (y<0)
1615         ld  (hl),a              ;save new y-pos
1616         ret                     ;finish
1617 movedown:
1618         inc a                   ;increase y-pos
1619         cp  55                  ;compare with bottom
1620         ret nc                  ;return if it has passed that line (>40)
1621         ld  (hl),a              ;otherwise save new position
1622         ret                     ;and return
1623
1624 ;--------------------------- check collision ----------------------------------
1625
1626 Enemies_hit:
1627         ld  de,(x)              ;e = X, d = Y
1628         ld  hl,enemies
1629         ld  b,nrenemies         ;check all 20 enemies
1630 check_collision:
1631         psh hl
1632         ld  a,(hl)
1633         and %00000010
1634         jr  z,check_next        ;2 or 3 = ok
1635         inc hl
1636
1637 collide_enemy:
1638 ;       psh hl
1639 ;       psh bc
1640 ;       ld  hl,enemy00          ;enemy 1 specs
1641 ;       add a,a                 ;a=type*2
1642 ;       add a,a                 ;a=type*4
1643 ;       ld  c,a                 ;c=type
1644 ;       ld  b,0                 ;bc = 4 * enemy nr.
1645 ;       add hl,bc               ;hl = enemy specs
1646 ;       ld  a,(hl)              ;load size byte
1647 ;       pop bc
1648 ;       pop hl
1649 ;       ld  c,a                 ;save size in c
1650
1651         inc hl
1652         ld  a,(hl)              ;check x match
1653         sub e                   ;enemy position minus yours
1654         add a,6
1655         jp  m,check_next
1656         cp  12
1657         jr  nc,check_next
1658
1659         inc hl
1660         ld  a,(hl)              ;check y match
1661         sub d                   ;same as with x-check
1662         add a,6
1663         jp  m,check_next
1664         cp  12
1665         jr  nc,check_next
1666         dec hl
1667         dec hl
1668
1669 take_pickup:
1670         ld  a,(hl)              ;load enemy type
1671
1672         psh hl                  ;we need hl
1673         ld  hl,2                ;increase score by 2
1674         cal scoreInc
1675         pop hl                  ;we're done
1676
1677         or  a
1678         jr  nz,collide          ;enemy when <>0
1679
1680         psh hl
1681         ld  hl,your_pickup      ;your pickups
1682         ld  a,(hl)              ;current
1683         inc a                   ;go to next
1684         cp  6                   ;pickups >=6
1685         jr  c,not_maxpickup
1686         ld  a,1                 ;yes: reset to pickup 1
1687 not_maxpickup:
1688         ld  (hl),a              ;save new
1689         cal disp_icons          ;display altered pickupicons
1690         pop hl
1691
1692         dec hl                  ;to enemy occ
1693         xor a                   ;set to 0 = gone
1694         ld  (hl),a              ;remove
1695         jr  check_next          ;all done, next..
1696
1697 collide:
1698         xor a
1699         ld  (hl),a              ;explosionFrame 0
1700         dec hl
1701         inc a
1702         ld  (hl),a              ;set to explode
1703         cal damage_you          ;auch!
1704
1705 check_next:
1706         pop hl
1707         inc hl
1708         inc hl
1709         inc hl
1710         inc hl
1711         djnz check_collision
1712         ret
1713
1714 ;--------------------------- story -------------------------------------------
1715
1716 storyPage:
1717         psh hl
1718         cal _clrLCD
1719         pop hl
1720 storyLine:
1721         inc hl
1722         ld  e,(hl)
1723         inc hl
1724         ld  d,(hl)
1725         ld  (_penCol),de
1726         inc hl
1727         cal _vputs
1728
1729         ld  a,(hl)
1730         dec a
1731         jr  z,storyLine
1732
1733         psh hl
1734         ld  hl,VIDEO_MEM
1735         ld  de,GRAPH_MEM
1736         ld  bc,1024
1737         ldir
1738         cal _clrLCD
1739         pop hl
1740
1741         inc hl
1742         ld  a,(hl)
1743         inc hl
1744         ld  b,(hl)
1745         psh hl
1746         cal DoSFX
1747         cal _getkey
1748         pop hl
1749         ret
1750
1751 Story:
1752         ld  hl,story01-1
1753         cal storyPage
1754         cal storyPage
1755         cal storyPage
1756         ret
1757
1758 story01:
1759         .db $21,$1d,"Cosmic year 6716"          ,0,0,$1d,$06
1760         .db $1b,$1d,"storyline coming soon..."  ,0,0,$1d,$06
1761         .db $09,$19,"the Nemesis saga continues",0,1
1762         .db $2e,$21,"with NEMESIS 86"           ,0,1
1763         .db $52,$36,"by Shiar"                  ,0,0,$19,$23
1764
1765 ;--------------------------- SFX ---------------------------------------------
1766
1767 CDoSFX:
1768         ld  hl,VIDEO_MEM
1769         ld  de,GRAPH_MEM
1770         ld  bc,1024
1771         ldir
1772         ld  b,64
1773         ld  a,-1
1774
1775 DoSFX:                          ;ins: a=beginLine b=nrOfLines
1776         ld  (curline),a
1777 SFXframe:
1778         psh bc
1779
1780         ld  a,(curline)         ;get line number
1781         inc a                   ;go to the next line
1782         ld  (curline),a         ;update
1783
1784         ld  l,a
1785         ld  h,0
1786         add hl,hl
1787         add hl,hl
1788         add hl,hl
1789         add hl,hl
1790
1791         ld  b,h                 ;save hl for later
1792         ld  c,l
1793
1794         ld  de,VIDEO_MEM
1795         add hl,de               ;go to ymin
1796         ld  d,h
1797         ld  e,l
1798
1799         ld  hl,GRAPH_MEM
1800         add hl,bc               ;hl->logo
1801
1802         ld  a,(curline)         ;Calculate how many lines to draw
1803         ld  c,a
1804         ld  a,64
1805         sub c
1806         ld  b,a
1807
1808 SFXdisp:                        ;display this frame on screen
1809         ld  a,b                 ;psh b (a will not be used)
1810         ld  bc,16               ;one line (=16 bytes, you'd know by now)
1811         ldir                    ;display (copy actually)
1812         ld  bc,-16              ;go up one line (not on screen)
1813         add hl,bc               ;so the same line will be displayed
1814         ld  b,a                 ;pop b
1815         djnz SFXdisp            ;repeat until whole screen is displayed
1816
1817         ld  b,8
1818 SFXdelay:
1819         halt
1820         djnz SFXdelay
1821
1822         pop  bc
1823         djnz SFXframe
1824         ret
1825
1826 ;--------------------------- handle boss -------------------------------------
1827
1828 Handle_boss:
1829         ld  hl,GRAPH_MEM
1830         ld  (PutWhere),hl
1831         ld  ix,spr_boss01
1832         ld  hl,bossx
1833         ld  d,(hl)
1834         inc hl
1835         ld  e,(hl)
1836         jp  putwidesprite
1837
1838 ;--------------------------- update score ------------------------------------
1839
1840 scoreInc:
1841         psh bc
1842         ld  bc,(score)
1843         add hl,bc
1844         ld  (score),hl
1845         pop bc
1846         ret
1847
1848 ;--------------------------- show icon ----------------------------------------
1849
1850 disp_icons:
1851         ld  hl,VIDEO_MEM+(16*57);57 rows down = seven rows from bottom
1852         ld  b,16*7              ;draw 16x (screen width) 7x (height)
1853         xor a                   ;blank line mask
1854 cleanline:
1855         ld  (hl),a              ;draw one piece of the divider-line
1856         inc hl                  ;move right (8 pixels = 1 byte)
1857         djnz cleanline          ;repeat (16bytes * 7rows * 8pixels)
1858
1859         ld  hl,VIDEO_MEM+(56*16)
1860         ld  (PutWhere),hl
1861
1862         cal disp_lives
1863
1864         ld  ix,spr_icon01       ;armorIcon
1865         ld  de,$1901            ;icon #1
1866         cal putwidesprite       ;display icon
1867         cal disp_armor          ;display value
1868
1869         ld  ix,spr_icon00
1870         ld  a,(torp_occ)
1871         or  a
1872         jr  z,no_torp
1873         ld  ix,spr_icon02       ;torpedoIcon
1874 no_torp:
1875         ld  de,$2901            ;icon #2
1876         cal putwidesprite       ;display
1877
1878         ld  ix,spr_icon03       ;emptyIcon
1879         ld  de,$3901            ;icon #3
1880         cal putwidesprite
1881
1882         ld  ix,spr_icon00       ;emptyIcon
1883         ld  a,(your_laser)
1884         or  a
1885         jr  z,no_laser
1886         ld  ix,spr_icon04       ;laserIcon
1887 no_laser:
1888         ld  de,$4901            ;icon #4
1889         cal putwidesprite
1890
1891         ld  ix,spr_icon00       ;emptyIcon
1892         ld  a,(your_multiples)
1893         and %11
1894         jr  z,no_multiples
1895         ld  ix,spr_icon05
1896 no_multiples:
1897         ld  de,$5901            ;icon #5
1898         cal putwidesprite
1899
1900         ld  ix,spr_icon03
1901         ld  de,$6901
1902         cal putwidesprite
1903
1904         ld  a,(your_pickup)     ;pickups taken
1905         add a,a                 ;picks*2 (sets z-flag)
1906         ret z                   ;return if no pickups
1907         add a,a                 ;picks*4
1908         add a,a                 ;picks*8
1909         add a,a                 ;picks*$10
1910         add a,$09               ;add 0ah
1911         ld  d,a                 ;y-pos = picks * $10 + $0a (19,29,39,49,59)
1912         ld  e,$01               ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
1913
1914         ld  ix,spr_icon
1915         cal putwidesprite
1916         ret
1917
1918 disp_armor:
1919         ld  hl,$3925            ;Display Armor left
1920         ld  (_penCol),hl        ;place @ armorIcon
1921         ld  a,(your_armor)      ;load armor left
1922         add a,'0'               ;make digit
1923         cal _vputmap            ;display char
1924         ret
1925
1926 disp_lives:
1927         ld  hl,$3900            ;display Lives
1928         ld  (_penCol),hl        ;bottom left
1929         ld  hl,savestr+2
1930         ld  (hl),'L'
1931         inc hl
1932         ld  (hl),'x'
1933         inc hl
1934
1935         ld  a,(your_lives)      ;nr of lives in a
1936         add a,'0'               ;make digit
1937         ld  (hl),a
1938         dec hl \ dec hl
1939         cal _vputs              ;display on screen
1940         ret
1941
1942 ;--------------------------- proc ---------------------------------------------
1943
1944 BLACKLCD:
1945         ld  hl,VIDEO_MEM        ;screen location (top left)
1946         ld  de,VIDEO_MEM+1
1947         ld  (hl),%11111111
1948         ld  bc,1024             ;loop 1024 times = entire screen
1949         ldir
1950         set 3,(iy+5)            ;set white on black
1951         ret
1952
1953 ;--------------------------- game over / new game / death ---------------------
1954 own_name:
1955         .db $12,7,"nemesis"
1956
1957 save_hi:
1958         ld  hl,own_name         ;find own variable
1959         xor a
1960         cal _ABS_MOV10TOOP1
1961         cal _FINDSYM
1962         ret c                   ;not found? who cares...
1963
1964         ld  a,b                 ;save the stored section
1965         ld  h,d
1966         ld  l,e
1967         ld  b,0
1968         ld  de,4+stored_data_start-_asm_exec_ram
1969         add hl,de
1970         adc a,b
1971         cal _SET_ABS_DEST_ADDR
1972         ld  a,0
1973         ld  hl,stored_data_start
1974         cal _SET_ABS_SRC_ADDR
1975         ld  hl,stored_data_end-stored_data_start
1976         cal _SET_MM_NUM_BYTES
1977         cal _mm_ldir
1978         ret                     ;save done
1979
1980 game_over:
1981         pop hl                  ;=ret (game_over was called from a procedure)
1982 game_over_nopop:
1983         cal BLACKLCD            ;clear screen
1984         ld  hl,$0603
1985         ld  (_curRow),hl        ;center
1986         ld  hl,txt_gameover
1987         cal _puts               ;display "GAME OVER"
1988
1989         xor a                   ;clear a (AHL will be displayed)
1990         ld  hl,$1006            ;bottom-1 right
1991         ld  (_curRow),hl        ;set
1992         ld  hl,(score)          ;your score
1993         cal _dispahl            ;display it (a=0)
1994         ld  hl,$314b            ;bottom-1 right before score ^^
1995         ld  (_penCol),hl        ;set
1996         ld  hl,txt_score        ;"Score"
1997         cal _vputs              ;display (small)
1998
1999         ld  hl,$1007            ;bottom right
2000         ld  (_curRow),hl        ;set
2001         ld  hl,(hiscore)        ;hi-score
2002         cal _dispahl            ;display
2003         ld  hl,$3946            ;bottom right before hiscore ^^
2004         ld  (_penCol),hl        ;set
2005         ld  hl,txt_hiscore      ;"Hiscore"
2006         cal _vputs              ;display (small)
2007         res 3,(iy+5)
2008
2009         ld  de,(score)
2010         ld  hl,(hiscore)
2011         cal CP_HL_DE
2012         jr  nc,no_hiscore
2013         ld  (hiscore),de
2014
2015 no_hiscore:
2016         cal save_hi
2017
2018         ld  b,$20
2019 wait2:  halt \ halt
2020         djnz wait2              ;delay
2021         cal _getkey             ;wait for keypress
2022         jp  quit                ;restore some things and return to TI-OS/shell
2023
2024 New_game:
2025         xor a                   ;score 0
2026         ld  (score),a           ;reset score
2027         ld  (score+1),a         ;reset score
2028         inc a                   ;level #1
2029         ld  (level),a           ;reset level nr
2030         ld  hl,level01          ;set level pointer to level#1
2031         ld  (levelp),hl         ;reset level pointer
2032         ld  a,4
2033         ld  (your_lives),a      ;3 lives (4 will be decreased @ You_die)
2034         ld  (pickuptimer),a     ;next pickup after 4 enemies destroyed
2035
2036 You_die:
2037         ld  hl,your_lives
2038         dec (hl)                ;decrease lives
2039         ld  a,(hl)              ;load lives left
2040         inc a                   ;if lives=0ffh then a=0
2041         jp  z,game_over         ;if so, game's over
2042
2043         xor a                   ;a=0
2044 ;       ld  (your_armor),a      ;no armor
2045         ld  (torp_occ),a        ;no torpedoes
2046         ld  (your_laser),a      ;no laser
2047         ld  (your_pickup),a     ;reset pickups
2048         ld  (your_multiples),a  ;no multiples
2049  ld a,5 ;&&& betatest; remove when released!
2050  ld (your_armor),a
2051         jr  nonext_level
2052
2053 ;--------------------------- next level ---------------------------------------
2054
2055 Next_level:
2056         ld  hl,level            ;level number
2057         ld  a,(hl)
2058         inc a
2059         ld  (hl),a
2060
2061         ld  hl,(levelp)         ;level pointer
2062         ld  bc,5+32+4           ;advance four bytes (=one level)
2063         add hl,bc               ;update to point to next level
2064         ld  (levelp),hl         ;save
2065
2066         ld  h,0                 ;increase score....
2067         ld  l,a                 ;by level number
2068         ld  bc,20
2069         add hl,bc               ;plus 20
2070         cal scoreInc            ;update score
2071
2072 nonext_level:
2073         ld  a,80
2074         ld  (nextevent),a       ;time to first enemy appearance
2075
2076         ld  hl,(levelp)         ;level pointer
2077         ld  a,(hl)              ;load new level-enemy type
2078         ld  (level_enemy),a     ;set level-enemy
2079         inc hl
2080         ld  a,(hl)              ;load new appearance-time
2081         ld  (eventtime),a       ;set
2082         inc hl
2083         ld  a,(hl)              ;load nr of enemies in this level
2084         ld  (eventleft),a       ;set nr of events left
2085         inc hl
2086         ld  a,(hl)              ;movement of enemies in this level
2087         ld  (level_move),a      ;do it
2088         inc hl
2089         ld  a,(hl)              ;how frequent the enemies fire a bullet
2090         ld  (level_fire),a      ;consider it done
2091
2092         inc hl
2093         ld  de,spacespace
2094         ld  bc,36
2095         ldir
2096
2097 ;       xor a
2098 ;       ld  (level_occ),a       ;no boss (yet)
2099
2100         ld  ix,starx1
2101         ld  b,nrstars1
2102         cal placestars
2103         ld  hl,RanPos
2104         inc (hl)
2105         ld  ix,starx2
2106         ld  b,nrstars2
2107         cal placestars
2108
2109         xor a
2110         ld  (timer),a           ;reset time
2111         ld  hl,your_occ         ;hl = your_occ
2112         ld  (hl),a              ;reset your ship (not exploding)
2113         inc hl                  ;hl = your_inv
2114         ld  (hl),50             ;set 50 frames invulnerable
2115         ld  hl,x                ;begin position x=...
2116         ld  (hl),a              ;...=a=0=left
2117         inc hl                  ;y=...
2118         ld  a,24                ;...=24=middle
2119         ld  (hl),a              ;your y
2120         ld  (bossy),a           ;and y of boss
2121         ld  a,80
2122         ld  (bossx),a
2123
2124         ld  a,(torp_occ)
2125         or  a                   ;no torpedoes?
2126         jr  z,torpsclear        ;then just continue (=0)
2127         ld  a,1                 ;if so, set to "ready to fire" (=1)
2128 torpsclear:
2129
2130         ld  de,$0018            ;x=0, y=24 (like you..)
2131         cal Place_multiples     ;place all multiple-positions at (0,24)
2132
2133         ld  hl,ybullets         ;clear your/enemy bullets
2134         ld  (hl),a              ;clear first byte
2135         ld  de,ybullets+1       ;and copy this byte to the next byte
2136         ld  bc,(nrybullets+nrebullets)*3-1      ;bc times (all bullets)
2137         ldir
2138
2139         ld  hl,enemies          ;and remove all enemies as well
2140         ld  (hl),a              ;clear first byte
2141         ld  de,enemies+1        ;point to the next
2142         ld  bc,add2enemy+nrenemies*2    ;clear enemy-info + enemiesxtra
2143         ldir
2144
2145 ;--------------------------- setup game ---------------------------------------
2146
2147 game_setup:
2148         cal BLACKLCD
2149         ld  hl,$0703
2150         ld  (_curRow),hl        ;center
2151         ld  hl,txt_level
2152         cal _puts               ;display "LEVEL "
2153
2154         ld  a,(level)
2155         ld  l,a
2156         ld  h,$00
2157
2158         cal UNPACK_HL
2159         add a,'0'
2160         ld  b,a
2161         cal UNPACK_HL
2162         add a,'0'
2163         cal _putc               ;display second digit
2164         ld  a,b
2165         cal _putmap             ;display first digit
2166
2167         ld  hl,$0904
2168         ld  (_curRow),hl        ;display lives left below level nr
2169         ld  hl,txt_lives        ;bar text: "Lx0"...
2170         ld  a,(your_lives)      ;lives left
2171         add a,'0'               ;make value
2172         ld  (txt_lives+3),a     ;add to text
2173         cal _puts               ;display the string
2174         res 3,(iy+5)            ;set white on black
2175
2176         ld  b,$20
2177 wait:   halt \ halt
2178         djnz wait               ;delay
2179         cal _getkey             ;wait for keypress
2180
2181         cal CLEARLCD            ;clear screen
2182         cal disp_icons          ;display bottom icons
2183
2184         ld  hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
2185         ld  b,16                ;draw 16x (screen width)
2186         ld  a,%11111111         ;horizontal line mask
2187 drawline:
2188         ld  (hl),a              ;draw one piece of the divider-line
2189         inc hl                  ;move right (8 pixels = 1 byte)
2190         djnz drawline           ;repeat (16bytes * 8pixels =128= screen width)
2191         ret
2192
2193
2194 placestars:
2195         add a,b
2196         rlca \ rlca
2197         ld  hl,(RanPos)
2198         add a,(hl)
2199         xor %00100100
2200         rlca
2201         ld  (hl),a
2202
2203         ld  h,0                 ; l = 0
2204         ld  l,a                 ;hl = 0..255
2205         add hl,hl               ;hl = 0..510
2206         ld  c,a                 ;hl = 0..765
2207
2208         ld  a,r                 ;a = 0..255
2209         rra                     ;a = 0..127
2210         ld  d,0
2211         ld  e,a
2212         add hl,de
2213         ld  e,c
2214         add hl,de
2215
2216         ld  de,GRAPH_MEM
2217         add hl,de
2218
2219         ld  (ix),l
2220         ld  (ix+1),h
2221         inc ix \ inc ix
2222         djnz placestars
2223         ret
2224
2225 ;--------------------------- putsprite ----------------------------------------
2226 ;--------------------------- de =(X,Y) ----------------------------------------
2227
2228 offsets_table:
2229         .db 128,64,32,%10000,%01000,%00100,%00010,%00001
2230 putsprite:
2231         ld  a,d                 ;a = X
2232         and %00000111           ;a = X mod 8 = bit nr. to mask
2233         ld  hl,offsets_table    ;pixel mask table
2234         ld  c,a                 ;bit nr.
2235         ld  b,0                 ;word
2236         add hl,bc               ;add to table
2237         ld  a,(hl)              ;a = pixel mask
2238         ld  (_smc1+1),a         ;alter pixel mask
2239
2240         ld  hl,GRAPH_MEM        ;save-location
2241         ld  a,e                 ;y-coord
2242         add a,a                 ;y*2
2243         add a,a                 ;y*4
2244         add a,a                 ;y*8
2245         rl  b                   ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
2246         add a,a                 ;y*16 (width of screen)
2247         rl  b                   ;b=b*2+overflow (if y>64 then bc=bc+512)
2248         srl d                   ;d/2
2249         srl d                   ;d/4
2250         srl d                   ;d/8 (8 bits in byte) ** c is set when overflow
2251         add a,d                 ;a = (Y*16+X/8) mod 256
2252         jr  nc,_n1              ;jump if no carry = no overflow = a<=255
2253         inc b                   ;a>255 so increase bc by 256
2254 _n1:    ld  c,a                 ;c = (Y*16+X/8) mod 256
2255         add hl,bc               ;bc = Y*16+X/8
2256           
2257         ld  d,(ix)
2258         ld  b,(ix+1)
2259 _oloop: psh bc                  ;Save # of rows
2260         psh hl                  ;Save screen address
2261         ld  b,d                 ;Load width
2262         ld  c,(ix+2)            ;Load one line of image
2263         inc ix
2264 _smc1:  ld  a,1                 ;Load pixel mask
2265 _iloop: sla c                   ;Test leftmost pixel
2266         jr  nc,_noplot          ;See if a plot is needed
2267         ld  e,a                 ;OR pixel with screen
2268         or  (hl)
2269         ld  (hl),a
2270         ld  a,e
2271 _noplot:rrca
2272         jr  nc,_notedge         ;Test if edge of byte reached
2273         inc hl                  ;Go to next byte
2274 _notedge:
2275         djnz _iloop
2276         pop hl                  ;Restore address
2277         ld  bc,16               ;Go to next line
2278         add hl,bc
2279         pop bc                  ;Restore data
2280         djnz _oloop
2281         ret
2282
2283 ;--------------------------- putbigsprite -------------------------------------
2284
2285 putwidesprite:
2286         ld       a,d
2287         and      7
2288         ld       hl,offsets_table
2289         ld       c,a
2290         ld       b,0
2291         add      hl,bc
2292         ld       a,(hl)
2293         ld       (wsmc1+1),a
2294         ld       (wsmc2+1),a
2295         ld       hl,(PutWhere)
2296
2297         ld       a,e
2298         add      a,a
2299         add      a,a
2300         add      a,a
2301
2302         rl       b
2303         add      a,a
2304         rl       b
2305         srl      d
2306         srl      d
2307         srl      d
2308         add      a,d
2309         jr       nc,n1
2310         inc      b
2311 n1:     ld       c,a
2312         add      hl,bc                                    
2313           
2314         ld       d,(ix)       
2315         ld       b,(ix+1)        
2316 woloop: psh      bc                         ;Save # of rows
2317         psh      hl                         ;Save screen address
2318         ld       b,d                        ;Load width
2319         ld       c,(ix+2)                   ;Load one line of image
2320         inc      ix
2321 wsmc1:  ld       a,1                        ;Load pixel mask
2322 wiloop: sla      c                          ;Test leftmost pixel
2323         jr       nc,wnoplot                 ;See if a plot is needed
2324         ld       e,a                        ;OR pixel with screen
2325         or       (hl)
2326         ld       (hl),a
2327         ld       a,e
2328 wnoplot:
2329         rrca
2330         jr       nc,wnotedge                ;Test if edge of byte reached
2331         inc      hl                         ;Go to next byte
2332 wnotedge:
2333 wsmc2:  cp       1
2334         jr       z,wover_1
2335
2336         djnz     wiloop
2337         pop      hl                         ;Restore address
2338         ld       bc,16                      ;Go to next line
2339         add      hl,bc
2340         pop      bc                         ;Restore data
2341         djnz     woloop
2342         ret
2343 wover_1:
2344         ld       c,(ix+2)
2345         inc      ix
2346         djnz     wiloop
2347         dec      ix
2348         pop      hl
2349         ld       bc,16
2350         add      hl,bc
2351         pop      bc
2352         djnz     woloop
2353         ret
2354
2355 ;------------------------------------------------------------------------------
2356 ;------------------------------- sprites --------------------------------------
2357 ;------------------------------------------------------------------------------
2358
2359 spr_ship01:
2360         .db 7,7         ;ship alpha class
2361         .db %01111000   ;  ████
2362         .db %11100000   ; ███
2363         .db %11111100   ; ██████
2364         .db %11110010   ; ████  █
2365         .db %11111100   ; ██████
2366         .db %11100000   ; ███
2367         .db %01111000   ;  ████
2368 spr_ship01i:
2369         .db 7,7         ;ship alpha class
2370         .db %01010000   ;  █ █
2371         .db %10100000   ; █ █
2372         .db %01010100   ;  █ █ █
2373         .db %10100010   ; █ █   █
2374         .db %01010100   ;  █ █ █
2375         .db %10100000   ; █ █
2376         .db %01010000   ;  █ █
2377
2378 spr_ship02:
2379 ;       .db 7,7         ;ship beta class
2380 ;       .db %11100000   ; ███
2381 ;       .db %11110000   ; ████
2382 ;       .db %01111100   ;  █████
2383 ;       .db %01110010   ;  ███  █
2384 ;       .db %01111100   ;  █████
2385 ;       .db %11110000   ; ████
2386 ;       .db %11100000   ; ███
2387 spr_ship02i:
2388 ;       .db 7,7         ;ship beta class
2389 ;       .db %01000000   ;  █
2390 ;       .db %10100000   ; █ █
2391 ;       .db %01010100   ;  █ █ █
2392 ;       .db %00100010   ;   █   █
2393 ;       .db %01010100   ;  █ █ █
2394 ;       .db %10100000   ; █ █
2395 ;       .db %01000000   ;  █
2396
2397 spr_multiple:
2398         .db 6,4         ;multiples
2399         .db %01111000   ;  ████
2400         .db %11111100   ; ██████
2401         .db %11111100   ; ██████
2402         .db %01111000   ;  ████
2403
2404 spr_bullet01:
2405         .db 5,3         ;your bullets
2406         .db %00110000   ;   ░▒▓█▒
2407         .db %11111000   ; ░▒▓████▒
2408         .db %00110000   ;   ░▒▓█▒
2409 spr_bullet02:
2410         .db 5,3
2411         .db %11110000   ; ░▒▓███▒
2412         .db %11111000   ; ░▒▓████▒
2413         .db %11110000   ; ░▒▓███▒
2414 spr_bullett1:
2415         .db 4,3         ;▒▒▒
2416         .db %11100000   ;▒███
2417         .db %11110000   ; ████
2418         .db %01110000   ;  ███
2419
2420 spr_bullete1:
2421         .db 4,3         ;enemy bullets
2422         .db %01100000   ;  ▒█▓▒░
2423         .db %11110000   ; ▒███▓▒░
2424         .db %01100000   ;  ▒█▓▒░
2425
2426 ;---------------------------------------- explosion -------------------------------------------
2427
2428 spr_explosion:                               
2429         .db 8,6         ;1
2430         .db %00000000
2431         .db %00011100   ;    ███
2432         .db %00111110   ;   █████
2433         .db %01010110   ;  █ █ ██
2434         .db %00111000   ;   ███
2435         .db %00000000
2436
2437         .db 8,6         ;2
2438         .db %00110000   ;   ██
2439         .db %01001110   ;  █ ▒███
2440         .db %10111110   ; █ █████
2441         .db %01001111   ;  █ ▒████
2442         .db %00111000   ;   ███
2443         .db %00011010   ;    ██ █
2444
2445         .db 8,6         ;3
2446         .db %10110000   ; █ ██
2447         .db %01001110   ;  █  ███
2448         .db %10110101   ; █ ██▒█▒█
2449         .db %01000101   ;  █  ▒█▒█
2450         .db %00111110   ;   █████
2451         .db %01011010   ;  █ ██ █
2452
2453         .db 8,6         ;4
2454         .db %00101010   ; ▒ █▒█ █
2455         .db %01000110   ;  █  ▒██
2456         .db %10110101   ; █ ██ █ █
2457         .db %01100110   ;  ██  ██▒
2458         .db %00111100   ;   ████▒
2459         .db %01011001   ;  █ ██ ▒█
2460
2461         .db 8,6         ;5
2462         .db %01000000   ;  █▒ ▒ ▒
2463         .db %00100101   ;  ▒█  █▒█
2464         .db %00010100   ; ▒ ▒█ █ ▒
2465         .db %01000100   ;  █▒  █
2466         .db %00010010   ;   ▒█▒▒█
2467         .db %10011010   ; █▒ ██ █▒
2468
2469         .db 8,6         ;6
2470         .db %01000100   ;  █   █
2471         .db %00100000   ;   ▒█ ▒ ▒
2472         .db %00000001   ;    ▒ ▒ █
2473         .db %01000100   ;  █   █
2474         .db %00100010   ;   █▒  █
2475         .db %01001000   ; ▒█ ▒█ ▒
2476
2477         .db 8,6         ;7
2478         .db %00001000   ;  ▒  █▒
2479         .db %11000010   ; ██ ▒  █
2480         .db %00000000   ;        ▒
2481         .db %00100000   ;  ▒█  ▒
2482         .db %00000001   ;   ▒   ▒█
2483         .db %00110000   ;  ▒██▒
2484
2485         .db 8,6         ;8
2486         .db %00000100   ;     ▒█
2487         .db %00000000   ; ▒▒    ▒
2488         .db %01000000   ;  █
2489         .db %00000000   ;   ▒
2490         .db %00000010   ;       █▒
2491         .db %00100100   ;   █▒ █
2492
2493 ;--------------------------------------- bar -----------------------------------
2494
2495 spr_icon:
2496         .db 16,7        ;selected .......:.......:
2497         .db %11111111,%11111111 ; ████████████████
2498         .db %11000000,%00000001 ; ██             █
2499         .db %11000000,%00000001 ; ██             █
2500         .db %11000000,%00000001 ; ██             █
2501         .db %11000000,%00000001 ; ██             █
2502         .db %11000000,%00000001 ; ██             █
2503         .db %11111111,%11111111 ; ████████████████
2504 spr_icon00:
2505         .db 16,7        ;unused   .......:.......:
2506         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
2507         .db %11010101,%01010101 ; ██ █ █ █ █ █ █ █
2508         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
2509         .db %11010101,%01010101 ; ██ █ █ █ █ █ █ █
2510         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
2511         .db %11010101,%01010101 ; ██ █ █ █ █ █ █ █
2512         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
2513 spr_icon01:
2514         .db 16,7        ;armor  ; .......:.......:
2515         .db %10001111,%10000000 ; █   █████
2516         .db %10010000,%01000000 ; █  █     █  ▒▒▒
2517         .db %10101110,%00100000 ; █ █ ███   █ ▒▒▒
2518         .db %10100111,%10100000 ; █ █  ████ █ ▒▒▒
2519         .db %10101110,%00100000 ; █ █ ███   █ ▒▒▒
2520         .db %10010000,%01000000 ; █  █     █  ▒▒▒
2521         .db %10001111,%10000000 ; █   █████
2522 spr_icon02:
2523         .db 16,7        ;torpedo  .......:.......:
2524         .db %10111000,%00010101 ; █ ███      █ █ █
2525         .db %10011100,%00010101 ; █  ███     █ █ █
2526         .db %10111000,%01001010 ; █ ███    █  █ █
2527         .db %10000000,%11101010 ; █       ███ █ █
2528         .db %11100001,%11100101 ; ███    ████  █ █
2529         .db %10011000,%11110101 ; █  ██   ████ █ █
2530         .db %11100110,%00110010 ; ███  ██   ██  █
2531 spr_icon03:
2532         .db 8,7         ;empty    .......:
2533         .db %10000000 ;00000000 ; █
2534         .db %10000000 ;00000000 ; █
2535         .db %10000000 ;00000000 ; █
2536         .db %10000000 ;00000000 ; █
2537         .db %10000000 ;00000000 ; █
2538         .db %10000000 ;00000000 ; █
2539         .db %10000000 ;00000000 ; █
2540 spr_icon04:
2541         .db 16,7        ;laser    .......:.......:
2542         .db %10000000,%00000000 ; █
2543         .db %10110010,%10000000 ; █ ██  █ █
2544         .db %10111011,%00000000 ; █ ███ ██
2545         .db %10011101,%11111111 ; █  ███ █████████
2546         .db %10111011,%00000000 ; █ ███ ██
2547         .db %10110010,%10000000 ; █ ██  █ █
2548         .db %10000000,%00000000 ; █
2549 spr_icon05:
2550         .db 16,7        ;multiple .......:.......:
2551         .db %10000011,%10000000 ; █     ███
2552         .db %10000001,%11100110 ; █      ████  ██
2553         .db %10000001,%11100000 ; █      ████
2554         .db %10000011,%10000000 ; █     ███
2555         .db %10011000,%00000000 ; █  ██
2556         .db %10111100,%11000011 ; █ ████  ██    ██
2557         .db %10011000,%00000000 ; █  ██
2558
2559 ;---------------------------- texts -------------------------------------------
2560
2561 txt_about:      .db " v0.94.A08",127,"by Shiar",0
2562 txt_email:      .db "shiar0@hotmail.com",0
2563 txt_menu1:      .db "CONTINUE",0
2564 txt_menu2:      .db "NEW GAME",0
2565
2566 txt_level:      .db "LEVEL ",0
2567 txt_gameover:   .db "GAME OVER!",0
2568 txt_score:      .db "Score",0
2569 txt_hiscore:    .db "Hiscore",0
2570 txt_lives:      .db "Lx0?",0
2571 txt_pressenter: .db "Enter to continue",0
2572
2573 ;---------------------------- save data ---------------------------------------
2574
2575 PutWhere        .dw GRAPH_MEM           ;where to put the wide sprites
2576 level           .db $00                 ;level number
2577 levelp          .dw $0000               ;pointer to level data
2578
2579 score           .dw $0000
2580
2581 stored_data_start:
2582 hiscore         .dw $0000
2583 stored_data_end:
2584
2585 your_pickup     .db $00
2586 your_occ        .db $00                 ;0=normal 1..16=exploding
2587 your_inv        .db $00                 ;invincibility left
2588 your_armor      .db $00                 ;HP left
2589 your_lives      .db $00                 ;
2590
2591 your_laser      .db $00                 ;laser avail: 0=no, 1=yes
2592 your_multiples  .db $00                 ;multiples present
2593 torp_occ        .db $00                 ;torp.state: 0=unavail 1=avail 2=presnt
2594 torp_pos        .dw $0000               ;torpedo position (x,y)
2595
2596 ;---------------------------- enemy data --------------------------------------
2597
2598 sprites:
2599         .db $00
2600         .db spr_enemy01-spr_enemy00
2601         .db spr_enemy02-spr_enemy00
2602         .db spr_enemy03-spr_enemy00
2603         .db spr_enemy04-spr_enemy00
2604         .db spr_enemy05-spr_enemy00
2605         .db spr_enemy06-spr_enemy00
2606         .db spr_enemy07-spr_enemy00
2607         .db spr_enemy08-spr_enemy00
2608
2609 spr_enemy00:
2610         .db 7,5                         ;pickup
2611         .db %11111110                   ; ███████
2612         .db %11111110                   ; ███████
2613         .db %11000110                   ; ██   ██
2614         .db %11111110                   ; ███████
2615         .db %11111110                   ; ███████
2616 spr_enemy01:
2617         .db 6,6                         ;enemy type one
2618         .db %00111100                   ;   ████
2619         .db %01110000                   ;  ███
2620         .db %11110000                   ; ████
2621         .db %11110000                   ; ████
2622         .db %01110000                   ;  ███
2623         .db %00111100                   ;   ████
2624 spr_enemy02:
2625         .db 8,6                         ;enemy type two
2626         .db %00111111                   ;    █████
2627         .db %01111000                   ;  ████
2628         .db %11111100                   ; ██████
2629         .db %11111100                   ; ██████
2630         .db %01111000                   ;  ████
2631         .db %00111111                   ;    █████
2632 spr_enemy03:
2633         .db 6,6                         ;enemy type three
2634         .db %01111100                   ;  █████
2635         .db %11110000                   ; ████
2636         .db %11111000                   ; █████
2637         .db %11111000                   ; █████
2638         .db %11110000                   ; ████
2639         .db %01111100                   ;  █████
2640 spr_enemy04:
2641         .db 6,6                         ;enemy type four
2642         .db %00111000                   ;   ███
2643         .db %01111100                   ;  █████
2644         .db %11111000                   ; █████
2645         .db %11111000                   ; █████
2646         .db %01111100                   ;  █████
2647         .db %00111000                   ;   ███
2648 spr_enemy05:
2649         .db 7,6                         ;enemy type five
2650         .db %00011110                   ;    ████
2651         .db %01111110                   ;  ██████
2652         .db %11111100                   ; ██████
2653         .db %11111100                   ; ██████
2654         .db %01111110                   ;  ██████
2655         .db %00011110                   ;    ████
2656 spr_enemy06:
2657         .db 7,6                         ;enemy type six
2658         .db %00011100                   ;    ███
2659         .db %01111110                   ;  ██████
2660         .db %10111000                   ; █ ███
2661         .db %10111000                   ; █ ███
2662         .db %01111110                   ;  ██████
2663         .db %00011100                   ;    ███
2664 spr_enemy07:
2665         .db 8,6                         ;enemy type seven
2666         .db %00011110                   ;    ████
2667         .db %01111111                   ;  ███████
2668         .db %10011100                   ; █  ███
2669         .db %10011100                   ; █  ███
2670         .db %01111111                   ;  ███████
2671         .db %00011110                   ;    ████
2672 spr_boss01:
2673         .db 16,10                       ;boss type one
2674         .db %00000001,%11111111         ;        █████████
2675         .db %00001111,%11111110         ;     ███████████
2676         .db %00111111,%11110000         ;   ██████████
2677         .db %01011111,%10000000         ;  █ ██████
2678         .db %10011111,%01000000         ; █  █████ █
2679         .db %10011111,%01000000         ; █  █████ █
2680         .db %01011111,%10000000         ;  █ ██████
2681         .db %00111111,%11110000         ;   ██████████
2682         .db %00001111,%11111110         ;     ███████████
2683         .db %00000001,%11111111         ;        █████████
2684
2685
2686 spr_enemy08:
2687         .db 8,6         ;enemy type eight
2688         .db %00011110   ;    ████
2689         .db %01111111   ;  ███████
2690 enemy00:.db %10011100   ; █  ███
2691         .db %10011100   ; █  ███
2692         .db %01111111   ;  ███████
2693         .db %00011110   ;    ████
2694
2695         ;enemyInfo:     %000000:HP %10:occ $00:type $00:app $00:unused
2696 enemy01:                        ;#1     HP:1    app:random
2697         .db %00000010,1,1,0
2698 enemy02:                        ;#2     HP:1    app:halflure
2699         .db %00000010,2,3,0
2700 enemy03:                        ;#3     HP:1    app:lure
2701         .db %00001111,3,2,0
2702
2703 enemy04:                        ;#4     HP:2    app:lure
2704         .db %00000110,4,2,0
2705 enemy05:                        ;#5     HP:2    app:random      moving
2706         .db %00000111,5,3,0
2707 enemy06:                        ;#6     HP:3    app:lure        moving
2708         .db %00001011,6,2,0
2709
2710 enemy07:                        ;#7     HP:7    app:halflure    moving
2711         .db %00011011,7,3,0
2712
2713 ;----------------------------- level info -------------------------------------
2714
2715         ;format: enemy nr; enemy frequency; next lvl; level_move; level_fire
2716         ;tunnel size; groundtype; 17_ground; 17_ceiling; stars1; stars2
2717 level01:                                ;efrequency must be odd if halfluring!
2718         .db $01,$1b,$2f,%00010000,255,0,0
2719         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2720         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2721         .db 1,1
2722 level02:
2723         .db $02,$13,$4b,%01010000,064,0,0
2724         .db 1,2,3,4,5,6,6,5,4,3,4,5,4,3,2,1
2725         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2726         .db 1,1
2727 level03:
2728         .db $03,$2d,$3f,%01100000,255,-9,1
2729         .db 3,2,4,3,2,2,1,1,1,1 ,1,1,21,17,18,20
2730         .db 1,1,1,1,1,1,1,3,6,12,9,1,21,19,18,18
2731         .db -1,-1
2732
2733 level04:
2734         .db $04,$11,$41,%00010000,057,0,0
2735         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2736         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2737         .db 1,1
2738 level05:
2739         .db $05,$11,$45,%01010010,031,-7,1
2740         .db 14,12,11,9,10,7,7,5,4,3,4,4,2,3,1,2
2741         .db 1, 1, 1, 1,1, 1,1,1,1,1,1,1,1,1,1,1
2742         .db 1,1
2743 level06:
2744         .db $06,$19,$3a,%01110000,255,-4,1
2745         .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
2746         .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
2747         .db 1,1
2748
2749 level07:
2750         .db $07,$09,$ff,%00010000,043,0,0
2751         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2752         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2753         .db 1,1
2754
2755 ;----------------------------- logo -------------------------------------------
2756
2757 logo_nemesis:
2758 .db %11111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00001011,%11111111,%11111111,%11111111,%11111000
2759 .db %01111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00011011,%11111111,%11111111,%11111111,%11110000
2760 .db %00111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00111011,%11111111,%11111111,%11111111,%11100000
2761 .db %00011111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%01111011,%11111111,%11111111,%11111111,%11000000
2762 .db %00000000,%00000000,%00000001,%00011110,%00010000,%00000000,%10000001,%00011110,%00010000,%000000001,%00000000,%00001000,%01000000,%00000000,%00000000,%00000000
2763 .db %00000000,%00000000,%00000011,%00011110,%00110000,%00000001,%10000011,%00011110,%00110000,%000000011,%00000000,%00011000,%11000000,%00000000,%00000000,%00000000
2764 .db %00000000,%00000000,%00000111,%00011110,%01110000,%00000011,%10000111,%00011110,%01110000,%000000111,%00000000,%00111001,%11000000,%00000000,%00000000,%00000000
2765 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
2766 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
2767 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
2768 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
2769 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
2770 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
2771 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
2772 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
2773 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000111,%11010001
2774 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00011011
2775 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010101
2776 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010001
2777
2778 ;----------------------------- end --------------------------------------------
2779
2780         .end
2781 .end
2782
2783
2784 ;------------------------------------------------------------------------------
2785
2786 ;0.94.1008 -- 08.X.99 -- size 4531 (4456)
2787 ;
2788 ;       + starfield background scrolling left (2 layers (front and back))
2789 ;       * enemies aim their bullets towards you: 5 different directions!
2790 ;       # removed some unintended <add a,a> instructions
2791 ;       * gamefield is now white on black instead of normal black on white!
2792 ;       + enemies can also move slowly, fast, very fast, or 1st fast then slow
2793 ;       # you can't fire when you're exploding
2794 ;       + GROUND scrolling at bottom. You die if you hit the ground (!!!)
2795 ;         (unlike the ground in version 0.925test there are NO bugs)
2796 ;       + ceiling scrolling at top, just like the ground
2797 ;       * ground and ceiling profile are different each level
2798 ;       * ground and/or ceiling can be non-present (speeding up cause skipped)
2799 ;       # no more BIG crash if enemies fire too much bullets ( >10)
2800 ;       + frequency of enemies firing bullets differs per level
2801 ;       * stars scroll at alternate speeds, different than any ship/pick (3/4)
2802 ;       + special effect displaying titlescreen (stole from Spaze Invaders'83)
2803 ;       * enemies can fire either directly on entering the level, or not
2804 ;       + "tunnel" (playfield) can narrow/grow at random (depending on level)
2805 ;       * minimum size of "tunnel" can be different per level
2806 ;       + menu at startup. select "NEW GAME" and "LOAD GAME" with up/down
2807 ;       - nemesis doesn't use the SpazeInvaders effect anymore (took too long)
2808 ;       + choosing new game will display a demo first (text will be displayed
2809 ;         with special effect [SI] saying the storyline will come soon)
2810 ;       * levels altered to be more challenging and different (seven levels)
2811 ;       # the usual bugs that come with new features removed (i think?)
2812 ;       * you get 5 shield-points at start and after death
2813 ;
2814 ;
2815 ;        + added        - removed       * changed       # bug fixed
2816