;----------------------------------------------------------
; level_4_load (28 lines)
level_4_load_004:
   PUSH AF                     ;

   CALL VDP_off                ; Stop VDP

   CALL load_tile_data_004     ; Load tiles
   CALL load_bg_data_004       ; Load background
   CALL load_palette_data_004  ; Load palette
   CALL initialize_score_bg4   ; Set up background in RAM
   CALL set_initial_sprites_level_4 ; Set up sprites
   CALL sprites_to_VRAM        ;

   LD a, STATE_LEVEL_4_RUN     ; Go to next state
   LD (RAM_GAME_STATE), a      ;

   LD a, LEVEL_TIMER_START     ; 99 second timer
   LD (RAM_TIME_1), a          ; Time 1
   LD (RAM_TIME_2), a          ; Time 2
   LD a, LEVEL_4_HEALTH        ; 6 health
   LD (RAM_HEALTH_1), a        ; Health

   LD a, 240                   ; Foes start 240 frames after clock starts.
   LD (RAM_FOE_1_COUNT), a     ;
   LD (RAM_FOE_2_COUNT), a     ;
   LD (RAM_FOE_3_COUNT), a     ;
   LD (RAM_FOE_4_COUNT), a     ;
   LD a, 120                   ; Foes start 120 frames after clock starts.
   LD (RAM_FOE_5_COUNT), a     ;
   LD (RAM_FOE_6_COUNT), a     ;
   LD (RAM_FOE_7_COUNT), a     ;
   LD (RAM_FOE_8_COUNT), a     ;

   LD a, $7F                   ; Enable scrolling
   LD (RAM_ENABLE_SCROLLING), a ;
   LD a, $00                   ; Initialize color index
   LD (RAM_COLOR_INDEX), a     ;

   CALL copy_song_to_RAM003    ; Start a level

   CALL VDP_on                 ; Start VDP

   POP AF                      ;
   RET                         ; End subroutine 
;----------------------------------------------------------

;----------------------------------------------------------
; level_4_run_004 (10 lines)
;
; Run level 1.
; * Copy score from RAM to VRAM 
; * Make pig fly
; * Make foes and points move
; * Collision detection
; * Check for no health (game over)
; * Check for no time (level complete)
;----------------------------------------------------------
level_4_run_004:

; Copy score from RAM to VRAM
   CALL copy_score_bg          ; Copy score from RAM to VRAM

; Copy sprites from RAM to VRAM
   CALL sprites_to_VRAM        ; Copy sprites to VRAM
   CALL level_4_poo_blink      ; Animated tile

; Run everything that does not use VRAM
   CALL set_score_level_4      ; Set the score in RAM
   CALL run_timer_level_4      ; Count down to 00. At 00, go to next level.
   CALL pig_flight_level_4     ; Flap pig wings
   CALL move_foes_level_4      ; Move the foes
   CALL lv4_collision_detect   ; Shot hit foe?
   CALL pig_got_hit_lv4        ; Pig got hit?

   RET                         ; End subroutine 
;----------------------------------------------------------

;----------------------------------------------------------
; load_tile_data_004 (12 lines)
;
; Load tile data to $0000.
;----------------------------------------------------------
load_tile_data_004: 
   LD a, $00                   ; Low address byte
   OUT (VDP_ADDR),a            ;
   LD a, $00                   ; High address byte
   OUT (VDP_ADDR),a            ;

   LD hl, tiles_004 + 1        ; tile_data is defined below
   LD c, VDP_DATA              ; C <- $BE;   LD b, 128  

   LD e, 89                   ; Set up counter (177 tiles, 89 sets of 2 tiles)

tile_load_loopt4:
   LD b, 64                    ; Write 2 tiles (64 characters)               
   CALL copy_to_vdp_loop       ; HL -> VDP, until B goes to 0

   DEC e                       ;
   JR NZ, tile_load_loopt4     ; Loop until de is empty.

   RET                         ; End subroutine 
;---------------------------------------

;----------------------------------------------------------
; load_bg_data_004 (12 lines)
;
; Load background data
;----------------------------------------------------------
load_bg_data_004: 
   LD a, $FF                   ; Low address byte
   OUT (VDP_ADDR),a            ;
   LD a, $37                   ; High address byte
   OUT (VDP_ADDR),a            ;

   LD hl, background_004       ; background_000 is defined below
   LD c, VDP_DATA              ; C <- $BE;   LD b, 128  

   LD e, 24                    ; Set up counter (24 rows)

tile_load_loopbg4:
   LD b, 64                    ; Write 1 row (64 characters)               
   CALL copy_to_vdp_loop       ; HL -> VDP, until B goes to 0

   DEC e                       ;
   JR NZ, tile_load_loopbg4    ; Loop until de is empty.

   RET                         ; End subroutine 
;---------------------------------------

;----------------------------------------------------------
; load_palette_data_004 (12 lines)
;
; Load palette data.
;----------------------------------------------------------
load_palette_data_004:
   LD a, $00                   ; Low address byte
   OUT (VDP_ADDR),a            ;
   LD a, $C0                   ; High address byte
   OUT (VDP_ADDR),a            ;

   LD hl, palette_001          ; 
   LD b, 32                    ;
   CALL copy_to_vdp_loop       ; HL -> VDP, until B goes to 0

   LD hl, palette_001          ; Copy restore color
   LD de, RAM_RESTORE_COLOR    ;
   LD bc, 32                   ;
   LDIR                        ;

   RET                         ; End subroutine  
;---------------------------------------


;---------------------------------------
; set_initial_sprites_level_4 (10 lines)
;
; Copy initial sprite values to RAM.
;---------------------------------------
set_initial_sprites_level_4:
   LD hl, vpos_sprites_level_4 ; VPOS
   LD de, RAM_VPOS            ; 
   LD bc, 45                  ;
   LDIR                       ;

   LD hl, hpos_sprites_level_4 ; HPOS, TILE
   LD de, RAM_HPOS            ; 
   LD bc, 89                  ;
   LDIR                       ;

   RET                        ; End subroutine 
;---------------------------------------

vpos_sprites_level_4:
.db $70 ; Pig 00
.db $70 ;
.db $70 ;
.db $70 ;
.db $78 ; 
.db $78 ;
.db $78 ;
.db $78 ;
.db $00 ; Shot 1 8
.db $00 ;
.db $08 ;
.db $08 ;
.db $20 ; Foe 1 12
.db $20 ;
.db $28 ;
.db $28 ;
.db $A0 ; Foe 2 16
.db $A0 ;
.db $A8 ;
.db $A8 ;
.db $20 ; Foe 3 20
.db $20 ;
.db $28 ;
.db $28 ;
.db $A0 ; Foe 4 24
.db $A0 ;
.db $A8 ;
.db $A8 ;
.db $30 ; Foe 5 28
.db $30 ;
.db $38 ;
.db $38 ;
.db $80 ; Foe 6 32
.db $80 ;
.db $88 ;
.db $88 ;
.db $30 ; Foe 7 36
.db $30 ;
.db $38 ;
.db $38 ;
.db $80 ; Foe 8 40
.db $80 ;
.db $88 ;
.db $88 ;
.db $D0 ; Delimiter

hpos_sprites_level_4:
.db $70, $01 ; Pig 00
.db $78, $02 ;
.db $80, $03 ;
.db $88, $04 ;
.db $70, $13 ; 
.db $78, $14 ;
.db $80, $15 ;
.db $88, $00 ;
.db $00, $27 ; Shot 1 16
.db $08, $28 ;
.db $00, $3B ;
.db $08, $3C ;
.db $30, $00 ; Foe 1 24
.db $38, $00 ;
.db $30, $00 ;
.db $38, $00 ;
.db $60, $00 ; Foe 2 32
.db $68, $00 ;
.db $60, $00 ;
.db $68, $00 ;
.db $90, $00 ; Foe 3 40
.db $98, $00 ;
.db $90, $00 ;
.db $98, $00 ;
.db $C0, $00 ; Foe 4 48
.db $C8, $00 ;
.db $C0, $00 ;
.db $C8, $00 ;
.db $20, $00 ; Foe 5 56
.db $28, $00 ;
.db $20, $00 ;
.db $28, $00 ;
.db $C0, $00 ; Foe 6 64
.db $C8, $00 ;
.db $C0, $00 ;
.db $C8, $00 ;
.db $20, $00 ; Foe 7 72
.db $28, $00 ;
.db $20, $00 ;
.db $28, $00 ;
.db $C0, $00 ; Foe 8 80
.db $C8, $00 ;
.db $C0, $00 ;
.db $C8, $00 ;
.db $D0 ; Delimiter


;---------------------------------------
; initialize_score_bg4 (10 lines)
;
;---------------------------------------
initialize_score_bg4:
   LD hl, background_004 + 64  ; Initial background
   LD de, RAM_SCORE_BG         ; RAM location
   LD b, 64*2                  ; Set B

isbg_loop_004:
   LD a, (hl)                  ; Copy
   LD (de), a                  ;
   INC hl                      ; Increment
   INC de                      ; Increment
   DEC b                       ; 

   JP NZ, isbg_loop_004        ;
   RET                         ; End subroutine 
;---------------------------------------


;---------------------------------------
; copy_score_bg4 (23 lines)
;
; Copy score data from RAM to background
;---------------------------------------
copy_score_bg4:
; Copy row 1 or row 2?
   LD a, (RAM_FRAME_CTR)       ; Frame counter
   AND $01                     ; Mask all but last bit
   JP NZ, csbg4_row2            ;

; Row 1
   LD a, $3F                   ; Low address byte
   OUT (VDP_ADDR),a            ;
   LD a, $38                   ; High address byte
   OUT (VDP_ADDR),a            ;
   LD hl, RAM_SCORE_BG         ; RAM source
   JP csbg4_start_copy          ;
 
; Row 2
csbg4_row2:
   LD a, $7F                   ; Low address byte
   OUT (VDP_ADDR),a            ;
   LD a, $38                   ; High address byte
   OUT (VDP_ADDR),a            ;
   LD hl, RAM_SCORE_BG + 64    ; RAM source

csbg4_start_copy:
   LD b, 64                    ; Write 1 row (64 characters)               
   CALL tool_copy_loop4        ; HL -> VDP, until B goes to 0

   RET                         ; End subroutine 

tool_copy_loop4:
   LD a, (hl)                 ; Read tile data
   OUT (VDP_DATA), a          ; Write to VRAM
   INC hl                     ; Increment hl

   DEC b                      ; Loop until all data is copied.
   JP NZ, tool_copy_loop4     ; 

   RET                        ; End subroutine
;---------------------------------------

;---------------------------------------
; set_score_level_4 (55 lines)
;
; Translate score to background info.
;
; 7 digits for score
; 1 digit for health
; 4 digits for time
;---------------------------------------
set_score_level_4:
   PUSH AF                    ;
   PUSH BC                    ;

   LD a, (RAM_SCORE_1)        ; Digit 1
   LD c, a                    ;
   LD de, $C306               ;
   LD hl, $C346               ;
   CALL number_to_score_level_4 ;

   LD a, (RAM_SCORE_2)        ; Digit 2
   LD c, a                    ;
   LD de, $C306 + 4           ;
   LD hl, $C346 + 4           ;
   CALL number_to_score_level_4 ;

   LD a, (RAM_SCORE_3)        ; Digit 3
   LD c, a                    ;
   LD de, $C306 + 8           ;
   LD hl, $C346 + 8           ;
   CALL number_to_score_level_4 ;

   LD a, (RAM_SCORE_4)        ; Digit 4
   LD c, a                    ;
   LD de, $C306 + 12          ;
   LD hl, $C346 + 12          ;
   CALL number_to_score_level_4 ;

   LD a, (RAM_SCORE_5)        ; Digit 5
   LD c, a                    ;
   LD de, $C306 + 16          ;
   LD hl, $C346 + 16          ;
   CALL number_to_score_level_4 ;

   LD a, (RAM_SCORE_6)        ; Digit 6
   LD c, a                    ;
   LD de, $C306 + 20          ;
   LD hl, $C346 + 20          ;
   CALL number_to_score_level_4 ;

   LD a, (RAM_SCORE_7)        ; Digit 7
   LD c, a                    ;
   LD de, $C306 + 24          ;
   LD hl, $C346 + 24          ;
   CALL number_to_score_level_4 ;

   LD a, (RAM_HEALTH_1)       ; Health
   LD c, a                    ;
   LD de, $C326               ;
   LD hl, $C366               ;
   CALL number_to_score_level_4 ;   

   LD a, (RAM_TIME_1)         ; Time 1
   LD c, a                    ;
   LD de, $C336               ;
   LD hl, $C376               ;
   CALL number_to_score_level_4 ; 

   LD a, (RAM_TIME_2)         ; Time 2
   LD c, a                    ;
   LD de, $C336 + 4           ;
   LD hl, $C376 + 4           ;
   CALL number_to_score_level_4 ; 

   POP BC                     ;
   POP AF                     ;
   RET                        ; End subroutine
;---------------------------------------

;---------------------------------------
; number_to_score_level_3 (240 lines)
;
; C = number
; DE = location to write to
; HL = location to write to
;---------------------------------------
number_to_score_level_4:
   LD a, c                    ; Translate
   CP 0                       ;
   JP Z, ntsl4_0              ;
   LD a, c                    ; Translate
   CP 1                       ;
   JP Z, ntsl4_1              ;
   LD a, c                    ; Translate
   CP 2                       ;
   JP Z, ntsl4_2              ;
   LD a, c                    ; Translate
   CP 3                       ;
   JP Z, ntsl4_3              ;
   LD a, c                    ; Translate
   CP 4                       ;
   JP Z, ntsl4_4              ;
   LD a, c                    ; Translate
   CP 5                       ;
   JP Z, ntsl4_5              ;
   LD a, c                    ; Translate
   CP 6                       ;
   JP Z, ntsl4_6              ;
   LD a, c                    ; Translate
   CP 7                       ;
   JP Z, ntsl4_7              ;
   LD a, c                    ; Translate
   CP 8                       ;
   JP Z, ntsl4_8              ;
   LD a, c                    ; Translate
   CP 9                       ;
   JP Z, ntsl4_9              ;

ntsl4_0:
   LD a, $49                  ; 0
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $49                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $02                  ;
   LD (de), a                 ;

   LD a, $65                  ; 0
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $66                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP ntsl4_copy_end          ;

ntsl4_1:
   LD a, $4A                  ; 1
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $4B                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;

   LD a, $4A                  ; 1
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $04                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $4B                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $04                  ;
   LD (hl), a                 ;
   JP ntsl4_copy_end          ;

ntsl4_2:
   LD a, $4C                  ; 2
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $4D                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;

   LD a, $67                  ; 2
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $68                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP ntsl4_copy_end          ;

ntsl4_3:
   LD a, $4E                  ; 3
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $4F                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;

   LD a, $69                  ; 3
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $6A                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP ntsl4_copy_end          ;

ntsl4_4:
   LD a, $50                  ; 4
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $51                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;

   LD a, $6B                  ; 4
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $6C                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP ntsl4_copy_end          ;

ntsl4_5:
   LD a, $52                  ; 5
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $53                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;

   LD a, $6D                  ; 5
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $6E                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP ntsl4_copy_end          ;

ntsl4_6:
   LD a, $54                  ; 6
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $55                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;

   LD a, $6F                  ; 6
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $70                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP ntsl4_copy_end          ;

ntsl4_7:
   LD a, $56                  ; 7
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $57                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;

   LD a, $71                  ; 7
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $72                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP ntsl4_copy_end          ;

ntsl4_8:
   LD a, $58                  ; 8
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $59                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;

   LD a, $73                  ; 8
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $74                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP ntsl4_copy_end          ;

ntsl4_9:
   LD a, $5A                  ; 9
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $5B                  ;
   LD (de), a                 ;
   INC de                     ;
   LD a, $00                  ;
   LD (de), a                 ;

   LD a, $75                  ; 9
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $76                  ;
   LD (hl), a                 ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;

ntsl4_copy_end:
   RET                        ; End subroutine   
;---------------------------------------

;---------------------------------------
; run_timer_level_4 (18 lines)
;
; Count down the timer digits.
;---------------------------------------
run_timer_level_4:
   LD a, (RAM_FRAME_CTR)      ; Frame counter
   CP 59                      ; 60 frames per second
   JP NZ, rtlv4_skip_000      ;

   LD a, (RAM_TIME_2)         ; Time 2
   DEC a                      ;
   LD (RAM_TIME_2), a         ;

   CP $FF                     ; at -1? 
   JP NZ, rtlv4_skip_000      ;

   LD a, $09                  ;
   LD (RAM_TIME_2), a         ;

   LD a, (RAM_TIME_1)         ; Time 2
   DEC a                      ;
   LD (RAM_TIME_1), a         ;

   CP $FF                     ; at -1? 
   JP NZ, rtlv4_skip_000      ;

   LD a, STATE_END_LOAD       ; Go to next level
   LD (RAM_GAME_STATE), a     ;

rtlv4_skip_000:
   RET                        ; End subroutine 
;---------------------------------------

;---------------------------------------
; pig_flight_level_4 (83 lines)
;
; Make the pig fly.
;---------------------------------------
pig_flight_level_4:
   LD a, (RAM_PIG_BLINK)      ;
   CP $00                     ;
   JP NZ, pflv4_end2          ;

   LD a, (RAM_FRAME_CTR)      ; Frame counter
   CP 0                       ; flap
   JP Z, pflv4_000            ;
   CP 15                      ; flap
   JP Z, pflv4_001            ;
   CP 30                      ; flap
   JP Z, pflv4_002            ;
   CP 45                      ; flap
   JP Z, pflv4_001            ;
   JP pflv4_end               ;

; High wing
pflv4_000:
   LD a, $01                  ;
   LD (RAM_HPOS + 1), a       ;
   LD a, $02                  ;
   LD (RAM_HPOS + 3), a       ;
   LD a, $03                  ;
   LD (RAM_HPOS + 5), a       ;
   LD a, $04                  ;
   LD (RAM_HPOS + 7), a       ;
   LD a, $13                  ;
   LD (RAM_HPOS + 9), a       ;
   LD a, $14                  ;
   LD (RAM_HPOS + 11), a      ;
   LD a, $15                  ;
   LD (RAM_HPOS + 13), a      ;
   LD a, $00                  ;
   LD (RAM_HPOS + 15), a      ;
   JP pflv4_end               ;

; Middle wing
pflv4_001:
   LD a, $05                  ;
   LD (RAM_HPOS + 1), a       ;
   LD a, $06                  ;
   LD (RAM_HPOS + 3), a       ;
   LD a, $03                  ;
   LD (RAM_HPOS + 5), a       ;
   LD a, $07                  ;
   LD (RAM_HPOS + 7), a       ;
   LD a, $16                  ;
   LD (RAM_HPOS + 9), a       ;
   LD a, $17                  ;
   LD (RAM_HPOS + 11), a      ;
   LD a, $15                  ;
   LD (RAM_HPOS + 13), a      ;
   LD a, $00                  ;
   LD (RAM_HPOS + 15), a      ;
   JP pflv4_end               ;

; Low wing
pflv4_002:
   LD a, $08                  ;
   LD (RAM_HPOS + 1), a       ;
   LD a, $09                  ;
   LD (RAM_HPOS + 3), a       ;
   LD a, $03                  ;
   LD (RAM_HPOS + 5), a       ;
   LD a, $04                  ;
   LD (RAM_HPOS + 7), a       ;
   LD a, $18                  ;
   LD (RAM_HPOS + 9), a       ;
   LD a, $19                  ;
   LD (RAM_HPOS + 11), a      ;
   LD a, $15                  ;
   LD (RAM_HPOS + 13), a      ;
   LD a, $00                  ;
   LD (RAM_HPOS + 15), a      ;
   JP pflv4_end               ;

pflv4_end2:
   LD a, (RAM_PIG_BLINK)      ; Make the pig blink
   DEC a                      ;
   LD (RAM_PIG_BLINK), a      ;

   LD a, $0A                  ;
   LD (RAM_HPOS + 1), a       ;
   LD a, $0B                  ;
   LD (RAM_HPOS + 3), a       ;
   LD a, $0C                  ;
   LD (RAM_HPOS + 5), a       ;
   LD a, $0D                  ;
   LD (RAM_HPOS + 7), a       ;
   LD a, $13                  ;
   LD (RAM_HPOS + 9), a       ;
   LD a, $1A                  ;
   LD (RAM_HPOS + 11), a      ;
   LD a, $1B                  ;
   LD (RAM_HPOS + 13), a      ;
   LD a, $1C                  ;
   LD (RAM_HPOS + 15), a      ;
pflv4_end:
   RET                        ; End subroutine 
;---------------------------------------

;----------------------------------------
; move_foes_level_4 (413 lines) 
;
; Move all 8 foes.
; 
; Each foe has two bytes in RAM that
; define it's behavior.
; byte 1 - Terminate counter
;          If zero, move as normal.
;          else, count down to zero, 
;          then respawn. 
; byte 2 - Algorithm temp byte.
;          Some movement algorithms may
;          require a state variable.
;
; RAM_FOE_1_COUNT
; RAM_FOE_1_STATE
; RAM_FOE_2_COUNT
; RAM_FOE_2_STATE
; RAM_FOE_3_COUNT
; RAM_FOE_3_STATE
; RAM_FOE_4_COUNT
; RAM_FOE_4_STATE
; RAM_FOE_5_COUNT
; RAM_FOE_5_STATE
; RAM_FOE_6_COUNT
; RAM_FOE_6_STATE
; RAM_FOE_7_COUNT
; RAM_FOE_7_STATE
; RAM_FOE_8_COUNT
; RAM_FOE_8_STATE
;
; Foe 1 - Bat
; Foe 2 - Bat
; Foe 3 - Bat
; Foe 4 - Bat
; Foe 5 - Bat
; Foe 6 - Bat
; Foe 7 - Bat
; Foe 8 - Bat
;----------------------------------------
move_foes_level_4:
;------------------------------------------
; Foe 1 - Bat
mflv4_next_001:
  LD hl, RAM_FOE_1_COUNT        ;
  LD a, (hl)                    ; Termination counter expired? 
  CP $00                        ;
  JP NZ, mflv4_countdown_001    ;

  LD hl, RAM_HPOS + 24          ; Flames flicker
  CALL set_bat_sprites_lv4      ;

  LD a, (RAM_FOE_1_STATE)       ;
  CP $00                        ;
  JP Z, mflv4_downright_001     ;
  CP $01                        ;
  JP Z, mflv4_downleft_001      ;
  CP $02                        ;
  JP Z, mflv4_upleft_001        ;
  CP $03                        ;
  JP Z, mflv4_upright_001       ;

mflv4_downright_001:
  LD hl, RAM_VPOS + 12          ; Down
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 24          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 24)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4_next_002         ;
  LD a, $01                     ;
  LD (RAM_FOE_1_STATE), a       ; Change state
  JP mflv4_next_002             ;

mflv4_downleft_001:
  LD hl, RAM_VPOS + 12          ;
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 24          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 12)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4_next_002         ;
  LD a, $02                     ;
  LD (RAM_FOE_1_STATE), a       ; Change state
  JP mflv4_next_002             ;

mflv4_upleft_001:
  LD hl, RAM_VPOS + 12          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 24          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 24)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4_next_002         ;
  LD a, $03                     ;
  LD (RAM_FOE_1_STATE), a       ; Change state
  JP mflv4_next_002             ;

mflv4_upright_001:
  LD hl, RAM_VPOS + 12          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 24          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 12)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4_next_002         ;
  LD a, $00                     ;
  LD (RAM_FOE_1_STATE), a       ; Change state
  JP mflv4_next_002             ;

mflv4_countdown_001:
  DEC (hl)                      ; Decrement counter

  LD a, (hl)                    ; Respawn?
  CP $00                        ;
  JP NZ, mflv4_next_002         ;
  LD hl, vpos_sprites_level_4 + 12 ; Y respawn
  LD de, RAM_VPOS + 12          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 24 ; X respawn
  LD de, RAM_HPOS + 24          ;
  CALL copy_4_hpos_lv4          ;

;------------------------------------------
; Foe 2 - Bat
mflv4_next_002:
  LD hl, RAM_FOE_2_COUNT        ;
  LD a, (hl)                    ; Termination counter expired? 
  CP $00                        ;
  JP NZ, mflv4_countdown_002    ;

  LD hl, RAM_HPOS + 32          ; Flames flicker
  CALL set_bat2_sprites_lv4     ;

  LD a, (RAM_FOE_2_STATE)       ;
  CP $00                        ;
  JP Z, mflv4_downright_002     ;
  CP $01                        ;
  JP Z, mflv4_downleft_002      ;
  CP $02                        ;
  JP Z, mflv4_upleft_002        ;
  CP $03                        ;
  JP Z, mflv4_upright_002       ;

mflv4_downright_002:
  LD hl, RAM_VPOS + 16          ; Down
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 32          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 32)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4_next_003         ;
  LD a, $01                     ;
  LD (RAM_FOE_2_STATE), a       ; Change state
  JP mflv4_next_003             ;

mflv4_downleft_002:
  LD hl, RAM_VPOS + 16          ;
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 32          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 16)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4_next_003         ;
  LD a, $02                     ;
  LD (RAM_FOE_2_STATE), a       ; Change state
  JP mflv4_next_003             ;

mflv4_upleft_002:
  LD hl, RAM_VPOS + 16          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 32          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 32)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4_next_003         ;
  LD a, $03                     ;
  LD (RAM_FOE_2_STATE), a       ; Change state
  JP mflv4_next_003             ;

mflv4_upright_002:
  LD hl, RAM_VPOS + 16          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 32          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 16)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4_next_003         ;
  LD a, $00                     ;
  LD (RAM_FOE_2_STATE), a       ; Change state
  JP mflv4_next_003             ;

mflv4_countdown_002:
  DEC (hl)                      ; Decrement counter

  LD a, (hl)                    ; Respawn?
  CP $00                        ;
  JP NZ, mflv4_next_003         ;
  LD hl, vpos_sprites_level_4 + 16 ; Y respawn
  LD de, RAM_VPOS + 16          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 32 ; X respawn
  LD de, RAM_HPOS + 32          ;
  CALL copy_4_hpos_lv4          ;

;------------------------------------------
; Foe 3 - Bat
mflv4_next_003:
  LD hl, RAM_FOE_3_COUNT        ;
  LD a, (hl)                    ; Termination counter expired? 
  CP $00                        ;
  JP NZ, mflv4_countdown_003    ;

  LD hl, RAM_HPOS + 40          ; Flames flicker
  CALL set_bat3_sprites_lv4     ;

  LD a, (RAM_FOE_3_STATE)       ;
  CP $00                        ;
  JP Z, mflv4_downright_003     ;
  CP $01                        ;
  JP Z, mflv4_downleft_003      ;
  CP $02                        ;
  JP Z, mflv4_upleft_003        ;
  CP $03                        ;
  JP Z, mflv4_upright_003       ;

mflv4_downright_003:
  LD hl, RAM_VPOS + 20          ; Down
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 40          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 40)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4_next_004         ;
  LD a, $01                     ;
  LD (RAM_FOE_3_STATE), a       ; Change state
  JP mflv4_next_004             ;

mflv4_downleft_003:
  LD hl, RAM_VPOS + 20          ;
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 40          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 20)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4_next_004         ;
  LD a, $02                     ;
  LD (RAM_FOE_3_STATE), a       ; Change state
  JP mflv4_next_004             ;

mflv4_upleft_003:
  LD hl, RAM_VPOS + 20          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 40          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 40)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4_next_004         ;
  LD a, $03                     ;
  LD (RAM_FOE_3_STATE), a       ; Change state
  JP mflv4_next_004             ;

mflv4_upright_003:
  LD hl, RAM_VPOS + 20          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 40          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 20)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4_next_004         ;
  LD a, $00                     ;
  LD (RAM_FOE_3_STATE), a       ; Change state
  JP mflv4_next_004             ;

mflv4_countdown_003:
  DEC (hl)                      ; Decrement counter

  LD a, (hl)                    ; Respawn?
  CP $00                        ;
  JP NZ, mflv4_next_004         ;
  LD hl, vpos_sprites_level_4 + 20 ; Y respawn
  LD de, RAM_VPOS + 20          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 40 ; X respawn
  LD de, RAM_HPOS + 40          ;
  CALL copy_4_hpos_lv4          ;

;------------------------------------------
; Foe 4 - Bat
mflv4_next_004:
  LD hl, RAM_FOE_4_COUNT        ;
  LD a, (hl)                    ; Termination counter expired? 
  CP $00                        ;
  JP NZ, mflv4_countdown_004    ;

  LD hl, RAM_HPOS + 48          ; Flames flicker
  CALL set_bat4_sprites_lv4     ;

  LD a, (RAM_FOE_4_STATE)       ;
  CP $00                        ;
  JP Z, mflv4_downright_004     ;
  CP $01                        ;
  JP Z, mflv4_downleft_004      ;
  CP $02                        ;
  JP Z, mflv4_upleft_004        ;
  CP $03                        ;
  JP Z, mflv4_upright_004       ;

mflv4_downright_004:
  LD hl, RAM_VPOS + 24          ; Down
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 48          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 48)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4_next_005         ;
  LD a, $01                     ;
  LD (RAM_FOE_4_STATE), a       ; Change state
  JP mflv4_next_005             ;

mflv4_downleft_004:
  LD hl, RAM_VPOS + 24          ;
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 48          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 24)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4_next_005         ;
  LD a, $02                     ;
  LD (RAM_FOE_4_STATE), a       ; Change state
  JP mflv4_next_005             ;

mflv4_upleft_004:
  LD hl, RAM_VPOS + 24          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 48          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 48)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4_next_005         ;
  LD a, $03                     ;
  LD (RAM_FOE_4_STATE), a       ; Change state
  JP mflv4_next_005             ;

mflv4_upright_004:
  LD hl, RAM_VPOS + 24          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 48          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 24)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4_next_005         ;
  LD a, $00                     ;
  LD (RAM_FOE_4_STATE), a       ; Change state
  JP mflv4_next_005             ;

mflv4_countdown_004:
  DEC (hl)                      ; Decrement counter

  LD a, (hl)                    ; Respawn?
  CP $00                        ;
  JP NZ, mflv4_next_005         ;
  LD hl, vpos_sprites_level_4 + 24 ; Y respawn
  LD de, RAM_VPOS + 24          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 48 ; X respawn
  LD de, RAM_HPOS + 48          ;
  CALL copy_4_hpos_lv4          ;

;------------------------------------------
; Foe 5 - Bat
mflv4_next_005:
  LD hl, RAM_FOE_5_COUNT        ;
  LD a, (hl)                    ; Termination counter expired? 
  CP $00                        ;
  JP NZ, mflv4_countdown_005    ;

  LD hl, RAM_HPOS + 56          ; Flames flicker
  CALL set_bat_sprites_lv4      ;

  LD a, (RAM_FOE_5_STATE)       ;
  CP $00                        ;
  JP Z, mflv4_downright_005     ;
  CP $01                        ;
  JP Z, mflv4_downleft_005      ;
  CP $02                        ;
  JP Z, mflv4_upleft_005        ;
  CP $03                        ;
  JP Z, mflv4_upright_005       ;

mflv4_downright_005:
  LD hl, RAM_VPOS + 28          ; Down
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 56          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 56)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4_next_006         ;
  LD a, $01                     ;
  LD (RAM_FOE_5_STATE), a       ; Change state
  JP mflv4_next_006             ;

mflv4_downleft_005:
  LD hl, RAM_VPOS + 28          ;
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 56          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 28)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4_next_006         ;
  LD a, $02                     ;
  LD (RAM_FOE_5_STATE), a       ; Change state
  JP mflv4_next_006             ;

mflv4_upleft_005:
  LD hl, RAM_VPOS + 28          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 56          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 56)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4_next_006         ;
  LD a, $03                     ;
  LD (RAM_FOE_5_STATE), a       ; Change state
  JP mflv4_next_006             ;

mflv4_upright_005:
  LD hl, RAM_VPOS + 28          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 56          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 28)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4_next_006         ;
  LD a, $00                     ;
  LD (RAM_FOE_5_STATE), a       ; Change state
  JP mflv4_next_006             ;

mflv4_countdown_005:
  DEC (hl)                      ; Decrement counter

  LD a, (hl)                    ; Respawn?
  CP $00                        ;
  JP NZ, mflv4_next_006         ;
  LD hl, vpos_sprites_level_4 + 28 ; Y respawn
  LD de, RAM_VPOS + 28          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 56 ; X respawn
  LD de, RAM_HPOS + 56          ;
  CALL copy_4_hpos_lv4          ;

;------------------------------------------
; Foe 6 - Bat
mflv4_next_006:
  LD hl, RAM_FOE_6_COUNT        ;
  LD a, (hl)                    ; Termination counter expired? 
  CP $00                        ;
  JP NZ, mflv4_countdown_006    ;

  LD hl, RAM_HPOS + 64          ; Flames flicker
  CALL set_bat2_sprites_lv4     ;

  LD a, (RAM_FOE_6_STATE)       ;
  CP $00                        ;
  JP Z, mflv4_downright_006     ;
  CP $01                        ;
  JP Z, mflv4_downleft_006      ;
  CP $02                        ;
  JP Z, mflv4_upleft_006        ;
  CP $03                        ;
  JP Z, mflv4_upright_006       ;

mflv4_downright_006:
  LD hl, RAM_VPOS + 32          ; Down
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 64          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 64)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4_next_007         ;
  LD a, $01                     ;
  LD (RAM_FOE_6_STATE), a       ; Change state
  JP mflv4_next_007             ;

mflv4_downleft_006:
  LD hl, RAM_VPOS + 32          ;
  CALL lv4_down_subroutine      ;
  LD hl, RAM_HPOS + 64          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 32)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4_next_007         ;
  LD a, $02                     ;
  LD (RAM_FOE_6_STATE), a       ; Change state
  JP mflv4_next_007             ;

mflv4_upleft_006:
  LD hl, RAM_VPOS + 32          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 64          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 64)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4_next_007         ;
  LD a, $03                     ;
  LD (RAM_FOE_6_STATE), a       ; Change state
  JP mflv4_next_007             ;

mflv4_upright_006:
  LD hl, RAM_VPOS + 32          ;
  CALL lv4_up_subroutine        ;
  LD hl, RAM_HPOS + 64          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 32)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4_next_007         ;
  LD a, $00                     ;
  LD (RAM_FOE_6_STATE), a       ; Change state
  JP mflv4_next_007             ;

mflv4_countdown_006:
  DEC (hl)                      ; Decrement counter

  LD a, (hl)                    ; Respawn?
  CP $00                        ;
  JP NZ, mflv4_next_007         ;
  LD hl, vpos_sprites_level_4 + 32 ; Y respawn
  LD de, RAM_VPOS + 32          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 64 ; X respawn
  LD de, RAM_HPOS + 64          ;
  CALL copy_4_hpos_lv4          ;

; Skip foe 7 - too much on screen
; Skip foe 8 - too much on screen
mflv4_next_007:

   RET                        ; End subroutine 
;---------------------------------------


;----------------------------------------
; lv4_up_subroutine (8 lines)
; HL = VPOS
;----------------------------------------
lv4_up_subroutine:
  LD a, (hl)                    ; $20 to $C0
  CP $20                        ;
  JP Z, lv4usub_001             ;

lv4_up_subroutine2:
  DEC (hl)                      ;
  INC hl                        ;
  DEC (hl)                      ;
  INC hl                        ;
  DEC (hl)                      ;
  INC hl                        ;
  DEC (hl)                      ;

  RET                           ; End subroutine 

lv4usub_001:  
  LD a, $C0                     ; $20 to $C0
  LD (hl), a                    ;
  INC hl                        ;
  LD a, $C0                     ;
  LD (hl), a                    ;
  INC hl                        ;
  LD a, $C8                     ;
  LD (hl), a                    ;
  INC hl                        ;
  LD a, $C8                     ;
  LD (hl), a                    ;

  RET                           ; End subroutine
;----------------------------------------

;----------------------------------------
; lv4_down_subroutine (8 lines)
; HL = VPOS
;----------------------------------------
lv4_down_subroutine:
  LD a, (hl)                    ; $C0 to $20
  CP $C0                        ;
  JP Z, lv4dsub_001             ;

lv4_down_subroutine2:
  INC (hl)                      ;
  INC hl                        ;
  INC (hl)                      ;
  INC hl                        ;
  INC (hl)                      ;
  INC hl                        ;
  INC (hl)                      ;

  RET                           ; End subroutine 

lv4dsub_001:
  LD a, $20                     ; $C0 to $20
  LD (hl), a                    ;
  INC hl                        ;
  LD a, $20                     ;
  LD (hl), a                    ;
  INC hl                        ;
  LD a, $28                     ;
  LD (hl), a                    ;
  INC hl                        ;
  LD a, $28                     ;
  LD (hl), a                    ;

  RET                           ; End subroutine
;----------------------------------------


;----------------------------------------
; lv4_right_subroutine (11 lines)
; HL = HPOS
;----------------------------------------
lv4_right_subroutine:
  INC (hl)                      ;
  INC hl                        ;
  INC hl                        ;
  INC (hl)                      ;
  INC hl                        ;
  INC hl                        ;
  INC (hl)                      ;
  INC hl                        ;
  INC hl                        ;
  INC (hl)                      ;
  
  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; lv4_left_subroutine (11 lines)
; HL = HPOS
;----------------------------------------
lv4_left_subroutine:
  DEC (hl)                      ;
  INC hl                        ;
  INC hl                        ;
  DEC (hl)                      ;
  INC hl                        ;
  INC hl                        ;
  DEC (hl)                      ;
  INC hl                        ;
  INC hl                        ;
  DEC (hl)                      ;
  
  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; copy_4_vpos_lv4 (8 lines)
;
; HL = source
; DE = destination
;----------------------------------------
copy_4_vpos_lv4:
  LD b, 4            ;
copy_4_vpos_lv4_loop:
  LD a, (hl)         ; 
  LD (de), a         ; 
  INC hl             ;
  INC de             ;
  DEC b              ;
  JP NZ, copy_4_vpos_lv4_loop ;

  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; copy_4_hpos_lv4 (10 lines)
;
; HL = source
; DE = destination
;----------------------------------------
copy_4_hpos_lv4:
  LD b, 4            ;
copy_4_hpos_lv4_loop:
  LD a, (hl)         ; 
  LD (de), a         ; 
  INC hl             ;
  INC de             ;
  INC hl             ;
  INC de             ;
  DEC b              ;
  JP NZ, copy_4_hpos_lv4_loop ;

  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; set_bat_sprites_lv4 (38 lines)
;
; HL = destination
;----------------------------------------
set_bat_sprites_lv4:
  INC hl                        ;

  LD a, (RAM_FRAME_CTR)         ;
  AND $10                       ;
  CP $00                        ;
  JP Z, bat_1_000               ;

  LD a, $0E                     ;; 0E 0F 1D 1E
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $0F                     ;; 0E 0F 1D 1E
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $1D                     ;; 0E 0F 1D 1E
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $1E                     ;; 0E 0F 1D 1E
  LD (hl), a                    ;
  JP sfslv4_end                 ;

bat_1_000:
  LD a, $10                     ;; 10 11 1F 20
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $11                     ;; 10 11 1F 20
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $1F                     ;  10 11 1F 20
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $20                     ;; 10 11 1F 20
  LD (hl), a                    ;
  JP sfslv4_end                 ;

sfslv4_end:
  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; set_bat2_sprites_lv4 (38 lines)
;
; HL = destination
;----------------------------------------
set_bat2_sprites_lv4:
  INC hl                        ;

  LD a, (RAM_FRAME_CTR)         ;
  AND $10                       ;
  CP $00                        ;
  JP Z, bat2_1_000               ;

  LD a, $29                     ;; 29 2A 3D 3E
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $2A                     ;; 29 2A 3D 3E
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $3D                     ;; 29 2A 3D 3E
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $3E                     ;; 29 2A 3D 3E
  LD (hl), a                    ;
  JP sfslv4_end2                ;

bat2_1_000:
  LD a, $2B                     ;; 2B 2C 3F 40
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $2C                     ;; 2B 2C 3F 40
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $3F                     ;  2B 2C 3F 40
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $40                     ;; 2B 2C 3F 40
  LD (hl), a                    ;
  JP sfslv4_end2                ;

sfslv4_end2:
  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; set_bat3_sprites_lv4 (38 lines)
;
; HL = destination
;----------------------------------------
set_bat3_sprites_lv4:
  INC hl                        ;

  LD a, (RAM_FRAME_CTR)         ;
  AND $10                       ;
  CP $00                        ;
  JP Z, bat3_1_000               ;

  LD a, $2D                     ;; 2D 2E 41 42
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $2E                     ;; 2D 2E 41 42
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $41                     ;; 2D 2E 41 42
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $42                     ;; 2D 2E 41 42
  LD (hl), a                    ;
  JP sfslv4_end3                ;

bat3_1_000:
  LD a, $2F                     ;; 2F 30 43 44
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $30                     ;; 2F 30 43 44
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $43                     ;  2F 30 43 44
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $44                     ;; 2F 30 43 44
  LD (hl), a                    ;
  JP sfslv4_end3                ;

sfslv4_end3:
  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; set_bat4_sprites_lv4 (38 lines)
;
; HL = destination
;----------------------------------------
set_bat4_sprites_lv4:
  INC hl                        ;

  LD a, (RAM_FRAME_CTR)         ;
  AND $10                       ;
  CP $00                        ;
  JP Z, bat4_1_000               ;

  LD a, $31                     ;; 31 32 45 46
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $32                     ;; 31 32 45 46
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $45                     ;; 31 32 45 46
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $46                     ;; 31 32 45 46
  LD (hl), a                    ;
  JP sfslv4_end4                ;

bat4_1_000:
  LD a, $33                     ;; 33 34 47 48
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $34                     ;; 33 34 47 48
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $47                     ;  33 34 47 48
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $48                     ;; 33 34 47 48
  LD (hl), a                    ;
  JP sfslv4_end4                ;

sfslv4_end4:
  RET                           ; End subroutine 
;----------------------------------------

;-----------------------------------------
; lv4_collision_detect (135 lines)
;
; Did the light gun hit a target?
;
; RAM_COLL_X1
; RAM_COLL_X2
; RAM_COLL_Y1
; RAM_COLL_Y2
; RAM_COLL_RESULT
; CALL xy_collision_detect
;-----------------------------------------
lv4_collision_detect:
  LD a, (RAM_LIGHT_GUN_READ)    ; Only detect when 
  CP $7F                        ; trigger is pulled.
  JP NZ, lv4_cd_skip_007        ;

  LD a, (RAM_VPOS + 8)          ;
  LD (RAM_COLL_Y1), a           ; Shot Y
  LD a, (RAM_HPOS + 16)         ;
  LD (RAM_COLL_X1), a           ; Shot X

; Foe 1
  LD a, (RAM_FOE_1_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, lv4_cd_skip_002        ;

  LD a, (RAM_VPOS + 12)         ;
  LD (RAM_COLL_Y2), a           ; Foe 1 Y
  LD a, (RAM_HPOS + 24)         ;
  LD (RAM_COLL_X2), a           ; Foe 1 X
  CALL xy_collision_detect      ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, lv4_cd_skip_002        ;
  LD a, 240                     ; If hit, set respawn counter
  LD (RAM_FOE_1_COUNT), a       ;
  CALL  ds_lv4_add_to_score     ;
  LD hl, RAM_HPOS + 24          ;
  CALL ds_lv4_set_sprite        ;

lv4_cd_skip_002:
; Foe 2
  LD a, (RAM_FOE_2_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, lv4_cd_skip_003        ;

  LD a, (RAM_VPOS + 16)         ;
  LD (RAM_COLL_Y2), a           ; Foe 2 Y
  LD a, (RAM_HPOS + 32)         ;
  LD (RAM_COLL_X2), a           ; Foe 2 X
  CALL xy_collision_detect      ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, lv4_cd_skip_003        ;
  LD a, 240                     ; If hit, set respawn counter
  LD (RAM_FOE_2_COUNT), a       ;
  CALL  ds_lv4_add_to_score     ;
  LD hl, RAM_HPOS + 32          ;
  CALL ds_lv4_set_sprite        ;

lv4_cd_skip_003:
; Foe 3
  LD a, (RAM_FOE_3_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, lv4_cd_skip_004        ;

  LD a, (RAM_VPOS + 20)         ;
  LD (RAM_COLL_Y2), a           ; Foe 3 Y
  LD a, (RAM_HPOS + 40)         ;
  LD (RAM_COLL_X2), a           ; Foe 3 X
  CALL xy_collision_detect      ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, lv4_cd_skip_004        ;
  LD a, 240                     ; If hit, set respawn counter
  LD (RAM_FOE_3_COUNT), a       ;
  CALL  ds_lv4_add_to_score     ;
  LD hl, RAM_HPOS + 40          ;
  CALL ds_lv4_set_sprite        ;

lv4_cd_skip_004:
; Foe 4
  LD a, (RAM_FOE_4_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, lv4_cd_skip_005        ;

  LD a, (RAM_VPOS + 24)         ;
  LD (RAM_COLL_Y2), a           ; Foe 4 Y
  LD a, (RAM_HPOS + 48)         ;
  LD (RAM_COLL_X2), a           ; Foe 4 X
  CALL xy_collision_detect      ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, lv4_cd_skip_005        ;
  LD a, 240                     ; If hit, set respawn counter
  LD (RAM_FOE_4_COUNT), a       ;
  CALL  ds_lv4_add_to_score     ;
  LD hl, RAM_HPOS + 48          ;
  CALL ds_lv4_set_sprite        ;

lv4_cd_skip_005:
; Foe 5
  LD a, (RAM_FOE_5_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, lv4_cd_skip_006        ;

  LD a, (RAM_VPOS + 28)         ;
  LD (RAM_COLL_Y2), a           ; Foe 5 Y
  LD a, (RAM_HPOS + 56)         ;
  LD (RAM_COLL_X2), a           ; Foe 5 X
  CALL xy_collision_detect      ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, lv4_cd_skip_006        ;
  LD a, 240                     ; If hit, set respawn counter
  LD (RAM_FOE_5_COUNT), a       ;
  CALL  ds_lv4_add_to_score     ;
  LD hl, RAM_HPOS + 56          ;
  CALL ds_lv4_set_sprite        ;

lv4_cd_skip_006:
; Foe 6
  LD a, (RAM_FOE_6_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, lv4_cd_skip_007        ;

  LD a, (RAM_VPOS + 32)         ;
  LD (RAM_COLL_Y2), a           ; Foe 6 Y
  LD a, (RAM_HPOS + 64)         ;
  LD (RAM_COLL_X2), a           ; Foe 6 X
  CALL xy_collision_detect      ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, lv4_cd_skip_007        ;
  LD a, 240                     ; If hit, set respawn counter
  LD (RAM_FOE_6_COUNT), a       ;
  CALL  ds_lv4_add_to_score     ;
  LD hl, RAM_HPOS + 64          ;
  CALL ds_lv4_set_sprite        ;

lv4_cd_skip_007:
  RET                           ; End subroutine 
;----------------------------------------


;----------------------------------------
; ds_lv4_set_sprite (17 lines)
;
; Set sprite to "100".
;----------------------------------------
; HL = target address
ds_lv4_set_sprite:
  INC hl                        ;
  LD a, $25                     ;; 24 25 38 39
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $26                     ;; 24 25 38 39
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $39                     ;; 24 25 38 39
  LD (hl), a                    ;
  INC hl                        ;
  INC hl                        ;
  LD a, $3A                     ;; 24 25 38 39
  LD (hl), a                    ;

  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; ds_lv4_add_to_score (16  lines)
;
; Increment the score by 100.
;----------------------------------------
ds_lv4_add_to_score:
  LD b, 5                       ;
  LD hl, RAM_SCORE_5            ; LSD
  INC (hl)                      ;

  LD a, (hl)                    ;
  CP 10                         ; 10 = 1, 0
  JP NZ, ds_lv4_add_to_score_end ;

ds_lv4_add_to_score_loop:
  LD a, 0                       ; 
  LD (hl), a                    ;

  DEC hl                        ; Next digit
  INC (hl)                      ;

  LD a, (hl)                    ;
  CP 10                         ; 10 = 1, 0
  JP NZ, ds_lv4_add_to_score_end ;

  DEC b                         ;
  JP NZ, ds_lv4_add_to_score_loop ;
 
ds_lv4_add_to_score_end:
  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; pig_got_hit_lv4 (149 lines) 
;
; Did pig get hit?
;    Decrement health
;    Set pig invincibility counter
;    Decrement counter
;    If counter is 0, can get hit again
;----------------------------------------
pig_got_hit_lv4:
  LD a, (RAM_VPOS + 1)          ;
  LD (RAM_COLL_Y1), a           ; Pig Y
  LD a, (RAM_HPOS + 2)          ;
  LD (RAM_COLL_X1), a           ; Pig X

;-----------------------------------
; Foe 1
  LD a, (RAM_FOE_1_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, pghlv4_skip_002        ;

  LD a, (RAM_VPOS + 12)         ;
  LD (RAM_COLL_Y2), a           ; Foe 1 Y
  LD a, (RAM_HPOS + 24)         ;
  LD (RAM_COLL_X2), a           ; Foe 1 X
  CALL xy_collision_detect16    ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, pghlv4_skip_002        ;

  CALL decrement_health_lv4     ;
  LD hl, vpos_sprites_level_4 + 12 ; Y respawn
  LD de, RAM_VPOS + 12          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 24 ; X respawn
  LD de, RAM_HPOS + 24          ;
  CALL copy_4_hpos_lv4          ;
pghlv4_skip_002:

;-----------------------------------
; Foe 2
  LD a, (RAM_FOE_2_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, pghlv4_skip_003        ;

  LD a, (RAM_VPOS + 16)         ;
  LD (RAM_COLL_Y2), a           ; Foe 1 Y
  LD a, (RAM_HPOS + 32)         ;
  LD (RAM_COLL_X2), a           ; Foe 1 X
  CALL xy_collision_detect16    ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, pghlv4_skip_003        ;

  CALL decrement_health_lv4     ;
  LD hl, vpos_sprites_level_4 + 16 ; Y respawn
  LD de, RAM_VPOS + 16          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 32 ; X respawn
  LD de, RAM_HPOS + 32          ;
  CALL copy_4_hpos_lv4          ;
pghlv4_skip_003:

;-----------------------------------
; Foe 3
  LD a, (RAM_FOE_3_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, pghlv4_skip_004        ;

  LD a, (RAM_VPOS + 20)         ;
  LD (RAM_COLL_Y2), a           ; Foe 1 Y
  LD a, (RAM_HPOS + 40)         ;
  LD (RAM_COLL_X2), a           ; Foe 1 X
  CALL xy_collision_detect16    ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, pghlv4_skip_004        ;

  CALL decrement_health_lv4     ;
  LD hl, vpos_sprites_level_4 + 20 ; Y respawn
  LD de, RAM_VPOS + 20          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 40 ; X respawn
  LD de, RAM_HPOS + 40          ;
  CALL copy_4_hpos_lv4          ;
pghlv4_skip_004:

;-----------------------------------
; Foe 4
  LD a, (RAM_FOE_4_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, pghlv4_skip_005        ;

  LD a, (RAM_VPOS + 24)         ;
  LD (RAM_COLL_Y2), a           ; Foe 1 Y
  LD a, (RAM_HPOS + 48)         ;
  LD (RAM_COLL_X2), a           ; Foe 1 X
  CALL xy_collision_detect16    ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, pghlv4_skip_005        ;

  CALL decrement_health_lv4     ;
  LD hl, vpos_sprites_level_4 + 24 ; Y respawn
  LD de, RAM_VPOS + 24          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 48 ; X respawn
  LD de, RAM_HPOS + 48          ;
  CALL copy_4_hpos_lv4          ;
pghlv4_skip_005:

;-----------------------------------
; Foe 5
  LD a, (RAM_FOE_5_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, pghlv4_skip_006        ;

  LD a, (RAM_VPOS + 28)         ;
  LD (RAM_COLL_Y2), a           ; Foe 1 Y
  LD a, (RAM_HPOS + 56)         ;
  LD (RAM_COLL_X2), a           ; Foe 1 X
  CALL xy_collision_detect16    ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, pghlv4_skip_006        ;

  CALL decrement_health_lv4     ;
  LD hl, vpos_sprites_level_4 + 28 ; Y respawn
  LD de, RAM_VPOS + 28          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 56 ; X respawn
  LD de, RAM_HPOS + 56          ;
  CALL copy_4_hpos_lv4          ;
pghlv4_skip_006:

;-----------------------------------
; Foe 6
  LD a, (RAM_FOE_6_COUNT)       ; Hit occured in this frame 
  CP 0                          ;
  JP NZ, pghlv4_skip_007        ;

  LD a, (RAM_VPOS + 32)         ;
  LD (RAM_COLL_Y2), a           ; Foe 1 Y
  LD a, (RAM_HPOS + 64)         ;
  LD (RAM_COLL_X2), a           ; Foe 1 X
  CALL xy_collision_detect16    ;

  LD a, (RAM_COLL_RESULT)       ; Hit? 
  CP $7F                        ;
  JP NZ, pghlv4_skip_007        ;

  CALL decrement_health_lv4     ;
  LD hl, vpos_sprites_level_4 + 32 ; Y respawn
  LD de, RAM_VPOS + 32          ;
  CALL copy_4_vpos_lv4          ;
  LD hl, hpos_sprites_level_4 + 64 ; X respawn
  LD de, RAM_HPOS + 64          ;
  CALL copy_4_hpos_lv4          ;
pghlv4_skip_007:
  RET                           ; End subroutine 
;----------------------------------------

;----------------------------------------
; decrement_health_lv4 (14 lines)
;
; Health goes down by 1.
;----------------------------------------
decrement_health_lv4:
  LD a, (RAM_PIG_BLINK)      ;
  CP $00                     ;
  JP NZ, dhlv4_skip_000      ;

  CALL copy_song_to_RAM004   ; Ouch

  LD a, (RAM_HEALTH_1)       ; Health 1
  DEC a                      ;
  CP $00                     ; At 0 health?
  JP Z, dhlv4_game_over      ;
  LD (RAM_HEALTH_1), a       ;
  LD a, 60                   ; 2 second pig blink
  LD (RAM_PIG_BLINK), a      ;
  JP  dhlv4_skip_000         ;

dhlv4_game_over
  LD a, STATE_GAME_OVER      ;
  LD (RAM_GAME_STATE), a     ;
dhlv4_skip_000:
  RET                        ; End subroutine 
;----------------------------------------


background_004:
.include "ppolis_level4_BG.inc"

tiles_004:
.include "ppolis_level4_T.inc"


;----------------------------------------------------------
; level_4_load_002 (17 lines)
level_4_load_002:
   PUSH AF                     ;

   CALL VDP_off                ; Stop VDP

   CALL set_initial_sprites_level_4end ; Set up sprites
   CALL sprites_to_VRAM        ;

   LD a, $01                   ; 11 second timer
   LD (RAM_TIME_1), a          ; Time 1
   LD (RAM_TIME_2), a          ; Time 2

   LD a, $00                   ; Set bouncing
   LD (RAM_FOE_1_STATE), a     ;
   LD a, $01                   ;
   LD (RAM_FOE_2_STATE), a     ;
   LD a, $02                   ;
   LD (RAM_FOE_3_STATE), a     ;
   LD a, $03                   ;
   LD (RAM_FOE_4_STATE), a     ;

   LD a, STATE_END_RUN         ; Go to next state
   LD (RAM_GAME_STATE), a      ;

   LD a, $00                  ; Prevent light gun from being read 
   LD (RAM_END_TRIGGER_READY), a ; until timer ends.

   LD a, $7F                   ; Enable scrolling
   LD (RAM_ENABLE_SCROLLING), a ;

   CALL VDP_on                 ; Start VDP

   POP AF                      ;
   RET                         ; End subroutine 
;----------------------------------------------------------

;----------------------------------------------------------
; level_4_run_004end (26 lines)
;
; Wait 10 seconds.
; Any trigger press after that restarts game.
;----------------------------------------------------------
level_4_run_end:
; Copy sprites from RAM to VRAM
   CALL sprites_to_VRAM        ; Copy sprites to VRAM
   CALL level_4_poo_blink      ; Animated tile

; Run everything that does not use VRAM
   CALL move_foes_level_4end   ; Flap pig wings
   CALL pig_flight_level_4     ; Flap pig wings
   CALL run_timer_level_4end   ; Count down to 00. At 00, accept trigger

; Run until trigger is pulled.
; Wait for player to press trigger to 
; return to title screen.
   LD a, (RAM_END_TRIGGER_READY) ; Let timer expire
   CP $7F                      ;
   JP NZ, level_4_run_004_end  ;
   LD a, (RAM_LIGHT_GUN_READ)  ; Light gun trigger pressed?
   CP $7F                      ;
   JP NZ, level_4_run_004_end  ;

   CALL VDP_off                ; Stop VDP

   LD hl, $C000                ;
   LD b, 255                   ;
   CALL tool_clear_RAM_loop    ; Clear working RAM
   CALL clear_vram             ; Clear VRAM
   CALL clear_palette_data     ; Clear palette data
   CALL intro_load_sprites     ; Load intro sprites
   CALL load_tile_data_000     ; Load tile data
   CALL load_bg_data_000       ;
   CALL load_palette_data_000  ; Load colors

   LD a, STATE_INTRO           ; Go to next state
   LD (RAM_GAME_STATE), a      ;

   CALL copy_song_to_RAM       ; Load sound

   CALL VDP_on                 ; Start VDP

level_4_run_004_end:
   RET                         ; End subroutine 
;----------------------------------------------------------

;---------------------------------------
; set_initial_sprites_level_4end (10 lines)
;
; Copy initial sprite values to RAM.
;---------------------------------------
set_initial_sprites_level_4end:
   LD hl, vpos_sprites_level_4end ; VPOS
   LD de, RAM_VPOS            ; 
   LD bc, 45                  ;
   LDIR                       ;

   LD hl, hpos_sprites_level_4end ; HPOS, TILE
   LD de, RAM_HPOS            ; 
   LD bc, 89                  ;
   LDIR                       ;

   RET                        ; End subroutine 
;---------------------------------------

vpos_sprites_level_4end:
.db $70 ; Pig 00
.db $70 ;
.db $70 ;
.db $70 ;
.db $78 ; 
.db $78 ;
.db $78 ;
.db $78 ;

.db $00 ; Shot 1 8
.db $00 ;
.db $08 ;
.db $08 ;

.db $60 ; Pig 01
.db $60 ;
.db $60 ;
.db $60 ;
.db $68 ; 
.db $68 ;
.db $68 ;
.db $68 ;

.db $50 ; Pig 02
.db $50 ;
.db $50 ;
.db $50 ;
.db $58 ; 
.db $58 ;
.db $58 ;
.db $58 ;

.db $80 ; Pig 03
.db $80 ;
.db $80 ;
.db $80 ;
.db $88 ; 
.db $88 ;
.db $88 ;
.db $88 ;

.db $90 ; Pig 04
.db $90 ;
.db $90 ;
.db $90 ;
.db $98 ; 
.db $98 ;
.db $98 ;
.db $98 ;
.db $D0 ; Delimiter

hpos_sprites_level_4end:
.db $70, $01 ; Pig 00
.db $78, $02 ;
.db $80, $03 ;
.db $88, $04 ;
.db $70, $13 ; 
.db $78, $14 ;
.db $80, $15 ;
.db $88, $00 ;

.db $00, $27 ; Shot 1 16
.db $08, $28 ;
.db $00, $3B ;
.db $08, $3C ;

.db $70, $01 ; Pig 01
.db $78, $02 ;
.db $80, $03 ;
.db $88, $04 ;
.db $70, $13 ; 
.db $78, $14 ;
.db $80, $15 ;
.db $88, $00 ;

.db $70, $01 ; Pig 02
.db $78, $02 ;
.db $80, $03 ;
.db $88, $04 ;
.db $70, $13 ; 
.db $78, $14 ;
.db $80, $15 ;
.db $88, $00 ;

.db $70, $01 ; Pig 03
.db $78, $02 ;
.db $80, $03 ;
.db $88, $04 ;
.db $70, $13 ; 
.db $78, $14 ;
.db $80, $15 ;
.db $88, $00 ;

.db $70, $01 ; Pig 04
.db $78, $02 ;
.db $80, $03 ;
.db $88, $04 ;
.db $70, $13 ; 
.db $78, $14 ;
.db $80, $15 ;
.db $88, $00 ;

.db $D0 ; Delimiter

;------------------------------------------
; move_foes_level_4end (261 lines)
;
;------------------------------------------
move_foes_level_4end:
; Pig 01 - move
mflv4e_next_001:
  LD hl, RAM_HPOS + 24          ;
  CALL pig_flight_level_4end    ;

  LD a, (RAM_FOE_1_STATE)       ;
  CP $00                        ;
  JP Z, mflv4e_downright_001    ;
  CP $01                        ;
  JP Z, mflv4e_downleft_001     ;
  CP $02                        ;
  JP Z, mflv4e_upleft_001       ;
  CP $03                        ;
  JP Z, mflv4e_upright_001      ;

mflv4e_downright_001:
  LD hl, RAM_VPOS + 12          ; Down
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 24          ; Right
  CALL lv4_right_subroutine     ;
  LD hl, RAM_VPOS + 16          ; Down
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 32          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 32)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4e_next_002        ;
  LD a, $01                     ;
  LD (RAM_FOE_1_STATE), a       ; Change state
  JP mflv4e_next_002            ;

mflv4e_downleft_001:
  LD hl, RAM_VPOS + 12          ;
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 24          ;
  CALL lv4_left_subroutine      ;
  LD hl, RAM_VPOS + 16          ;
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 32          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 12)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4e_next_002        ;
  LD a, $02                     ;
  LD (RAM_FOE_1_STATE), a       ; Change state
  JP mflv4e_next_002            ;

mflv4e_upleft_001:
  LD hl, RAM_VPOS + 12          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 24          ;
  CALL lv4_left_subroutine      ;
  LD hl, RAM_VPOS + 16          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 32          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 24)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4e_next_002        ;
  LD a, $03                     ;
  LD (RAM_FOE_1_STATE), a       ; Change state
  JP mflv4e_next_002            ;

mflv4e_upright_001:
  LD hl, RAM_VPOS + 12          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 24          ;
  CALL lv4_right_subroutine     ;
  LD hl, RAM_VPOS + 16          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 32          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 12)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4e_next_002        ;
  LD a, $00                     ;
  LD (RAM_FOE_1_STATE), a       ; Change state
  JP mflv4e_next_002            ;


;------------------------------------------
; Pig 2 - move
mflv4e_next_002:
  LD hl, RAM_HPOS + 40          ;
  CALL pig_flight_level_4end    ;

  LD a, (RAM_FOE_2_STATE)       ;
  CP $00                        ;
  JP Z, mflv4e_downright_002    ;
  CP $01                        ;
  JP Z, mflv4e_downleft_002     ;
  CP $02                        ;
  JP Z, mflv4e_upleft_002       ;
  CP $03                        ;
  JP Z, mflv4e_upright_002      ;

mflv4e_downright_002:
  LD hl, RAM_VPOS + 20          ; Down
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 40          ; Right
  CALL lv4_right_subroutine     ;
  LD hl, RAM_VPOS + 24          ; Down
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 48          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 48)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4e_next_003        ;
  LD a, $01                     ;
  LD (RAM_FOE_2_STATE), a       ; Change state
  JP mflv4e_next_003            ;

mflv4e_downleft_002:
  LD hl, RAM_VPOS + 20          ;
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 40          ;
  CALL lv4_left_subroutine      ;
  LD hl, RAM_VPOS + 24          ;
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 48          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 20)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4e_next_003        ;
  LD a, $02                     ;
  LD (RAM_FOE_2_STATE), a       ; Change state
  JP mflv4e_next_003            ;

mflv4e_upleft_002:
  LD hl, RAM_VPOS + 20          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 40          ;
  CALL lv4_left_subroutine      ;
  LD hl, RAM_VPOS + 24          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 48          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 40)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4e_next_003        ;
  LD a, $03                     ;
  LD (RAM_FOE_2_STATE), a       ; Change state
  JP mflv4e_next_003            ;

mflv4e_upright_002:
  LD hl, RAM_VPOS + 20          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 40          ;
  CALL lv4_right_subroutine     ;
  LD hl, RAM_VPOS + 24          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 48          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 20)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4e_next_003        ;
  LD a, $00                     ;
  LD (RAM_FOE_2_STATE), a       ; Change state
  JP mflv4e_next_003            ;


;------------------------------------------
; Pig 3 - move
mflv4e_next_003:
  LD hl, RAM_HPOS + 56          ;
  CALL pig_flight_level_4end    ;

  LD a, (RAM_FOE_3_STATE)       ;
  CP $00                        ;
  JP Z, mflv4e_downright_003    ;
  CP $01                        ;
  JP Z, mflv4e_downleft_003     ;
  CP $02                        ;
  JP Z, mflv4e_upleft_003       ;
  CP $03                        ;
  JP Z, mflv4e_upright_003      ;

mflv4e_downright_003:
  LD hl, RAM_VPOS + 28          ; Down
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 56          ; Right
  CALL lv4_right_subroutine     ;
  LD hl, RAM_VPOS + 32          ; Down
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 64          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 64)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4e_next_004        ;
  LD a, $01                     ;
  LD (RAM_FOE_3_STATE), a       ; Change state
  JP mflv4e_next_004            ;

mflv4e_downleft_003:
  LD hl, RAM_VPOS + 28          ;
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 56          ;
  CALL lv4_left_subroutine      ;
  LD hl, RAM_VPOS + 32          ;
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 64          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 28)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4e_next_004        ;
  LD a, $02                     ;
  LD (RAM_FOE_3_STATE), a       ; Change state
  JP mflv4e_next_004            ;

mflv4e_upleft_003:
  LD hl, RAM_VPOS + 28          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 56          ;
  CALL lv4_left_subroutine      ;
  LD hl, RAM_VPOS + 32          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 64          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 64)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4e_next_004        ;
  LD a, $03                     ;
  LD (RAM_FOE_3_STATE), a       ; Change state
  JP mflv4e_next_004            ;

mflv4e_upright_003:
  LD hl, RAM_VPOS + 28          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 56          ;
  CALL lv4_right_subroutine     ;
  LD hl, RAM_VPOS + 32          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 64          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 28)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4e_next_004        ;
  LD a, $00                     ;
  LD (RAM_FOE_3_STATE), a       ; Change state
  JP mflv4e_next_004            ;


;------------------------------------------
; Pig 4 - move
mflv4e_next_004:
  LD hl, RAM_HPOS + 72          ;
  CALL pig_flight_level_4end    ;

  LD a, (RAM_FOE_4_STATE)       ;
  CP $00                        ;
  JP Z, mflv4e_downright_004    ;
  CP $01                        ;
  JP Z, mflv4e_downleft_004     ;
  CP $02                        ;
  JP Z, mflv4e_upleft_004       ;
  CP $03                        ;
  JP Z, mflv4e_upright_004      ;

mflv4e_downright_004:
  LD hl, RAM_VPOS + 36          ; Down
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 72          ; Right
  CALL lv4_right_subroutine     ;
  LD hl, RAM_VPOS + 40          ; Down
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 80          ; Right
  CALL lv4_right_subroutine     ;
  LD a, (RAM_HPOS + 80)         ; Hit right wall?
  CP $E0                        ;
  JP NZ, mflv4e_next_005        ;
  LD a, $01                     ;
  LD (RAM_FOE_4_STATE), a       ; Change state
  JP mflv4e_next_005            ;

mflv4e_downleft_004:
  LD hl, RAM_VPOS + 36          ;
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 72          ;
  CALL lv4_left_subroutine      ;
  LD hl, RAM_VPOS + 40          ;
  CALL lv4_down_subroutine2     ;
  LD hl, RAM_HPOS + 80          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_VPOS + 36)         ; Hit floor?
  CP $C0                        ;
  JP NZ, mflv4e_next_005        ;
  LD a, $02                     ;
  LD (RAM_FOE_4_STATE), a       ; Change state
  JP mflv4e_next_005            ;

mflv4e_upleft_004:
  LD hl, RAM_VPOS + 36          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 72          ;
  CALL lv4_left_subroutine      ;
  LD hl, RAM_VPOS + 40          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 80          ;
  CALL lv4_left_subroutine      ;
  LD a, (RAM_HPOS + 72)         ; Hit left wall?
  CP $10                        ;
  JP NZ, mflv4e_next_005        ;
  LD a, $03                     ;
  LD (RAM_FOE_4_STATE), a       ; Change state
  JP mflv4e_next_005            ;

mflv4e_upright_004:
  LD hl, RAM_VPOS + 36          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 72          ;
  CALL lv4_right_subroutine     ;
  LD hl, RAM_VPOS + 40          ;
  CALL lv4_up_subroutine2       ;
  LD hl, RAM_HPOS + 80          ;
  CALL lv4_right_subroutine     ;
  LD a, (RAM_VPOS + 36)         ; Hit ceiling?
  CP $20                        ;
  JP NZ, mflv4e_next_005        ;
  LD a, $00                     ;
  LD (RAM_FOE_4_STATE), a       ; Change state
  JP mflv4e_next_005            ;


;------------------------------------------
; Pig 4 - move
mflv4e_next_005:

  RET                           ; End subroutine 
;---------------------------------------

;---------------------------------------
; pig_flight_level_4end (117 lines)
;
; Make the pigs fly.
; Set HL to RAM_HPOS first!
;---------------------------------------
pig_flight_level_4end:
   INC hl                     ;
   LD a, (RAM_FRAME_CTR)      ; Frame counter
   CP 0                       ; flap
   JP Z, pflv4e_000           ;
   CP 15                      ; flap
   JP Z, pflv4e_001           ;
   CP 30                      ; flap
   JP Z, pflv4e_002           ;
   CP 45                      ; flap
   JP Z, pflv4e_001           ;
   JP pflv4e_end              ;

; High wing
pflv4e_000:
   LD a, $01                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $02                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $03                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $04                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $13                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $14                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $15                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP pflv4e_end              ;

; Middle wing
pflv4e_001:
   LD a, $05                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $06                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $03                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $07                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $16                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $17                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $15                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;
   JP pflv4e_end              ;

; Low wing
pflv4e_002:
   LD a, $08                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $09                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $03                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $04                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $18                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $19                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $15                  ;
   LD (hl), a                 ;
   INC hl                     ;
   INC hl                     ;
   LD a, $00                  ;
   LD (hl), a                 ;

pflv4e_end:
   RET                        ; End subroutine 
;---------------------------------------

;---------------------------------------
; run_timer_level_4end (18 lines)
;
; Count down the timer digits.
;---------------------------------------
run_timer_level_4end:
   LD a, (RAM_FRAME_CTR)      ; Frame counter
   CP 59                      ; 60 frames per second
   JP NZ, rtlv4e_skip_000     ;

   LD a, (RAM_TIME_2)         ; Time 2
   DEC a                      ;
   LD (RAM_TIME_2), a         ;

   CP $FF                     ; at -1? 
   JP NZ, rtlv4e_skip_000     ;

   LD a, $09                  ;
   LD (RAM_TIME_2), a         ;

   LD a, (RAM_TIME_1)         ; Time 2
   DEC a                      ;
   LD (RAM_TIME_1), a         ;

   CP $FF                     ; at -1? 
   JP NZ, rtlv4e_skip_000     ;

   LD a, $7F                  ; Prevent light gun from being read 
   LD (RAM_END_TRIGGER_READY), a ; until timer ends.

rtlv4e_skip_000:
   RET                        ; End subroutine 
;---------------------------------------

;---------------------------------------
; level_4_poo_blink (23 lines)
;
; Make tile $B0 animated.
;
;---------------------------------------
level_4_poo_blink:
   LD a, (RAM_FRAME_CTR)      ;
   AND $07                    ;
   CP $00                     ; Only 8 per second
   JP NZ, lv4pb_end_000       ; 

   LD hl, poo_blink_table     ; Load base address
   LD de, $0000               ;
   LD a, (RAM_COLOR_INDEX)    ; Load color index    
   LD e, a                    ;
   ADD hl, de                 ;

   LD a, $FF                  ; Low address byte
   OUT (VDP_ADDR),a           ;
   LD a, $15                  ; High address byte
   OUT (VDP_ADDR),a           ;   
   
   LD b, 32                   ;
lv4pb_loop:
   LD a, (hl)                 ; Copy tile data
   OUT (VDP_DATA), a          ;
   INC hl                     ;
   DEC b                      ;
   JP NZ, lv4pb_loop          ;

   LD a, (RAM_COLOR_INDEX)    ; Load color index
   ADD a, 4                   ; Increment by 4
   AND $1F                    ; Maximum is 31
   LD (RAM_COLOR_INDEX), a    ;

lv4pb_end_000:
   RET                        ; End subroutine 
;---------------------------------------

poo_blink_table:
.db $DB $3C $00 $00 $E7 $99 $42 $00 $7E $C3 $24 $00 $BD $66 $18 $00 $DB $3C $81 $00 $E7 $99 $42 $00 $7E $C3 $24 $00 $BD $66 $18 $00
.db $DB $3C $00 $00 $E7 $99 $42 $00 $7E $C3 $24 $00 $BD $66 $18 $00 $DB $3C $81 $00 $E7 $99 $42 $00 $7E $C3 $24 $00 $BD $66 $18 $00



