; -------------------------------------------------------------;
;                          MR. ULTRA                           ;
; -------------------------------------------------------------;

.sdsctag 0.1, "Mr. Ultra", "Mr. Ultra", "Bologna S. Stupid"

.memorymap
       defaultslot 0
       slotsize $4000
       slot 0 $0000        ; rom bank 0 (0-16 kb).
       slot 1 $4000        ; rom bank 1 (16-32 kb).
       slot 2 $8000
      ; slotsize $100 ; RAM
       slot 3 $c000

.endme

.rombankmap
           bankstotal 4
           banksize $4000 ; 16kb
           banks 4
.endro

.equ   vspeed 7            ; players' vertical speed.
.equ   hspeed 3            ; horiz. speed of player and enemy.
.equ   rightb $dc          ; right border of the road.
.equ   leftb $14           ; left border of the road.

; Map of the sprite attribute table (sat) buffer.
; Contains sprites' vertical position (vpos), horizontal posi-
; tion (hpos) and character codes (cc).

.equ livesvp $c004
.equ liveshp $c088
.equ livescc $c089

.equ plrvp $c008           ; mr. ultra vpos.
.equ plrhp $c090           ; mr. ultra hpos.
.equ plrcc $c091           ; mr. ultra cc.

.equ cloudvp $c018           ; cloud vpos.
.equ cloudhp $c0b0           ; cloud hpos.
.equ cloudcc $c0b1           ; cloud cc.

.equ cloud2vp $c028           ; second cloud vpos.
.equ cloud2hp $c0d0           ; second cloud hpos.
.equ cloud2cc $c0d1           ; second cloud cc.


.equ endspr $c038          ; first unused sprite.

 ; Organize ram - create the sat buffer and variables.

.enum $c000 export         ; export labels to symbol file.

       satbuf dsb 256      ; sprite attribute table buffer.
                           ; see the map for object offsets.


       input db            ; input from player 1 controller.
       iflag db
       frame db            ; frame counter.
       status db           ; vdp status (for collision detect.).

       cloudy db              ; Player y.
       cloudx db              ; Player x

       cloud2y db              ; Player y.
       cloud2x db              ; Player x

       thi db
       event   db
       bananaevent  db
       enemyframe   db
       enemycollision  db
       enemyycollision db

       level db
       icetimer db
       lives db

       playintro db           ; is intro being played?
       jumping db             ; is player jumping?
       falling db               ; is player falling?

       ply db              ; Player y.
       plx db              ; Player x.
.ende

.bank 0 slot 0
.org 0
       di                  ; disable interrupts.
       im 1                ; interrupt mode 1.
       ld sp,$dff0         ; default stack pointer address.
       jp inigam           ; initialize game.

; Read the vdp status flag at every frame interrupt.
; Sprite collision is read from bit 5 of the status flag.

.orga $0038                ; frame interrupt address.
        ex af,af'           ; save accumulator in its shadow reg.
        in a,$bf            ; get vdp status / satisfy interrupt. 
        ld (status),a       ; save vdp status in ram.
        ld a,1              ; load accumulator with raised flag.
        ld (iflag),a        ; set interrupt flag. 
        ex af,af'           ; restore accumulator. 
        ei                  ; enable interrupts.
        reti                ; return from interrupt.

; Disable the pause button - this is an unforgiving game!

.orga $0066                ; pause button interrupt.
       retn                ; disable pause button.

; Initialize game.
; Overwrite the first 4 kb of ram with zeroes.



inigam 


       ld hl,$c000         ; point to beginning of ram.
       ld bc,$1000         ; 4 kb to fill.
       ld a,0              ; with value 0.
       call mfill          ; do it!

; Use the initialized ram to clean all of vram.

       ld hl,$0000         ; prepare vram for data at $0000.
       call vrampr
       ld b,4              ; write 4 x 4 kb = 16 kb.
-      push bc             ; save the countter.
       ld hl,$c000         ; source = freshly initialized ram.
       ld bc,$1000         ; 4 kb of zeroes.
       call vramwr         ; purge vram.
       pop bc              ; retrieve counter.
       djnz -


; Load various assets into vram.

stopcurrentmusic
       call PSGStop

title_screen
    


       ld hl,$2000         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,pltile1        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,cloudtile     ; cloud tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 288.
       call vrampr         ; prepare vram.
       ld hl,cloudtile2
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write crashed player tiles to vram.


       ld hl,$c000         ; color bank 2, color 0.
       call vrampr         ; prepare vram.
       ld hl,bgpal         ; background palette.
       ld bc,32            ; 4 colors.
       call vramwr         ; set background palette.

       ld hl,$c020         ; color bank 2, color 0 (sprites).
       call vrampr         ; prepare vram.
       ld hl,plpal         ; sprite palette data.
       ld bc,32            ; 5 colors.
       call vramwr         ; set sprite palette.

; Initialize variables - once per game.

       ld a,97           ;
       ld (ply),a          ; set player y.

       ld a,50           ;
       ld (cloudy),a          ; set player y.

       ld a,50           ;
       ld (cloud2y),a          ; set player y.



       ld a,0            ;
       ld (playintro),a          ; set player y.

; Initialize the VDP registers.

       ld hl,regdat        ; point to register init data.
       ld b,11             ; 11 bytes of register data.
       ld c,$80            ; VDP register command byte.

-:     ld a,(hl)           ; load one byte  of data into A.
       out ($bf),a         ; output data to VDP command port.
       ld a,c              ; load the command byte.
       out ($bf),a         ; output it to the VDP command port.
       inc hl              ; inc. pointer to next byte of data.
       inc c               ; inc. command byte to next register.
       djnz -              ; jump back to '-' if b > 0.

; Load assets for main loop.
  
; Setup the background assets for the main loop.

       ; always put a blank tile for the first tile of the bgmap. The player graphics rely on that.
       ld hl,$0000         ; first tile @ index 0.
       call vrampr         ; prepare vram.
       ld hl,bgtile        ; background tile data (the road).
       ld bc,77*32         ; each tile is 32 bytes.
       call vramwr         ; write background tiles to vram.

       ld hl,$3800         ; point to name table.
       call vrampr         ; prepare vram.
       ld hl,bgmap         ; point to background tilemap data.
       ld bc,32*28*2       ; 32 x 28 tiles, each is 2 bytes.
       call vramwr         ; write name table to vram.

; Put the sprites in.



       ld de,plrcc         ; point to player cc in buffer.
       ld hl,plrcar        ; point to player car graphics.
       call carcc          ; set the char codes for player car.

       ld a,79             ; player starts at the road's center.
       ld (plx),a          ; set x-coordinate.



       ld de,cloudcc       ; point to player cc in buffer.
       ld hl,plrhole       ; point to player car graphics.
       call cloud1cc        ; set the char codes for player car.

       ld a,89             ; player starts at the road's center.
       ld (cloudx),a       ; set x-coordinate.

       ld de,cloud2cc       ; point to player cc in buffer.
       ld hl,plrhole      ; point to player car graphics.
       call cloud1cc        ; set the char codes for player car.

       ld a,97            ; player starts at the road's center.
       ld (cloud2x),a       ; set x-coordinate.

      ; xor a               ; set A = 0.
      ; ld (scroll),a       ; reset scroll register buffer.
       ;ld (frame),a        ; reset frame counter.

       ld hl,endspr        ; point to end of active sprites.
       ld (hl),$d0         ; insert sprite terminator here.



       call upbuf         ; update buffer for cars and digits.

       ei                  ; enable frame interrupt (vblank).
       halt                ; wait for it to happen...
       call ldsat          ; load sat from buffer.

       ld a,%11100000      ; turn screen on - normal sprites.
       ld b,1
       call setreg         ; set register 1.

       call PSGInit

       ld hl,titlescreenmusic
       call PSGPlay


; This is the main loop.

mloop


     halt                ; start main loop with vblank.




; Update vdp right when vblank begins!

      ; ld a,(scroll)       ; 1-byte scroll reg. buffer in ram.
      ; ld b,9              ; target VDP register 9 (v-scroll).
      ; call setreg         ; now vdp register = buffer, and the
                           ; screen scrolls accordingly.

       call ldsat          ; load sat buffer to vram. The cars
                           ; and the (hi)-score sprites are
                           ; updated on the screen.


       call PSGFrame



       ld a,(playintro)
       cp 1
       jp nc,mp1           ; yes - skip to left test.

       ld a,(cloudx)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloudx),a          ; update player x-coordinate.

       ld a,(cloud2x)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloud2x),a          ; update player x-coordinate.

       in     a,($00)
       ;cpl                    ; invert logic so 1 = pressed
       and    %10000000

       jp nz,endchk           ; no - test for left key.




mp1
       ld a,(plx)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (plx),a          ; update player x-coordinate.

       ld a,(plx)          ; get player's hpos (x-coordinate).
       cp rightb           ; is player over thr right border?
       jp nc,begin_level_1          ; yes - start game


       ld a,1             ; player starts at the road's center.
       ld (playintro),a       ; set x-coordinate.


endchk                     ; end key check

       ld a,(frame)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (frame),a          ; update player x-coordinate.

       ld a,(frame)          ; get player's hpos (x-coordinate).
       cp 10          ; is player over thr right border?
       jp nc,anim2          ; yes - skip to left test.


       ld hl,$2000         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,pltile1        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       jp endofanim

anim2
       ld hl,$2000         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,pltile2        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       ld a,(frame)          ; get player's hpos (x-coordinate).
       cp 20          ; is player over thr right border?
       jp c,endofanim          ; yes - skip to left test.

       ld a,1             ; player starts at the road's center.
       ld (frame),a       ; set x-coordinate.


endofanim
; Update player sprites in the buffer.

       ld a,3          ;
       ld (lives),a          ; set player y.

       ld hl,$2600         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,two           ; player car tile data.
       ld bc,1*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.


       call upbuf          ; update sat buffer.

; Scroll background - update the vertical scroll buffer.

      ; ld a,(scroll)       ; get scroll buffer value.
      ; sub vspeed          ; subtract vertical speed.
      ; ld (scroll),a       ; update scroll buffer.

       jp mloop            ; jump back for another round.

begin_level_1
       call PSGStop



       ld a,1          ;
       ld (level),a          ; set player y.


       ld a,5          ;
       ld (level),a          ; set player y.



        jp begin_level_5


       ; jp begin_level_2

       ; jp begin_level_4
       

       ld hl,level1music
       call PSGPlay


       xor a
       ld (iflag),a

; Setup the background assets for the main loop.
       ld a,97           ;
       ld (ply),a          ; set player y.

       ld a,0            ; player starts at the road's center.
       ld (jumping),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (falling),a       ; set x-coordinate.



       ld hl,$c000         ; color bank 1, color 0.
       call vrampr         ; prepare vram.
       ld hl,bgpal         ; background palette.
       ld bc,15             ; 4 colors.
       call vramwr         ; set background palette.

       ld hl,$0000         ; first tile @ index 0.
       call vrampr         ; prepare vram.
       ld hl,level1bgtile        ; background tile data (the road).
       ld bc,77*32          ; 2 tiles (!), each tile is 32 bytes.
       call vramwr         ; write background tiles to vram.

       ld hl,$3800         ; point to name table.
       call vrampr         ; prepare vram.
       ld hl,level1bgmap        ; point to background tilemap data.
       ld bc,32*28*2       ; 32 x 28 tiles, each is 2 bytes.
       call vramwr         ; write name table to vram.

       ld de,livescc       ; point to player cc in buffer.
       ld hl,lifenumber    ; point to player car graphics.
       call carcc          ; set the char codes for player car.

       ld de,plrcc         ; point to player cc in buffer.
       ld hl,plrcar        ; point to player car graphics.
       call carcc          ; set the char codes for player car.

       ld a,80             ; player starts at the road's center.
       ld (plx),a          ; set x-coordinate.

; Put the sprites in.


       ld a,0            ; player starts at the road's center.
       ld (event),a       ; set x-coordinate.

       ;jp this_is_stupid





level1events


       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 4          ; is player over thr right border?
       jp nc,level4events      ; yes - skip to left test.
 
       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp nc,level3events      ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp nc,level2events      ; yes - skip to left test.





       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 20         ; is player over thr right border?
       jp nc,main_game      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 17                  ; is player over thr right border?
       jp nc,reintroduce_hole       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 18                  ; is player over thr right border?
       jp nc,reintroduce_hole       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 19         ; is player over thr right border?
       jp nc,reintroduce_bananas       ; yes - skip to left test.



       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp c,reintroduce_hole     ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp c,reintroduce_hole        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 4         ; is player over thr right border?
       jp c,reintroduce_bananas       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 5         ; is player over thr right border?
       jp c,reintroduce_hole         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 6         ; is player over thr right border?
       jp c,reintroduce_bananas       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 7         ; is player over thr right border?
       jp c,reintroduce_bananas       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 8         ; is player over thr right border?
       jp c,reintroduce_hole         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 9        ; is player over thr right border?
       jp c,reintroduce_hole       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 10         ; is player over thr right border?
       jp c,reintroduce_bananas       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 11                  ; is player over thr right border?
       jp c,reintroduce_hole       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 12         ; is player over thr right border?
       jp c,reintroduce_bananas       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 13         ; is player over thr right border?
       jp c,reintroduce_bananas       ; yes - skip to left test.
       
       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 14         ; is player over thr right border?
       jp c,reintroduce_bananas       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 15                  ; is player over thr right border?
       jp c,reintroduce_hole       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 16         ; is player over thr right border?
       jp nc,reintroduce_bananas       ; yes - skip to left test.



       jp reintroduce_hole

level2events
       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 20         ; is player over thr right border?
       jp nc,main_game      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 17                  ; is player over thr right border?
       jp nc,reintroduce_hole       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 18                  ; is player over thr right border?
       jp nc,reintroduce_celery       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 19         ; is player over thr right border?
       jp nc,reintroduce_celery        ; yes - skip to left test.
         ;----

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp c,reintroduce_celery     ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp c,reintroduce_hole        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 4         ; is player over thr right border?
       jp c,reintroduce_celery       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 5         ; is player over thr right border?
       jp c,reintroduce_celery         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 6         ; is player over thr right border?
       jp c,reintroduce_hole       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 7         ; is player over thr right border?
       jp c,reintroduce_celery       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 8         ; is player over thr right border?
       jp c,reintroduce_celery         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 9        ; is player over thr right border?
       jp c,reintroduce_hole       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 10         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 11                  ; is player over thr right border?
       jp c,reintroduce_celery       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 12         ; is player over thr right border?
       jp c,reintroduce_celery       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 13         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.
       
       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 14         ; is player over thr right border?
       jp c,reintroduce_celery        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 15                  ; is player over thr right border?
       jp c,reintroduce_celery      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 16         ; is player over thr right border?
       jp nc,reintroduce_hole       ; yes - skip to left test.



       jp reintroduce_hole

       ;=====
level3events
       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 20         ; is player over thr right border?
       jp nc,main_game      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 17                  ; is player over thr right border?
       jp nc,reintroduce_corn       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 18                  ; is player over thr right border?
       jp nc,reintroduce_corn       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 19         ; is player over thr right border?
       jp nc,reintroduce_hole      ; yes - skip to left test.
         ;----

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp c,reintroduce_hole     ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp c,reintroduce_corn        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 4         ; is player over thr right border?
       jp c,reintroduce_corn       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 5         ; is player over thr right border?
       jp c,reintroduce_hole        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 6         ; is player over thr right border?
       jp c,reintroduce_corn       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 7         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 8         ; is player over thr right border?
       jp c,reintroduce_hole        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 9        ; is player over thr right border?
       jp c,reintroduce_corn        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 10         ; is player over thr right border?
       jp c,reintroduce_corn      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 11                  ; is player over thr right border?
       jp c,reintroduce_hole     ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 12         ; is player over thr right border?
       jp c,reintroduce_corn        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 13         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.
       
       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 14         ; is player over thr right border?
       jp c,reintroduce_hole       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 15                  ; is player over thr right border?
       jp c,reintroduce_corn       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 16         ; is player over thr right border?
       jp nc,reintroduce_corn        ; yes - skip to left test.



       jp reintroduce_hole


       ;=====
level4events
       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 20         ; is player over thr right border?
       jp nc,main_game      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 17                  ; is player over thr right border?
       jp nc,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 18                  ; is player over thr right border?
       jp nc,reintroduce_pepper       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 19         ; is player over thr right border?
       jp nc,reintroduce_pepper      ; yes - skip to left test.
         ;----

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp c,reintroduce_pepper       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp c,reintroduce_pepper         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 4         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 5         ; is player over thr right border?
       jp c,reintroduce_pepper         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 6         ; is player over thr right border?
       jp c,reintroduce_pepper         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 7         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 8         ; is player over thr right border?
       jp c,reintroduce_pepper         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 9        ; is player over thr right border?
       jp c,reintroduce_pepper        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 10         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 11                  ; is player over thr right border?
       jp c,reintroduce_pepper      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 12         ; is player over thr right border?
       jp c,reintroduce_pepper        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 13         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.
       
       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 14         ; is player over thr right border?
       jp c,reintroduce_pepper        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 15                  ; is player over thr right border?
       jp c,reintroduce_pepper        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 16         ; is player over thr right border?
       jp nc,reintroduce_pepper         ; yes - skip to left test.



       jp reintroduce_hole



       ;=====
level5events
       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 20         ; is player over thr right border?
       jp nc,main_game      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 17                  ; is player over thr right border?
       jp nc,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 18                  ; is player over thr right border?
       jp nc,reintroduce_lettuce        ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 19         ; is player over thr right border?
       jp nc,reintroduce_lettuce        ; yes - skip to left test.
         ;----

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp c,reintroduce_lettuce         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp c,reintroduce_lettuce         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 4         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 5         ; is player over thr right border?
       jp c,reintroduce_lettuce           ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 6         ; is player over thr right border?
       jp c,reintroduce_lettuce         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 7         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 8         ; is player over thr right border?
       jp c,reintroduce_lettuce           ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 9        ; is player over thr right border?
       jp c,reintroduce_lettuce         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 10         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 11                  ; is player over thr right border?
       jp c,reintroduce_lettuce       ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 12         ; is player over thr right border?
       jp c,reintroduce_lettuce         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 13         ; is player over thr right border?
       jp c,reintroduce_hole      ; yes - skip to left test.
       
       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 14         ; is player over thr right border?
       jp c,reintroduce_lettuce          ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 15                  ; is player over thr right border?
       jp c,reintroduce_lettuce         ; yes - skip to left test.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 16         ; is player over thr right border?
       jp nc,reintroduce_lettuce       ; yes - skip to left test.



       jp reintroduce_hole

reintroduce_lettuce
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,lettucetile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,lettucetile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       jp food_pos

reintroduce_pepper
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,peppertile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,peppertile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       jp food_pos

reintroduce_corn
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,corntile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,corntile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       jp food_pos

reintroduce_celery
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,celerytile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,celerytile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       jp food_pos

reintroduce_bananas

       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,bananatile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,bananatile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.


food_pos
       ; Put the sprites in.
       ld a,210           ; player starts at the road's center.
       ld (cloudx),a       ; set x-coordinate.

       ld a,113        ; player starts at the road's center.
       ld (cloudy),a       ; set x-coordinate.

       ld a,218          ; player starts at the road's center.
       ld (cloud2x),a       ; set x-coordinate.

       ld a,113          ; player starts at the road's center.
       ld (cloud2y),a       ; set x-coordinate.



       ld a,1            ; player starts at the road's center.
       ld (bananaevent),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (enemyframe),a       ; set x-coordinate.


       ld a,24        ; player starts at the road's center.
       ld (cloudy),a       ; set x-coordinate.



       ld a,24          ; player starts at the road's center.
       ld (cloud2y),a       ; set x-coordinate.
       jp this_is_stupid




reintroduce_hole
       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 5         ; is player over thr right border?
       jp nc,hole_level_5     ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 4         ; is player over thr right border?
       jp nc,hole_level_1_and_4     ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 3         ; is player over thr right border?
       jp nc,hole_level_3     ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 2         ; is player over thr right border?
       jp nc,hole_level_2     ; yes - skip to left test.


hole_level_1_and_4
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holetile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holetile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       jp reintroduce_hole_2

hole_level_5
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel5tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel5tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       jp reintroduce_hole_2

hole_level_2
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel2tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel2tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       jp reintroduce_hole_2

hole_level_3
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel3tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel3tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.


reintroduce_hole_2
       ld a,0            ; player starts at the road's center.
       ld (enemyframe),a       ; set x-coordinate.

       ld a,210            ; player starts at the road's center.
       ld (cloudx),a       ; set x-coordinate.

       ld a,127         ; player starts at the road's center.
       ld (cloudy),a       ; set x-coordinate.

       ld a,218            ; player starts at the road's center.
       ld (cloud2x),a       ; set x-coordinate.

       ld a,127          ; player starts at the road's center.
       ld (cloud2y),a       ; set x-coordinate.


        ld a,0            ; player starts at the road's center.
       ld (bananaevent),a       ; set x-coordinate.



       ;jp main_game

this_is_stupid

       ;ld de,cloud2cc       ; point to player cc in buffer.
       ;ld hl,plrhole       ; point to player car graphics.
       ;call cloud1cc        ; set the char codes for player car.

       ;ld de,cloudcc       ; point to player cc in buffer.
       ;ld hl,plrhole      ; point to player car graphics.
       ;call cloud1cc        ; set the char codes for player car.

       ld a,(event)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (event),a          ; update player x-coordinate.




main_game


       call wait



       call ldsat          ; load sat buffer to vram. The cars
                           ; and the (hi)-score sprites are
                           ; updated on the screen.

       ld a,(event)          ; get player's hpos (x-coordinate).
       cp 20         ; is player over thr right border?
       jp nc,level_1_ending      ; yes - skip to left test.

       call gameengine

maingame_part2
       call upbufholes

       call PSGFrame


       jp main_game


level_1_ending
       ld a,(plx)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (plx),a          ; update player x-coordinate.



       ld a,(plx)          ; get player's hpos (x-coordinate).
       cp rightb         ; is player over thr right border?
       jp nc,begin_level_2    ; yes - skip to left test.


       ld a,(frame)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (frame),a          ; update player x-coordinate.

       ld a,(frame)          ; get player's hpos (x-coordinate).
       cp 10          ; is player over thr right border?
       jp nc,level1endinganim1        ; yes - skip to left test.


       ld hl,$2000         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,pltile1        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       jp maingame_part2

level1endinganim1
       ld hl,$2000         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,pltile2        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       ld a,(frame)          ; get player's hpos (x-coordinate).
       cp 20          ; is player over thr right border?
       jp c,endlevelend         ; yes - skip to left test.

       ld a,1             ; player starts at the road's center.
       ld (frame),a       ; set x-coordinate.

endlevelend
       jp maingame_part2

.bank 1 slot 1

gameengine
       ld de,plx        ; point to score.


       ld a,(cloudx)          ; get player x-coordinate.
       add a,16       ; add constant hspeed
       ld (thi),a          ; update player x-coordinate.

       ld hl,thi       ; point to hiscore.

       ld a,(de)           ; load score digit
       cp (hl)             ; is hiscore digit > score digit?
       jp nc,main_game_11        ; yes - break out of loop.
       


       ld de,plx        ; point to score.
       ld hl,cloudx        ; point to hiscore.


       ld a,(de)           ; load score digit
       cp (hl)             ; is hiscore digit > score digit?
       jp c,main_game_11        ; yes - break out of loop.

       ;ld a,(ply)          ; get player's hpos (x-coordinate).
       ;cp 95          ; is player over thr right border?
       ;jp c,main_game_11        ; yes - skip to left test.


       ld a,(status)       ; load vdp status (set by interrupt).
       bit 5,a             ; is the sprite collision bit set?
       jp nz,falling_down_hole_code  ; yes - jump out of main loop.








main_game_11
       ld a,(bananaevent)          ; get player's hpos (x-coordinate).
       cp 1          ; is player over thr right border?
       jp c,enemyanim4         ; yes - skip to left test.



       

       ld a,(cloudx)          ; get player's hpos (x-coordinate).
       cp 208          ; is player over thr right border?
       jp c,main_game_12        ; yes - skip to left test.




       call getkey         ; read controller port.
       ld a,(input)        ; read input from ram mirror.
       bit 3,a             ; is right key pressed?
       jp nz,enemyanim4   ; no - test for left key.

       ld a,1             ; player starts at the road's center.
       ld (icetimer),a       ; set x-coordinate.


main_game_12

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 5          ; is player over thr right border?
       jp nc,level_5_enemy_action        ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 4          ; is player over thr right border?
       jp nc,level_4_enemy_action        ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp nc,level_3_enemy_action        ; yes - skip to left test.


       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp nc,level_2_enemy_action        ; yes - skip to left test.


       ld a,(cloudx)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloudx),a          ; update player x-coordinate.

       ld a,(cloud2x)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloud2x),a          ; update player x-coordinate.



       ld a,(cloud2x)          ; get player's hpos (x-coordinate).
       cp 20          ; is player over thr right border?
       jp c,level1events         ; yes - skip to left test.



       ld a,(enemyframe)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (enemyframe),a          ; update player x-coordinate.

       ld a,(enemyframe)          ; get player's hpos (x-coordinate).
       cp 10          ; is player over thr right border?
       jp nc,enemyanim2         ; yes - skip to left test.






       ld hl,$2200         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,bananatile        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.


       jp enemyanim3




enemyanim2
       ld hl,$2200         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,bananatile2        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.




enemyanim3


       ld a,(enemyframe)          ; get player's hpos (x-coordinate).
       cp 20          ; is player over thr right border?
       jp c,enemyanim4          ; yes - skip to left test.

       ld a,1             ; player starts at the road's center.
       ld (enemyframe),a       ; set x-coordinate.

       jp enemyanim4

level_5_enemy_action

         ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,lettucetile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,lettucetile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld a,(cloudx)          ; get player x-coordinate.
       ld b, 1       ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloudx),a          ; update player x-coordinate.

       ld a,(cloud2x)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloud2x),a          ; update player x-coordinate.

       ld a,(cloudy)          ; get player's hpos (x-coordinate).
       cp 100         ; is player over thr right border?
       jp nc,level_5_enemy_action_2          ; yes - skip to left test.



       ld a,(cloud2y)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (cloud2y),a          ; update player x-coordinate.

       ld a,(cloudy)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (cloudy),a          ; update player x-coordinate.




level_5_enemy_action_2
       ld a,(enemyframe)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (enemyframe),a          ; update player x-coordinate.



       ld a,(enemyframe)          ; get player's hpos (x-coordinate).
       cp 10          ; is player over thr right border?
       jp c,enemyanim4        ; yes - skip to left test.




lettuce_anim2




       ld hl,$2200         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,lettucetile2        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       ld a,(enemyframe)          ; get player's hpos (x-coordinate).
       cp 20          ; is player over thr right border?
       jp c,enemyanim4          ; yes - skip to left test.

       ld a,1             ; player starts at the road's center.
       ld (enemyframe),a       ; set x-coordinate.

       jp enemyanim4

;==================

level_4_enemy_action
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,peppertile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,peppertile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       jp level_3_enemy_action_2

level_3_enemy_action
       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,corntile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,corntile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

level_3_enemy_action_2
       ld a,(cloudx)          ; get player x-coordinate.
       ld b, 1       ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloudx),a          ; update player x-coordinate.

       ld a,(cloud2x)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloud2x),a          ; update player x-coordinate.




       ld a,(cloud2x)          ; get player's hpos (x-coordinate).
       cp 20          ; is player over thr right border?
       jp c,level1events         ; yes - skip to left test.

       ld a,(enemyframe)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (enemyframe),a          ; update player x-coordinate.

       ld a,(enemyframe)          ; get player's hpos (x-coordinate).
       cp 22          ; is player over thr right border?
       jp nc,cornanim2         ; yes - skip to left test.

       ld a,(cloud2y)          ; get player x-coordinate.
       ld b, 2        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloud2y),a          ; update player x-coordinate.

       ld a,(cloudy)          ; get player x-coordinate.
       ld b, 2        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloudy),a          ; update player x-coordinate.





       jp enemyanim4




cornanim2
       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 4          ; is player over thr right border?
       jp nc,pepper_anim       ; yes - skip to left test.


       ld hl,$2200         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,corntile2        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       jp corn_anim_3

pepper_anim
       ld hl,$2200         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,peppertile2        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       jp corn_anim_3
       
corn_anim_3
       ld a,(cloud2y)          ; get player x-coordinate.
       add a,2       ; add constant hspeed
       ld (cloud2y),a          ; update player x-coordinate.

       ld a,(cloudy)          ; get player x-coordinate.
       add a,2       ; add constant hspeed
       ld (cloudy),a          ; update player x-coordinate.



       ld a,(enemyframe)          ; get player's hpos (x-coordinate).
       cp 42         ; is player over thr right border?
       jp c,enemyanim4          ; yes - skip to left test.

       ld a,0             ; player starts at the road's center.
       ld (enemyframe),a       ; set x-coordinate.
       
       jp enemyanim4
;===========================================

level_2_enemy_action
       ld a,(enemyframe)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (enemyframe),a          ; update player x-coordinate.

       ld a,(enemyframe)          ; get player's hpos (x-coordinate).
       cp 35          ; is player over thr right border?
       jp nc,celeryanim2         ; yes - skip to left test.

       ld a,(cloud2y)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloud2y),a          ; update player x-coordinate.

       ld a,(cloudy)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloudy),a          ; update player x-coordinate.

       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,celerytile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,celerytile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       jp enemyanim4




celeryanim2

       ld a,(cloud2y)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (cloud2y),a          ; update player x-coordinate.

       ld a,(cloudy)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (cloudy),a          ; update player x-coordinate.

       ld hl,$2200         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,celerytile2        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       ld a,(enemyframe)          ; get player's hpos (x-coordinate).
       cp 68          ; is player over thr right border?
       jp c,enemyanim4          ; yes - skip to left test.

       ld a,0             ; player starts at the road's center.
       ld (enemyframe),a       ; set x-coordinate.




enemyanim4

       ld a,(falling)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp nc,falling_down_hole_code         ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp nc,enemyanim5         ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp c,enemyanim5         ; yes - skip to left test.

       ld a,(icetimer)          ; get player's hpos (x-coordinate).
       cp 1               ; is player over thr right border?
       jp nc,going        ; yes - skip to left test.



enemyanim5
       call getkey         ; read controller port.
       ld a,(input)        ; read input from ram mirror.
       bit 3,a             ; is right key pressed?
       jp nz,main_game_2   ; no - test for left key.


       ld a,1             ; player starts at the road's center.
       ld (icetimer),a       ; set x-coordinate.



going
       ld a,(bananaevent)          ; get player's hpos (x-coordinate).
       cp 0          ; is player over thr right border?
       jp nc,going2         ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 1          ; is player over thr right border?
       jp c,going2         ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp c,going2         ; yes - skip to left test.

       jp going3

going2
       ld a,(cloudx)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloudx),a          ; update player x-coordinate.

       ld a,(cloud2x)          ; get player x-coordinate.
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (cloud2x),a          ; update player x-coordinate.

going3
       ld a,(cloud2x)          ; get player's hpos (x-coordinate).
       cp 20          ; is player over thr right border?
       jp c,level1events         ; yes - skip to left test.

       ld a,(icetimer)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (icetimer),a          ; update player x-coordinate.

       ld a,(icetimer)          ; get player's hpos (x-coordinate).
       cp 27          ; is player over thr right border?
       jp nc,stopsliding        ; yes - skip to left test.

       ld a,(frame)          ; get player x-coordinate.
       add a,1       ; add constant hspeed
       ld (frame),a          ; update player x-coordinate.

       ld a,(frame)          ; get player's hpos (x-coordinate).
       cp 10          ; is player over thr right border?
       jp nc,anim2main          ; yes - skip to left test.


       ld hl,$2000         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,pltile1        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       jp main_game_2

anim2main
       ld hl,$2000         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,pltile2        ; player car tile data.
       ld bc,5*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

       ld a,(frame)          ; get player's hpos (x-coordinate).
       cp 20          ; is player over thr right border?
       jp c,main_game_2          ; yes - skip to left test.

       ld a,1             ; player starts at the road's center.
       ld (frame),a       ; set x-coordinate.

       jp main_game_2

stopsliding
       ld a,0            ; player starts at the road's center.
       ld (icetimer),a       ; set x-coordinate.



main_game_2






dont_fall_stupid
       call getkey         ; read controller port into ram.
       ld a,(input)        ; read input from ram mirror.
       bit 5,a             ; is button 1 pressed?
       jp nz,falling_code  ; if not then go to rest of code

       ld a,(falling)          ; get player's hpos (x-coordinate).
       cp 1          ; is player over thr right border?
       jp nc,falling_code          ; if not then go to rest of code

       ld a,(jumping)          ; get player's hpos (x-coordinate).
       cp 1          ; is player over thr right border?
       jp nc,dont_fall_stupid_1          ; if not then go to rest of code




       ld a,1             ; player starts at the road's center.
       ld (jumping),a       ; set x-coordinate.

dont_fall_stupid_1
       ld a,(ply)          ; get player's hpos (x-coordinate).
       cp 37          ; is player over thr right border?
       jp c,falling_code        ; if not then go to rest of code



       ld a,1             ; player starts at the road's center.
       ld (frame),a       ; set x-coordinate.



dont_fall_stupid_2
       ld a,(ply)          ; get player x-coordinate.
       ld b, 2        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (ply),a          ; update player x-coordinate.

       ;ld a,(ply)          ; get player's hpos (x-coordinate).
       ;cp 41          ; is player over thr right border?
       ;jp nc,falling_code          ; if not then go to rest of code




      ret



falling_down_hole_code

       ld a,(cloudy)          ; get player's hpos (x-coordinate).
       ld b, 8        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (enemyycollision),a          ; update player x-coordinate.



       ld a,(ply)          ; get player x-coordinate.
       add a,4       ; add constant hspeed
       ld (ply),a          ; update player x-coordinate.

       ld a,(ply)          ; get player's hpos (x-coordinate).
       cp 157          ; is player over thr right border?
       jp nc,die

       ld a,3            ; player starts at the road's center.
       ld (falling),a       ; set x-coordinate.

       ret




falling_code




       ld a,(ply)          ; get player's hpos (x-coordinate).
       cp 95          ; is player over thr right border?
       jp c,falling_code_2      ; if not then go to rest of code

       ld a,97           ; player starts at the road's center.
       ld (ply),a       ; set x-coordinate.

       jp stop_falling


falling_code_2

       ;call PSGStop        ; turn of the music.

       ld a,(ply)          ; get player's hpos (x-coordinate).
       cp 97          ; is player over thr right border?
       jp nc,stop_falling         ; if not then go to rest of code


falling_code_3
       ld a,1            ; player starts at the road's center.
       ld (falling),a       ; set x-coordinate.

        ld a,0            ; player starts at the road's center.
       ld (jumping),a       ; set x-coordinate.

       ld a,(ply)          ; get player x-coordinate.
       add a,4       ; add constant hspeed
       ld (ply),a          ; update player x-coordinate.




      ret


stop_falling

       ld a,2            ; player starts at the road's center.
       ld (falling),a       ; set x-coordinate.

       ld a,(input)        ; read input from ram mirror.
       bit 5,a             ; is button 1 pressed?
       jp z,stop_falling_4  ; if not then go to rest of code

       ld a,0            ; player starts at the road's center.
       ld (falling),a       ; set x-coordinate.
 

stop_falling_4
       ret




die

       ld a,(lives)          ; get player's hpos (x-coordinate).
       ld b, 1        ; load horizontal speed (constant).
       sub b               ; subtract hspeed from player x.
       ld (lives),a          ; update player x-coordinate.

       ld a,(lives)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp nc,life_one       ; yes - skip to left test.

       ld a,(lives)          ; get player's hpos (x-coordinate).
       cp 1          ; is player over thr right border?
       jp nc,life_zero        ; yes - skip to left test.

       jp stopcurrentmusic        ; yes - skip to left test.

life_one
       ld hl,$2600         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,one           ; player car tile data.
       ld bc,1*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

          jp die2

life_zero
       ld hl,$2600         ; first tile @ index 256.
       call vrampr         ; prepare vram.
       ld hl,zero         ; player car tile data.
       ld bc,1*32          ; 4 tiles, 32 bytes each.
       call vramwr         ; write player car tiles to vram.

die2

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 5          ; is player over thr right border?
       jp nc,begin_level_5die         ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 4          ; is player over thr right border?
       jp nc,begin_level_4die         ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp nc,begin_level_3die         ; yes - skip to left test.

       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp nc,begin_level_2die         ; yes - skip to left test.

       jp begin_level_1         ; yes - skip to left test.

begin_level_3


       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 3          ; is player over thr right border?
       jp nc,begin_level_4         ; yes - skip to left test.

begin_level_3die

       call PSGStop

       ld a,3          ;
       ld (level),a          ; set player y.

       ld hl,level3music
       call PSGPlay

       ld a,0          ;
       ld (enemyframe),a          ; set player y.

       ld a,0            ; player starts at the road's center.
       ld (bananaevent),a       ; set x-coordinate.

       ld a,1           ; player starts at the road's center.
       ld (event),a       ; set x-coordinate.

       xor a
       ld (iflag),a

       ld a,97           ;
       ld (ply),a          ; set player y.

       ld a,210           ; player starts at the road's center.
       ld (cloudx),a       ; set x-coordinate.

       ld a,218            ; player starts at the road's center.
       ld (cloud2x),a       ; set x-coordinate.

       ld a,127            ; player starts at the road's center.
       ld (cloud2y),a       ; set x-coordinate.

       ld a,127           ; player starts at the road's center.
       ld (cloudy),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (jumping),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (falling),a       ; set x-coordinate.



       ld hl,$c020         ; color bank 2, color 0 (sprites).
       call vrampr         ; prepare vram.
       ld hl,bgpal         ; sprite palette data.
       ld bc,32            ; 5 colors.
       call vramwr         ; set sprite palette.

       ld hl,$c000         ; color bank 1, color 0.
       call vrampr         ; prepare vram.
       ld hl,bgpal       ; background palette.
       ld bc,16             ; 4 colors.
       call vramwr         ; set background palette.

       ld hl,$0000         ; first tile @ index 0.
       call vrampr         ; prepare vram.
       ld hl,level3bgtile  ; background tile data (the road).
       ld bc,77*32         ; 2 tiles (!), each tile is 32 bytes.
       call vramwr         ; write background tiles to vram.

       ld hl,$3800         ; point to name table.
       call vrampr         ; prepare vram.
       ld hl,level3bgmap        ; point to background tilemap data.
       ld bc,32*28*2       ; 32 x 28 tiles, each is 2 bytes.
       call vramwr         ; write name table to vram.

       ld de,plrcc         ; point to player cc in buffer.
       ld hl,plrcar        ; point to player car graphics.
       call carcc          ; set the char codes for player car.

       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel3tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel3tile     ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld a,79             ; player starts at the road's center.
       ld (plx),a          ; set x-coordinate.



      jp main_game_forall

      ;=============
begin_level_5


       ld a,5          ;
       ld (level),a          ; set player y.

begin_level_5die
       ld hl,level5music
       call PSGPlay

       ld a,0          ;
       ld (enemyframe),a          ; set player y.

       ld a,0            ; player starts at the road's center.
       ld (bananaevent),a       ; set x-coordinate.

       ld a,1           ; player starts at the road's center.
       ld (event),a       ; set x-coordinate.

       xor a
       ld (iflag),a

       ld a,97           ;
       ld (ply),a          ; set player y.

       ld a,210           ; player starts at the road's center.
       ld (cloudx),a       ; set x-coordinate.

       ld a,218            ; player starts at the road's center.
       ld (cloud2x),a       ; set x-coordinate.

       ld a,127          ; player starts at the road's center.
       ld (cloud2y),a       ; set x-coordinate.

       ld a,127          ; player starts at the road's center.
       ld (cloudy),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (jumping),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (falling),a       ; set x-coordinate.



       ld hl,$c020         ; color bank 2, color 0 (sprites).
       call vrampr         ; prepare vram.
       ld hl,bgpal         ; sprite palette data.
       ld bc,32            ; 5 colors.
       call vramwr         ; set sprite palette.

       ld hl,$c000         ; color bank 1, color 0.
       call vrampr         ; prepare vram.
       ld hl,bgpal       ; background palette.
       ld bc,16             ; 4 colors.
       call vramwr         ; set background palette.

       ld hl,$0000         ; first tile @ index 0.
       call vrampr         ; prepare vram.
       ld hl,level5bgtile  ; background tile data (the road).
       ld bc,77*32         ; 2 tiles (!), each tile is 32 bytes.
       call vramwr         ; write background tiles to vram.

       ld hl,$3800         ; point to name table.
       call vrampr         ; prepare vram.
       ld hl,level5bgmap        ; point to background tilemap data.
       ld bc,32*28*2       ; 32 x 28 tiles, each is 2 bytes.
       call vramwr         ; write name table to vram.

       ld de,plrcc         ; point to player cc in buffer.
       ld hl,plrcar        ; point to player car graphics.
       call carcc          ; set the char codes for player car.

       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel5tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel5tile     ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld a,79             ; player starts at the road's center.
       ld (plx),a          ; set x-coordinate.



      jp main_game_forall

      ;=============
begin_level_4


       ld a,4          ;
       ld (level),a          ; set player y.

begin_level_4die
       ld hl,level4music
       call PSGPlay

       ld a,0          ;
       ld (enemyframe),a          ; set player y.

       ld a,0            ; player starts at the road's center.
       ld (bananaevent),a       ; set x-coordinate.

       ld a,1           ; player starts at the road's center.
       ld (event),a       ; set x-coordinate.

       xor a
       ld (iflag),a

       ld a,97           ;
       ld (ply),a          ; set player y.

       ld a,210           ; player starts at the road's center.
       ld (cloudx),a       ; set x-coordinate.

       ld a,218            ; player starts at the road's center.
       ld (cloud2x),a       ; set x-coordinate.

       ld a,127            ; player starts at the road's center.
       ld (cloud2y),a       ; set x-coordinate.

       ld a,127           ; player starts at the road's center.
       ld (cloudy),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (jumping),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (falling),a       ; set x-coordinate.



       ld hl,$c020         ; color bank 2, color 0 (sprites).
       call vrampr         ; prepare vram.
       ld hl,bgpal         ; sprite palette data.
       ld bc,32            ; 5 colors.
       call vramwr         ; set sprite palette.

       ld hl,$c000         ; color bank 1, color 0.
       call vrampr         ; prepare vram.
       ld hl,bgpal       ; background palette.
       ld bc,16             ; 4 colors.
       call vramwr         ; set background palette.

       ld hl,$0000         ; first tile @ index 0.
       call vrampr         ; prepare vram.
       ld hl,level4bgtile  ; background tile data (the road).
       ld bc,77*32         ; 2 tiles (!), each tile is 32 bytes.
       call vramwr         ; write background tiles to vram.

       ld hl,$3800         ; point to name table.
       call vrampr         ; prepare vram.
       ld hl,level4bgmap        ; point to background tilemap data.
       ld bc,32*28*2       ; 32 x 28 tiles, each is 2 bytes.
       call vramwr         ; write name table to vram.

       ld de,plrcc         ; point to player cc in buffer.
       ld hl,plrcar        ; point to player car graphics.
       call carcc          ; set the char codes for player car.

       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holetile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holetile     ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld a,79             ; player starts at the road's center.
       ld (plx),a          ; set x-coordinate.



      jp main_game_forall

begin_level_2

       ;the next 3 lines are temporary!
       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 5          ; is player over thr right border?
       jp nc,begin_level_5         ; yes - skip to left test.


       ld a,(level)          ; get player's hpos (x-coordinate).
       cp 2          ; is player over thr right border?
       jp nc,begin_level_3         ; yes - skip to left test.

begin_level_2die
       call PSGStop


       ld hl,level2music
       call PSGPlay

       ld a,0            ; player starts at the road's center.
       ld (icetimer),a       ; set x-coordinate.

       ld a,2          ;
       ld (level),a          ; set player y.

       ld a,0            ; player starts at the road's center.
       ld (bananaevent),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (event),a       ; set x-coordinate.

       xor a
       ld (iflag),a

; Setup the background assets for the main loop.
       ld a,97           ;
       ld (ply),a          ; set player y.

       ld a,0            ; player starts at the road's center.
       ld (jumping),a       ; set x-coordinate.

       ld a,0            ; player starts at the road's center.
       ld (falling),a       ; set x-coordinate.



       ld hl,$c000         ; color bank 1, color 0.
       call vrampr         ; prepare vram.
       ld hl,bgpal         ; background palette.
       ld bc,15             ; 4 colors.
       call vramwr         ; set background palette.

       ld hl,$0000         ; first tile @ index 0.
       call vrampr         ; prepare vram.
       ld hl,level2bgtile        ; background tile data (the road).
       ld bc,77*32          ; 2 tiles (!), each tile is 32 bytes.
       call vramwr         ; write background tiles to vram.

       ld hl,$3800         ; point to name table.
       call vrampr         ; prepare vram.
       ld hl,level2bgmap        ; point to background tilemap data.
       ld bc,32*28*2       ; 32 x 28 tiles, each is 2 bytes.
       call vramwr         ; write name table to vram.

       ld de,plrcc         ; point to player cc in buffer.
       ld hl,plrcar        ; point to player car graphics.
       call carcc          ; set the char codes for player car.

       ld hl,$2200         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel2tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld hl,$2400         ; first tile @ index 272.
       call vrampr         ; prepare vram.
       ld hl,holelevel2tile      ; hole tile data.
       ld bc,5*32          ; 16 tiles, 32 bytes each.
       call vramwr         ; write enemy car tiles to vram.

       ld a,79             ; player starts at the road's center.
       ld (plx),a          ; set x-coordinate.

       ld a,119             ; player starts at the road's center.
       ld (cloudx),a       ; set x-coordinate.

       ld a,127             ; player starts at the road's center.
       ld (cloud2x),a       ; set x-coordinate.
   
       ld a,127             ; player starts at the road's center.
       ld (cloudy),a       ; set x-coordinate.

       ld a,127             ; player starts at the road's center.
       ld (cloud2y),a       ; set x-coordinate.
; Put the sprites in.


       ld a,0            ; player starts at the road's center.
       ld (event),a       ; set x-coordinate.


main_game_forall


       call wait



       call ldsat          ; load sat buffer to vram. The cars
                           ; and the (hi)-score sprites are
                           ; updated on the screen.

       call gameengine

       call upbufholes

       call PSGFrame

       jp main_game_forall


.bank 2 slot 1

; --------------------------------------------------------------
; SUBROUTINES
; --------------------------------------------------------------
; PREPARE VRAM.
; Set up vdp to recieve data at vram address in HL.

vrampr push af
       ld a,l
       out ($bf),a
       ld a,h
       or $40
       out ($bf),a
       pop af
       ret

; --------------------------------------------------------------
; WRITE TO VRAM
; Write BC amount of bytes from data source pointed to by HL.
; Tip: Use vrampr before calling.

vramwr ld a,(hl)
       out ($be),a
       inc hl
       dec bc
       ld a,c
       or b
       jp nz,vramwr
       ret

; --------------------------------------------------------------
; LOAD SPRITE ATTRIBUTE TABLE
; Load data into sprite attribute table (SAT) from the buffer.

ldsat  ld hl,$3f00         ; point to start of SAT in vram.
       call vrampr         ; prepare vram to recieve data.
       ld b,255            ; amount of bytes to output.
       ld c,$be            ; destination is vdp data port.
       ld hl,satbuf        ; source is start of sat buffer.
       otir                ; output buffer to vdp.



       ret

; --------------------------------------------------------------
; UPDATE SAT BUFFER
; Generate vpos, hpos and cc data for the sprites that make up
; each of the cars (player, Mae and Ash).
; Also generate char code (cc) data from hiscore and score.

; Generate sat buffer data from player's x,y coordinates.

upbuf

       ld a,0          ; load player's current y-coordinate.
       ld hl,livesvp         ; point to sat buffer.
       call lifey           ; refresh buffer according to y.
       
       ld a,180       ; load player's current x-coordinate.
       ld hl,liveshp         ; point to sat buffer.
       call lifex           ; refresh buffer according to x.

       ld a,(ply)          ; load player's current y-coordinate.
       ld hl,plrvp         ; point to sat buffer.
       call cary           ; refresh buffer according to y.

       ld a,(plx)          ; load player's current x-coordinate.
       ld hl,plrhp         ; point to sat buffer.
       call carx           ; refresh buffer according to x.


       ld a,(cloudy)          ; load player's current y-coordinate.
       ld hl,cloudvp         ; point to sat buffer.
       call holey2          ; refresh buffer according to y.


       ld a,(cloudx)          ; load player's current x-coordinate.
       ld hl,cloudhp         ; point to sat buffer.
       call holex2          ; refresh buffer according to x.

       ld a,(cloud2y)          ; load player's current y-coordinate.
       ld hl,cloud2vp         ; point to sat buffer.
       call holey2           ; refresh buffer according to y.


       ld a,(cloud2x)          ; load player's current x-coordinate.
       ld hl,cloud2hp         ; point to sat buffer.
       call holex2          ; refresh buffer according to x.




       ret

upbufholes
       ld a,32          ; load player's current y-coordinate.
       ld hl,livesvp         ; point to sat buffer.
       call lifey           ; refresh buffer according to y.

       ld a,180       ; load player's current x-coordinate.
       ld hl,liveshp         ; point to sat buffer.
       call lifex           ; refresh buffer according to x.



       ld a,(ply)          ; load player's current y-coordinate.
       ld hl,plrvp         ; point to sat buffer.
       call cary           ; refresh buffer according to y.

       ld a,(plx)          ; load player's current x-coordinate.
       ld hl,plrhp         ; point to sat buffer.
       call carx           ; refresh buffer according to x.

       ld a,(cloudy)          ; load player's current y-coordinate.
       ld hl,cloudvp         ; point to sat buffer.
       call holey2          ; refresh buffer according to y.


       ld a,(cloudx)          ; load player's current x-coordinate.
       ld hl,cloudhp         ; point to sat buffer.
       call holex2          ; refresh buffer according to x.

       ld a,(cloud2y)          ; load player's current y-coordinate.
       ld hl,cloud2vp         ; point to sat buffer.
       call holey2           ; refresh buffer according to y.


       ld a,(cloud2x)          ; load player's current x-coordinate.
       ld hl,cloud2hp         ; point to sat buffer.
       call holex2          ; refresh buffer according to x.

       ret

;=======
; life number to buffer
; ==========
; --------------------------------------------------------------
; CAR Y TO SPRITES' VERTICAL POSITIONS (VPOS) IN BUFFER.
; Generate vpos sat buffer data from a car's y position.
; A = car's y (i.e. ply), HL = buffer address of car vpos.

lifey  ld c,a              ; save hpos in C
       .rept 2             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A
       ld b,2             ; loop: Repeat four times.
-      ld (hl),a           ; write value too buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,0             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.
       ret

; --------------------------------------------------------------
; CAR X TO SPRITES' HORIZONTAL POSITIONS (HPOS) IN BUFFER.
; Generates hpos sat buffer data from a car's x position.
; A = car's x (i.e. plx), HL = buffer address of car hpos.

lifex ld c,a              ; save hpos in C
       .rept 1             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A

       ld b,1             ; loop: Repeat four times.
-      ld (hl),a           ; write value too buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,8             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.


       

       ret


; --------------------------------------------------------------



; --------------------------------------------------------------
; CAR Y TO SPRITES' VERTICAL POSITIONS (VPOS) IN BUFFER.
; Generate vpos sat buffer data from a car's y position.
; A = car's y (i.e. ply), HL = buffer address of car vpos.

cloud1y  ld c,a              ; save hpos in C
       .rept 2             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A
       ld b,2             ; loop: Repeat four times.
-      ld (hl),a           ; write value too buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,0             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.
       ret

; --------------------------------------------------------------
; CAR X TO SPRITES' HORIZONTAL POSITIONS (HPOS) IN BUFFER.
; Generates hpos sat buffer data from a car's x position.
; A = car's x (i.e. plx), HL = buffer address of car hpos.

cloud1x ld c,a              ; save hpos in C
       .rept 1             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A

       ld b,1             ; loop: Repeat four times.
-      ld (hl),a           ; write value too buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,8             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.


       

       ret


; --------------------------------------------------------------
; holes.

holey2   ld c,a              ; save hpos in C
       .rept 5             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A
       ld b,5             ; loop: Repeat four times.
-      ld (hl),a           ; write value too buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,8             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.
       ret

; --------------------------------------------------------------
holex2  ld c,a              ; save hpos in C
       .rept 4             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A
       ld b,4             ; loop: Repeat four times.
-      ld (hl),a           ; write value too buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,0             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.
       ret
; --------------------------------------------------------------
; CAR Y TO SPRITES' VERTICAL POSITIONS (VPOS) IN BUFFER.
; Generate vpos sat buffer data from a car's y position.
; A = car's y (i.e. ply), HL = buffer address of car vpos.

cary   ld c,a              ; save hpos in C
       .rept 4             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A
       ld b,4             ; loop: Repeat four times.
-      ld (hl),a           ; write value too buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,8             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.
       ret

; --------------------------------------------------------------
; CAR X TO SPRITES' HORIZONTAL POSITIONS (HPOS) IN BUFFER.
; Generates hpos sat buffer data from a car's x position.
; A = car's x (i.e. plx), HL = buffer address of car hpos.

carx   ld c,a              ; save hpos in C
       .rept 3             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A
       ld b,3             ; loop: Repeat four times.
-      ld (hl),a           ; write value too buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,0             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.
       ret


; SET CLOUD SPRITES' CHARACTER CODES (CC)
; HL = pointer to 16 byte char codes block, DE = buffer index.

cloud1cc ld bc,16
-      ldi
       inc de
       ld a,b
       or c
       jp nz,-
       ret
; --------------------------------------------------------------

; --------------------------------------------------------------
; SET CAR SPRITES' CHARACTER CODES (CC)
; HL = pointer to 16 byte char codes block, DE = buffer index.

carcc ld bc,16
-      ldi
       inc de
       ld a,b
       or c
       jp nz,-
       ret
; --------------------------------------------------------------
; GET KEYS.
; Read player 1 keys (port $dc) into ram mirror (input).

getkey in a,$dc            ; read player 1 input port $dc.
       ld (input),a        ; let variable mirror port status.
       ret

; --------------------------------------------------------------
; SET VDP REGISTER.
; Write to target register.
; A = byte to be loaded into vdp register.
; B = target register 0-10.

setreg out ($bf),a         ; output command word 1/2.
       ld a,$80
       or b
       out ($bf),a         ; output command word 2/2.
       ret
; --------------------------------------------------------------
; Wait for vertical blanking phase.
wait   ld a,(iflag)        ; load frame interrupt flag.
       or a                ; is it set?
       jp z,wait           ; no? - keep looping.
       xor a               ; else - reset flag.
       ld (iflag),a
       ret                 ; return.
; --------------------------------------------------------------
; MEMORY FILL.
; HL = base address, BC = area size, A = fill byte.

mfill  ld (hl),a           ; load filler byte to base address.
       ld d,h              ; make DE = HL.
       ld e,l
       inc de              ; increment DE to HL + 1.
       dec bc              ; decrement counter.
       ld a,b              ; was BC = 0001 to begin with?
       or c
       ret z               ; yes - then just return.
       ldir                ; else - write filler byte BC times,
                           ; while incrementing DE and HL...
       ret

; --------------------------------------------------------------
; DATA
; --------------------------------------------------------------
; Initial values for the 11 vdp registers.

regdat .db %00000110       ; reg. 0, display and interrupt mode.
                           ; bit 4 = line interrupt (disabled).
                           ; 5 = blank left column (disabled).
                           ; 6 = hori. scroll inhibit (disabled).
                           ; 7 = vert. scroll inhibit (disabled).

       .db %10100001       ; reg. 1, display and interrupt mode.
                           ; bit 0 = zoomed sprites (enabled).
                           ; 1 = 8 x 16 sprites (disabled).
                           ; 5 = frame interrupt (enabled).
                           ; 6 = display (blanked).

       .db $ff             ; reg. 2, name table address.
                           ; $ff = name table at $3800.

       .db $ff             ; reg. 3, n.a.
                           ; always set it to $ff.

       .db $ff             ; reg. 4, n.a.
                           ; always set it to $ff.

       .db $ff             ; reg. 5, sprite attribute table.
                           ; $ff = sprite attrib. table at $3F00.

       .db $ff             ; reg. 6, sprite tile address.
                           ; $ff = sprite tiles in bank 2.

       .db %11110011       ; reg. 7, border color.
                           ; set to color 3 in bank 2.

       .db $00             ; reg. 8, horizontal scroll value = 0.

       .db $00             ; reg. 9, vertical scroll value = 0.

       .db $ff             ; reg. 10, raster line interrupt.
                           ; turn off line int. requests.

; Charcodes for player, enemy and invisible car.

.bank 3 slot 2

bgpal  .include "filestouse\background (palette).inc"
bgtile .include "filestouse\background (tiles)2.inc"
bgmap  .include "filestouse\background (tilemap)2.inc"

level1bgtile .include "filestouse\level1bg (tiles).inc"
level1bgmap  .include "filestouse\level1bg (tilemap).inc"
level2bgtile .include "filestouse\level2bg (tiles).inc"
level2bgmap  .include "filestouse\level2bg (tilemap).inc"
level3bgtile .include "filestouse\level3bg (tiles).inc"
level3bgmap  .include "filestouse\level3bg (tilemap).inc"
level4bgtile .include "filestouse\level4bg (tiles).inc"
level4bgmap  .include "filestouse\level4bg (tilemap).inc"
level5bgtile .include "filestouse\level5bg (tiles).inc"
level5bgmap  .include "filestouse\level5bg (tilemap).inc"


lifenumber .dw $0030

; Sprite assets. The plrcar one is all screwed up but works perfectly.
plrcar .dw $0000
       .dw $0102
       .dw $0103
       .dw $0104
       .dw $0101

plrhole2 .dw $0920
         .dw $0921
         .dw $0922
         .dw $0923
         .dw $0924


plrhole .dw $0910
       .dw $0911
       .dw $0912
       .dw $0913
       .dw $0914



plpal  .include "filestouse\background (palette).inc"
pltile1 .include "filestouse\player (ingametiles1).inc"
pltile2 .include "filestouse\player (ingametiles2).inc"
holetile .include "filestouse\hole (tilemap).inc"
holelevel2tile .include "filestouse\holelevel2 (tilemap).inc"
holelevel3tile .include "filestouse\holelevel3 (tilemap).inc"
holelevel5tile .include "filestouse\holelevel5 (tilemap).inc"
cloudtile .include "filestouse\cloud (tilemap).inc"
cloudtile2 .include "filestouse\cloud (tilemap)2.inc"

two        .include "filestouse\two (tiles).inc"
one        .include "filestouse\one (tiles).inc"
zero        .include "filestouse\zero (tiles).inc"

bananatile .include "filestouse\banana (tilemap).inc"
bananatile2 .include "filestouse\banana (tilemap)2.inc"

lettucetile .include "filestouse\lettuce (tilemap).inc"
lettucetile2 .include "filestouse\lettuce (tilemap)2.inc"

celerytile .include "filestouse\celery (tilemap).inc"
celerytile2 .include "filestouse\celery (tilemap)2.inc"

corntile .include "filestouse\corn (tilemap).inc"
corntile2 .include "filestouse\corn (tilemap)2.inc"

peppertile .include "filestouse\pepper (tilemap).inc"
peppertile2 .include "filestouse\pepper (tilemap)2.inc"

level1music .incbin "filestouse\level1forest.psg"
level2music .incbin "filestouse\level2mountain.psg"
level3music .incbin "filestouse\level3gulch.psg"
level4music .incbin "filestouse\level4beach.psg"
level5music .incbin "filestouse\level5avenue.psg"
titlescreenmusic .incbin "filestouse\titlescreen.psg"
.include "filestouse\PSGlib.inc"          ; include the library
