Tatara

Chapter 17
Repeat blocks

A repeat block is a group of lines that TATARA repeats where it stands. It works like a macro without a name, which is defined and used in the same place. REPT repeats its lines a given number of times, IRP once for each item in a list, and IRPC once for each character in a piece of text.

All three end with ENDM, as a macro does, and follow the rules of chapter 16 for their body, for LOCAL and for EXITM.

17.1 REPT

REPT is followed by a count, and the lines up to ENDM are assembled that many times:

                cseg 
here:           rept    3 
                nop 
                endm 
                dw      here
 
                                here:           rept    3 
                                                nop 
                                                endm 
  0000'   00              +                     nop 
  0001'   00              +                     nop 
  0002'   00              +                     nop 
  0003'   00 00                                 dw      here
 

The listing shows the block as it was written, then each round, marked + as in a macro expansion. A label on the REPT line names the start of the first round: here is 0000h.

The count can be any expression, but TATARA works it out before it reads the lines of the block, so it must be a number TATARA already knows: a name defined further down stops TATARA with undefined symbol in an expression., and a relocatable value, such as a label in a code segment, with the relocation error of chapter 8. A count of 0 assembles nothing.

A repeat block is where DEFL (chapter 12) is most useful. A name defined with DEFL can be given a new value in each round, and so can count the rounds:

n               defl    0 
                rept    4 
                db      n 
n               defl    n+1 
                endm
 
  0000'   00              +                     db      n 
  0001'   01              +                     db      n 
  0002'   02              +                     db      n 
  0003'   03              +                     db      n
 

The listing shows each line as it was written, db n, and the bytes show the value n had in that round.

17.2 IRP

IRP is followed by a parameter name, a comma, and a list of items between angle brackets. The block is assembled once for each item, with the parameter replaced by that item:

                irp     x,<1,2,4,8> 
                db      x 
                endm
 
  0000'   01              +                     db      1 
  0001'   02              +                     db      2 
  0002'   04              +                     db      4 
  0003'   08              +                     db      8
 

The items follow the rules of a macro’s arguments (section 16.2). An item that holds a comma is written between angle brackets of its own, and % passes a value instead of text:

five            equ     5 
                irp     s,<'ab',<'c,d'>> 
                db      s 
                endm 
                irp     v,<five*2,%five*2> 
                db      '&v' 
                endm
 
  0005'   61 62           +                     db      'ab' 
  0007'   63 2C 64        +                     db      'c,d' 
  000A'   66 69 76 65     +                     db      'five*2' 
  000E'   2A 32           + 
  0010'   31 30           +                     db      '10'
 

The angle brackets round the list can be left out: irp x,1,2,3 is the same as irp x,<1,2,3>. An empty list, irp x,<>, gives one round, with the parameter empty.

IRP is most useful inside a macro, over an argument that is itself a list:

bytes           macro   list 
                irp     b,<list> 
                db      b 
                endm 
                endm
 
                                                bytes   <10,20,30> 
  0000'   0A              +                     db      10 
  0001'   14              +                     db      20 
  0002'   1E              +                     db      30
 

17.3 IRPC

IRPC is followed by a parameter name, a comma, and a piece of text. The block is assembled once for each character of the text, with the parameter replaced by that character. As in a macro, a parameter inside a string needs & (section 16.3):

                irpc    c,TATARA 
                db      '&c' 
                endm
 
  0000'   54              +                     db      'T' 
  0001'   41              +                     db      'A' 
  0002'   54              +                     db      'T' 
  0003'   41              +                     db      'A' 
  0004'   52              +                     db      'R' 
  0005'   41              +                     db      'A'
 

Every character counts, spaces and commas included: irpc c,<A B,C> gives five rounds, for A, a space, B, a comma and C. The angle brackets are needed only to keep a space in the text, and are not part of it. An empty text, irpc c,<>, gives no rounds at all. ! and % have no special meaning in the text of IRPC.

17.4 LOCAL, EXITM and nesting

LOCAL works in a repeat block as in a macro, and gives each round names of its own:

                rept    2 
                local   skip 
                jr      skip 
                nop 
skip: 
                endm
 
  0000'   18 01           +                     jr      ??0000 
  0002'   00              +                     nop 
  0003'   18 01           +                     jr      ??0001 
  0005'   00              +                     nop
 

Without LOCAL, the second round would define skip again. A line that holds only a label produces no bytes, and is not shown in the expansion.

EXITM ends the whole block, including the rounds that have not run yet. This block would run ten times, but stops after three:

n               defl    0 
                rept    10 
                if      n eq 3 
                exitm 
                endif 
                db      n 
n               defl    n+1 
                endm 
                db      0ffh
 
  0000'   00              +                     db      n 
  0001'   01              +                     db      n 
  0002'   02              +                     db      n 
  0003'   FF                                    db      0ffh
 

Repeat blocks can be put inside each other and inside macros, and each ENDM ends the innermost one. Together with macro expansions and include files, they can be 16 deep (section 16.7).

17.5 Messages

Table 17.1 lists the messages about repeat blocks, each with the line that causes it. When an error happens inside a repeat block, the trail that follows the message names it as a repeat block.

Line

Message

rept count, count defined further down

undefined symbol in an expression.

rept start, start a label in a code segment

relocation error - a segment-relative value is not allowed here.

irp x, with no comma

bad macro parameter list.

a repeat block with no ENDM

macro definition not closed by ENDM.

Table 17.1: Messages about repeat blocks.