Как «beq [label]» может вызвать ошибку вне допустимого диапазона?

Я пытаюсь скомпилировать этот фрагмент кода и не могу понять ошибку ассемблера:

      [...]
.macro collflag flags
    RW_forced a8i16
    lda EXRAM, x
    and flags
    RW_forced a16i16
.endmac

[...]

col_r:
    RW_forced a16i16
    lda lamus_vx
    bmi col_l
    beq col_d
    lda lamus_tile
    inc a
    tax
    collflag #PROPS_WALL_LEFT
    beq :+
    jmp r_detected  ; Collision detected - right
:   lda lamus_y
    and #$0300
    beq col_d
    txa
    add #32
    tax
    collflag #PROPS_WALL_LEFT
    beq col_d
    ; Collision detected - right

В этом фрагменте кода я получаю эту ошибку ассемблера:

      metroix.s(264): Error: Range error (130 not in [-128..127])

строка 264 будет относиться к:

          beq col_d

RW_ Force реализованы в библиотеке, и на самом деле все, что они должны делать, это выводить инструкции sep / rep и макросы .a8 / .a16, которые должны работать. Но вот их реализация, которая мне нравится:

      /**
  Macro: RW_assume
  Assume known accumulator/index register widths without emitting any instructions

  Parameter:
  >:in:    widths    Register widths         a8/a16/i8/i16/a8i8/a16i16/a8i16/a16i8
*/
.macro RW_assume widths
.if .blank({widths})
  SFX_error "RW_assume: Missing required parameter"
.else
  RW_init
  .if .xmatch({widths},{a8})
    SFX_RW_a_size .set 1
    .a8
  .elseif .xmatch({widths},{a16})
    SFX_RW_a_size .set 0
    .a16
  .elseif .xmatch({widths},{i8})
    SFX_RW_i_size .set 1
    .i8
  .elseif .xmatch({widths},{i16})
    SFX_RW_i_size .set 0
    .i16
  .elseif .xmatch({widths},{a8i8})
    RW_assume a8
    RW_assume i8
  .elseif .xmatch({widths},{a16i16})
    RW_assume a16
    RW_assume i16
  .elseif .xmatch({widths},{a8i16})
    RW_assume a8
    RW_assume i16
  .elseif .xmatch({widths},{a16i8})
    RW_assume a16
    RW_assume i8
  .else
    SFX_error "RW_assume: Illegal parameter"
  .endif
.endif
.endmac

/**
  Macro: RW_forced
  Force set accumulator/index register widths (ie. always emit rep/sep instructions)

  Parameter:
  >:in:    widths    Register widths         a8/a16/i8/i16/a8i8/a16i16/a8i16/a16i8
*/
.macro RW_forced widths
.if .blank({widths})
  SFX_error "RW_forced: Missing required parameter"
.else
  .if .xmatch({widths},{a8i8})
    sep #$30
  .elseif .xmatch({widths},{a16i16})
    rep #$30
  .elseif .xmatch({widths},{a8i16})
    sep #$20
    rep #$10
  .elseif .xmatch({widths},{a16i8})
    rep #$20
    sep #$10
  .else
    SFX_error "RW_forced: Illegal parameter"
  .endif
  RW_assume widths
.endif
.endmac

Мой вопрос, как это, черт возьми, beq col_dили что-нибудь вокруг этого вне зоны досягаемости? Где вообще 130? Это ошибка ассемблера?

Для справки, если я изменю ЛИБО вызов callflag другой версией без вызовов RW_forced, код будет ассемблирован (но ошибочен).

0 ответов

Другие вопросы по тегам