the cutting room mirror

Vex Block

Vex Block is a game by Sachen, under their moniker Commin. It is a clone of the arcade game Klax, which also received multiple Game Boy ports which render this version useless. Beware the invisible blocks that make it impossible to complete the game!

To do:
Rip everything beyond the invisible blocks.

Source Code#

There is uncompiled source code located in the game's ROM, beginning at hex address 51FF:

    LD  A,0
    STA GAME_STAGE
    JP  START_SUB


CACULATE_MAKE_GAME:
    LDA STAGE_OVER_DELAY
    CP  0
    JR  Z,CAL_TOTAL_MAKE
    JP  OVER_MAKE
CAL_TOTAL_MAKE:
    LDA STAGE_STATUS+0
    CP  3
    JR  Z,CACULATE_HORIZON
    CP  2
    JR  Z,CACULATE_DIAGON
    CP  1
    JR  Z,CACULATE_CONTING
CACULATE_POINT:
    LDA STAGE_STATUS+1
    AND 0FH
    STA TEMP4
    LDA STAGE_STATUS+1
    SWAPA
    AND 0FH
    STA TEMP5

    LD  HL,TEMP5
    LDA  STAGE_SCORE+3 ;SECOND VAL.
    LD  B,A
    LDA TEMP4
    SUB A,B
    JR  NC,PASS_INC
    LD  A,(HL)
    CP  0
    JR  Z,OVER_SCORE
    DEC (HL)
    LDA TEMP4
    ADD A,10
    SUB A,B
PASS_INC:
    AND 00001111B
    STA TEMP4

    LDA  STAGE_SCORE+2 ; FIRST VAL.
    LD  B,A
    LDA TEMP5
    SUB A,B
    BIT 7,A
    JR  Z,PASS_LAST
OVER_SCORE:
    LD  A,0
    STA STAGE_STATUS+2
    JR  SET_OVER_DELAY
PASS_LAST:
    AND 00001111B
    SWAPA
    LD  HL,TEMP4
    OR  (HL)
    JR  Z,OVER_SCORE
    STA STAGE_STATUS+2
    RET

CACULATE_CONTING:
    LDA STAGE_CONTING
    LD  B,A
    CALL    CACULATE_MAKE_SUBX
    RET NZ
    JR  SET_OVER_DELAY
CACULATE_DIAGON:
    LDA STAGE_DIAGON
    LD  B,A
    CALL    CACULATE_MAKE_SUBX
    RET NZ
    JR  SET_OVER_DELAY
CACULATE_HORIZON:
    LDA STAGE_HORIZON
    LD  B,A
    CALL    CACULATE_MAKE_SUBX
    RET NZ
SET_OVER_DELAY:
    LD  A,20H
    STA STAGE_OVER_DELAY
    RET

CACULATE_MAKE_SUBX:
    LDA STAGE_STATUS+1;CURRENT.
    SUB B
    STA STAGE_STATUS+2
    RET


POINT_WORD:  ;SCORE NUMBER.
    DB  'YOU MUST',RTN
    DB  'GET        SCORE',RTN
    DB  'TO PASS THIS STAGE!',END
CONTING_WORD:
    DB  'YOU MUST',RTN
    DB  'MAKE    POINTS',RTN
    DB  'TO PASS THIS STAGE!',END
DIAGON_WORD:
    DB  'YOU MUST',RTN
    DB  'GET    DIAGONALS',RTN
    DB  'TO PASS THIS STAGE!',END
HORIZON_WORD:
    DB  'YOU MUST',RTN
    DB  'GET    HORIZONALS',RTN
    DB  'TO PASS THIS STAGE!',END
ZERO_WORD:
    DB  '0000',0

PR_CONDICTION:
    LDA STAGE_STATUS+0
    CP  3
    JP  Z,PR_HORIZON
    CP  2
    JR  Z,PR_DIAGON
    CP  1
    JR  Z,PR_CONTING
PR_POINT:
    LD  A,0
    STA CURSOR+0
    LD  A,10
    STA CURSOR+1
    LD  HL,POINT_WORD
    CALL    WPRINT
    LD  A,6
    STA CURSOR+0
    LD  A,11
    STA CURSOR+1
    LD  HL,ZERO_WORD
    CALL    WPRINT
       mSETHV   4,11
    LDA STAGE_STATUS+1
PR_POINT_SUBX:
    PUSH    AF
    SWAPA
    CALL    PRHEX
    POP AF
    JP  PRHEX
PR_CONTING:
    LD  A,0
    STA CURSOR+0
    LD  A,10
    STA CURSOR+1
    LD  HL,CONTING_WORD
    CALL    WPRINT
       mSETHV   5,11
    LDA STAGE_STATUS+1
    CALL    HTOD
    JP  PRBYT
PR_DIAGON:
    LD  A,0
    STA CURSOR+0
    LD  A,10
    STA CURSOR+1
    LD  HL,DIAGON_WORD
    CALL    WPRINT
       mSETHV   4,11
    LDA STAGE_STATUS+1
    CALL    HTOD
    JP  PRBYT
PR_HORIZON:
    LD  A,0
    STA CURSOR+0
    LD  A,10
    STA CURSOR+1
    LD  HL,HORIZON_WORD
    CALL    WPRINT
       mSETHV   4,11
    LDA STAGE_STATUS+1
    CALL    HTOD
    JP  PRBYT


PRINT_STATUS:
    LD  A,17
    STA CURSOR+0
    LD  A,7
    STA CURSOR+1
    LDA STAGE_STATUS+0
    CP  3
    JR  Z,PR_HORIZON_PIC
    CP  2
    JR  Z,PR_DIAGON_PIC
    CP  1
    JR  Z,PR_CONTING_PIC
PR_POINT_PIC:
    LD  HL,POINT_PIC
    JP  WPRINT
PR_CONTING_PIC:
    LD  HL,MAKE_PIC
    JP  WPRINT
PR_DIAGON_PIC:
    LD  HL,DIAGON_PIC
    JP  WPRINT
PR_HORIZON_PIC:
    LD  HL,HORIZON_PIC
    JP  WPRINT

PRINT_STAGE_STATUS:
    LDA STAGE_STATUS+0
    CP  0
    JR  NZ,PR_NUMBER
PR_SCORE:
       mSETHV   17,10
    LDA STAGE_STATUS+2
    CALL    PR_POINT_SUBX
    LD  A,'0'
    CALL    PRASC
       mSETHV   18,11
    LD  A,'K'
    JP  PRASC

PR_NUMBER:
       mSETHV   17,10
    LDA STAGE_STATUS+2
    CALL    HTOD
PR_NUMBER_SUB1:
    CP  10
    JR  NC,PR_NUMBER_SUB2
    PUSH    AF
    LD  A,' '
    CALL    PRASC
    POP AF
    JP  PRHEX
PR_NUMBER_SUB2:
    JP  PRBYT

;
; CACULATE FREE SPACE WHEN OVER STAGE.
;
OVER_MAKE:
    LDA NEW_BLOCK_FLAG
    CP  -1
    RET Z
    LD  HL,STAGE_OVER_DELAY
    DEC (HL)
    RET NZ
    CALL    CLSPR

    LD  A,3
    STA MUSIC_NO
    CALL    INIT_MUSIC

    LD  A,3*60
    CALL    WAITSEC

    CALL    CACULATE_FREE_SPACE

    LD  A,4*60
    CALL    WAITSEC

    POP AF
    JP  RE_START_POINT

CLEAR_TOTAL_SCORE:
    LD  HL,TOTAL_SCORE
    LD  E,8
    LD  A,0
LOOP    DEFL    $
    LMAI
    DEC E
    JR  NZ,LOOP
    RET

LEVEL_BLOCK_VAL:
    DB  5,8,13
SET_BLOCK_LEVEL:
    LD  HL,LEVEL_BLOCK_VAL
    LDA GAME_LEVEL+0
LOOP    DEFL    $
    DEC A
    CP  -1
    JR  Z,SET_LEVEL_BLOCK
    INC HL
    JR  LOOP
SET_LEVEL_BLOCK:
    LD  A,(HL)
    STA GAME_LEVEL+1
    RET

CACULATE_FREE_SPACE:
    LD  HL,BLOCK_BOX
    LD  B,2    ; X
    LD  C,12   ; Y
    LD  E,7    ; X
    LD  D,5    ; Y
FREE_SPACE_SUB1:
    LD  A,B
    STA CURSOR+0
    LD  A,C
    STA CURSOR+1
    CALL    SETHV
LOOP    DEFL    $
    LAMI
    PUSH    HL
    PUSH    BC
    PUSH    DE
    CP  -1
    JR  Z,PASS_PRINT_1
    CALL    SEARCH_BLOCK_PIC
    LAMI
    CALL    PRASC
    LAMI
    CALL    PRASC
    JR  PASS_PRINT_2
FREE_SCORE:
    DB  0,0,0,0,0,0,3,0
PASS_PRINT_1:
    LD  A,0FAH ;
    CALL    PRASC  ; SAMPLE PICTURE.
    LD  A,074H ;
    CALL    PRASC  ;
    LD  BC,FREE_SCORE+7
    LD  HL,TOTAL_SCORE+7
    CALL    ADD_SCORE_TO_SCORE
    LDA SCRADDR+0
    STA TEMP7
    LDA SCRADDR+1
    STA TEMP6
    CALL    PRINT_SCORE
    LDA TEMP6
    STA SCRADDR+1
    LDA TEMP7
    STA SCRADDR+0
    LD  A,7
    STA EFFECT1
    LD  A,15*1
    CALL    WAITSEC
PASS_PRINT_2:
    POP DE
    POP BC
    POP HL
    DEC E
    JR  NZ,LOOP
    INC C
    LD  E,7
    DEC D
    JR  NZ,FREE_SPACE_SUB1
    RET

CACULATE_HARD:
    LDA TEMP_LEVEL
    CP  15
    RET C
    LD  A,0
    STA TEMP_LEVEL
    LDA GAME_LEVEL+0
    CP  2
    RET Z
    INC A
    STA GAME_LEVEL+0
    JP  SET_BLOCK_LEVEL