The Cutting Room Floor now has a Patreon page. Thanks for all your support!

If you've blocked our ad, please consider unblocking it.
We promise it isn't annoying. No flash, no sound, ever.

Ads by Project Wonderful! Your ad here, right now: $0

Urban Strike (Game Boy)

From The Cutting Room Floor
Jump to: navigation, search

Title Screen

Urban Strike

Developer: Borta
Publisher: Black Pearl
Platforms: Game Boy, Super Game Boy
Released in US: February 1995
Released in EU: 1995


SourceIcon.png This game has uncompiled source code.


Say hello to one of Game Boy's most hideous title screens.

Uncompiled Source Code

Two big chunks of uncompiled code can be found by using a hex editor on the ROM. Note that the formatting seen below matches the formatting seen in the ROM.

69E80:

        call    DO_SEQUENCE




START_INTERIOR_CAMPAIGN:

        ld      sp, $dfff                    ; set the stack pointer

        call    LCD_off

        call    InitWorld

        call    PlayGame

;═════════════════════════════════════════════════════════════════════════════

vr_start_wait:

; Waits for the beginning of vertical retrace. Returns immediately if the
; display is turned off. Interrupts must be disabled if this routine is called
; while the display is turned on.

        push    af

        ld      a, (LCDC)
        and     a, %10000000
        jr      z, .exit

.loop:

        ld      a, (LY)
        cp      a, 145 ; 144
        jr      nz, .loop

.exit:

        pop     af

        ret

;─────────────────────────────────────────────────────────────────────────────

vr_end_wait:

; Waits for the end of vertical retrace. Returns immediately if the display is
; turned off. Interrupts must be disabled if this routine is called while the
; display is turned on.

        push    af

        ld      a, (LCDC)
        and     a, %10000000
        jr      z, .exit

.loop:

        ld      a, (LY)
        or      a, a
        jr      nz, .loop

.exit:

        pop     af

        ret

;─────────────────────────────────────────────────────────────────────────────

LCD_off:

; Turns off the video display. Assumes interrupts are disabled.

        push    af

        call    vr_start_wait

        ld      a, (LCDC)
        and     a, %01111100
        ld      (LCDC), a

        pop     af

        ret

;─────────────────────────────────────────────────────────────────────────────

LCD_on:

; Turns on the video display.

        push    af

        ld      a, (LCDC)
        or      a, %10000011
        ld      (LCDC), a

        pop     af

        ret

;─────────────────────────────────────────────────────────────────────────────

;LCD_on_bkgr_off:

; Disables the display of the background but leaves the screen on.

;        push    af
;
;        ld      a, (LCDC)
;        or      a, %10000000
;        and     a, %11111110
;        ld      (LCDC), a
;
;        pop     af
;
;        ret


;─────────────────────────────────────────────────────────────────────────────

bkgr_off:

; Disables the display of the background.

        push    af

        ld      a, (LCDC)
        and     a, %11111110
        ld      (LCDC), a

        pop     af

        ret

;─────────────────────────────────────────────────────────────────────────────

bkgr_on:

; Enables the display of the background.

        push    af

        ld      a, (LCDC)
        or      a, %00000001
        ld      (LCDC), a

        pop     af

        ret

;─────────────────────────────────────────────────────────────────────────────

spr_off:

; Disables the display of sprites.

        push    af

        ld      a, (LCDC)
        and     a, %11111101
        ld      (LCDC), a

        pop     af

        ret

;─────────────────────────────────────────────────────────────────────────────

spr_on:

; Enables the display of sprites.

        push    af

        ld      a, (LCDC)
        or      a, %00000010
        ld      (LCDC), a

        pop     af

        ret




;─────────────────────────────────────────────────────────────────────────────




sound_off:

        push    af

        ld      a, (sound_flags)
        and     a, 254
        ld      (sound_flags), a

        xor     a, a
	ld	(NR52), a

        pop     af

        ret


sound_on:

        push    af

        ld      a, (sound_flags)
        or      a, 1
        ld      (sound_flags), a



        ld      a, %11111111
	ld	(NR51), a
	ld	(NR50), a

        ld      a, %10001000
	ld	(NR52), a


        pop     af

        ret




;─────────────────────────────────────────────────────────────────────────────

cls:

; Clears one of the two VRAM display areas. May be called only when the
; display is turned off.

; call with D = area number (0 or 1)
;           E = clear value

;        push    af
;        push    bc
;        push    hl

        ld      bc, 1024

        ld      hl, $9800

        bit     0, d
        jr      z, .loop

        ld      h, $9c

.loop:

        ld      (hl), e
        inc     hl

        dec     bc
        ld      a, c
        or      a, b
        jr      nz, .loop

;        pop     hl
;        pop     bc
;        pop     af

        ret


;─────────────────────────────────────────────────────────────────────────────

get_buttons:

; Returns with A = status of the buttons.

        push    bc

        ld      c, 0

        ld      a, $20
        ld      (c), a                 ; select direction buttons

        ld      a, (c)
        ld      a, (c)
        ld      a, (c)

        and     a, $0f                 ; A = 0000dulr
        ld      b, a                   ; B = 0000dulr

        ld      a, $10
        ld      (c), a                 ; select other buttons

        ld      a, (c)
        ld      a, (c)
        ld      a, (c)
        ld      a, (c)
        ld      a, (c)
        ld      a, (c)
        ld      a, (c)
        ld      a, (c)
        ld      a, (c)

        and     a, $0f                 ; A = 0 0 0 0 sta sel b a
        swap    a                      ; A = sta sel b a 0 0 0 0
        or      a, b                   ; A = sta sel b a d u l r
        cpl

        pop     bc

        ret




;─────────────────────────────────────────────────────────────────────────────

fill_copy_proc:

; call with B  =  total bytes of data / 2; B must be <= 144
;           DE -> second-to-last byte of data
;           the correct bank selected

; Before jumping to copy_proc, set SP -> byte after last destination byte, and
; HL = return address.

        push    af
        push    bc
        push    de
        push    hl

        ld      hl, copy_proc

.loop:

        inc     hl

        ld      a, (de)
        inc     de
        ld      (hli), a

        ld      a, (de)
        dec     de
        dec     de
        dec     de
        ld      (hli), a

        inc     hl

        dec     b
        jr      nz, .loop

        ld      a, (jp_addr)
        ld      e, a
        ld      a, (jp_addr + 1)
        ld      d, a
        ld      a, $11
        ld      (de), a                ; "erase" previous "jp (hl)" instr.

        ld      a, $e9                 ; $e9 = "jp (hl)"
        ld      (hl), a                ; insert "jp (hl)" instruction

        ld      a, l
        ld      (jp_addr), a
        ld      a, h
        ld      (jp_addr + 1), a

        pop     hl
        pop     de
        pop     bc
        pop     af

        ret

;─────────────────────────────────────────────────────────────────────────────

load_chars:

; call with (dest_addr) -> byte after last destination byte

; May be called only when the display is turned off or during v-blank. If
; (dest_addr + 1) = 0, then load_chars does nothing. load_chars sets
; (dest_addr + 1) = 0.


        ld      (stack_save), sp
        ld      sp, hl                 ; SP = (dest_addr)

        ld      hl, .back

        jp      copy_proc

.back:

        ld      hl, stack_save
        ld      a, (hli)
        ld      h, (hl)
        ld      l, a                   ; HL = (stack_save)
        ld      sp, hl                 ; SP = (stack_save)


        ret

;─────────────────────────────────────────────────────────────────────────────

RAMMoveSpriteObject:

; call with A = total sprites in object
;           C = number of first sprite (0 - 39)
;           D = dy
;           E = dx

        push    af
        push    bc
        push    hl

        ld      b, a                   ; B = total sprites in object

        ld      a, c                   ; A = number of first sprite
        add     a, a
        add     a, a                   ; A = number of first sprite * 4

        ld      l, a
        ld      h, $c0                 ; HL -> sprite in RAM sprite table

.loop:

        ld      a, (hl)                ; A = sprite y-coordinate
        cp      a, $e0
        jr      z, .skip

        add     a, d
        ld      (hli), a

        ld      a, (hl)                ; A = sprite x-coordi

6EB0B:

ld      b, 11

.ENCODE_LOOP:

        ld      a, (hl)

        ld      de, PASS_CHAR

        add     a, e
        ld      e, a
        ld      a, d
        adc     a, 0
        ld      d, a

        ld      a, (de)

        ld      (hli), a

        dec     b
        jr      nz, .ENCODE_LOOP



        ret







;*******************************************************
;*******************************************************
;*******************************************************
;*******************************************************
;*******************************************************

; password decoding








;*******************************************************
; PASS_DECODE:
;*******************************************************

PASS_DECODE:

        ; copy PASSWD to PASSWD_TEMP, reduce to 0-31 range

        ld      hl, PWString
        ld      de, PWTemp
        ld      b, 11

.REDUCE_LOOP:

        ld      a, (hli)                ; a = character from p.w. string

        push    bc
        push    hl

        ld      hl, PASS_CHAR + 30   ; 28 ; 31

        ld      b, 31       ; 29 ; 32

.search:

        ld      c, (hl)
        dec     hl

        cp      a, c

        jr      z, .match

        dec     b
        jr      nz, .search

        pop     hl
        pop     bc

        jp      .FAIL

.match:

        dec     b
        ld      a, b

        ld      (de), a
        inc     de

        pop     hl
        pop     bc

        dec     b
        jr      nz, .REDUCE_LOOP







.DECODE:

        ld      a, (PWTemp_5)
        sra     a
        ld      b, a
        ld      (nibble_2), a

        ld      a, (PWTemp_10)
        sub     a, b
        ld      b, a
        ld      (nibble_5), a

        ld      a, (PWTemp_1)
        sub     a, b
        ld      b, a
        ld      (nibble_3), a

        ld      a, (PWTemp_4)
        sub     a, b
        ld      b, a
        ld      (nibble_0), a

        ld      a, (PWTemp_7)
        sub     a, b
        ld      b, a
        ld      (nibble_1), a

        ld      a, (PWTemp_8)
        sub     a, b
        ld      b, a
        ld      (nibble_7), a

        ld      a, (PWTemp_0)
        sub     a, b
        ld      b, a
        ld      (nibble_4), a

        ld      a, (PWTemp_9)
        sub     a, b
        ld      b, a
        ld      (nibble_6), a

        ld      a, (PWTemp_2)
        sub     a, b
        ld      b, a
        ld      (nibble_8), a





.CHECK:

        ld      hl, nibble
        ld      de, 0
        ld      b, 9

.CHECK_LOOP:

        ld      a, (hl)
        add     a, d
        ld      d, a

        ld      a, (hli)
        xor     a, e
        ld      e, a

        dec     b
        jr      nz, .CHECK_LOOP

        ld      a, (PWTemp_3)
        ld      c, a
        ld      a, d

;        and     a, 01Fh

.loop:

        cp      a, 31
        jr      c, .ok

        sub     a, 31
        jr      .loop

.ok:


        cp      c
        jr      NZ, .FAIL

        ld      a, (PWTemp_6)
        ld      c, a
        ld      a, e
        sla     a
        cp      c
        jr      NZ, .FAIL





.UNMANGLE:

        ld      de, GameScore
        ld      hl, CRYPTO
        STORE_HL_TO      TEMPW_2
        
        ld      hl, nibble
        
        ld      b, 4


.UNMANGLE_LOOP:

        ld      a, (hli)
        ld      c, a

        ld      a, (hli)
        sla     a
        sla     a
        sla     a
        sla     a
        or      a, c

        push    hl
        push    af
        LOAD_HL_FROM     TEMPW_2
        pop     af

        xor     a, (hl)
        inc     hl

        ld      (de), a
        inc     de

        STORE_HL_TO      TEMPW_2
        pop     hl



        dec     b
        jr      nz, .UNMANGLE_LOOP


        ; check level < FINAL_WORLD

        ld      a, (hl)
        cp      a, FINAL_WORLD + 3      ; allow view game end (=10) , credits (=11), fail on (=12)
        jr      NC, .FAIL

        ld      (CURR_WORLD), a

        and     a, a
        
        ret

.FAIL:

 jr .FAIL


        ; zero out the current world and game score

        xor     a
        ld      hl, GameScore
        ld      (hli), a
        ld      (hli), a
        ld      (hli), a
        ld      (hli), a
        ld      (CURR_WORLD), a


        scf
        
        ret

cp      a, FINAL_WORLD + 3      ; allow view game end (=10) , credits (=11), fail on (=12)
        jr      NC, .FAIL

        ld      (CURR_WORLD), a

        and     a, a
        
        ret

.FAIL:

 jr .FAIL


        ; z