version 0.99 pre2: pause options, gameplay fixes/features
authorMischa Poslawsky <nemesis@shiar.org>
Wed, 16 Aug 2000 11:49:22 +0000 (13:49 +0200)
committerMischa Poslawsky <nemesis@shiar.org>
Wed, 18 Mar 2009 03:50:25 +0000 (04:50 +0100)
# when enemy changed into a pickup, movement is set to vslow
* instead of turning into a pickup, enemies explode and a pickup
   appears at the right side of the screen (moves left slowly)
# bullets do damage again (screenflash made damage become 0)
+ when destroyed by bullets, the armor bar will show 0HP left
* all enemy bullets do the same damage in all levels
* you now appear at (*32*,30) because enemies can come from left
* improved bullet handling (faster, smaller, etc.)
+ multiples are animated like real Nemesis (pulsating)
# fixed a bug that didn't select multiples when you were moving
# enemy collision screwed up invert and some other weird stuff
+ in pause screen change contrast with up/down and B/W mode with F1
+ lasers can have different durations (beams last longer)
* some sign-flag checkings replaced by carry-flag (thus reducing size)
# slow enemies (including pickups) didn't always appear (just 25-50%)
+ enemies can fire different kinds of bullets: aiming, double, triple
* maximum number of bullets increased (48 for enemies, 128 for you)

nemesis.txt
nemesis.z80

index 81dbc27e21357d95f6d2da5ac60b0d231b5f7d0f..2e0ac9a0d925ed7d039710e9e1ff1be63c193baa 100644 (file)
@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
  Title                         : Nemesis
- Version                       : 0.99.810 Beta
- Release Date                  : 10.VIII.00
+ Version                       : 0.99.816 Beta
+ Release Date                  : 16.VIII.00
  Filename                      : nemesis.86p (size 7kB)
  Author(s)                     : Shiar
  Email Address                 : shiar0@hotmail.com
@@ -34,11 +34,11 @@ for systems including the Game Boy, (S)NES and Play Station.
    GRAPH : teacher/boss! (press graph again to resume)
     EXIT : whooo, what does _this_ button do?
 
-  Collect the pickups enemies leave after they're destroyed to upgrade your
-ship. The highlighted icon in the score bar (bottom) can be activated by
-pressing ALPHA.
+  After destroying several enemies, pickups will appear. Collect them to
+upgrade your vessel. The highlighted icon in the score bar (bottom) can be
+activated by pressing ALPHA.
 
-  Upgrades: ARMOR | TAIL-BEAM | WEAPON-UPG | LASER | MULTIPLES
+  Upgrades: ARMOR | TAIL-BEAM | BEAM/UPG | LASER/UPG | MULTIPLES
 
   The upper bar on the left shows your hitpoints left (armor). The bar below
 that shows the current power of your weapon.
@@ -46,10 +46,8 @@ that shows the current power of your weapon.
 
 >>>>>>> BETA STUFF -----------------------------------------------------------
 
-  There are just five levels for now, don't play beyond there. In future
-versions I'll add more levels and enemies, maybe obstacles, and I'll release
-the source code. I don't think I will add greyscale, sound or a multiplayer
-option.
+  Rightnow I'm finishing the other six (of 12) levels. I don't think I will
+add greyscale, sound or a multiplayer option.
 
   Continue to send me any IDEAS and BUGS found!! Or send me you like this
 program, or even send me something if you don't. Again: shiar@mailroom.com,
@@ -62,20 +60,19 @@ memory LOCKED! Besides that there shouldn't be any bugs.
 
 >>>>>>> CREDITS --------------------------------------------------------------
 
-  Programming/levels/gfx - - - SHIAR
-  Official betatesters - - - - DAVE -- BLACKBELT -- MATTHEW DALE
-  Support (advise/ideas/etc) - JONAH -- SCABBY -- BRIAN KOROPOFF -- CULLEN S
+  Programming/levels/gfx     - SHIAR
+  Official betatesters       - DAVE -- BLACKBELT -- MATTHEW DALE
+  Support (advise/ideas/etc) - JONAH -- SCABBY -- BRIAN KOROPOFF
   Original engine (Galaxian) - PATRICK DAVIDSON
-  Original Nemesises - - - - - KONAMI
+  Original Nemesises         - KONAMI
 
 Also alot of thanks to EVERYBODY WHO SENT ME SOMETHING and everybody I forgot.
 
 
 >>>>>>> RULEZ AND REGULATIONS ------------------------------------------------
 
-* Damage to you, your calc, or anything else was not caused by Nemesis
-   and I am certainly not responsible
-* Thou shalt NOT release an altered version of Nemesis
+* Thou shalt not hold me responsible for damage to your calc or anything else
+* Thou shalt NEVER release an altered version of Nemesis
 * Thou shalt include this documentation with distribution (except calc2calc)
 * Thou shalt not ask money for this program
 * Thou shalt eat plenty of vegetables every day
index fed759c2e945804af4059f2768ce274ad39425e6..413ab08496af0e15b1f4431774706018e4166247 100644 (file)
@@ -1,16 +1,17 @@
 ;----------------------------------------------------------------------------
 ;---------------------- NEMESIS ---------------------------------------------
-;----------------------------------------------------------------------------
+;----------------------------------------------- cool arcade-shoot-em-up-game
 
 ;by SHIAR | shiar0@hotmail.com | icq#43840958 | www.shiar.org
 
-;Description           : cool arcade-shoot-em-up-game
-;Other games by author : Worm
 ;This source should only be used for learning practises, do not
 ;alter it, and certainly never distribute an altered version!!
 
 ;&&& marks uncertainties or things to optimize
 
+;TO DO:
+; up-double | torpedoes | levels 7-12 | jp m | better weapons
+
 ;---------------------- nemesis.z80 start -----------------------------------
 
 #include       "asm86.h"
@@ -68,13 +69,13 @@ mm          = 4                             ;max. number of multiples
 ;^-----------------------------------<1        ;-120=$78
 
 enemies                = storepos2             ;  +0   ;info about each enemy
-enemysize      =                             ;infobytes per enemy
+enemysize      = 10                            ;infobytes per enemy
 nrenemies      = 16                            ;max. nr of enemies
 
 ybullets       = enemies+(nrenemies*enemysize) ;60 bytes = 20(state,damg,x,y)
-nrybuls                = 64                    ; +80\
+nrybuls                = 128                   ; +80\
 ebullets       = ybullets+(nrybuls*4)  ;+110   ;30 bytes = 10(state,x,y)
-nrebuls                = 16
+nrebuls                = 48
 lvlenemies     = ebullets+(nrebuls*3)
 
 ;^-----------------------------------<2        ;-141=$8D
@@ -82,7 +83,8 @@ lvlenemies    = ebullets+(nrebuls*3)
 ;      [0000:damage 0:diagfire 0:ground 0:ceiling 0:-]
 ;enemies:
 ;      [HP64] [000000:HP left 00:(00=no enemy 01=exploding 10=normal 11=moving)]
-;      [ship type or explosion frame] [x] [y] [movetype] [movecounter] [firecounter] [firefreq]
+;      [ship type or explosion frame] [x] [y] [movetype] [movecounter]
+;      [firecounter] [firefreq] [firetype]
 
 ;---------------------- introduction ----------------------------------------
 
@@ -92,7 +94,7 @@ lvlenemies    = ebullets+(nrebuls*3)
        .dw Title               ;pointer to description (all shells)
        .dw Icon                ;pointer to YAS icon
 
-Title: .db "Nemesis v0.99.810 by SHIAR",0
+Title: .db "Nemesis v0.99.812 by SHIAR",0
 
 Icon:  .db 8,1                 ;icon for YAS: width = 1byte; height = 9bytes
        .db %11100000           ; ███
@@ -103,7 +105,7 @@ Icon:       .db 8,1                 ;icon for YAS: width = 1byte; height = 9bytes
        .db %01111000           ;  ████
        .db %11100000           ; ███             ;recommend 80x50 screen mode
        .db 0                   ;YAS 0.92 compatibility
-;43
+
 ;---------------------- init ------------------------------------------------
 
 int_handler:                   ;new interrupt proc
@@ -127,17 +129,17 @@ FixKeys:                  ;fixes some key problems like left+down bug
        ld  a,$D4
        ld  bc,$0100
        ld  h,a
-       ld  l,c                 ;ld hl,$D400
+       ld  l,c                 ;ld hl,$D400 (user silent link routine space)
        ld  d,a
        ld  e,b                 ;ld de,$D401
        dec a                   ;ld a,$D3
        ld  (hl),a
-       ldir
+       ldir                    ;fill $D400-D500 with $D3s (slink/user on)
        ld  hl,int_handler      ;new interrupt handler
        ld  d,a
        ld  e,a                 ;ld de,$D3D3
        ld  bc,int_end-int_handler
-       ldir
+       ldir                    ;load new handler at ($D3D3)
        inc a                   ;ld a,$D4
        ld  i,a
        im  2
@@ -210,8 +212,6 @@ menuitem =$-1
        jr  z,start_tha_freakin_game
        cp  K_EXIT
        jr  z,menuexit
-       cp  K_F1
-       cal z,do_invert
        cp  K_UP
        jr  z,menuchange
        cp  K_DOWN
@@ -234,14 +234,14 @@ menuexit:
        ld  (your_score),hl     ;(prevents hiscore while never played)
        jp  game_over           ;and go to game over screen
 
-do_invert:                     ;invert screen (b<>w); destr:b
+do_invert:                     ;invert screen (b<>w)
        psh hl
-       ld  b,a                 ;psh a
+       psh af                  ;can't destroy b
        ld  hl,_invert
        ld  a,$98
        xor (hl)                ;$2F (cpl) <-> $B7 (or a)
        ld  (hl),a
-       ld  a,b                 ;pop a
+       pop af
        pop hl
        ret
 
@@ -313,7 +313,9 @@ check_exitkey:
        jp  z,game_over         ;<exit> pressed, so be it
 check_morekey:                 ;another unused label... poor compiler
        bit 7,a                 ;test bit 7 = more-key = PAUSE
+       psh af
        cal z,Pause             ;yes, go to pause
+       pop af
 
 check_firekey:
        bit 5,a                 ;test bit 5 = 2nd-key = FIRE
@@ -323,6 +325,7 @@ check_firekey:
        pop hl                  ;no cal to Fire_bullet made, so pop stack
        ld  hl,just_fired       ;no:
        ld  (hl),5              ;able to fire (five turns = laser duration)
+laserdur =$-1                  ;SMC laser duration
 
 check_selkey:
        ld  a,%01011111         ;look at first column of keys (ALPHA to STO)
@@ -499,7 +502,7 @@ CheckGround:                        ;check for collision with the ground
        neg
        cp  (hl)
        ret nc
-       ld  b,5
+       ld  b,auch_ground
        jp  damage_you
 
 ;--------------------------- ceiling ----------------------------------------
@@ -588,7 +591,7 @@ CheckCeiling:                       ;check for collision with the ground
        inc a
        cp  (hl)                ;compare with ceiling
        ret nc                  ;carry if ceiling is above you
-       ld  b,5
+       ld  b,auch_ground
        jp  damage_you          ;otherwise you don't wanna be in that ship
 
 ;--------------------------- move stars -------------------------------------
@@ -643,17 +646,35 @@ newstarok:
 ;--------------------------- pause ------------------------------------------
 
 Pause:
-       psh af
-       ld  hl,$0200            ;top left
+       ld  hl,_txt_pause
+       ld  (_penCol),hl
+       ld  hl,txt_pause
+       cal _vputs              ;display small font
+       ld  hl,_txt_pressenter  ;top centered
        ld  (_curRow),hl
        ld  hl,txt_pressenter   ;"Enter to continue"
        cal _puts               ;display message
 pause:
-       cal _getkey             ;enter low-power mode and wait for key
-       cp  kEnter              ;keypressed = enter?
-       jr  nz,pause            ;no, wait some more
-       pop af
-       ret                     ;continue
+       cal getsomekeys         ;GET_KEY w/ halts and checks for enter
+       ret z                   ;enter/second pressed: continue game
+       cp  K_F1                ;F1 pressed?
+       cal z,do_invert         ;if so then change invert screen (AF saved)
+       ld  hl,CONTRAST         ;contrast setting (0-31)
+       ld  b,(hl)              ;load contrast into b
+       cp  K_UP                ;+ key changes contrast up
+       jr  nz,contr_not_up
+       inc b                   ;increase contrast
+       jr  setcontrast         ;set
+contr_not_up:
+       cp  K_DOWN              ;- key
+       jr  nz,pause            ;nope: loop
+       dec b                   ;decrease contrast
+setcontrast:
+       ld  a,b
+       ld  (hl),a
+       out (2),a               ;and set it
+       cal releasekeys
+       jr  pause               ;and loop
 
 ;--------------------------- teacher ----------------------------------------
 
@@ -844,7 +865,7 @@ disp_ship:
 handle_multiples:
        ld  a,(your_multiples)  ;do you have multiples
        ld  b,a                 ;save a for 2nd check
-       and %111                ;no? (last two bits = nr of multiples)
+       and %1111               ;no? (last four bits = nr of multiples)
        ret z                   ;then don't handle them either
        bit 7,b                 ;move the multiples??? (=move bit set?)
        jr  z,mult_adv          ;nope, just let them (saves (y)in y, (x)in x)
@@ -861,22 +882,29 @@ handle_multiples:
        ld  (hl),e              ;y-pos
 
 mult_adv:
-       ld  hl,your_prevpos+16  ;first pos.
+       ld  ix,spr_multiple     ;normal sprite
+       ld  hl,timer
+       bit 3,(hl)              ;change sprites every 8 turns
+       jr  z,disp_multiples
+       ld  ix,spr_multiple2    ;second sprite
 disp_multiples:
+       ld  hl,your_prevpos+16  ;first pos.
+dispmultiplesloop:
        psh af
        psh hl
        ld  d,(hl)              ;load coords
        inc hl
        ld  e,(hl)
-       ld  ix,spr_multiple     ;sprite
+       psh ix
        cal putsprite           ;display
+       pop ix                  ;same sprite next time ;)
        pop hl
        ld  de,14
        add hl,de               ;next multiple
        pop af                  ;counter
        dec a
        ret z                   ;return if all done
-       jr  disp_multiples      ;loop
+       jr  dispmultiplesloop   ;loop
 
 ;----explode----
 
@@ -910,21 +938,19 @@ damage_you:                       ;damages you B points
 dothadamage:
        ld  hl,time2invert
        xor a                   ;a=0
-       cp  (hl)                ;no already inverted?
+       cp  (hl)                ;not already inverted?
        cal z,do_invert         ;then invert screen
-       ld  a,2
-       ld  (hl),a              ;change back 2 frames from now
+       ld  (hl),2              ;change back 2 frames from now
 
        ld  hl,your_armor       ;armor left
        ld  a,(hl)              ;load hp in A
        sub b                   ;decrease hp by B
-       jp  m,no_armor          ;<0hp left so explode
-       ld  (hl),a              ;no, so save decreased hp
-       jp  disp_armor          ;and display new value
-no_armor:
+       jr  nc,newarmor         ;>=0hp left so don't explode
        ld  a,%01               ;occ %xxxxxx01 = explode
        ld  (your_occ),a        ;too bad, you're dead meat
-       ret
+newarmor:
+       ld  (hl),a              ;save decreased hp
+       jp  disp_armor          ;and display new value
 
 ;------------------------- place multiples ----------------------------------
 
@@ -960,14 +986,14 @@ select:
 select1:
        ld  (hl),a              ;reset pickups
        cal inc_armor
-       jp  disp_icons          ;display and return
+       jr  disp_icons          ;display and return
 select2:
        dec a                   ;is it 2?
        jr  nz,select3          ;no, carry on
        ld  (hl),a              ;reset pickups
        inc a                   ;a=1
        ld  (your_tail),a       ;ready tail beam
-       jp  disp_icons          ;display 'n return
+       jr  disp_icons          ;display 'n return
 select3:
        dec a                   ;is it 3?
        jr  nz,select4          ;no, carry on
@@ -976,10 +1002,10 @@ select3:
        ld  a,(hl)
        inc a
        cp  maxweapon
-       jp  nc,disp_icons       ;weapon maxed out
+       jr  nc,disp_icons       ;weapon maxed out
        ld  (hl),a              ;set new weapon
         cal loadweapon         ;load it (damage and stuff)
-       jp  disp_icons          ;display n return
+       jr  disp_icons          ;display n return
 select4:
        dec a                   ;is it 4?
        jr  nz,select5          ;no, carry on again
@@ -992,16 +1018,17 @@ select4:
 upgradelaser:
        inc a                   ;next laser
        cp  maxlaser
-       jp  nc,disp_icons       ;laser maxed out
+       jr  nc,disp_icons       ;laser maxed out
        ld  (hl),a
        cal loadweapon
-       jp  disp_icons          ;display + return
+       jr  disp_icons          ;display + return
 select5:
        dec a                   ;is it 5?
        jr  nz,select6          ;no, carry on once more
        ld  (hl),a              ;reset pickups
        ld  hl,your_multiples
        ld  a,(hl)              ;multiples you already got
+       and %1111               ;reset movebit so (your_multiples)=real value
        inc a                   ;one more
        cp  mm+1
        jr  nc,enoughmultiples  ;maxed out
@@ -1010,16 +1037,177 @@ enoughmultiples:
        ld  de,(x)
        dec a                   ;if this is your first multiple then...
        cal z,Place_multiples   ;reset multiples positions
-       jp  disp_icons          ;display, return
+       jr  disp_icons          ;display, return
 select6:
        ld  (hl),0              ;reset pickups
-       jp  disp_icons          ;display/return
+;      jr  disp_icons
+
+;--------------------------- show icon --------------------------------------
+
+disp_icons:
+ psh bc \ psh de \ psh hl \ psh ix ;&&&
+
+       ld  hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
+       ld  (PutWhere),hl       ;place icons at bottom of normal screen
+       ld  b,16                ;draw 16x (screen width)
+       ld  a,%11111111         ;horizontal line mask
+       cal drawline            ;draw divider-line
+
+       ld  b,16*7              ;draw 16x (screen width) 7x (height)
+       xor a                   ;blank line mask
+       cal drawline            ;clear scorebar
+
+disp_lives:
+       ld  de,5                ;(0,5)
+       ld  a,(your_lives)      ;nr of lives
+       or  a
+       jr  z,displivesdone     ;no lives
+       ld  b,a
+displivesloop:
+       psh bc
+       ld  ix,spr_lship
+       cal safeputsprite       ;put li'l ship
+       ld  a,lshipsize+1
+       add a,d
+       ld  d,a                 ;x=x+5
+       pop bc
+       dnz displivesloop       ;one ship per life
+displivesdone:
+       cal disp_armor          ;display bar
+
+       ld  ix,spr_icon01       ;torpedoIcon
+       ld  de,$1901            ;icon #1
+       cal putwidesprite       ;display icon
+
+       ld  ix,spr_icon00
+       ld  a,(your_weapon)     ;ur weapon
+       cp  maxweapon           ;laser?
+       psh af                  ;(your_weapon)
+       jr  nc,no_tail          ;if laser (nc) then tail ain't fired
+       ld  a,(your_tail)
+       or  a
+       jr  z,no_tail
+       ld  ix,spr_icon02       ;tailbeamIcon
+no_tail:
+       ld  de,$2901            ;icon #2
+       cal putwidesprite       ;display
+
+       ld  ix,spr_icon00
+       pop af                  ;a=(your_weapon); cf=bullets
+       psh af
+       jr  nc,no_bullets       ;=laser
+       ld  hl,$3945            ;position to display bullet-type digit
+       pop af                  ;digit=(your_weapon)
+       psh af
+       inc a                   ;1 = weapon #1 (=0)
+       ld  (_penCol),hl        ;set location
+       add a,'0'               ;make digit
+       cal _vputmap            ;display char
+       ld  ix,spr_icon03       ;bulletIcon
+no_bullets:
+       ld  de,$3901            ;icon #3
+       cal putwidesprite       ;display icon
+
+       ld  ix,spr_icon00       ;emptyIcon
+       pop af                  ;ld a,(your_weapon)
+       ld  b,a
+       jr  c,no_laser          ;popped carry
+       ld  hl,$3955            ;position to display bullet-type digit
+       ld  (_penCol),hl        ;set location
+       ld  a,b                 ;(your_weapon)  ;load = faster than push
+       sub maxweapon-1         ;1 = laser #1 (=maxweapon)
+       add a,'0'               ;make digit
+       cal _vputmap            ;display char
+       ld  ix,spr_icon04       ;laserIcon
+no_laser:
+       ld  de,$4901            ;icon #4
+       cal putwidesprite
+
+       ld  ix,spr_icon00       ;emptyIcon
+       ld  a,(your_multiples)
+       and %111
+       jr  z,no_multiples
+       ld  ix,spr_icon05
+no_multiples:
+       ld  de,$5901            ;icon #5
+       cal putwidesprite
+
+       ld  ix,spr_dividerline
+       ld  de,$6901
+       cal putwidesprite
+
+       ld  a,(your_pickup)     ;pickups taken
+       add a,a                 ;picks*2 (sets z-flag)
+       jr  z,iconsdone         ;return if no pickups
+       add a,a                 ;picks*4
+       add a,a                 ;picks*8
+       add a,a                 ;picks*$10
+       add a,$09               ;add 0ah
+       ld  d,a                 ;y-pos = picks * $10 + $0a (19,29,39,49,59)
+       ld  e,$01               ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
+
+       ld  ix,spr_icon
+       cal putwidesprite
+iconsdone:
+       ld  hl,dispbuffer       ;normal game-screen
+       ld  (PutWhere),hl       ;set sprite-position to normal screen
+
+ pop ix \ pop hl \ pop de \ pop bc
+       ret
+
+disp_armor:
+       ld  de,16               ;line size
+       ld  hl,(57*16)+VIDEO_MEM+3
+       ld  b,3
+armorbarclr:
+       dec hl
+       ld  (hl),0
+       add hl,de
+       ld  (hl),0
+       sbc hl,de
+       dnz armorbarclr
+
+       ld  a,(your_armor)      ;load your armor (<25)
+       ld  c,a                 ;psh a
+       srl a                   ;/2
+       srl a                   ;/4
+       srl a                   ;/8: don't display last 3 bits of a (later)
+       jr  z,noarmorbar        ;if a=0 then it would loop 256x so skip it
+       ld  b,a                 ;loop b=a times
+armorbar:                      ;starting at ($39*16)+VIDEO_MEM
+       ld  (hl),%11111111      ;draw a piece of the bar
+       add hl,de               ;one down (resets carry)
+       ld  (hl),%11111111      ;same piece
+       sbc hl,de               ;up again
+       inc hl                  ;next position
+       dnz armorbar            ;loop it b times
+
+noarmorbar:
+       ld  a,c                 ;pop a
+       and %111                ;display last bits of armor
+       ret z                   ;if armor=0 then bit = %00000000 (don't disp)
+       ld  b,a                 ;into B
+       xor a                   ;bit = %00000000
+armorbarbit:
+       scf                     ;set carry flag
+       rra                     ;rotates A right and sets bit 7 (c-flag)
+       dnz armorbarbit         ;repeat B times (so if B=6 then a=%11111100)
+armorbarready:                 ;               (an if B=3 then a=%11100000)
+       ld  (hl),a              ;draw this last byte
+       add hl,de
+       ld  (hl),a              ;and just below
+       ret
+
+drawline:
+       ld  (hl),a              ;draw one piece of the divider-line
+       inc hl                  ;move right (8 pixels = 1 byte)
+       dnz drawline            ;repeat (16bytes * 8pixels =128= screen width)
+       ret
 
 ;------------------------- fire bullet --------------------------------------
 
 fire_multiple:
        psh af
-       dec h                   ;one up (-2 height: keeps weapons centered)
        psh ix                  ;save ix for next fire
        cal fireany             ;fire from multiple position
        pop ix                  ;saving ix is much faster than recalculating
@@ -1062,7 +1250,7 @@ fireOK:
        add ix,bc               ;ix=weapon ptr
 
        ld  a,(your_multiples)  ;any multiples?
-       and %111                ;nr. of multiples
+       and %1111               ;nr. of multiples
        cal nz,fire_multiples   ;if >0 then fire them too
        ld  hl,(x)              ;fire from ship position (x)
 fireany:                       ;HL=(x,y)
@@ -1071,11 +1259,14 @@ fireany:                        ;HL=(x,y)
 fire_weapon:
        psh bc                  ;save counter
        ld  a,(ix)              ;load this weapon
-       cp  %11100000           ;%11110000=laser
-       cal z,fire_laser        ;fire laser (will set a=0 when done)
-       or  a                   ;<>0=bullet
-       cal nz,fire_ybullet
-       inc ix
+       ld  c,a                 ;save bulletType in c
+       and %11100000           ;%111?????=laser
+       cp  %11100000           ;is it?
+       cal z,fire_laser        ;fire laser (will set c=0 when done)
+       xor a                   ;<>0=bullet
+       cp  c                   ;c<>0?
+       cal nz,fire_ybullet     ;then fire bullet
+       inc ix                  ;otherwise fire next weapon
        inc ix
        pop bc                  ;weapon counter (do 3 weapons)
        dnz fire_weapon
@@ -1093,7 +1284,6 @@ fire_tail:
 ;-----fire BULLETs-----
 
 fire_ybullet:          ;fire bullet type=C dam=(curweapdamage) at (firex/y)
-       ld  c,a                 ;save bulletType in c
        ld  hl,ybullets         ;check for unused bullet
        ld  de,4
        ld  b,nrybuls
@@ -1182,7 +1372,7 @@ laserhits:                        ;hits with normal enemies
        inc hl
        ld  a,(hl)              ;check x
        sub d
-       jp  m,nolashit          ;no hit when enemy is left of you
+       jr  c,nolashit          ;no hit when enemy is left of you
        inc hl
        ld  a,(hl)              ;check y
        sub e
@@ -1201,9 +1391,10 @@ nolashit:
        add hl,bc               ;go to next enemy
        ld  b,a                 ;pop bc
        dnz laserhits           ;check all enemies
-       xor a                   ;a=0 otherwise weird things might happen :P
+       xor a
        ld  (weapincs),a        ;reset damage
        pop ix
+       ld  c,a                 ;c=0
        ret
 
 ;------------------------ handle bullets ------------------------------------
@@ -1391,15 +1582,18 @@ enemy_hit:                      ;*in:a=damage;hl=enemy+y
 
        inc hl                  ;goto occ again
        ld  (hl),%01            ;set to explode
+
        ld  a,(pickuptimer)     ;counts enemies destroyed
        dec a                   ;enough destroyed for a pickup?
+       psh af                  ;save flags and a=0
        jr  nz,pickupdone       ;otherwise just explode
-       ld  (hl),%110           ;change it into a pickup (with 2 HP)
        ld  a,18                ;reset enemies counter (18 hits = next)
 pickupdone:
        ld  (pickuptimer),a     ;save new enemiescounter value
-       inc hl
-       ld  (hl),$00            ;explosionFrame 0
+       inc hl                  ;@type
+       ld  (hl),0              ;explosionFrame 0 or enemy #0=pickup
+       pop af
+       cal z,place_enemy       ;place pickup (enemy#=0=a cuz ZF)
 
        ld  hl,1                ;increase score by one
        jp  scoreInc            ;+ret
@@ -1428,7 +1622,7 @@ eventtime =$-2
        dec a                   ;has it reached 2?
        jr  z,place_boss        ;yep: place the BigBossTM!
        dec a                   ;has it reached 3?
-       jr  nz,do_event         ;nope: >3 = place an enemy
+       jr  nz,place_ranenemy   ;nope: >3 = place an enemy
        inc hl                  ;nextevent located behind eventleft
        ld  (hl),123            ;set delay
        ret                     ;don't place any more enemies
@@ -1437,10 +1631,10 @@ standby_event:
        ld  b,nrenemies
        ld  hl,enemies+1-enemysize
        ld  de,enemysize
+       xor a
 chk_enemyleft:
        add hl,de
-       ld  a,(hl)
-       or  a                   ;0 = no enemy present
+       cp  (hl)                ;0 = no enemy present
        jr  nz,enemyleft
        dnz chk_enemyleft
        ret
@@ -1450,33 +1644,33 @@ enemyleft:
        ret
 
 
+place_ranenemy:
+       ld  bc,0                ;0..nrlvlenemies
+nrlvlenemies =$-1              ;=nr of enemies minus 1
+       cal Random              ;random enemy b..b+c = 0..nrenemies-1
+       ld  b,0
+       ld  c,a                 ;bc=a
+       ld  hl,lvlenemies
+       add hl,bc               ;go to a random enemy
+       ld  a,(hl)              ;load enemy nr of this mysterious random enemy
+       jr  place_enemy
+
 place_boss:
-       ld  a,1
-       ld  (nrlvlenemies),a    ;just one enemy: the BOSS
        ld  hl,(levelp)         ;the leveldata (including the boss)
        dec hl                  ;points to leveldata\boss\enemynr
-       ld  a,(hl)              ;load it
-       ld  (lvlenemies),a      ;set new enemy (boss)
+       ld  a,(hl)              ;load enemy# of boss
 
-do_event:
+place_enemy:                   ;places enemy #=a
+       psh af
        ld  hl,enemies+1-enemysize
        ld  bc,enemysize
        xor a                   ;a=0
-chk_noenemy:
-       add hl,bc
+chk_noenemy:                   ;find an unused (no) enemy
+       add hl,bc               ;check next enemy
        cp  (hl)                ;(hl) = 0 ??
        jr  nz,chk_noenemy      ;jump if enemy present (non-0)
-       ex  de,hl               ;de=hl=usable enemy
-
-place_enemy:                   ;de = enemy+1
-       ld  bc,0                ;0..nrlvlenemies
-nrlvlenemies =$-1              ;=nr of enemies minus 1
-       cal Random              ;random enemy b..b+c = 0..nrenemies-1
-       ld  b,0
-       ld  c,a                 ;bc=a
-       ld  hl,lvlenemies
-       add hl,bc               ;go to a random enemy
-       ld  a,(hl)              ;load enemy nr of this mysterious random enemy
+       ex  de,hl               ;de=hl=usable enemy +1
+       pop af                  ;enemy# to place
        cal findenemyspecs      ;hl = enemy #a specs
 
        dec de                  ;goto hp64 (before occ)
@@ -1520,17 +1714,18 @@ ypos_OK:                        ;random value successfully created
        inc de                  ;@firecounter
        ldi                     ;set time-to-1st-fire
        ldi                     ;set firefreq
+       ldi                     ; "  firetype
        ret                     ;return
 
 ;--------------------------- enemy fires ------------------------------------
 
-Enemy_fires:                   ;de = x,y
+Enemy_fires:                   ;de = x,y; c = type
+       ld  hl,ebullets         ;first bullet to check
+       ld  b,nrebuls
        dec d
        dec d                   ;d = x-2
        inc e                   ;e = y+1
-
-       ld  b,nrebuls
-       ld  hl,ebullets
+enemy_fires_again:             ;same but hl = first bullet possibly free
        xor a
 find_ebullet:
        cp  (hl)
@@ -1540,30 +1735,52 @@ find_ebullet:
        ret
 
 found_ebullet:
-       ld  b,1                 ;default normal bullet
-       ld  a,(level_info)
-       and %00001000
-       jr  z,bulletok
+       ld  a,c
+       sub 6
+       jr  c,bulletok          ;type #0-5 = done (normal/diag)
+       or  a
+       jr  z,bulletaiming      ;type #6 = aiming = type#2..5
+       dec a
+       jr  z,bullettriple      ;type #7 = triple
 
+bulletdouble:
+       dec e                   ;one up
+       ld  c,1                 ;type #1
+       cal enemy_fires_again   ;fire bullet
+       inc hl                  ;next bullet position
+       inc e
+       inc e                   ;one down
+       jr  bulletok            ;fire another bullet
+
+bullettriple:
+       ld  c,1                 ;type #1 = normal
+       cal enemy_fires_again   ;fire
+       inc hl                  ;next bullet
+       ld  c,4                 ;type #4 = down 50%
+       cal enemy_fires_again
+       inc hl
+       ld  c,5                 ;type #5 = up 50%
+       jr  bulletok
+
+bulletaiming:
        ld  a,(y)
        sub e
        add a,10
        jp  p,bulletnotup
-       ld  b,5                 ;yourY-bulY = negative (=bullet below you)
+       ld  c,5                 ;yourY-bulY = negative (=bullet below you)
        add a,10
        jp  p,bulletnotup
-       ld  b,3                 ;yourY-bulY = even more negative (going up)
-
+       ld  c,3                 ;yourY-bulY = even more negative (going up)
 bulletnotup:
        sub 20
-       jp  m,bulletok
-       ld  b,4                 ;bullet going down
+       jr  c,bulletok
+       ld  c,4                 ;bullet going down (=jp m)
        sub 10
-       jp  m,bulletok          ;even more going down
-       ld  b,2
+       jr  c,bulletok          ;even more going down
+       ld  c,2
 
 bulletok:
-       ld  (hl),b              ;set bullet direction
+       ld  (hl),c              ;set bullet direction
        inc hl
        ld  (hl),d              ;set x-pos
        inc hl
@@ -1573,98 +1790,92 @@ bulletok:
 ;----------------------------- enemy bullets --------------------------------
 
 Enemy_bullets:
-       ld  hl,ebullets
-       ld  b,nrebuls
+       ld  hl,ebullets         ;hl=bullet pointer
+       ld  b,nrebuls           ;number of bullets (or _possible_ bullets)
 handle_bullet:
        psh bc
        psh hl
        ld  a,(hl)              ;load bulletType in a
        or  a                   ;bullet present?
-       jr  nz,enemy_bullet     ;non-0: handle bullet
-next_bullet:
-       pop hl                  ;do not move the <pop hl>
-       pop bc
-       inc hl \ inc hl \ inc hl
-       dnz handle_bullet
+       cal nz,enemy_bullet     ;non-0: handle bullet
+       pop hl                  ;enemy_bullet could've added one or two to hl
+       pop bc                  ;bullet counter
+       inc hl \ inc hl \ inc hl ;next bullet (3 bytes per bullet)
+       dnz handle_bullet       ;loop for each and every bullet
        ret
 
 enemy_bullet:
-       ld  b,a                 ;save type&%1111
-       inc hl                  ;bullet x
-       ld  a,(hl)              ;check if it has reached the left side of scrn
-       bit 7,a                 ;x<0?
+       inc hl                  ;@x
+       ld  d,(hl)              ;check if it has reached the left side of scrn
+       bit 7,d                 ;x<0?
        jr  nz,remove_ebullet   ;yes, remove bullet
-       dec (hl)                ;move one left
-       dec (hl)                ;and another one
-       ld  d,(hl)              ;d=x
-       inc hl                  ;@y
+       dec d                   ;move one pixel left
+       dec d                   ;and another one (that makes 2)
+       ld  (hl),d              ;save new x-coordinate in (HL) and D
+       inc hl                  ;@y   (BTW: x >= -2)
+       ld  e,(hl)              ;e=y
 
-       dec b
+       dec a
        jr  z,ebullet_common    ;type 1: normal bullet
-       dec b
+       dec a
        jr  z,ebullet_down      ;type 2: moving down
-       dec b
+       dec a
        jr  z,ebullet_up        ;type 3: moving up
 
-       ld  a,(timer)
-       rra                     ;half speed
+       ld  b,a                 ;save bulletType
+       ld  a,(timer)           ;load timer
+       rra                     ;half speed (CF set every other turn)
        jr  c,ebullet_common    ;if bit then normal bullet
 
        dec b
        jr  z,ebullet_down      ;type 4: moving down 50%
                                ;type 5: moving up 50%
 ebullet_up:
-       ld  a,(hl)
-       dec a
-       jp  m,ebullet_common    ;y<0
-       ld  (hl),a
+       dec e                   ;move up
+       jp  m,ebullet_common    ;y<top; don't save new value (so y=0)
+       ld  (hl),e
        jr  ebullet_common
-
 ebullet_down:
-       ld  a,(hl)
-       inc a
-       cp  58-3
-       jr  z,ebullet_common
-       ld  (hl),a
+       inc e                   ;move down
+       ld  a,e                 ;a=y too
+       cp  58-3                ;y>bottom?
+       jr  z,ebullet_common    ;then keep it there
+       ld  (hl),e              ;otherwise save new y
 
 ebullet_common:
-       ld  e,(hl)              ;e=y
        ld  ix,spr_bullete1     ;display enemy bullet
+       psh hl
        cal putsprite
+       pop hl                  ;we'll need it again
 
 ebullet_hits:
        ld  a,(your_occ)
        or  a
-       jr  nz,next_bullet      ;0 = you're normal
+       ret nz                  ;0 = you're normal
 
-       pop hl
-       psh hl
-       inc hl                  ;check x
-       ld  a,(x)
+       ld  a,(y)               ;check y collision
        sub (hl)
        add a,6
-       jp  m,next_bullet
+       ret m
        cp  9
-       jr  nc,next_bullet
+       ret nc
 
-       inc hl                  ;check y
-       ld  a,(y)
+       dec hl                  ;check x
+       ld  a,(x)
        sub (hl)
        add a,6
-       jp  m,next_bullet
+       ret m
        cp  9
-       jr  nc,next_bullet
+       ret nc
 
-       pop hl                  ;points to bullettype again
-       psh hl                  ;and save it again (ivm call to damage_you)
-       ld  a,(hl)              ;load bullettype
-       cal _shracc             ;isolate damage-bits (%1111???? -> %00001111)
-       ld  b,a                 ;set damage-amount
+       ld  b,auch_bullet       ;set damage-amount
+       psh hl
        cal damage_you          ;HIT!!
+       pop hl                  ;save hl to remove the bullet
 remove_ebullet:
-       pop hl                  ;hl destroyed by damage_you
+       dec hl                  ;points to bullettype again
        ld  (hl),0              ;bullet > unused
-       jr  next_bullet+1       ;next bullet (SKIP THE <POP HL> = one byte)
+       ret
 
 ;--------------------------- handle enemies ---------------------------------
 
@@ -1708,7 +1919,7 @@ enemyonscreenY:
        dec hl                  ;@x
 
        ld  a,d                 ;new x value
-       cp  128                 ;x<128
+       cp  129                 ;x<=128
        jr  c,enemyonscreenX    ;=on screen
        cp  -7                  ;x<=-8
        jr  c,remove_enemy      ;=off screen
@@ -1717,11 +1928,6 @@ enemyonscreenX:
        ld  a,c                 ;a = enemy type
        or  a                   ;type 0? (pickup)
        jr  nz,check_enemyfire  ;no, a normal enemy; let em fire
-       ld  a,(timer)           ;load time
-       and %1                  ;move left once every 2 turns
-       jr  z,firing_done       ;don't move now
-       inc d                   ;increase x-position (don't move this turn)
-       inc (hl)                ;and save it
        jr  firing_done         ;continue
 
 check_enemyfire:
@@ -1734,7 +1940,10 @@ check_enemyfire:
 
        inc hl                  ;@firefreq
        ld  a,(hl)
+       inc hl                  ;@firetype
+       ld  c,(hl)              ;in c
        dec hl
+       dec hl                  ;@firecount again
        ld  (hl),a              ;reset counter for next blast
        psh de                  ;save registers for firing-use
        cal Enemy_fires         ;fires bullet
@@ -1856,6 +2065,7 @@ movetype_slow:
        ret c
        inc d                   ;don't move
        ret
+
 movetype_vslow:
        and %11
        ret z
@@ -1901,16 +2111,17 @@ Enemies_hit:
        ld  hl,enemies+1
        ld  b,nrenemies         ;check all 20 enemies
 check_collision:
-       psh hl
+       psh bc                  ;counter
+       psh hl                  ;pointer
        ld  a,(hl)
-       and %00000010
-       jr  z,check_next        ;2 or 3 = ok
-       inc hl
+       and %00000010           ;enemy status
+       jr  z,check_next        ;2 or 3 = ok, otherwise: next enemy
+       inc hl                  ;enemy#
 
 collide_enemy:                 ;&&& include in Handle_enemy proc
        cal find_sprite
 
-       inc hl
+       inc hl                  ;@x
        ld  a,(hl)              ;check x match
        sub e                   ;enemy position minus yours minus 7
        jp  p,check_next
@@ -1921,7 +2132,7 @@ collide_enemy:                    ;&&& include in Handle_enemy proc
        inc hl
        ld  a,(hl)              ;check y match
        sub d                   ;same as with x-check
-       jp  p,check_next
+       jr  nc,check_next       ;(=jp p)
        add a,6
        add a,(ix+1)            ;enemy height
        jp  m,check_next
@@ -1955,30 +2166,24 @@ not_maxpickup:
        ld  (hl),a              ;remove
        jr  check_next          ;all done, next..
 
-destroy_enemy:
-       ld  (hl),%01            ;set to explode
-       inc hl
-       ld  (hl),0              ;explosionFrame 0
-       jr  collide_done
-
 collide:
        dec hl
        ld  a,(hl)
-       and %11111100
-       jr  z,destroy_enemy
-       ld  a,(hl)
-       sub collidedamage
+       sub auch_ecollide
        ld  (hl),a
-collide_done:
-       ld  b,collidedamage     ;damage
+       jr  nc,enemydamaged     ;enemy still ok (HP>=0)
+       ld  (hl),%01            ;set to explode
+       inc hl
+       ld  (hl),0              ;explosionFrame 0
+enemydamaged:                  ;damage to enemy delivered
+       ld  b,auch_collide      ;your damage
        cal damage_you
 
 check_next:
        pop hl
-       ld  a,b                 ;psh bc
        ld  bc,enemysize
        add hl,bc
-       ld  b,a                 ;pop bc
+       pop bc
        dnz check_collision
        ret
 
@@ -2072,168 +2277,6 @@ SFXdelay:
        dnz SFXloop
        ret
 
-;--------------------------- show icon --------------------------------------
-
-drawline:
-       ld  (hl),a              ;draw one piece of the divider-line
-       inc hl                  ;move right (8 pixels = 1 byte)
-       dnz drawline            ;repeat (16bytes * 8pixels =128= screen width)
-       ret
-
-disp_icons:
- psh bc \ psh de \ psh hl \ psh ix ;&&&
-
-       ld  hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
-       ld  (PutWhere),hl       ;place icons at bottom of normal screen
-       ld  b,16                ;draw 16x (screen width)
-       ld  a,%11111111         ;horizontal line mask
-       cal drawline            ;draw divider-line
-
-       ld  b,16*7              ;draw 16x (screen width) 7x (height)
-       xor a                   ;blank line mask
-       cal drawline            ;clear scorebar
-
-disp_lives:
-       ld  de,5                ;(0,5)
-       ld  a,(your_lives)      ;nr of lives
-       or  a
-       jr  z,displivesdone     ;no lives
-       ld  b,a
-displivesloop:
-       psh bc
-       ld  ix,spr_lship
-       cal safeputsprite       ;put li'l ship
-       ld  a,lshipsize+1
-       add a,d
-       ld  d,a                 ;x=x+5
-       pop bc
-       dnz displivesloop       ;one ship per life
-displivesdone:
-
-       ld  ix,spr_icon01       ;armorIcon
-       ld  de,$1901            ;icon #1
-       cal putwidesprite       ;display icon
-       cal disp_armor          ;display bar
-
-       ld  ix,spr_icon00
-       ld  a,(your_weapon)     ;ur weapon
-       cp  maxweapon           ;laser?
-       psh af                  ;(your_weapon)
-       jr  nc,no_tail          ;if laser (nc) then tail ain't fired
-       ld  a,(your_tail)
-       or  a
-       jr  z,no_tail
-       ld  ix,spr_icon02       ;tailbeamIcon
-no_tail:
-       ld  de,$2901            ;icon #2
-       cal putwidesprite       ;display
-
-       ld  ix,spr_icon00
-       pop af                  ;a=(your_weapon); cf=bullets
-       psh af
-       jr  nc,no_bullets       ;=laser
-       ld  hl,$3945            ;position to display bullet-type digit
-       pop af                  ;digit=(your_weapon)
-       psh af
-       inc a                   ;1 = weapon #1 (=0)
-       ld  (_penCol),hl        ;set location
-       add a,'0'               ;make digit
-       cal _vputmap            ;display char
-       ld  ix,spr_icon03       ;bulletIcon
-no_bullets:
-       ld  de,$3901            ;icon #3
-       cal putwidesprite       ;display icon
-
-       ld  ix,spr_icon00       ;emptyIcon
-       pop af                  ;ld a,(your_weapon)
-       ld  b,a
-       jr  c,no_laser          ;popped carry
-       ld  hl,$3955            ;position to display bullet-type digit
-       ld  (_penCol),hl        ;set location
-       ld  a,b                 ;(your_weapon)  ;load = faster than push
-       sub maxweapon-1         ;1 = laser #1 (=maxweapon)
-       add a,'0'               ;make digit
-       cal _vputmap            ;display char
-       ld  ix,spr_icon04       ;laserIcon
-no_laser:
-       ld  de,$4901            ;icon #4
-       cal putwidesprite
-
-       ld  ix,spr_icon00       ;emptyIcon
-       ld  a,(your_multiples)
-       and %111
-       jr  z,no_multiples
-       ld  ix,spr_icon05
-no_multiples:
-       ld  de,$5901            ;icon #5
-       cal putwidesprite
-
-       ld  ix,spr_dividerline
-       ld  de,$6901
-       cal putwidesprite
-
-       ld  a,(your_pickup)     ;pickups taken
-       add a,a                 ;picks*2 (sets z-flag)
-       jr  z,iconsdone         ;return if no pickups
-       add a,a                 ;picks*4
-       add a,a                 ;picks*8
-       add a,a                 ;picks*$10
-       add a,$09               ;add 0ah
-       ld  d,a                 ;y-pos = picks * $10 + $0a (19,29,39,49,59)
-       ld  e,$01               ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
-
-       ld  ix,spr_icon
-       cal putwidesprite
-iconsdone:
-       ld  hl,dispbuffer       ;normal game-screen
-       ld  (PutWhere),hl       ;set sprite-position to normal screen
-
- pop ix \ pop hl \ pop de \ pop bc
-       ret
-
-disp_armor:
-       ld  de,16               ;line size
-       ld  hl,(57*16)+VIDEO_MEM+3
-       ld  b,3
-armorbarclr:
-       dec hl
-       ld  (hl),0
-       add hl,de
-       ld  (hl),0
-       sbc hl,de
-       dnz armorbarclr
-
-       ld  a,(your_armor)      ;load your armor (<25)
-       ld  c,a                 ;psh a
-       srl a                   ;/2
-       srl a                   ;/4
-       srl a                   ;/8: don't display last 3 bits of a (later)
-       jr  z,noarmorbar        ;if a=0 then it would loop 256x so skip it
-       ld  b,a                 ;loop b=a times
-armorbar:                      ;starting at ($39*16)+VIDEO_MEM
-       ld  (hl),%11111111      ;draw a piece of the bar
-       add hl,de               ;one down (resets carry)
-       ld  (hl),%11111111      ;same piece
-       sbc hl,de               ;up again
-       inc hl                  ;next position
-       dnz armorbar            ;loop it b times
-
-noarmorbar:
-       ld  a,c                 ;pop a
-       and %111                ;display last bits of armor
-       ret z                   ;if armor=0 then bit = %00000000 (don't disp)
-       ld  b,a                 ;into B
-       xor a                   ;bit = %00000000
-armorbarbit:
-       scf                     ;set carry flag
-       rra                     ;rotates A right and sets bit 7 (c-flag)
-       dnz armorbarbit         ;repeat B times (so if B=6 then a=%11111100)
-armorbarready:                 ;               (an if B=3 then a=%11100000)
-       ld  (hl),a              ;draw this last byte
-       add hl,de
-       ld  (hl),a              ;and just below
-       ret
-
 ;--------------------------- proc -------------------------------------------
 
 Random:                                ;a=c<random<b+c; destr:none
@@ -2310,10 +2353,12 @@ releasekeys:
        jp  GET_KEY             ;clear buffer
 
 findenemyspecs:                        ;enemy #a specs in (hl); in:b=0; out:ac=?
-       ld  hl,enemyspecs-8     ;enemy "0" specs (1 before enemy #1)
+       ld  hl,enemyspecs       ;enemy "0" specs
+       ld  c,a
        add a,a                 ;a=type*2
        add a,a                 ;a=type*4
        add a,a                 ;a=type*8
+       add a,c                 ;a=type*9
        ld  c,a                 ;b=0; c=bc=type*8
        add hl,bc               ;hl = enemy specs
        ret
@@ -2649,11 +2694,9 @@ samelevel:
        ld  (eventleft),a       ;set nr of events left
        inc hl
        ld  de,level_info
-       ldi                     ;load (level_info)
-       ldi                     ;load (level_move)
-       ldi                     ;load (spacespace)
-       ldi                     ;load (groundinfo)
-
+       ld  c,4                 ;bc=4
+       ldir                    ;4xLDI
+               ;loads (level_info); (level_move); (spacespace); (groundinfo)
        ld  a,1
        ld  b,32                ;fill (groundpos) and (ceilingpos)
 fillground:
@@ -2674,7 +2717,7 @@ fillground:
        ld  (hl),a              ;reset your ship (not exploding)
        inc hl                  ;hl = your_inv
        ld  (hl),25             ;set 25*4=100 frames invulnerable
-       ld  de,$1800
+       ld  de,$1820
        ld  (x),de              ;begin position (x,y)
        cal Place_multiples     ;place all multiple-positions at that (0,24)
 
@@ -2759,6 +2802,10 @@ loadweapon:
         inc hl
         ld  a,(hl)
         ld  (weapdaminc),a     ;damage increase
+       inc hl
+       ld  a,(hl)
+       and %00011111           ;laser duration
+       ld  (laserdur),a
        ret
 
 ;----------------------------------------------------------------------------
@@ -2988,13 +3035,39 @@ spr_ship04i:
        .db %11110001   ; ████   █
        .db %11000010   ; ██    █
 
+spr_ship05:
+       .db 8,8         ;XC1701II ship
+       .db %11110000   ;████
+       .db %10001100   ;█   ██
+       .db %11110010   ;████  █
+       .db %01011101   ; █ ███ █
+       .db %01011101   ; █ ███ █
+       .db %11110010   ;████  █
+       .db %10001100   ;█   ██
+       .db %11110000   ;████
+
+auch_bullet  = 1       ;damage to you when hit by an enemy bullet
+auch_ground  = 5       ;the same when you hit the ground/ceiling
+auch_collide = 3       ;when you hit an enemy
+auch_ecollide = 2*4    ;damage to both the enemy that hit you (skip bit 0/1)
+
 spr_multiple:
-       .db 6,5         ;multiples
-       .db %01111000   ;  ████
-       .db %11001100   ; ██  ██
-       .db %10000100   ; █    █
-       .db %11001100   ; ██  ██
-       .db %01111000   ;  ████
+       .db 6,6         ;multiples
+       .db %00000000   ;
+       .db %00111000   ;  ███
+       .db %01111100   ; █████
+       .db %01111100   ; █████
+       .db %01111100   ; █████
+       .db %00111000   ;  ███
+spr_multiple2:
+       .db 7,7         ;multiples
+       .db %00111000   ;  ███
+       .db %01111100   ; █████
+       .db %11111110   ;███████
+       .db %11111110   ;███████
+       .db %11111110   ;███████
+       .db %01111100   ; █████
+       .db %00111000   ;  ███
 
 ;-------------------------------- explosions --------------------------------
 
@@ -3215,13 +3288,11 @@ weapondata:
        .db 7,4,%01110100,2,%10010100,2,%00110100,2     ;7
        .db 12,5,%01110110,2,%10010110,2,%00110110,2    ;8
 maxweapon = 8
-       .db 1,1,%00000000,0,%00000000,0,%11100000,3     ;1 single laser
-       .db 1,1,%00000000,0,%11100000,0,%11100000,6     ;2 double laser
-       .db 1,1,%11100000,0,%11100000,6,%11100000,3     ;3 triple laser
+       .db 1,1,%11100100,3,%00000000,0,%00000000,0     ;1 single laser
+       .db 1,1,%11111111,0,%11100000,6,%00000000,0     ;2 double laser
+       .db 10,1,%11100001,0,%11100000,6,%11100000,3    ;3 triple laser
 maxlaser = 11
 
-collidedamage = 4
-
 ;------------------------------------ bar -----------------------------------
 
 spr_lship:
@@ -3266,22 +3337,22 @@ spr_icon00:
        .db %01010101
        .db %10101010
 spr_icon01:
-       .db 16,7        ;armor  ;.......:.......:
-       .db %10000111           ;█    ███████    
-       .db %10011000           ;█  ██       ██  ▒
-       .db %10110011           ;█ ██  ████   ██ 
-       .db %10110000           ;█ ██    ████ ██ 
-       .db %10110011           ;█ ██  ████   ██ ▒
-       .db %10011000           ;█  ██       ██  ▒
-       .db %10000111           ;█    ███████    ▒
+       .db 16,7        ;torpedo .......:.......:
+       .db %10000001           ;█      ███  ██ █
+       .db %10000000           ;█       ███  ██ ▒
+       .db %11000000           ;██      ███   ██
+       .db %10110001           ;█ ██   ███   █ █
+       .db %11001100           ;██  ██      ██  ▒
+       .db %10110011           ;█ ██  ██   ████ ▒
+       .db %11001100           ;██  ██  ██   ██ ▒
        .db 7
-       .db %11110000
-       .db %00001100
-       .db %11000110
+       .db %11001101
        .db %11100110
-       .db %11000110
+       .db %11100011
+       .db %11000101
        .db %00001100
-       .db %11110000
+       .db %00011110
+       .db %11000110
 spr_icon02:
        .db 16,7        ;tailbeam.......:.......:
        .db %10000000           ;█               ▒
@@ -3291,33 +3362,14 @@ spr_icon02:
        .db %10000001           ;█      ███      ▒
        .db %10000011           ;█     ██        ▒
        .db %10000000           ;█               ▒
-       .db 7
+       .db 5
        .db %00000000
        .db %00000000
        .db %11000000
        .db %11110011
        .db %11000000
-       .db %00000000
-       .db %00000000
-spr_icon02b:
-       .db 16,7        ;torpedo .......:.......:
-       .db %10111000           ;█ ███      █ █ █▒
-       .db %10011100           ;█  ███     █ █ █▒
-       .db %10111000           ;█ ███    █  █ █ ▒
-       .db %10000000           ;█       ███ █ █ ▒
-       .db %11100001           ;███    ████  █ █▒
-       .db %10011000           ;█  ██   ████ █ █▒
-       .db %11100110           ;███  ██   ██  █ ▒
-       .db 7
-       .db %00010101
-       .db %00010101
-       .db %01001010
-       .db %11101010
-       .db %11100101
-       .db %11110101
-       .db %00110010
 spr_icon03:
-       .db 16,7        ;bullets .......:.......:
+       .db 11,7        ;bullets .......:.......:
        .db %10000000           ;█       ██      ▒
        .db %10000011           ;█     █████ ▒▒▒ ▒
        .db %10011000           ;█  ██   ██  ▒▒▒ ▒
@@ -3342,14 +3394,11 @@ spr_icon04:
        .db %11101100           ;███ ██      ▒▒▒ ▒
        .db %10001010           ;█   █ █     ▒▒▒ ▒
        .db %10000000           ;█               ▒
-       .db 7
+       .db 4
        .db %00000000
        .db %00000000
        .db %00000000
        .db %11111111
-       .db %00000000
-       .db %00000000
-       .db %00000000
 spr_icon05:
        .db 16,7        ;multiple.......:.......:
        .db %10000011           ;█     ███       ▒
@@ -3359,14 +3408,13 @@ spr_icon05:
        .db %10011000           ;█  ██           ▒
        .db %10111100           ;█ ████  ██    ██▒
        .db %10011000           ;█  ██           ▒
-       .db 7
+       .db 6
        .db %10000000
        .db %11100110
        .db %11100000
        .db %10000000
        .db %00000000
        .db %11000011
-       .db %00000000
 spr_dividerline:
        .db 8,7
        .db 128,128,128,128,128,128,128 ;128 = %10000000
@@ -3375,9 +3423,9 @@ spr_dividerline:
 
 txt_email:     .db "www.shiar.org ",127 ;title screen
                .db " shiar0@hotmail.com",0
-_txt_email = $3A01 ;$3A1E=just email
-txt_about:     .db "v0.99.810 ",127," by Shiar",0 ;right behind txt_email
-_txt_about = $3321
+_txt_email       = $3A01 ;$3A1E=just email
+txt_about:     .db "v0.99.812 ",127," by Shiar",0 ;right behind txt_email
+_txt_about       = $3321
 txt_menu1:     .db "NEW GAME",0
 txt_menu2:     .db "CONTINUE",0
 
@@ -3389,7 +3437,11 @@ txt_gameover:    .db "GAME OVER!",0 ;game over screen
 txt_score:     .db "Score",0
 txt_hiscore:   .db "Hiscore",0
 
+txt_pause:     .db " ",6,"/",7," ",$1C,"contrast; "
+               .db "F1",$1C,"B",$CF,5,"W Mode",0
+_txt_pause       = $020B
 txt_pressenter:        .db "Enter to continue",0 ;pause
+_txt_pressenter          = $0201
 txt_teacher:   .db "(2",Lpi,"*.98)/sin 13",0 ;teacher
 txt_teacherans:        .db Lneg,"14.6549373495",0
 
@@ -3406,12 +3458,12 @@ levelp          .dw level01             ;pointer to level data          l01
 pickuptimer    .db  4                  ;counts when to place a pickup  4
 your_ship      .dw spr_ship01          ;your sprite                    sprs1
 your_score     .dw  0                  ;current score                  0
-your_pickup    .db  5                  ;pickups already picked up      0
+your_pickup    .db  4                  ;pickups already picked up      0
 your_occ       .db  0                  ;0=normal 1..16=exploding       0
 your_inv       .db  0                  ;invincibility left             0
-your_armor     .db 12                  ;HP left                        12
+your_armor     .db 22                  ;HP left                        12
 your_lives     .db  3                  ;lives left                     3
-your_weapon    .db  0                  ;current weapon upgrade         0
+your_weapon    .db  8                  ;current weapon upgrade         0
 your_multiples .db  0                  ;multiples present              0
 your_tail      .db  0                  ;tail beam present              0
 storesave_end:
@@ -3533,47 +3585,50 @@ level07:
 
 ;------------------------------ enemies -------------------------------------
 
-;format: [HP64] [000000:HP 00:occ] [sprite] [xpos] [appearance(ypos)]
-;       [movetype] [time2fire] [firefreq]
-;appearances: 1=random; 2=lure; 3=halflure
-;case movetype:
-;  1=updown; 2=1/4x; 3=1/2x; 4=1.5x; 5=2x; 6=smart; 7=y-lure;
-;  8=y-lure 1/2x; 9=x; 10=x+y-lure 1/2x
+;format:       [HP64] [000000:HP 00:occ] [sprite] [xpos] [appearance(ypos)]
+;              [movetype] [time2fire] [firefreq] [firetype]
+;appearances:  1=random; 2=lure; 3=halflure
+;movetypes:    1=updown; 2=1/4x; 3=1/2x; 4=1.5x; 5=2x; 6=smart; 7=y-lure;
+;              8=y-lure 1/2x; 9=x; 10=x+y-lure 1/2x
+;firetypes:    1=normal; 6=aiming; 7=triple; 8=double
+
 enemyspecs:
-;1-5=asteroids
-       .db 0,%00100110,(spr_enemyA1-spr_enemy00)/2,128,1,0,0,0
-       .db 0,%00111110,(spr_enemyA2-spr_enemy00)/2,128,1,0,0,0
-       .db 0,%01011010,(spr_enemyA3-spr_enemy00)/2,128,1,4,0,0
-       .db 1,%00001010,(spr_enemyA4-spr_enemy00)/2,128,1,3,0,0
-       .db 0,%00111110,(spr_enemyA4-spr_enemy00)/2,128,1,5,0,0
-;6-10=basic enemies
-       .db 0,%00010010,(spr_enemyE1-spr_enemy00)/2,128,1,0,10,0 ;weak
-       .db 0,%00110010,(spr_enemyE4-spr_enemy00)/2,128,1,3,6,50 ;slow
-       .db 0,%00100110,(spr_enemyE2-spr_enemy00)/2,128,1,0,1,0
-       .db 0,%00101110,(spr_enemyE3-spr_enemy00)/2,128,3,0,19,39
-       .db 0,%00101010,(spr_enemyE5-spr_enemy00)/2,128,3,4,1,0  ;fast
-;11-12=backwards
-       .db 0,%00011110,(spr_enemyB1-spr_enemy00)/2,0,3,11,19,92
-       .db 0,%00101110,(spr_enemyB2-spr_enemy00)/2,0,1,12,11,45
-       .db 0,%00110110,(spr_enemyB3-spr_enemy00)/2,0,1,11,10,41 ;small
-
-       .db 0,%00001111,(spr_enemyN3-spr_enemy00)/2,128,2,1,87,5
-       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;15
-       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;16
-       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;17
-       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;18
-       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0   ;19
-;20-23=first bosses
-       .db 1,%00101011,(spr_boss2-spr_enemy00)/2,127,1,8,20,12 ;small
-       .db 1,%00110011,(spr_boss1-spr_enemy00)/2,127,1,8,15,10
-       .db 1,%01001011,(spr_boss1-spr_enemy00)/2,127,3,10,10,9
-       .db 0,%11111111,(spr_boss3-spr_enemy00)/2,127,3,10,1,4 ;weak+rapidfire
-;24-25=asteroid bosses
-       .db 2,%00001011,(spr_bossA1-spr_enemy00)/2,127,1,10,36,14
-       .db 2,%00110011,(spr_bossA1-spr_enemy00)/2,127,2,10,28,12
-;26-27=big bosses
-       .db 2,%00000111,(spr_boss4-spr_enemy00)/2,127,3,7,18,7
-       .db 2,%01001011,(spr_boss5-spr_enemy00)/2,127,3,7,18,7
+       .db 0,%00000110,(spr_enemy00-spr_enemy00)/2,128,2,03, 0, 0,1 ;pickup
+;1-5=asteroids         ,                           ,   , ,  ,  ,
+       .db 0,%00100110,(spr_enemyA1-spr_enemy00)/2,128,1,00, 0, 0,1
+       .db 0,%00111110,(spr_enemyA2-spr_enemy00)/2,128,1,00, 0, 0,1
+       .db 0,%01011010,(spr_enemyA3-spr_enemy00)/2,128,1,04, 0, 0,1
+       .db 1,%00001010,(spr_enemyA4-spr_enemy00)/2,128,1,03, 0, 0,1 ;slow+hard
+       .db 0,%00111110,(spr_enemyA4-spr_enemy00)/2,128,1,05, 0, 0,1
+;6-10=basic enemies    ,                           ,   , ,  ,  ,
+       .db 0,%00010010,(spr_enemyE1-spr_enemy00)/2,128,1,00,10, 0,1 ;weak
+       .db 0,%00110010,(spr_enemyE4-spr_enemy00)/2,128,1,03, 6,50,1 ;slow
+       .db 0,%00100110,(spr_enemyE2-spr_enemy00)/2,128,1,00, 1, 0,1
+       .db 0,%00101110,(spr_enemyE3-spr_enemy00)/2,128,3,00,19,39,8 ;heavy
+       .db 0,%00101010,(spr_enemyE5-spr_enemy00)/2,128,3,04, 1, 0,1 ;fast
+;11-13=backwards enemies                           ,   , ,  ,  ,
+       .db 0,%00011110,(spr_enemyB1-spr_enemy00)/2,000,3,11,19,92,1
+       .db 0,%00101110,(spr_enemyB2-spr_enemy00)/2,000,1,12,11,45,1
+       .db 0,%00110110,(spr_enemyB3-spr_enemy00)/2,000,1,11,10,41,8 ;small
+;14=improved enemies   ,                           ,   , ,  ,  ,
+       .db 0,%01001010,(spr_enemyG1-spr_enemy00)/2,128,3,00, 1,35,1
+
+       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,128,0,00, 0, 0,1 ;15
+       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,128,0,00, 0, 0,1 ;16
+       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,128,0,00, 0, 0,1 ;17
+       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,128,0,00, 0, 0,1 ;18
+       .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,128,0,00, 0, 0,1 ;19
+;20-23=first bosses    ,                           ,   , ,  ,  ,
+       .db 1,%00101011,(spr_boss2  -spr_enemy00)/2,127,1,08,20,12,1 ;small
+       .db 1,%00110011,(spr_boss1  -spr_enemy00)/2,127,1,08,15,11,8 ;normal
+       .db 1,%01001011,(spr_boss1  -spr_enemy00)/2,127,3,10,10,11,1 ;moving
+       .db 0,%11111111,(spr_boss3  -spr_enemy00)/2,127,2,10, 1, 4,1 ;weak+rapidfire
+;24-25=asteroid bosses ,                           ,   , ,  ,  ,
+       .db 2,%00001011,(spr_bossA1 -spr_enemy00)/2,127,1,10,36,14,6
+       .db 2,%00110011,(spr_bossA1 -spr_enemy00)/2,127,2,10,28,12,6
+;26-27=big bosses      ,                           ,   , ,  ,  ,
+       .db 2,%00000111,(spr_bossB1 -spr_enemy00)/2,127,3,07,18, 7,7
+       .db 2,%01001011,(spr_bossB2 -spr_enemy00)/2,127,3,07,18, 7,7
 
 spr_enemy00:
        .db 16,8                        ;pickup
@@ -3819,6 +3874,26 @@ spr_enemyN3:
        .db %01011101                   ; █ ███ █
        .db %10111110                   ;█ █████
        .db 0
+spr_enemyN4:
+       .db 8,8                         ;Stolen from XC1701II
+       .db %01111110                   ; ██████
+       .db %11110101                   ;████ █ █
+       .db %00011111                   ;   █████
+       .db %00111101                   ;  ████ █
+       .db %00111001                   ;  ███  █
+       .db %00011111                   ;   █████
+       .db %11110101                   ;████ █ █
+       .db %01111110                   ; ██████
+spr_enemyN5:
+       .db 7,8                         ;Stolen from XC1701II
+       .db %00111100                   ;  ████
+       .db %01010010                   ; █ █  █
+       .db %11111110                   ;███████
+       .db %01001010                   ; █  █ █
+       .db %01011010                   ; █ ██ █
+       .db %11111110                   ;███████
+       .db %01010010                   ; █ █  █
+       .db %01111100                   ;  ████
 
 spr_boss1:
        .db 16,10                       ;.......:.......:
@@ -3893,7 +3968,7 @@ spr_boss3:
        .db %11100001
        .db %10001111
 spr_bossA1:
-       .db 16,11                       ;bigasteroid one
+       .db 16,11                       ;AsteroidBoss one
        .db %00011110                   ;   ████
        .db %01110011                   ; ███  ███
        .db %01111111                   ; ███████ █
@@ -3916,8 +3991,8 @@ spr_bossA1:
        .db %11110000
        .db %11000000
        .db 0
-spr_boss4:
-       .db 16,18                       ;bigboss one    :
+spr_bossB1:
+       .db 16,18                       ;BigBoss one    :
        .db %00000000                   ;         █ █
        .db %00000111                   ;     ███ ███
        .db %00000011                   ;      ████ █
@@ -3956,8 +4031,8 @@ spr_boss4:
        .db %11010000
        .db %01110000
        .db %01010000
-spr_boss5:
-       .db 16,15                       ;bigboss two    :
+spr_bossB2:
+       .db 16,15                       ;BigBoss two    :
        .db %00001111                   ;    █████
        .db %00111110                   ;  █████ █████
        .db %01111101                   ; █████ █ ███████
@@ -4099,12 +4174,29 @@ logo_nemesis:
 ;      # after pause weapon will not be fired
 ;      # teacher key fixed (waits for GRAPH to be release before&after)
 ;
-; 0.99.79 -- 9.VII.00 -- size 6747
+; 0.99.815 -- 15.VIII.00 -- size 6399
 ;
 ;      + you can have upto FOUR multiples! (~20 pixels apart)
 ;      * some optimizations: keycall, menu handling, port nops removed,
 ;         more SMC, fire handling, fast bullet handling, enemy movement
 ;      * better "backwards" enemies handling (and implemented in game)
+;      # when enemy changed into a pickup, movement is set to vslow
+;      * instead of turning into a pickup, enemies explode and a pickup
+;         appears at the right side of the screen (moves left slowly)
+;      # bullets do damage again (screenflash made damage become 0)
+;      + when destroyed by bullets, the armor bar will show 0HP left
+;      * all enemy bullets do the same damage in all levels
+;      * you now appear at (*32*,30) because enemies can come from left
+;      * improved bullet handling (faster, smaller, etc.)
+;      + multiples are animated like real Nemesis (grow-shrink-grow-shrink>)
+;      # fixed a bug that didn't select multiples when you were moving
+;      # enemy collision screwed up invert and some other weird stuff
+;      + in pause screen change contrast with up/down and B/W mode with F1
+;      + lasers can have different durations (beams last longer)
+;      * some sign-flag checkings replaced by carry-flag (thus reducing size)
+;      # slow enemies (including pickups) didn't always appear (just 25-50%)
+;      + enemies can fire different kinds of bullets: aiming, double, triple
+;      * maximum number of bullets increased (48 for enemies, 128 for you)
 ;
 ;       + added        - removed       * changed       # bug fixed